Author | Message | Time |
---|---|---|
iago | This isn't complete, but I got bored with it, so it's as complete as it's getting without somebody else contributing. Here it is: [code]#include "ParseStatString.h" #include <string> #include <strstream> using namespace std; const char *Races[] = { "Unknown", "Amazon", "Sorceress", "Necromancer", "Paladin", "Barbarian", "Druid", "Assassin", "Unknown", "Unknown (Grey)", "Unknown (Grey)", "Diablo 1", "Diablo 1", "Diablo 1", "Starcraft Marine", "Brood War Medic", "Warcraft II Grunt", "Blizzard Rep", "Moderator", "Sysop", "Referee", "Chat", "Speaker" }; string ParseStatString::GetStatString(char *SS) { string Product = SS; strstream Return; Product.resize(4); DWORD a, b, c, d, e, f, g, h, i, j; if(Product == "RHSS") { return "using Starcraft Shareware"; } if(Product == "RATS" || Product == "PXES" || Product == "NB2W") { if(Product[0] == 'R') Return << "using Starcraft"; else if(Product[0] == 'P') Return << "using Starcraft Broodwar"; else Return << "using Warcraft II"; if(sscanf(SS + 5, "%d %d %d %d %d %d %d %d %d", &a, &b, &c, &d, &e, &f, &g, &h, &i, &j) != 9) { Return << (BYTE)0; return Return.str(); } else { if(d) Return << " spawn"; if(a > 0) { Return << " (" << c << " wins, ladder: " << a << ", ladder max: " << f << ")"; } else { Return << " (" << c << " wins)"; } Return << (BYTE) 0; return Return.str(); } } if(Product == "PX2D" || Product == "VD2D") { if(Product == "PX2D") { Return << "using Diablo 2: LoD"; } else { Return << "using Diablo 2"; } SS += 4; char *CharName = strchr(SS, ','); // Make sure there was a comma in it if(CharName == NULL) { Return << (BYTE) '\0'; return Return.str(); } // Set the last character in the realm to NULL *CharName = '\0'; // Put the realm into a string string Realm = SS; // Go to the first character of the character name CharName++; // Get the first part of the stats section char *Stats = strchr(CharName, ','); // If no comma was found, return what we have if(Stats == NULL || strlen(Stats + 1) != 33) { Return << (BYTE) '\0'; return Return.str(); } // Set the end of CharName to NULL *Stats = '\0'; Stats++; string Character = CharName; // Ok, we must be good, we will parse the rest of it now BYTE Level = Stats[25]; BYTE Race = Stats[13]; BOOL Hardcore = (BOOL)(Stats[26] & 4); BOOL Dead = (BOOL)(Stats[26] & 8); BYTE Helmet = Stats[2]; BYTE Weapon = Stats[7]; BYTE Shield = Stats[9]; if(Race > 22) { Race = 0; } string strRace = Races[Race]; string strHelm; switch(Helmet) { case 4: case 57: strHelm = "Cap"; break; case 5: case 58: strHelm = "Skullcap"; break; case 6: case 59: strHelm = "Helm"; break; case 7: case 60: strHelm = "Fullhelm"; break; case 8: case 61: strHelm = "Greathelm"; break; case 10: case 63: strHelm = "Mask"; break; case 40: case 82: strHelm = "Bonehelm"; break; case 89: strHelm = "Fanged Helm"; break; case 90: strHelm = "Warhelm"; break; case 91: strHelm = "Winged Helm"; break; default: strHelm = "No helm ("; strHelm += (int) Helmet; strHelm += ")"; break; } string strWeapon; switch(Weapon) { case 4: strWeapon = "Hatchet/Waraxe"; // break; case 5: strWeapon = "Axe"; // break; case 6: strWeapon = "Large Axe 6"; break; case 7: strWeapon = "Large Axe 7"; break; case 8: strWeapon = "Great Axe"; break; case 9: strWeapon = "Wand 9"; break; case 10: strWeapon = "Wand 10"; break; case 11: strWeapon = "Wand 11"; break; case 12: strWeapon = "Spiked Club"; // break; case 13: strWeapon = "Scepter"; // break; case 14: strWeapon = "Hammer"; break; case 15: strWeapon = "Flail"; break; case 16: strWeapon = "Maul"; break; case 17: strWeapon = "Short Sword"; break; case 18: strWeapon = "Scimitar/Saber"; // break; case 19: strWeapon = "Warsword"; // break; case 20: strWeapon = "Crystal Sword"; break; case 21: strWeapon = "Sword 21"; break; case 22: strWeapon = "Sword 22"; break; case 23: strWeapon = "Sword 23"; break; case 24: strWeapon = "Sword 24"; break; case 25: strWeapon = "Dagger"; // break; case 26: strWeapon = "Dirk/Kris"; // break; case 27: strWeapon = "Unk 27"; break; case 28: strWeapon = "Unk 28"; break; case 29: strWeapon = "Unk 29"; break; case 30: strWeapon = "Spear"; // break; case 31: strWeapon = "Trident"; break; case 32: strWeapon = "Spetum"; break; case 33: strWeapon = "Pike"; break; case 34: strWeapon = "Bardiche/Halberd"; // break; case 35: strWeapon = "Sickle"; break; case 36: strWeapon = "Poleaxe"; break; case 37: strWeapon = "Staff 37"; break; case 38: strWeapon = "Staff 38"; break; case 39: strWeapon = "Staff 39"; break; case 40: strWeapon = "Staff 40"; break; case 49: strWeapon = "Unk 49"; break; case 50: strWeapon = "Unk 50"; break; case 56: strWeapon = "Unk 56"; break; case 121: strWeapon = "Unk 121"; break; case 122: strWeapon = "Unk 122"; break; case 123: strWeapon = "Unk 123"; break; case 124: strWeapon = "Unk 124"; break; case 125: strWeapon = "Poison Potion"; break; case 126: strWeapon = "Fulmigating Potion"; break; case 127: strWeapon = "Potion 3"; break; case 128: strWeapon = "Potion 4"; break; case 129: strWeapon = "Potion 5"; break; default: strWeapon = "No weapon ("; strWeapon += (int)Weapon; strWeapon += ")"; } string strShield; switch(Shield) { case 79: strShield = "Small shield"; break; case 80: strShield = "Buckler"; break; case 81: strShield = "Kite Shield"; break; case 82: strShield = "Tower Shield"; break; case 84: strShield = "Bone Shield"; break; case 85: strShield = "Spiked Shield"; break; case 92: strShield = "Rondache"; break; case 94: strShield = "Crown Shield"; break; default: strShield = "No Shield ("; strShield += (int)Shield; strShield += ")"; } // Now that we have all the pieces, build the packet Return << " (" << Character << ", a level " << (int)Level << " " << Races[Race] << " using a " << strWeapon << ", a " << strHelm << ", and a " << strShield; if(Hardcore) Return << ", Hardcore"; if(Dead) Return << ", Dead"; Return << ")" << (BYTE) '\0'; return Return.str(); } if(Product == "LTRD" || Product == "RHSD") { if(Product == "LTRD") Return << "using Diablo"; else Return << "using Diablo Shareware"; if(sscanf(SS + 5, "%d %d %d %d %d %d %d %d %d", &a, &b, &c, &d, &e, &f, &g, &h, &i, &j) != 9) { Return << (BYTE) '\0'; return Return.str(); } Return << ", a Level " << a; if(b == 0) { Return << " warrior"; } else if(b == 1) { Return << " rogue"; } else if(b == 2) { Return << " sorcerer"; } Return << " with " << c << " dots, " << d << " strength, " << e << " magic, " << f << " dexterity, " << g << " vitality, and " << h << " gold" << (BYTE) '\0'; return Return.str(); } if(Product == "TAHC") { Return << "using a Chat Bot" << (BYTE) '\0'; } if(Product == "3RAW") { Return << "using Warcraft 3" << (BYTE) 0; return Return.str(); } Return << "with an unrecognized statstring: " << SS << '\0'; return Return.str(); } [/code] | October 3, 2003, 8:47 PM |
iago | hmm, I guess I should also post the .h file: [code] #ifndef PARSESTATSTRING_H #define PARSESTATSTRING_H #include <windows.h> #include <iostream> using namespace std; class ParseStatString { public: ParseStatString(); static string GetStatString(char *SS); }; #endif[/code] | October 3, 2003, 8:48 PM |
UserLoser | ;D Thanks a ton - now for me to change it to VB :P | October 3, 2003, 8:48 PM |
iago | lol, no. It's not terribly complicated code, for the most part.. shouldn't be horribly difficult to translate :) | October 3, 2003, 8:49 PM |
K | Just as a really picky sidenote, you shouldn't use [code] using namespace std; [/code] in a header file, since it will e(a?)ffect all the source files that include it, which can cause some undesired naming conflicts. I'll usually write out the fully qualified name (std::string) in the header, and then add using declarations in the source file. But other than that teeny point, nicely done. | October 3, 2003, 10:02 PM |
St0rm.iD | Wow...someone actually uses the std c++ string class!? | October 4, 2003, 12:08 AM |
K | [quote author=St0rm.iD link=board=17;threadid=2937;start=0#msg22941 date=1065226135] Wow...someone actually uses the std c++ string class!? [/quote] The real question is why anyone wouldn't use it. Goodbye dealing with null terminator; goodbye strcmp, strcat, strcpy; goodbye buffer overflows; goodbye possible memory leaks... | October 4, 2003, 12:19 AM |
Eibro | If i'm not mistaken, std::strstream is deprecated. You should use header file sstream instead. std::ostringstream/std::istringstream/std::stringstream should offer the same functionality. | October 4, 2003, 12:55 AM |
St0rm.iD | K, I know the benefits, but no one uses it. | October 4, 2003, 1:57 AM |
Kp | [quote author=K link=board=17;threadid=2937;start=0#msg22942 date=1065226754]The real question is why anyone wouldn't use it.[/quote]When was the last time you saw a system call that took or returned an std::string? STL may be nice for intraprocess work, but it can be a nuisance when you're regularly passing things into and out of the OS. | October 4, 2003, 2:31 AM |
iago | We use std::string and strstream in school for assignments, so that's why I use it; a lot of people use is, especially at school. And Kp is right - but I'm not using any API calls, so life is good. And K - I've never had a problem with setting that namespace in .h files, but that's the only namespace I ever use. | October 4, 2003, 3:18 AM |