Author | Message | Time |
---|---|---|
Mephisto | 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++. | March 4, 2004, 1:23 AM |
Null | For someone who knows 10 or so language's Fluently this should be an easy task.. | March 4, 2004, 1:25 AM |
Mephisto | 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. | March 4, 2004, 1:27 AM |
LoRd | Go to the C/C++ programming forum. | March 4, 2004, 2:08 AM |
Mephisto | 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. | March 4, 2004, 2:43 AM |
Zakath | 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. | March 4, 2004, 6:47 AM |
K | I like to use a std::map to map battle.net names to unique bot names, to map to user info. something like [code] 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; [/code] | March 4, 2004, 7:05 AM |
Myndfyr | 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: [code] 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); } [/code] 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. | March 4, 2004, 6:20 PM |
Adron | 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: [code] struct User { char name[MAX_NAME]; unsigned flags; }; [/code] A command could then be: [code] struct Command { char trigger[MAX_TRIGGER]; unsigned positiveflags; unsigned negativeflags; void (*processcommand)( ... ); }; [/code] [code] if((user.flags & cmd.positiveflags) && !(user.flags & cmd.negativeflags)) cmd.processcommand(...); [/code] | March 5, 2004, 5:09 PM |
DarkMinion | First I have a struct: [code]struct User{ char szMask[32]; unsigned long dwFlags; };[/code] Then a list (if you want my linked list class you can have that too, just ask): [code] List<User *> Database; [/code] Then I use these 3 functions to set/remove/check my flags (thanks Sky for these, btw): [code] 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')); } [/code] So say I wanted to make a new DB entry I would do something like... [code] 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); [/code] If I wanted to modify an entry's flags, I would do something like... [code] //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 [/code] If you have questions, feel free to ask...I'll post a link to my linked list class if you want it. | March 5, 2004, 6:06 PM |
Kp | 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.] | March 5, 2004, 10:13 PM |
DarkMinion | Sorry, forgot to initialize flags...thanks for reminding me Kp, fixed. | March 6, 2004, 1:24 AM |