Has the way GM:Shutdown() works changed at all?

I’ve noticed as of late when my Gamemodes are shutting down player information isn’t being saved and I’ve isolated it to the snippets of code not actually having enough time to run and instead of waiting for it all to run, it just shuts down. So has the way it works changed or do I just need to fill the function with bloat to slow it down?

I’m using a loop at the moment to save the information and not even the first entry is ran.

( **[Gamemode.ShutDown

http://wiki.garrysmod.com/favicon.ico](wiki.garrysmod.com/?title=Gamemode.ShutDown)** )

Try using Shutdown on both changing map and exiting make it write an file, but I think this only works on map change.

Did you even view the link to see what it does?

How are you saving your player information? If you’re using sqlite or files all your queries will block (assuming you run them). If you’re using tmysql it will automatically finish all the queries in Shutdown (but callbacks aren’t guaranteed pre version 3). If you’re using a different mysql module the behavior might not be as well defined.

I’m using mysqloo. I’m not too worried about callbacks (after all I want to shut it down). I suppose I may end up having to use wait() if that’s the case.

ShutDown is called on map change and when you run the commands: “exit”, “killserver” and any other function that shuts the server down via command.

Thank you for your insightful input!

After a bit more investigation, it seems that it’s not running loops unless it can access the table quick enough.

A localised table with some strings in will run (and will be printed) whereas a loop trying to grab all players won’t have enough time to run. Any thoughts or am I just building a box fort here?

Localise the players before the call?

The server won’t shutdown/change level before the code in the ShutDown hook has finished executing.

Try running a loop grabbing all players and printing something per player. You’ll find it won’t even print the first one in the table.

He seems to be correct




] lua_run hook.Add("ShutDown","test",function() print("called") for k,v in pairs(player.GetAll()) do print(v) end end)
> hook.Add("ShutDown","test",function() print("called") for k,v in pairs(player.GetAll()) do print(v) end end)...
] disconnect 
called
Dropped Flawless from server (Server shutting down)


The problem there is that player.GetAll() doesn’t seem to work as expected in the ShutDown hook.

Neither does ents.GetAll().


] lua_run local pl  hook.Add("Think" , 0, function() pl = player.GetAll() end ) hook.Add("ShutDown" , 0 , function() print("Called") for k , v in pairs(pl) do print(v) end end )
> local pl  hook.Add("Think" , 0, function() pl = player.GetAll() end ) hook.Add("ShutDown" , 0 , function() print("Called") for k , v in pairs(pl) do print(v) end end )...
lua_run	167
] changelevel gm_construct
Called
Player [NULL]
-

Looks like you’ll need to use another method.

[editline]19th July 2011[/editline]

You could store steamids and whatever data you need to, then save it on shut down. That would work.

It would but that’s bit of a workaround considering the expected behaviour is that player.GetAll() would still work until the lua engine has shut down.

I know in the past player.GetAll() worked however it seems to have been a recent update (how recent I’m not entirely sure) that’s causing this issue.

I didn’t change anything, but the engine change might have. I will look into it.

My workaround is something like this: (This loads data when a player connects, and saves it when they disconnect, but the basic idea is the same if you aren’t saving it until the server shuts down)
[lua]
local player_data = {}
hook.Add(“PlayerAuthed”, “load player data”, function(ply)
– load player data here
player_data[ply:SteamID()] = ply.saved_data
end)
hook.Add(“PlayerDisconnect”, “save player data”, function(ply)
– save player data here
player_data[ply:SteamID()] = nil
end)
hook.Add(“ShutDown”, “save player data”, function()
for steamid, data in pairs(player_data) do
– save player data here
end
end)
[/lua]

I have something like that already and I have a workaround going at the moment, but it’d be better overall of player/ents.GetAll() worked properly in the ShutDown hook so other tasks can also be performed.