diff --git a/bin/scripts/reply.def b/bin/scripts/reply.def index 8772262..fc736a2 100644 --- a/bin/scripts/reply.def +++ b/bin/scripts/reply.def @@ -2,7 +2,7 @@ SET,player ${@thiswhisper_name} SET,lang ${@0} -DEAULT,lang ${@thiswhisper_lang} +DEFAULT,lang ${@thiswhisper_lang} SET,msg ${@def} WHISPER,{${player}},{${lang}} ${msg} diff --git a/src/Client/ConfigReader.cpp_ b/src/Client/ConfigReader.cpp_ deleted file mode 100644 index 6e6fda3..0000000 --- a/src/Client/ConfigReader.cpp_ +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include "common.h" -#include "PseuWoW.h" -#include "DefScript/DefScript.h" -#include "ConfigReader.h" - -bool ConfigReader::ReadConf(std::string fn, VarSet& vs, bool capitalize){ - std::fstream f; - char z; - std::string line,label,value; - - f.open(fn.c_str(), std::ios_base::in); - if(!f) - return false; - while(!f.eof()){ - line.clear(); - while (true) { - f.get(z); - if(z=='\n' || f.eof()) - break; - line+=z; - } - if(line.empty()) - continue; // line is empty, proceed with next line - while( (line.at(0)==' ' || line.at(0)=='\t') ) - line.erase(0,1); - if(line.empty()) - continue; - if(line.at(0)=='/' && line.at(1)=='/') - continue; // line is comment, proceed with next line - label=line.substr(0,line.find('=',0)); - if(capitalize) - label=stringToUpper(label); - value=line.substr(line.find('=',0)+1,line.length()); - - DEBUGMODE(printf("CONF: '%s' = '%s'\n",label.c_str(),value.c_str());); - vs.Set(label,value); - } - f.close(); - return true; -} - -void ConfigReader::SetMainConf(VarSet& vs){ - - if(vs.Exists("DEBUG")){ - DEBUG=atoi(vs.Get("DEBUG").c_str()); - DEBUG1(printf("DEBUG level=%d\n",DEBUG);); - } - if(vs.Exists("REALMLIST")){ - strcpy(realmlist,vs.Get("REALMLIST").c_str()); - if(DEBUG>=1)printf("Realmlist set to \"%s\"\n",realmlist); - } - if(vs.Exists("ACCNAME")){ - strcpy(accname,vs.Get("ACCNAME").c_str()); - if(DEBUG>=1)printf("Account Name set to \"%s\"\n",accname); - } - if(vs.Exists("ACCPASS")){ - strcpy(accpass,vs.Get("ACCPASS").c_str()); - if(DEBUG>=1)printf("Account Password set to \"%s\"\n",accpass); - } - if(vs.Exists("ALLOWCONTROLLER")){ - std::string opt=vs.Get("ALLOWCONTROLLER"); - if( opt=="1" || opt=="true" || opt=="on" ){ - allowcontroller=true; - }else{ - allowcontroller=false; - } - } - if(vs.Exists("EXITONERROR")){ - std::string opt=vs.Get("EXITONERROR"); - if( opt=="1" || opt=="true" || opt=="on" ){ - exitonerror=true; - }else{ - exitonerror=false; - } - } - if(vs.Exists("CONTROLLERPORT")){ - c_port=atoi(vs.Get("CONTROLLERPORT").c_str()); - if(DEBUG>=1)printf("Controller Port set to %d\n",c_port); - } - if(vs.Exists("REALMPORT")){ - rs_port=atoi(vs.Get("REALMPORT").c_str()); - if(DEBUG>=1)printf("Realm Server Port set to %d\n",rs_port); - } - if(vs.Exists("CLIENTVERSION")){ // e.g. 1.10.2 -- max number in this case is 255.255.255 -> address a matrix of 3x3 - std::string opt=vs.Get("CLIENTVERSION")+"."; - std::string num; - uint8 p=0; - for(uint8 i=0;i2) - break; - continue; - } - num+=opt.at(i); - } - DEBUG1(printf("Emulating client version %d.%d.%d\n",clientversion[0],clientversion[1],clientversion[2]);); - } - if(vs.Exists("CLIENTBUILD")){ - clientbuild=atoi(vs.Get("CLIENTBUILD").c_str()); - if(DEBUG>=1)printf("Client Build set to %d\n",clientbuild); - } - if(vs.Exists("CLIENTLANG")){ - char *opt=(char*)vs.Get("CLIENTLANG").c_str(); - clientlang[0]=opt[0]; - clientlang[1]=opt[1]; - clientlang[2]=opt[2]; - clientlang[3]=opt[3]; - DEBUG1(printf("Client language set to \"%c%c%c%c\"\n",clientlang[0],clientlang[1],clientlang[2],clientlang[3]);); - } - if(vs.Exists("REALMNAME")){ - strcpy(realmname,vs.Get("REALMNAME").c_str()); - if(DEBUG>=1)printf("Realm Name set to \"%s\"\n",realmname); - } - if(vs.Exists("CHARNAME")){ - charname=vs.Get("CHARNAME"); - if(DEBUG>=1)printf("Character Name set to \"%s\"\n",charname.c_str()); - } - if(vs.Exists("IDLESLEEPTIME")){ - idleSleepTime=atoi(vs.Get("IDLESLEEPTIME").c_str()); - if(DEBUG>=1)printf("Idle Sleep Time set to \"%u\"\n",idleSleepTime); - } - - defScp.RunScriptByName("_setconf",NULL,255); - - // more conf? - -} - - diff --git a/src/Client/ConfigReader.h_ b/src/Client/ConfigReader.h_ deleted file mode 100644 index a816a49..0000000 --- a/src/Client/ConfigReader.h_ +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _CONFIGREADER_H -#define _CONFIGREADER_H - -#include "DefScript/DefScript.h" - -namespace ConfigReader { - - bool ReadConf(std::string, VarSet&, bool); - void SetMainConf(VarSet&); - void SetUsersConf(VarSet&); - - -}; - -#endif diff --git a/src/Client/DefScript/DefScript.cpp b/src/Client/DefScript/DefScript.cpp index a02efd3..9eac128 100644 --- a/src/Client/DefScript/DefScript.cpp +++ b/src/Client/DefScript/DefScript.cpp @@ -75,6 +75,7 @@ DefScriptFunctionTable *DefScriptPackage::_GetFunctionTable(void) const {"logerror",&DefScriptPackage::SClogerror}, {"logdebug",&DefScriptPackage::SClogdebug}, {"castspell", &DefScriptPackage::SCcastspell}, + {"queryitem", &DefScriptPackage::SCqueryitem}, // table termination {NULL,NULL} diff --git a/src/Client/DefScript/DefScript.h b/src/Client/DefScript/DefScript.h index 5f7fd6a..0fac547 100644 --- a/src/Client/DefScript/DefScript.h +++ b/src/Client/DefScript/DefScript.h @@ -156,6 +156,7 @@ private: bool SClogdebug(CmdSet); bool SClogerror(CmdSet); bool SCcastspell(CmdSet); + bool SCqueryitem(CmdSet); // Own variable declarations std::map my_usrPermissionMap; diff --git a/src/Client/DefScript/ParsingFunctions.cpp_ b/src/Client/DefScript/ParsingFunctions.cpp_ deleted file mode 100644 index d694177..0000000 --- a/src/Client/DefScript/ParsingFunctions.cpp_ +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include -#include "ParsingFunctions.h" -#include "../GarbageStack.h" - -char *strparse::fgetlabel(char *line){ - //printf("Extracting label..."); - char *ret; - int i,len; - for(i=0;line[i]!='=';i++); - len=i; - ret=NewTempString(len); - for(i=0;i "blah \0/ crap\0" -> "blah \0" - } - return txt; -} - -char *strparse::TrimSpacesLeft(char *txt){ - int len=strlen(txt); - if(len<1)return txt; - for(int p=0;p<=len;p++) - if(txt[0]==' '||txt[0]==' ') - txt++; - else - return txt; -} - -bool strparse::HasEqual(char *in){ - if(strchr(in,(char)'=')==NULL)return false; else return true; -} diff --git a/src/Client/DefScript/ParsingFunctions.h_ b/src/Client/DefScript/ParsingFunctions.h_ deleted file mode 100644 index 9a4394b..0000000 --- a/src/Client/DefScript/ParsingFunctions.h_ +++ /dev/null @@ -1,10 +0,0 @@ - -namespace strparse { - -char *fgetlabel(char*); -char *fgetvalue(char*); -char *RemoveComments(char*); -char *TrimSpacesLeft(char*); -bool HasEqual(char*); - -} \ No newline at end of file diff --git a/src/Client/DefScriptInterface.cpp b/src/Client/DefScriptInterface.cpp index ac7a806..d99e728 100644 --- a/src/Client/DefScriptInterface.cpp +++ b/src/Client/DefScriptInterface.cpp @@ -49,13 +49,17 @@ bool DefScriptPackage::SCSendChatMessage(CmdSet Set){ bool DefScriptPackage::SCsavecache(CmdSet Set){ ((PseuInstance*)parentMethod)->SaveAllCache(); - std::stringstream tmp; - std::string str; + std::stringstream str; if(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid()) { - tmp << ((PseuInstance*)parentMethod)->GetWSession()->plrNameCache.GetSize(); - str+="Cache saved. [ "+tmp.str()+ " Playernames ]"; - ((PseuInstance*)parentMethod)->GetWSession()->SendChatMessage(CHAT_MSG_SAY,0,str,""); + str << "Cache saved. [ "; + str << ((PseuInstance*)parentMethod)->GetWSession()->plrNameCache.GetSize(); + str << " Playernames, "; + str << ((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetItemProtoCount(); + str << " Item Prototypes"; + str << " ]"; + + ((PseuInstance*)parentMethod)->GetWSession()->SendChatMessage(CHAT_MSG_SAY,0,str.str(),""); } return true; } @@ -190,6 +194,20 @@ bool DefScriptPackage::SCcastspell(CmdSet Set) return true; } +bool DefScriptPackage::SCqueryitem(CmdSet Set){ + uint32 id = atoi(Set.defaultarg.c_str()); + if(!id) + return true; + + if(!(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())) + { + logerror("Invalid Script call: SCqueryitem: WorldSession not valid"); + return false; + } + ((PseuInstance*)parentMethod)->GetWSession()->SendQueryItem(id,0); + return true; +} + void DefScriptPackage::My_LoadUserPermissions(VarSet &vs) { static char *prefix = "USERS::"; diff --git a/src/Client/PseuWoW.cpp b/src/Client/PseuWoW.cpp index 382df8b..d136fdf 100644 --- a/src/Client/PseuWoW.cpp +++ b/src/Client/PseuWoW.cpp @@ -11,6 +11,8 @@ #include "DefScript/DefScript.h" #include "Realm/RealmSocket.h" #include "World/WorldSession.h" +#include "CacheHandler.h" + #include "Cli.h" @@ -206,6 +208,7 @@ void PseuInstance::SaveAllCache(void) if(GetWSession() && GetWSession()->IsValid()) { GetWSession()->plrNameCache.SaveToFile(); + ItemProtoCache_WriteDataToCache(GetWSession()); //... } } diff --git a/src/Client/Realm/RealmAuth.cpp_ b/src/Client/Realm/RealmAuth.cpp_ deleted file mode 100644 index fa94107..0000000 --- a/src/Client/Realm/RealmAuth.cpp_ +++ /dev/null @@ -1,150 +0,0 @@ -#include "basics.h" -#include "PseuWoW.h" -#include "RealmAuth.h" -#include "Auth/BigNumber.h" -#include "Auth/Sha1.h" -#include "realmfunc.h" - -#define BNLEN 32 // length of the hard-coded N blizz uses, has been 32 since the first alpha of WoW - -extern BigNumber sessionkey; // defined in WorldPacketHandler.cpp - -void ProcessClientLogonProof(char *pkt){ - BigNumber N,A,B,a,u,x,v,S,salt,unk1,g,k(3); // init BNs, default k to 3 - char _auth[128]; - strcpy(_auth,strupr(accname)); - strcat(_auth,":"); - strcat(_auth,strupr(accpass)); - DEBUG3(printf("Authentication String=\"%s\"\n",_auth);) - char N_str[BNLEN+1],g_str[2],salt_str[BNLEN+1],unk1_str[16+1],B_str[BNLEN+1]; // +1 for '\0' - - // extract data from packet - memcpy(B_str,&pkt[3],32);B_str[32]=0; - memcpy(g_str,&pkt[36],1);g_str[1]=0; - memcpy(N_str,&pkt[38],32);N_str[32]=0; - memcpy(salt_str,&pkt[70],32);salt_str[32]=0; - memcpy(unk1_str,&pkt[102],16);unk1_str[16]=0; - - // debug output - DEBUG3(printchex(B_str,BNLEN,true);) - DEBUG3(printchex(g_str,1,true);) - DEBUG3(printchex(N_str,BNLEN,true);) - DEBUG3(printchex(salt_str,BNLEN,true);) - DEBUG3(printchex(unk1_str,16,true);) - - // convert into BigNumbers - B.SetBinary((const uint8*)B_str,BNLEN); - g.SetBinary((const uint8*)g_str,1); - N.SetBinary((const uint8*)N_str,BNLEN); - salt.SetBinary((const uint8*)salt_str,BNLEN); - unk1.SetBinary((const uint8*)unk1_str,16); - - // client-side BN calculations: - DEBUG3(printf("--> k=%s\n",k.AsHexStr());) - a.SetRand(19*8); - Sha1Hash userhash,xhash,uhash; - std::string _authstr(_auth); - userhash.UpdateData(_authstr); - userhash.Finalize(); - xhash.UpdateData(salt.AsByteArray(),salt.GetNumBytes()); - xhash.UpdateData(userhash.GetDigest(),userhash.GetLength()); - xhash.Finalize(); - x.SetBinary(xhash.GetDigest(),xhash.GetLength()); - DEBUG3(printf("--> x=%s\n",x.AsHexStr());) - v=g.ModExp(x,N); - DEBUG3(printf("--> v=%s\n",v.AsHexStr());) - A=g.ModExp(a,N); - DEBUG3(printf("--> A=%s\n",A.AsHexStr());) - uhash.UpdateBigNumbers(&A, &B, NULL); - uhash.Finalize(); - u.SetBinary(uhash.GetDigest(), 20); - DEBUG3(printf("--> u=%s\n",u.AsHexStr());) - S=(B - k*g.ModExp(x,N) ).ModExp((a + u * x),N); - DEBUG3(printf("--> S=%s\n",S.AsHexStr());) - - // calc M1 & M2 - unsigned int i=0; - char S1[16+1],S2[16+1]; // 32/2=16 :) +1 for \0 - // split it into 2 seperate strings, interleaved - - for(i=0;i<=15;i++){ - S1[i]=S.AsByteArray()[i*2]; - S2[i]=S.AsByteArray()[i*2+1]; - } - //printchex(S1);printchex(S2); - // hash each one: - Sha1Hash S1hash,S2hash; - S1hash.UpdateData((const uint8*)S1,16); - S1hash.Finalize(); - S2hash.UpdateData((const uint8*)S2,16); - S2hash.Finalize(); - // Re-combine them - char S_hash[40+1]; // 2*Sha1Len+1 for \0 - for(i=0;i<20;i++){ - S_hash[i*2]=S1hash.GetDigest()[i]; - S_hash[i*2+1]=S2hash.GetDigest()[i]; - } - sessionkey.SetBinary((uint8*)S_hash,40); // used later when authing to world - //printf("-> S_hash=");printchex(S_hash,40,true); - - char Ng_hash[20+1]; - Sha1Hash userhash2,Nhash,ghash; - userhash2.UpdateData((const uint8*)strupr(accname),strlen(accname)); - userhash2.Finalize(); - //printchex((char*)userhash2.GetDigest(),userhash2.GetLength(),true); - Nhash.UpdateBigNumbers(&N,NULL); - Nhash.Finalize(); - ghash.UpdateBigNumbers(&g,NULL); - ghash.Finalize(); - for(i=0;i<20;i++)Ng_hash[i] = Nhash.GetDigest()[i]^ghash.GetDigest()[i]; - //printchex(Ng_hash,20,true); - - BigNumber t_acc,t_Ng_hash; - t_acc.SetBinary((const uint8*)userhash2.GetDigest(),userhash2.GetLength()); - t_Ng_hash.SetBinary((const uint8*)Ng_hash,20); - - - Sha1Hash M1hash,M2hash; - - M1hash.UpdateBigNumbers(&t_Ng_hash,&t_acc,&salt,&A,&B,NULL); - M1hash.UpdateData((const uint8*)S_hash,40); - M1hash.Finalize(); - - M2hash.UpdateBigNumbers(&A,NULL); - M2hash.UpdateData((const uint8*)M1hash.GetDigest(),M1hash.GetLength()); - M2hash.UpdateData((const uint8*)S_hash,40); - M2hash.Finalize(); - - - DEBUG3( - printf("--> M1=");printchex((char*)M1hash.GetDigest(),20,true);\ - printf("--> M2=");printchex((char*)M2hash.GetDigest(),20,true);\ - ) - - // Calc CRC & CRC_hash - // i don't know yet how to calc it, so set it to zero - char crc_hash[20+1]; - nullify(crc_hash,20); - - - // now lets prepare the packet - DEBUG2(printf("Calculations finished, preparing packet...\n");) - char outpkt[100]; - memset(outpkt,0,100); - outpkt[0]=0x01; // opcode: CLIENT_GOGON_PROOF - memcpy(&outpkt[1],A.AsByteArray(),BNLEN); - memcpy(&outpkt[33],M1hash.GetDigest(),M1hash.GetLength()); - memcpy(&outpkt[53],crc_hash,20); // TODO: as soon as crc_hash is calculated, correct this line! - outpkt[73]=0; // number_of_keys=0 - outpkt[74]=0; // unk=0 (added in 1.12.1) - DEBUG3(printf("... finished, packet content=");printchex(outpkt,73,true);) - memcpy(Auth_M2,M2hash.GetDigest(),M2hash.GetLength()); // save M2 to an extern var to check it later - DEBUG2(printf("Sending packet\n");) - if(clientbuild>5302) - realmCon.Send(outpkt,75); // 1.11.x and upwards - else - realmCon.Send(outpkt,74); // < 1.11.x compatibility - - - -} \ No newline at end of file diff --git a/src/Client/Realm/RealmAuth.h_ b/src/Client/Realm/RealmAuth.h_ deleted file mode 100644 index 940da86..0000000 --- a/src/Client/Realm/RealmAuth.h_ +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _REALMAUTH_H -#define _REALMAUTH_H - -void ProcessClientLogonProof(char*); - -#endif \ No newline at end of file diff --git a/src/Client/Realm/RealmListHandler.cpp_ b/src/Client/Realm/RealmListHandler.cpp_ deleted file mode 100644 index 6202214..0000000 --- a/src/Client/Realm/RealmListHandler.cpp_ +++ /dev/null @@ -1,62 +0,0 @@ -#include "basics.h" -#include "PseuWoW.h" -#include "Auth/ByteBuffer.h" -#include "RealmListHandler.h" -#include "realmfunc.h" - -// process a given realmlist packet - -struct SRealmInfo - { - uint32 icon; // icon near realm - uint8 color; // color of record - std::string name; // Text zero terminated name of Realm - std::string addr_port; // Text zero terminated address of Realm ("ip:port") - float population; // 1.6 -> population value. lower == lower population and vice versa - uint8 chars_here; // number of characters on this server - uint8 timezone; // timezone - uint8 unknown; // - } * realms; - - - -bool HandleRealmList(ByteBuffer pkt){ - uint8 PosOfRealm=0; - bool FoundRealm=false; - uint32 i=0,pktpos=0, unk1=0; - uint16 datalen; - uint8 count, trash; - pkt >> trash >> datalen >> unk1 >> count; - DEBUG3(printf("Length of realm data: %d\n",datalen);) - DEBUG1(printf("Realms in List: %d\n",count);); - if(count==0) - something_went_wrong=true; - realms=new SRealmInfo[count]; - for(i=0;i> realms[i].icon >> realms[i].color >> realms[i].name >> realms[i].addr_port >> realms[i].population >> realms[i].chars_here >> realms[i].timezone >> realms[i].unknown; - if(stricmp(realmname,realms[i].name.c_str())==0){PosOfRealm=i;FoundRealm=true;} - printf("Realm: %s (%s)",realms[i].name.c_str(),realms[i].addr_port.c_str()); - DEBUG1(printf("[chars:%d][population:%f][timezone:%d]",realms[i].chars_here,realms[i].population,realms[i].timezone);); - printf("\n"); - } - // the rest of the packet is not interesting - - // now setup where the woldserver is and how to login there - if(!FoundRealm){ - printf("Realm \"%s\" was not found on the realmlist!\n",realmname); - something_went_wrong=true; - realmCon.Close(); - return false; - } - - // transform "hostname:port" into something useful - // -> convert the worldserver port from string to int - // -> and remove it from the hostname, then write the remains into worldhost - - uint16 colonpos=realms[PosOfRealm].addr_port.find(":"); - worldhost=realms[PosOfRealm].addr_port.substr(0,colonpos); - ws_port=atoi(realms[PosOfRealm].addr_port.substr(colonpos+1,realms[PosOfRealm].addr_port.length()-colonpos-1).c_str()); - - return true; - -} \ No newline at end of file diff --git a/src/Client/Realm/RealmListHandler.h_ b/src/Client/Realm/RealmListHandler.h_ deleted file mode 100644 index eef919a..0000000 --- a/src/Client/Realm/RealmListHandler.h_ +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _REALMLISTHANDLER_H -#define _REALMLISTHANDLER_H - -bool HandleRealmList(ByteBuffer); - -#endif \ No newline at end of file diff --git a/src/Client/World/CMSGConstructor.cpp b/src/Client/World/CMSGConstructor.cpp index 7595765..bda606d 100644 --- a/src/Client/World/CMSGConstructor.cpp +++ b/src/Client/World/CMSGConstructor.cpp @@ -41,6 +41,7 @@ void WorldSession::SendQueryPlayerName(uint64 guid){ packet << guid; packet.SetOpcode(CMSG_NAME_QUERY); SendWorldPacket(packet); + // to prevent opcode spam, we need to make a list with already requested names } void WorldSession::SendPing(uint32 ping){ @@ -62,6 +63,20 @@ void WorldSession::SendEmote(uint32 id){ SendWorldPacket(packet); } +void WorldSession::SendQueryItem(uint32 id, uint64 guid) // is it a guid? not sure +{ + if(objmgr.ItemNonExistent(id)) + { + logdebug("Skipped query of item %u (was marked as nonexistent before)",id); + return; + } + WorldPacket packet; + packet << id << guid; + packet.SetOpcode(CMSG_ITEM_QUERY_SINGLE); + SendWorldPacket(packet); + // to prevent opcode spam, we need to make a list with already requested items +} + diff --git a/src/Client/World/CacheHandler.cpp b/src/Client/World/CacheHandler.cpp new file mode 100644 index 0000000..af1465a --- /dev/null +++ b/src/Client/World/CacheHandler.cpp @@ -0,0 +1,321 @@ +#include +#include +#include "common.h" +#include "PseuWoW.h" +#include "Opcodes.h" +#include "SharedDefines.h" +#include "Player.h" +#include "NameTables.h" +#include "DefScript/DefScript.h" +#include "WorldSession.h" +#include "CacheHandler.h" +#include "Item.h" + +bool PlayerNameCache::AddInfo(uint64 guid, std::string name){ + PlayerNameCacheItem *cacheItem=new PlayerNameCacheItem; + cacheItem->_name=name; + cacheItem->_guid=guid; + return AddInfo(cacheItem); +} + +bool PlayerNameCache::AddInfo(PlayerNameCacheItem* cacheItem){ + for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) + if(cacheItem->_guid==(*i)->_guid) + return false; + _cache.push_back(cacheItem); + return true; +} + +std::string PlayerNameCache::GetName(uint64 guid){ + for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) + if(guid==(*i)->_guid) + return (*i)->_name; + return ""; +} + +uint64 PlayerNameCache::GetGuid(std::string name){ + for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) + if(name==(*i)->_name) + return (*i)->_guid; + return 0; +} + +bool PlayerNameCache::SaveToFile(void){ + log("Saving PlayerNameCache..."); + char *fn="./cache/playernames.cache"; + std::fstream fh; + fh.open(fn, std::ios_base::out | std::ios_base::binary); + if(!fh) + { + logerror("PlayerNameCache: Could not write to file '%s'!",fn); + return false; + } + uint32 size=_cache.size(); + if(size==0) + return false; + uint8 len; + fh.write((char*)&size,sizeof(uint32)); + + for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) + { + fh.write( (char*)&((*i)->_guid),sizeof(uint64) ); + len=(*i)->_name.length(); + fh.write( (char*)&len,sizeof(uint8) ); + fh.write( (char*)(*i)->_name.c_str(),len ); + DEBUG(log( "PlayerNameCache << " I64FMT " -> %s", (*i)->_guid, (*i)->_name.c_str());); + } + fh.close(); + log("PlayerNameCache saved successfully."); + return true; +} + +bool PlayerNameCache::ReadFromFile(void){ + char *fn="./cache/playernames.cache"; + log("Loading PlayerNameCache..."); + bool success=true; + std::fstream fh; + fh.open(fn, std::ios_base::in | std::ios_base::binary); + if(!fh) + { + logerror("PlayerNameCache: Could not open file '%s'!",fn); + return false; + } + uint32 size; + fh.read((char*)&size,sizeof(uint32)); + std::string tmp; + uint8 len; + char *nameptr=new char[13]; + for(unsigned int i=0;i_guid),sizeof(uint64)); + fh.read((char*)&len,sizeof(uint8)); + if(len>12 || len<2){ + logerror("\nPlayerNameCache data seem corrupt [namelength=%d, should be <=12]",len); + log("-> Clearing cache, creating new.\n"); + _cache.clear(); + success=false; + break; + } + fh.read(nameptr,len); + cacheItem->_name=nameptr; + AddInfo(cacheItem); + printf("\rPlayerNameCache [ %u / %u ] items loaded",i+1,size); + DEBUG(printf( " >> " I64FMT " -> %s\n", cacheItem->_guid, nameptr);); + } + printf("\n"); + delete nameptr; + fh.close(); + if(success) + log("PlayerNameCache successfully loaded."); + return success; +} + +uint32 PlayerNameCache::GetSize(void){ + return _cache.size(); +} + +void ItemProtoCache_InsertDataToSession(WorldSession *session) +{ + char* fn = "./cache/ItemPrototypes.cache"; + std::fstream fh; + fh.open(fn, std::ios_base::in | std::ios_base::binary); + if(!fh) + { + logerror("ItemProtoCache: Could not open file '%s'!",fn); + return; + } + + uint32 datasize,counter=0; + ByteBuffer buf; + while(!fh.eof()) + { + buf.clear(); + fh.read((char*)&datasize,sizeof(uint32)); + buf.resize(datasize); + fh.read((char*)buf.contents(),datasize); + ItemProto *proto = new ItemProto; + buf >> proto->Id; + buf >> proto->Class; + buf >> proto->SubClass; + for(uint8 i=0;i<4;i++) + buf >> proto->Name[i]; + buf >> proto->DisplayInfoID; + buf >> proto->Quality; + buf >> proto->Flags; + buf >> proto->BuyPrice; + buf >> proto->SellPrice; + buf >> proto->InventoryType; + buf >> proto->AllowableClass; + buf >> proto->AllowableRace; + buf >> proto->ItemLevel; + buf >> proto->RequiredLevel; + buf >> proto->RequiredSkill; + buf >> proto->RequiredSkillRank; + buf >> proto->RequiredSpell; + buf >> proto->RequiredHonorRank; + buf >> proto->RequiredCityRank; + buf >> proto->RequiredReputationFaction; + buf >> proto->RequiredReputationRank; + buf >> proto->MaxCount; + buf >> proto->Stackable; + buf >> proto->ContainerSlots; + for(int i = 0; i < 10; i++) + { + buf >> proto->ItemStat[i].ItemStatType; + buf >> proto->ItemStat[i].ItemStatValue; + } + for(int i = 0; i < 5; i++) + { + buf >> proto->Damage[i].DamageMin; + buf >> proto->Damage[i].DamageMax; + buf >> proto->Damage[i].DamageType; + } + buf >> proto->Armor; + buf >> proto->HolyRes; + buf >> proto->FireRes; + buf >> proto->NatureRes; + buf >> proto->FrostRes; + buf >> proto->ShadowRes; + buf >> proto->ArcaneRes; + buf >> proto->Delay; + buf >> proto->Ammo_type; + + buf >> (float)proto->RangedModRange; + for(int s = 0; s < 5; s++) + { + buf >> proto->Spells[s].SpellId; + buf >> proto->Spells[s].SpellTrigger; + buf >> proto->Spells[s].SpellCharges; + buf >> proto->Spells[s].SpellCooldown; + buf >> proto->Spells[s].SpellCategory; + buf >> proto->Spells[s].SpellCategoryCooldown; + } + buf >> proto->Bonding; + buf >> proto->Description; + buf >> proto->PageText; + buf >> proto->LanguageID; + buf >> proto->PageMaterial; + buf >> proto->StartQuest; + buf >> proto->LockID; + buf >> proto->Material; + buf >> proto->Sheath; + buf >> proto->Extra; + buf >> proto->Block; + buf >> proto->ItemSet; + buf >> proto->MaxDurability; + buf >> proto->Area; + buf >> proto->Unknown1; + buf >> proto->Unknown2; // Added in 1.12.x client branch + if(proto->Id) + { + logdebug("ItemProtoCache: Loaded %u [%s]",proto->Id, proto->Name[0].c_str()); + session->objmgr.Add(proto); + counter++; + } + } + fh.close(); + log("ItemProtoCache: Loaded %u Item Prototypes",counter); +} + +void ItemProtoCache_WriteDataToCache(WorldSession *session) +{ + char* fn = "./cache/ItemPrototypes.cache"; + std::fstream fh; + fh.open(fn, std::ios_base::out | std::ios_base::binary); + if(!fh) + { + logerror("ItemProtoCache: Could not write to file '%s'!",fn); + return; + } + + uint32 counter=0; + ByteBuffer buf; + for(uint32 i=0;iobjmgr.GetItemProtoCount();i++) + { + buf.clear(); + ItemProto *proto = session->objmgr.GetItemProtoByPos(i); + buf << proto->Id; + buf << proto->Class; + buf << proto->SubClass; + for(uint8 i=0;i<4;i++) + buf << proto->Name[i]; + buf << proto->DisplayInfoID; + buf << proto->Quality; + buf << proto->Flags; + buf << proto->BuyPrice; + buf << proto->SellPrice; + buf << proto->InventoryType; + buf << proto->AllowableClass; + buf << proto->AllowableRace; + buf << proto->ItemLevel; + buf << proto->RequiredLevel; + buf << proto->RequiredSkill; + buf << proto->RequiredSkillRank; + buf << proto->RequiredSpell; + buf << proto->RequiredHonorRank; + buf << proto->RequiredCityRank; + buf << proto->RequiredReputationFaction; + buf << proto->RequiredReputationRank; + buf << proto->MaxCount; + buf << proto->Stackable; + buf << proto->ContainerSlots; + for(int i = 0; i < 10; i++) + { + buf << proto->ItemStat[i].ItemStatType; + buf << proto->ItemStat[i].ItemStatValue; + } + for(int i = 0; i < 5; i++) + { + buf << proto->Damage[i].DamageMin; + buf << proto->Damage[i].DamageMax; + buf << proto->Damage[i].DamageType; + } + buf << proto->Armor; + buf << proto->HolyRes; + buf << proto->FireRes; + buf << proto->NatureRes; + buf << proto->FrostRes; + buf << proto->ShadowRes; + buf << proto->ArcaneRes; + buf << proto->Delay; + buf << proto->Ammo_type; + + buf << (float)proto->RangedModRange; + for(int s = 0; s < 5; s++) + { + buf << proto->Spells[s].SpellId; + buf << proto->Spells[s].SpellTrigger; + buf << proto->Spells[s].SpellCharges; + buf << proto->Spells[s].SpellCooldown; + buf << proto->Spells[s].SpellCategory; + buf << proto->Spells[s].SpellCategoryCooldown; + } + buf << proto->Bonding; + buf << proto->Description; + buf << proto->PageText; + buf << proto->LanguageID; + buf << proto->PageMaterial; + buf << proto->StartQuest; + buf << proto->LockID; + buf << proto->Material; + buf << proto->Sheath; + buf << proto->Extra; + buf << proto->Block; + buf << proto->ItemSet; + buf << proto->MaxDurability; + buf << proto->Area; + buf << proto->Unknown1; + buf << proto->Unknown2; // Added in 1.12.x client branch + + logdebug("ItemProtoCache: Saved %u [%s]",proto->Id, proto->Name[0].c_str()); + uint32 size = buf.size(); + fh.write((char*)&size,sizeof(uint32)); + fh.write((char*)buf.contents(),buf.size()); + counter++; + } + fh.close(); + log("ItemProtoCache: Saved %u Item Prototypes",counter); +} \ No newline at end of file diff --git a/src/Client/World/CacheHandler.h b/src/Client/World/CacheHandler.h new file mode 100644 index 0000000..3e1432d --- /dev/null +++ b/src/Client/World/CacheHandler.h @@ -0,0 +1,25 @@ +#ifndef _CACHEHANDLER_H +#define _CACHEHANDLER_H + +struct PlayerNameCacheItem { + uint64 _guid; + std::string _name; +}; + +class PlayerNameCache { +public: + std::string GetName(uint64); + uint64 GetGuid(std::string); + bool AddInfo(uint64 guid, std::string name); + bool AddInfo(PlayerNameCacheItem*); + bool SaveToFile(void); + bool ReadFromFile(void); + uint32 GetSize(void); +private: + std::vector _cache; +}; + +void ItemProtoCache_InsertDataToSession(WorldSession *session); +void ItemProtoCache_WriteDataToCache(WorldSession *session); + +#endif \ No newline at end of file diff --git a/src/Client/World/Item.cpp b/src/Client/World/Item.cpp index f8b4f97..91c8955 100644 --- a/src/Client/World/Item.cpp +++ b/src/Client/World/Item.cpp @@ -3,6 +3,98 @@ #include "Item.h" +void WorldSession::_HandleItemQuerySingleResponseOpcode(WorldPacket& recvPacket) +{ + ItemProto *proto = new ItemProto; + recvPacket >> proto->Id; + uint8 field[64]; + memset(field,0,64); + if(memcmp(recvPacket.contents()+sizeof(uint32),field,64)) + { + recvPacket >> proto->Class; + recvPacket >> proto->SubClass; + for(uint8 i=0;i<4;i++) + recvPacket >> proto->Name[i]; + recvPacket >> proto->DisplayInfoID; + recvPacket >> proto->Quality; + recvPacket >> proto->Flags; + recvPacket >> proto->BuyPrice; + recvPacket >> proto->SellPrice; + recvPacket >> proto->InventoryType; + recvPacket >> proto->AllowableClass; + recvPacket >> proto->AllowableRace; + recvPacket >> proto->ItemLevel; + recvPacket >> proto->RequiredLevel; + recvPacket >> proto->RequiredSkill; + recvPacket >> proto->RequiredSkillRank; + recvPacket >> proto->RequiredSpell; + recvPacket >> proto->RequiredHonorRank; + recvPacket >> proto->RequiredCityRank; + recvPacket >> proto->RequiredReputationFaction; + recvPacket >> proto->RequiredReputationRank; + recvPacket >> proto->MaxCount; + recvPacket >> proto->Stackable; + recvPacket >> proto->ContainerSlots; + for(int i = 0; i < 10; i++) + { + recvPacket >> proto->ItemStat[i].ItemStatType; + recvPacket >> proto->ItemStat[i].ItemStatValue; + } + for(int i = 0; i < 5; i++) + { + recvPacket >> proto->Damage[i].DamageMin; + recvPacket >> proto->Damage[i].DamageMax; + recvPacket >> proto->Damage[i].DamageType; + } + recvPacket >> proto->Armor; + recvPacket >> proto->HolyRes; + recvPacket >> proto->FireRes; + recvPacket >> proto->NatureRes; + recvPacket >> proto->FrostRes; + recvPacket >> proto->ShadowRes; + recvPacket >> proto->ArcaneRes; + recvPacket >> proto->Delay; + recvPacket >> proto->Ammo_type; + + recvPacket >> (float)proto->RangedModRange; + for(int s = 0; s < 5; s++) + { + recvPacket >> proto->Spells[s].SpellId; + recvPacket >> proto->Spells[s].SpellTrigger; + recvPacket >> proto->Spells[s].SpellCharges; + recvPacket >> proto->Spells[s].SpellCooldown; + recvPacket >> proto->Spells[s].SpellCategory; + recvPacket >> proto->Spells[s].SpellCategoryCooldown; + } + recvPacket >> proto->Bonding; + recvPacket >> proto->Description; + recvPacket >> proto->PageText; + recvPacket >> proto->LanguageID; + recvPacket >> proto->PageMaterial; + recvPacket >> proto->StartQuest; + recvPacket >> proto->LockID; + recvPacket >> proto->Material; + recvPacket >> proto->Sheath; + recvPacket >> proto->Extra; + recvPacket >> proto->Block; + recvPacket >> proto->ItemSet; + recvPacket >> proto->MaxDurability; + recvPacket >> proto->Area; + recvPacket >> proto->Unknown1; + recvPacket >> proto->Unknown2; // Added in 1.12.x client branch + + logdetail("Got Item Info: Id=%u Name='%s' ReqLevel=%u Armor=%u Desc='%s'", + proto->Id, proto->Name[0].c_str(), proto->RequiredLevel, proto->Armor, proto->Description.c_str()); + objmgr.Add(proto); + } + else + { + logdetail("Got info of nonexistent Item %u",proto->Id); + objmgr.AddNonexistentItem(proto->Id); + delete proto; + } +} + Item::Item() { _type |= TYPE_ITEM; diff --git a/src/Client/World/Item.h b/src/Client/World/Item.h index fb31d39..401ff44 100644 --- a/src/Client/World/Item.h +++ b/src/Client/World/Item.h @@ -93,6 +93,301 @@ enum SellFailure SELL_ERR_CANT_FIND_VENDOR = 3 }; +enum ITEM_STAT_TYPE +{ + ITEM_STAT_POWER = 0, + ITEM_STAT_HEALTH = 1, + ITEM_STAT_UNKNOWN = 2, + ITEM_STAT_AGILITY = 3, + ITEM_STAT_STRENGTH = 4, + ITEM_STAT_INTELLECT = 5, + ITEM_STAT_SPIRIT = 6, + ITEM_STAT_STAMINA = 7 +}; + +enum ITEM_DAMAGE_TYPE +{ + NORMAL_DAMAGE = 0, + HOLY_DAMAGE = 1, + FIRE_DAMAGE = 2, + NATURE_DAMAGE = 3, + FROST_DAMAGE = 4, + SHADOW_DAMAGE = 5, + ARCANE_DAMAGE = 6 +}; + +enum ITEM_SPELLTRIGGER_TYPE +{ + USE = 0, + ON_EQUIP = 1, + CHANCE_ON_HIT = 2, + SOULSTONE = 4 +}; + +enum ITEM_BONDING_TYPE +{ + NO_BIND = 0, + BIND_WHEN_PICKED_UP = 1, + BIND_WHEN_EQUIPED = 2, + BIND_WHEN_USE = 3, + //TODO: Better name these + QUEST_ITEM = 4, + QUEST_ITEM1 = 5 +}; + +// masks for ITEM_FIELD_FLAGS field +enum ITEM_FLAGS +{ + ITEM_FLAGS_BINDED = 1 +}; + +enum BAG_FAMILY +{ + BAG_FAMILY_NONE = 0, + BAG_FAMILY_ARROWS = 1, + BAG_FAMILY_BULLETS = 2, + BAG_FAMILY_SOUL_SHARDS = 3, + //BAG_FAMILY_UNK1 = 4, + //BAG_FAMILY_UNK1 = 5, + BAG_FAMILY_HERBS = 6, + BAG_FAMILY_ENCHANTING_SUPP = 7, + BAG_FAMILY_ENGINEERING_SUPP = 8, + BAG_FAMILY_KEYS = 9, + BAG_FAMILY_GEMS = 10, + //BAG_FAMILY_UNK3 = 11, + BAG_FAMILY_MINING_SUPP = 12 +}; + +enum INVENTORY_TYPES +{ + INVTYPE_NON_EQUIP = 0, + INVTYPE_HEAD = 1, + INVTYPE_NECK = 2, + INVTYPE_SHOULDERS = 3, + INVTYPE_BODY = 4, + INVTYPE_CHEST = 5, + INVTYPE_WAIST = 6, + INVTYPE_LEGS = 7, + INVTYPE_FEET = 8, + INVTYPE_WRISTS = 9, + INVTYPE_HANDS = 10, + INVTYPE_FINGER = 11, + INVTYPE_TRINKET = 12, + INVTYPE_WEAPON = 13, + INVTYPE_SHIELD = 14, + INVTYPE_RANGED = 15, + INVTYPE_CLOAK = 16, + INVTYPE_2HWEAPON = 17, + INVTYPE_BAG = 18, + INVTYPE_TABARD = 19, + INVTYPE_ROBE = 20, + INVTYPE_WEAPONMAINHAND = 21, + INVTYPE_WEAPONOFFHAND = 22, + INVTYPE_HOLDABLE = 23, + INVTYPE_AMMO = 24, + INVTYPE_THROWN = 25, + INVTYPE_RANGEDRIGHT = 26, + INVTYPE_SLOT_ITEM = 27, + INVTYPE_RELIC = 28, + NUM_INVENTORY_TYPES = 29 +}; + +enum INVENTORY_CLASS +{ + ITEM_CLASS_CONSUMABLE = 0, + ITEM_CLASS_CONTAINER = 1, + ITEM_CLASS_WEAPON = 2, + ITEM_CLASS_JEWELRY = 3, + ITEM_CLASS_ARMOR = 4, + ITEM_CLASS_REAGENT = 5, + ITEM_CLASS_PROJECTILE = 6, + ITEM_CLASS_TRADE_GOODS = 7, + ITEM_CLASS_GENERIC = 8, + ITEM_CLASS_BOOK = 9, + ITEM_CLASS_MONEY = 10, + ITEM_CLASS_QUIVER = 11, + ITEM_CLASS_QUEST = 12, + ITEM_CLASS_KEY = 13, + ITEM_CLASS_PERMANENT = 14, + ITEM_CLASS_JUNK = 15 +}; + +// Client understand only 0 subclass for ITEM_CLASS_CONSUMABLE +// but this value used in code as implementation workaround +enum ITEM_SUBCLASS_CONSUMABLE +{ + ITEM_SUBCLASS_FOOD = 1, + ITEM_SUBCLASS_LIQUID = 2, + ITEM_SUBCLASS_POTION = 3, + ITEM_SUBCLASS_SCROLL = 4, + ITEM_SUBCLASS_BANDAGE = 5, + ITEM_SUBCLASS_HEALTHSTONE = 6, + ITEM_SUBCLASS_COMBAT_EFFECT = 7 +}; + +enum ITEM_SUBCLASS_CONTAINER +{ + ITEM_SUBCLASS_CONTAINER = 0, + ITEM_SUBCLASS_SOUL_CONTAINER = 1, + ITEM_SUBCLASS_HERB_CONTAINER = 2, + ITEM_SUBCLASS_ENCHANTING_CONTAINER = 3, + ITEM_SUBCLASS_ENGINEERING_CONTAINER = 4 +}; + +enum INVENTORY_SUBCLASS_WEAPON +{ + ITEM_SUBCLASS_WEAPON_AXE = 0, + ITEM_SUBCLASS_WEAPON_AXE2 = 1, + ITEM_SUBCLASS_WEAPON_BOW = 2, + ITEM_SUBCLASS_WEAPON_GUN = 3, + ITEM_SUBCLASS_WEAPON_MACE = 4, + ITEM_SUBCLASS_WEAPON_MACE2 = 5, + ITEM_SUBCLASS_WEAPON_POLEARM = 6, + ITEM_SUBCLASS_WEAPON_SWORD = 7, + ITEM_SUBCLASS_WEAPON_SWORD2 = 8, + ITEM_SUBCLASS_WEAPON_obsolete = 9, + ITEM_SUBCLASS_WEAPON_STAFF = 10, + ITEM_SUBCLASS_WEAPON_EXOTIC = 11, + ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12, + ITEM_SUBCLASS_WEAPON_UNARMED = 13, + ITEM_SUBCLASS_WEAPON_GENERIC = 14, + ITEM_SUBCLASS_WEAPON_DAGGER = 15, + ITEM_SUBCLASS_WEAPON_THROWN = 16, + ITEM_SUBCLASS_WEAPON_SPEAR = 17, + ITEM_SUBCLASS_WEAPON_CROSSBOW = 18, + ITEM_SUBCLASS_WEAPON_WAND = 19, + ITEM_SUBCLASS_WEAPON_FISHING_POLE = 20 +}; + +enum ITEM_SUBCLASS_ARMOR +{ + ITEM_SUBCLASS_ARMOR_GENERIC = 0, + ITEM_SUBCLASS_ARMOR_CLOTH = 1, + ITEM_SUBCLASS_ARMOR_LEATHER = 2, + ITEM_SUBCLASS_ARMOR_MAIL = 3, + ITEM_SUBCLASS_ARMOR_PLATE = 4, + ITEM_SUBCLASS_ARMOR_BUCKLER = 5, + ITEM_SUBCLASS_ARMOR_SHIELD = 6 +}; + +enum ITEM_SUBCLASS_PROJECTILE +{ + ITEM_SUBCLASS_ARROW = 2, + ITEM_SUBCLASS_BULLET = 3 +}; + +enum ITEM_SUBCLASS_TRADE_GOODS +{ + ITEM_SUBCLASS_TRADE_GOODS = 0, + ITEM_SUBCLASS_PARTS = 1, + ITEM_SUBCLASS_EXPLOSIVES = 2, + ITEM_SUBCLASS_DEVICES = 3 +}; + +enum ITEM_SUBCLASS_BOOK +{ + ITEM_SUBCLASS_BOOK = 0, + ITEM_SUBCLASS_LEATHERWORKING_PATTERN = 1, + ITEM_SUBCLASS_TAILORING_PATTERN = 2, + ITEM_SUBCLASS_ENGINEERING_SCHEMATIC = 3, + ITEM_SUBCLASS_COOKING_RECIPE = 5, + ITEM_SUBCLASS_ALCHEMY_RECIPE = 6, + ITEM_SUBCLASS_FIRST_AID_MANUAL = 7, + ITEM_SUBCLASS_ENCHANTING_FORMULA = 8, + ITEM_SUBCLASS_FISHING_MANUAL = 9 +}; + +enum ITEM_SUBCLASS_QUIVER +{ + ITEM_SUBCLASS_QUIVER = 2, + ITEM_SUBCLASS_AMMO_POUCH = 3 +}; + +struct _ItemStat +{ + uint32 ItemStatType; + uint32 ItemStatValue; + +}; + +struct _ItemSpell +{ + uint32 SpellId; + uint32 SpellTrigger; + uint32 SpellCharges; + uint32 SpellCooldown; + uint32 SpellCategory; + uint32 SpellCategoryCooldown; + +}; + +struct _ItemDamage +{ + float DamageMin; + float DamageMax; + uint32 DamageType; + +}; + +struct ItemProto +{ + uint32 Id; + uint32 Class; + uint32 SubClass; + std::string Name[4]; + uint32 DisplayInfoID; + uint32 Quality; + uint32 Flags; + uint32 BuyCount; + uint32 BuyPrice; + uint32 SellPrice; + uint32 InventoryType; + uint32 AllowableClass; + uint32 AllowableRace; + uint32 ItemLevel; + uint32 RequiredLevel; + uint32 RequiredSkill; + uint32 RequiredSkillRank; + uint32 RequiredSpell; + uint32 RequiredHonorRank; + uint32 RequiredCityRank; + uint32 RequiredReputationFaction; + uint32 RequiredReputationRank; + uint32 MaxCount; + uint32 Stackable; + uint32 ContainerSlots; + _ItemStat ItemStat[10]; + _ItemDamage Damage[5]; + uint32 Armor; + uint32 HolyRes; + uint32 FireRes; + uint32 NatureRes; + uint32 FrostRes; + uint32 ShadowRes; + uint32 ArcaneRes; + uint32 Delay; + uint32 Ammo_type; + float RangedModRange; + _ItemSpell Spells[5]; + uint32 Bonding; + std::string Description; + uint32 PageText; + uint32 LanguageID; + uint32 PageMaterial; + uint32 StartQuest; + uint32 LockID; + uint32 Material; + uint32 Sheath; + uint32 Extra; + uint32 Block; + uint32 ItemSet; + uint32 MaxDurability; + uint32 Area; + uint32 BagFamily; + uint32 Unknown1; + uint32 Unknown2; +}; + class Item : public Object { public: diff --git a/src/Client/World/ObjMgr.cpp b/src/Client/World/ObjMgr.cpp new file mode 100644 index 0000000..999b1b9 --- /dev/null +++ b/src/Client/World/ObjMgr.cpp @@ -0,0 +1,76 @@ +#include "common.h" +#include "Object.h" +#include "Item.h" +#include "ObjMgr.h" + +ObjMgr::~ObjMgr() +{ + for(ObjList::iterator i = _obj.begin(); i!=_obj.end(); i++) + { + delete *i; + } + for(ItemProtoList::iterator i = _iproto.begin(); i!=_iproto.end(); i++) + { + delete *i; + } +} + + +void ObjMgr::Add(Object *o) +{ + _obj.push_back(o); +} + +Object *ObjMgr::GetObject(uint64 guid) +{ + for(ObjList::iterator i = _obj.begin(); i!=_obj.end(); i++) + if((*i)->GetGUID() == guid) + return *i; + return NULL; +} + +void ObjMgr::RemoveObject(uint64 guid) +{ + for(ObjList::iterator i = _obj.begin(); i!=_obj.end(); i++) + if((*i)->GetGUID() == guid) + { + delete *i; + _obj.erase(i); + } +} + +void ObjMgr::Add(ItemProto *proto) +{ + _iproto.push_back(proto); +} + +ItemProto *ObjMgr::GetItemProto(uint32 entry) +{ + for(ItemProtoList::iterator i = _iproto.begin(); i!=_iproto.end(); i++) + if((*i)->Id == entry) + return *i; + return NULL; +} + +ItemProto *ObjMgr::GetItemProtoByPos(uint32 pos) +{ + return _iproto[pos]; +} + +void ObjMgr::AddNonexistentItem(uint32 id) +{ + _noitem.push_back(id); +} + +bool ObjMgr::ItemNonExistent(uint32 id) +{ + for(std::vector::iterator i=_noitem.begin(); i != _noitem.end(); i++) + { + if(*i == id) + return true; + } + return false; +} + + + diff --git a/src/Client/World/ObjMgr.h b/src/Client/World/ObjMgr.h new file mode 100644 index 0000000..c357899 --- /dev/null +++ b/src/Client/World/ObjMgr.h @@ -0,0 +1,35 @@ +#ifndef _OBJMGR_H +#define _OBJMGR_H + +#include + +class Object; +struct ItemProto; + +typedef std::list ObjList; +typedef std::vector ItemProtoList; + + +class ObjMgr +{ +public: + ~ObjMgr(); + void Add(Object*); + void Add(ItemProto*); + void AddNonexistentItem(uint32); + bool ItemNonExistent(uint32); + Object *GetObject(uint64); + void RemoveObject(uint64); + uint32 GetOjectCount(void) { return _obj.size(); } + uint32 GetItemProtoCount(void) { return _iproto.size(); } + ItemProto *GetItemProto(uint32); + ItemProto *GetItemProtoByPos(uint32); + +private: + ObjList _obj; + ItemProtoList _iproto; + std::vector _noitem; + +}; + +#endif \ No newline at end of file diff --git a/src/Client/World/Object.cpp b/src/Client/World/Object.cpp index e33701b..2306216 100644 --- a/src/Client/World/Object.cpp +++ b/src/Client/World/Object.cpp @@ -13,7 +13,6 @@ Object::Object() Object::~Object() { - // TODO: unregister object from object mgr if(_uint32values) delete [] _uint32values; } diff --git a/src/Client/World/Object.h b/src/Client/World/Object.h index 9b32dcc..a568a4d 100644 --- a/src/Client/World/Object.h +++ b/src/Client/World/Object.h @@ -34,7 +34,7 @@ enum TYPEID class Object { public: - Object(); + virtual ~Object(); inline const uint64 GetGUID() const { return GetUInt64Value(0); } inline const uint32 GetGUIDLow() const { return GetUInt32Value(0); } inline const uint32 GetGUIDHigh() const { return GetUInt32Value(1); } @@ -71,7 +71,7 @@ public: } protected: - ~Object(); + Object(); void _Create(uint64 guid); void _InitValues(void); diff --git a/src/Client/World/Player.cpp b/src/Client/World/Player.cpp index 655aa34..2c5bdc4 100644 --- a/src/Client/World/Player.cpp +++ b/src/Client/World/Player.cpp @@ -9,113 +9,8 @@ #include "DefScript/DefScript.h" #include "WorldSession.h" -bool PlayerNameCache::AddInfo(uint64 guid, std::string name){ - PlayerNameCacheItem *cacheItem=new PlayerNameCacheItem; - cacheItem->_name=name; - cacheItem->_guid=guid; - return AddInfo(cacheItem); -} -bool PlayerNameCache::AddInfo(PlayerNameCacheItem* cacheItem){ - for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) - if(cacheItem->_guid==(*i)->_guid) - return false; - _cache.push_back(cacheItem); - return true; -} - -std::string PlayerNameCache::GetName(uint64 guid){ - for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) - if(guid==(*i)->_guid) - return (*i)->_name; - return ""; -} - -uint64 PlayerNameCache::GetGuid(std::string name){ - for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) - if(name==(*i)->_name) - return (*i)->_guid; - return 0; -} - -bool PlayerNameCache::SaveToFile(void){ - log("Saving PlayerNameCache..."); - char *fn="./cache/playernames.cache"; - std::fstream fh; - fh.open(fn, std::ios_base::out | std::ios_base::binary); - if(!fh) - { - log("ERROR: could not write to file '%s'!",fn); - return false; - } - uint32 size=_cache.size(); - if(size==0) - return false; - uint8 len; - fh.write((char*)&size,sizeof(uint32)); - - for(std::vector::iterator i=_cache.begin(); i!=_cache.end(); i++) - { - fh.write( (char*)&((*i)->_guid),sizeof(uint64) ); - len=(*i)->_name.length(); - fh.write( (char*)&len,sizeof(uint8) ); - fh.write( (char*)(*i)->_name.c_str(),len ); - DEBUG(log( "PlayerNameCache << " I64FMT " -> %s", (*i)->_guid, (*i)->_name.c_str());); - } - fh.close(); - log("PlayerNameCache saved successfully."); - return true; -} - -bool PlayerNameCache::ReadFromFile(void){ - char *fn="./cache/playernames.cache"; - log("Loading PlayerNameCache..."); - bool success=true; - std::fstream fh; - fh.open(fn, std::ios_base::in | std::ios_base::binary); - if(!fh) - { - log("ERROR: could not open file '%s'!",fn); - return false; - } - uint32 size; - fh.read((char*)&size,sizeof(uint32)); - std::string tmp; - uint8 len; - char *nameptr=new char[13]; - for(unsigned int i=0;i_guid),sizeof(uint64)); - fh.read((char*)&len,sizeof(uint8)); - if(len>12 || len<2){ - log("\nERROR: PlayerNameCache data seem corrupt [namelength=%d, should be <=12}]",len); - log("-> Clearing cache, creating new.\n"); - _cache.clear(); - success=false; - break; - } - fh.read(nameptr,len); - cacheItem->_name=nameptr; - AddInfo(cacheItem); - printf("\rPlayerNameCache [ %u / %u ] items loaded",i+1,size); - DEBUG(printf( " >> " I64FMT " -> %s\n", cacheItem->_guid, nameptr);); - } - printf("\n"); - delete nameptr; - fh.close(); - if(success) - log("PlayerNameCache successfully loaded."); - return success; -} - -uint32 PlayerNameCache::GetSize(void){ - return _cache.size(); -} - -void Player::Init(PlayerEnum player) +/*void Player::Init(PlayerEnum player) { this->player = player; } @@ -126,9 +21,9 @@ void PlayerSettings::SetActionButtons(WorldPacket &data) return; // TODO: Implent this -} +}*/ -void PlayerSettings::SetSpells(WorldPacket &data) +/*void PlayerSettings::SetSpells(WorldPacket &data) { if (!init) return; @@ -152,7 +47,7 @@ void PlayerSettings::CastSpell(uint32 spellId, uint64 target) WorldPacket packet; packet.SetOpcode(CMSG_CAST_SPELL); - packet << spellId << (uint16)2 /* TARGET_FLAG_UNIT */ << (uint8)1 /* guid stuff */ << (uint8)target; + packet << spellId << (uint16)2 << (uint8)1 << (uint8)target; // 2 = TARGET_FLAG_UNIT // Can be bugged, not fully tested, probably doesn't work when the guid is high // Damn packed guid stuff! xD @@ -183,4 +78,4 @@ void PlayerSettings::HandleCastResultOpcode(WorldPacket &packet) //logdetail(l); -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/src/Client/World/Player.h b/src/Client/World/Player.h index 7391baa..22964ff 100644 --- a/src/Client/World/Player.h +++ b/src/Client/World/Player.h @@ -5,30 +5,12 @@ #include "WorldPacket.h" #include "SysDefs.h" -struct PlayerItem +struct PlayerEnumItem { - uint32 itemID; + uint32 displayId; uint8 inventorytype; }; -struct PlayerNameCacheItem { - uint64 _guid; - std::string _name; -}; - -class PlayerNameCache { -public: - std::string GetName(uint64); - uint64 GetGuid(std::string); - bool AddInfo(uint64 guid, std::string name); - bool AddInfo(PlayerNameCacheItem*); - bool SaveToFile(void); - bool ReadFromFile(void); - uint32 GetSize(void); -private: - std::vector _cache; -}; - class PlayerEnum { public: uint64 _guid; @@ -52,7 +34,7 @@ public: uint32 _petInfoId; uint32 _petLevel; uint32 _petFamilyId; - PlayerItem _items[20]; + PlayerEnumItem _items[20]; private: @@ -70,45 +52,28 @@ private: PlayerEnum player; }; -class PlayerSettings + +// class about the character that is used to login. +// needs to store known spells, action buttons,... +// basically everything that is needed to play. +class MyCharacter : public Player { public: - PlayerSettings() + MyCharacter(WorldSession *ws) { - castingSpell = false; - init = false; + _worldSession = ws; + _isbusy = false; } - void Init(WorldSession *worldSession) - { - _worldSession = worldSession; - } - - void SetActionButtons(WorldPacket &data); + /*void SetActionButtons(WorldPacket &data); void SetSpells(WorldPacket &data); void CastSpell(uint32 spellId, uint64 target); - void HandleCastResultOpcode(WorldPacket &packet); + void HandleCastResultOpcode(WorldPacket &packet);*/ private: - bool castingSpell; + bool _isbusy; WorldSession *_worldSession; - bool init; }; -/* -class PlayerCache { -public: - void Add(Player*); - void Remove(Player*); - void Remove(uint64); - uint32 GetCount(void) { return _players.size(); } - -private: - std::vector _players; - -}; -*/ - - #endif \ No newline at end of file diff --git a/src/Client/World/WorldPacketHandler.cpp_ b/src/Client/World/WorldPacketHandler.cpp_ deleted file mode 100644 index 859c171..0000000 --- a/src/Client/World/WorldPacketHandler.cpp_ +++ /dev/null @@ -1,463 +0,0 @@ -#include -#include -#include "zlib/zlib.h" -#include "common.h" -#include "PseuWoW.h" -#include "Auth/AuthCrypt.h" -#include "../shared/CircularBuffer.h" // to have the Buf data structure -#include "../shared/SDLTCPConnection.h" -#include "Auth/ByteBuffer.h" -#include "Auth/BigNumber.h" -#include "Auth/Sha1.h" -#include "Opcodes.h" -#include "WorldPacketHandler.h" -#include "SharedDefines.h" -#include "Player.h" -#include "NameTables.h" -#include "CMSGConstructor.h" -#include "DefScript/DefScript.h" - - -struct ClientPktHeader -{ - uint16 size; - uint16 cmd; - uint16 nil; -}; - -struct ServerPktHeader -{ - uint16 size; - uint16 cmd; -}; - -AuthCrypt _crypt; -BigNumber sessionkey; - -uint8 GetCompressedGuidSize(uint8 mask){ - uint8 size=0; - for(unsigned int i=0;i<8;i++){ - if(mask>>i){ - size++; - } - } - return size; -} - -uint64 DecompressGuid(uint8 *z, uint8 mask){ - uint64 guid=0; - for(uint8 i=0;i<8;i++){ - if(mask>>i){ - ((uint8*)&guid)[i]=*z; - z++; - } - } - return guid; -} - - -void SendWorldPacket(uint16 opcode, ByteBuffer *pkt){ - ClientPktHeader hdr={0,0,0}; - ByteBuffer buf; - if(pkt!=NULL)buf.append(*pkt); - hdr.cmd=opcode; - hdr.size=ntohs(buf.size()+4); - _crypt.EncryptSend((uint8*)&hdr, 6); - ByteBuffer final; - final.append((uint8*)&hdr,6); - if(buf.size()){ - final.append(buf); - } - worldCon.Send((char*)final.contents(), final.size()); -} - - -void HandleWorldPacket(ByteBuffer pkt){ - - static uint16 _last_cmd,_last_remaining; - static bool _last_pkt_wrong; - ServerPktHeader hdr; - uint16 _remaining, _cmd; - ByteBuffer wdata; - pkt >> hdr.size >> hdr.cmd; - _crypt.DecryptRecv((uint8*)&hdr, 4); - _remaining=ntohs(hdr.size)-2; - _cmd=hdr.cmd; - //DEBUG3(printf("DECRYPT: rest=%d, opcode=%d\n",_remaining,_cmd);) - if(_cmd>800){ - DEBUG3(printf("Recieved weird opcode [%u] pktsize=%u remaining=%u(corrupted header?)\n",_cmd,pkt.size(),_remaining);) - DEBUG3(pkt.hexlike();) - //if(pkt.size()==_last_remaining){ - // DEBUG3(printf("Trying to attach packet to last recieved opcode [%s], size=%u\n",LookupName(_last_cmd,g_worldOpcodeNames),_last_remaining);) - // wdata.append(pkt.contents(),_last_remaining); - // HandleOpcode(_last_cmd,wdata); // lets hope it wont crash :/ - //} else - //DEBUG1(printf("Packet rescue failed, dropping. size=%u opcode=%u\n",_remaining,_cmd);) - - return; - } - else - if(pkt.size()>4 && _remaining+4==pkt.size()){ - DEBUG3(printf("Rcvd pkt hdr is too big (%u)! Assuming {header+data}, opcode=%d [%s]\n",pkt.size(),_cmd,LookupName(_cmd,g_worldOpcodeNames));) - wdata.append(&pkt.contents()[4],4); - //wdata.hexlike(); - _last_cmd=_cmd; - _last_remaining=_remaining; - HandleOpcode(_cmd,wdata); - - } else { - if(!_remaining){ - ByteBuffer dummy; - HandleOpcode(_cmd,dummy); - } - if(_remaining){ - ByteBuffer content; - content.append(worldCon.GetDataString()); // fetch the next packet - content.resize(content.size()-1); // remove the \0 - if(content.size()<_remaining ){ // packet is smaller then expected - //content.hexlike(); - DEBUG3(printf("Packet was smaller then expected! (expected: %u, recvd: %u)\n",_remaining,content.size());) - //if(content.size()==_last_remaining){ - // DEBUG3(printf("Trying to attach packet to last recieved opcode [%s], size=%u\n",LookupName(_last_cmd,g_worldOpcodeNames),_last_remaining);) - // wdata.append(pkt.contents(),_last_remaining); - // HandleOpcode(_last_cmd,wdata); // lets hope it wont crash :/ - // //something_went_wrong=true; - //} else - // printf("Packet rescue failed, dropping. size=%u opcode=%u\n",_remaining,_cmd); - return; - } else { // packet seems ok, use the full packet that came in - //content.hexlike(); - wdata.append(content.contents(),_remaining); - _last_cmd=_cmd; - _last_remaining=_remaining; - HandleOpcode(_cmd,wdata); - } - } - } -} - -void HandleOpcode(uint16 opcode, ByteBuffer &data){ - - //DEBUG3(printf("W: opcode=0x%X | %d , datasize=%d [%s]\n",opcode,opcode,data.size(),LookupName(opcode,g_worldOpcodeNames));) - switch(opcode){ - case SMSG_AUTH_CHALLENGE:{ - std::string acc(strupr(accname)); - uint32 serverseed; - data>>serverseed; - DEBUG3(printf("W:auth: serverseed=0x%X\n",serverseed);) - Sha1Hash digest; - digest.UpdateData(acc); - uint32 unk=0; - digest.UpdateData((uint8*)&unk,sizeof(uint32)); - BigNumber clientseed; - clientseed.SetRand(8*4); - unsigned int clientseed_uint32=clientseed.AsDword(); - digest.UpdateData((uint8*)&clientseed_uint32,sizeof(uint32)); - digest.UpdateData((uint8*)&serverseed,sizeof(uint32)); - digest.UpdateBigNumbers(&sessionkey,NULL); - digest.Finalize(); - ByteBuffer outpkt; - outpkt<<(uint32)clientbuild<> num; - if(num==0){ - printf("W:No chars found!\n"); - something_went_wrong=true; - return; - } - printf("W: Chars in list: %u\n",num); - for(unsigned int i=0;i> plr[i]._guid; - data >> plr[i]._name; - data >> plr[i]._race; - data >> plr[i]._class; - data >> plr[i]._gender; - data >> plr[i]._bytes1; - data >> plr[i]._bytes2; - data >> plr[i]._bytes3; - data >> plr[i]._bytes4; - data >> plr[i]._bytesx; - data >> plr[i]._level; - data >> plr[i]._zoneId; - data >> plr[i]._mapId; - data >> plr[i]._x; - data >> plr[i]._y; - data >> plr[i]._z; - data >> plr[i]._guildId; - data >> dummy8; - data >> plr[i]._flags; - data >> dummy8 >> dummy8 >> dummy8; - data >> plr[i]._petInfoId; - data >> plr[i]._petLevel; - data >> plr[i]._petFamilyId; - for(unsigned int inv=0;inv<20;inv++){ - data >> dummy32 >> dummy8; // item data are not relevant yet ( (uint32)itemID , (uint8)inventorytype ) - } - plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); - } - bool char_found=false; - uint64 login_guid; - for(unsigned int i=0;i coords: map=%u zone=%u x=%f y=%f z=%f\n", - plr[i]._mapId,plr[i]._zoneId,plr[i]._x,plr[i]._y,plr[i]._z);) - if(plr[i]._name==charname){ - char_found=true; - login_guid=plr[i]._guid; - } - - } - if(!char_found){ - printf("W: Character \"%s\" was not found on char list!\n",charname.c_str()); - something_went_wrong=true; - return; - } else { - printf("W: Entering World with Character \"%s\"...\n",charname.c_str()); - ByteBuffer pkt; - pkt << login_guid; - _myGUID=login_guid; - _targetGUID=0; - SendWorldPacket(CMSG_PLAYER_LOGIN,&pkt); - } - - - - }break; - - case SMSG_ACCOUNT_DATA_MD5: - case SMSG_SET_PROFICIENCY: - case SMSG_CAST_RESULT: - case SMSG_LOGIN_SETTIMESPEED: //those opcodes are sent on login - { - if(!inworld){ - inworld=true; - defScp.RunScriptByName("_enterworld",NULL,255); - } - // o_O - } break; - - case SMSG_MESSAGECHAT:{ - uint8 type=0; - uint32 lang=0; - uint64 target_guid=0; - uint32 msglen=0; - std::string msg,ext; - bool isCmd=false; - - data >> type >> lang; - - if (type == CHAT_MSG_CHANNEL) - data >> ext; // extract channel name - - data >> target_guid; - std::string plrname; - if(target_guid){ - plrname=plrNameCache.GetName(target_guid); - if(plrname.empty()) - { - QueryPlayerName(target_guid); - plrname="Unknown Entity"; - } - } - defScp.variables.Set("@lastmsg_name",defScp.variables.Get("@thismsg_name")); - defScp.variables.Set("@lastmsg",defScp.variables.Get("@lastmsg")); - defScp.variables.Set("@thismsg_name",plrname); - defScp.variables.Set("@thismsg",toString(target_guid)); - - - if(type == CHAT_MSG_SAY || type == CHAT_MSG_YELL || type == CHAT_MSG_PARTY) - data >> target_guid; - - data >> msglen >> msg; - if (type == CHAT_MSG_SYSTEM){ - printf("W:SYSMSG: \"%s\"\n",msg.c_str()); - } else if (type==CHAT_MSG_WHISPER ){ - printf("W:WHISP: %s [%s]: %s\n",plrname.c_str(),LookupName(lang,langNames),msg.c_str()); - } else { - printf("W:CHAT: %s [%s]: %s\n",plrname.c_str(),LookupName(lang,langNames),msg.c_str()); - } - - if(target_guid!=_myGUID && msg.length()>1 && msg.at(0)=='-') - isCmd=true; - - // some fun code :P - if(type==CHAT_MSG_SAY && target_guid!=_myGUID && !isCmd) - { - if(msg=="lol") - SendChatMessage(CHAT_MSG_SAY,lang,"say \"lol\" if you have nothing else to say... lol xD",""); - else if(msg.length()>4 && msg.find("you?")!=std::string::npos) - SendChatMessage(CHAT_MSG_SAY,lang,std::string(ver).append(" -- i am a bot, made by False.Genesis, my master."),""); - else if(msg=="hi") - SendChatMessage(CHAT_MSG_SAY,lang,"Hi, wadup?",""); - else if(msg.length()<12 && msg.find("wtf")!=std::string::npos) - SendChatMessage(CHAT_MSG_SAY,lang,"Yeah, WTF is a good way to say you dont understand anything... :P",""); - else if(msg.length()<15 && (msg.find("omg")!=std::string::npos || msg.find("omfg")!=std::string::npos) ) - SendChatMessage(CHAT_MSG_SAY,lang,"OMG a bot logged in, you don't believe it :O",""); - else if(msg.find("from")!=std::string::npos || msg.find("download")!=std::string::npos) - SendChatMessage(CHAT_MSG_SAY,lang,"you can dl me from http://my.opera.com/PseuWoW",""); - else if(msg.find("Genesis")!=std::string::npos || msg.find("genesis")!=std::string::npos) - SendChatMessage(CHAT_MSG_YELL,lang,"False.Genesis, they are calling you!! Come here, master xD",""); - } - - if(isCmd){ - defScp.variables.Set("@lastcmd_name",defScp.variables.Get("@thiscmd_name")); - defScp.variables.Set("@lastcmd",defScp.variables.Get("@lastcmd")); - defScp.variables.Set("@thiscmd_name",plrname); - defScp.variables.Set("@thiscmd",toString(target_guid)); - std::string lin=msg.substr(1,msg.length()-1); - uint8 perm=atoi(playerPermissions.Get(plrname).c_str()); - try{ - if(!defScp.RunSingleLine(lin,perm)) - defScp.RunScriptByName("_nopermission",NULL,255); - } catch (...) { - SendChatMessage(CHAT_MSG_SAY,0,"Exception while trying to execute: [ "+lin+" ]",""); - } - - } - if(type==CHAT_MSG_WHISPER && !isCmd){ - defScp.variables.Set("@lastwhisper_name",defScp.variables.Get("@thiswhisper_name")); - defScp.variables.Set("@lastwhisper",defScp.variables.Get("@thiswhisper")); - defScp.variables.Set("@lastwhisper_lang",defScp.variables.Get("@thiswhisper_lang")); - defScp.variables.Set("@thiswhisper_name",plrname); - defScp.variables.Set("@thiswhisper",toString(target_guid)); - defScp.variables.Set("@thiswhisper_lang",toString((uint64)lang)); - defScp.RunScriptByName("_onwhisper",NULL,255); - } - - - - } break; - - case SMSG_MONSTER_MOVE:{ - // register moving mobs, etc - } break; - - case SMSG_STOP_MIRROR_TIMER:{ - // mangos spams u with that if you are dead (bug) - } break; - - case SMSG_NAME_QUERY_RESPONSE:{ - uint64 pguid; - std::string pname; - data >> pguid >> pname; - if(pname.length()>12 || pname.length()<2) - break; // playernames maxlen=12 - // rest of the packet is not interesting for now - if(plrNameCache.AddInfo(pguid,pname)) - { - printf("CACHE: Assigned new player name: '%s'",pname.c_str()); - SendChatMessage(CHAT_MSG_SAY,0,"Player "+pname+" added to cache.",""); - DEBUG2(printf(" to guid "I64FMTD,pguid);); - printf("\n"); - } - - } break; - - case MSG_MOVE_SET_FACING: - case MSG_MOVE_START_FORWARD: - case MSG_MOVE_START_BACKWARD: - case MSG_MOVE_STOP: - case MSG_MOVE_START_STRAFE_LEFT: - case MSG_MOVE_START_STRAFE_RIGHT: - case MSG_MOVE_STOP_STRAFE: - case MSG_MOVE_JUMP: - case MSG_MOVE_START_TURN_LEFT: - case MSG_MOVE_START_TURN_RIGHT: - case MSG_MOVE_STOP_TURN: - case MSG_MOVE_START_SWIM: - case MSG_MOVE_STOP_SWIM: - case MSG_MOVE_HEARTBEAT: - case MSG_MOVE_FALL_LAND: - { - uint32 flags, time; - float x, y, z, o; - uint64 guid; - uint8 mask,guidlen,*zguid; - std::string plrname; - data >> mask; - guidlen=GetCompressedGuidSize(mask); - zguid=new uint8[guidlen]; - data.read(zguid,guidlen); - guid=DecompressGuid(zguid,mask); - delete zguid; - data >> flags >> time >> x >> y >> z >> o; - if(guid){ - plrname=plrNameCache.GetName(guid); - if(plrname.empty()) - { - QueryPlayerName(guid); - plrname="Unknown Entity"; - } - } - // for follow: - if(_followGUID==guid){ - ByteBuffer bb; - bb << time << flags << x << y << z << o; - SendWorldPacket(opcode,&bb); - } - // more to come - } break; - - case SMSG_PONG:{ - uint32 pong; - data >> pong; - printf("Recieved Ping reply: %u ms latency, including %u ms fetch delay.\n",clock()-pong,idleSleepTime); - } break; - - case SMSG_TRADE_STATUS:{ - data.hexlike(); - uint8 unk; - data >> unk; - if(unk==1){ - SendChatMessage(CHAT_MSG_SAY,0,"It has no sense trying to trade with me, that feature is not yet implemented!",""); - SendWorldPacket(CMSG_CANCEL_TRADE,NULL); - } - } - - case SMSG_GROUP_INVITE:{ - data.hexlike(); - SendWorldPacket(CMSG_GROUP_DECLINE,NULL); - } - - - //... - - default: { - DEBUG1(printf("Recieved unknown opcode=%u [%s] pktlen=%u\n",opcode,LookupName(opcode,g_worldOpcodeNames),data.size());); - } break; - - } - -} \ No newline at end of file diff --git a/src/Client/World/WorldPacketHandler.h_ b/src/Client/World/WorldPacketHandler.h_ deleted file mode 100644 index daeb150..0000000 --- a/src/Client/World/WorldPacketHandler.h_ +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _WORLDPACKETHANDLER_H -#define _WORLDPACKETHANDLER_H - -#include -#include "Auth/ByteBuffer.h" -void HandleWorldPacket(ByteBuffer); -void HandleOpcode(uint16,ByteBuffer&); -void SendWorldPacket(uint16, ByteBuffer*); - -#endif \ No newline at end of file diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index d276ddc..ccb3606 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -22,6 +22,7 @@ WorldSession::WorldSession(PseuInstance *in) _followGUID=0; // dont follow anything _myGUID=0; // i dont have a guid yet plrNameCache.ReadFromFile(); // load names/guids of known players + ItemProtoCache_InsertDataToSession(this); _deleteme = false; _channels = new Channel(this); // _playerSettings->Init(this); @@ -157,7 +158,8 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const {MSG_MOVE_TELEPORT_ACK, &WorldSession::_HandleTelePortAckOpcode}, {SMSG_COMPRESSED_UPDATE_OBJECT, &WorldSession::_HandleCompressedUpdateObjectOpcode}, - {SMSG_CAST_RESULT, &WorldSession::_HandleCastResultOpcode}, + {SMSG_CAST_RESULT, &WorldSession::_HandleCastResultOpcode}, + {SMSG_ITEM_QUERY_SINGLE_RESPONSE, &WorldSession::_HandleItemQuerySingleResponseOpcode}, // table termination { 0, NULL } @@ -272,7 +274,6 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) uint8 num; PlayerEnum plr[10]; // max characters per realm is 10 uint8 dummy8; - //uint32 dummy32; // Unused recvPacket >> num; if(num==0){ @@ -305,9 +306,10 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) recvPacket >> plr[i]._petInfoId; recvPacket >> plr[i]._petLevel; recvPacket >> plr[i]._petFamilyId; - for(unsigned int inv=0;inv<20;inv++){ - recvPacket >> plr[i]._items[inv].itemID >> plr[i]._items[inv].inventorytype; // item data are not relevant yet ( (uint32)itemID , (uint8)inventorytype ) - } + for(unsigned int inv=0;inv<20;inv++) + { + recvPacket >> plr[i]._items[inv].displayId >> plr[i]._items[inv].inventorytype; + } plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); } bool char_found=false; @@ -318,7 +320,13 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket) plr[i]._name.c_str(),plr[i]._level,raceName[plr[i]._race],className[plr[i]._class]); logdetail("-> coords: map=%u zone=%u x=%f y=%f z=%f", plr[i]._mapId,plr[i]._zoneId,plr[i]._x,plr[i]._y,plr[i]._z); - if(plr[i]._name==GetInstance()->GetConf()->charname){ + for(unsigned int inv=0;inv<20;inv++) + { + if(plr[i]._items[inv].displayId) + logdebug("-> Has Item: Model=%u InventoryType=%u",plr[i]._items[inv].displayId,plr[i]._items[inv].inventorytype); + } + if(plr[i]._name==GetInstance()->GetConf()->charname) + { char_found=true; _myGUID=plr[i]._guid; playerNum = i; @@ -535,7 +543,7 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket) recvPacket >> unk >> guid >> unk3 >> unk1 >> unk2 >> o >> x >> y >> z >> ang >> unk4; - logdetail("DEBUG: Got teleport, data: x: %f, y: %f, z: %f, o: %f, guid: %d\n", x, y, z, o, guid); + logdetail("Got teleported, data: x: %f, y: %f, z: %f, o: %f, guid: %d\n", x, y, z, o, guid); WorldPacket response; response.SetOpcode(MSG_MOVE_FALL_LAND); diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index 8c5e699..c327699 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -1,18 +1,21 @@ #ifndef _WORLDSESSION_H #define _WORLDSESSION_H -#include +#include "common.h" #include "PseuWoW.h" #include "Network/SocketHandler.h" -#include "common.h" #include "Player.h" #include "Auth/AuthCrypt.h" #include "SharedDefines.h" +#include "ObjMgr.h" +#include "CacheHandler.h" class WorldSocket; class WorldPacket; class Channel; + + struct OpcodeHandler { uint16 opcode; @@ -56,8 +59,10 @@ public: void SendQueryPlayerName(uint64 guid); void SendPing(uint32); void SendEmote(uint32); + void SendQueryItem(uint32, uint64); PlayerNameCache plrNameCache; + ObjMgr objmgr; private: @@ -83,18 +88,15 @@ private: void _HandleCastResultOpcode(WorldPacket& recvPacket); void _HandleCompressedUpdateObjectOpcode(WorldPacket& recvPacket); void _HandleUpdateObjectOpcode(WorldPacket& recvPacket); + void _HandleItemQuerySingleResponseOpcode(WorldPacket& recvPacket); - - //Player *_player; // The connected character - //PlayerSettings *_playerSettings; // Settings for the connected character - PseuInstance *_instance; WorldSocket *_socket; ZThread::LockedQueue pktQueue; bool _valid,_authed,_logged,_deleteme; // world status SocketHandler _sh; // handles the WorldSocket Channel *_channels; - uint64 _targetGUID,_followGUID,_myGUID; + uint64 _targetGUID,_followGUID,_myGUID; }; #endif \ No newline at end of file diff --git a/src/Client/basics.h_ b/src/Client/basics.h_ deleted file mode 100644 index de71b4d..0000000 --- a/src/Client/basics.h_ +++ /dev/null @@ -1,36 +0,0 @@ -// --- Defines --- -//... - -// --- Includes --- -#include -#include -#include -#include -#include -#include - -//#include - -#include "../shared/OurDefs.h" -#include "../shared/common.h" -#include "../shared/DebugStuff.h" - -// --- platform stuff --- -#if COMPILER == COMPILER_MICROSOFT - #define I64FMT "%016I64X" - #define I64FMTD "%I64u" - #define SI64FMTD "%I64d" - #define snprintf _snprintf - #define atoll __atoi64 - #define vsnprintf _vsnprintf - #define strdup _strdup -#else - #define stricmp strcasecmp - #define strnicmp strncasecmp - #define I64FMT "%016llX" - #define I64FMTD "%llu" - #define SI64FMTD "%lld" -#endif - - - diff --git a/src/Client/controller.h_ b/src/Client/controller.h_ deleted file mode 100644 index f8b5ec7..0000000 --- a/src/Client/controller.h_ +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef CONTROLLER_H -#define CONTROLLER_H - -void c_send(char,char*); -int c_closeconnection(void*); -int c_recieve(void*); -int c_cmdhandler(void*); -int c_create_listener(void*); -void c_quit(void); -void c_init(void); - -extern unsigned int c_port; -extern bool allowcontroller; -extern char *c_password; - -#endif \ No newline at end of file diff --git a/src/Client/log.cpp b/src/Client/log.cpp index 60d3860..8a5dccd 100644 --- a/src/Client/log.cpp +++ b/src/Client/log.cpp @@ -92,13 +92,13 @@ void logdebug(const char *str, ...) void logerror(const char *str, ...) { va_list ap; - _log_setcolor(true,LRED); + _log_setcolor(false,LRED); va_start(ap, str); - vprintf( str, ap ); + vfprintf( stderr, str, ap ); va_end(ap); - _log_resetcolor(true); + _log_resetcolor(false); - printf("\n"); + fprintf(stderr,"\n"); if(logfile) { @@ -117,13 +117,13 @@ void logcritical(const char *str, ...) if(!str || instance->GetConf()->debug < 2) return; va_list ap; - _log_setcolor(true,RED); + _log_setcolor(false,RED); va_start(ap, str); - vprintf( str, ap ); + vfprintf( stderr, str, ap ); va_end(ap); - _log_resetcolor(true); + _log_resetcolor(false); - printf("\n"); + fprintf(stderr,"\n"); if(logfile) { diff --git a/src/Client/log.h b/src/Client/log.h index 91ec86c..806ad62 100644 --- a/src/Client/log.h +++ b/src/Client/log.h @@ -22,7 +22,7 @@ enum Color WHITE }; -void log_prepare(char *fn, PseuInstance* p); +void log_prepare(char *fn, PseuInstance* p); // instance reference needed for log level determination void log(const char *str, ...); void logdetail(const char *str, ...); void logdebug(const char *str, ...); diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index 7ff9290..69f0ff2 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -260,6 +260,12 @@ + + + + @@ -281,6 +287,12 @@ + + + +