antoniofr
01/04/2015, 03:36 PM
Segue a função usada para a criação de comandos sem relogar, tinha feito uma função semelhante mais usando a função gObjDel e não vinha funcionando
muito bem, então fui procurando outros métodos e encontrei essas duas funções originais do gameserver.
usei a função gObjTeleport no final porque depois de execultado a função os mobs não apareciam mais.
as offsets usadas são para a versão 97d.
STRUCTS:
struct PMSG_CHARMAPJOINRESULT
{
// static data ------------------------------------
// non-static data --------------------------------
/*<thisrel this+0x0>*/ /*|0x3|*/ struct PBMSG_HEAD h;
/*<thisrel this+0x3>*/ /*|0x1|*/ unsigned char subcode;
/*<thisrel this+0x4>*/ /*|0x1|*/ unsigned char MapX;
/*<thisrel this+0x5>*/ /*|0x1|*/ unsigned char MapY;
/*<thisrel this+0x6>*/ /*|0x1|*/ unsigned char MapNumber;
/*<thisrel this+0x7>*/ /*|0x1|*/ unsigned char Dir;
/*<thisrel this+0x8>*/ /*|0x4|*/ unsigned long Exp;
/*<thisrel this+0xc>*/ /*|0x4|*/ unsigned long NextExp;
/*<thisrel this+0x10>*/ /*|0x2|*/ unsigned short LevelUpPoint;
/*<thisrel this+0x12>*/ /*|0x2|*/ unsigned short Str;
/*<thisrel this+0x14>*/ /*|0x2|*/ unsigned short Dex;
/*<thisrel this+0x16>*/ /*|0x2|*/ unsigned short Vit;
/*<thisrel this+0x18>*/ /*|0x2|*/ unsigned short Energy;
/*<thisrel this+0x1a>*/ /*|0x2|*/ unsigned short Life;
/*<thisrel this+0x1c>*/ /*|0x2|*/ unsigned short MaxLife;
/*<thisrel this+0x1e>*/ /*|0x2|*/ unsigned short Mana;
/*<thisrel this+0x20>*/ /*|0x2|*/ unsigned short MaxMana;
/*<thisrel this+0x22>*/ /*|0x2|*/ unsigned short BP;
/*<thisrel this+0x24>*/ /*|0x2|*/ unsigned short MaxBP;
/*<thisrel this+0x28>*/ /*|0x4|*/ int Money;
/*<thisrel this+0x2c>*/ /*|0x1|*/ unsigned char PkLevel;
/*<thisrel this+0x2d>*/ /*|0x1|*/ unsigned char CtlCode;
/*<thisrel this+0x2e>*/ /*|0x2|*/ short AddPoint;
/*<thisrel this+0x30>*/ /*|0x2|*/ short MaxAddPoint;
// base classes -----------------------------------
// friends ----------------------------------------
// static functions -------------------------------
// non-virtual functions --------------------------
// virtual functions ------------------------------
};
struct PMSG_CHARREGEN
{
PBMSG_HEAD h;
char subcode;
char MapX;
char MapY;
char MapNumber;
char Dir;
unsigned short Life;
unsigned short Mana;
unsigned short BP;
unsigned int Exp;
unsigned int Money;
};
Função:
void Functions::PlayerRefresh(DWORD aIndex)
{
//------------------------------------------------------------
// CHAR MAP JOIN - SEND [CREATE]
//------------------------------------------------------------
PMSG_CHARMAPJOINRESULT lpMsg;
lpMsg.h.c = 0xC3;
lpMsg.h.head = 0xF3;
lpMsg.h.size = 0x33;
lpMsg.subcode = 0x03;
lpMsg.MapX = lpObj[aIndex].X;
lpMsg.MapY = lpObj[aIndex].Y;
lpMsg.MapNumber = lpObj[aIndex].MapNumber;
lpMsg.Dir = lpObj[aIndex].Dir;
lpMsg.Exp = lpObj[aIndex].Experience;
lpMsg.NextExp = lpObj[aIndex].NextExp;
lpMsg.LevelUpPoint = lpObj[aIndex].LevelUpPoints;
lpMsg.Str = lpObj[aIndex].Strength;
lpMsg.Dex = lpObj[aIndex].Dexterity;
lpMsg.Vit = lpObj[aIndex].Vitality;
lpMsg.Energy = lpObj[aIndex].Energy;
lpMsg.Money = lpObj[aIndex].Money;
lpMsg.PkLevel = lpObj[aIndex].PK_Level;
lpMsg.Life = (short)lpObj[aIndex].Life;
lpMsg.MaxLife = (short)((double)lpObj[aIndex].AddLife + lpObj[aIndex].MaxLife);
lpMsg.Mana = (short)lpObj[aIndex].Mana;
lpMsg.MaxMana = (short)((double)lpObj[aIndex].AddMana + lpObj[aIndex].MaxMana);
lpMsg.CtlCode = (short)lpObj[aIndex].Authority;
lpMsg.BP = lpObj[aIndex].BP;
lpMsg.MaxBP = lpObj[aIndex].AddBP + lpObj[aIndex].MaxBP;
DataSend(aIndex, &lpMsg.h.c, (DWORD)lpMsg.h.size);
//------------------------------------------------------------
// CHAR REGEN - SEND [DESTROY]
//------------------------------------------------------------
PMSG_CHARREGEN pMsg;
pMsg.h.c = 0xC1;
pMsg.h.head = 0xF3;
pMsg.h.size = 0x24;
pMsg.subcode = 0x04;
pMsg.Dir = lpObj[aIndex].Dir;
pMsg.MapX = LOBYTE(lpObj[aIndex].X);
pMsg.MapY = LOBYTE(lpObj[aIndex].Y);
pMsg.Life = (float)lpObj[aIndex].Life;
pMsg.Mana = (float)lpObj[aIndex].Mana;
pMsg.Exp = lpObj[aIndex].Experience;
pMsg.MapNumber = lpObj[aIndex].MapNumber;
pMsg.Money = lpObj[aIndex].Money;
pMsg.BP = LOWORD(lpObj[aIndex].BP);
pObj[aIndex].PathCount = 0;
DataSend(aIndex, &pMsg.h.c, (DWORD)pMsg.h.size);
gObjTeleport(aIndex,lpObj[aIndex].MapNumber,lpObj[aIndex].X,lpObj[aIndex].Y);
GCItemListSend(aIndex);
CGRequestQuestInfo(aIndex);
DGGuildMemberInfoRequest(aIndex);
}
OFFSETS:
#define GCItemListSend ((void(*)(int aIndex))0x00411010)
#define CGRequestQuestInfo ((void(*)(int aIndex))0x0042A7C0)
#define DGGuildMemberInfoRequest ((void(*)(int aIndex))0x0042C460)
Créditos: antonio.fr
muito bem, então fui procurando outros métodos e encontrei essas duas funções originais do gameserver.
usei a função gObjTeleport no final porque depois de execultado a função os mobs não apareciam mais.
as offsets usadas são para a versão 97d.
STRUCTS:
struct PMSG_CHARMAPJOINRESULT
{
// static data ------------------------------------
// non-static data --------------------------------
/*<thisrel this+0x0>*/ /*|0x3|*/ struct PBMSG_HEAD h;
/*<thisrel this+0x3>*/ /*|0x1|*/ unsigned char subcode;
/*<thisrel this+0x4>*/ /*|0x1|*/ unsigned char MapX;
/*<thisrel this+0x5>*/ /*|0x1|*/ unsigned char MapY;
/*<thisrel this+0x6>*/ /*|0x1|*/ unsigned char MapNumber;
/*<thisrel this+0x7>*/ /*|0x1|*/ unsigned char Dir;
/*<thisrel this+0x8>*/ /*|0x4|*/ unsigned long Exp;
/*<thisrel this+0xc>*/ /*|0x4|*/ unsigned long NextExp;
/*<thisrel this+0x10>*/ /*|0x2|*/ unsigned short LevelUpPoint;
/*<thisrel this+0x12>*/ /*|0x2|*/ unsigned short Str;
/*<thisrel this+0x14>*/ /*|0x2|*/ unsigned short Dex;
/*<thisrel this+0x16>*/ /*|0x2|*/ unsigned short Vit;
/*<thisrel this+0x18>*/ /*|0x2|*/ unsigned short Energy;
/*<thisrel this+0x1a>*/ /*|0x2|*/ unsigned short Life;
/*<thisrel this+0x1c>*/ /*|0x2|*/ unsigned short MaxLife;
/*<thisrel this+0x1e>*/ /*|0x2|*/ unsigned short Mana;
/*<thisrel this+0x20>*/ /*|0x2|*/ unsigned short MaxMana;
/*<thisrel this+0x22>*/ /*|0x2|*/ unsigned short BP;
/*<thisrel this+0x24>*/ /*|0x2|*/ unsigned short MaxBP;
/*<thisrel this+0x28>*/ /*|0x4|*/ int Money;
/*<thisrel this+0x2c>*/ /*|0x1|*/ unsigned char PkLevel;
/*<thisrel this+0x2d>*/ /*|0x1|*/ unsigned char CtlCode;
/*<thisrel this+0x2e>*/ /*|0x2|*/ short AddPoint;
/*<thisrel this+0x30>*/ /*|0x2|*/ short MaxAddPoint;
// base classes -----------------------------------
// friends ----------------------------------------
// static functions -------------------------------
// non-virtual functions --------------------------
// virtual functions ------------------------------
};
struct PMSG_CHARREGEN
{
PBMSG_HEAD h;
char subcode;
char MapX;
char MapY;
char MapNumber;
char Dir;
unsigned short Life;
unsigned short Mana;
unsigned short BP;
unsigned int Exp;
unsigned int Money;
};
Função:
void Functions::PlayerRefresh(DWORD aIndex)
{
//------------------------------------------------------------
// CHAR MAP JOIN - SEND [CREATE]
//------------------------------------------------------------
PMSG_CHARMAPJOINRESULT lpMsg;
lpMsg.h.c = 0xC3;
lpMsg.h.head = 0xF3;
lpMsg.h.size = 0x33;
lpMsg.subcode = 0x03;
lpMsg.MapX = lpObj[aIndex].X;
lpMsg.MapY = lpObj[aIndex].Y;
lpMsg.MapNumber = lpObj[aIndex].MapNumber;
lpMsg.Dir = lpObj[aIndex].Dir;
lpMsg.Exp = lpObj[aIndex].Experience;
lpMsg.NextExp = lpObj[aIndex].NextExp;
lpMsg.LevelUpPoint = lpObj[aIndex].LevelUpPoints;
lpMsg.Str = lpObj[aIndex].Strength;
lpMsg.Dex = lpObj[aIndex].Dexterity;
lpMsg.Vit = lpObj[aIndex].Vitality;
lpMsg.Energy = lpObj[aIndex].Energy;
lpMsg.Money = lpObj[aIndex].Money;
lpMsg.PkLevel = lpObj[aIndex].PK_Level;
lpMsg.Life = (short)lpObj[aIndex].Life;
lpMsg.MaxLife = (short)((double)lpObj[aIndex].AddLife + lpObj[aIndex].MaxLife);
lpMsg.Mana = (short)lpObj[aIndex].Mana;
lpMsg.MaxMana = (short)((double)lpObj[aIndex].AddMana + lpObj[aIndex].MaxMana);
lpMsg.CtlCode = (short)lpObj[aIndex].Authority;
lpMsg.BP = lpObj[aIndex].BP;
lpMsg.MaxBP = lpObj[aIndex].AddBP + lpObj[aIndex].MaxBP;
DataSend(aIndex, &lpMsg.h.c, (DWORD)lpMsg.h.size);
//------------------------------------------------------------
// CHAR REGEN - SEND [DESTROY]
//------------------------------------------------------------
PMSG_CHARREGEN pMsg;
pMsg.h.c = 0xC1;
pMsg.h.head = 0xF3;
pMsg.h.size = 0x24;
pMsg.subcode = 0x04;
pMsg.Dir = lpObj[aIndex].Dir;
pMsg.MapX = LOBYTE(lpObj[aIndex].X);
pMsg.MapY = LOBYTE(lpObj[aIndex].Y);
pMsg.Life = (float)lpObj[aIndex].Life;
pMsg.Mana = (float)lpObj[aIndex].Mana;
pMsg.Exp = lpObj[aIndex].Experience;
pMsg.MapNumber = lpObj[aIndex].MapNumber;
pMsg.Money = lpObj[aIndex].Money;
pMsg.BP = LOWORD(lpObj[aIndex].BP);
pObj[aIndex].PathCount = 0;
DataSend(aIndex, &pMsg.h.c, (DWORD)pMsg.h.size);
gObjTeleport(aIndex,lpObj[aIndex].MapNumber,lpObj[aIndex].X,lpObj[aIndex].Y);
GCItemListSend(aIndex);
CGRequestQuestInfo(aIndex);
DGGuildMemberInfoRequest(aIndex);
}
OFFSETS:
#define GCItemListSend ((void(*)(int aIndex))0x00411010)
#define CGRequestQuestInfo ((void(*)(int aIndex))0x0042A7C0)
#define DGGuildMemberInfoRequest ((void(*)(int aIndex))0x0042C460)
Créditos: antonio.fr