Ulysses
General => Developers Corner => Topic started by: ZGMATT on February 19, 2016, 08:25:00 PM
-
So i am one of the developers of a Dark RP server, and the Owner has asked me to make a "punish" command to save time, which needs to jail someone, and warn them.
only thing is.... i cant get it to work. and i have no clue what I'm doing wrong.
here's my lua filewhich is really just an edited version of ulx jail:
local doJail
local jailableArea
function ulx.punish( calling_ply, target_plys, seconds, should_unjail )
local affected_plys = {}
for i=1, #target_plys do
local v = target_plys[ i ]
if not should_unjail then
if ulx.getExclusive( v, calling_ply ) then
ULib.tsayError( calling_ply, ulx.getExclusive( v, calling_ply ), true )
elseif not jailableArea( v:GetPos() ) then
ULib.tsayError( calling_ply, v:Nick() .. " is not in an area where a jail can be placed!", true )
else
doJail( v, seconds )
table.insert( affected_plys, v )
end
elseif v.jail then
v.jail.unjail()
v.jail = nil
table.insert( affected_plys, v )
end
end
if not should_unjail then
local str = "#A punished #T"
if seconds > 0 then
str = str .. " for #i seconds"
end
ulx.fancyLogAdmin( calling_ply, str, affected_plys, seconds )
else
ulx.fancyLogAdmin( calling_ply, "#A unjailed #T", affected_plys )
end
end
local punish = ulx.command( "Utility", "ulx punish", ulx.punish, "!punish" )
punish:addParam{ type=ULib.cmds.PlayersArg }
punish:addParam{ type=ULib.cmds.NumArg, min=0, default=0, hint="seconds, 0 is forever", ULib.cmds.round, ULib.cmds.optional }
punish:addParam{ type=ULib.cmds.BoolArg, invisible=true }
punish:defaultAccess( ULib.ACCESS_ADMIN )
punish:help( "punishes target(s)." )
and heres the error i get everytime i use the command on myself in my sp trying to test to get it to work:
addons/admin menu/lua/autorun/util.lua:11: attempt to call upvalue 'jailableArea' (a nil value)matthew: !punish matt 5
-
in line 2 you define jailableArea as a variable
in line 11, you're trying to call it as a function.
You defined but never initialized it, so it's still nil.
-
If you look in fun.lua in ULX, around line 498 you'll notice that we initialize jailableArea as a function that returns a boolean when passed a vector. You'd need to do the same in your file since the function set up in fun.lua is in the local scope and can't be seen by anything outside that file.
-
thanks ill fix it now! this is really good news since i just got a deadline to meet... hopefully it will work by then!
EDIT: jail part works, now i just gotta get the warn part working and i can go do other
EDIT 2: so now i got it running a concommand to warn the target, and i get this in the rcon: Lua Error: addons/e - awarn2/lua/autorun/server/sv_awarn.lua:252: attempt to get length of local 'args' (a nil value)
heres the current lua file: local doJail
local jailableArea
function ulx.punish( calling_ply, target_plys, seconds, should_unjail )
local affected_plys = {}
for i=1, #target_plys do
local v = target_plys[ i ]
if not should_unjail then
if ulx.getExclusive( v, calling_ply ) then
ULib.tsayError( calling_ply, ulx.getExclusive( v, calling_ply ), true )
elseif not jailableArea( v:GetPos() ) then
ULib.tsayError( calling_ply, v:Nick() .. " is not in an area where a jail can be placed!", true )
else
doJail( v, seconds )
table.insert( affected_plys, v )
end
elseif v.jail then
v.jail.unjail()
v.jail = nil
table.insert( affected_plys, v )
end
end
function formatReason()
GM:PlayerSay( calling_ply, text, teamChat )
reas = string.match( text, "%u", 1 )
warnargs = { v:Nick(), reas }
warnargsstr = string.Implode( warnargs, " " )
end
concommand.Run( calling_ply, "awarn_warn", warnargs, warnargsstr )
if not should_unjail then
local str = "#A punished #T"
if seconds > 0 then
str = str .. " for #i seconds"
end
ulx.fancyLogAdmin( calling_ply, str, affected_plys, seconds )
else
ulx.fancyLogAdmin( calling_ply, "#A unjailed #T", affected_plys )
end
end
local punish = ulx.command( "Utility", "ulx punish", ulx.punish, "!punish" )
punish:addParam{ type=ULib.cmds.PlayersArg }
punish:addParam{ type=ULib.cmds.NumArg, min=0, default=0, hint="seconds, 0 is forever", ULib.cmds.round, ULib.cmds.optional }
punish:addParam{ type=ULib.cmds.BoolArg, invisible=true }
punish:defaultAccess( ULib.ACCESS_ADMIN )
punish:help( "punishes target(s)." )
local function jailCheck()
local remove_timer = true
local players = player.GetAll()
for i=1, #players do
local ply = players[ i ]
if ply.jail then
remove_timer = false
end
if ply.jail and (ply.jail.pos-ply:GetPos()):LengthSqr() >= 6500 then
ply:SetPos( ply.jail.pos )
if ply.jail.jail_until then
doJail( ply, ply.jail.jail_until - CurTime() )
else
doJail( ply, 0 )
end
end
end
if remove_timer then
timer.Remove( "ULXJail" )
end
end
jailableArea = function( pos )
entList = ents.FindInBox( pos - Vector( 35, 35, 5 ), pos + Vector( 35, 35, 110 ) )
for i=1, #entList do
if entList[ i ]:GetClass() == "trigger_remove" then
return false
end
end
return true
end
local mdl1 = Model( "models/props_building_details/Storefront_Template001a_Bars.mdl" )
local jail = {
{ pos = Vector( 0, 0, -5 ), ang = Angle( 90, 0, 0 ), mdl=mdl1 },
{ pos = Vector( 0, 0, 97 ), ang = Angle( 90, 0, 0 ), mdl=mdl1 },
{ pos = Vector( 21, 31, 46 ), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( 21, -31, 46 ), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( -21, 31, 46 ), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( -21, -31, 46), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( -52, 0, 46 ), ang = Angle( 0, 0, 0 ), mdl=mdl1 },
{ pos = Vector( 52, 0, 46 ), ang = Angle( 0, 0, 0 ), mdl=mdl1 },
}
doJail = function( v, seconds )
if v.jail then -- They're already jailed
v.jail.unjail()
end
if v:InVehicle() then
local vehicle = v:GetParent()
v:ExitVehicle()
vehicle:Remove()
end
-- Force other players to let go of this player
if v.physgunned_by then
for ply, v in pairs( v.physgunned_by ) do
if ply:IsValid() and ply:GetActiveWeapon():IsValid() and ply:GetActiveWeapon():GetClass() == "weapon_physgun" then
ply:ConCommand( "-attack" )
end
end
end
if v:GetMoveType() == MOVETYPE_NOCLIP then -- Take them out of noclip
v:SetMoveType( MOVETYPE_WALK )
end
local pos = v:GetPos()
local walls = {}
for _, info in ipairs( jail ) do
local ent = ents.Create( "prop_physics" )
ent:SetModel( info.mdl )
ent:SetPos( pos + info.pos )
ent:SetAngles( info.ang )
ent:Spawn()
ent:GetPhysicsObject():EnableMotion( false )
ent:SetMoveType( MOVETYPE_NONE )
ent.jailWall = true
table.insert( walls, ent )
end
local key = {}
local function unjail()
if not v:IsValid() or not v.jail or v.jail.key ~= key then -- Nope
return
end
for _, ent in ipairs( walls ) do
if ent:IsValid() then
ent:DisallowDeleting( false )
ent:Remove()
end
end
if not v:IsValid() then return end -- Make sure they're still connected
v:DisallowNoclip( false )
v:DisallowMoving( false )
v:DisallowSpawning( false )
v:DisallowVehicles( false )
ulx.clearExclusive( v )
ulx.setNoDie( v, false )
v.jail = nil
end
if seconds > 0 then
timer.Simple( seconds, unjail )
end
local function newWall( old, new )
table.insert( walls, new )
end
for _, ent in ipairs( walls ) do
ent:DisallowDeleting( true, newWall )
ent:DisallowMoving( true )
end
v:DisallowNoclip( true )
v:DisallowMoving( true )
v:DisallowSpawning( true )
v:DisallowVehicles( true )
v.jail = { pos=pos, unjail=unjail, key=key }
if seconds > 0 then
v.jail.jail_until = CurTime() + seconds
end
ulx.setExclusive( v, "in jail" )
ulx.setNoDie( v, true )
timer.Create( "ULXJail", 1, 0, jailCheck )
end
local function jailDisconnectedCheck( ply )
if ply.jail then
ply.jail.unjail()
end
end
hook.Add( "PlayerDisconnected", "ULXJailDisconnectedCheck", jailDisconnectedCheck, HOOK_MONITOR_HIGH )
local function playerPickup( ply, ent )
if CLIENT then return end
if ent:IsPlayer() then
ent.physgunned_by = ent.physgunned_by or {}
ent.physgunned_by[ ply ] = true
end
end
hook.Add( "PhysgunPickup", "ulxPlayerPickupJailCheck", playerPickup, HOOK_MONITOR_HIGH )
local function playerDrop( ply, ent )
if CLIENT then return end
if ent:IsPlayer() and ent.physgunned_by then
ent.physgunned_by[ ply ] = nil
end
end
hook.Add( "PhysgunDrop", "ulxPlayerDropJailCheck", playerDrop )
btw im using a dev server so thats why the error showed up in rcon
EDIT 3: before i reversed the implode function this is what showed up in rcon:
Lua Error: addons/admin menu/lua/autorun/util.lua:36: bad argument #1 to 'Implode' (table expected, got nil)
-
I don't think it's a good idea to set the GM:PlayerSay hook, and it's an even worse idea to use all globals inside it. Why don't you just add an extra "reason" parameter to the command?
string.Implode is meant to turn a string into a table, string.Explode is meant to turn a table into a string. You're using string.Implode where you should be using string.Explode, but I think you might have figured that out by now.
As for why AWarn2 is throwing an error message, I couldn't tell you. Mr. President may be able to shed some more light on it seeing as he made it.
edit:
(http://wiki.garrysmod.com/favicon.ico) concommand.Run (http://wiki.garrysmod.com/page/concommand/Run):
(http://i.imgur.com/UhTZXZe.png)
You should be using (http://wiki.garrysmod.com/favicon.ico) Global.RunConsoleCommand (http://wiki.garrysmod.com/page/Global/RunConsoleCommand) instead.
The reason AWarn2 is (probably) giving you an error is because you aren't passing concommand.Run the correct arguments. Just use RunConsoleCommand( "awarn_warn", "PlayerName", "Reason" ).
-
alright, almost got it now all thats happening now is this: Lua Error: addons/admin menu/lua/autorun/util.lua:38: attempt to call method 'Nick' (a nil value)
heres the code:
local doJail
local jailableArea
function ulx.punish( calling_ply, target_plys, seconds, should_unjail )
local affected_plys = {}
for i=1, #target_plys do
local v = target_plys[ i ]
if not should_unjail then
if ulx.getExclusive( v, calling_ply ) then
ULib.tsayError( calling_ply, ulx.getExclusive( v, calling_ply ), true )
elseif not jailableArea( v:GetPos() ) then
ULib.tsayError( calling_ply, v:Nick() .. " is not in an area where a jail can be placed!", true )
else
doJail( v, seconds )
table.insert( affected_plys, v )
end
elseif v.jail then
v.jail.unjail()
v.jail = nil
table.insert( affected_plys, v )
end
end
function formatReason()
GM:PlayerSay( calling_ply, text, teamChat )
reas = string.match( text, "%u", 1 )
reason = string.lower( reas )
end
for i=1, #target_plys do
local v = target_plys[ i ]
RunConsoleCommand( "awarn_warn", target_plys:Nick(), reason )
if not should_unjail then
local str = "#A punished #T"
if seconds > 0 then
str = str .. " for #i seconds"
end
ulx.fancyLogAdmin( calling_ply, str, affected_plys, seconds )
else
ulx.fancyLogAdmin( calling_ply, "#A unjailed #T", affected_plys )
end
end
local punish = ulx.command( "Utility", "ulx punish", ulx.punish, "!punish" )
punish:addParam{ type=ULib.cmds.PlayersArg }
punish:addParam{ type=ULib.cmds.NumArg, min=0, default=0, hint="seconds, 0 is forever", ULib.cmds.round, ULib.cmds.optional }
punish:addParam{ type=ULib.cmds.BoolArg, invisible=true }
punish:defaultAccess( ULib.ACCESS_ADMIN )
punish:help( "punishes target(s)." )
local function jailCheck()
local remove_timer = true
local players = player.GetAll()
for i=1, #players do
local ply = players[ i ]
if ply.jail then
remove_timer = false
end
if ply.jail and (ply.jail.pos-ply:GetPos()):LengthSqr() >= 6500 then
ply:SetPos( ply.jail.pos )
if ply.jail.jail_until then
doJail( ply, ply.jail.jail_until - CurTime() )
else
doJail( ply, 0 )
end
end
end
if remove_timer then
timer.Remove( "ULXJail" )
end
end
jailableArea = function( pos )
entList = ents.FindInBox( pos - Vector( 35, 35, 5 ), pos + Vector( 35, 35, 110 ) )
for i=1, #entList do
if entList[ i ]:GetClass() == "trigger_remove" then
return false
end
end
return true
end
local mdl1 = Model( "models/props_building_details/Storefront_Template001a_Bars.mdl" )
local jail = {
{ pos = Vector( 0, 0, -5 ), ang = Angle( 90, 0, 0 ), mdl=mdl1 },
{ pos = Vector( 0, 0, 97 ), ang = Angle( 90, 0, 0 ), mdl=mdl1 },
{ pos = Vector( 21, 31, 46 ), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( 21, -31, 46 ), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( -21, 31, 46 ), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( -21, -31, 46), ang = Angle( 0, 90, 0 ), mdl=mdl1 },
{ pos = Vector( -52, 0, 46 ), ang = Angle( 0, 0, 0 ), mdl=mdl1 },
{ pos = Vector( 52, 0, 46 ), ang = Angle( 0, 0, 0 ), mdl=mdl1 },
}
doJail = function( v, seconds )
if v.jail then -- They're already jailed
v.jail.unjail()
end
if v:InVehicle() then
local vehicle = v:GetParent()
v:ExitVehicle()
vehicle:Remove()
end
-- Force other players to let go of this player
if v.physgunned_by then
for ply, v in pairs( v.physgunned_by ) do
if ply:IsValid() and ply:GetActiveWeapon():IsValid() and ply:GetActiveWeapon():GetClass() == "weapon_physgun" then
ply:ConCommand( "-attack" )
end
end
end
if v:GetMoveType() == MOVETYPE_NOCLIP then -- Take them out of noclip
v:SetMoveType( MOVETYPE_WALK )
end
local pos = v:GetPos()
local walls = {}
for _, info in ipairs( jail ) do
local ent = ents.Create( "prop_physics" )
ent:SetModel( info.mdl )
ent:SetPos( pos + info.pos )
ent:SetAngles( info.ang )
ent:Spawn()
ent:GetPhysicsObject():EnableMotion( false )
ent:SetMoveType( MOVETYPE_NONE )
ent.jailWall = true
table.insert( walls, ent )
end
local key = {}
local function unjail()
if not v:IsValid() or not v.jail or v.jail.key ~= key then -- Nope
return
end
for _, ent in ipairs( walls ) do
if ent:IsValid() then
ent:DisallowDeleting( false )
ent:Remove()
end
end
if not v:IsValid() then return end -- Make sure they're still connected
v:DisallowNoclip( false )
v:DisallowMoving( false )
v:DisallowSpawning( false )
v:DisallowVehicles( false )
ulx.clearExclusive( v )
ulx.setNoDie( v, false )
v.jail = nil
end
if seconds > 0 then
timer.Simple( seconds, unjail )
end
local function newWall( old, new )
table.insert( walls, new )
end
for _, ent in ipairs( walls ) do
ent:DisallowDeleting( true, newWall )
ent:DisallowMoving( true )
end
v:DisallowNoclip( true )
v:DisallowMoving( true )
v:DisallowSpawning( true )
v:DisallowVehicles( true )
v.jail = { pos=pos, unjail=unjail, key=key }
if seconds > 0 then
v.jail.jail_until = CurTime() + seconds
end
ulx.setExclusive( v, "in jail" )
ulx.setNoDie( v, true )
timer.Create( "ULXJail", 1, 0, jailCheck )
end
local function jailDisconnectedCheck( ply )
if ply.jail then
ply.jail.unjail()
end
end
hook.Add( "PlayerDisconnected", "ULXJailDisconnectedCheck", jailDisconnectedCheck, HOOK_MONITOR_HIGH )
local function playerPickup( ply, ent )
if CLIENT then return end
if ent:IsPlayer() then
ent.physgunned_by = ent.physgunned_by or {}
ent.physgunned_by[ ply ] = true
end
end
hook.Add( "PhysgunPickup", "ulxPlayerPickupJailCheck", playerPickup, HOOK_MONITOR_HIGH )
local function playerDrop( ply, ent )
if CLIENT then return end
if ent:IsPlayer() and ent.physgunned_by then
ent.physgunned_by[ ply ] = nil
end
end
hook.Add( "PhysgunDrop", "ulxPlayerDropJailCheck", playerDrop ) end
-
target_plys is a table of players. You have to run Nick() on each player in the table, not on the table itself.
-
If you're still having trouble with calling any of the awarn function, please post in the awarn2 thread and I can help you out.