Valhalla Legends Archive

Programming => Battle.net Bot Development => Topic started by: Mephisto on March 03, 2004, 07:23 PM

Title: Setting Bot Users - Method
Post by: Mephisto on March 03, 2004, 07:23 PM
I'm new to this whole bot development thing, and I have recently finished coding the necessary code to connect to Battle.net and receive/parse chat events.  Now I am moving on to writing the database, and I am wondering how to do this.  How do I represent a user?  I was thinking of just having the bot read from a database file and get the username and their flags.  That brings me to my next question, how should I represent flags?  I was thinking of writing a class for each flag, and in that class write each of the commands as a function.  But then I get to the point of how do I add a flag (class) to that username, and limit access to other flags (classes)?  I havn't put much thought into it, but I will be thinking of ideas as I get feedback from those who can assist in this.

Keep in mind, this is being written in C++.
Title: Re:Setting Bot Users - Method
Post by: effect on March 03, 2004, 07:25 PM
For someone who knows 10 or so language's Fluently this should be an easy task..
Title: Re:Setting Bot Users - Method
Post by: Mephisto on March 03, 2004, 07:27 PM
You guys are fast.

I never said I knew 10 languages, let alone knew them fluently.

Additionally, I said in the post I havn't put much thought into it, I'm already applying some ideas.  This is just to get some feedback on experienced people in doing this, so I don't go implement a system which would be otherwise infurior to other methods which can be used.

Edit: Well, I suppose it's 10 if you count English.  But I still stand by the fact I never said I knew them fluently.
Title: Re:Setting Bot Users - Method
Post by: Eric on March 03, 2004, 08:08 PM
Go to the C/C++ programming forum.
Title: Re:Setting Bot Users - Method
Post by: Mephisto on March 03, 2004, 08:43 PM
If this was C/C++ specific, I think someone would have moved it by now.

Additionally, you don't necessarily have to know C++ to help me out with this.
Title: Re:Setting Bot Users - Method
Post by: Zakath on March 04, 2004, 12:47 AM
Represent a user's flags as a bitmask. When you retrieve a user's information from the database file, convert each flag into the equivalent value, then construct the bitmask out of them. Then when processing a command, simply see if they have the necessary flag by using the & operator.
Title: Re:Setting Bot Users - Method
Post by: K on March 04, 2004, 01:05 AM
I like to use a std::map to map battle.net names to unique bot names, to map to user info.
something like


class BotUserInfo
{
public:
  // the name to call the user
  std::string ReferenceName;

  std::vector<std::string> AccountNames;
  std::string Email;
  std::string AIM;
 
  bool CanBan() { return (Flags & bn::BAN_MASK); }
  bool CanKick() { return (Flags & bn::KICK_MASK); }
  // etc or:
  bool GetPriv(unsigned int mask) { return (Flags & mask); }

  void SetPriv(unsigned int mask) { Flags |= mask; }
private:
  unsigned int Flags;
};


// now we can translate one of several battle.net names
// into a unique user account name
std::map<std::string, std::string>  UserLookup;

// and that account name into the user's info.
std::map<std::string, bn::BotUserInfo>  UserInfo;



Title: Re:Setting Bot Users - Method
Post by: MyndFyre on March 04, 2004, 12:20 PM
I'm big on extensions, so I created a simple interface (IUser) that any extension assembly (note that I'm writing in C#, so it's .NET) can provide their own implementation and then just pass that around.  I also defined an interface for a data provider such as:


public interface IDataProvider {
 IUser GetUser(string szUserName);
 IUser CreateUser(string szUserName, int dwRank);
 //etc...
 void SendBotMail(IUser sender, IUser receiver, string Message);
 IBotMaiil[] GetMessages(IUser receiver);
}


That is obviously not the entire idea, but I believe if you define well first how you want your database to behave, you'll find yourself in a much better position down the road.
Title: Re:Setting Bot Users - Method
Post by: Adron on March 05, 2004, 11:09 AM
I tend to like having flags. If 32 flags is enough for you, use a bitmap. For maximum configurability, allow users to be given any combination of flags, and allow commands or actions to require any combination of flags.

A user could then be:

struct User {
  char name[MAX_NAME];
  unsigned flags;
};


A command could then be:


struct Command {
  char trigger[MAX_TRIGGER];
  unsigned positiveflags;
  unsigned negativeflags;
  void (*processcommand)( ... );
};



if((user.flags & cmd.positiveflags) && !(user.flags & cmd.negativeflags))
   cmd.processcommand(...);


Title: Re:Setting Bot Users - Method
Post by: DarkMinion on March 05, 2004, 12:06 PM
First I have a struct:

struct User{
   char szMask[32];
   unsigned long dwFlags;
};


Then a list (if you want my linked list class you can have that too, just ask):


List<User *> Database;


Then I use these 3 functions to set/remove/check my flags (thanks Sky for these, btw):


bool CheckFlag(unsigned long dwMask, char bFlag)
{
   if(bFlag < 'A' || bFlag > 'Z')
      return false;
   return !!(dwMask & (1 << (bFlag - 'A')));
}

void SetFlag(unsigned long *dwMask, char bFlag)
{
   if(bFlag < 'A' || bFlag > 'Z')
      return;
   *dwMask |= (1 << (bFlag - 'A'));
}

void RemoveFlag(unsigned long *dwMask, char bFlag)
{
   if(bFlag < 'A' || bFlag > 'Z')
      return;
   *dwMask &= ~(1 << (bFlag - 'A'));
}


So say I wanted to make a new DB entry I would do something like...


User *pNew = new User;
strcpy(pNew->szMask, "testuser"); //set the user mask
pNew->dwFlags = 0;
SetFlag(pNew->dwFlags, 'A'); //set flag(s)
Database.Add(pNew);


If I wanted to modify an entry's flags, I would do something like...


//find the user
User *p;
for(int i = 0; i < Database.Count(); i++){
   p = Database.Get(i);
   if(!stricmp(szEntryToFind, p->szMask))
      break;
}
//modify
RemoveFlag(p->dwFlags, 'N'); //or whatever


If you have questions, feel free to ask...I'll post a link to my linked list class if you want it.
Title: Re:Setting Bot Users - Method
Post by: Kp on March 05, 2004, 04:13 PM
Minor suggested improvement to DarkMinion's approach -- since you're already using new to allocate the structure, it'll take care of calling a constructor if you provide one.  As such, you could have two constructors: default, which sets name = "" and flags to 0, and one that takes a const char* and an unsigned, and saves the string + flags into the user structure before returning.  It wouldn't be any more or less efficient runtime wise afaik, but it would make for simpler user creation code. :)

[Edit: just noticed that DarkMinion's code will actually produce a user with unpredictable flags.  SetFlag is more properly AddFlag, and the flags aren't being set to a known value first.  Therefore, your only guarantee is that the resulting user will have 'A' as a flag -- he might have other flags as well.  To avoid this, explicitly set the flags variable to zero.]
Title: Re:Setting Bot Users - Method
Post by: DarkMinion on March 05, 2004, 07:24 PM
Sorry, forgot to initialize flags...thanks for reminding me Kp, fixed.