mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
148 lines
3.6 KiB
Lua
148 lines
3.6 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
|
|
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
|
|
|
|
-- gmsave.SaveMap is very expensive for big maps/lots of entities. Do not allow random ppl to save the map in multiplayer!
|
|
-- TODO: Actually do proper hooks for this
|
|
if ( !game.SinglePlayer() && !ply:IsAdmin() ) then return end
|
|
|
|
if ( ply.m_NextSave && ply.m_NextSave > CurTime() && !game.SinglePlayer() ) then
|
|
ServerLog( tostring( ply ) .. " tried to save too quickly!\n" )
|
|
return
|
|
end
|
|
|
|
ply.m_NextSave = CurTime() + 10
|
|
|
|
ServerLog( tostring( ply ) .. " requested a save.\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 = false
|
|
if ( args[ 1 ] == "spawnmenu" ) then ShowSave = true 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 } )
|
|
|
|
local function LoadGModSave( savedata )
|
|
|
|
-- If we loaded the save from main menu and the player entity is not ready yet
|
|
if ( game.SinglePlayer() && !IsValid( Entity( 1 ) ) ) then
|
|
|
|
timer.Create( "LoadGModSave_WaitForPlayer", 0.1, 0, function()
|
|
if ( !IsValid( Entity( 1 ) ) ) then return end
|
|
|
|
timer.Remove( "LoadGModSave_WaitForPlayer" )
|
|
LoadGModSave( savedata )
|
|
end )
|
|
|
|
return
|
|
|
|
end
|
|
|
|
local ply = nil
|
|
if ( IsValid( Entity( 1 ) ) && ( game.SinglePlayer() || Entity( 1 ):IsListenServerHost() ) ) then ply = Entity( 1 ) end
|
|
if ( !IsValid( ply ) && #player.GetHumans() == 1 ) then ply = player.GetHumans()[ 1 ] end
|
|
|
|
gmsave.LoadMap( savedata, ply )
|
|
|
|
end
|
|
|
|
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
|
|
|
|
LoadGModSave( savedata )
|
|
|
|
end )
|
|
|
|
else
|
|
|
|
local buffer = ""
|
|
net.Receive( "GModSave", function( len, client )
|
|
local done = net.ReadBool()
|
|
local showsave = net.ReadBool()
|
|
|
|
local length = net.ReadUInt( 16 )
|
|
local data = net.ReadData( length )
|
|
|
|
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
|
|
|
|
local MapAddon = nil
|
|
for id, addon in pairs( engine.GetAddons() ) do
|
|
if ( file.Exists( "maps/" .. game.GetMap() .. ".bsp", addon.title ) ) then
|
|
MapAddon = addon.wsid
|
|
end
|
|
end
|
|
|
|
engine.WriteSave( buffer, game.GetMap() .. " " .. util.DateStamp(), CurTime(), game.GetMap(), MapAddon )
|
|
buffer = ""
|
|
|
|
if ( showsave ) then
|
|
hook.Run( "PostGameSaved" )
|
|
end
|
|
|
|
end )
|
|
|
|
end
|