ULX votemap2 not changing map when run from init.lua
9 replies, posted
I'm trying to make it so that when someone on my game mode reaches the kill limit it starts a map vote using votemap2. It is working fine as far as starting the map vote for everyone with the maps I specified but even when the vote is successful the map still doesn't change. I'm thinking it may have something to do with the fact that when an admin starts a map vote using votemap2 the admin has to accept the results of the vote for the map to change. If you know how I can make this work then please let me know.
Thanks in advance.
Edit: I found out it is giving an error in rcon:
addons/ulx/lua/ulx/modules/sh/vote.lua:29: Tried to use a NULL entity!
here is the code from the ulx addon it is talking about:
[LUA]---------------
--Public vote--
---------------
if SERVER then ulx.convar( "voteEcho", "0", _, ULib.ACCESS_SUPERADMIN ) end -- Echo votes?
-- First, our helper function to make voting so much easier!
local voteInProgress
function ulx.doVote( title, options, callback, timeout, filter, noecho, ... )
timeout = timeout or 20
if voteInProgress then
Msg( "Error! ULX tried to start a vote when another vote was in progress!\n" )
return
end
if not options[ 1 ] or not options[ 2 ] then
Msg( "Error! ULX tried to start a vote without at least two options!\n" )
return
end
local voters = 0
local rp = RecipientFilter()
if not filter then
rp:AddAllPlayers()
voters = #player.GetAll()
else
for _, ply in ipairs( filter ) do
rp:AddPlayer( ply ) //<<<<This is line 29
voters = voters + 1
end
end
umsg.Start( "ulx_vote", rp )
umsg.String( title )
umsg.Short( timeout )
ULib.umsgSend( options )
umsg.End()
voteInProgress = { callback=callback, options=options, title=title, results={}, voters=voters, votes=0, noecho=noecho, args={...} }
timer.Create( "ULXVoteTimeout", timeout, 1, ulx.voteDone )
end[/LUA]
Sorry to bump this but I find it hard to believe that no one has an answer to this problem.
If anyone has an answer to this problem can you please give it to me?
Try deleting the admin check ?
Still haven't gotten an answer to this over a week later.
I counted line 29 to be " end"
Please give us the exact line of where the error is occurring. A common thing that can be done to bypass the a-ok message being sent to an admin, is if the vote was initially started by a NULL player ( The server / user with rcon connecting via out-side program ) you should let it go through.
Also, you haven't posted the contents of voteDone which I'm assuming is where the map would change; however is may not even be getting that far as it's halting at the error?
[QUOTE=Acecool;42386109]I counted line 29 to be " end"
Please give us the exact line of where the error is occurring. A common thing that can be done to bypass the a-ok message being sent to an admin, is if the vote was initially started by a NULL player ( The server / user with rcon connecting via out-side program ) you should let it go through.
Also, you haven't posted the contents of voteDone which I'm assuming is where the map would change; however is may not even be getting that far as it's halting at the error?[/QUOTE]
The code I posted is code straight off the ulx addon. If you do not have the addon to reference here is the entire file, all 370 lines of it.
[LUA]local CATEGORY_NAME = "Voting"
---------------
--Public vote--
---------------
if SERVER then ulx.convar( "voteEcho", "0", _, ULib.ACCESS_SUPERADMIN ) end -- Echo votes?
-- First, our helper function to make voting so much easier!
local voteInProgress
function ulx.doVote( title, options, callback, timeout, filter, noecho, ... )
timeout = timeout or 20
if voteInProgress then
Msg( "Error! ULX tried to start a vote when another vote was in progress!\n" )
return
end
if not options[ 1 ] or not options[ 2 ] then
Msg( "Error! ULX tried to start a vote without at least two options!\n" )
return
end
local voters = 0
local rp = RecipientFilter()
if not filter then
rp:AddAllPlayers()
voters = #player.GetAll()
else
for _, ply in ipairs( filter ) do
rp:AddPlayer( ply ) //<========================Line 29 believe it or not
voters = voters + 1
end
end
umsg.Start( "ulx_vote", rp )
umsg.String( title )
umsg.Short( timeout )
ULib.umsgSend( options )
umsg.End()
voteInProgress = { callback=callback, options=options, title=title, results={}, voters=voters, votes=0, noecho=noecho, args={...} }
timer.Create( "ULXVoteTimeout", timeout, 1, ulx.voteDone )
end
function ulx.voteCallback( ply, command, argv )
if not voteInProgress then
ULib.tsayError( ply, "There is not a vote in progress" )
return
end
if not argv[ 1 ] or not tonumber( argv[ 1 ] ) or not voteInProgress.options[ tonumber( argv[ 1 ] ) ] then
ULib.tsayError( ply, "Invalid or out of range vote." )
return
end
if ply.ulxVoted then
ULib.tsayError( ply, "You have already voted!" )
return
end
local echo = util.tobool( GetConVarNumber( "ulx_voteEcho" ) )
local id = tonumber( argv[ 1 ] )
voteInProgress.results[ id ] = voteInProgress.results[ id ] or 0
voteInProgress.results[ id ] = voteInProgress.results[ id ] + 1
voteInProgress.votes = voteInProgress.votes + 1
ply.ulxVoted = true -- Tag them as having voted
local str = ply:Nick() .. " voted for: " .. voteInProgress.options[ id ]
if echo and not voteInProgress.noecho then
ULib.tsay( _, str ) -- TODO, color?
end
ulx.logString( str )
if game.IsDedicated() then Msg( str .. "\n" ) end
if voteInProgress.votes >= voteInProgress.voters then
timer.Destroy( "ULXVoteTimeout" )
ulx.voteDone()
end
end
if SERVER then concommand.Add( "ulx_vote", ulx.voteCallback ) end
function ulx.voteDone()
local players = player.GetAll()
for _, ply in ipairs( players ) do -- Clear voting tags
ply.ulxVoted = nil
end
local vip = voteInProgress
voteInProgress = nil
ULib.pcallError( vip.callback, vip, unpack( vip.args, 1, 10 ) ) -- Unpack is explicit in length to avoid odd LuaJIT quirk.
end
-- End our helper functions
local function voteDone( t )
local results = t.results
local winner
local winnernum = 0
for id, numvotes in pairs( results ) do
if numvotes > winnernum then
winner = id
winnernum = numvotes
end
end
local str
if not winner then
str = "Vote results: No option won because no one voted!"
else
str = "Vote results: Option '" .. t.options[ winner ] .. "' won. (" .. winnernum .. "/" .. t.voters .. ")"
end
ULib.tsay( _, str ) -- TODO, color?
ulx.logString( str )
Msg( str .. "\n" )
end
function ulx.vote( calling_ply, title, ... )
if voteInProgress then
ULib.tsayError( calling_ply, "There is already a vote in progress. Please wait for the current one to end.", true )
return
end
ulx.doVote( title, { ... }, voteDone )
ulx.fancyLogAdmin( calling_ply, "#A started a vote (#s)", title )
end
local vote = ulx.command( CATEGORY_NAME, "ulx vote", ulx.vote, "!vote" )
vote:addParam{ type=ULib.cmds.StringArg, hint="title" }
vote:addParam{ type=ULib.cmds.StringArg, hint="options", ULib.cmds.takeRestOfLine, repeat_min=2, repeat_max=10 }
vote:defaultAccess( ULib.ACCESS_ADMIN )
vote:help( "Starts a public vote." )
local function voteMapDone2( t, changeTo, ply )
local shouldChange = false
if t.results[ 1 ] and t.results[ 1 ] > 0 then
ulx.logServAct( ply, "#A approved the votemap" )
shouldChange = true
else
ulx.logServAct( ply, "#A denied the votemap" )
end
if shouldChange then
ULib.consoleCommand( "changelevel " .. changeTo .. "\n" )
end
end
local function voteMapDone( t, argv, ply )
local results = t.results
local winner
local winnernum = 0
for id, numvotes in pairs( results ) do
if numvotes > winnernum then
winner = id
winnernum = numvotes
end
end
local ratioNeeded = GetConVarNumber( "ulx_votemap2Successratio" )
local minVotes = GetConVarNumber( "ulx_votemap2Minvotes" )
local str
local changeTo
if (#argv < 2 and winner ~= 1) or not winner or winnernum < minVotes or winnernum / t.voters < ratioNeeded then
str = "Vote results: Vote was unsuccessful."
else
str = "Vote results: Option '" .. t.options[ winner ] .. "' won, changemap pending approval. (" .. winnernum .. "/" .. t.voters .. ")"
-- Figure out the map to change to.
if #argv > 1 then
changeTo = t.options[ winner ]
else
changeTo = argv[ 1 ]
end
ulx.doVote( "Accept result and changemap to " .. changeTo .. "?", { "Yes", "No" }, voteMapDone2, 30000, { ply }, true, changeTo, ply )
end
ULib.tsay( _, str ) -- TODO, color?
ulx.logString( str )
if game.IsDedicated() then Msg( str .. "\n" ) end
end
function ulx.votemap2( calling_ply, ... )
local argv = { ... }
if voteInProgress then
ULib.tsayError( calling_ply, "There is already a vote in progress. Please wait for the current one to end.", true )
return
end
for i=2, #argv do
if ULib.findInTable( argv, argv[ i ], 1, i-1 ) then
ULib.tsayError( calling_ply, "Map " .. argv[ i ] .. " was listed twice. Please try again" )
return
end
end
if #argv > 1 then
ulx.doVote( "Change map to..", argv, voteMapDone, _, _, _, argv, calling_ply )
ulx.fancyLogAdmin( calling_ply, "#A started a votemap with options" .. string.rep( " #s", #argv ), ... )
else
ulx.doVote( "Change map to " .. argv[ 1 ] .. "?", { "Yes", "No" }, voteMapDone, _, _, _, argv, calling_ply )
ulx.fancyLogAdmin( calling_ply, "#A started a votemap for #s", argv[ 1 ] )
end
end
local votemap2 = ulx.command( CATEGORY_NAME, "ulx votemap2", ulx.votemap2, "!votemap2" )
votemap2:addParam{ type=ULib.cmds.StringArg, completes=ulx.maps, hint="map", error="invalid map \"%s\" specified", ULib.cmds.restrictToCompletes, ULib.cmds.takeRestOfLine, repeat_min=1, repeat_max=10 }
votemap2:defaultAccess( ULib.ACCESS_ADMIN )
votemap2:help( "Starts a public map vote." )
if SERVER then ulx.convar( "votemap2Successratio", "0.5", _, ULib.ACCESS_ADMIN ) end -- The ratio needed for a votemap2 to succeed
if SERVER then ulx.convar( "votemap2Minvotes", "3", _, ULib.ACCESS_ADMIN ) end -- Minimum votes needed for votemap2
local function voteKickDone2( t, target, time, ply, reason )
local shouldKick = false
if t.results[ 1 ] and t.results[ 1 ] > 0 then
ulx.logUserAct( ply, target, "#A approved the votekick against #T (" .. (reason or "") .. ")" )
shouldKick = true
else
ulx.logUserAct( ply, target, "#A denied the votekick against #T" )
end
if shouldKick then
if reason and reason ~= "" then
ULib.kick( target, "Vote kick successful. (" .. reason .. ")" )
else
ULib.kick( target, "Vote kick successful." )
end
No, but you haven't given us the exact line of the error. We know its' 29, but which line is 29?
[QUOTE=Acecool;42387296]No, but you haven't given us the exact line of the error. We know its' 29, but which line is 29?[/QUOTE]
Take a closer look at the code I marked line 29 with //<========================Line 29 believe it or not
I also marked which line is 29 in the original post in a similar way.
I did not see that, sorry!
Ok, so it's trying to use a ply that is either connecting or who has disconnected after the vote has started / where the player list was copied over. Or rp is nil; but if rp was nil it would report that AddPlayer function doesn't exist so you should be safe with assuming ply is nil.
Move line 29 down to 30, and on 29 add:
[lua]if ( !IsValid( ply ) ) then continue; end[/lua]
Sorry, you need to Log In to post a reply to this thread.