• GlobalStrings get reset for no good reason - this makes absolutely no sense.
    8 replies, posted
I seriously cannot wrap my head around this. We've been trying to solve it pretty much all day, this makes absolutely no sense. We're trying to implement prop protection for our gamemode and running into technical problems. Here's what we're trying to do: 1. When a player spawns a prop, we SetNWString on it with key "EGOwner" and value of the creator's Unique ID. 2. When a player decides to share his props with someone (currently with /share chat command), we SetGlobalString with key ("EGShare_"..UniqueID) and value of _every_uniqueid_shared_with 3. When a player tries to use a tool on an entity, we check the entity's EGOwner NWString. If it's equal to the player's UniqueID, allow the tool. If not, check the EGOwner's share list using string.explode on GetGlobalString and, if the player's UniqueID is not in that table, disallow the tool. The problem we're running into is as follows: 1. Player A spawns a prop. 2. Player B tries to make a button on prop. It doesn't allow him (good). 3. Player A shares his prop with Player B. 4. Player B tries to make a button on the prop. It allows the tool (good). 5. Right now Player B can create as many buttons on the prop as he wants - nothing is broken. 6. Either player welds or ropes the prop to the floor. (world) 7. Player B tries to make a button on the prop. It doesn't work (!) 8. At this time, the Global String had somehow reset itself to "". 9. In some of our tests (but not all), the client's Global String was still showing the list (so the tool's ray showed up), but the server's version of the Global String had somehow reset. It makes no sense that the two got out of sync, since we only write to it on the server's side. Please help me debug this. All relevant code is in code blocks below. init.lua: [lua]AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include( "shared.lua" ) include( "entity_guard.lua" ) include( "undocatcher.lua" )[/lua] shared.lua: [lua]GM.Name = "Test Gamemode" GM.Author = "NeatNit" DeriveGamemode( "sandbox" ) function GM:Initialize() -- Do nothing. end[/lua] cl_init.lua: [lua]include( "shared.lua" ) include( "entity_guard.lua" )[/lua] undocatcher.lua: [lua] local oldfunc = undo.Finish --[[------------------------------------------------------------------------------ Catch undos - call the UndoCaught hook when a player did any undoable action. ---------------------------------------------------------------------------------]] function undo.Finish() local OUT = {} -- OUT = Old Undo Table for uid, undos in pairs(undo.GetTable() ) do OUT[uid] = table.GetKeys(undos) end oldfunc() -- Do the ACTUAL undo.Finish() local CUT = undo.GetTable() -- CUT = Current Undo Table for uid, undos in pairs(CUT) do for undokey, undodata in pairs(undos) do if !OUT[uid] or !table.HasValue(OUT[uid], undokey) then hook.Run( "UndoCaught", uid, undodata ) end end end end[/lua] entity_guard.lua: [lua]AddCSLuaFile() function GuardNewEntity(uid, undodata) for k, NewEntity in pairs(undodata["Entities"]) do if NewEntity then NewEntity:SetNWString("EGOwner", uid) print ("New entity spawned by " .. uid .. ":") print (NewEntity) print ("GetNWString (EGOwner) of entity is " .. NewEntity:GetNWString("EGOwner", "IDK")) end end end hook.Add("UndoCaught", "Guard New Entity", GuardNewEntity) function InterpretSays(sender, text, teamChat) local playerstable = player.GetHumans() if string.sub(text, 1, 7) == "/share " then guestname = string.sub(text, 8) for plynum, plydata in pairs(playerstable) do if guestname == (plydata:Nick()) then Share(sender, plydata) end end end if string.sub(text, 1, 9) == "/unshare " then guestname = string.sub(text, 10) for plynum, plydata in pairs(playerstable) do if guestname == (plydata:Nick()) then UnShare(sender, plydata) --And notify end end end if string.sub(text, 1, 11) == "/unshareall" then UnShareAll(sender) end return true end hook.Add("PlayerSay", "Triggers Team Sequence", InterpretSays) function Share(sender, plydata) local host = sender:UniqueID() local guest = plydata:UniqueID() local sharestring = GetGlobalString("EGShare_" .. host, "") local sharetable = string.Explode("_", GetGlobalString("EGShare_" .. host, "")) local newsharestring = sharestring .. "_" .. guest if plydata and sender then if !table.HasValue(sharetable, guest) then SetGlobalString("EGShare_" .. host, newsharestring) print (host .. " is now sharing with " .. guest) print ("Newly calculated newsharestring is now " .. newsharestring) print (host .. "'s global string is now " .. GetGlobalString("EGShare_" .. host, "IDK")) end end end function UnShare(sender, plydata) local host = sender:UniqueID() local guest = plydata:UniqueID() local sharestring = GetGlobalString("EGShare_" .. host, "") local sharetable = string.Explode("_", GetGlobalString("EGShare_" .. host, "")) if plydata and sender then if table.HasValue(sharetable, guest) then local newsharestring = string.Replace(sharestring, "_" .. guest, "") SetGlobalString("EGShare_" .. host, newsharestring) print (host .. " unshared " .. guest) print ("Newly calculated newsharestring is " .. newsharestring) print (host .. "'s global string is now " .. GetGlobalString("EGShare_" .. host, "IDK")) end end end function UnShareAll(sender) local host = sender:UniqueID() if sender then SetGlobalString("EGShare_" .. host, "") print (host .. " unshared all!") print (host .. "'s global string is now " .. GetGlobalString("EGShare_" .. host, "IDK")) end end function EGAllow(EGOwner, uid) local sharestring = GetGlobalString("EGShare_" .. EGOwner, "") local sharetable = string.Explode("_", GetGlobalString("EGShare_" .. EGOwner, "")) print (sharestring) PrintTable (sharetable) if EGOwner == uid then print ("cantooler is owner! allowing!") return true elseif table.HasValue(sharetable, uid) then print ("tooler's id exists in owners' global string! allowing!") return true else return false end end function GM:CanTool( ply , tr , tool ) local uid = ply:UniqueID() local tooldEnt = tr.Entity local EGOwner = tr.Entity:GetNWString("EGOwner", "nil") if IsValid(tooldEnt) and !EGAllow(EGOwner, uid) then return false elseif (tool == "remover") then return true else return true--AllowDisallow(uid) - Replace "true" when mergine end --[[ if (table.HasValue(bannedTools , tool)) then return false else Needs to include upper if statement when merging! end ]] return true end[/lua] I think this may be a gmod/engine bug. Any help is [b][i]HUGELY[/i][/b] appreciated. I think I'm about to pull my hair out.
Why the hell are you even using GlobalVars for this? Use NWVars, or better yet, net library or something. Are you testing this on Dev branch?
[QUOTE=Robotboy655;47041083]Why the hell are you even using GlobalVars for this? Use NWVars, or better yet, net library or something. Are you testing this on Dev branch?[/QUOTE] No, not the dev branch. Why wouldn't I use Global vars - what are they meant for then? I thought they were essentially there to save me the trouble of networking everything to the client by myself - a variable that is synced across server and all clients. I mean, I'm not going to argue with you. Using the net library is, in fact, what we're gonna do, so thanks for that tip. But why is THAT not working??
I have no idea why it does not work, maybe because GlobalVars are bad. They are supposed to be used for networking one global variable to clients. You should be using Player:SetNWString("ShareWith", str ) for example.
[QUOTE=Robotboy655;47041275]I have no idea why it does not work, maybe because GlobalVars are bad. They are supposed to be used for networking one global variable to clients. You should be using Player:SetNWString("ShareWith", str ) for example.[/QUOTE] its not working because he's trying to set a global variable on a players client. Using setGlobalAnything on client doesn't sync with the server for obvious reasons, same with network variables
[QUOTE=AJ10017;47041714]its not working because he's trying to set a global variable on a players client. Using setGlobalAnything on client doesn't sync with the server for obvious reasons, same with network variables[/QUOTE] He executes the functions that set the global var from a serverside only hook PlayerSay
TTT uses global vars for how many rounds are left, thats a good use. You wouldn't use a global var for player specific stuff
SetGlobal* = SetNW* on the world entity.
[QUOTE=Willox;47042460]SetGlobal* = SetNW* on the world entity.[/QUOTE] Okay, so that means the world's NWString gets, for some reason, reset every time something is constrained to it (we've noted rope and weld, not tried anything else). Sounds like a bug to me! Thanks a ton for the tips, Robotboy! I'd still like to know why you say "GlobalVars are bad", sounds like a strange thing to say without any basis. (assuming this bug didn't exist)
Sorry, you need to Log In to post a reply to this thread.