There are still a lot of bugs in SVN (as in it's completely unplayable). This is one crash bug in loading save game:
Index: rlplayer.pas
===================================================================
--- rlplayer.pas (revision 876)
+++ rlplayer.pas (working copy)
@@ -1877,7 +1877,7 @@
end;
ISt.Read(tsob, sizeof(tsob));
- for Count := 1 to Game.Lua.Table['quests','__counter'] do
+ for Count := 1 to Game.Lua.Table['achievments','__counter'] do
if Count in tsob then
begin
Game.Lua.IndexedTable['achievments', Count, 'active'] := true;
Even with this it won't work though. There is a deep problem in rllua.pas/TRLLua.RunHook when it comes to loading Grisworld's magical items. I can't work out how this should work. It's clear the current system can't work because after calling CallFunction with no args, the function is at the top of the stack and there are no arguments... except the lua references a first argument "self" and that bombs. You can add an extra parameter saying "resurrect the previous n arguments from the stack" and that gets you somewhere... But there's still the problem of what the object you're working with actually is, and how you get a handle to it. At the moment it's looking up stuff in the "items" table, and that seems to be prototypes. But how to get hold of instance isn't clear to me. Here's how far I got, in case this is useful.
Index: rllua.pas
===================================================================
--- rllua.pas (revision 876)
+++ rllua.pas (working copy)
@@ -210,7 +210,7 @@
try
with TLuaTable.Create( Self, TableName, Index ) do
try
- RunHook := State.CallFunction( Name, Args, -1 );
+ RunHook := State.CallFunction( Name, Args, -1, 1 );
finally
Free;
end;
And the corresponding fpcvalkyrie changes:
Index: vluastate.pas
===================================================================
--- vluastate.pas (revision 243)
+++ vluastate.pas (working copy)
@@ -83,7 +83,7 @@
procedure UnRegisterObject( Obj : TLuaReferencedObject );
procedure RegisterNewSubObject( Ref : Integer; Obj : TObject; const Field, Prototype : AnsiString );
function RunHook( Obj : TLuaReferencedObject; HookName : AnsiString; const Params : array of const ) : Variant;
- function CallFunction( Name : AnsiString; const Params : array of const; idx : Integer = GLOBALSINDEX ) : Variant;
+ function CallFunction(Name : AnsiString; const Params : array of const; idx : Integer = GLOBALSINDEX; extra_args: Integer = 0 ) : Variant;
destructor Done;
procedure RegisterSubTable( Ref : Integer; const Name : AnsiString );
procedure SubTableToStream( Obj : TLuaReferencedObject; const Name : AnsiString; OSt : TStream );
@@ -522,8 +522,9 @@
end;
function TLuaState.CallFunction( Name : AnsiString;
- const Params : array of const; idx : Integer = GLOBALSINDEX ) : Variant;
+ const Params : array of const; idx : Integer = GLOBALSINDEX; extra_args : Integer = 0): Variant;
var Index : Integer;
+var i : Integer ;
begin
Index := lua_absindex( FState, idx );
lua_pushstring( FState, Name );
@@ -532,7 +533,11 @@
Push( Params );
- if lua_pcall( FState, High( Params ) + 1, 1, 0 ) <> 0 then PopRaise( 1, 'Lua error : '+lua_tostring( FState, -1) );
+ (* Raise the extra parameters from their previous (assumed) stack position *)
+ for i := 1 to extra_args do
+ lua_pushvalue(FState, -2 - extra_args + i);
+
+ if lua_pcall( FState, High( Params ) + 1 + extra_args, 1, 0 ) <> 0 then PopRaise( 1, 'Lua error : '+lua_tostring( FState, -1) );
CallFunction := lua_tovariant( FState, -1 );
lua_pop( FState, 1 );
end;
Four crash bugs I found; I have a fix for two.
1) Barrels killing an NPC causes a segfault. Fix:
--- rlnpc.pas 2011-08-30 23:36:33.000000000 +0100
+++ rlnpc.fix 2011-08-30 23:34:58.000000000 +0100
@@ -502,7 +502,12 @@
game.player.querry := nil;
if Visible then UI.Msg(GetName(CTheName)+' dies.');
PlaySound('d');
- RunHook( Hook_OnDrop, [ Attacker ] );
+
+ if Attacker <> nil then
+ RunHook( Hook_OnDrop, [ Attacker ] )
+ else
+ RunHook( Hook_OnDrop, [ ] );
+
if AI in AIMonster then
UI.Msg('You gain '+IntToStr(getExpValue(Game.Player.Level))+' experience.');
Game.Player.AddExp(getExpValue(Game.Player.Level));
2) Under certain circumstances, the lua calls through to drop item with invalid coordinates. Below fixes the crash, the lua still needs to be identified.
Index: rllevel.pas
===================================================================
--- rllevel.pas (revision 878)
+++ rllevel.pas (working copy)
@@ -715,6 +715,11 @@
if State.StackSize < 2 then Exit(0);
tid := State.ToString(1);
Coord := State.ToCoord(2);
+
+ if ((Coord.X < 1) or (Coord.X > MapSizeX) or
+ (Coord.Y < 1) or (Coord.Y > MapSizeY) ) then
+ Exit(luaL_error(L, PChar('Coordinates out of range')));
+
if tid = '' then
begin
FreeAndNil(Game.Lua.Level.Map[Coord.X, Coord.Y].NPC);
3) Valgrind backtrace identified this access of free'd memory. I'm not really sure where to start. I can take a look at it, but I could use a hint.
==5016== Invalid read of size 8
==5016== at 0x52F3A8: VLUASTATE_TLUASTATE_$__PUSH$TLUAREFERENCEDOBJECT (vluastate.pas:403)
==5016== by 0x4E32290: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E3C422: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E326FD: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31E36: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31EB4: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E2DF74: lua_pcall (in /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x5297EA: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:611)
==5016== by 0x4E7B92: VLUA_TLUATABLE_$__EXECUTE$ANSISTRING$array_of_VARIANT$$VARIANT (vlua.pas:830)
==5016== by 0x4EFC7B: RLNPC_TNPC_$__ACTIVATECELL$TCOORD2D$$BOOLEAN (rlnpc.pas:367)
==5016== by 0x493806: RLPLAYER_TPLAYER_$_ACTION_TRYMOVE$TDIRECTION (rlplayer.pas:1479)
==5016== by 0x49299F: RLPLAYER_TPLAYER_$__ACTION (rlplayer.pas:1531)
==5016== Address 0x7123660 is 128 bytes inside a block of size 256 free'd
==5016== at 0x4C2130F: free (vg_replace_malloc.c:323)
==5016== by 0x4534F4: CMEM_CFREEMEM$POINTER$$QWORD (in /home/ed/sources/diablorl-svn/bin/rl)
==5016== by 0x489AD5: RLLEVEL_LUA_LEVEL_DROP_ITEM$PLUA_STATE$$LONGINT (rllevel.pas:727)
==5016== by 0x4E32290: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E3C422: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E326FD: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31E36: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31EB4: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E2DF74: lua_pcall (in /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x5297EA: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:611)
==5016== by 0x4E7B92: VLUA_TLUATABLE_$__EXECUTE$ANSISTRING$array_of_VARIANT$$VARIANT (vlua.pas:830)
==5016== by 0x4EFC7B: RLNPC_TNPC_$__ACTIVATECELL$TCOORD2D$$BOOLEAN (rlnpc.pas:367)
==5016==
==5016== Invalid read of size 4
==5016== at 0x4ED660: RLGOBJ_TGAMEOBJECT_$__GETLUAINDEX$$LONGINT (rlgobj.pas:174)
==5016== by 0x4E32290: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E3C422: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E326FD: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31E36: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31EB4: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E2DF74: lua_pcall (in /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x5297EA: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:611)
==5016== by 0x4E7B92: VLUA_TLUATABLE_$__EXECUTE$ANSISTRING$array_of_VARIANT$$VARIANT (vlua.pas:830)
==5016== by 0x4EFC7B: RLNPC_TNPC_$__ACTIVATECELL$TCOORD2D$$BOOLEAN (rlnpc.pas:367)
==5016== by 0x493806: RLPLAYER_TPLAYER_$_ACTION_TRYMOVE$TDIRECTION (rlplayer.pas:1479)
==5016== by 0x49299F: RLPLAYER_TPLAYER_$__ACTION (rlplayer.pas:1531)
==5016== Address 0x7123658 is 120 bytes inside a block of size 256 free'd
==5016== at 0x4C2130F: free (vg_replace_malloc.c:323)
==5016== by 0x4534F4: CMEM_CFREEMEM$POINTER$$QWORD (in /home/ed/sources/diablorl-svn/bin/rl)
==5016== by 0x489AD5: RLLEVEL_LUA_LEVEL_DROP_ITEM$PLUA_STATE$$LONGINT (rllevel.pas:727)
==5016== by 0x4E32290: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E3C422: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E326FD: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31E36: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E31EB4: (within /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x4E2DF74: lua_pcall (in /usr/lib/liblua5.1.so.0.0.0)
==5016== by 0x5297EA: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:611)
==5016== by 0x4E7B92: VLUA_TLUATABLE_$__EXECUTE$ANSISTRING$array_of_VARIANT$$VARIANT (vlua.pas:830)
==5016== by 0x4EFC7B: RLNPC_TNPC_$__ACTIVATECELL$TCOORD2D$$BOOLEAN (rlnpc.pas:367)
==5016==
4) I really don't know what happened here. Things went BOOM in a bad way.
==5417== Invalid read of size 8
==5417== at 0x445551: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x4E7C12: VLUA_TLUATABLE_$__EXECUTE$ANSISTRING$array_of_VARIANT$$VARIANT (vlua.pas:830)
==5417== by 0x4EFCFB: RLNPC_TNPC_$__ACTIVATECELL$TCOORD2D$$BOOLEAN (rlnpc.pas:367)
==5417== by 0x493886: RLPLAYER_TPLAYER_$_ACTION_TRYMOVE$TDIRECTION (rlplayer.pas:1479)
==5417== by 0x492A1F: RLPLAYER_TPLAYER_$__ACTION (rlplayer.pas:1531)
==5417== by 0x4F0582: RLNPC_TNPC_$__TIMEFLOW$LONGINT (rlnpc.pas:485)
==5417== by 0x434E02: main (rl.pas:27)
==5417== Address 0x7fefff638 is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes
==5417==
==5417== Invalid read of size 8
==5417== at 0x449D04: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x4E7C12: VLUA_TLUATABLE_$__EXECUTE$ANSISTRING$array_of_VARIANT$$VARIANT (vlua.pas:830)
==5417== by 0x4EFCFB: RLNPC_TNPC_$__ACTIVATECELL$TCOORD2D$$BOOLEAN (rlnpc.pas:367)
==5417== by 0x493886: RLPLAYER_TPLAYER_$_ACTION_TRYMOVE$TDIRECTION (rlplayer.pas:1479)
==5417== by 0x492A1F: RLPLAYER_TPLAYER_$__ACTION (rlplayer.pas:1531)
==5417== by 0x4F0582: RLNPC_TNPC_$__TIMEFLOW$LONGINT (rlnpc.pas:485)
==5417== by 0x434E02: main (rl.pas:27)
==5417== Address 0x7fefff5f8 is not stack'd, malloc'd or (recently) free'd
==5417==
==5417== Invalid read of size 8
==5417== at 0x449D07: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x4E7C12: VLUA_TLUATABLE_$__EXECUTE$ANSISTRING$array_of_VARIANT$$VARIANT (vlua.pas:830)
==5417== by 0x4EFCFB: RLNPC_TNPC_$__ACTIVATECELL$TCOORD2D$$BOOLEAN (rlnpc.pas:367)
==5417== by 0x493886: RLPLAYER_TPLAYER_$_ACTION_TRYMOVE$TDIRECTION (rlplayer.pas:1479)
==5417== by 0x492A1F: RLPLAYER_TPLAYER_$__ACTION (rlplayer.pas:1531)
==5417== by 0x4F0582: RLNPC_TNPC_$__TIMEFLOW$LONGINT (rlnpc.pas:485)
==5417== by 0x434E02: main (rl.pas:27)
==5417== Address 0x7fefff600 is not stack'd, malloc'd or (recently) free'd
==5417==
==5417== Invalid read of size 8
==5417== at 0x449D0B: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x0: ???
==5417== by 0x0: ???
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x4FC358: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:615)
==5417== by 0x7FEFFFA0F: ???
==5417== by 0x64540EF: ???
==5417== by 0x6FBF237: ???
==5417== by 0x167: ???
==5417== by 0x64495E7: ???
==5417== Address 0x7fefff608 is not stack'd, malloc'd or (recently) free'd
==5417==
==5417== Invalid read of size 8
==5417== at 0x449D0F: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x0: ???
==5417== by 0x0: ???
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x4FC358: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:615)
==5417== by 0x7FEFFFA0F: ???
==5417== by 0x64540EF: ???
==5417== by 0x6FBF237: ???
==5417== by 0x167: ???
==5417== by 0x64495E7: ???
==5417== Address 0x7fefff610 is not stack'd, malloc'd or (recently) free'd
==5417==
==5417== Invalid read of size 8
==5417== at 0x449D13: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x0: ???
==5417== by 0x0: ???
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x4FC358: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:615)
==5417== by 0x7FEFFFA0F: ???
==5417== by 0x64540EF: ???
==5417== by 0x6FBF237: ???
==5417== by 0x167: ???
==5417== by 0x64495E7: ???
==5417== Address 0x7fefff618 is not stack'd, malloc'd or (recently) free'd
==5417== Invalid read of size 8
==5417== at 0x449D17: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x0: ???
==5417== by 0x0: ???
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x4FC358: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:615)
==5417== by 0x7FEFFFA0F: ???
==5417== by 0x64540EF: ???
==5417== by 0x6FBF237: ???
==5417== by 0x167: ???
==5417== by 0x64495E7: ???
==5417== Address 0x7fefff620 is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes
==5417==
==5417== Invalid read of size 8
==5417== at 0x449D27: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x0: ???
==5417== by 0x0: ???
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x4FC358: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:615)
==5417== by 0x7FEFFFA0F: ???
==5417== by 0x64540EF: ???
==5417== by 0x6FBF237: ???
==5417== by 0x167: ???
==5417== by 0x64495E7: ???
==5417== Address 0x7fefff630 is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes
==5417==
==5417== Invalid read of size 8
==5417== at 0x449D2B: SYSTEM_LONGJMP$JMP_BUF$LONGINT (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x44555E: fpc_raiseexception (in /home/ed/sources/diablorl-svn/bin/rl)
==5417== by 0x0: ???
==5417== by 0x0: ???
==5417== by 0x7FEFFFAFF: ???
==5417== by 0x4FC358: LUA_LUA_CALLFUNCTION$PLUA_STATE$ANSISTRING$array_of_VARIANT$LONGINT$$VARIANT (lua.pas:615)
==5417== by 0x7FEFFFA0F: ???
==5417== by 0x64540EF: ???
==5417== by 0x6FBF237: ???
==5417== by 0x167: ???
==5417== by 0x64495E7: ???
==5417== Address 0x7fefff628 is just below the stack ptr. To suppress, use: --workaround-gcc296-bugs=yes