local Debugger = {} Debugger.Clients = {} Debugger.NameMap = {} Debugger.EntVarCounts = {} util.AddNetworkString("metrostroi-debugger-dataupdate") util.AddNetworkString("metrostroi-debugger-entremoved") util.AddNetworkString("metrostroi-debugger-entnamemap") if game.SinglePlayer() then RunConsoleCommand("metrostroi_debugger_update_interval",0) end --[[else --Lets not reset it every time on dedicated servers RunConsoleCommand("metrostroi_debugger_update_interval",0.5) end--]] local function SendNameMap(ply,ent) net.Start("metrostroi-debugger-entnamemap") net.WriteInt(ent:EntIndex(),16) net.WriteTable(ent:GetDebugVars()) if ply then net.Send(ply) else net.Broadcast() end end --Add a new client to send an entities debugvars to local function AddClient(ply,ent) if not Debugger.Clients[ply] then Debugger.Clients[ply]={} end if table.HasValue(Debugger.Clients[ply],ent) then return end table.insert(Debugger.Clients[ply],ent) end local function RemoveEnt(ply,ent) if ply and Debugger.Clients[ply] then if ent then table.RemoveByValue(Debugger.Clients[ply],ent) else Debugger.Clients[ply]=nil end else for k,v in pairs(Debugger.Clients) do table.RemoveByValue(v,ent) end end end --Handler for adding new ents to listen to local function cmdinithandler(ply,cmd,args,fullstring) local ent = ply:GetEyeTrace().Entity if not IsValid(ent) or not ent.GetDebugVars then return end AddClient(ply,ent) end concommand.Add("metrostroi_debugtrainsystems", cmdinithandler, nil, "Add aimed at entity to debugger") -- Automatically engage debugger for train owner function Metrostroi.DebugTrain(train,ply) if not ply then ply = train:GetPlayer() end if (not IsValid(train)) or (not IsValid(ply)) then return end AddClient(ply,train) end local nextthink = 0 local function think() if CurTime() < nextthink then return end nextthink = CurTime() + GetConVar("metrostroi_debugger_update_interval"):GetFloat() --Loop over clients and their ents and send the collected data --Check for new entity variables for ply,entlist in pairs(Debugger.Clients) do for k,ent in pairs(entlist) do local count = table.Count(ent:GetDebugVars()) if Debugger.EntVarCounts[ent] ~= count then SendNameMap(nil,ent) Debugger.EntVarCounts[ent] = count end end end --Send the bulk, nameless data for ply,entlist in pairs(Debugger.Clients) do net.Start("metrostroi-debugger-dataupdate") local count = table.Count(entlist) net.WriteInt(count,8) for k,ent in pairs(entlist) do local entvars = ent:GetDebugVars() local newtable = {} for k,v in SortedPairs(entvars) do table.insert(newtable,v) end net.WriteTable({ent:EntIndex(),newtable}) end net.Send(ply) end end hook.Add("Think","metrostroi-debugger-think",think) local function OnEntRemove(ent) RemoveEnt(nil,ent) --Client doesn't get all removed ents, broadcast it manually to all net.Start("metrostroi-debugger-entremoved") net.WriteInt(ent:EntIndex(),16) net.Broadcast() end hook.Add("EntityRemoved","metrostroi-debugger-cleanup",OnEntRemove) hook.Add("PlayerDisconnected","metrstroi-debugger-plycleanup",RemoveEnt)