For the love of god give us reserved slots
Commander_Ghost
Join Date: 2003-05-02 Member: 15999Members
Love the game had a server up for a few days, and had some great feed back, however it is becoming extremely tiresome faced with queing for your own server. so far i have been home for 2 hrs and cant get in to my own server with out restarting the erver and alienating the people who are strting to hang round/ risk killing the community that are growing there.
Dev's please give us a way for res slots.
Oh and Awesome Job
Dev's please give us a way for res slots.
Oh and Awesome Job
Comments
+1
We need this feature.
Yes I do agree that we need this feature, but is it more vital to priorities a reserv slot feature rather than optimizing client/server? <b>No.</b>
Brian Nr.1 Has already confirm to me that this feature will be implemented later.
Yes I do agree that we need this feature, but is it more vital to priorities a reserv slot feature rather than optimizing client/server? <b>No.</b>
Brian Nr.1 Has already confirm to me that this feature will be implemented later.<!--QuoteEnd--></div><!--QuoteEEnd-->
while i agree optimizing should the very ****ing first priority, i dun think allowing reserve slot would take much afford...
As far as coding, I too am a coder. If I approached this then a quick method would be a whitelist of steam IDs that can join the last X reserved slots. So you have a CVAR for how many reserved slots (out of the normal amount) and a stringlist of steamids. Then only let the whitelist join the last X slots. Doesnt sound hard to me - no client artwork changes, all serverside changes. Since it is optional then no historical server config errors - a minor point release that doesnt need to force client consistency version check.
If you wanted to have an "admin joining so kick a player off" then it gets more complicated.
Exactly! Just have 1 or 2 hidden player slots that can only be filled by admins. People leaving will eventually put the server back down to the original number of players, and nobody is affected. Simple and elegant.
Actually, being a programmer who's actually made a reserved slots system for NS2, it's not that difficult. It would probably be few hours tops, and some testing. Most of the time I spent was learning how the game handled connections, so maybe even less time.
But they do have bigger fish to fry right now.
I'm actually pretty happy with my solution, the only thing I want now is a way to set a reason for the kick so players don't just see "Kicked".
Thankfully that's probably a very easy fix.
Example, if a user joins the "full" server (not yet knowing how to fake the player count report like Voogru), rather than kicking them instantly, give them a 30 second grace period where the server notifies them via psay a few times that they're going to be kicked (and why).
It's not ideal, but it's better than nothing.
Though that's extra work for the person with the slot. I just want it a connect and done.
<!--quoteo(post=2014153:date=Nov 7 2012, 11:19 AM:name=Guspaz)--><div class='quotetop'>QUOTE (Guspaz @ Nov 7 2012, 11:19 AM) <a href="index.php?act=findpost&pid=2014153"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Example, if a user joins the "full" server (not yet knowing how to fake the player count report like Voogru)<!--QuoteEnd--></div><!--QuoteEEnd-->
You don't really absolutely need the under-reporting, though it does help against people constantly trying to join only to be kicked after waiting for the map to load.
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->rather than kicking them instantly, give them a 30 second grace period where the server notifies them via psay a few times that they're going to be kicked (and why).<!--QuoteEnd--></div><!--QuoteEEnd-->
Probably not a bad idea. Though it would require a bit more code, for example, if some other player leaves before they are kicked bringing the player count back down.
The external app is for the server, not the player, and the buffer period is to notify a player who is about to be kicked (to give them time to read the message explaining why they're about to be kicked). The external tool would have a list of reserved slot holders as steamids. The reserved slot holder would need to do nothing except connect to the server, and the tool would know that somebody else needs to be kicked to make room for them.
<!--quoteo(post=2014872:date=Nov 7 2012, 10:43 PM:name=voogru)--><div class='quotetop'>QUOTE (voogru @ Nov 7 2012, 10:43 PM) <a href="index.php?act=findpost&pid=2014872"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->You don't really absolutely need the under-reporting, though it does help against people constantly trying to join only to be kicked after waiting for the map to load.<!--QuoteEnd--></div><!--QuoteEEnd-->
I would think it would be a fairly constant thing; a server would show up as, for example, 16/18, and even though it's really full (and anybody who joins will be kicked within 30 seconds to keep the server at 16), people are going to think it's not full and keep joining. The under-reporting would save a ton of headaches on the part of those people trying to join.
Unfortunately, I dug around in the lua source, and I can't find anything related to responding to the UDP queries (or anything remotely related to managing player counts), so I'm guessing this is all done in the executable, and that you're doing some sort of packet mangling on the router. Although if that's the case, it wouldn't work for us since we're using a server host rather than running the hardware ourselves.
In any case, short of a standalone release from you to do the under-reporting (assuming you're doing something else like patching/hooking/proxying/etc), it's probably off the table for the rest of us.
Under-reporting isn't strictly speaking necessary, but it's a rather critical feature that can't be implemented by ordinary means, leaving the current choice for reserved slots as being to live with the problem or give up on reserved slots.
<!--quoteo(post=2014872:date=Nov 7 2012, 10:43 PM:name=voogru)--><div class='quotetop'>QUOTE (voogru @ Nov 7 2012, 10:43 PM) <a href="index.php?act=findpost&pid=2014872"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Probably not a bad idea. Though it would require a bit more code, for example, if some other player leaves before they are kicked bringing the player count back down.<!--QuoteEnd--></div><!--QuoteEEnd-->
Well, it's all extra code since all of this is living in a separate executable (not even necessarily on the same physical box as the server process) that's periodically polling the server to see if it has to take any action. Certainly it would make sense to re-verify the condition of the server right before taking such action; the tool should be REALLY certain that it has to kick somebody before it does so, since it's such a disruptive action. The advantage from my perspective is that such a tool can do various things for the server (from reserved slots to MOTD to acting as something of an IRC-style bot responding to player inquiries/commands) without ever having to worry about consistency checking or whitelisting.
<!--quoteo(post=1966595:date=Aug 25 2012, 07:20 AM:name=player)--><div class='quotetop'>QUOTE (player @ Aug 25 2012, 07:20 AM) <a href="index.php?act=findpost&pid=1966595"><{POST_SNAPBACK}></a></div><div class='quotemain'><!--quotec-->Here are the contents of a PM I sent earlier, describing my (perfected) method in more detail:
I did manage to perfect reserved-slots, but it required quite a bit of work to accomplish, and may be a bit out of most modders' league.
What I did is disable NS2's query-responder, replace it with my own on a different port, and build a mastergameserver-communicator on the same socket to make it show up in the serverbrowser-list. The code-base is in shambles at the moment, because I was rewriting the whole thing at the time I decided to stop due to lack of motivation, so I can't really help you out by providing snippets.
What you need to do:
Disable NS2's query-responder (using the <a href="http://hg.opensteamworks.org/open-steamworks/src" target="_blank">Steam-API</a>).
Learn how to use the <a href="http://www.lua.org/pil/index.html#P4" target="_blank">Lua C-API</a> (or use something like Luabind)
Build a query-responder using the <a href="https://developer.valvesoftware.com/wiki/Server_queries" target="_blank">SourceEngine-protocol</a>.
Build a MasterServer-Communicator (<a href="https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol#Game_server_to_master_server" target="_blank">protocol</a>).
It's a ton of work to do from scratch, the unreleased GameOvermind is over 100.000 lines large using a dozen libraries. It's probably easier to maybe ask Max (or another UWE developer) to just introduce a SetMaxSlots-function to the Lua-scripts.<!--QuoteEnd--></div><!--QuoteEEnd-->
Really I think something like iptables+netsed to just twiddle the player count/max in the master server and query response packets as they go out would be enormously simpler, but that requires hosting your own hardware so that you can actually mess about on the router.
<!--quoteo--><div class='quotetop'>QUOTE </div><div class='quotemain'><!--quotec-->It's a ton of work to do from scratch, the unreleased GameOvermind is over 100.000 lines large using a dozen libraries. It's probably easier to maybe ask Max (or another UWE developer) to just introduce a SetMaxSlots-function to the Lua-scripts.<!--QuoteEnd--></div><!--QuoteEEnd-->
Wow. He did it the really hard way.
My way is about 300 lines of code. On top of that, I could still improve it a bit and bring it down to less than 100 lines, simply because I made a mistake early on that I only discovered after writing it.
Locate <i>Player_Server.lua</i> and add below <i>Script.Load("lua/Gamerules.lua")</i>
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->Script.Load("lua/ConfigFileUtility.lua")
local MAXPLAYER_SLOTS = 19
local serverAdminFileName = "ServerAdmin.json"
local defaultConfig = {
groups =
{
admin_group = { type = "disallowed", commands = { } },
mod_group = { type = "allowed", commands = { "sv_reset", "sv_ban" } }
},
users =
{
NsPlayer = { id = 10000001, groups = { "admin_group" } }
}
}
WriteDefaultConfigFile(serverAdminFileName, defaultConfig)
local adminsettings = LoadConfigFile(serverAdminFileName) or defaultConfig<!--c2--></div><!--ec2-->
In the function <i>Player:OnClientConnect(client)</i> add to the end:
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1--> /**
* OneEyed - Reserved Slot
*/
self.rslot = 0
//Save to client if they have rslot
local steamId = client:GetUserId()
for name, user in pairs(adminsettings.users) do
if user.id == steamId then
self.rslot = 1
break
end
end
//If server full, do our rslot kicking
local players = Shared.GetEntitiesWithClassname("Player")
if players:GetSize() >= MAXPLAYER_SLOTS then
//user doesn't have rslot, don't allow them to join
if self.rslot == 0 then
ServerAdminPrint(self:GetClient(), "Server is full. No reserve slot found for you. (0)")
Server.DisconnectClient(client)
else
//Partition the player list into two groups
local firstlist = {}
local secondlist = {}
for index, player in ientitylist(players) do
if player ~= self then
if player:isa("Spectator") or player:GetTeamNumber() == kTeamReadyRoom then
if player.rslot == 0 then
table.insert(firstlist, player)
end
else
if player.rslot == 0 then
table.insert(secondlist, player)
end
end
end
end
//If there is no one as spectator or in readyroom, use the in-game players
local thelist = firstlist
if #thelist == 0 then
thelist = secondlist
end
//Everyone has rslot, we cannot allow anyone else
if #thelist == 0 then
ServerAdminPrint(self:GetClient(), "Server is full. No reserve slot found for you. (1)")
Server.DisconnectClient(client)
return
end
//Find a random player to kick, make sure they are not commander
local playercnt = #thelist
local foundplayer = false
local theplayer
while not foundplayer do
theplayer = thelist[math.random(1, playercnt)]
if not theplayer:isa("Commander") then
foundplayer = true
end
end
//Disconnect the player who lost the lottery
if theplayer ~= nil then
ServerAdminPrint(self:GetClient(), "Server is full. No reserve slot found for you. (2)")
Server.DisconnectClient(theplayer:GetClient())
end
end
end<!--c2--></div><!--ec2-->
That's not how reserved slots work. When a reserved slot player joins, they take up that 16th slot only until the server kicks somebody else to take the server back down to 15.
This. More like hidden slots than just reserved. If the server is at 16/16 and someone with a reserved slot joins then the server would be 17/16 until someone leaves which would bring it back down to 16/16. I'd prefer that nobody gets kicked at any time for someone else to join.
It's actually not as bad as that... The server would be at 17/16 (well, you'd probably report it temporarily as 17/17 to avoid issues), and you just wait for somebody to leave, at which point that reserved slot is now free. Server is reported as 16/16 again, and only reserved slot players can join. Works with one or two extra slots, and then you rely on people leaving instead of kicking. Works slower such that reserved slots are not available all the time, but they would probably be available for most times. On most servers, it would probably only take twenty or thirty minutes for a slot to clear up, so you could afford to have more players than slots.