PDA

View Full Version : name , client id in menu



malyczolg
30th April 2013, 14:47
254
how add client id and name on red territory?

Cz3koladowyPotwor
30th April 2013, 16:01
it is too hard for your level :)

kung foo man
30th April 2013, 16:22
You can prepare 64 scriptMenuResponse-Buttons and 64 Textfields, which display 64 DVar's.

Thats the basic idea, I guess you can already do it know, since you made that menu already.

malyczolg
30th April 2013, 16:48
how to do to read a player id and name?

dvar

self setClientCvar("id0", ID : ** , NAME : ** );

getEntityNumber();
player.name

Tally
1st May 2013, 07:17
The only way to show any variable on a menu is through text. And the usual way to do that is with the use of a dvar. And as Kung says, you would need as many dvars as there are players. So, if you have 64 players on your server, you need 64 dvars for the name, and 64 dvars for the client entity number. And of course, you will need 128 itemDef{} to show them all (64 for the names, and 64 for the client entity number).

Now, once you've got all that set up, to show the player's name and his entity number, you have to save the values to a dvar. Then set the dvar in the menu itemDef{}:

Example:

Set the Dvars:


players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
player = players[i];

if( player getEntityNumber() == i )
{
player setClientCvar( "ui_player_name_" + i, player.name );
player setClientCvar( "ui_player_entNum_" + i, i );
}
}

Set the itemDef{}:


itemDef
{
name "player_name_1"
visible 1
rect 0 0 128 24
origin ORIGIN_POSITION1
forecolor 1.000 0.647 0.290 1
type ITEM_TYPE_BUTTON
dvar "ui_player_name_1"
textfont UI_FONT_NORMAL
textscale COUNT_SIZE
textstyle ITEM_TEXTSTYLE_SHADOWED
textaligny 20
textalignx 20
decoration
}



[php]itemDef
{
name "player_entNum_1"
visible 1
rect 0 0 128 24
origin ORIGIN_POSITION1
forecolor 1.000 0.647 0.290 1
type ITEM_TYPE_BUTTON
dvar "ui_player_entNum_1"
textfont UI_FONT_NORMAL
textscale COUNT_SIZE
textstyle ITEM_TEXTSTYLE_SHADOWED
textaligny 20
textalignx 20
decoration
}

malyczolg
1st May 2013, 10:01
itemDef
{
name p0
type ITEM_TYPE_BUTTON
style WINDOW_STYLE_FILLED
dvar "ui_player_name_1"
rect 195 76 190 11
visible 1
mouseEnter
{
play "mouse_over";
setitemcolor p0 backcolor 1 0 0 0.3
}
mouseExit
{
setitemcolor p0 backcolor 0 0 0 0
}
action
{
play "mouse_click";
scriptmenuresponse "0"
}
}



Callback_PlayerConnect()
{
players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
player = players[i];

if( player getEntityNumber() == i )
{
player setClientCvar( "ui_player_name_" + i, player.name );
player setClientCvar( "ui_player_entNum_" + i, i );
}
}
...

why not work ?

kung foo man
1st May 2013, 11:28
Any error message?

malyczolg
1st May 2013, 11:36
no , but if i add

player setClientCvar( "ui_player_name_" + i, "name :" player.name );

i dont have msg : name : **

Tally
1st May 2013, 17:12
itemDef
{
name p0
type ITEM_TYPE_BUTTON
style WINDOW_STYLE_FILLED
dvar "ui_player_name_1"
rect 195 76 190 11
visible 1
mouseEnter
{
play "mouse_over";
setitemcolor p0 backcolor 1 0 0 0.3
}
mouseExit
{
setitemcolor p0 backcolor 0 0 0 0
}
action
{
play "mouse_click";
scriptmenuresponse "0"
}
}



Callback_PlayerConnect()
{
players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
player = players[i];

if( player getEntityNumber() == i )
{
player setClientCvar( "ui_player_name_" + i, player.name );
player setClientCvar( "ui_player_entNum_" + i, i );
}
}
...

why not work ?

You wont be able to show the result of a dvar if you use the action{} element in an itemDef{}. Also, you aren't defining the font and fontstyle and size. It wont show unless you do that.

So, you will have to make 2 itemDef{} and use them as one. What I usually do is use the one with the action{} element to show the other, like this:



itemDef
{
name p0
type ITEM_TYPE_BUTTON
dvar "ui_player_name_1"
rect 195 76 190 11
type ITEM_TYPE_BUTTON
dvar "ui_allies_assault_total"
textfont UI_FONT_NORMAL
textscale COUNT_SIZE
textstyle ITEM_TEXTSTYLE_SHADOWED
textaligny 10
textalignx 10
visible 0
decoration
}

itemDef
{
name p0
type ITEM_TYPE_BUTTON
rect
visible 1
decoration
mouseEnter
{
show p0;
play "mouse_over";
setitemcolor p0 backcolor 1 0 0 0.3;
}
mouseExit
{
setitemcolor p0 backcolor 0 0 0 0;
hide p0;
}
action
{
play "mouse_click";
scriptmenuresponse "0";
}
}

IzNoGoD
1st May 2013, 17:43
no , but if i add

player setClientCvar( "ui_player_name_" + i, "name :" player.name );

i dont have msg : name : **

developer 1

Would have crashed the server for the lack of the + between "name :" and player.name

Even so, it is quite useless to write your OWN name to a cvar multiple times.

PatmanSan
2nd May 2013, 08:48
You wont be able to show the result of a dvar if you use the action{} element in an itemDef{}. Also, you aren't defining the font and fontstyle and size. It wont show unless you do that.


itemDef
{
name rcon_button
type ITEM_TYPE_BUTTON
dvar "rcon_rsp_player0"
rect 0 0 SLOT_SIZE
origin ORIGIN_SLOT
textstyle OPTIONS_ITEM_TEXT_STYLE
textalign OPTIONS_ITEM_ALIGN
textalignx SLOT_ALIGNX
textaligny SLOT_ALIGNY
textscale SLOT_TXTSCALE
style WINDOW_STYLE_FILLED
backcolor OPTIONS_CONTROL_BACKCOLOR
forecolor OPTIONS_CONTROL_FORECOLOR
visible 1
dvartest "rcon_rsp_result"
showDvar { "1" }
action
{
play "mouse_click";
scriptMenuResponse "rcon_cmd_player0";
}
mouseEnter
{
play "mouse_over";
}
}

Using a dvar as text, checking dvar to show at all, and with an action... shows perfectly fine.

serthy
2nd May 2013, 10:04
i did hours of testing and came up with some goodies to bring the max dynamic in cod2 .menu modding
the following menu contains everything what is possible in cod2
heres the result for those, who will understand and use it:


#define POS_TEXT_1 100 100
#define DRAW_BUTTON_DVAR_TEXT( _id , _name , _dvar ) \
itemDef \
{ \
visible 1 \
rect POS_ ## _id 80 80 HORIZONTAL_ALIGN_RIGHT VERTICAL_ALIGN_CENTER \
origin 10 10 \
forecolor GLOBAL_UNFOCUSED_COLOR \
type ITEM_TYPE_BUTTON \
dvar _dvar ## "_text" \
textscale 0.3 \
textstyle ITEM_TEXTSTYLE_SHADOWEDMORE \
textalign ITEM_ALIGN_CENTER \
textalignx 40 \
textaligny 45 \
dvartest _dvar ## "_text" \
hideDvar \
{ \
""; \
} \
action \
{ \
play "mouse_click"; \
scriptMenuResponse "response_" ## _name; \
} \
} \

...
...
...

DRAW_BUTTON_DVAR_TEXT( TEXT_1 , "button_next" , "ui_next_" )

you are allowed to use strings in a macro combined with the stringify operator (##)
restrictions:
-only 1 macro can be defined in another macro
-dont use global defined vars in a macro combined with the stringify

kung foo man
2nd May 2013, 14:08
I just rememberd, that we had this nice little collection: http://killtube.org/showthread.php?1082-CoD2-create-functions-in-menu-files!&highlight=define




BUTTON(80 80, "ui_weapon_0", "weapon 0", "ui_weapon_0_show", "1")
BUTTON(80 100, "ui_weapon_1", "weapon 1", "ui_weapon_1_show", "1")
BUTTON(80 120, "ui_weapon_2", "weapon 2", "ui_weapon_2_show", "1")
BUTTON(80 140, "ui_weapon_3", "weapon 3", "ui_weapon_3_show", "1")

Would be perfect for 64+64 items. I didn't know about the Stringifiy-operator back then, but my old example can be shortened with that (the _show one).

Ni3ls
26th May 2013, 18:50
itemDef
{
name rcon_button
type ITEM_TYPE_BUTTON
dvar "rcon_rsp_player0"
rect 0 0 SLOT_SIZE
origin ORIGIN_SLOT
textstyle OPTIONS_ITEM_TEXT_STYLE
textalign OPTIONS_ITEM_ALIGN
textalignx SLOT_ALIGNX
textaligny SLOT_ALIGNY
textscale SLOT_TXTSCALE
style WINDOW_STYLE_FILLED
backcolor OPTIONS_CONTROL_BACKCOLOR
forecolor OPTIONS_CONTROL_FORECOLOR
visible 1
dvartest "rcon_rsp_result"
showDvar { "1" }
action
{
play "mouse_click";
scriptMenuResponse "rcon_cmd_player0";
}
mouseEnter
{
play "mouse_over";
}
}

Using a dvar as text, checking dvar to show at all, and with an action... shows perfectly fine.
How did u do this? Cos I can't use a dvar and action :/

PatmanSan
28th May 2013, 17:17
Part of in-game RCON of the eXtreme+ mod (v2.8). Have a look at ui_mp\scriptmenus\rcon_playerctrl.menu

Tally
28th May 2013, 19:26
How did u do this? Cos I can't use a dvar and action :/

There is essential code missing from that example. This is from the eXtreme+ mod in full:


itemDef
{
name rcon_button
type ITEM_TYPE_MULTI
text " "
dvar "rcon_rsp_model"
dvarFloatList { "@RCON_PLAYERCTRL_ORIGINAL" 0 "@RCON_PLAYERCTRL_BARREL" 1 "@RCON_PLAYERCTRL_BATHTUB" 2 "@RCON_PLAYERCTRL_FUNMODE" 3
"@RCON_PLAYERCTRL_MATTRESS" 4 "@RCON_PLAYERCTRL_TOILET" 5 "@RCON_PLAYERCTRL_TOMBSTONE" 6 "@RCON_PLAYERCTRL_TREE" 7 }
rect 0 145 OPTION_SIZE
origin ORIGIN_ITEM
textstyle OPTIONS_ITEM_TEXT_STYLE
textalign OPTIONS_ITEM_ALIGN
textalignx OPTION_ALIGNX
textaligny OPTIONS_ITEM_ALIGN_Y
textscale OPTIONS_CONTROL_TXTSCALE
style WINDOW_STYLE_FILLED
backcolor OPTIONS_CONTROL_BACKCOLOR
forecolor OPTIONS_CONTROL_FORECOLOR
visible 1
dvartest "rcon_rsp_result"
showDvar { "1" }
action
{
play "mouse_click";
scriptMenuResponse "rcon_cmd_model";
}
mouseEnter
{
play "mouse_over";
}
}


Note the dvarFloatList{} - this is what enables you to show the result of a dvartest: it has to have a string (although it doesn't have to be a localized string) + a response element to go with it. You then monitor for the scriptmenuresponse, and then set the dvar on the cliient, and it will then show the corresponding string in the dvarFloatList{}.

PatmanSan
28th May 2013, 20:56
Both itemDef examples are from eXtreme+ rcon_playerctrl.menu. The one I quoted is for displaying a player's name for a specific slot, and that's what the OP wanted. Nothing is missing at all.
Your itemDef example is for setting a player action in eXtreme in-game RCON. Although the dvar/dvarFloatList stuff is good-to-know for some readers, it's certainly not required.

btw: dvarFloatList and dvartest are totally unrelated. dvar and dvarFLoatList are related, and dvartest/showdvar/hidedvar are related.

Tally
29th May 2013, 00:54
Post deleted. Refrain from flaming/flamebaiting

Tally
29th May 2013, 02:09
I just found out why previously I couldn't get the value of a dvar to show in an itemDef{} - I had always been using "decoration" as part of the itemDef{}. This prevents it working. Once you leave it out, it works.

Ni3ls
29th May 2013, 10:14
That still doesnt work for me:/ I already left it out.
Maybe i place this at the wrong part

players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
player = players[i];

if( player getEntityNumber() == i )
{
player setClientCvar( "ui_player_name_" + i, player.name );
player setClientCvar( "ui_player_entNum_" + i, i );
}
}

Where am I supposed to thread this?

Tally
29th May 2013, 11:30
That still doesnt work for me:/ I already left it out.
Maybe i place this at the wrong part

players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
player = players[i];

if( player getEntityNumber() == i )
{
player setClientCvar( "ui_player_name_" + i, player.name );
player setClientCvar( "ui_player_entNum_" + i, i );
}
}

Where am I supposed to thread this?

Well, in the 2 examples above, the dvar is set after a scriptmenuresponse. So, that would be anywhere you are monitoring for menu response (eg maps\mp\gametypes\_menus.gsc, but obviously any file where you have a script varible waiting for a menu and response). So, if your action{} item is a scriptmenuresponse, using a loop to find all players is pretty redundant as you already have the entity defined - it would be the player making the menu response.

Perhaps the best thing you can do is modding elementary - post your menu code and your menu response waiter script in full. That way we can see if we can spot any problems in the code.

ADDENDUM -

I would just point out that I've never had a problem showing a dvar value in a menu itemDef{}. My problem had always been when doing that with an action{} item as well. As I posted above, I just discovered what my problem had been - I was always including decoration as well in the item definition. If you leave it out, showing the value of a dvar works every time with an action{} item.

PatmanSan
30th May 2013, 13:47
Post deleted. Refrain from flaming/flamebaiting

Tally
30th May 2013, 14:37
Post deleted. Refrain from flaming/flamebaiting

IzNoGoD
30th May 2013, 17:21
Just removed 3 posts. Please refrain from flaming/flamebaiting.

Be polite and all that crap.

Ni3ls
1st June 2013, 16:03
playerlist.menu

#include "ui_mp/menudef.h"

#define ORIGIN_TITLE 48 64
#define ORIGIN_CHOICE1 80 84
#define ORIGIN_CHOICE2 80 108

{
menuDef
{
name "playerlist"
rect 0 0 640 480
focuscolor GLOBAL_FOCUSED_COLOR
style WINDOW_STYLE_EMPTY
blurWorld 5.0
onEsc
{
close playerlist;
}


// Gradient
itemDef
{
style WINDOW_STYLE_SHADER
//rect -107 0 554 480
rect 0 0 640 480 HORIZONTAL_ALIGN_FULLSCREEN VERTICAL_ALIGN_FULLSCREEN
background "gradient"
visible 1
}

#include "ui/bars.menu"

itemDef
{
type ITEM_TYPE_TEXT
visible 1
origin ORIGIN_TITLE
forecolor 1 1 1 1
text "Playerlist"
textfont UI_FONT_NORMAL
textscale GLOBAL_HEADER_SIZE
}

itemDef
{
name "player1"
visible 1
rect 0 0 128 24
origin ORIGIN_CHOICE1
forecolor GLOBAL_UNFOCUSED_COLOR
type ITEM_TYPE_BUTTON
dvar "player_0"
textfont UI_FONT_NORMAL
textscale GLOBAL_TEXT_SIZE
textstyle ITEM_TEXTSTYLE_SHADOWED
textaligny 20

}
itemDef
{
name "player2"
visible 1
rect 0 0 128 24
origin ORIGIN_CHOICE2
forecolor GLOBAL_UNFOCUSED_COLOR
type ITEM_TYPE_BUTTON
dvar "player_1"
textfont UI_FONT_NORMAL
textscale GLOBAL_TEXT_SIZE
textstyle ITEM_TEXTSTYLE_SHADOWED
textaligny 20

}


}
}


in CallbackPlayer_Connect

{
thread dummy();

self.statusicon = "hud_status_connecting";
self waittill("begin");
self.statusicon = "";

level notify("connected", self);

if(!level.splitscreen)
iprintln(&"MP_CONNECTED", self);

players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
player = players[i];

if( player getEntityNumber() == i )
{
player setClientCvar( "player_" + i, player.name );
player iprintlnbold("player_"+i);
player iprintlnbold(player.name);
}
}

I can open the menu, but there is nothing inside. If I click on invisible name, it kicks me. So the button is working, the name is just not showing

Tally
1st June 2013, 16:31
How many were playing when you tested? Because you have it check entity number against the number of players on server. If there was just 1, that would make your entity number 0. Which means the dvar "player_1" wont show for you. Perhaps try testing "player_0" and see what happens.

FYI - there is nothing wrong with the itemDef{} showing the dvar. I tested it and it was fine. I just set the dvar "player_1" onPlayerConnect, and put my name in. It showed up fine. So, the problem is the script setting the dvar after callback_playerConnect.

Ni3ls
1st June 2013, 17:39
I was the only person on the server. The button has the name player_1, but the dvar has player_0. So it should work if there is only 1 person in the server. I tried it too with setting my name it and that worked fine as you said. But I dont have any error and the iprints dont show up. So i dont have any clue what to do :/

Tally
1st June 2013, 18:02
I was the only person on the server. The button has the name player_1, but the dvar has player_0. So it should work if there is only 1 person in the server. I tried it too with setting my name it and that worked fine as you said. But I dont have any error and the iprints dont show up. So i dont have any clue what to do :/

No, you are setting the dvar "player_" + their entity number. The itemDef{} you posted has a display for the dvar "player_1" - which wont show when the dvar set is "player_0".

If you have other itemDef{} to cover all possible scenarios, then the above wont explain why it wont show. So, I suggest you post the complete menu so we can check it again.

Ni3ls
1st June 2013, 18:16
Huh that is the complete menu.
Look here


name "player1" The button has the name player_1


dvar "player_0" the dvar is player_0

So it should work when i got ID 0
I dont understand what you are saying :(

Tally
1st June 2013, 18:31
Huh that is the complete menu.
Look here


name "player1" The button has the name player_1


dvar "player_0" the dvar is player_0

So it should work when i got ID 0
I dont understand what you are saying :(

Sorry, my bad. I was looking only at the last itemDef{}.

I'll check your scripting to see whether it's at fault.

Tally
1st June 2013, 18:40
Yeah, it's the script. This works:


Callback_PlayerConnect()
{
thread dummy();

self.statusicon = "hud_status_connecting";
self waittill( "begin" );
self.statusicon = "";

level notify( "connected", self );

i = self getEntityNumber();

self setClientCvar( "player_" + i, self.name );
self iprintlnbold( "player_" + i );
self iprintlnbold( self.name );

lpselfnum = self getEntityNumber();
lpGuid = self getGuid();
logPrint("J;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n");

if( game["state"] == "intermission" )
{
spawnIntermission();
return;
}
----------- snip ----------------

IzNoGoD
1st June 2013, 19:49
That wont give your name as clientcvar to all clients, only to yourself

Tally
1st June 2013, 20:15
That wont give your name as clientcvar to all clients, only to yourself

So does the other method - it only sets the cvar on a player if their entity number matches their trace in the for() loop. So, that means only to themselves. Not to everyone.

EDIT -

If it is truly wanted, this sets the Cvar for all players:


Callback_PlayerConnect()
{
thread dummy();

self.statusicon = "hud_status_connecting";
self waittill( "begin" );
self.statusicon = "";

level notify( "connected", self );

i = self getEntityNumber();

setCvar( "player_" + i, self.name );

self iprintlnbold( "player_" + i );
self iprintlnbold( self.name );

lpselfnum = self getEntityNumber();
lpGuid = self getGuid();
logPrint("J;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n");

if( game["state"] == "intermission" )
{
spawnIntermission();
return;
}

----------- snip ----------------

Peterlankton
2nd June 2013, 09:07
setCvar() will only set a server cvar, not a cvar for all players. Without setting them for every client using setClientCvar(), the names won't show up in the menu.

Tally
2nd June 2013, 11:33
setCvar() will only set a server cvar, not a cvar for all players. Without setting them for every client using setClientCvar(), the names won't show up in the menu.

If you mean a player wont see the value of cvar in a menu unless it is set on them as well, I know that. But I was shot down for not setting the cvar for all, so I added the edit as a bit of a joke. I don't believe Niels' original code intended to set the cvar on all players because it limits that action to whichever player has the same entity number as the loop increment. I thought this was backed up by the fact that, if you are going to use onPlayerConnect, you don't try to set a cvar on all players from there. It isn't the place to do it. You do it from some other place.

Going on the yet unfounded assumption that Niels wanted to set the cvar on all players, if I were doing this, I would probably do something like this:


Callback_PlayerConnect()
{
thread dummy();

self.statusicon = "hud_status_connecting";
self waittill( "begin" );
self.statusicon = "";

level notify( "connected", self );

i = self getEntityNumber();
dvar = "player_" + i;
self setClientCvar( dvar, self.name );
self thread UpdateAllPLayers( dvar, self, self.name );

self iprintlnbold( "player_" + i );
self iprintlnbold( self.name );

lpselfnum = self getEntityNumber();
lpGuid = self getGuid();
logPrint("J;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n");

if( game["state"] == "intermission" )
{
spawnIntermission();
return;
}

----------- snip ----------------

}

UpdateAllPLayers( dvar, newPlayer, name )
{

players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
players = players[i];
if( players == NewPlayer )
continue;

players setClientCvar( dvar, name );
}

}


That works because I tested it. Which was the whole point to begin with - Niels' original code did not work because it was trying to set a cvar on players from onPlayerConnect and using a loop trace to find 1 player when the player was already defined. I thought that was pretty redundant, so I posted the easier way of doing that. People then interjected that it wasn't setting the dvar on all players, and that's where the whole thing got side-tracked.

People really need to start taking notice of the POINT of a thread. Not nit picking at the smallest detail. Really does begin to get on your tits after a while.

Ni3ls
2nd June 2013, 12:49
Works perfectly!

IzNoGoD
2nd June 2013, 14:20
Try to make one player disconnect. It will not empty the string.
Try to change your name. It will not change with you.

Ni3ls
3rd June 2013, 10:54
Fixed it.Everytime i open the menu I update the cvars

Ni3ls
3rd June 2013, 14:16
Oh no, doesnt work. It works for the name check, but when u disconnect it stilll appears in the list :(

Tally
3rd June 2013, 14:53
Oh no, doesnt work. It works for the name check, but when u disconnect it stilll appears in the list :(

Create a method at Callback_PlayerDisconnect(). When the player leaves, update all players:


Callback_PlayerDisconnect()
{
self dropFlag();

if(!level.splitscreen)
iprintln(&"MP_DISCONNECTED", self);

dvar = "player_" + getEntityNumber();
self thread UpdateAllPLayersDisconnect( dvar );

if(isdefined(self.pers["team"]))
{
if(self.pers["team"] == "allies")
setplayerteamrank(self, 0, 0);
else if(self.pers["team"] == "axis")
setplayerteamrank(self, 1, 0);
else if(self.pers["team"] == "spectator")
setplayerteamrank(self, 2, 0);
}

lpselfnum = self getEntityNumber();
lpGuid = self getGuid();
logPrint("Q;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n");
}

UpdateAllPLayersDisconnect( dvar )
{
players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
players[i] setClientCvar( dvar, "" );
}

}

Ni3ls
3rd June 2013, 20:21
It's very strange. When i enter the server, I see my name in the list. Somebody else enter, I can see his name in the list under mine. But when he checks the list, he only can see his own name :/

IzNoGoD
3rd June 2013, 22:23
Ofc, for when he connects, he sets his cvar for everybody.
When you connected, you set the cvar for everyone (but not for him, as he was not connected yet...)

Tally
4th June 2013, 06:08
Here is an updated method:


Callback_StartGameType()
{
------------- snip ----------------

thread startGame();
thread updateGametypeCvars();

thread updateAllPlayers();
thread kickRandomBot();
}

updateAllPlayers()
{
if( !isDefined( level.playerDvars ) )
level.playerDvars = [];

if( !isDefined( level.playerDvarValues ) )
level.playerDvarValues = [];

for( ;; )
{
level waittill( "connected", player );

dvar = "player_" + player getEntityNumber();
name = player.name;

level.playerDvars[level.playerDvars.size] = dvar;
level.playerDvarValues[level.playerDvarValues.size] = name;

player thread setDvarsOnPlayers( level.playerDvars, level.playerDvarValues );
}
}

setDvarsOnPlayers( dvarArray, nameArray )
{
for( i=0; i < dvarArray.size; i++ )
{
self setClientCvar( dvarArray[i], nameArray[i] );

println( "^1------------ DVARS AND NAMES ------------" );
println( dvarArray[i] );
println( nameArray[i] );
println( "^1----------------------------------------" );

}
}

updateDvarsOnPlayers( dvarArray, nameArray )
{
players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
for( j=0; j < dvarArray.size; j++ )
{
players[i] setClientCvar( dvarArray[j], nameArray[j] );

println( "^1------------ DVARS AND NAMES ------------" );
println( dvarArray[j] );
println( nameArray[j] );
println( "^1----------------------------------------" );

}
}
}

remove_from_array( array, element )
{
if( !isdefined( element ) )
return( array );

newarray = [];
for( i = 0; i < array.size; i++ )
{
if( array[ i ] == element )
continue;

newarray[ newarray.size ] = array[ i ];
}

return( newarray );
}

kickRandomBot()
{
AllBots = [];
for( ;; )
{
wait( 30 );

players = getEntArray( "player", "classname" );
for( i=0; i < players.size; i++ )
{
if( !demon\_bots::IsBot( players[i] ) )
continue;

AllBots[AllBots.size] = players[i];
}

break;
}

candidate = AllBots[ randomInt( AllBots.size ) ];
Kick( candidate getEntityNumber() );
}

Callback_PlayerDisconnect()
{
if(!level.splitscreen)
iprintln(&"MP_DISCONNECTED", self);

level.playerDvars = remove_from_array( level.playerDvars, "player_" + self getEntityNumber() );
level.playerDvarValues = remove_from_array( level.playerDvarValues, self.name );
self thread updateDvarsOnPlayers( level.playerDvars, level.playerDvarValues );

if(isdefined(self.pers["team"]))
{
if(self.pers["team"] == "allies")
setplayerteamrank(self, 0, 0);
else if(self.pers["team"] == "axis")
setplayerteamrank(self, 1, 0);
else if(self.pers["team"] == "spectator")
setplayerteamrank(self, 2, 0);
}

lpselfnum = self getEntityNumber();
lpGuid = self getGuid();
logPrint("Q;" + lpGuid + ";" + lpselfnum + ";" + self.name + "\n");
}



This method:

1. builds an array for each player dvar derived from "player_" + the player's entity number.
2. builds an array for each player's name
3. Updates all players as they connect, and cycles through both player dvar and player name from the arrays
4. Removes the player's data from both player dvar array and player name array when they disconnect.

In the code above you will see a method to randomly kick a bot after 30 seconds. I did this for testing purposes because I wanted to use println() and record someone leaving and getting their data removed from the arrays from the player disconnect method. Obviously, it would have been ideal to have been able to run a dedicated server and leave myself, as the println() would print out the updated arrays, but I couldn't do this as you cannot run a dedicated server in developer mode. And I couldn't do it on a local server and leave myself as the println() would not have time to print before the server shut down. Hence the need to do it on a bot.

Here is the console log file showing the arrays updated when the bot left (it was bot 1 that got kicked). You will see that everyone got the Cvars updated minus the removed bot:


execing custombuttons.cfg
PunkBuster Client: PnkBstrA successfully loaded PnkBstrB
SV_DirectConnect()
Connecting player #1 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 1 guid 0)
SV_SendClientGameState() for bot0
Going from CS_CONNECTED to CS_PRIMED for bot0
Sending 16566 bytes in gamestate to client: 1
Going from CS_PRIMED to CS_ACTIVE for bot0
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
PunkBuster Client: PnkBstrB service installed and started successfully
dvar set scr_demon_hardcore 0
dvar set ui_axis_medic_total 1
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 1
SV_DirectConnect()
Connecting player #2 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 2 guid 0)
SV_SendClientGameState() for bot1
Going from CS_CONNECTED to CS_PRIMED for bot1
Sending 16566 bytes in gamestate to client: 2
Going from CS_PRIMED to CS_ACTIVE for bot1
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_allies_officer_total 0
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
SV_DirectConnect()
Connecting player #3 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 3 guid 0)
SV_SendClientGameState() for bot2
Going from CS_CONNECTED to CS_PRIMED for bot2
Sending 16566 bytes in gamestate to client: 3
Going from CS_PRIMED to CS_ACTIVE for bot2
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_axis_assault_total 4
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
SV_DirectConnect()
Connecting player #4 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 4 guid 0)
SV_SendClientGameState() for bot3
Going from CS_CONNECTED to CS_PRIMED for bot3
Sending 16566 bytes in gamestate to client: 4
Going from CS_PRIMED to CS_ACTIVE for bot3
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_axis_engineer_total 4
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
SV_DirectConnect()
Connecting player #5 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 5 guid 0)
SV_SendClientGameState() for bot4
Going from CS_CONNECTED to CS_PRIMED for bot4
Sending 16566 bytes in gamestate to client: 5
Going from CS_PRIMED to CS_ACTIVE for bot4
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_allies_officer_total 0
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
SV_DirectConnect()
Connecting player #6 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 6 guid 0)
SV_SendClientGameState() for bot5
Going from CS_CONNECTED to CS_PRIMED for bot5
Sending 16566 bytes in gamestate to client: 6
Going from CS_PRIMED to CS_ACTIVE for bot5
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_axis_engineer_total 3
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
SV_DirectConnect()
Connecting player #7 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 7 guid 0)
SV_SendClientGameState() for bot6
Going from CS_CONNECTED to CS_PRIMED for bot6
Sending 16566 bytes in gamestate to client: 7
Going from CS_PRIMED to CS_ACTIVE for bot6
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_allies_sniper_total 1
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
Giving bot6 a 999 ping - !count:
SV_DirectConnect()
Connecting player #8 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 8 guid 0)
SV_SendClientGameState() for bot7
Going from CS_CONNECTED to CS_PRIMED for bot7
Sending 16566 bytes in gamestate to client: 8
Going from CS_PRIMED to CS_ACTIVE for bot7
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_allies_assault_total 3
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
SV_DirectConnect()
Connecting player #9 has a zero GUID
Going from CS_FREE to CS_CONNECTED for (num 9 guid 0)
SV_SendClientGameState() for bot8
Going from CS_CONNECTED to CS_PRIMED for bot8
Sending 16566 bytes in gamestate to client: 9
Going from CS_PRIMED to CS_ACTIVE for bot8
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_2
bot1
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
dvar set scr_demon_hardcore 0
dvar set ui_axis_engineer_total 2
dvar set ui_allow_allies_assault 1
dvar set ui_allow_allies_engineer 1
dvar set ui_allow_allies_gunner 1
dvar set ui_allow_allies_sniper 1
dvar set ui_allow_allies_medic 1
dvar set ui_allow_allies_officer 0
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------
------------ DVARS AND NAMES ------------
player_0
Tally
----------------------------------------
------------ DVARS AND NAMES ------------
player_1
bot0
----------------------------------------
------------ DVARS AND NAMES ------------
player_3
bot2
----------------------------------------
------------ DVARS AND NAMES ------------
player_4
bot3
----------------------------------------
------------ DVARS AND NAMES ------------
player_5
bot4
----------------------------------------
------------ DVARS AND NAMES ------------
player_6
bot5
----------------------------------------
------------ DVARS AND NAMES ------------
player_7
bot6
----------------------------------------
------------ DVARS AND NAMES ------------
player_8
bot7
----------------------------------------
------------ DVARS AND NAMES ------------
player_9
bot8
----------------------------------------

Going to CS_ZOMBIE for bot1
7:bot1 EXE_PLAYERKICKED

]\quit
quitting...
----- CL_Shutdown -----
dvar set sv_disableClientConsole 0
writing to: C:\Program Files (x86)\Activision\Call of Duty 2\servercache.dat
-----------------------
----- Server Shutdown -----
==== ShutdownGame ====
Going to CS_ZOMBIE for Tally
0:Tally EXE_DISCONNECTED
Going to CS_ZOMBIE for bot0
1:bot0 EXE_DISCONNECTED
Going to CS_ZOMBIE for bot1
2:bot1 EXE_DISCONNECTED
Going to CS_ZOMBIE for bot2
3:bot2 EXE_DISCONNECTED
Going to CS_ZOMBIE for bot3
4:bot3 EXE_DISCONNECTED
Going to CS_ZOMBIE for bot4
5:bot4 EXE_DISCONNECTED
Going to CS_ZOMBIE for bot5
6:bot5 EXE_DISCONNECTED
Going to CS_ZOMBIE for bot7
8:bot7 EXE_DISCONNECTED
Going to CS_ZOMBIE for bot8
9:bot8 EXE_DISCONNECTED
dvar set sv_running 0
---------------------------

Ni3ls
7th June 2013, 12:42
I got an error, but I did the same as you wrote :/

function called with too many parameters:


updateAllPlayers()
*
called from:
(file 'maps/mp/gametypes/tdm.gsc', line 172)
self thread UpdateAllPLayers( dvar, self, self.name );

kung foo man
7th June 2013, 12:51
The only reference to UpdateAllPlayers() I see in Tally's updated code is here:



Callback_StartGameType()
{
------------- snip ----------------

thread startGame();
thread updateGametypeCvars();

thread updateAllPlayers();
thread kickRandomBot();
}


But your error called updateAllPlayers() with three arguments, so you might have some old code left over?

Ni3ls
7th June 2013, 13:28
I had it open 2 times and was editing the wrong one....