 |
Server Help Community forums for Subgame, ASSS, and bots
|
Author |
Message |
BugZap Guest
Offline
|
Posted: Mon Aug 20, 2007 9:59 am Post subject: PlayerTags delay before delete - Merv |
 |
|
|
|
I want to give players 5 mins to return before deleting the tags. Whats the best way of going about this?
Heres what im thinking, loop the player list marking players not here, then next time if they are still not here delete it. However, when I logoff with one nick and log back in with a different nick it assumes the playertags of the first nick. Im not finding it easy testing this, any clues on the best way to go about this would be appreciated.
thx |
|
Back to top |
|
 |
Cyan~Fire I'll count you!

Age:37 Gender: Joined: Jul 14 2003 Posts: 4608 Location: A Dream Offline
|
Posted: Mon Aug 20, 2007 10:08 am Post subject: |
 |
|
|
|
Well in EVENT_PlayerLeaving you could get rid of killTags() and instead create a tag of his leave time. Then in EVENT_Tick just keep checking for tags you should delete. _________________ This help is informational only. No representation is made or warranty given as to its content. User assumes all risk of use. Cyan~Fire assumes no responsibility for any loss or delay resulting from such use.
Wise men STILL seek Him. |
|
Back to top |
|
 |
BugZap Guest
Offline
|
Posted: Mon Aug 20, 2007 1:06 pm Post subject: |
 |
|
|
|
You was suppose to just write it for me
case EVENT_PlayerEntering:
{
Player *p = (Player*)event.p[0];
set_tag(p, PHERE, 1);
}
break;
case EVENT_PlayerLeaving:
{
Player *p = (Player*)event.p[0];
//killTags(p);
set_tag(p, PHERE, 99);
}
break;
case EVENT_Tick:
{
for (int i = 0; i <1; ++i)
--countdown[i];
if(countdown[0] < 1)
{
countdown[0]=300; // reset timer every 5 mins
// CODE NEEDED TO LOCATE PLAYERS NOT HERE
}
|
Heres what Im using to trying to figure out, stuff..
if (c->check("tags"))
{
_listnode <PlayerTag> *parse = taglist.head;
PlayerTag *tag;
while (parse)
{
tag = parse->item;
parse = parse->next;
sendPublic("P: " + (String)tag->data + " INDEX: " + (String)tag->index + " DATA: " + (String) tag->data);
//taglist.kill(tag);
}
}
|
When the timer hits 1 and is reset to 5 mins I want to check each players tag,
get_tag(p, PHERE)
If tag PHERE is 1 they are here move next,
if tag PHERE is 99 they are not here, set it to 98 so it is deleted next time timer hit 1,
if tag PHERE is 98 they have been gone atleast 5 mins, delete tags.
But I cant figure out how to locate and set/delete the tags of players that are not here. |
|
Back to top |
|
 |
Samapico No, these DO NOT look like penises, ok?

Joined: May 08 2003 Posts: 1252 Offline
|
|
Back to top |
|
 |
BugZap Guest
Offline
|
|
Back to top |
|
 |
Samapico No, these DO NOT look like penises, ok?

Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Mon Aug 20, 2007 5:01 pm Post subject: |
 |
|
|
|
hmmmmmmmm that made me think......
If a player leaves, then reenters, the pointer will most likely be different... So what you'd want to do is re-assign all the old tags of that player to his new pointer
So it might be easier to store all the data you want about that player in something else than a tag when he leaves.
Have a linkedlist of these data items
If a player is gone for more than 5 minutes, clear the data item created for him, if he comes back, it's easy to re-set tags to the player.
Something like...
struct PlayerData
{
char name[20];
int thisdata;
int thatdata;
int blahblah;
int LeaveTime;
};
...
_linkedlist <PlayerData> datalist; //not sure about exact syntax here
...
case EVENT_PlayerEntering:
{
Player *p = (Player*)event.p[0];
//search the datalist list, if an item->name matches p->name, set_tag the data back on the player
}
break;
case EVENT_PlayerLeaving:
{
Player *p = (Player*)event.p[0];
PlayerData* data = new PlayerData;
if (data == NULL)
break;
strcpy(...);//whatever the syntax is... copy p->name to data->name
data->thisdata = get_tag(p, ....);
//set all data you want to remember
data->LeaveTime = GetTickCount();
datalist.append(data);
killTags(p);
}
break;
|
Anyways......... thats the reason why I don't use tags much, I usually create a whole new class from scratch. Gives more flexibility |
|
Back to top |
|
 |
CypherJF I gargle nitroglycerin

Gender: Joined: Aug 14 2003 Posts: 2582 Location: USA Offline
|
Posted: Mon Aug 20, 2007 5:25 pm Post subject: |
 |
|
|
|
Don't rely on comparing player names... player 012345678901234567890123 looks the same as 012345678901234567890122 due to inconsistencies of max player name length. Granted, not many people have names > 19 characters. I would have my plugins do *info, *einfo for their complete name, biller id, etc. and if their true name was > 19 characters they'd be booted. _________________ Performance is often the art of cheating carefully. - James Gosling |
|
Back to top |
|
 |
BugZap Guest
Offline
|
Posted: Mon Aug 20, 2007 7:08 pm Post subject: |
 |
|
|
|
Other then comparing player names, Im not seeing many options. |
|
Back to top |
|
 |
CypherJF I gargle nitroglycerin

Gender: Joined: Aug 14 2003 Posts: 2582 Location: USA Offline
|
Posted: Mon Aug 20, 2007 8:56 pm Post subject: |
 |
|
|
|
Exactly, there isn't much you can do until you pull their userid (assuming it's connected to a biller), or read in the *einfo/*info which provides the user's full name. |
|
Back to top |
|
 |
BugZap Guest
Offline
|
Posted: Fri Aug 24, 2007 8:56 pm Post subject: |
 |
|
|
|
So here is the conclusion
I put all game data in a struct, the rest gets reset often (on death, team change) still uses tags.
When the bot enters it wips the struct clean setting all data to default values, then claims the first slot [0] as a blank, and slot [1] for itself. Then loops the player list adding all player in the arena to the struct, and resets the game etc..
If in a rare case someone isnt listed in the stuct, or a player with 19+ name, their data is put in the first slot the "BLANK" one reserved by the bot on enter, and deleted regularly. The first 2 slots are skipped my stat printout, mvp records etc..
This is the code I came up for the delay, after many many hours of figuring the proper syntax to create a struct, and basically rewriting my whole bot from scratch ..
case EVENT_PlayerEntering:
{
Player *p = (Player*)event.p[0];
int PID = GetPilot(p);
if(PID==0)
{
AddPilot(p);
}
else{pilots[PID].ishere = 1;}
}
break;
case EVENT_PlayerLeaving:
{
Player *p = (Player*)event.p[0];
killTags(p);
int PID = GetPilot(p);
if(PID!=0)
{
pilots[PID].ishere = GetTickCount();
}
}
break;
..
// Called once every 90 sec - gives atleast 5 mins to return, as much as 6.5 mins
void botInfo::DoCleanUp()
{
int isvalue;
for (int PID = 2; PID < playercount; PID++)
{
isvalue = pilots[PID].ishere;
if(isvalue !=1 && GetTickCount() - isvalue > 300000)
{
ClearStruct(PID);
}
}
}
|
I do have one other question,
When the bot enters it populates all 50 struct with blank data "ClearStruct(int PID)"
This seems to work fine, but im sure theres a way to detect a NULL value of a struct that isnt in use, and then destroy one when its not needed?
struct PlayerData
{
char name[20];
int kills;
int deaths;
int tks;
int points;
int bonus;
int multikill;
int optmsg;
int ishere;
};
..
void botInfo::ClearStruct(int PID)
{
strncpy(pilots[PID].name, "AVAIL", 20);
pilots[PID].kills = 0;
pilots[PID].deaths= 0;
pilots[PID].tks = 0;
pilots[PID].points = 0;
pilots[PID].bonus = 0;
pilots[PID].multikill = 0;
pilots[PID].optmsg = 0;
pilots[PID].ishere = 1;
}
|
|
|
Back to top |
|
 |
Samapico No, these DO NOT look like penises, ok?

Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Sat Aug 25, 2007 12:42 am Post subject: |
 |
|
|
|
You can have a linkedlist of PlayerData structures instead of an array of them
_linkedlist <PlayerData> myplayerdata;
...
//to create a new struct:
//allocate memory
PlayerData* newdata = new PlayerData;
//initialize data
strncpy(newdata->name, p->name, 20);
newdata->kills = 0;
newdata->deaths= 0;
newdata->tks = 0;
newdata->points = 0;
newdata->bonus = 0;
newdata->multikill = 0;
newdata->optmsg = 0;
newdata->ishere = 1;
//append the new struct to the list
myplayerdata.append(newdata);
|
To remove something from the list, you'll need a function that finds an item in the list using the name of the player. It would look like...
PlayerData* FindDataByName(char* name)
{
_listnode <PlayerData> *parse = myplayerdata.head;
PlayerData *data;
while (parse)
{
data = parse->item;
if (strcmp(...)) // compare data->name with name
//if they're the same:
return data;
parse = parse->next;
}
return NULL;
} |
and then...
void KillData(Player *p) //kills data associated to player p
{
PlayerData* data = FindDataByName(p->name);
if (data != NULL)
myplayerdata.kill(data);
//else, no struct associated to that player was found
} |
By the way, you should have used "" instead of "AVAIL" for unused structs, what if someone was named Avail?  |
|
Back to top |
|
 |
BugZap Guest
Offline
|
Posted: Sat Aug 25, 2007 1:46 am Post subject: |
 |
|
|
|
HAH, I actually used "AVA" A gamble I suppose
I tried the linkedlist method first, but failed, gave up, and went to the array method. But now that you put out the proper syntax for me, the question is it more efficient using the linkedlist method?
Thanks |
|
Back to top |
|
 |
Samapico No, these DO NOT look like penises, ok?

Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Sat Aug 25, 2007 2:05 am Post subject: |
 |
|
|
|
Maybe not more efficient performance-wise... but makes your code more efficient and flexible
1- No predefined limit in the size of the list
2- No waste of memory for having 40 empty items
searching through the list is 'a bit' slower, but we're speaking of nanoseconds here so...
a linkedlist also allows you to easily insert elements anywhere in the list... so it's easy to sort items while you add them (if you wanted to sort them alphabetically, for example)
Since I learned to work with them, I use them alot... Whenever you need a variable-size array, they make your life easier... |
|
Back to top |
|
 |
BugZap Guest
Offline
|
Posted: Sat Aug 25, 2007 11:46 am Post subject: |
 |
|
|
|
It all makes perfect sense now, Im going to rewrite it soon as I recover from this last rewrite. Actually converting it should take very long.
Thanks for you help |
|
Back to top |
|
 |
Cyan~Fire I'll count you!

Age:37 Gender: Joined: Jul 14 2003 Posts: 4608 Location: A Dream Offline
|
Posted: Mon Aug 27, 2007 1:43 pm Post subject: |
 |
|
|
|
One thing that you'll have to change is using the 0 and 1 index for special purposes, but I don't really know why you did that in the first place. Why does the bot need a structure? Why handle players with 20 char names differently? If you're worried about that, just kick them. |
|
Back to top |
|
 |
BugZap Guest
Offline
|
Posted: Mon Aug 27, 2007 3:23 pm Post subject: |
 |
|
|
|
The 0 index is just a default in the case someone slips past the bot onenter. The GetPilot function could just add someone if not found in the struct, and return that value. With a default I never need to worry about a value not being returned or returned null or whatever other unforseen whatever that could happen. If someone with a 20+ nick wants to play without stats they can do so for now, it just goes in the default, but I'll prob endup just booting them like you said.
The bot is just included in the struct for testing. I dont have other players flying around my LAN to compare end game stats/mvp recoders with. |
|
Back to top |
|
 |
Cyan~Fire I'll count you!

Age:37 Gender: Joined: Jul 14 2003 Posts: 4608 Location: A Dream Offline
|
Posted: Tue Aug 28, 2007 12:39 pm Post subject: |
 |
|
|
|
Yeah, but just putting a player in a junk area is horribly messy, at the very least warn them, but really the only good solution is to boot them. |
|
Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You can attach files in this forum You can download files in this forum
|
Software by php BB © php BB Group Server Load: 493 page(s) served in previous 5 minutes.
|