Accessing a variable from both client and init.lua
6 replies, posted
Basically I have a boolean called isTimerActive and what that does is basically checking if a bomb is ticking or not.
The issue i'm having is when change the timer in the client side the timer will only update on that specific client.
For instance when i plant the bomb it the timer still remains false for other users and they can plant it aswell. I've tried networking the thing but it just turns into a shitstorm back and fourth. Any ideas on how to make the variable "isTimerActive" more static and available anywhere, anytime for anyone to change?
Put the variable in the shared.lua file of the thing.
Assuming this is your bomb entity, use Entity/NetworkVar or NWVars. If not use net messages and keep track of this server side.
Indeed there are a few methods.
Create it in the shared realm and both server and client can access it
Use Entity/NetworkVar to access it specific to the entity.
Use the Net Library
Just a note that making a variable in the shared realm doesn't guarantee the variable will have the exact same value. If you're changing a timer on the clientside you will not affect anyone else's client, or the server equivalent value. You need to network the changes made clientside or make the change serverside and broadcast
The issue i'm having is when change the timer in the client side the timer will only update on that specific client.
The client shouldn't be setting values - you need to do this sort of thing from the server.
Lots of exploits happen because of developers trust clients to set values and then malicious people set arbitrary values that break things.
You should set the timer up in a server-side hook (such as ENT:Use()) and then set a NetworkVar to let all clients know about it.
Here is an example script:
AddCSLuaFile()
DEFINE_BASECLASS( "base_anim" )
ENT.PrintName = "Ticker"
ENT.Spawnable = true
function ENT:SetupDataTables()
-- Set up a networked value to store our timer end in
self:NetworkVar( "Float", 0, "BombTimer" );
end
if SERVER then
function ENT:Initialize()
self:SetModel( "models/weapons/w_c4.mdl" )
self:PhysicsInit( SOLID_VPHYSICS )
self:PhysWake()
-- Stops ENT:Use() being spammed, see http://wiki.garrysmod.com/page/Entity/SetUseType for more info
self:SetUseType( SIMPLE_USE )
end
function ENT:Use()
-- Let both the client and server know the bomb is active
self:SetBombTimer( CurTime() + 10 )
end
function ENT:Think()
local timer = self:GetBombTimer()
if timer == 0 then
-- Do nothing if the timer isn't running
return
elseif timer > CurTime() then
-- If the timer is in the future, there's nothing to do on the server
return
end
-- Boom
local effectdata = EffectData()
effectdata:SetOrigin( self:GetPos() )
util.Effect( "Explosion", effectdata, true, true )
-- Reset the timer. In real life you'd probably want to use self:Remove()
self:SetBombTimer( 0 )
end
else
ENT._NextTick = 0
function ENT:Think()
-- Do nothing if the timer isn't active
if self:GetBombTimer() == 0 then
return
end
-- Only beep every 0.2 seconds
local now = CurTime()
if now < self._NextTick then
return
end
self._NextTick = now + 0.2
-- Beep
self:EmitSound( "buttons/button15.wav" )
end
end
Thanks, i'll be sure to check it out
Sorry, you need to Log In to post a reply to this thread.