-
Notifications
You must be signed in to change notification settings - Fork 800
/
save_load.lua
104 lines (69 loc) · 2.52 KB
/
save_load.lua
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
if ( SERVER ) then
--
-- Pool the shared network string
--
util.AddNetworkString( "GModSave" )
--
-- Console command to trigger the save serverside (and send the save to the client)
--
concommand.Add( "gm_save", function( ply, cmd, args )
if ( !IsValid( ply ) ) then return end
if ( !game.SinglePlayer() && !ply:IsAdmin() ) then return end -- gmsave.SaveMap is very expensive for big maps/lots of entities. Do not allow random ppl to save the map in multiplayer!
if ( ply.m_NextSave && ply.m_NextSave > CurTime() && !game.SinglePlayer() ) then
ServerLog( "Player is saving too quickly! " .. tostring( ply ) .. "\n" )
return end
ply.m_NextSave = CurTime() + 10
ServerLog( "Sending save to player " .. tostring( ply ) .. "\n" )
local save = gmsave.SaveMap( ply )
if ( !save ) then return end
local compressed_save = util.Compress( save )
if ( !compressed_save ) then compressed_save = save end
local len = string.len( compressed_save )
local send_size = 60000
local parts = math.ceil( len / send_size )
local ShowSave = 0
if ( args[ 1 ] == "spawnmenu" ) then ShowSave = 1 end
local start = 0
for i = 1, parts do
local endbyte = math.min( start + send_size, len )
local size = endbyte - start
net.Start( "GModSave" )
net.WriteBool( i == parts )
net.WriteBool( ShowSave )
net.WriteUInt( size, 16 )
net.WriteData( compressed_save:sub( start + 1, endbyte + 1 ), size )
net.Send( ply )
start = endbyte
end
end, nil, "", { FCVAR_DONTRECORD } )
hook.Add( "LoadGModSave", "LoadGModSave", function( savedata, mapname, maptime )
savedata = util.Decompress( savedata )
if ( !isstring( savedata ) ) then
MsgN( "gm_load: Couldn't load save!" )
return
end
gmsave.LoadMap( savedata, nil )
end )
else
local buffer = ""
net.Receive( "GModSave", function( len, client )
local done = net.ReadBool()
local showsave = net.ReadBool()
local len = net.ReadUInt( 16 )
local data = net.ReadData( len )
buffer = buffer .. data
if ( !done ) then return end
MsgN( "Received save. Size: " .. buffer:len() )
local uncompressed = util.Decompress( buffer )
if ( !uncompressed ) then
MsgN( "Received save - but couldn't decompress!?" )
buffer = ""
return
end
engine.WriteSave( buffer, game.GetMap() .. " " .. util.DateStamp(), CurTime(), game.GetMap() )
buffer = ""
if ( showsave ) then
hook.Run( "PostGameSaved" )
end
end )
end