PDA

View Full Version : Renaming bots



guiismiti
2nd September 2014, 04:51
Quick question, just need a confirmation - is it possible to rename bots?

I created this code just now:



if(isdefined(self.isbot))
{
botname = getSubStr(self.name, 0, 3);

if(botname == "bot")
{
number = getSubStr(self.name, 3, self.name.size);
self.name = "new name #"+number;
self setclientcvar("name", "new name #"+number);
iprintlnBold("a bot has been renamed");
}
}


I'm aware setclientcvar would never work since bots don't have their own configurations like players do. Still, as a noob, it's worth the try.
Also, it's weird that I can get self.name from a bot but cannot change it.
I'm reading the printed message in game every time the code is read, so, it is reaching the renaming commands.

Hmm... I actually just tried to use 'self.name = ' to rename myself ingame, and it didn't work. Any clues?

filthy_freak_
2nd September 2014, 05:01
Possible but very hard.

741
742

Basically you'd need to create a custom scoreboard, killfeed and kill messages, while figuring out how to hide the stock ones.

There might be a way to do it using libcod (See http://killtube.org/showthread.php?1940-Kicking-bots/page2 ) but examples on that thread have been done with cod1.

guiismiti
2nd September 2014, 05:10
Yea, I can see the ping is also modified.

Mitch
2nd September 2014, 06:36
You can try it with libcod like explained here:

http://killtube.org/showthread.php?1940-Kicking-bots&p=9963&viewfull=1#post9963

filthy_freak_
2nd September 2014, 19:28
You can try it with libcod like explained here:

http://killtube.org/showthread.php?1940-Kicking-bots&p=9963&viewfull=1#post9963

That is for CoDExtended.

Could you convert it to libcod for those who are unfamiliar with C++? (Myself being one)

Mitch
3rd September 2014, 08:27
That is for CoDExtended.

Could you convert it to libcod for those who are unfamiliar with C++? (Myself being one)

When i got time i will start with 'isbot' function for libcod. After that works i will start on 'renamebot'.

1.3


int __cdecl sub_808C316(int a1, char *dest, int a3)
{
int v3; // ST14_4@5
int v5; // [sp+10h] [bp-8h]@2

if ( *(_DWORD *)(a1 + 452308) == 2 )
{
sub_8094A10(0, 0, "%c \"EXE_CANNOTKICKHOSTPLAYER\"", 101);
v5 = 0;
}
else
{
if ( dest )
{
sub_80B7AB6(dest, (const char *)(a1 + 134216), a3);
sub_80B7E54(dest);
}
v3 = *(_DWORD *)(a1 + 714500);
sub_808F02E(a1, "EXE_PLAYERKICKED");
*(_DWORD *)(a1 + 134688) = dword_8423084;
v5 = v3;
}
return v5;
}



if ( *(_DWORD *)(a1 + 452308) == 2 )

if( cl->netchan.remoteAddress.type == NA_LOOPBACK )
NA_BOT = 0



void gsc_player_addresstype(int id) {
#if COD2_VERSION == COD2_VERSION_1_3
int info_start = *(int *)0x08423084;
int info_base = *(int *)0x0842308C;
int info_size = 0xB1064;
int info_addresstype_offset = 0x6E6D4; // same as 1.2
#else
#warning gsc_player_addresstype() got no working addresses
int info_start = *(int *)0x0;
int info_base = *(int *)0x0;
int info_size = 0x0;
int info_addresstype_offset = 0x0;
#endif

int info_player = info_base + id * info_size;
int addrtype = info_start - *(unsigned int *)(info_player + info_addresstype_offset);
stackPushInt(addrtype);
}


1.0 offset is 0x6E5C4.

guiismiti
3rd September 2014, 15:07
I'm only guessing here but I think he's manipulating the default bot name (Which can be done without libcod by editing cod2_mp with a hex editor, but the bot name is limited to 3 chars without libcod) which affects all bots globally.

If its possible to individually change their name (Without making your own scoreboard/obituary) then by all means prove me wrong =D

62 6F 74 25 64 found it

Also, Game Tracker does not count bots as players, but what if they are renamed? Can't test it, haven't got a server.

Mitch
4th September 2014, 12:52
I made some progress to rename them. (1.3)



sub_80B85CE(&dest, (unsigned int)"challenge", v6);
if ( (unsigned __int8)sub_80B2FAA("fs_restrict") )
{
v7 = (unsigned int)sub_80B8108(&dest, (int)"sv_keywords");
sub_80B7F0A(&s, 0x400u, "demo %s", v7);
sub_80B85CE(&dest, (unsigned int)"sv_keywords", (int)&s);
}


Info_SetValueForKey = 0x080B85CE



result = sub_808BAF8();
v3 = result;
if ( result )
{
sub_8060DEA("userinfo\n");
sub_8060DEA("--------\n");
result = sub_80614EA(v3 + 12);


=


cl = SV_GetPlayerByName();
if ( !cl ) {
return;
}

Com_Printf( "userinfo\n" );
Com_Printf( "--------\n" );
Info_Print( cl->userinfo );


Now i only need to set the name to the client struct.

In SV_GetPlayerByName function:


sub_80B7AB6(&dest, (const char *)i + 134216, 64);

=


Q_strncpyz( cleanName, cl->name, sizeof(cleanName) );

Mitch
5th September 2014, 08:50
I got currently this. I haven't tested or compiled it yet.


void gsc_player_renamebot(int id) {
char * key;

if ( ! stackGetParams("s", &key)) {
printf("scriptengine> ERROR: gsc_player_renamebot(): param \"key\"[1] has to be an string!\n");
stackPushUndefined();
return;
}

#if COD2_VERSION == COD2_VERSION_1_0
int info_base = *(int *)0x0841FB0C;
int info_size = 0x78F14;
#elif COD2_VERSION == COD2_VERSION_1_2
int info_base = *(int *)0x0842200C;
int info_size = 0x79064;
#elif COD2_VERSION == COD2_VERSION_1_3
int info_base = *(int *)0x0842308C;
int info_size = 0xB1064;
#else
#warning gsc_player_renamebot() got no working addresses
int info_base = *(int *)0x0;
int info_size = 0x0;
#endif

int info_player = info_base + id * info_size;

#if COD2_VERSION == COD2_VERSION_1_3
typedef int (*Info_SetValueForKey_t)(char *s, const char *key, const char *value);
Info_SetValueForKey_t Info_SetValueForKey = (Info_SetValueForKey_t)0x080B85CE;

Info_SetValueForKey((unsigned int *)(info_player + 12), "name", key);
char * name = (const char *)(unsigned int *)(info_player + 134216);
memcpy(&name[0], key, 32);
name[31] = '\0';
printf("name = %s\n", name);
#endif

stackPushInt(1);
}


https://github.com/M-itch/libcod/commit/8d9589ae71165b90ffc86fb8ec82494c140901de

Mitch
5th September 2014, 18:24
You can now download the working version: http://znation.nl/libcod/libcod2_1_3.so (only tested with rcon status)



bot renamebot("NEW NAME");

https://github.com/M-itch/libcod/commit/cd7fe791f7fb700aef4799b67de757e2758eca9a

filthy_freak_
5th September 2014, 19:33
You can now download the working version: http://znation.nl/libcod/libcod2_1_3.so (only tested with rcon status)

Woot! Ty very much!!! Works very well!

752

However there is one bug i'm noticing - console is being spammed with "Giving <Bot Name> a 999 ping - !count:", not sure if its something on my end since I had to switch to 1.3 to test this.

753

Mitch
5th September 2014, 19:42
However there is one bug i'm noticing - console is being spammed with "Giving <Bot Name> a 999 ping - !count:", not sure if its something on my end since I had to switch to 1.3 to test this.

753

Was developer on?

filthy_freak_
5th September 2014, 19:52
Was developer on?

Yup that was it. Force of habit lol.

754

Mitch
5th September 2014, 19:58
For 1.2 and 1.0 you only need these address for Info_SetValueForKey.

80B848A 1.2
80B5FF6 1.0

filthy_freak_
5th September 2014, 20:22
For 1.2 and 1.0 you only need these address for Info_SetValueForKey.

80B848A 1.2
80B5FF6 1.0

Do you mind compiling 1.0 for me? Having errors on my end due to mysql;

./doit.sh base
##### COMPILE GSC_MYSQL.CPP #####
cc1plus: error: unrecognised command line option "-std=gnu++11"

./cod2.Bots/cod2_lnxded: symbol lookup error: ./cod2.Bots/libcod2_1_0.so: undefined symbol: gsc_mysql_init

Used to work in the past.

filthy_freak_
5th September 2014, 22:28
Do you mind compiling 1.0 for me? Having errors on my end due to mysql;

./doit.sh base
##### COMPILE GSC_MYSQL.CPP #####
cc1plus: error: unrecognised command line option "-std=gnu++11"

./cod2.Bots/cod2_lnxded: symbol lookup error: ./cod2.Bots/libcod2_1_0.so: undefined symbol: gsc_mysql_init

Used to work in the past.

Nevermind - fixed it and working like a charm =D

Mitch
6th September 2014, 12:57
Nevermind - fixed it and working like a charm =D

I just uploaded the 1.0 and 1.2 version.

http://znation.nl/libcod/

guiismiti
11th September 2014, 07:17
When i got time i will start with 'isbot' function for libcod.

Hm, not sure if I understood it but, if you mean you wanna add the 'isbot' function to the game through libcod, it already exists

isdefined(self.isbot)

kung foo man
11th September 2014, 08:16
I didn't find the isbot attribute in _teams.gsc nor in the server binary itself (with WinHex):



addTestClients()
{
wait 5;

for(;;)
{
if(getCvarInt("scr_testclients") > 0)
break;
wait 1;
}

testclients = getCvarInt("scr_testclients");
for(i = 0; i < testclients; i++)
{
ent[i] = addtestclient();

if(i & 1)
team = "axis";
else
team = "allies";

ent[i] thread TestClient(team);
}
}

TestClient(team)
{
while(!isdefined(self.pers["team"]))
wait .05;

self notify("menuresponse", game["menu_team"], team);
wait 0.5;

if(team == "allies")
self notify("menuresponse", game["menu_weapon_allies"], "m1carbine_mp");
else if(team == "axis")
self notify("menuresponse", game["menu_weapon_axis"], "mp40_mp");
}


You might have just a mod, where the attribute player.isbot is set manually?

filthy_freak_
11th September 2014, 08:35
Yup can confirm there is no default player.isBot function. I remember checking for this a while ago.

Mitch
11th September 2014, 08:50
Yup can confirm there is no default player.isBot function. I remember checking for this a while ago.

I was planning on adding 'if(player isbot())' but i renamed the function to 'getAddressType'. Because you can use it for more than bots. So it is now 'if(player getAddressType() == 0)'.

You can use 'if(isDefined(player.isbot))'. But you need to set it after creating the test client.



ent[i] = addtestclient();
ent[i].isbot = true;


getAddressType types

0 = NA_BOT
1 = NA_BAD (an address lookup failed)
2 = NA_LOOPBACK
3 = NA_BROADCAST
4 = NA_IP
5 = NA_IPX (ipv6, possibly unsupported)
6 = NA_BROADCAST_IPX

filthy_freak_
11th September 2014, 08:52
You can use 'if(isDefined(player.isbot))'. But you need to set it after creating the test client.

Yes this is what I did many months ago. No problems. Was just confirming that kung is correct.

php
11th September 2014, 15:47
Or how about just hook the player/class memberfields so you can make a default player.isbot attribute. :rolleyes:

guiismiti
13th September 2014, 01:41
Just found this in mbot.gsc from meatbot:



addlotdaxis() //<Master|dEvis>
{
bot = undefined;
if(!isdefined(bot))
bot = addtestclient();


if(isdefined(bot))
{
pweapon = "";
bot.isbot = true;
bot thread botJoin("axis", pweapon);
}
if(isdefined(level.botstart))
{
bot thread [[level.botstart]]();
}
}

filthy_freak_
13th September 2014, 01:54
Just found this in mbot.gsc from meatbot:

What about it?

guiismiti
13th September 2014, 02:28
I'm just showing where isbot is defined in meatbot