-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathScripts.pas
153 lines (119 loc) · 3.33 KB
/
Scripts.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
unit Scripts;
(*
Description: Lua scripting support.
Author: Alexander Shostak aka Berserker
*)
(***) interface (***)
uses
StrUtils,
SysUtils,
DataLib,
Debug,
DlgMes,
Files,
FilesEx,
Utils,
EventMan,
GameExt,
Log,
Lua;
const
SCRIPTS_DIR = 'Data\Lua';
ENTRY_SCRIPT = 'init.lua';
type
(* Import *)
TStrList = DataLib.TStrList;
var
{O} L: PLua_State;
(***) implementation (***)
function OnLuaError (L: PLua_State): integer; cdecl;
var
Error: string;
begin
Error := lua_tostring(L, -1);
Log.Write('Lua', 'Execution', Error);
Debug.FatalError(Error);
result := 0;
end;
function OnLuaCallError (L: PLua_State): integer; cdecl;
begin
result := 1;
if not lua_isstring(L, 1) then begin
exit;
end;
lua_getfield(L, TLUA_GLOBALSINDEX, 'debug');
if not lua_istable(L, -1) then begin
lua_pop(L, 1);
exit;
end;
lua_getfield(L, -1, 'traceback');
if not lua_isfunction(L, -1) then begin
lua_pop(L, 2);
exit;
end;
lua_pushvalue(L, 1); (* pass error message *)
lua_pushinteger(L, 2); (* skip this function and traceback *)
lua_call(L, 2, 1); (* call debug.traceback *)
end; // .function OnLuaCallError
procedure InitLua;
begin
// Initialize Lua engine and setup error handler
L := luaL_newstate();
{!} Assert(L <> nil, 'Failed to initialize Lua engine');
lua_atpanic(L, OnLuaError);
luaL_openlibs(L);
// Setup package search paths
lua_getglobal(L, 'package');
lua_pushstring(L, GameExt.GameDir + '\' + SCRIPTS_DIR + '\lib\?.lua');
lua_setfield(L, -2, 'path');
lua_pop(L, 1);
lua_getglobal(L, 'package');
lua_pushstring(L, GameExt.GameDir + '\' + SCRIPTS_DIR + '\dll\?.dll');
lua_setfield(L, -2, 'cpath');
lua_pop(L, 1);
end; // .procedure InitLua
procedure ExecuteLuaScript (const FilePath: string);
var
Error: string;
ErrCode: integer;
begin
lua_pushcfunction(L, OnLuaCallError);
if luaL_loadfile(L, pchar(FilePath)) <> 0 then begin
Debug.FatalError('Failed to load and compile Lua script.'#13#10 + lua_tostring(L, -1));
end;
ErrCode := lua_pcall(L, 0, 0, 1);
Error := 'Out of memory error occured during execution of Lua script "' + FilePath + '"';
if ErrCode = TLUA_ERRMEM then begin
// Leave error message as is
end else if ErrCode = TLUA_ERRERR then begin
if (lua_isstring(L, -1)) and (lua_tostring(L, -1) = 'error in error handling') then begin
Error := 'Stack overflow during Lua handler execution';
end else begin
Error := 'Error occured during Lua error handler execution';
end;
end else if ErrCode <> 0 then begin
if lua_isstring(L, -1) then begin
Error := 'Lua script error occured.'#13#10 + lua_tostring(L, -1);
end else begin
Error := 'Error occured during execution of Lua script "' + FilePath + '"';
end;
end; // .elseif
if ErrCode <> 0 then begin
Log.Write('Lua', 'Execution', Error);
Debug.FatalError(Error);
end;
lua_pop(L, 1);
end; // .procedure ExecuteLuaScript
procedure OnAfterLoadEraPlugins (Event: GameExt.PEvent); stdcall;
var
EntryScriptPath: string;
begin
EntryScriptPath := GameExt.GameDir + '\' + SCRIPTS_DIR + '\' + ENTRY_SCRIPT;
if Files.FileExists(EntryScriptPath) then begin
InitLua;
ExecuteLuaScript(EntryScriptPath);
end;
end;
begin
EventMan.GetInstance.On('$OnAfterLoadEraPlugins', OnAfterLoadEraPlugins);
end.