* Added support for item prototypes
* new DefScript command: "queryitem #id" * added cache for known item prototypes * fixed a little typo in script: reply.def * error logs go to stderr now * misc stuff
This commit is contained in:
parent
c00ad9aae3
commit
d6b6960c29
@ -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}
|
||||
|
||||
@ -1,133 +0,0 @@
|
||||
#include <fstream>
|
||||
#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;i<opt.length();i++){
|
||||
if(!isdigit(opt.at(i))){
|
||||
clientversion[p]=(unsigned char)atoi(num.c_str());
|
||||
num.clear();
|
||||
p++;
|
||||
if(p>2)
|
||||
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?
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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}
|
||||
|
||||
@ -156,6 +156,7 @@ private:
|
||||
bool SClogdebug(CmdSet);
|
||||
bool SClogerror(CmdSet);
|
||||
bool SCcastspell(CmdSet);
|
||||
bool SCqueryitem(CmdSet);
|
||||
|
||||
// Own variable declarations
|
||||
std::map<std::string, unsigned char> my_usrPermissionMap;
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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<len;i++)ret[i]=line[i];
|
||||
ret[len]=0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *strparse::fgetvalue(char *line){
|
||||
int i;
|
||||
char *out;
|
||||
for(i=0;line[i]!='='&&i<strlen(line);i++);
|
||||
out=line+i+1;
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
char *strparse::RemoveComments(char *txt){
|
||||
char *ptr;
|
||||
ptr=strchr(txt,(char)'/');
|
||||
if(ptr==NULL)return txt;
|
||||
else {
|
||||
ptr[0]=0; // terminate the string a bit earlier if a comment is found. "blah // crap\0" -> "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;
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
|
||||
namespace strparse {
|
||||
|
||||
char *fgetlabel(char*);
|
||||
char *fgetvalue(char*);
|
||||
char *RemoveComments(char*);
|
||||
char *TrimSpacesLeft(char*);
|
||||
bool HasEqual(char*);
|
||||
|
||||
}
|
||||
@ -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::";
|
||||
|
||||
@ -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());
|
||||
//...
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
#ifndef _REALMAUTH_H
|
||||
#define _REALMAUTH_H
|
||||
|
||||
void ProcessClientLogonProof(char*);
|
||||
|
||||
#endif
|
||||
@ -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<count;i++){
|
||||
pkt >> 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;
|
||||
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
#ifndef _REALMLISTHANDLER_H
|
||||
#define _REALMLISTHANDLER_H
|
||||
|
||||
bool HandleRealmList(ByteBuffer);
|
||||
|
||||
#endif
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
321
src/Client/World/CacheHandler.cpp
Normal file
321
src/Client/World/CacheHandler.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#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<PlayerNameCacheItem*>::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<PlayerNameCacheItem*>::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<PlayerNameCacheItem*>::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<PlayerNameCacheItem*>::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<size;i++)
|
||||
{
|
||||
len=255;
|
||||
memset(nameptr,0,13);
|
||||
PlayerNameCacheItem *cacheItem=new PlayerNameCacheItem;
|
||||
fh.read((char*)&(cacheItem->_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;i<session->objmgr.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);
|
||||
}
|
||||
25
src/Client/World/CacheHandler.h
Normal file
25
src/Client/World/CacheHandler.h
Normal file
@ -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<PlayerNameCacheItem*> _cache;
|
||||
};
|
||||
|
||||
void ItemProtoCache_InsertDataToSession(WorldSession *session);
|
||||
void ItemProtoCache_WriteDataToCache(WorldSession *session);
|
||||
|
||||
#endif
|
||||
@ -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;
|
||||
|
||||
@ -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:
|
||||
|
||||
76
src/Client/World/ObjMgr.cpp
Normal file
76
src/Client/World/ObjMgr.cpp
Normal file
@ -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<uint32>::iterator i=_noitem.begin(); i != _noitem.end(); i++)
|
||||
{
|
||||
if(*i == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
35
src/Client/World/ObjMgr.h
Normal file
35
src/Client/World/ObjMgr.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef _OBJMGR_H
|
||||
#define _OBJMGR_H
|
||||
|
||||
#include <list>
|
||||
|
||||
class Object;
|
||||
struct ItemProto;
|
||||
|
||||
typedef std::list<Object*> ObjList;
|
||||
typedef std::vector<ItemProto*> 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<uint32> _noitem;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -13,7 +13,6 @@ Object::Object()
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
// TODO: unregister object from object mgr
|
||||
if(_uint32values)
|
||||
delete [] _uint32values;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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<PlayerNameCacheItem*>::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<PlayerNameCacheItem*>::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<PlayerNameCacheItem*>::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<PlayerNameCacheItem*>::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<size;i++)
|
||||
{
|
||||
len=255;
|
||||
memset(nameptr,0,13);
|
||||
PlayerNameCacheItem *cacheItem=new PlayerNameCacheItem;
|
||||
fh.read((char*)&(cacheItem->_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);
|
||||
}
|
||||
}*/
|
||||
@ -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<PlayerNameCacheItem*> _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<Player*> _players;
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,463 +0,0 @@
|
||||
#include <winsock.h>
|
||||
#include <time.h>
|
||||
#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<<unk<<acc<<clientseed_uint32;
|
||||
outpkt.append(digest.GetDigest(),20);
|
||||
// recvPacket << real_size
|
||||
// recvPacket << ziped_UI_Plugins_Info
|
||||
// TODO: add addon data, simulate no addons.
|
||||
outpkt<<(uint32)0; // no addons? no idea, but seems to work. MaNGOS doesnt accept without this.
|
||||
|
||||
DEBUG3(
|
||||
printf("CMSG_AUTH_SESSION=");
|
||||
printchex((char*)outpkt.contents(),outpkt.size(),true);
|
||||
)
|
||||
SendWorldPacket(CMSG_AUTH_SESSION,&outpkt);
|
||||
_crypt.SetKey(sessionkey.AsByteArray(), 40);
|
||||
_crypt.Init();
|
||||
}break;
|
||||
|
||||
case SMSG_AUTH_RESPONSE:{
|
||||
uint8 errcode;
|
||||
data>>errcode;
|
||||
if(errcode==0xC){
|
||||
DEBUG1(printf("World Authentication successful, preparing for char list request...\n"););
|
||||
SendWorldPacket(CMSG_CHAR_ENUM,NULL);
|
||||
} else {
|
||||
printf("World Authentication failed, errcode=0x%X\n",(unsigned char)errcode);
|
||||
}
|
||||
}break;
|
||||
|
||||
case SMSG_CHAR_ENUM:{
|
||||
uint8 num;
|
||||
Player plr[10];
|
||||
uint8 dummy8;
|
||||
uint32 dummy32;
|
||||
|
||||
data >> 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<num;i++){
|
||||
data >> 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<num;i++){
|
||||
printf("## %s (%u) [%s/%s]\n",
|
||||
plr[i]._name.c_str(),plr[i]._level,raceName[plr[i]._race],className[plr[i]._class]);
|
||||
DEBUG1(printf("-> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
#ifndef _WORLDPACKETHANDLER_H
|
||||
#define _WORLDPACKETHANDLER_H
|
||||
|
||||
#include <string>
|
||||
#include "Auth/ByteBuffer.h"
|
||||
void HandleWorldPacket(ByteBuffer);
|
||||
void HandleOpcode(uint16,ByteBuffer&);
|
||||
void SendWorldPacket(uint16, ByteBuffer*);
|
||||
|
||||
#endif
|
||||
@ -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);
|
||||
|
||||
@ -1,18 +1,21 @@
|
||||
#ifndef _WORLDSESSION_H
|
||||
#define _WORLDSESSION_H
|
||||
|
||||
#include <deque>
|
||||
#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<WorldPacket*,ZThread::FastMutex> pktQueue;
|
||||
bool _valid,_authed,_logged,_deleteme; // world status
|
||||
SocketHandler _sh; // handles the WorldSocket
|
||||
Channel *_channels;
|
||||
uint64 _targetGUID,_followGUID,_myGUID;
|
||||
uint64 _targetGUID,_followGUID,_myGUID;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,36 +0,0 @@
|
||||
// --- Defines ---
|
||||
//...
|
||||
|
||||
// --- Includes ---
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
|
||||
//#include <SDL/SDL.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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, ...);
|
||||
|
||||
@ -260,6 +260,12 @@
|
||||
<Filter
|
||||
Name="World"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\Client\World\CacheHandler.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\World\CacheHandler.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\World\Channel.cpp">
|
||||
</File>
|
||||
@ -281,6 +287,12 @@
|
||||
<File
|
||||
RelativePath=".\Client\World\Object.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\World\ObjMgr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\World\ObjMgr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\World\Opcodes.cpp">
|
||||
</File>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user