Server Help Forum Index Server Help
Community forums for Subgame, ASSS, and bots
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   StatisticsStatistics   RegisterRegister 
 ProfileProfile   Login to check your private messagesLogin to check your private messages   LoginLogin (SSL) 

Server Help | ASSS Wiki (0) | Shanky.com
PlayerTags delay before delete - Merv

 
Post new topic   Reply to topic Printable version
 View previous topic  Purge's CTF plugin Post :: Post prize3.dll plugin  View next topic  
Author Message
BugZap
Guest


Offline

PostPosted: Mon Aug 20, 2007 9:59 am    Post subject: PlayerTags delay before delete - Merv Reply to topic Reply with quote

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!
I'll count you!


Age:37
Gender:Gender:Male
Joined: Jul 14 2003
Posts: 4608
Location: A Dream
Offline

PostPosted: Mon Aug 20, 2007 10:08 am    Post subject: Reply to topic Reply with quote

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
View users profile Send private message Add User to Ignore List Visit posters website
BugZap
Guest


Offline

PostPosted: Mon Aug 20, 2007 1:06 pm    Post subject: Reply to topic Reply with quote

You was suppose to just write it for me icon_sad.gif


Code: Show/Hide

   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..


Code: Show/Hide


      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

PostPosted: Mon Aug 20, 2007 3:15 pm    Post subject: Reply to topic Reply with quote

Much simpler... as Cyan said:


Code: Show/Hide

#define TAGLEAVETIME 100 //index of the tag
#define KILLTAGDELAY 300000 //5 minutes

....
   case EVENT_PlayerEntering:
      {
         Player *p = (Player*)event.p[0];
             //Reset leave time
            set_tag(p, TAGLEAVETIME , 0);
      }
      break;

   case EVENT_PlayerLeaving:
      {
         Player *p = (Player*)event.p[0];
         
         //killTags(p);

   //Set the tag to current time
         set_tag(p, TAGLEAVETIME , GetTickCount());
      }
      break;



....


case EVENT_Tick:
{

      for (int i = 0; i <1; ++i)
      --countdown[i];

      //every second, check if any tags need to be killed
      CheckTagsToKill();
      }



...


void botInfo::CheckTagsToKill()
{
         _listnode <PlayerTag> *parse = taglist.head;
         PlayerTag *tag;
           
            while (parse)
            {
                  tag = parse->item;
                 
             if (tag->index == TAGLEAVETIME &&
                      tag->value != 0 &&
                      GetTickCount() - tag->value > KILLTAGDELAY)
                     
                      killTags(tag->player);

                  parse = parse->next;
            }

}



Some stuff might not be exact, but that should work
_________________
(Insert a bunch of dead links here)
Back to top
View users profile Send private message Add User to Ignore List
BugZap
Guest


Offline

PostPosted: Mon Aug 20, 2007 4:28 pm    Post subject: Reply to topic Reply with quote

Looks good, I try it out soon as I get a chance,

I was attempting to add name reference to the struct, then a killTags_byname function etc.. but your way is much better.


Thanks Samapico




Code: Show/Hide

struct PlayerTag
{
   Player *p;
   char name[20]; //
   int index;
   int data;
};


void botInfo::killTags_byname(char *pname)
{
   _listnode <PlayerTag> *parse = taglist.head;
   PlayerTag *tag;

   while (parse)
   {
      tag = parse->item;
      parse = parse->next;

      if ((String)tag->name != (String)pname) continue;
      
   ///   sendPublic("deleted function: " + (String)pname);

      taglist.kill(tag);
   }
}

ticker//

    _listnode <PlayerTag> *parse = taglist.head;
    PlayerTag *tag;

    while (parse)
    {
      tag = parse->item;

      if (tag->index == 9)
      {
         if(tag->data == 99)
            {
                 tag->data = 98;       
            }
            else if(tag->data == 98)
            {
                 killTags_byname((String)tag->name);
            }
           
            else if(tag->data == 1){
                  tag->data = 98;
                 sendPublic("data=98");
                  }
      }
      parse = parse->next;
    }

Back to top
Samapico
No, these DO NOT look like penises, ok?


Joined: May 08 2003
Posts: 1252
Offline

PostPosted: Mon Aug 20, 2007 5:01 pm    Post subject: Reply to topic Reply with quote

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...
Code: Show/Hide

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
View users profile Send private message Add User to Ignore List
CypherJF
I gargle nitroglycerin


Gender:Gender:Male
Joined: Aug 14 2003
Posts: 2582
Location: USA
Offline

PostPosted: Mon Aug 20, 2007 5:25 pm    Post subject: Reply to topic Reply with quote

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
View users profile Send private message Add User to Ignore List
BugZap
Guest


Offline

PostPosted: Mon Aug 20, 2007 7:08 pm    Post subject: Reply to topic Reply with quote

Other then comparing player names, Im not seeing many options.
Back to top
CypherJF
I gargle nitroglycerin


Gender:Gender:Male
Joined: Aug 14 2003
Posts: 2582
Location: USA
Offline

PostPosted: Mon Aug 20, 2007 8:56 pm    Post subject: Reply to topic Reply with quote

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
View users profile Send private message Add User to Ignore List
BugZap
Guest


Offline

PostPosted: Fri Aug 24, 2007 8:56 pm    Post subject: Reply to topic Reply with quote

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 ..

Code: Show/Hide

   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?


Code: Show/Hide


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

PostPosted: Sat Aug 25, 2007 12:42 am    Post subject: Reply to topic Reply with quote

You can have a linkedlist of PlayerData structures instead of an array of them

Code: Show/Hide

_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...

Code: Show/Hide
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...
Code: Show/Hide

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? tongue.gif
Back to top
View users profile Send private message Add User to Ignore List
BugZap
Guest


Offline

PostPosted: Sat Aug 25, 2007 1:46 am    Post subject: Reply to topic Reply with quote

HAH, I actually used "AVA" A gamble I suppose icon_smile.gif


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

PostPosted: Sat Aug 25, 2007 2:05 am    Post subject: Reply to topic Reply with quote

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
View users profile Send private message Add User to Ignore List
BugZap
Guest


Offline

PostPosted: Sat Aug 25, 2007 11:46 am    Post subject: Reply to topic Reply with quote

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!
I'll count you!


Age:37
Gender:Gender:Male
Joined: Jul 14 2003
Posts: 4608
Location: A Dream
Offline

PostPosted: Mon Aug 27, 2007 1:43 pm    Post subject: Reply to topic Reply with quote

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
View users profile Send private message Add User to Ignore List Visit posters website
BugZap
Guest


Offline

PostPosted: Mon Aug 27, 2007 3:23 pm    Post subject: Reply to topic Reply with quote

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!
I'll count you!


Age:37
Gender:Gender:Male
Joined: Jul 14 2003
Posts: 4608
Location: A Dream
Offline

PostPosted: Tue Aug 28, 2007 12:39 pm    Post subject: Reply to topic Reply with quote

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
View users profile Send private message Add User to Ignore List Visit posters website
Display posts from previous:   
Post new topic   Reply to topic    Server Help Forum Index -> Bot Questions All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
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
View online users | View Statistics | View Ignored List


Software by php BB © php BB Group
Server Load: 266 page(s) served in previous 5 minutes.

phpBB Created this page in 0.457209 seconds : 41 queries executed (89.7%): GZIP compression disabled