* 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,player ${@thiswhisper_name}
|
||||||
SET,lang ${@0}
|
SET,lang ${@0}
|
||||||
DEAULT,lang ${@thiswhisper_lang}
|
DEFAULT,lang ${@thiswhisper_lang}
|
||||||
SET,msg ${@def}
|
SET,msg ${@def}
|
||||||
|
|
||||||
WHISPER,{${player}},{${lang}} ${msg}
|
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},
|
{"logerror",&DefScriptPackage::SClogerror},
|
||||||
{"logdebug",&DefScriptPackage::SClogdebug},
|
{"logdebug",&DefScriptPackage::SClogdebug},
|
||||||
{"castspell", &DefScriptPackage::SCcastspell},
|
{"castspell", &DefScriptPackage::SCcastspell},
|
||||||
|
{"queryitem", &DefScriptPackage::SCqueryitem},
|
||||||
|
|
||||||
// table termination
|
// table termination
|
||||||
{NULL,NULL}
|
{NULL,NULL}
|
||||||
|
|||||||
@ -156,6 +156,7 @@ private:
|
|||||||
bool SClogdebug(CmdSet);
|
bool SClogdebug(CmdSet);
|
||||||
bool SClogerror(CmdSet);
|
bool SClogerror(CmdSet);
|
||||||
bool SCcastspell(CmdSet);
|
bool SCcastspell(CmdSet);
|
||||||
|
bool SCqueryitem(CmdSet);
|
||||||
|
|
||||||
// Own variable declarations
|
// Own variable declarations
|
||||||
std::map<std::string, unsigned char> my_usrPermissionMap;
|
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){
|
bool DefScriptPackage::SCsavecache(CmdSet Set){
|
||||||
((PseuInstance*)parentMethod)->SaveAllCache();
|
((PseuInstance*)parentMethod)->SaveAllCache();
|
||||||
std::stringstream tmp;
|
std::stringstream str;
|
||||||
std::string str;
|
|
||||||
if(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())
|
if(((PseuInstance*)parentMethod)->GetWSession() && ((PseuInstance*)parentMethod)->GetWSession()->IsValid())
|
||||||
{
|
{
|
||||||
tmp << ((PseuInstance*)parentMethod)->GetWSession()->plrNameCache.GetSize();
|
str << "Cache saved. [ ";
|
||||||
str+="Cache saved. [ "+tmp.str()+ " Playernames ]";
|
str << ((PseuInstance*)parentMethod)->GetWSession()->plrNameCache.GetSize();
|
||||||
((PseuInstance*)parentMethod)->GetWSession()->SendChatMessage(CHAT_MSG_SAY,0,str,"");
|
str << " Playernames, ";
|
||||||
|
str << ((PseuInstance*)parentMethod)->GetWSession()->objmgr.GetItemProtoCount();
|
||||||
|
str << " Item Prototypes";
|
||||||
|
str << " ]";
|
||||||
|
|
||||||
|
((PseuInstance*)parentMethod)->GetWSession()->SendChatMessage(CHAT_MSG_SAY,0,str.str(),"");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -190,6 +194,20 @@ bool DefScriptPackage::SCcastspell(CmdSet Set)
|
|||||||
return true;
|
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)
|
void DefScriptPackage::My_LoadUserPermissions(VarSet &vs)
|
||||||
{
|
{
|
||||||
static char *prefix = "USERS::";
|
static char *prefix = "USERS::";
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
#include "DefScript/DefScript.h"
|
#include "DefScript/DefScript.h"
|
||||||
#include "Realm/RealmSocket.h"
|
#include "Realm/RealmSocket.h"
|
||||||
#include "World/WorldSession.h"
|
#include "World/WorldSession.h"
|
||||||
|
#include "CacheHandler.h"
|
||||||
|
|
||||||
#include "Cli.h"
|
#include "Cli.h"
|
||||||
|
|
||||||
|
|
||||||
@ -206,6 +208,7 @@ void PseuInstance::SaveAllCache(void)
|
|||||||
if(GetWSession() && GetWSession()->IsValid())
|
if(GetWSession() && GetWSession()->IsValid())
|
||||||
{
|
{
|
||||||
GetWSession()->plrNameCache.SaveToFile();
|
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 << guid;
|
||||||
packet.SetOpcode(CMSG_NAME_QUERY);
|
packet.SetOpcode(CMSG_NAME_QUERY);
|
||||||
SendWorldPacket(packet);
|
SendWorldPacket(packet);
|
||||||
|
// to prevent opcode spam, we need to make a list with already requested names
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::SendPing(uint32 ping){
|
void WorldSession::SendPing(uint32 ping){
|
||||||
@ -62,6 +63,20 @@ void WorldSession::SendEmote(uint32 id){
|
|||||||
SendWorldPacket(packet);
|
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"
|
#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()
|
Item::Item()
|
||||||
{
|
{
|
||||||
_type |= TYPE_ITEM;
|
_type |= TYPE_ITEM;
|
||||||
|
|||||||
@ -93,6 +93,301 @@ enum SellFailure
|
|||||||
SELL_ERR_CANT_FIND_VENDOR = 3
|
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
|
class Item : public Object
|
||||||
{
|
{
|
||||||
public:
|
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()
|
Object::~Object()
|
||||||
{
|
{
|
||||||
// TODO: unregister object from object mgr
|
|
||||||
if(_uint32values)
|
if(_uint32values)
|
||||||
delete [] _uint32values;
|
delete [] _uint32values;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ enum TYPEID
|
|||||||
class Object
|
class Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Object();
|
virtual ~Object();
|
||||||
inline const uint64 GetGUID() const { return GetUInt64Value(0); }
|
inline const uint64 GetGUID() const { return GetUInt64Value(0); }
|
||||||
inline const uint32 GetGUIDLow() const { return GetUInt32Value(0); }
|
inline const uint32 GetGUIDLow() const { return GetUInt32Value(0); }
|
||||||
inline const uint32 GetGUIDHigh() const { return GetUInt32Value(1); }
|
inline const uint32 GetGUIDHigh() const { return GetUInt32Value(1); }
|
||||||
@ -71,7 +71,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~Object();
|
Object();
|
||||||
void _Create(uint64 guid);
|
void _Create(uint64 guid);
|
||||||
void _InitValues(void);
|
void _InitValues(void);
|
||||||
|
|
||||||
|
|||||||
@ -9,113 +9,8 @@
|
|||||||
#include "DefScript/DefScript.h"
|
#include "DefScript/DefScript.h"
|
||||||
#include "WorldSession.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){
|
/*void Player::Init(PlayerEnum player)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
this->player = player;
|
this->player = player;
|
||||||
}
|
}
|
||||||
@ -126,9 +21,9 @@ void PlayerSettings::SetActionButtons(WorldPacket &data)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: Implent this
|
// TODO: Implent this
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void PlayerSettings::SetSpells(WorldPacket &data)
|
/*void PlayerSettings::SetSpells(WorldPacket &data)
|
||||||
{
|
{
|
||||||
if (!init)
|
if (!init)
|
||||||
return;
|
return;
|
||||||
@ -152,7 +47,7 @@ void PlayerSettings::CastSpell(uint32 spellId, uint64 target)
|
|||||||
|
|
||||||
WorldPacket packet;
|
WorldPacket packet;
|
||||||
packet.SetOpcode(CMSG_CAST_SPELL);
|
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
|
// Can be bugged, not fully tested, probably doesn't work when the guid is high
|
||||||
// Damn packed guid stuff! xD
|
// Damn packed guid stuff! xD
|
||||||
|
|
||||||
@ -183,4 +78,4 @@ void PlayerSettings::HandleCastResultOpcode(WorldPacket &packet)
|
|||||||
|
|
||||||
|
|
||||||
//logdetail(l);
|
//logdetail(l);
|
||||||
}
|
}*/
|
||||||
@ -5,30 +5,12 @@
|
|||||||
#include "WorldPacket.h"
|
#include "WorldPacket.h"
|
||||||
#include "SysDefs.h"
|
#include "SysDefs.h"
|
||||||
|
|
||||||
struct PlayerItem
|
struct PlayerEnumItem
|
||||||
{
|
{
|
||||||
uint32 itemID;
|
uint32 displayId;
|
||||||
uint8 inventorytype;
|
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 {
|
class PlayerEnum {
|
||||||
public:
|
public:
|
||||||
uint64 _guid;
|
uint64 _guid;
|
||||||
@ -52,7 +34,7 @@ public:
|
|||||||
uint32 _petInfoId;
|
uint32 _petInfoId;
|
||||||
uint32 _petLevel;
|
uint32 _petLevel;
|
||||||
uint32 _petFamilyId;
|
uint32 _petFamilyId;
|
||||||
PlayerItem _items[20];
|
PlayerEnumItem _items[20];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -70,45 +52,28 @@ private:
|
|||||||
PlayerEnum player;
|
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:
|
public:
|
||||||
PlayerSettings()
|
MyCharacter(WorldSession *ws)
|
||||||
{
|
{
|
||||||
castingSpell = false;
|
_worldSession = ws;
|
||||||
init = false;
|
_isbusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(WorldSession *worldSession)
|
/*void SetActionButtons(WorldPacket &data);
|
||||||
{
|
|
||||||
_worldSession = worldSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetActionButtons(WorldPacket &data);
|
|
||||||
void SetSpells(WorldPacket &data);
|
void SetSpells(WorldPacket &data);
|
||||||
void CastSpell(uint32 spellId, uint64 target);
|
void CastSpell(uint32 spellId, uint64 target);
|
||||||
void HandleCastResultOpcode(WorldPacket &packet);
|
void HandleCastResultOpcode(WorldPacket &packet);*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool castingSpell;
|
bool _isbusy;
|
||||||
WorldSession *_worldSession;
|
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
|
#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
|
_followGUID=0; // dont follow anything
|
||||||
_myGUID=0; // i dont have a guid yet
|
_myGUID=0; // i dont have a guid yet
|
||||||
plrNameCache.ReadFromFile(); // load names/guids of known players
|
plrNameCache.ReadFromFile(); // load names/guids of known players
|
||||||
|
ItemProtoCache_InsertDataToSession(this);
|
||||||
_deleteme = false;
|
_deleteme = false;
|
||||||
_channels = new Channel(this);
|
_channels = new Channel(this);
|
||||||
// _playerSettings->Init(this);
|
// _playerSettings->Init(this);
|
||||||
@ -157,7 +158,8 @@ OpcodeHandler *WorldSession::_GetOpcodeHandlerTable() const
|
|||||||
|
|
||||||
{MSG_MOVE_TELEPORT_ACK, &WorldSession::_HandleTelePortAckOpcode},
|
{MSG_MOVE_TELEPORT_ACK, &WorldSession::_HandleTelePortAckOpcode},
|
||||||
{SMSG_COMPRESSED_UPDATE_OBJECT, &WorldSession::_HandleCompressedUpdateObjectOpcode},
|
{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
|
// table termination
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
@ -272,7 +274,6 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
uint8 num;
|
uint8 num;
|
||||||
PlayerEnum plr[10]; // max characters per realm is 10
|
PlayerEnum plr[10]; // max characters per realm is 10
|
||||||
uint8 dummy8;
|
uint8 dummy8;
|
||||||
//uint32 dummy32; // Unused
|
|
||||||
|
|
||||||
recvPacket >> num;
|
recvPacket >> num;
|
||||||
if(num==0){
|
if(num==0){
|
||||||
@ -305,9 +306,10 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
recvPacket >> plr[i]._petInfoId;
|
recvPacket >> plr[i]._petInfoId;
|
||||||
recvPacket >> plr[i]._petLevel;
|
recvPacket >> plr[i]._petLevel;
|
||||||
recvPacket >> plr[i]._petFamilyId;
|
recvPacket >> plr[i]._petFamilyId;
|
||||||
for(unsigned int inv=0;inv<20;inv++){
|
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 )
|
{
|
||||||
}
|
recvPacket >> plr[i]._items[inv].displayId >> plr[i]._items[inv].inventorytype;
|
||||||
|
}
|
||||||
plrNameCache.AddInfo(plr[i]._guid, plr[i]._name);
|
plrNameCache.AddInfo(plr[i]._guid, plr[i]._name);
|
||||||
}
|
}
|
||||||
bool char_found=false;
|
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]);
|
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",
|
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);
|
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;
|
char_found=true;
|
||||||
_myGUID=plr[i]._guid;
|
_myGUID=plr[i]._guid;
|
||||||
playerNum = i;
|
playerNum = i;
|
||||||
@ -535,7 +543,7 @@ void WorldSession::_HandleTelePortAckOpcode(WorldPacket& recvPacket)
|
|||||||
|
|
||||||
recvPacket >> unk >> guid >> unk3 >> unk1 >> unk2 >> o >> x >> y >> z >> ang >> unk4;
|
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;
|
WorldPacket response;
|
||||||
response.SetOpcode(MSG_MOVE_FALL_LAND);
|
response.SetOpcode(MSG_MOVE_FALL_LAND);
|
||||||
|
|||||||
@ -1,18 +1,21 @@
|
|||||||
#ifndef _WORLDSESSION_H
|
#ifndef _WORLDSESSION_H
|
||||||
#define _WORLDSESSION_H
|
#define _WORLDSESSION_H
|
||||||
|
|
||||||
#include <deque>
|
#include "common.h"
|
||||||
#include "PseuWoW.h"
|
#include "PseuWoW.h"
|
||||||
#include "Network/SocketHandler.h"
|
#include "Network/SocketHandler.h"
|
||||||
#include "common.h"
|
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "Auth/AuthCrypt.h"
|
#include "Auth/AuthCrypt.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
|
#include "ObjMgr.h"
|
||||||
|
#include "CacheHandler.h"
|
||||||
|
|
||||||
class WorldSocket;
|
class WorldSocket;
|
||||||
class WorldPacket;
|
class WorldPacket;
|
||||||
class Channel;
|
class Channel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct OpcodeHandler
|
struct OpcodeHandler
|
||||||
{
|
{
|
||||||
uint16 opcode;
|
uint16 opcode;
|
||||||
@ -56,8 +59,10 @@ public:
|
|||||||
void SendQueryPlayerName(uint64 guid);
|
void SendQueryPlayerName(uint64 guid);
|
||||||
void SendPing(uint32);
|
void SendPing(uint32);
|
||||||
void SendEmote(uint32);
|
void SendEmote(uint32);
|
||||||
|
void SendQueryItem(uint32, uint64);
|
||||||
|
|
||||||
PlayerNameCache plrNameCache;
|
PlayerNameCache plrNameCache;
|
||||||
|
ObjMgr objmgr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -83,18 +88,15 @@ private:
|
|||||||
void _HandleCastResultOpcode(WorldPacket& recvPacket);
|
void _HandleCastResultOpcode(WorldPacket& recvPacket);
|
||||||
void _HandleCompressedUpdateObjectOpcode(WorldPacket& recvPacket);
|
void _HandleCompressedUpdateObjectOpcode(WorldPacket& recvPacket);
|
||||||
void _HandleUpdateObjectOpcode(WorldPacket& recvPacket);
|
void _HandleUpdateObjectOpcode(WorldPacket& recvPacket);
|
||||||
|
void _HandleItemQuerySingleResponseOpcode(WorldPacket& recvPacket);
|
||||||
|
|
||||||
|
|
||||||
//Player *_player; // The connected character
|
|
||||||
//PlayerSettings *_playerSettings; // Settings for the connected character
|
|
||||||
|
|
||||||
PseuInstance *_instance;
|
PseuInstance *_instance;
|
||||||
WorldSocket *_socket;
|
WorldSocket *_socket;
|
||||||
ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> pktQueue;
|
ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> pktQueue;
|
||||||
bool _valid,_authed,_logged,_deleteme; // world status
|
bool _valid,_authed,_logged,_deleteme; // world status
|
||||||
SocketHandler _sh; // handles the WorldSocket
|
SocketHandler _sh; // handles the WorldSocket
|
||||||
Channel *_channels;
|
Channel *_channels;
|
||||||
uint64 _targetGUID,_followGUID,_myGUID;
|
uint64 _targetGUID,_followGUID,_myGUID;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#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, ...)
|
void logerror(const char *str, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
_log_setcolor(true,LRED);
|
_log_setcolor(false,LRED);
|
||||||
va_start(ap, str);
|
va_start(ap, str);
|
||||||
vprintf( str, ap );
|
vfprintf( stderr, str, ap );
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
_log_resetcolor(true);
|
_log_resetcolor(false);
|
||||||
|
|
||||||
printf("\n");
|
fprintf(stderr,"\n");
|
||||||
|
|
||||||
if(logfile)
|
if(logfile)
|
||||||
{
|
{
|
||||||
@ -117,13 +117,13 @@ void logcritical(const char *str, ...)
|
|||||||
if(!str || instance->GetConf()->debug < 2)
|
if(!str || instance->GetConf()->debug < 2)
|
||||||
return;
|
return;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
_log_setcolor(true,RED);
|
_log_setcolor(false,RED);
|
||||||
va_start(ap, str);
|
va_start(ap, str);
|
||||||
vprintf( str, ap );
|
vfprintf( stderr, str, ap );
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
_log_resetcolor(true);
|
_log_resetcolor(false);
|
||||||
|
|
||||||
printf("\n");
|
fprintf(stderr,"\n");
|
||||||
|
|
||||||
if(logfile)
|
if(logfile)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,7 +22,7 @@ enum Color
|
|||||||
WHITE
|
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 log(const char *str, ...);
|
||||||
void logdetail(const char *str, ...);
|
void logdetail(const char *str, ...);
|
||||||
void logdebug(const char *str, ...);
|
void logdebug(const char *str, ...);
|
||||||
|
|||||||
@ -260,6 +260,12 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="World"
|
Name="World"
|
||||||
Filter="">
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath=".\Client\World\CacheHandler.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Client\World\CacheHandler.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Client\World\Channel.cpp">
|
RelativePath=".\Client\World\Channel.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -281,6 +287,12 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\Client\World\Object.h">
|
RelativePath=".\Client\World\Object.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Client\World\ObjMgr.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Client\World\ObjMgr.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Client\World\Opcodes.cpp">
|
RelativePath=".\Client\World\Opcodes.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user