mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
147
gamemodes/sandbox/gamemode/save_load.lua
Normal file
147
gamemodes/sandbox/gamemode/save_load.lua
Normal file
@@ -0,0 +1,147 @@
|
||||
--[[
|
||||
| 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
|
||||
Reference in New Issue
Block a user