Facepunch / garrysmod-issues

Garry's Mod issue tracker
141 stars 56 forks source link

NW2Vars Breaks under certain conditions #5455

Open RaphaelIT7 opened 1 year ago

RaphaelIT7 commented 1 year ago

Details

The NW2 System seems to break clientside, if you create the same entity twice but delayed by a few ticks and then creating an Entity that is based on that entity. I don't know how to describe it the best, but it seems like the Client gets somehow confused with the NW2 Vars, and starts screwing them up. The example provided shows the Entity class changing and the same NW2Var getting updated multiple times clientside. It can also happen that the NW2Vars of other entities get set on the Bugged one, or the other way around.

This Bug won't exist, if you host the server. (But only for you.)

Steps to reproduce

Files needed

You can create all files yourself, or you could just download the folder from this repo

entities/testing.lua

if SERVER then AddCSLuaFile() end

ENT.Type = "anim"
function ENT:NW()
    self:SetNW2String("Baum", "Haus")
    self:SetNW2Int("Hi", 1)
end

function ENT:Initialize()
    self:SetModel("models/props_junk/PlasticCrate01a.mdl")
    self:NW()
end

entites/testing_2.lua

if SERVER then AddCSLuaFile() end

ENT.Type = "anim"
ENT.Base = "testing"

function ENT:NW()
    self:SetNW2String("Test2", "NW2-Bug")
end

autorun/bug.lua

function BreakNW2(stop)
    local ent = ents.Create("testing")
    ent:Spawn()

    timer.Simple(1, function()
        ent:Remove()
        if !stop then
            BreakNW2(true)
        end

        timer.Simple(0.5, function()
            local ent2 = ents.Create("testing_2")
            ent2:Spawn()
            timer.Simple(1, function()
                ent2:Remove()
            end)
        end)
    end)
end

hook.Add("PlayerInitialSpawn", "", function()
    timer.Simple(5, function()
        BroadcastLua([[hook.Add("EntityNetworkedVarChanged", "", print)]])

        BreakNW2(false)
    end)
end)

Five seconds after spawning, you're going to see something like this in your console:

Entity [85][testing]    Baum    nil Haus -- First Entity
Entity [85][testing]    Hi  nil 1
Entity [89][testing]    Baum    nil Haus -- Second Entity
Entity [89][testing]    Hi  nil 1
Entity [90][testing_2]  Test2   nil NW2-Bug -- Fist Entity based of the testing Entity
Entity [85][testing_2]  Test2   nil NW2-Bug -- Second Entity based of the testing Entity. (This one will break)
Entity [85][testing]    Baum    nil Haus
Entity [85][testing]    Hi  nil 1
Entity [85][testing_2]  Test2   nil NW2-Bug
Entity [85][testing]    Baum    nil Haus
Entity [85][testing]    Hi  nil 1
Entity [85][testing_2]  Test2   nil NW2-Bug
Entity [85][testing]    Baum    nil Haus
Entity [85][testing]    Hi  nil 1
Entity [85][testing_2]  Test2   nil NW2-Bug
RaphaelIT7 commented 4 months ago

It should be noted that hosting a local server and then connecting to the server allows you to easily reproduce it. Maybe this makes it easier to find the cause.

RaphaelIT7 commented 3 months ago

This seems to actually affect all entities. Not just Lua ones like first described, which makes this a far bigger issue than first anticipated :/

Example code:

hook.Add("EntityNetworkedVarChanged", "Example", print)
if CLIENT then return end

function BreakNW2(stop)
    local ent = ents.Create("prop_physics")
    ent:SetModel("models/props_c17/oildrum001.mdl")
    ent:Spawn()
    ent:SetNW2String("Example-1", "Hello")

    timer.Simple(1, function()
        ent:Remove()
        if !stop then
            BreakNW2(true)
        end

        timer.Simple(0.5, function()
            local ent2 = ents.Create("prop_physics")
            ent2:SetModel("models/props_c17/oildrum001.mdl")
            ent2:Spawn()
            ent2:SetNW2String("Example-2", "World")
            timer.Simple(1, function()
                ent2:Remove()
            end)
        end)
    end)
end

if Entity(1) != NULL then
    BreakNW2(false)
end

hook.Add("PlayerInitialSpawn", "", function()
    timer.Simple(5, function()
        BreakNW2(false)
    end)
end)