📄 item.cpp
字号:
//#include "abot.h"
#pragma warning( disable : 4786 )
#include "external\D2Client.h"
#include "item.h"
#include <stdio.h>
#include "properties.h"
#include "TextPatch.h"
#include "botfunc.h"
#include <stack>
using namespace std;
void D2Print(LPCSTR lpszFormat,...);
extern int _debug;
map<string,DWORD> CD2Item::_mod_def;
list<string> CD2Item::_filter;
map<DWORD,SIZE> CD2Item::_item_size;
void DebugItemBits(DWORD data, DWORD size, DWORD pos)
{
/*
BYTE n;
char DebugBuffer[200];
sprintf(DebugBuffer,"%d: ",pos);
if(size>32) size = 32;
if(size!=32) data = data<<(32 - size);
for(n = 0;n < size;n++)
{
if((data & 0x80000000) !=0)
sprintf(DebugBuffer,"%s1",DebugBuffer);
else
sprintf(DebugBuffer,"%s0",DebugBuffer);
data = data<<1;
}
D2Print(DebugBuffer);
*/
}
BOOL CD2Item::ParseMods(BitFields &iPacket)
{
int temp;
mod_num=0;
do
{
ITEM_MOD *p=&mod[mod_num];
p->id=iPacket.GetField(9);
if(mod_num>0)
{
if(p->id<mod[mod_num-1].id)
{
mod_num=0;
return FALSE;
}
}
if(p->id==511)
{
return TRUE;
};
D2_PROPERTIE* prop=GetPropertiesRow(p->id);
if(!prop) break;
for(int i=0;i<prop->numFields;i++)
{
p->value[i]=iPacket.GetField(prop->bits[i]);
p->value[i]-=prop->bias;
}
switch(p->id)
{
case 48:
case 50:
case 52:
case 54:
p->num=1;
p->value[0]+=p->value[1];
break;
case 57:
p->num=2;
//p->value[0]/=5;
temp=(p->value[0]+p->value[1])/2;
p->value[0]=p->value[2]*0.04;
p->value[1]=temp*p->value[0]/10;
break;
default:
p->num=prop->numFields;
break;
}
mod_num++;
}while(mod_num<MAX_MOD && iPacket.pos+9<iPacket.max);
return FALSE;
}
BOOL CD2Item::FromPacket(BYTE* aPacket, DWORD aLen,BOOL identify)
{
BitFields iPacket(aPacket,aLen);
memset(this,0,sizeof(CD2Item));
iPacket.GetField(8);//message
action=(BYTE)iPacket.GetField(8);
iPacket.GetField(8);//message size
ItemType=(BYTE)iPacket.GetField(8);
// DebugItemBits(iPacket.GetField(4),4,iPacket.pos);
id=(DWORD)iPacket.GetField(32);
this->isSocketsFull = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(3),3,iPacket.pos);
this->isIdentified = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(1),1,iPacket.pos);
this->isSwitchin = iPacket.GetField(1);
this->isSwitchout = iPacket.GetField(1);
this->isBroken = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(1),1,iPacket.pos);
this->fromBelt = iPacket.GetField(1);
this->hasSockets = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(1),1,iPacket.pos);
this->isJustGenerated = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(2),2,iPacket.pos);
this->isEar = iPacket.GetField(1);
this->isStartitem = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(3),3,iPacket.pos);
this->isMiscItem = iPacket.GetField(1);
this->isEthereal = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(1),1,iPacket.pos);
this->isPersonalized = iPacket.GetField(1);
this->isGamble = iPacket.GetField(1);
this->isRuneWord = iPacket.GetField(1);
DebugItemBits(iPacket.GetField(18),18,iPacket.pos);
// D2Print("%d[%d]",iPacket.pos/8, iPacket.pos%8);
if(action== ITEM_ACTION_DROP||action== ITEM_ACTION_NEW_GROUND)
{
pos_x=(WORD)iPacket.GetField(16);
pos_y=(WORD)iPacket.GetField(16);
}
else
{
DebugItemBits(iPacket.GetField(4),4,iPacket.pos);
pos_x=(WORD)iPacket.GetField(4);
pos_y=(WORD)iPacket.GetField(4);
storage_id=(BYTE)iPacket.GetField(3);
}
if(isEar)return TRUE;
code_id=iPacket.GetField(32);
if(code[3]==' ') code[3]='\0';
code[4]='\0';
switch(code_id)
{
case 6581351://gld
if(iPacket.GetField(1)) GoldAmount = iPacket.GetField(32);
else GoldAmount = iPacket.GetField(12);
isGold=TRUE;
return TRUE;
case 7037545:
case 7037556:
case 7955819:
case 7892834://cube
case 7762275://bolt
case 7762273://arrow
return TRUE;
}
// packet not long enough to read ItemLevel
if(iPacket.pos+14>=iPacket.max) return TRUE;
GemedNumber =(BYTE)iPacket.GetField(3);
Ilvl = (BYTE)iPacket.GetField(7);
ItemQuality = (BYTE)iPacket.GetField(4);
BOOL flag1=iPacket.GetField(1);
BOOL flag2=iPacket.GetField(1);
if(flag1)//ring amu charm jew
{
DebugItemBits(iPacket.GetField(3),3,iPacket.pos);
}
else if(flag2)
{
DebugItemBits(iPacket.GetField(11),11,iPacket.pos);
}
int pos_begin=iPacket.pos;
///////////////////////////////////////////
int retry_time=0;
RE_TRY:
iPacket.pos=pos_begin;
///////////////////////////////////////////
if(isIdentified)
{
switch(ItemQuality)
{
case ITEM_LEVEL_MAGIC:
MagicPrefix = (WORD)iPacket.GetField(11);
MagicSuffix = (WORD)iPacket.GetField(11);
break;
case ITEM_LEVEL_UNIQUE:
UniqueId=(WORD)iPacket.GetField(12);
break;
case ITEM_LEVEL_SET:
SetId=(WORD)iPacket.GetField(12);
//GetRandBits(iPacket);
//DebugItemBits(iPacket.GetField(5),5,iPacket.pos);
break;
case ITEM_LEVEL_SUPERIOR:
//?
DebugItemBits(iPacket.GetField(3),3,iPacket.pos);
break;
case ITEM_LEVEL_RARE:
case ITEM_LEVEL_CRAFT:
RarePrefix=(WORD)iPacket.GetField(8)-155;
RareSuffix=(WORD)iPacket.GetField(8);
if(!isIdentified) return TRUE;
/////////////////////////////////////////////
// 这一段不知道是什么含义,长度也不固定
DebugItemBits(iPacket.GetField(6),6,iPacket.pos);
const int rcskip[]={3,4,5,2,6,7,1,8,9};
for(int i=0;i<rcskip[retry_time];i++)
{
DebugItemBits(iPacket.GetField(11),11,iPacket.pos);
}
/////////////////////////////////////////////
break;
}
}
if(this->isRuneWord)
{
DebugItemBits(iPacket.GetField(16),16,iPacket.pos);
}
//基本防御
if(ItemType==ITEM_ITEMTYPE_ARMOR
||ItemType==ITEM_ITEMTYPE_HELM
||ItemType==ITEM_ITEMTYPE_SHIELD
||ItemType==ITEM_ITEMTYPE_EXPANSION
||ItemType==ITEM_ITEMTYPE_OTHER&&!flag1)
{
nDefense=iPacket.GetField(11)-10;
}
if(IsThrowItem())
{
// GetRandBits(iPacket);
//DebugItemBits(iPacket.GetField(52),52,iPacket.pos);
// nQuantity=iPacket.GetField(6);
DebugItemBits(iPacket.GetField(9),9,iPacket.pos);
DebugItemBits(iPacket.GetField(17),17,iPacket.pos);
}
else if( code_id==7496503 ) //幻化
{
DebugItemBits(iPacket.GetField(8),8,iPacket.pos);
}
else if(ItemType==ITEM_ITEMTYPE_BOW)
{
DebugItemBits(iPacket.GetField(17),17,iPacket.pos);
}
else if( !flag1)
{
nMaxDur=iPacket.GetField(8);
nDur=iPacket.GetField(8);
DebugItemBits(iPacket.GetField(1),1,iPacket.pos);
}
if( this->hasSockets)
{
nSocket=iPacket.GetField(4);
}
if(!isIdentified) return TRUE;
if(ItemQuality==ITEM_LEVEL_SET)
{
DebugItemBits(iPacket.GetField(5),5,iPacket.pos);
}
BOOL bModOK=ParseMods(iPacket);
///////////////////////////////////////////////////
if(!bModOK)
{
if((ItemQuality==ITEM_LEVEL_RARE
||ItemQuality==ITEM_LEVEL_CRAFT)
&&retry_time<9)
{
nDefense=0;
nMaxDur=0;
nDur=0;
nSocket=0;
retry_time++;
goto RE_TRY;
}
}
///////////////////////////////////////////////////
if(identify)Identify();
return TRUE;
}
void CD2Item::WriteToLog()
{
char buf[200];
char buf2[13];
// BotWriteLog("----------------------------------");
GetName(buf);
if(Ilvl)
{
strcat(buf," (l");
sprintf(buf2,"%d",Ilvl);
strcat(buf,buf2);
strcat(buf,")");
}
BotWriteLog(buf);
// D2Print("----------------------------------");
// D2Print("code=%s (%d)",code,Code2Number(code));
if(nDefense)BotWriteLog("Base Defense: %d",nDefense);
if(IsThrowItem())
{
BotWriteLog("Quantity: %d",nQuantity);
}
if(nMaxDur)BotWriteLog("Durability: %d of %d",nDur,nMaxDur);
for(int i=0;i<mod_num;i++)
{
ITEM_MOD *p=&mod[i];
// D2_PROPERTIE* prop=GetPropertiesRow(p->id);
// if(!prop)
// {
// BotWriteLog("$$3 <Unkown Mod>");
// continue;
// }
string format= GetTextPatch(p->id,D2_TEXT_PROPERTIES);
if(format.empty())
{
switch(p->num)
{
case 1:format="(%d)";break;
case 2:format="(%d) (%d)";break;
case 3:format="(%d) (%d) (%d)";break;
case 4:format="(%d) (%d) (%d) (%d)";break;
}
}
switch(p->num)
{
case 1:
sprintf(buf,format.c_str(),p->value[0]);
break;
case 2:
sprintf(buf,format.c_str(),p->value[1],p->value[0]);
break;
case 3:
sprintf(buf,format.c_str(),p->value[2],p->value[0],p->value[1]);
break;
case 4:
sprintf(buf,format.c_str(),p->value[0],p->value[1],p->value[2],p->value[3]);
break;
}
/*
if(p->id==39 && i+3<mod_num)
{
//all res
if(mod[i+1].id==41 && mod[i+2].id==43 && mod[i+3].id==45
&& p->value[0]==mod[i+1].value[0] && p->value[0]==mod[i+2].value[0] && p->value[0]==mod[i+3].value[0])
{
BotWriteLog("[39-45] $$3All Resistances %+d",p->value[0]);
i+=3;
continue;
}
}
else if(p->id==0 && i+3<mod_num)
{
//all res
if(mod[i+1].id==1 && mod[i+2].id==2 && mod[i+3].id==3
&& p->value[0]==mod[i+1].value[0] && p->value[0]==mod[i+2].value[0] && p->value[0]==mod[i+3].value[0])
{
BotWriteLog("[0-3] $$3%+d to all Attributes",p->value[0]);
i+=3;
continue;
}
}
*/
BotWriteLog("[%d] $$3%s",p->id,buf);
}
if(nSocket)BotWriteLog("$$3Socketed(%d)",nSocket);
if(isEthereal) BotWriteLog("$$3Ethereal (Can Not Be Repaired)");
// if(isUselessItem) BotWriteLog("$$1(Useless)");
// D2Print("----------------------------------"); //BotWriteLog
}
void CD2Item::Dump()
{
char buf[200];
char buf2[13];
D2Print("----------------------------------");
GetName(buf);
if(Ilvl)
{
strcat(buf," (l");
sprintf(buf2,"%d",Ilvl);
strcat(buf,buf2);
strcat(buf,")");
}
D2Print(buf);
// D2Print("----------------------------------");
D2Print("code=%s (%d)",code,Code2Number(code));
if(nDefense)D2Print("Base Defense: %d",nDefense);
if(IsThrowItem())
{
D2Print("Quantity: %d",nQuantity);
}
if(nMaxDur)D2Print("Durability: %d of %d",nDur,nMaxDur);
for(int i=0;i<mod_num;i++)
{
ITEM_MOD *p=&mod[i];
// D2_PROPERTIE* prop=GetPropertiesRow(p->id);
// if(!prop)
// {
// D2Print("$$3 <Unkown Mod>");
// continue;
// }
string format= GetTextPatch(p->id,D2_TEXT_PROPERTIES);
if(format.empty())
{
switch(p->num)
{
case 1:format="(%d)";break;
case 2:format="(%d) (%d)";break;
case 3:format="(%d) (%d) (%d)";break;
case 4:format="(%d) (%d) (%d) (%d)";break;
}
}
switch(p->num)
{
case 1:
sprintf(buf,format.c_str(),p->value[0]);
break;
case 2:
sprintf(buf,format.c_str(),p->value[1],p->value[0]);
break;
case 3:
sprintf(buf,format.c_str(),p->value[2],p->value[0],p->value[1]);
break;
case 4:
sprintf(buf,format.c_str(),p->value[0],p->value[1],p->value[2],p->value[3]);
break;
}
/* if(p->id==39 && i+3<mod_num)
{
//all res
if(mod[i+1].id==41 && mod[i+2].id==43 && mod[i+3].id==45
&& p->value[0]==mod[i+1].value[0] && p->value[0]==mod[i+2].value[0] && p->value[0]==mod[i+3].value[0])
{
D2Print("[39-45] $$3All Resistances %+d",p->value[0]);
i+=3;
continue;
}
}
else if(p->id==0 && i+3<mod_num)
{
//all res
if(mod[i+1].id==1 && mod[i+2].id==2 && mod[i+3].id==3
&& p->value[0]==mod[i+1].value[0] && p->value[0]==mod[i+2].value[0] && p->value[0]==mod[i+3].value[0])
{
D2Print("[0-3] $$3%+d to all Attributes",p->value[0]);
i+=3;
continue;
}
}
*/
D2Print("[%d] $$3%s",p->id,buf);
}
if(nSocket)D2Print("$$3Socketed(%d)",nSocket);
if(isEthereal) D2Print("$$3Ethereal (Can Not Be Repaired)");
if(isUselessItem) D2Print("$$1(Useless)");
// D2Print("----------------------------------");
}
DWORD GetBitField(BYTE* data, DWORD pos, DWORD len, DWORD max)
{
// trying to read beyond the end of the packet
if(pos + len > max) {
// if we are already at or beyond the end of packet, return 0;
if(pos >= max) {
return 0;
}
// otherwise adjust len to all remaining bits
// D2Print("Trying to read beyond eop. len:%d pos:%d max:%d",len,pos,max);
len = max - pos;
}
return (DWORD)(*(unsigned __int64 *)(data+pos/8)<<(64-len-(pos&7))>>(64-len));
}
void CD2Item::GetName(char *buf)
{
if(isEar)
{
strcpy(buf,"Ear");
return;
}
if(isGold)
{
sprintf(buf,"%d Gold",this->GoldAmount);
return;
}
if(!this->isIdentified)
{
sprintf(buf,"$$1UnIdentified %s%s",
GetColorCode(),
GetTextPatch(Code2Number(code),D2_TEXT_BASENAME).c_str());
return;
}
if(this->ItemQuality == ITEM_LEVEL_MAGIC)
{
sprintf(buf,"$$3%s %s %s",
GetTextPatch(MagicPrefix,D2_TEXT_MAGICPREFIX).c_str(),
GetTextPatch(Code2Number(code),D2_TEXT_BASENAME).c_str(),
GetTextPatch(MagicSuffix,D2_TEXT_MAGICSUFFIX).c_str()
);
}
else if(this->ItemQuality == ITEM_LEVEL_UNIQUE)
{
sprintf(buf,"$$4[%d] %s",UniqueId,GetTextPatch(UniqueId,D2_TEXT_UNIQUE).c_str());
}
else if(this->ItemQuality == ITEM_LEVEL_SET)
{
sprintf(buf,"$$2[%d] %s",
SetId,
GetTextPatch(SetId,D2_TEXT_SET).c_str()
);
}
else if(this->ItemQuality == ITEM_LEVEL_RARE)
{
sprintf(buf,"$$9%s %s %s",
GetTextPatch(RarePrefix,D2_TEXT_RAREPREFIX).c_str(),
GetTextPatch(RareSuffix,D2_TEXT_RARESUFFIX).c_str(),
GetTextPatch(Code2Number(code),D2_TEXT_BASENAME).c_str()
);
}
else if(this->ItemQuality == ITEM_LEVEL_CRAFT)
{
sprintf(buf,"$$8%s %s %s",
GetTextPatch(RarePrefix,D2_TEXT_RAREPREFIX).c_str(),
GetTextPatch(RareSuffix,D2_TEXT_RARESUFFIX).c_str(),
GetTextPatch(Code2Number(code),D2_TEXT_BASENAME).c_str()
);
}
else
{
sprintf(buf,"%s%s",GetColorCode(),GetTextPatch(Code2Number(code),D2_TEXT_BASENAME).c_str());
}
}
BOOL CD2Item::IsPotion()
{
switch(code_id)
{
case 7108210: //rvl
case 7566962: //rvl
case 3240040: //hp1
case 3305576: //hp2
case 3371112: //hp3
case 3436648: //hp4
case 3502184: //hp5
case 3240045: //mp1
case 3305581: //mp2
case 3371117: //mp3
case 3436653: //mp4
case 3502189: //mp5
case 7565433:
return TRUE;
default:
return FALSE;
}
}
//DEL void CD2Item::GetRandBits(BitFields &iPacket)
//DEL {
//DEL static int aaa=0;
//DEL D2Print("aaa=%d",aaa);
//DEL
//DEL for(int i=0;i<aaa;i++)
//DEL iPacket.GetField(1);
//DEL aaa++;
//DEL }
BOOL CD2Item::IsThrowItem()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -