Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- AddCSLuaFile()
- if SERVER then
- util.AddNetworkString("H.PrepIPly")
- util.AddNetworkString("H.IPly")
- util.AddNetworkString("H.Ply")
- util.AddNetworkString("H.PV")
- GM.PFields = {}
- GM.PVars = {}
- -- ids aren't registered variables so we have to add them ourselves
- GM.GlobalPVars = {id = NW_MEDIUMINT}
- GM.SharedPVars = {}
- end
- -- Internals
- local VAR_PRIVATE, VAR_SHARED, VAR_GLOBAL = VAR_PRIVATE, VAR_SHARED, VAR_GLOBAL
- local meta = FindMetaTable("Player")
- -- use this for values that are different for each player (e.g. registration date)
- -- nwtype must be one of the NW_* enums
- -- shared: VAR_SHARED will sync the player, VAR_GLOBAL will sync everyone
- function GM:AddPlayerField(name, funcname, default, nwtype, shared)
- print("added player field: " .. name .. " (default: " .. tostring(default) .. ")")
- if SERVER then
- meta["Set" .. funcname] = function(self, val, nosave)
- self.PVars = self.PVars or {}
- if val == self.PVars[name] then return end
- self.PVars[name] = val
- if shared ~= nil then
- print("updating " .. name .. " on " .. self:Nick())
- net.Start("SP.PV")
- net.WriteUInt(self:EntIndex(), 8)
- net.WriteString(name)
- net.Write(nwtype, val)
- if shared then
- net.Broadcast()
- else
- net.Send(self)
- end
- end
- if not nosave then
- self:SavePlayerField(name, val)
- end
- end
- self.PFields[name] = {Type = type(default), NWType = nwtype, Shared = shared}
- if shared == VAR_GLOBAL then
- self.GlobalPVars[name] = nwtype
- elseif shared == VAR_SHARED then
- self.SharedPVars[name] = nwtype
- end
- end
- if SERVER or nwtype ~= VAR_PRIVATE then
- meta["Get" .. funcname] = function(self)
- if not self.PVars or self.PVars[name] == nil then
- return default
- end
- return self.PVars[name]
- end
- end
- end
- -- Adds a variable as a row in sp_player_vars
- -- Should be used for variables that will rarely vary from the default
- -- nwtype must be one of the NW_* enums
- -- shared: VAR_SHARED will sync the player, VAR_GLOBAL will sync everyone
- function GM:AddPlayerVar(name, funcname, default, nwtype, shared)
- print("added PV: " .. name .. " (default: " .. tostring(default) .. ")")
- if SERVER then
- meta["Set" .. funcname] = function(self, val, nosave)
- self.PVars = self.PVars or {}
- -- local cur = self.PVars[name]
- -- if val == cur or (cur == nil and val == default) then
- -- return
- -- end
- if val == self.PVars[name] then return end
- self.PVars[name] = val
- if shared ~= nil then
- print("updating " .. name .. " on " .. self:Nick())
- net.Start("SP.PV")
- net.WriteUInt(self:EntIndex(), 8)
- net.WriteString(name)
- net.Write(nwtype, val)
- if shared then
- net.Broadcast()
- else
- net.Send(self)
- end
- end
- if not nosave then
- self:SavePlayerVariable(name, val)
- end
- end
- self.PVars[name] = {Type = type(default), NWType = nwtype, Shared = shared, Save = true}
- if shared == VAR_GLOBAL then
- self.GlobalPlayerVars[name] = nwtype
- elseif shared == VAR_SHARED then
- self.SharedPlayerVars[name] = nwtype
- end
- else
- meta["Set" .. funcname] = function(self, val)
- self.PVars = self.PVars or {}
- end
- end
- if SERVER or nwtype ~= VAR_PRIVATE then
- meta["Get" .. funcname] = function(self)
- if not self.PVars or self.PVars[name] == nil then
- return default
- end
- return self.PVars[name]
- end
- end
- end
- -- Adds a temporary player var
- -- nwtype must be one of the NW_* enums
- -- shared: VAR_SHARED will sync the player, VAR_GLOBAL will sync everyone
- function GM:AddTempPlayerVar(name, funcname, default, nwtype, shared)
- print("added runtime PV: " .. name .. " (default: " .. tostring(default) .. ")")
- if SERVER then
- meta["Set" .. funcname] = function(self, val)
- self.PVars = self.PVars or {}
- -- local cur = self.PVars[name]
- -- if val == cur or (cur == nil and val == default) then
- -- return
- -- end
- if val == self.PVars[name] then return end
- self.PVars[name] = val
- if shared ~= nil then
- print("updating " .. name .. " on " .. self:Nick())
- net.Start("SP.PV")
- net.WriteUInt(self:EntIndex(), 8)
- net.WriteString(name)
- net.Write(nwtype, val)
- if shared then
- net.Broadcast()
- else
- net.Send(self)
- end
- end
- end
- self:PVars[name] = {Type = type(default), NWType = nwtype, Shared = shared, Save = false}
- if shared == VAR_GLOBAL then
- self:GlobalPlayerVars[name] = nwtype
- elseif shared == VAR_SHARED then
- self:SharedPlayerVars[name] = nwtype
- end
- end
- if SERVER or nwtype ~= VAR_PRIVATE then
- meta["Get" .. funcname] = function(self)
- if not self.PVars or self.PVars[name] == nil then
- return default
- end
- return self.PVars[name]
- end
- end
- end
- GM:AddPlayerVar("charlimit", "CharLimit", GM.CharLimit, NW_TINYUINT, VAR_SHARED)
- GM:AddPlayerVar("tooltrust", "Tooltrust", GM.Tooltrust, NW_TINYUINT, VAR_SHARED)
- GM:AddTempPlayerVar("typing", "Typing", false, NW_BOOL, VAR_GLOBAL)
- GM:AddTempPlayerVar("holstered", "Holstered", 0, NW_TINYUINT, VAR_GLOBAL)
- GM:AddTempPlayerVar("ic", "InCharacter", false, NW_BOOL, VAR_GLOBAL)
- Player.IsTyping, Player.GetTyping = Player.GetTyping, nil
- Player.IsHolstered, Player.GetHolstered = Player.GetHolstered, nil
- Player.IsInCharacter, Player.GetInCharacter = Player.GetInCharacter, nil
- if SERVER then return end
- local target = {}
- net.Receive("H.PrepIPly", function(len)
- print("INITIAL PLAYER SYNC")
- GAMEMODE.LocalIndex = net.ReadUInt(8)
- GAMEMODE.IPlayers = net.ReadUInt(8)
- end)
- net.Receive("H.IPly", function(len)
- local index = net.ReadUInt(8)
- local ply = Entity(index)
- print("Initial sync: #" .. index .. " (" .. tostring(ply) .. ")")
- local vars = {}
- for i = 1, net.ReadUInt(8) do
- vars[net.ReadString()] = net.Read()
- end
- -- LocalPlayer() is rarely valid at this point
- if index == GAMEMODE.LocalIndex then
- GAMEMODE.CurrentPlayerVars = vars
- local flags = {}
- print("\tLocal player\n\tFlags:")
- for i = 1, net.ReadUInt(8) do
- local id = net.ReadString()
- print("\t\t" .. id)
- flags[id] = GAMEMODE.PlayerFlags[id]
- end
- GAMEMODE.CurrentPlayerFlags = flags
- end
- if ply:IsValid() then
- ply.PVars = vars
- else
- GAMEMODE.PVQueue[index] = vars
- end
- GAMEMODE.IPlayers = GAMEMODE.IPlayers - 1
- if GAMEMODE.IPlayers == 0 then
- GAMEMODE.IPlayers = nil
- -- merge any newer, non-initial updates.
- -- this is very unlikely.
- for index, vars in pairs(target) do
- local t = GAMEMODE.PVQueue[index]
- if t then
- table.Merge(t, vars)
- else
- GAMEMODE.PVQueue[index] = vars
- end
- local ply = Entity(index)
- if ply:IsValid() then
- ply.PVars = vars
- GAMEMODE.PVQueue[index] = nil
- end
- end
- -- PV updates are applied normally now
- target = GAMEMODE.PVQueue
- hook.Run("PostReadPlayers")
- if GAMEMODE.CharacterList then
- hook.Run("PlayerReady")
- end
- end
- end)
- net.Receive("SP.Ply", function(len)
- local index = net.ReadUInt(8)
- local ply = Entity(index)
- print("Sync: #" .. index .. " (" .. tostring(ply) .. ")")
- local vars = {}
- for i = 1, net.ReadUInt(8) do
- vars[net.ReadString()] = net.Read()
- end
- if ply:IsValid() and not SP.IPlayers then
- ply.PVars = vars
- if index == SP.LocalIndex then
- SP.CurrentPlayerVars = vars
- end
- else
- target[index] = vars
- end
- end)
- net.Receive("SP.PV", function(len)
- local index = net.ReadUInt(8)
- local ply = Entity(index)
- if ply:IsValid() and not SP.IPlayers then
- ply.PVars[net.ReadString()] = net.Read()
- else
- local vars = target[index]
- if vars then
- vars[net.ReadString()] = net.Read()
- else
- target[index] = {
- [net.ReadString()] = net.Read()
- }
- end
- end
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement