Initial MSVC 2008 projects workspace

This commit is contained in:
alexey.min
2012-02-01 05:25:08 +00:00
commit 03de3bdc95
1446 changed files with 476853 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_AbnormalStatusUpdate( class L2Client *pcls, L2GamePacket *p )
{
//pcls->log_packet( true, packbuffer, plen );
pcls->buffs.parse_AbnormalStatusUpdate( p );
pcls->postUpdateUI( UPDATE_BUFFS );
}

View File

@@ -0,0 +1,22 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x39);
writeS(_requestorName);
writeD(_itemDistribution); */
// 0 - Finders Keepers
// 1 - Random
// 2 - Random including spoil
// 3 - by turn
// 4 - by turn including spoil
void L2Client::ph_AskJoinParty( class L2Client *pcls, L2GamePacket *p )
{
WCHAR requesterName[256] = {0};
unsigned int itemDistribution;
p->getPacketType();
wcscpy( requesterName, p->readUnicodeStringPtr() );
itemDistribution = p->readUInt();
pcls->handle_AskJoinParty( requesterName, itemDistribution );
}

View File

@@ -0,0 +1,19 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_AuthLoginFail( class L2Client *pcls, L2GamePacket *p )
{
L2Game_AuthLoginFail *paf = new L2Game_AuthLoginFail(
(unsigned char *)p->getBytesPtr(), p->getPacketSize() );
if( paf->parse() )
{
char reason[256] = {0};
L2Game_AuthLoginFail::reasonCodeToString( paf->p_reasonCode, reason );
log_error( LOG_ERROR, "AuthLognFail: %s\n", reason );
pcls->addChatToTabFormat( CHAT_SYS, L"Game AuthLoginFail: %S", reason );
}
delete paf;
paf = NULL;
pcls->disconnectClient(true);
}

View File

@@ -0,0 +1,102 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/*** Server: Len 2765 [BuyList] |
CD 0A
07
C7 55 35 00 // money 3 495 367
90 00 00 00 // list ID 144
2B 00 // items count 43
[ for each item ]
04 00 // item type 1 0-weapon/ring/earring/necklace 1-armor/shield 4-item/questitem/adena
00 00 00 00 // objectID
2B 07 00 00 // itemID 1835 Soulshot no grade
00 00 00 00 // current count
05 00 // item type2 0-weapon 1-shield/armor 2-ring/earring/necklace 3-questitem 4-adena 5-item
00 00 // ??
00 00 00 00 // bodypart (for armor)
00 00 // enchant level
00 00 00 00 // ??
07 00 00 00 // price (=7)
FE FF FF FF // atk attribute type (-2) \\
00 00 00 00 // atk attribute value \\
00 00 00 00 // fire def \\
00 00 00 00 // water def || 8 element attributes
00 00 00 00 // wind def ||
00 00 00 00 // earth def //
00 00 00 00 // holy def //
00 00 00 00 // unholy def // ***/
void L2Client::ph_BuyList( L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
long long int curMoney = 0;
L2_VERSION ver = pcls->account.getL2Version();
if( ver < L2_VERSION_T23 ) curMoney = p->readInt();
else curMoney = p->readInt64();
unsigned int listID = p->readUInt();
int cnt = (int)p->readUShort();
if( cnt <= 0 ) return;
TradeItem it;
TradeItemsList *list = new TradeItemsList();
list->curMoney = curMoney;
list->itemCount = 0;
list->listID = listID;
int i = 0;
for( i=0; i<cnt; i++ )
{
it.setUnused();
it.type1 = (int)p->readUShort(); // type1
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( ver < L2_VERSION_T23 ) it.count = p->readD();
else it.count = p->readQ();
it.type2 = (int)p->readUShort(); // type2
p->readUShort(); // ??
p->readUInt(); // bodypart
it.enchantLevel = (int)p->readUShort();
p->readUInt(); // ??
if( ver < L2_VERSION_T23 ) it.price = p->readD();
else it.price = p->readQ();
// read 8 attributes
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
//
list->addItem( it );
}
if( list->itemCount != cnt )
{
log_error( LOG_ERROR, "BuyList handler error!\n" );
delete list;
list = NULL;
return;
}
pcls->handle_BuyList( list );
}

View File

@@ -0,0 +1,45 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 15 [ChangeMoveType]
0F 00
28
B2 16 00 10 // object id
00 00 00 00 // 0 - walk, 1 - run
00 00 00 00 // ?? **/
void L2Client::ph_ChangeMoveType( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
int run = p->readInt();
//log_error( LOG_OK, "ChangeMoveType: objectID %u to %d\n", objectID, run );
if( pcls->usr.objectID == objectID )
{
pcls->usr.isRunning = run;
pcls->postUpdateUI( UPDATE_USER );
//log_error( LOG_OK, "User ChangeMoveType\n" );
if( run ) pcls->addChatToTab( CHAT_DMG, L"You run" );
else pcls->addChatToTab( CHAT_DMG, L"You walk" );
}
else
{
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->isRunning = run;
} break;
case L2OT_NPC:
{
pcls->world_npcs.npcs_array[idx]->isRunning = run;
} break;
}
}
else log_error( LOG_ERROR, "WOT cannot find objectID while ChangeMoveType\n" );
}
}

View File

@@ -0,0 +1,62 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x29);
writeD(_charObjId);
writeD(_moveType);
writeD(_x);
writeD(_y);
writeD(_z); **/
void L2Client::ph_ChangeWaitType( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
unsigned int moveType = p->readUInt();
/*int x = */p->readInt();
/*int y = */p->readInt();
/*int z = */p->readInt();
//
const unsigned int WT_SITTING = 0;
const unsigned int WT_STANDING = 1;
const unsigned int WT_START_FAKEDEATH = 2;
const unsigned int WT_STOP_FAKEDEATH = 3;
//
if( pcls->usr.objectID == objectID )
{
switch( moveType )
{
case WT_SITTING: { pcls->usr.isSitting = 1; pcls->addChatToTab( CHAT_DMG, L"You sit" ); } break;
case WT_STANDING: { pcls->usr.isSitting = 0; pcls->addChatToTab( CHAT_DMG, L"You stand" ); } break;
case WT_START_FAKEDEATH: { pcls->usr.isFakeDeath = 1; pcls->addChatToTab( CHAT_DMG, L"You start FakeDeath" ); } break;
case WT_STOP_FAKEDEATH: { pcls->usr.isFakeDeath = 0; pcls->addChatToTab( CHAT_DMG, L"You stop FakeDeath" ); } break;
}
pcls->postUpdateUI( UPDATE_USER );
//log_error( LOG_OK, "User ChangeMoveType %u\n", moveType );
}
else
{
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
switch( moveType )
{
case WT_SITTING: pcls->world_chars.chars_array[idx]->isSitting = 1; break;
case WT_STANDING: pcls->world_chars.chars_array[idx]->isSitting = 0; break;
}
} break;
/*case L2OT_NPC:
{
pcls->world_npcs.npcs_array[idx]->isRunning = run;
} break;*/
}
}
else log_error( LOG_ERROR, "WOT cannot find objectID while ChangeMoveType\n" );
}
}

View File

@@ -0,0 +1,18 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_CharCreateFail( class L2Client *pcls, L2GamePacket *p )
{
L2Game_CharCreateFail *pf = new L2Game_CharCreateFail(
p->getBytesPtr(), p->getPacketSize() );
if( pf->parse( pcls->account.getL2Version() ) )
{
char reason[256] = {0};
pf->reasonCodeToString( pf->p_reasonCode, reason );
log_error( LOG_ERROR, "CharCreateFail: %s\n", reason );
pcls->addChatToTabFormat( CHAT_SYS, L"Char create error: %S", reason );
}
delete pf;
pf = NULL;
}

View File

@@ -0,0 +1,15 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_CharCreateSuccess( class L2Client *pcls, L2GamePacket *p )
{
L2Game_CharCreateSuccess *pc = new L2Game_CharCreateSuccess(
p->getBytesPtr(), p->getPacketSize() );
if( pc->parse( pcls->account.getL2Version() ) )
{
log_error( LOG_OK, "Char create OK\n" );
pcls->addChatToTab( CHAT_SYS, L"Char create OK" );
}
delete pc;
}

View File

@@ -0,0 +1,21 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_CharDeleteFail( class L2Client *pcls, L2GamePacket *p )
{
L2Game_CharDeleteFail *cdf = new L2Game_CharDeleteFail(
p->getBytesPtr(), p->getPacketSize() );
if( cdf->parse() )
{
char reason[256] = {0};
L2Game_CharDeleteFail::reasonCodeToString( cdf->p_reasonCode, reason );
log_error( LOG_ERROR, "CharDeleteFail: %s\n", reason );
pcls->addChatToTabFormat( CHAT_SYS, L"CharDeleteFail: %S\n", reason );
}
delete cdf;
cdf = NULL;
// request charSelection info
pcls->send_RequestGotoLobby();
}

View File

@@ -0,0 +1,12 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_CharDeleteSuccess( class L2Client *pcls, L2GamePacket *p )
{
log_error( LOG_DEBUG, "CharDeleteSuccess\n" );
p->getPacketType(); // just trigger
// request character selection info
pcls->send_RequestGotoLobby();
pcls->addChatToTab( CHAT_SYS, L"Character marked to deletion." );
}

View File

@@ -0,0 +1,54 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_CharInfo( class L2Client *pcls, L2GamePacket *p )
{
L2Player *cha = new L2Player();
cha->parse_CharInfo( p, pcls->account.getL2Version() );
// we should request PledgeInfo for every clan that we do not know
if( cha->clanID != 0 )
{
TCHAR tszClanName[256] = {0};
if( !pcls->world_clans.GetClanNameByID( cha->clanID, tszClanName ) )
{
L2GamePacket *pack = new L2GamePacket();
pack->writeReset();
pack->setPacketType( 0x65 ); // RequestPledgeInfo
pack->writeUInt( cha->clanID );
pcls->sendPacket( pack, true );
delete pack; pack = NULL;
log_error( LOG_USERAI, "CharInfo: Clan %u unknown, sent RequestPledgeInfo\n",
cha->clanID );
}
}
// set last time when chars coordinates were known exactly
// cha->lastMoveTickTime = GetTickCount(); // done by parse()
// first try to find
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( cha->objectID, &wotNode ) )
{
// already exists, update info
pcls->world_chars.UpdateCharInfo( wotNode.getArrayIdx(), cha );
}
else
{
// add new char
int idx = pcls->world_chars.AddCharInfo( cha );
if( idx >= 0 )
{
wotNode.setPlayer( cha );
wotNode.setArrayIdx( idx );
pcls->world_tree.AddObject( cha->objectID, &wotNode );
}
else
log_error( LOG_ERROR, "Character [%S] failed to add to world and to chars list, possible chars limit exceeded\n",
cha->charName );
}
delete cha;
pcls->postUpdateUI( UPDATE_MAP_PLAYERS );
}

View File

@@ -0,0 +1,84 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_CharSelected( class L2Client *pcls, L2GamePacket *p )
{
pcls->setState( STATE_IN_GAME );
pcls->addChatToTab( CHAT_SYS, L"Entering game..." );
L2Game_CharSelected *p_charSel =
new L2Game_CharSelected( p->getBytesPtr(), p->getPacketSize() );
if( p_charSel->parse( pcls->account.getL2Version() ) )
{
// check obfuscator
if( p_charSel->p_opcodeObfuscatorSeed > 0 )
{
log_error( LOG_WARNING, "CharSelected: client opcode obfusation enabled, seed %08X\n",
p_charSel->p_opcodeObfuscatorSeed );
pcls->addChatToTab( CHAT_SYS, L"Notice: client opcode obfusation enabled!" );
// remember obfuscator
pcls->game_opcodeObfuscatorSeed = p_charSel->p_opcodeObfuscatorSeed;
// init enc/dec tables
if( pcls->game_pCodeObfuscator )
{
#ifdef _DEBUG
log_error( LOG_DEBUG, "CharSelected: deleting existing obfuscator class\n" );
#endif
delete pcls->game_pCodeObfuscator;
pcls->game_pCodeObfuscator = NULL;
}
pcls->game_pCodeObfuscator = new L2PCodeObfuscator();
pcls->game_pCodeObfuscator->setVersionMode( pcls->account.getL2Version() );
pcls->game_pCodeObfuscator->init_tables( pcls->game_opcodeObfuscatorSeed );
}
}
else
{
delete p_charSel;
log_error( LOG_ERROR, "CharSelected parse error!\n" );
pcls->disconnectClient( true ); // FIXME: is it correct here?
return;
}
delete p_charSel;
p_charSel = NULL;
// now we must request some data from server...
// and indicate that client initialization complete (EnterWorld)
// RequestManorList
// RequestKeyMapping
// EnterWorld
unsigned char pack[32];
unsigned int plen = 0;
// lock sending...
EnterCriticalSection( &(pcls->cs_sendPacket) );
// send: D0:0001 RequestManorList
pack[0] = 5; pack[1] = 0; // length 5
pack[2] = 0xD0; pack[3] = 0x01; pack[4] = 0x00; // opcode D0:0001
pcls->pack_OpcodeObfuscate( pack, 5 );
L2GamePacket::encodeXOR_buffer( pack, 5, pcls->game_key_send );
L2PacketSend2( pack, pcls->sock, pcls->game_sendTimeoutMsec, &plen );
// send: D0:0021 RequestKeyMapping
pack[0] = 5; pack[1] = 0; // length 5
pack[2] = 0xD0; pack[3] = 0x21; pack[4] = 0x00; // opcode D0:0021
pcls->pack_OpcodeObfuscate( pack, 5 );
L2GamePacket::encodeXOR_buffer( pack, 5, pcls->game_key_send );
L2PacketSend2( pack, pcls->sock, pcls->game_sendTimeoutMsec, &plen );
// send 11 EnterWorld
L2Game_EnterWorld *ew = new L2Game_EnterWorld();
ew->create();
pcls->pack_OpcodeObfuscate( ew );
ew->encodeXOR( pcls->game_key_send );
L2PacketSend( pcls->sock, ew, pcls->game_sendTimeoutMsec, &plen );
// unlock sending
LeaveCriticalSection( &(pcls->cs_sendPacket) );
delete ew; ew = NULL;
}

View File

@@ -0,0 +1,115 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
#include "ChooseCharDlg.h"
void L2Client::ph_CharSelectionInfo( class L2Client *pcls, L2GamePacket *p )
{
// ok, we authorized ok
pcls->setState( STATE_AUTHED_GAME );
pcls->addChatToTab( CHAT_SYS, L"Received Char list" );
// vars
int i = 0;
unsigned int nCharsInCharSelection = 0;
unsigned int nServerMaxChars = 0;
const int supported_MaxChars = 32;
L2Game_CharSelectionInfoBlock csb_chars[ supported_MaxChars ];
int iSelectedChar = -1;
L2Game_CharSelectionInfo *p_game_charsel = new L2Game_CharSelectionInfo();
p_game_charsel->setBytes( p->getBytesPtr(), p->getPacketSize() );
// parse CharSelectionInfo
p_game_charsel->read_nChars( &nCharsInCharSelection );
p_game_charsel->read_server_maxChars( &nServerMaxChars );
log_error( LOG_DEBUGDUMP, "Char sel: %d chars (max %d)\n", nCharsInCharSelection, nServerMaxChars );
memset( csb_chars, 0, sizeof(csb_chars) ); // clear buffer to save chars list to
for( i=0; i<(int)nCharsInCharSelection; i++ )
{
p_game_charsel->read_next_charSelectInfoBlock( pcls->account.getL2Version(), &(csb_chars[i]) );
log_error( LOG_DEBUGDUMP, "%d: %S lv %d %s\n", i,
csb_chars[i].charName,
csb_chars[i].level,
L2Data_getClass( csb_chars[i].classID ) );
}
delete p_game_charsel;
p_game_charsel = NULL;
// let user choose char in manual mode
// or select char automatically if set so
if( pcls->account.charSelectManual )
{
iSelectedChar = -1;
iSelectedChar = ChooseChar( pcls->hWnd, csb_chars, nCharsInCharSelection );
}
else // auto select char
{
iSelectedChar = -1;
for( i=0; i<(int)nCharsInCharSelection; i++ )
{
if( _wcsicmp( pcls->account.charSelectName, csb_chars[i].charName ) == 0 ) iSelectedChar = i;
}
// auto select failed?
if( iSelectedChar == -1 )
{
log_error( LOG_DEBUG, "Auto select char: char [%S] not found!\n", pcls->account.charSelectName );
pcls->addChatToTabFormat( CHAT_SYS, L"Auto select char: char [%s] not found!", pcls->account.charSelectName );
log_error( LOG_DEBUG, "Running manual select...\n" );
iSelectedChar = ChooseChar( pcls->hWnd, csb_chars, nCharsInCharSelection );
}
else
{
log_error( LOG_DEBUG, "Auto select char: %d [%S]\n", iSelectedChar, csb_chars[iSelectedChar].charName );
}
}
// return value of ChooseChar dialog of -1 means cancel/error
if( iSelectedChar == -1 )
{
log_error( LOG_OK, "Char selection cancelled\n" );
pcls->addChatToTab( CHAT_SYS, L"Cancel." );
pcls->disconnectClient(true);
return;
}
// return value of 0..999 means select char number :)
if( (iSelectedChar >= 0) && (iSelectedChar <= 999) )
{
// reply CharSelect
log_error( LOG_DEBUG, "Manual choose char: %d [%S]\n", iSelectedChar,
csb_chars[iSelectedChar].charName );
pcls->send_CharacterSelect( iSelectedChar );
return;
}
// return value of 1000..1999 means request to delete char
if( (iSelectedChar >= 1000) && (iSelectedChar <= 1999) )
{
iSelectedChar -= 1000;
log_error( LOG_DEBUG, "Request to delete char [%d] [%S]\n", iSelectedChar,
csb_chars[iSelectedChar].charName );
pcls->send_CharacterDelete( iSelectedChar );
return;
}
// return value of 2000..21999 means request to cancel delete char
if( (iSelectedChar >= 2000) && (iSelectedChar <= 2999) )
{
iSelectedChar -= 2000;
log_error( LOG_DEBUG, "Request to cancel delete char [%d] [%S]\n", iSelectedChar,
csb_chars[iSelectedChar].charName );
pcls->send_CharacterRestore( iSelectedChar );
return;
}
// return value of 10000 means request to create char
if( iSelectedChar == 10000 )
{
log_error( LOG_DEBUG, "Request to create char...\n" );
pcls->send_NewCharacter();
return;
}
log_error( LOG_ERROR, "ph_CharSelectionInfo: ERROR: ChooseChar strange return "
"iSelectedChar = %d\n", iSelectedChar );
}

View File

@@ -0,0 +1,114 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
#include "utils.h"
/**
* <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Summon Friend <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
* "Nemu wishes to summon you from Imperial Tomb. Do you accept?"
*/
void L2Client::ph_ConfirmDlg( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
//
size_t sm_template_chars = 8192;
size_t sm_template_size = sm_template_chars*2;
wchar_t *sm_template = (wchar_t *)malloc( sm_template_size );
if( !sm_template )
{
log_error( LOG_ERROR, "ph_ConfirmDlg(): malloc failed!\n" );
return;
}
//
memset( sm_template, 0, sm_template_size );
const char *sm_a = NULL;
unsigned int i = 0;
//
unsigned int sm_ID = p->readUInt();
unsigned int paramCount = p->readUInt();
unsigned int sm_type = 0;
unsigned int timeLimit = 0;
unsigned int requestId = 0;
const wchar_t *text = NULL; // C/<2F>++ <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
sm_a = L2Data_SM_get( sm_ID );
if( !sm_a )
{
log_error( LOG_ERROR, "ph_ConfirmDlg(): cannot find system message with id = %u\n", sm_ID );
free( sm_template );
return;
}
MultiByteToWideChar( CP_ACP, 0, sm_a, -1, sm_template, sm_template_chars-1 );
//
const unsigned int TYPE_ZONE_NAME = 7;
const unsigned int TYPE_SKILL_NAME = 4;
const unsigned int TYPE_ITEM_NAME = 3;
const unsigned int TYPE_NPC_NAME = 2;
const unsigned int TYPE_NUMBER = 1;
const unsigned int TYPE_TEXT = 0;
//
for( i = 1; i < (paramCount + 1); i++ )
{
sm_type = p->readUInt();
switch( sm_type )
{
case TYPE_TEXT:
{
const wchar_t *str = p->readUnicodeStringPtr();
text = str;
Utils_replace_in_SM_template_S( sm_template, i, str );
} break;
case TYPE_NUMBER:
{
int n = p->readInt();
wchar_t str[16];
wsprintfW( str, L"%d", n );
Utils_replace_in_SM_template_S( sm_template, i, str );
} break;
case TYPE_NPC_NAME:
{
unsigned int npcID = p->readUInt() - 1000000;
wchar_t str[256];
char npcName[256] = {0};
L2Data_DB_GetNPCNameTitleByID( npcID, npcName, NULL );
wsprintfW( str, L"%S", npcName );
Utils_replace_in_SM_template_S( sm_template, i, str );
} break;
case TYPE_ITEM_NAME:
{
unsigned int itemID = p->readUInt();
wchar_t str[256];
char itemName[256] = {0};
L2Data_DB_GetItemNamePicByID( itemID, itemName, NULL );
wsprintfW( str, L"%S", itemName );
Utils_replace_in_SM_template_S( sm_template, i, str );
} break;
case TYPE_SKILL_NAME:
{
unsigned int skillID = p->readUInt();
int skillLvl = p->readInt();
wchar_t str[256];
char skillName[256];
L2Data_DB_GetSkillNameByID( skillID, skillName );
wsprintfW( str, L"%S lvl %d", skillName, skillLvl );
Utils_replace_in_SM_template_S( sm_template, i, str );
} break;
case TYPE_ZONE_NAME:
{
int x = p->readInt();
int y = p->readInt();
int z = p->readInt();
wchar_t str[32];
wsprintfW( str, L"(%d,%d,%d)", x, y, z );
Utils_replace_in_SM_template_S( sm_template, i, str );
} break;
}
}
timeLimit = p->readUInt();
requestId = p->readUInt();
//
//log_error_np( LOG_OK, "ConfirmDlg: SystemMessage: [%S]\n", sm_template );
//log_error_np( LOG_OK, "ConfirmDlg: timeout = %u, requestId = %u\n", timeLimit, requestId );
//free( sm_template );
pcls->handle_ConfirmDlg( sm_template, sm_ID, requestId, timeLimit, text );
}

View File

@@ -0,0 +1,39 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x4a);
writeD(_objectId);
writeD(_textType);
writeS(_charName);
writeS(_text); */
void L2Client::ph_CreatureSay( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
//
unsigned int objectID = p->readUInt();
unsigned int textType = p->readUInt();
wchar_t charName[256];
memset( charName, 0, sizeof(charName) );
wcsncpy( charName, p->readUnicodeStringPtr(), 255 );
charName[255] = 0;
wchar_t *text = p->readUnicodeString();
//
switch( textType )
{
case L2_CHAT_MESSAGE::ALL: pcls->addChatToTab( CHAT_ALL, text, charName ); break;
case L2_CHAT_MESSAGE::SHOUT: pcls->addChatToTab( CHAT_SHOUT, text, charName ); break;
case L2_CHAT_MESSAGE::TRADE: pcls->addChatToTab( CHAT_TRADE, text, charName ); break;
case L2_CHAT_MESSAGE::TELL: pcls->addChatToTab( CHAT_WHISPER, text, charName ); break;
case L2_CHAT_MESSAGE::PARTY: pcls->addChatToTab( CHAT_PARTY, text, charName ); break;
case L2_CHAT_MESSAGE::CLAN: pcls->addChatToTab( CHAT_CLAN, text, charName ); break;
case L2_CHAT_MESSAGE::ALLIANCE: pcls->addChatToTab( CHAT_ALLY, text, charName ); break;
case L2_CHAT_MESSAGE::HERO_VOICE: pcls->addChatToTab( CHAT_HERO, text, charName ); break;
case L2_CHAT_MESSAGE::ANNOUNCEMENT: pcls->addChatAnnouncement( text ); break;
}
//
pcls->scripter.call_onChat( objectID, textType, text, charName );
free( text );
text = NULL;
}

View File

@@ -0,0 +1,51 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x08);
writeD(_objectId);
writeD(0x00); //c2 */
void L2Client::ph_DeleteObject( class L2Client *pcls, L2GamePacket *p )
{
unsigned int objectID;
p->getPacketType();
objectID = p->readUInt();
if( objectID == 0 ) return; // O_o WTF
// delete object from world object tree and from corresponding array
// first try to find object in world tree
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
// delete from world tree
pcls->world_tree.DelObject( objectID );
// delete from specified array/list
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.DeleteCharByArrayIdx( wotNode.getArrayIdx() );
pcls->postUpdateUI( UPDATE_MAP_PLAYERS );
} break;
case L2OT_NPC:
{
int isAttackable = 0;
L2Npc *deletingNpc = wotNode.cast_L2Npc();
if( deletingNpc ) isAttackable = deletingNpc->isAttackable;
pcls->world_npcs.DelNPCByArrayIdx( wotNode.getArrayIdx() );
if( isAttackable ) pcls->postUpdateUI( UPDATE_MAP_MOBS );
else pcls->postUpdateUI( UPDATE_MAP_NPCS );
} break;
case L2OT_ITEM:
{
int del_idx = wotNode.getArrayIdx();
//log_error( LOG_USERAI, "DeleteObject: delete item [%s] idx %d!\n",
// pcls->world_ground_items.gi_array[del_idx]->itemName, del_idx );
pcls->world_ground_items.DelGIByArrayIdx( del_idx );
pcls->postUpdateUI( UPDATE_MAP_ITEMS );
} break;
default: log_error( LOG_ERROR, "DeleteObject: unknown objectType for oid %u\n", objectID ); break;
}
}
else log_error( LOG_ERROR, "WOT cannot find OID %u while DeleteObject\n", objectID );
}

View File

@@ -0,0 +1,74 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x00);
writeD(_charObjId);
writeD(_canTeleport ? 0x01 : 0);
writeD(0x00); // 6d 01 00 00 00 - to hide away
writeD(0x00); // 6d 02 00 00 00 - to castle
writeD(0x00); // 6d 03 00 00 00 - to siege HQ
writeD(_sweepable ? 0x01 : 0x00); // sweepable (blue glow)
writeD(_access.allowFixedRes() ? 0x01: 0x00); // 6d 04 00 00 00 - to FIXED
writeD(0x00); // 6d 05 00 00 00 - to fortress **/
void L2Client::ph_Die( class L2Client *pcls, L2GamePacket *p )
{
int party_idx = 0;
p->getPacketType();
unsigned int objectID = p->readUInt();
//
if( objectID == pcls->usr.objectID ) // user died :(
{
// user died :(((
log_error( LOG_USERAI, "User died ((((((!\n" );
pcls->addChatToTab( CHAT_DMG, L"You are dead! :(((" );
pcls->usr.isDead = 1;
pcls->usr.canResurrectToVillage = p->readInt();
pcls->usr.canResurrectToCH = p->readInt();
pcls->usr.canResurrectToCastle = p->readInt();
pcls->usr.canResurrectToSiegeHQ = p->readInt();
p->readUInt(); // sweepable (user cannot be sweepable) )))
pcls->usr.canResurrectFixed = p->readInt();
pcls->usr.canResurrectToFortress = p->readInt();
return;
}
// died other world object, not user :)
// TODO: store isSweepable when mob dies
bool oid_found = false;
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->isAlikeDead = 1;
wchar_t wmes[128] = {0};
swprintf( wmes, 127, L"Character [%s] died", pcls->world_chars.chars_array[idx]->charName );
pcls->addChatToTab( CHAT_DMG, wmes );
} break;
case L2OT_NPC:
{
pcls->world_npcs.npcs_array[idx]->isAlikeDead = 1;
} break;
}
oid_found = true;
}
// update also party if needed
if( pcls->party.isInParty( objectID, &party_idx ) )
{
L2Player *partyMember = pcls->party.getPartyPlayer( party_idx );
if( partyMember )
{
log_error( LOG_USERAI, "Party member [%d] = [%S] died!\n", party_idx, partyMember->charName );
partyMember->isAlikeDead = 1;
wchar_t wmes[128] = {0};
swprintf( wmes, 127, L"Party member [%s] died!", partyMember->charName );
pcls->addChatToTab( CHAT_DMG, wmes );
oid_found = true;
}
}
if( !oid_found ) log_error( LOG_ERROR, "WOT cannot find objectID while Die\n" );
}

View File

@@ -0,0 +1,44 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x16);
writeD(_charObjId); // who dropped item
writeD(_item.getObjectId()); // item object id
writeD(_item.getItemId()); // itemID
writeD(_item.getX());
writeD(_item.getY());
writeD(_item.getZ());
writeD(_item.isStackable()); // only show item count if it is a stackable item
writeD(_item.getCount()); */
void L2Client::ph_DropItem( class L2Client *pcls, L2GamePacket *p )
{
L2_VERSION ver = pcls->account.getL2Version();
GroundItem it;
unsigned int charObjectID = 0;
p->getPacketType();
charObjectID = p->readUInt();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
it.x = p->readInt();
it.y = p->readInt();
it.z = p->readInt();
it.stackable = p->readUInt();
if( ver < L2_VERSION_T23 ) it.count = p->readUInt();
else it.count = p->readUInt64();
// readD(); // unknown
//log_error( LOG_USERAI, "DropItem player [%u] dropped %s [%u] at (%d,%d,%d)\n",
// charObjectID, it.itemName, it.itemID, it.x, it.y, it.z );
// add item to ground items
int idx = pcls->world_ground_items.AddGIInfo( &it );
// add item to world object tree
WorldObjectTreeNode wotNode;
wotNode.setArrayIdx( idx );
wotNode.setGroundItem( &it );
pcls->world_tree.AddObject( it.objectID, &wotNode );
pcls->postUpdateUI( UPDATE_MAP_ITEMS );
}

View File

@@ -0,0 +1,9 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_EtcStatusUpdate( class L2Client *pcls, L2GamePacket *p )
{
pcls->etcStatus.parse_EtcStatusUpdate( p );
pcls->postUpdateUI( UPDATE_BUFFS );
}

View File

@@ -0,0 +1,32 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_ExNpcQuestHtmlMessage( class L2Client *pcls, L2GamePacket *p )
{
p->readReset();
p->readUChar(); // FE
p->readUShort(); // 008D
unsigned int npcObjectID = p->readUInt();
const wchar_t *html = p->readUnicodeStringPtr();
unsigned int questID = p->readUInt();
// get NPC info
L2Npc *pNpc = NULL;
WorldObjectTreeNode node;
if( pcls->world_tree.GetInfoByObjectID( npcObjectID, &node ) )
{
if( node.getObjectType() == L2OT_NPC )
{
int idx = node.getArrayIdx();
pNpc = pcls->world_npcs.npcs_array[idx];
}
}
// set copy of last NPC html to script engine to allow script to talk to NPCs
pcls->getInterface()->set_last_NPC_HTML( html, pcls->usr.targetObjectID );
// display UI dialog
pcls->npcHtmlDlg->displayNPCHTML( html, pNpc, 0, questID );
}

View File

@@ -0,0 +1,34 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
// FE:0080: d(oid) S(msg)
void L2Client::ph_ExSetPrivateStoreWholeMsg( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType(); // 0xFE
p->readUShort(); // 0x0080
unsigned int oid = p->readUInt();
const wchar_t *msg = p->readUnicodeStringPtr();
// is it user?
if( oid == pcls->usr.objectID )
{
memset( pcls->usr.privateStoreMsgSell, 0, 128 );
wcsncpy( pcls->usr.privateStoreMsgSell, msg, 63 );
pcls->usr.privateStoreMsgSell[63] = 0;
return;
}
// try to find oid in world tree, must be player
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( oid, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
if( wotNode.getObjectType() == L2OT_PC )
{
memset( pcls->world_chars.chars_array[idx]->privateStoreMsgSell, 0, 128 );
wcsncpy( pcls->world_chars.chars_array[idx]->privateStoreMsgSell, msg, 63 );
pcls->world_chars.chars_array[idx]->privateStoreMsgSell[63] = 0;
}
else log_error( LOG_ERROR, "ExSetPrivateStoreWholeMsg: oid is not player!\n" );
}
else log_error( LOG_ERROR, "ExSetPrivateStoreWholeMsg: cannot find objectID!\n" );
}

View File

@@ -0,0 +1,10 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_ExStorageMaxCount( class L2Client *pcls, L2GamePacket *p )
{
pcls->storageMaxCount.parse_ExStorageMaxCount( p );
pcls->inv.invSize = pcls->storageMaxCount.inventory;
pcls->postUpdateUI( UPDATE_INV );
}

View File

@@ -0,0 +1,38 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
Server: Len 19 [GameGuardQuery]
13 00
74
D9 3D 53 27 1D A5 72 2E 8B 03 17 20 A3 1E 5B C3
Client: Len 19 [GameGuardReply]
13 00
CB
7F 97 F0 78 04 3C E6 D6 71 0C F6 89 DD 9E 06 70
*/
void L2Client::ph_GameGuardQuery( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int q1 = p->readUInt();
unsigned int q2 = p->readUInt();
unsigned int q3 = p->readUInt();
unsigned int q4 = p->readUInt();
// parse request
if( q1 == 0x27533DD9 && q2 == 0x2E72A51D && q3 == 0x2017038B && q4 == 0xC35B1EA3 )
{
log_error( LOG_WARNING, "Received standard l2J GameGuardQuery, replying :)\n" );
pcls->addChatToTab( CHAT_SYS, L"L2J GameGuardQuery" );
// reply with well known answer
pcls->send_GameGuardReply( 0x78F0977F, 0xD6E63C04, 0x89F60C71, 0x70069EDD );
return;
}
//
log_error( LOG_WARNING, "Received unknown GameGuardQuery 0x%08X 0x%08X 0x%08X 0x%08X!\n",
q1, q2, q3, q4 );
pcls->addChatToTab( CHAT_SYS, L"Unknown GameGuardQuery!!!!!" );
pcls->send_GameGuardReply( rand(), rand(), rand(), rand() ); // :redlol:
}

View File

@@ -0,0 +1,26 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x17);
writeD(_playerId); // who picked item?
writeD(_item.getObjectId()); // item objectID
writeD(_item.getX());
writeD(_item.getY());
writeD(_item.getZ()); */
void L2Client::ph_GetItem( class L2Client *pcls, L2GamePacket *p )
{
UNREFERENCED_PARAMETER(pcls);
GroundItem it;
unsigned int charObjectID = 0;
p->getPacketType();
charObjectID = p->readUInt();
it.objectID = p->readUInt();
it.x = p->readInt();
it.y = p->readInt();
it.z = p->readInt();
//log_error( LOG_USERAI, "GetItem player [%u] picked up [%u] at (%d,%d,%d)\n",
// charObjectID, it.objectID, it.x, it.y, it.z );
// before GetItem server sends DeleteObject, so no need to delete item once more
}

View File

@@ -0,0 +1,9 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_InventoryUpdate( class L2Client *pcls, L2GamePacket *p )
{
pcls->inv.parse_InventoryUpdate( p, pcls->account.getL2Version() );
pcls->postUpdateUI( UPDATE_INV );
}

View File

@@ -0,0 +1,9 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_ItemList( class L2Client *pcls, L2GamePacket *p )
{
pcls->inv.parse_ItemList( p, pcls->account.getL2Version() );
pcls->postUpdateUI( UPDATE_INV );
}

View File

@@ -0,0 +1,14 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** writeC(0x3a);
writeD(_response); **/
void L2Client::ph_JoinParty( class L2Client *pcls, L2GamePacket *p )
{
UNREFERENCED_PARAMETER(pcls);
unsigned int response = 0;
p->getPacketType();
response = p->readUInt();
//log_error( LOG_OK, "ph_JoinParty(): response 0x%08X\n", response );
}

View File

@@ -0,0 +1,84 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_KeyPacket( class L2Client *pcls, L2GamePacket *p )
{
L2Game_KeyPacket *p_game_key = new L2Game_KeyPacket( p->getBytesPtr(), p->getPacketSize() );
// parse KeyPacket
if( p_game_key->getPacketSize() == 25 )
{
if( !p_game_key->parse( pcls->account.getL2Version() ) )
{
pcls->addChatToTab( CHAT_SYS, L"KeyPacket parse error!" );
log_error( LOG_ERROR, "KeyPacket parse error!\n" );
pcls->disconnectClient(true);
return;
}
}
else
{
log_error( LOG_WARNING, "KeyPacket: length %u bytes (not 25)\n", p->getPacketSize() );
pcls->addChatToTabFormat( CHAT_SYS, L"Warning! Short KeyPacket (L2Dream?)" );
if(p_game_key->getDataSize() >= 10 )
{
p_game_key->getPacketType();
p_game_key->p_protocolIsOK = p_game_key->readUChar(); // 0x01 - proto OK, 0x00 - proto not supported
p_game_key->readBytes( p_game_key->p_initialKey, 8 ); // first 8 bytes of XOR key
// short packet - ignore all rest bytes...
// add last 8 bytes of XOR key - they are constant
}
else
{
log_error( LOG_ERROR, "KeyPacket: packet len is VERY SHORT! Some protocol error or bot protection!\n" );
pcls->addChatToTab( CHAT_SYS, L"KeyPacket packet length is VERY SHORT! Some protocol error or bot protection!" );
}
L2Game_KeyPacket::createInitialHellboundKey( p_game_key->p_initialKey, p_game_key->p_initialKey );
// disable opcode obfuscation by default on fucking Java servers
p_game_key->p_obfuscatorSeed = 0;
p_game_key->p_serverId = 0;
p_game_key->p_protocolIsOK = 1;
}
// check correct protocol version
if( !p_game_key->p_protocolIsOK )
{
log_error( LOG_WARNING, "KeyPacket: server tells protocolVersion is incorrect? O_o\n" );
pcls->addChatToTab( CHAT_SYS, L"KeyPacket: server tells protocolVersion is incorrect? O_o" );
}
#ifdef _DEBUG
log_error( LOG_DEBUG, "KeyPacket: gs ID: %d\n", (int)p_game_key->p_serverId );
#endif
// create XOR encryption keys
L2Game_KeyPacket::createInitialHellboundKey( p_game_key->p_initialKey, p_game_key->p_initialKey );
// set BOTH recv & send keys to SAME value
memcpy( pcls->game_key_recv, p_game_key->p_initialKey, 16 );
memcpy( pcls->game_key_send, pcls->game_key_recv, 16 );
pcls->game_XOR_enabled = true;
// remember obfuscator
pcls->game_opcodeObfuscatorSeed = p_game_key->p_obfuscatorSeed;
#ifdef _DEBUG
log_error( LOG_DEBUG, "KeyPacket results:\nKey: " );
int i = 0;
for( i=0; i<16; i++ ) log_error_np( LOG_DEBUG, "%02X ", pcls->game_key_recv[i] );
log_error_np( LOG_DEBUG, "\n" );
log_error( LOG_DEBUG, "Obfuscator seed: %08X\n", pcls->game_opcodeObfuscatorSeed );
#endif
// free mem
delete p_game_key; p_game_key = NULL;
// obfuscator manage
if( pcls->game_opcodeObfuscatorSeed != 0 )
{
pcls->game_pCodeObfuscator = new L2PCodeObfuscator();
pcls->game_pCodeObfuscator->setVersionMode( pcls->account.getL2Version() );
pcls->game_pCodeObfuscator->init_tables( pcls->game_opcodeObfuscatorSeed );
log_error( LOG_WARNING, "Client opcode obfuscation enabled.\n" );
pcls->addChatToTab( CHAT_SYS, L"Notice: client opcode obfuscation enabled" );
pcls->addChatToTab( CHAT_SYS, L"Notice: L2 off server >= Hellbound?" );
}
// reply with AuthLogin
pcls->send_AuthLogin();
}

View File

@@ -0,0 +1,17 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** writeC(0x49);
writeD(_objectId); **/
void L2Client::ph_MagicSkillCanceld( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
if( objectID == pcls->usr.objectID )
{
pcls->skills.stopCasting();
pcls->postUpdateUI( UPDATE_USER_CASTING );
pcls->addChatToTab( CHAT_DMG, L"Casting stopped" );
}
}

View File

@@ -0,0 +1,40 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 49 [MagicSkillUse]
31 00
48
6C 08 00 10 // objectId
AC 16 00 10 // targetObjectId
79 05 00 00 // skillID 1401 - Major HEal
0A 00 00 00 // skillLevel level 10
57 07 00 00 // hitTime cast time 1879 ms
CF 08 00 00 // reuseDelay 2255 reuse delay
5B AD 00 00 // x
E5 A4 00 00 // y
5D F2 FF FF // z
00 00 00 00 // ??
00 00 00 00 // ??
00 00 // ?? **/
void L2Client::ph_MagicSkillUse( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
/*unsigned int targetObjectID =*/ p->readUInt();
unsigned int skillID = p->readUInt();
unsigned int skillLvl = p->readUInt();
if( objectID == pcls->usr.objectID )
{
pcls->skills.parse_MagicSkillUse( p );
//pcls->postUpdateUI( UPDATE_SKILL_COOLTIME ); // updated automatically at world tick every 250 ms :)
//pcls->postUpdateUI( UPDATE_USER_CASTING );
char askillName[256] = {0};
wchar_t wskillName[256] = {0};
L2Data_DB_GetSkillNameByID( skillID, askillName );
MultiByteToWideChar( CP_ACP, 0, askillName, -1, wskillName, 255 );
wchar_t wmes[512] = {0};
swprintf( wmes, 511, L"You use [%s] lvl %u", wskillName, skillLvl );
pcls->addChatToTab( CHAT_DMG, wmes );
}
}

View File

@@ -0,0 +1,51 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x2f);
writeD(_charObjId);
writeD(_xDst);
writeD(_yDst);
writeD(_zDst);
writeD(_x);
writeD(_y);
writeD(_z); **/
void L2Client::ph_MoveToLocation( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
int xDst = p->readInt();
int yDst = p->readInt();
int zDst = p->readInt();
int x = p->readInt();
int y = p->readInt();
int z = p->readInt();
//
if( objectID == pcls->usr.objectID )
{
pcls->usr.startMoveTo( xDst, yDst, zDst, x, y, z );
}
else
{
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC: pcls->world_chars.chars_array[idx]->startMoveTo( xDst, yDst, zDst, x, y, z ); break;
case L2OT_NPC:
{
//log_error( LOG_OK, "MoveToLocation NPC %S\n", pcls->world_npcs.npcs_array[idx]->charName );
pcls->world_npcs.npcs_array[idx]->startMoveTo( xDst, yDst, zDst, x, y, z );
} break;
}
}
else
{
log_error( LOG_ERROR, "WOT cannot find objectID while MoveToLocation\n" );
pcls->addChatToTab( CHAT_DMG, L"WARN: possible invisible GM nearby!" );
}
}
}

View File

@@ -0,0 +1,116 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 27 [MoveToPawn]
1B 00
72 // MoveToPawn
6C 08 00 10 // _charObjId // 6C080010 objectID who is moving (can be user at least)
B2 16 00 10 // _targetId // B2160010 is target object id, to which he moves to
39 00 00 00 // _distance wtf is 57?..
C7 AC 00 00 // x
0A A6 00 00 // y dunno if it is user coordinates or mob coordinates
5D F2 FF FF // z
possible these are target's coordinates */
void L2Client::ph_MoveToPawn( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int movingObjectId = p->readUInt();
unsigned int targetObjectId = p->readUInt();
/*int dist = */p->readInt();
int targetX = p->readInt();
int targetY = p->readInt();
int targetZ = p->readInt();
//
if( movingObjectId == pcls->usr.objectID )
{
//pcls->usr.targetObjectID = targetObjectId;
//log_error( LOG_OK, "User (%d,%d,%d) is moving to pawn %u (%d,%d,%d)\n",
// pcls->usr.x, pcls->usr.y, pcls->usr.z, targetObjectId, targetX, targetY, targetZ );
// get target coordinates
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( targetObjectId, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
targetX = pcls->world_chars.chars_array[idx]->x;
targetY = pcls->world_chars.chars_array[idx]->y;
targetZ = pcls->world_chars.chars_array[idx]->z;
} break;
case L2OT_NPC:
{
targetX = pcls->world_npcs.npcs_array[idx]->x;
targetY = pcls->world_npcs.npcs_array[idx]->y;
targetZ = pcls->world_npcs.npcs_array[idx]->z;
} break;
}
pcls->usr.startMoveTo( targetX, targetY, targetZ, pcls->usr.x, pcls->usr.y, pcls->usr.z );
//
//log_error( LOG_OK, "Calculated pawn coords: (%d,%d,%d)\n", targetX, targetY, targetZ );
}
//log_error( LOG_OK, "MoveToPawn: user move\n" );
}
else
{
WorldObjectTreeNode wotNode;
// get target coordinates
if( pcls->world_tree.GetInfoByObjectID( targetObjectId, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
targetX = pcls->world_chars.chars_array[idx]->x;
targetY = pcls->world_chars.chars_array[idx]->y;
targetZ = pcls->world_chars.chars_array[idx]->z;
} break;
case L2OT_NPC:
{
targetX = pcls->world_npcs.npcs_array[idx]->x;
targetY = pcls->world_npcs.npcs_array[idx]->y;
targetZ = pcls->world_npcs.npcs_array[idx]->z;
} break;
}
}
else
{
// maybe someone is movin to me?
if( targetObjectId == pcls->usr.objectID )
{
targetX = pcls->usr.x;
targetY = pcls->usr.y;
targetZ = pcls->usr.z;
}
}
// get moving object's coordinates
wotNode.~WorldObjectTreeNode();
if( pcls->world_tree.GetInfoByObjectID( movingObjectId, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
//log_error( LOG_OK, "MoveToPawn: PC move [%S]\n", pcls->world_chars.chars_array[idx]->charName );
int x = pcls->world_chars.chars_array[idx]->x;
int y = pcls->world_chars.chars_array[idx]->y;
int z = pcls->world_chars.chars_array[idx]->z;
pcls->world_chars.chars_array[idx]->startMoveTo( targetX, targetY, targetZ, x, y, z );
} break;
case L2OT_NPC:
{
int x = pcls->world_npcs.npcs_array[idx]->x;
int y = pcls->world_npcs.npcs_array[idx]->y;
int z = pcls->world_npcs.npcs_array[idx]->z;
//log_error( LOG_OK, "MoveToPawn NPC %S\n", pcls->world_npcs.npcs_array[idx]->charName );
pcls->world_npcs.npcs_array[idx]->startMoveTo( targetX, targetY, targetZ, x, y, z );
} break;
}
}
else log_error( LOG_ERROR, "WOT cannot find objectID while MoveToPawn\n" );
}
}

View File

@@ -0,0 +1,62 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
// dlg
#include "CreateCharDlg.h"
void L2Client::ph_NewCharacterSuccess( class L2Client *pcls, L2GamePacket *p )
{
L2Game_NewCharacterSuccess *ncs = new L2Game_NewCharacterSuccess(
p->getBytesPtr(), p->getPacketSize() );
//
int nTemplates = ncs->read_templatesCount();
int i;
const int supported_maxTemplates = 48;
//
log_error( LOG_DEBUG, "NewCharacterSuccess: %d templates\n", nTemplates );
// check
if( nTemplates > supported_maxTemplates )
{
log_error( LOG_WARNING, "NewCharacterSuccess: truncated templates count from %d to %d\n",
nTemplates, supported_maxTemplates );
nTemplates = supported_maxTemplates;
}
L2Game_NewCharacterTemplate char_templates[supported_maxTemplates];
memset( &char_templates, 0, sizeof(char_templates) );
for( i=0; i<nTemplates; i++ )
{
ncs->read_nextCharacterTemplate( &(char_templates[i]) );
//
log_error( LOG_DEBUG, "tmpl[%d]: race %d(%s), class %d(%s), %d,%d,%d,%d,%d,%d\n",
i,
char_templates[i].race, L2Data_getRace( char_templates[i].race ),
char_templates[i].classID, L2Data_getClass (char_templates[i].classID ),
char_templates[i].base_STR, char_templates[i].base_DEX, char_templates[i].base_CON,
char_templates[i].base_INT, char_templates[i].base_WIT, char_templates[i].base_MEN );
}
//
delete ncs;
ncs = NULL;
//
if( nTemplates > 0 )
{
CreateCharDialogResult res;
CreateCharDialog( pcls->hWnd, char_templates, nTemplates, &res );
if( res.createTemplateIndex < 0 )
{
// creation cancelled
log_error( LOG_DEBUG, "Char creation cancelled...\n" );
pcls->send_RequestGotoLobby();
return;
}
//
log_error( LOG_DEBUG, "Creating char [%S] tmpl index %d\n",
res.createCharName, res.createTemplateIndex );
// send CharacterCreate
pcls->send_CharacterCreate( res.createCharName,
&(char_templates[res.createTemplateIndex]),
res.createHairStyle, res.createHairColor, res.createFace, res.createGender );
// request char selection info
pcls->send_RequestGotoLobby();
}
}

View File

@@ -0,0 +1,30 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_NpcHtmlMessage( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int npcObjectID = p->readUInt(); // DO NOT TRUST THIS VALUE
const wchar_t *html = p->readUnicodeStringPtr(); // no malloc()
unsigned int itemID = p->readUInt();
// parse end
// get NPC info
L2Npc *pNpc = NULL;
WorldObjectTreeNode node;
if( pcls->world_tree.GetInfoByObjectID( npcObjectID, &node ) )
{
if( node.getObjectType() == L2OT_NPC )
{
int idx = node.getArrayIdx();
pNpc = pcls->world_npcs.npcs_array[idx];
}
}
// set copy of last NPC html to script engine to allow script to talk to NPCs
pcls->getInterface()->set_last_NPC_HTML( html, pcls->usr.targetObjectID );
// display UI dialog
pcls->npcHtmlDlg->displayNPCHTML( html, pNpc, itemID, 0 );
}

View File

@@ -0,0 +1,30 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_NpcInfo( class L2Client *pcls, L2GamePacket *p )
{
L2Npc npcInfo;
npcInfo.parse_NpcInfo( p, pcls->account.getL2Version() );
// set last time when chars coordinates were known exactly
//npcInfo.lastMoveTickTime = GetTickCount(); // done by parse()
// first try to find
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( npcInfo.objectID, &wotNode ) )
{
// already exists, update info
pcls->world_npcs.UpdateNpcInfo( wotNode.getArrayIdx(), &npcInfo );
}
else
{
// add new NPC
int idx = pcls->world_npcs.AddNpcInfo( &npcInfo );
wotNode.setNpc( &npcInfo );
wotNode.setArrayIdx( idx );
pcls->world_tree.AddObject( npcInfo.objectID, &wotNode );
}
if( npcInfo.isAttackable ) pcls->postUpdateUI( UPDATE_MAP_MOBS );
else pcls->postUpdateUI( UPDATE_MAP_NPCS );
}

View File

@@ -0,0 +1,10 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_PartyMemberPosition( class L2Client *pcls, L2GamePacket *p )
{
// TODO: ph_PartyMemberPosition
UNREFERENCED_PARAMETER(pcls);
UNREFERENCED_PARAMETER(p);
}

View File

@@ -0,0 +1,41 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x4f);
writeD(player.getObjectId()); // c3
writeD(0);//writeD(0x04); ?? //c3
writeD(_member.getObjectId());
writeS(_member.getName());
writeD((int) _member.getCurrentCp()); //c4
writeD(_member.getMaxCp()); //c4
writeD((int) _member.getCurrentHp());
writeD(_member.getMaxHp());
writeD((int) _member.getCurrentMp());
writeD(_member.getMaxMp());
writeD(_member.getLevel());
writeD(_member.getClassId().getId());
writeD(0);//writeD(0x01); ??
writeD(0); **/
void L2Client::ph_PartySmallWindowAdd( class L2Client *pcls, L2GamePacket *p )
{
L2Player pl;
p->getPacketType();
//
p->readUInt();
p->readUInt();
pl.objectID = p->readUInt();
pl.setName( p->readUnicodeStringPtr() );
pl.curCp = (double)p->readInt();
pl.maxCp = (double)p->readInt();
pl.curHp = (double)p->readInt();
pl.maxHp = (double)p->readInt();
pl.curMp = (double)p->readInt();
pl.maxMp = (double)p->readInt();
pl.level = p->readInt();
pl.classID = p->readUInt();
//
pcls->party.addPlayer( &pl );
pcls->postUpdateUI( UPDATE_PARTY );
}

View File

@@ -0,0 +1,78 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/*
6C 08 00 10 // party leader object id
00 00 00 00 // party loot type
01 00 00 00 // number of members (except you)
// for every member
6C 08 00 10 // member oobject id
41 00 65 00 72 00 69 00 6E 00 00 00 // member name
CD 06 00 00 // current cp
CD 06 00 00 // max cp
61 0D 00 00 // current hp
61 0D 00 00 // max hp
7B 0A 00 00 // current mp
7B 0A 00 00 // max mp
50 00 00 00 // level
1E 00 00 00 // class id
00 00 00 00 // constant 00 00 00 00
01 00 00 00 // race
00 00 00 00 // constant 00 00 00 00 */
void L2Client::ph_PartySmallWindowAll( class L2Client *pcls, L2GamePacket *p )
{
unsigned int leaderOid = 0;
unsigned int lootType = 0;
unsigned int nMembers = 0;
unsigned int i = 0;
L2Player pl;
//
pcls->party.clear();
//
p->getPacketType();
leaderOid = p->readUInt();
lootType = p->readUInt();
//
pcls->party.setLeaderObjectId( leaderOid );
pcls->party.setItemDistribution( lootType );
//
nMembers = p->readUInt();
for( i=0; i<nMembers; i++ )
{
pl.setUnused();
pl.objectID = p->readUInt();
pl.setName( p->readUnicodeStringPtr() );
pl.curCp = (double)p->readInt();
pl.maxCp = (double)p->readInt();
pl.curHp = (double)p->readInt();
pl.maxHp = (double)p->readInt();
pl.curMp = (double)p->readInt();
pl.maxMp = (double)p->readInt();
pl.level = p->readInt();
pl.classID = p->readInt();
p->readInt();
pl.race = p->readInt();
p->readInt(); // 0x00
// Gracia Final?
if( pcls->account.serverVersion == (int)L2_VERSION_T23 )
{
p->readInt(); // T2.3 0x00
// pet info
unsigned int petObjectID = p->readUInt(); // or 0x00, if no pet
if( petObjectID != 0 ) // must read pet info
{
p->readInt(); // pet npcId + 1000000
p->readUnicodeStringPtr(); // pet name
p->readInt(); // pet curHp
p->readInt(); // pet maxHp
p->readInt(); // pet curMp
p->readInt(); // pet maxMp
p->readInt(); // pet level
}
}
//
pcls->party.addPlayer( &pl );
}
pcls->postUpdateUI( UPDATE_PARTY );
}

View File

@@ -0,0 +1,16 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** writeC(0x51);
writeD(_member.getObjectId());
writeS(_member.getName()); **/
void L2Client::ph_PartySmallWindowDelete( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int oid = p->readUInt();
//const wchar_t *playerName = p->readUnicodeStringPtr();
pcls->party.delPlayer( oid );
//pcls->party.delPlayer( playerName );
pcls->postUpdateUI( UPDATE_PARTY );
}

View File

@@ -0,0 +1,13 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
// writeC(0x50);
void L2Client::ph_PartySmallWindowDeleteAll( class L2Client *pcls, L2GamePacket *p )
{
UNREFERENCED_PARAMETER(p);
// only trigger, no parse :)
pcls->party.deleteAll();
pcls->party.clear();
pcls->postUpdateUI( UPDATE_PARTY );
}

View File

@@ -0,0 +1,35 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x52);
writeD(_member.getObjectId());
writeS(_member.getName());
writeD((int) _member.getCurrentCp()); //c4
writeD(_member.getMaxCp()); //c4
writeD((int) _member.getCurrentHp());
writeD(_member.getMaxHp());
writeD((int) _member.getCurrentMp());
writeD(_member.getMaxMp());
writeD(_member.getLevel());
writeD(_member.getClassId().getId()); **/
void L2Client::ph_PartySmallWindowUpdate( class L2Client *pcls, L2GamePacket *p )
{
L2Player pl;
p->getPacketType();
//
pl.objectID = p->readUInt();
pl.setName( p->readUnicodeStringPtr() );
pl.curCp = (double)p->readInt();
pl.maxCp = (double)p->readInt();
pl.curHp = (double)p->readInt();
pl.maxHp = (double)p->readInt();
pl.curMp = (double)p->readInt();
pl.maxMp = (double)p->readInt();
pl.level = p->readInt();
pl.classID = p->readUInt();
//
pcls->party.updatePlayer( &pl );
pcls->postUpdateUI( UPDATE_PARTY );
}

View File

@@ -0,0 +1,20 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0xf4);
writeD(_activeChar instanceof L2SummonInstance ? 2 : _activeChar instanceof L2PetInstance ? 1 : 0);
writeD(_activeChar.getObjectId());
writeD(_effects.size());
for (Effect temp : _effects)
{
writeD(temp._skillId);
writeH(temp._dat);
writeD(temp._duration / 1000);
} **/
void L2Client::ph_PartySpelled( class L2Client *pcls, L2GamePacket *p )
{
pcls->party.parse_PartySpelled( p );
pcls->postUpdateUI( UPDATE_PARTY_BUFFSDURATION );
}

View File

@@ -0,0 +1,19 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x89);
writeD(_clan.getClanId());
writeS(_clan.getName());
writeS(_clan.getAllyName()); */
void L2Client::ph_PledgeInfo( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int clanID = p->readUInt();
const wchar_t *clanName = p->readUnicodeStringPtr();
const wchar_t *allyName = p->readUnicodeStringPtr();
pcls->world_clans.Add( clanID, clanName, allyName );
log_error( LOG_USERAI, "Clan info: [%S] ally [%S]\n", clanName, allyName );
pcls->postUpdateUI( UPDATE_MAP_PLAYERS );
}

View File

@@ -0,0 +1,109 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 81 [PrivateStoreListBuy]
51 00
BE
CE 09 00 10 // buyer oid
EA B0 0B 00 // cur.user adena
01 00 00 00 // sell items count
// for each item
C7 09 00 10 // item oid
F4 25 00 00 // item itemID
00 00 // enchant
02 00 00 00 // count
00 00 00 00 // reference price
00 00 // 00
00 00 00 00 // body part
05 00 // type2
01 00 00 00 // buyers price
02 00 00 00 // max buy amount
FE FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // attributes **/
void L2Client::ph_PrivateStoreListBuy( class L2Client *pcls, L2GamePacket *p )
{
L2_VERSION ver = pcls->account.getL2Version();
int i, cnt;
TradeItemsList *list = new TradeItemsList();
//
p->getPacketType();
list->listID = p->readUInt(); // save oid as listID
// cur user adena
if( ver < L2_VERSION_T23 ) list->curMoney = p->readInt();
else list->curMoney = p->readInt64();
cnt = p->readInt(); // count
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.objectID = p->readUInt();
it.itemID = p->readUInt();
it.enchantLevel = (int)p->readUShort();
if( ver < L2_VERSION_T23 )
{
it.count = p->readInt();
it.storePrice = p->readInt();
}
else
{
it.count = p->readInt64();
it.storePrice = p->readInt64();
}
p->readUShort();
p->readUInt(); // body part
it.type2 = (int)p->readUShort();
if( ver < L2_VERSION_T23 )
{
it.price = p->readInt();
it.count = p->readInt();
}
else
{
it.price = p->readInt64();
it.count = p->readInt64();
}
// attributes
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
// add to list
list->addItem( it );
//log_error_np( LOG_OK, "PrivateStoreListBuy: iid,oid(%u,%u) cnt,price(%d,%d)\n",
// it.itemID, it.objectID, it.count, it.price );
}
// find name
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( list->listID, &wotNode ) )
{
if( wotNode.getObjectType() == L2OT_PC )
wcscpy( list->message, pcls->world_chars.chars_array[wotNode.getArrayIdx()]->charName );
else log_error( LOG_ERROR, "PrivateStoreListBuy: buyer must be Player!\n" );
}
else log_error( LOG_ERROR, "WOT: cannot find objectID while PrivateStoreListBuy!\n" );
pcls->handle_PrivateStoreBuyList( list );
}

View File

@@ -0,0 +1,100 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 85 [PrivateStoreListSell]
55 00
A1
CE 09 00 10 // seller oid
00 00 00 00 // is package sale
EB B0 0B 00 // cur.user adena
01 00 00 00 // sell items count
/// for each item
05 00 00 00 // type2
D0 09 00 10 // item oid
F4 25 00 00 // item itemID
01 00 00 00 // item count
00 00 // 00
00 00 // enchant
00 00 // 00
00 00 00 00 // body part
01 00 00 00 // sell price
00 00 00 00 // reference price (original price)
FE FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // attribs **/
void L2Client::ph_PrivateStoreListSell( class L2Client *pcls, L2GamePacket *p )
{
L2_VERSION ver = pcls->account.getL2Version();
int i, cnt;
TradeItemsList *list = new TradeItemsList();
p->getPacketType();
list->listID = p->readUInt(); // save oid as listID
list->packageSale = p->readInt();
if( ver < L2_VERSION_T23 ) list->curMoney = p->readInt();
else list->curMoney = p->readInt64();
cnt = p->readInt();
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.type2 = p->readInt();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( ver < L2_VERSION_T23 ) it.count = p->readInt();
else it.count = p->readInt64();
p->readUShort();
it.enchantLevel = (int)p->readUShort();
p->readUShort();
p->readUInt(); // b. part
if( ver < L2_VERSION_T23 )
{
it.price = p->readInt();
it.storePrice = p->readInt();
}
else
{
it.price = p->readInt64();
it.storePrice = p->readInt64();
}
// attribs
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
// add
list->addItem( it );
}
// find name
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( list->listID, &wotNode ) )
{
if( wotNode.getObjectType() == L2OT_PC )
wcscpy( list->message, pcls->world_chars.chars_array[wotNode.getArrayIdx()]->charName );
else log_error( LOG_ERROR, "PrivateStoreListSell: seller must be Player!\n" );
}
else log_error( LOG_ERROR, "WOT: cannot find objectID while PrivateStoreListSell!\n" );
pcls->handle_PrivateStoreSellList( list );
}

View File

@@ -0,0 +1,129 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** 3 section to this packet
* 1)playerinfo which is always sent
* 2)list of items which can be added to buy
* 3)list of items which have already been setup */
void L2Client::ph_PrivateStoreManageListBuy( class L2Client *pcls, L2GamePacket *p )
{
//log_error( LOG_OK, "PrivateStoreManageListBuy\n" );
L2_VERSION ver = pcls->account.getL2Version();
p->getPacketType();
int cnt = 0;
int i = 0;
//
TradeItemsList *list1 = new TradeItemsList();
TradeItemsList *list2 = new TradeItemsList();
// section 1
p->readUInt(); // objectID
list1->packageSale = list2->packageSale = 0; // buylist cannot be package
// cur. money
if( ver < L2_VERSION_T23 ) list1->curMoney = p->readInt();
else list1->curMoney = p->readInt64();
// section 2
cnt = p->readInt();
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.itemID = p->readUInt();
it.enchantLevel = (int)p->readUShort();
if( ver < L2_VERSION_T23 )
{
it.count = p->readInt();
it.storePrice = p->readInt();
}
else
{
it.count = p->readInt64();
it.storePrice = p->readInt64();
}
p->readUShort();
p->readUInt(); // b.part
it.type2 = (int)p->readUShort();
// attributes
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
list1->addItem( it );
}
// section 3
cnt = p->readInt();
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.itemID = p->readUInt();
it.enchantLevel = (int)p->readUShort();
if( ver < L2_VERSION_T23 )
{
it.count = p->readInt();
it.storePrice = p->readInt();
}
else
{
it.count = p->readInt64();
it.storePrice = p->readInt64();
}
p->readUShort();
p->readUInt(); // b.part
it.type2 = (int)p->readUShort();
if( ver < L2_VERSION_T23 )
{
it.price = p->readInt();
it.storePrice = p->readInt();
}
else
{
it.price = p->readInt64();
it.storePrice = p->readInt64();
}
// attributes
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
list2->addItem( it );
}
pcls->handle_PrivateStoreManageListBuy( list1, list2 );
}

View File

@@ -0,0 +1,124 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** 3 section to this packet
* 1)playerinfo which is always sent
* 2)list of items which can be added to sell
* 3)list of items which have already been setup */
void L2Client::ph_PrivateStoreManageListSell( class L2Client *pcls, L2GamePacket *p )
{
//log_error( LOG_DEBUG, "PrivateStoreManageListSell\n" );
L2_VERSION ver = pcls->account.getL2Version();
p->getPacketType();
int cnt;
int i;
//
TradeItemsList *list1 = new TradeItemsList();
TradeItemsList *list2 = new TradeItemsList();
// section 1
p->readUInt(); // objectID
list1->packageSale = list2->packageSale = p->readUInt(); // is package sale
// cur money
if( ver < L2_VERSION_T23 ) list1->curMoney = p->readInt();
else list1->curMoney = p->readInt64();
// section 2
cnt = p->readInt();
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.type2 = p->readUInt();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( ver < L2_VERSION_T23 ) it.count = p->readInt();
else it.count = p->readInt64();
p->readUShort();
it.enchantLevel = (int)p->readUShort();
p->readUShort();
p->readUInt(); // body part
if( ver < L2_VERSION_T23 ) it.storePrice = p->readInt();
else it.storePrice = p->readInt();
it.price = 0;
// attributes
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
//
list1->addItem( it );
}
// section 3
cnt = p->readInt();
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.type2 = p->readUInt();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( ver < L2_VERSION_T23 ) it.count = p->readInt();
else it.count = p->readInt64();
p->readUShort();
it.enchantLevel = (int)p->readUShort();
p->readUShort();
p->readUInt(); // body part
if( ver < L2_VERSION_T23 )
{
it.price = p->readInt();
it.storePrice = p->readInt();
}
else
{
it.price = p->readInt64();
it.storePrice = p->readInt64();
}
// attributes
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
//
list2->addItem( it );
}
//
pcls->handle_PrivateStoreManageListSell( list1, list2 );
}

View File

@@ -0,0 +1,32 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_PrivateStoreMsgBuy( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType(); // 0xBF
unsigned int oid = p->readUInt();
const wchar_t *msg = p->readUnicodeStringPtr();
// is it user?
if( oid == pcls->usr.objectID )
{
memset( pcls->usr.privateStoreMsgBuy, 0, 128 );
wcsncpy( pcls->usr.privateStoreMsgBuy, msg, 63 );
pcls->usr.privateStoreMsgBuy[63] = 0;
return;
}
// try to find oid in world tree, must be player
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( oid, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
if( wotNode.getObjectType() == L2OT_PC && idx > 0 )
{
memset( pcls->world_chars.chars_array[idx]->privateStoreMsgBuy, 0, 128 );
wcsncpy( pcls->world_chars.chars_array[idx]->privateStoreMsgBuy, msg, 63 );
pcls->world_chars.chars_array[idx]->privateStoreMsgBuy[63] = 0;
}
else log_error( LOG_ERROR, "PrivateStoreMsgBuy: oid is not player!\n" );
}
else log_error( LOG_ERROR, "PrivateStoreMsgBuy: cannot find objectID!\n" );
}

View File

@@ -0,0 +1,32 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_PrivateStoreMsgSell( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType(); // 0xA2
unsigned int oid = p->readUInt();
const wchar_t *msg = p->readUnicodeStringPtr();
// is it user?
if( oid == pcls->usr.objectID )
{
memset( pcls->usr.privateStoreMsgSell, 0, 128 );
wcsncpy( pcls->usr.privateStoreMsgSell, msg, 63 );
pcls->usr.privateStoreMsgSell[63] = 0;
return;
}
// try to find oid in world tree, must be player
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( oid, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
if( wotNode.getObjectType() == L2OT_PC && idx > 0 )
{
memset( pcls->world_chars.chars_array[idx]->privateStoreMsgSell, 0, 128 );
wcsncpy( pcls->world_chars.chars_array[idx]->privateStoreMsgSell, msg, 63 );
pcls->world_chars.chars_array[idx]->privateStoreMsgSell[63] = 0;
}
else log_error( LOG_ERROR, "PrivateStoreMsgSell: oid is not player!\n" );
}
else log_error( LOG_ERROR, "PrivateStoreMsgSell: cannot find objectID!\n" );
}

View File

@@ -0,0 +1,41 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_RecipeShopManageList( class L2Client *pcls, L2GamePacket *p )
{
L2_VERSION ver = pcls->account.getL2Version();
p->getPacketType();
int cnt;
int i;
//
TradeItemsList *list1 = new TradeItemsList();
TradeItemsList *list2 = new TradeItemsList();
// section 1
p->readUInt(); // objectID
list1->curMoney = p->readInt();
list1->packageSale = list2->packageSale = 0; // craft cannot be package
list1->isCommonCraft = list2->isCommonCraft = p->readUInt();
// section 2
cnt = p->readInt();
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.itemID = p->readUInt(); // recipe ID here
p->readInt(); // pass seq.number
list1->addItem( it );
}
// section 3
cnt = p->readInt();
for( i=0; i<cnt; i++ )
{
TradeItem it;
it.itemID = p->readInt();
p->readInt(); // pass 0x00
if( ver < L2_VERSION_T23 ) it.price = p->readInt();
else it.price = p->readInt64();
list2->addItem( it );
}
pcls->handle_RecipeShopManageList( list1, list2 );
}

View File

@@ -0,0 +1,32 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_RecipeShopMsg( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType(); // 0xE1
unsigned int oid = p->readUInt();
const wchar_t *msg = p->readUnicodeStringPtr();
// is it user?
if( oid == pcls->usr.objectID )
{
memset( pcls->usr.privateStoreMsgRecipe, 0, 128 );
wcsncpy( pcls->usr.privateStoreMsgRecipe, msg, 63 );
pcls->usr.privateStoreMsgRecipe[63] = 0;
return;
}
// try to find oid in world tree, must be player
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( oid, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
if( wotNode.getObjectType() == L2OT_PC )
{
memset( pcls->world_chars.chars_array[idx]->privateStoreMsgRecipe, 0, 128 );
wcsncpy( pcls->world_chars.chars_array[idx]->privateStoreMsgRecipe, msg, 63 );
pcls->world_chars.chars_array[idx]->privateStoreMsgRecipe[63] = 0;
}
else log_error( LOG_ERROR, "RecipeShopMsg: oid is not player!\n" );
}
else log_error( LOG_ERROR, "RecipeShopMsg: cannot find objectID!\n" );
}

View File

@@ -0,0 +1,48 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 7 [Revive]
07 00
01
3F 8E 05 10 // objectID? ***/
void L2Client::ph_Revive( class L2Client *pcls, L2GamePacket *p )
{
int party_idx = 0;
p->getPacketType();
unsigned int objectID = p->readUInt();
if( objectID == pcls->usr.objectID )
{
// user is revived!
log_error( LOG_USERAI, "User is Revived!\n" );
pcls->addChatToTab( CHAT_DMG, L"You are revived!" );
pcls->usr.isDead = 0;
pcls->usr.canResurrectToVillage = pcls->usr.canResurrectToCH = pcls->usr.canResurrectToCastle =
pcls->usr.canResurrectToFortress = pcls->usr.canResurrectToSiegeHQ = pcls->usr.canResurrectFixed = 0;
}
else if( pcls->party.isInParty( objectID, &party_idx ) )
{
L2Player *partyMember = pcls->party.getPartyPlayer( party_idx );
partyMember->isAlikeDead = 0;
wchar_t wmes[128] = {0};
swprintf( wmes, 127, L"Party player [%s] revived", partyMember->charName );
pcls->addChatToTab( CHAT_DMG, wmes );
}
// someone in the world revived
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->isAlikeDead = 0;
wchar_t wmes[128] = {0};
swprintf( wmes, 127, L"Character [%s] revived", pcls->world_chars.chars_array[idx]->charName );
pcls->addChatToTab( CHAT_DMG, wmes );
} break;
}
}
}

View File

@@ -0,0 +1,18 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_SSQInfo( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned short sky = p->readUShort();
switch( sky )
{
case L2Game_SSQInfo::SSQ_DAWN_SKY:
pcls->addChatToTab( CHAT_SYS, L"SevenSigns: Dawn moon in the sky." ); break;
case L2Game_SSQInfo::SSQ_DUSK_SKY:
pcls->addChatToTab( CHAT_SYS, L"SevenSigns: Dusk moon in the sky." ); break;
case L2Game_SSQInfo::SSQ_NORMAL_SKY:
pcls->addChatToTab( CHAT_SYS, L"SevenSigns: Normal moon in the sky." ); break;
}
}

View File

@@ -0,0 +1,102 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/*** Server: Len 1357 [SellList]
4D 05
06
6F A5 34 00 // cur money
00 00 00 00 // list id?
15 00 // items count
[ for each item ]
04 00 // type1
C4 40 07 10 // objectID
E0 02 00 00 // itemID
0B 00 00 00 // count
05 00 // type2
00 00 // ??
00 00 00 00 // body part
00 00 // enchant level
00 00 00 00 // ??
C8 00 00 00 // sell price
FE FF FF FF // atk attrib type
00 00 00 00 // atk attrib val
00 00 00 00 // def attr fire
00 00 00 00 // -- water
00 00 00 00 // -- wind
00 00 00 00 // -- earth
00 00 00 00 // -- holy
00 00 00 00 // -- unholy **/
void L2Client::ph_SellList( L2Client *pcls, L2GamePacket *p )
{
L2_VERSION ver = pcls->account.getL2Version();
p->getPacketType();
long long int curMoney = 0;
if( ver < L2_VERSION_T23 ) curMoney = p->readInt();
else curMoney = p->readInt64();
unsigned int listID = p->readUInt();
int cnt = (int)p->readUShort();
if( cnt <= 0 ) return;
TradeItem it;
TradeItemsList *list = new TradeItemsList();
list->curMoney = curMoney;
list->itemCount = 0;
list->listID = listID;
int i = 0;
for( i=0; i<cnt; i++ )
{
it.setUnused();
it.type1 = (int)p->readUShort(); // type1
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( ver < L2_VERSION_T23 ) it.count = p->readD();
else it.count = p->readQ();
it.type2 = (int)p->readUShort(); // type2
p->readUShort(); // ??
p->readUInt(); // bodypart
it.enchantLevel = (int)p->readUShort();
p->readUInt(); // ??
if( ver < L2_VERSION_T23 ) it.price = p->readD();
else it.price = p->readQ();
// read 8 attributes
if( ver < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
//
list->addItem( it );
}
if( list->itemCount != cnt )
{
log_error( LOG_ERROR, "SellList handler error!\n" );
delete list;
list = NULL;
return;
}
pcls->handle_SellList( list );
}

View File

@@ -0,0 +1,32 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Trade receiver recieves:
Server: Len 7 [SendTradeRequest]
07 00
70 // pcode
CE 09 00 10 // object ID of person who wants to trade to you **/
void L2Client::ph_SendTradeRequest( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
// get requester name
WorldObjectTreeNode wotNode;
if( !pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
log_error( LOG_ERROR, "SendTradeRequest: trade requester [%u] not found in knownlist!\n", objectID );
return;
}
// create question string
TCHAR szQuestion[256] = {0};
wsprintf( szQuestion, TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %s <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?"),
pcls->world_chars.chars_array[wotNode.getArrayIdx()]->charName );
// create MessageBoxTimeout dialog (15 seconds)
MessageBoxTimeout *mb = new MessageBoxTimeout( pcls->hWnd, WMMY_UI_MESSAGEBOXTIMEOUTREPLY,
MessageBoxTimeout::TYPE_TRADEREQUEST, szQuestion, 15 );
mb->run( pcls->usr.charName );
}

View File

@@ -0,0 +1,29 @@
#include "stdafx.h"
#include "../Logger.h"
#include "../L2Client.h"
/** Server: Len 15 [SetupGauge]
0F 00
6B
00 00 00 00 // color 0-blue 1-red 2-cyan 3-
57 07 00 00 // skill cast time 1879, ms
57 07 00 00 **/
void L2Client::ph_SetupGauge( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int color = p->readInt(); // color
unsigned int time = p->readUInt();
//log_error( LOG_OK, "startCasting( %u )\n", time );
switch( color )
{
case 0: pcls->skills.startCasting( time ); break; // skill cast
// case 1: // arrow shoot?
case 2: // under water breathe
{
if( time == 0 )
log_error( LOG_USERAI, "Not sinking!" );
else
log_error( LOG_USERAI, "Sinking under water!" );
} break;
}
}

View File

@@ -0,0 +1,10 @@
#include "stdafx.h"
#include "../Logger.h"
#include "../L2Client.h"
void L2Client::ph_ShortBuffStatusUpdate( class L2Client *pcls, L2GamePacket *p )
{
//pcls->log_packet( true, packbuffer, plen );
pcls->buffs.parse_ShortBuffStatusUpdate( p );
pcls->postUpdateUI( UPDATE_BUFFS );
}

View File

@@ -0,0 +1,9 @@
#include "stdafx.h"
#include "../Logger.h"
#include "../L2Client.h"
void L2Client::ph_SkillCoolTime( class L2Client *pcls, L2GamePacket *p )
{
pcls->skills.parse_SkillCoolTime( p );
pcls->postUpdateUI( UPDATE_SKILLS );
}

View File

@@ -0,0 +1,14 @@
#include "stdafx.h"
#include "../Logger.h"
#include "../L2Client.h"
void L2Client::ph_SkillList( class L2Client *pcls, L2GamePacket *p )
{
pcls->skills.parse_SkillList( p, pcls->account.getL2Version() );
pcls->postUpdateUI( UPDATE_SKILLS );
// send RequestSkillCoolTime
L2GamePacket *pack = new L2GamePacket;
pack->setPacketType( 0xA6 ); // RequestSkillCoolTIme
pcls->sendPacket( pack, true );
delete pack; pack = NULL;
}

View File

@@ -0,0 +1,42 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x05);
writeD(_objectId);
writeD(_itemId);
writeD(_x);
writeD(_y);
writeD(_z);
// only show item count if it is a stackable item
writeD(_stackable);
writeD(_count);
writeD(0x00); //c2 */
void L2Client::ph_SpawnItem( class L2Client *pcls, L2GamePacket *p )
{
L2_VERSION ver = pcls->account.getL2Version();
GroundItem it;
p->getPacketType();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
it.x = p->readInt();
it.y = p->readInt();
it.z = p->readInt();
it.stackable = p->readUInt();
if( ver < L2_VERSION_T23 ) it.count = p->readD();
else it.count = p->readQ();
//log_error( LOG_USERAI, "SpawnItem %s [%u] at (%d,%d,%d)\n", it.itemName, it.itemID, it.x, it.y, it.z );
// add item to ground items
int idx = pcls->world_ground_items.AddGIInfo( &it );
// add item to world object tree
WorldObjectTreeNode wotNode;
wotNode.setArrayIdx( idx );
wotNode.setGroundItem( &it );
pcls->world_tree.AddObject( it.objectID, &wotNode );
pcls->postUpdateUI( UPDATE_MAP_ITEMS );
}

View File

@@ -0,0 +1,111 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**writeC(0x18);
writeD(_objectId);
writeD(_attributes.size());
for (Attribute temp: _attributes)
{
writeD(temp.id);
writeD(temp.value);
}**/
void L2Client::ph_StatusUpdate( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
//
const unsigned int LEVEL = 0x01;
const unsigned int EXP = 0x02;
const unsigned int STR = 0x03;
const unsigned int DEX = 0x04;
const unsigned int CON = 0x05;
const unsigned int INT = 0x06;
const unsigned int WIT = 0x07;
const unsigned int MEN = 0x08;
const unsigned int CUR_HP = 0x09;
const unsigned int MAX_HP = 0x0a;
const unsigned int CUR_MP = 0x0b;
const unsigned int MAX_MP = 0x0c;
const unsigned int SP = 0x0d;
const unsigned int CUR_LOAD = 0x0e;
const unsigned int MAX_LOAD = 0x0f;
const unsigned int P_ATK = 0x11;
const unsigned int ATK_SPD = 0x12;
const unsigned int P_DEF = 0x13;
const unsigned int EVASION = 0x14;
const unsigned int ACCURACY = 0x15;
const unsigned int CRITICAL = 0x16;
const unsigned int M_ATK = 0x17;
const unsigned int CAST_SPD = 0x18;
const unsigned int M_DEF = 0x19;
const unsigned int PVP_FLAG = 0x1a;
const unsigned int KARMA = 0x1b;
const unsigned int CUR_CP = 0x21;
const unsigned int MAX_CP = 0x22;
//
unsigned int objectID = p->readUInt();
unsigned int nAttributesUpdated = p->readUInt();
unsigned int i;
//
if( objectID == pcls->usr.objectID ) // update user stats
{
for( i=0; i<nAttributesUpdated; i++ )
{
unsigned int attrib = p->readUInt();
int attribVal = p->readInt();
switch( attrib )
{
case CUR_HP: pcls->usr.curHp = (double)attribVal; break;
case MAX_HP: pcls->usr.maxHp = (double)attribVal; break;
case CUR_MP: pcls->usr.curMp = (double)attribVal; break;
case MAX_MP: pcls->usr.maxMp = (double)attribVal; break;
case CUR_CP: pcls->usr.curCp = (double)attribVal; break;
case MAX_CP: pcls->usr.maxCp = (double)attribVal; break;
case CUR_LOAD: pcls->usr.curLoad = attribVal; break;
case MAX_LOAD: pcls->usr.maxLoad = attribVal; break;
case LEVEL: pcls->usr.level = attribVal; break;
case EXP: pcls->usr.experience = attribVal; break;
case SP: pcls->usr.skill_points = attribVal; break;
case STR: pcls->usr.s_STR = attribVal; break;
case DEX: pcls->usr.s_DEX = attribVal; break;
case CON: pcls->usr.s_CON = attribVal; break;
case INT: pcls->usr.s_INT = attribVal; break;
case WIT: pcls->usr.s_WIT = attribVal; break;
case MEN: pcls->usr.s_MEN = attribVal; break;
//
case P_ATK: pcls->usr.pAtk = attribVal; break;
case ATK_SPD: pcls->usr.pAtkSpd = attribVal; break;
case P_DEF: pcls->usr.pDef = attribVal; break;
case EVASION: pcls->usr.evasion = attribVal; break;
case ACCURACY: pcls->usr.accuracy = attribVal; break;
case CRITICAL: pcls->usr.critical = attribVal; break;
case M_ATK: pcls->usr.mAtk = attribVal; break;
case CAST_SPD: pcls->usr.mAtkSpd = attribVal; break;
case M_DEF: pcls->usr.mDef = attribVal; break;
case PVP_FLAG: pcls->usr.pvpFlag = attribVal; break;
case KARMA: pcls->usr.karma = attribVal; break;
}
}
pcls->postUpdateUI( UPDATE_USER );
}
else if( objectID == pcls->usr.targetObjectID ) // update target's stats
{
// for target only support update curHp/maxHp
for( i=0; i<nAttributesUpdated; i++ )
{
unsigned int attrib = p->readUInt();
int attribVal = p->readInt();
switch( attrib )
{
case CUR_HP: pcls->usr.targetCurHp = (double)attribVal; break;
case MAX_HP: pcls->usr.targetMaxHp = (double)attribVal; break;
}
}
pcls->postUpdateUI( UPDATE_USER_TARGET );
}
}

View File

@@ -0,0 +1,62 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 23 [StopMove]
17 00
47 // StopMove
6C 08 00 10 // objectID of char who stopped
9A AC 00 00 // x
F9 A4 00 00 // y
5D F2 FF FF // z
45 B9 00 00 // heading **/
void L2Client::ph_StopMove( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
int x = p->readInt();
int y = p->readInt();
int z = p->readInt();
//
if( pcls->usr.objectID == objectID )
{
pcls->usr.x = x;
pcls->usr.y = y;
pcls->usr.z = z;
pcls->usr.lastMoveTickTime = GetTickCount();
pcls->usr.stopMove();
}
else
{
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->x = x;
pcls->world_chars.chars_array[idx]->y = y;
pcls->world_chars.chars_array[idx]->z = z;
pcls->world_chars.chars_array[idx]->stopMove();
pcls->world_chars.chars_array[idx]->lastMoveTickTime = GetTickCount();
} break;
case L2OT_NPC:
{
//
pcls->world_npcs.npcs_array[idx]->x = x;
pcls->world_npcs.npcs_array[idx]->y = y;
pcls->world_npcs.npcs_array[idx]->z = z;
pcls->world_npcs.npcs_array[idx]->stopMove();
pcls->world_npcs.npcs_array[idx]->lastMoveTickTime = GetTickCount();
} break;
}
}
else
{
log_error( LOG_ERROR, "WOT cannot find objectID while StopMove\n" );
pcls->addChatToTab( CHAT_DMG, L"WARN: possible invisible GM nearby!" );
}
}
}

View File

@@ -0,0 +1,17 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
#include "utils.h"
void L2Client::ph_SystemMessage( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
//unsigned int sm_ID = p->readUInt();
//unsigned int paramCount = p->readUInt();
wchar_t *sm = (wchar_t *)malloc( 20480 );
if( !sm ) return;
memset( sm, 0, 20480 );
Utils_process_SystemMessage( p, sm );
pcls->addChatToTab( CHAT_SYS, sm );
free( sm ); sm = NULL;
}

View File

@@ -0,0 +1,72 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x23);
writeD(_objectId);
writeD(_targetObjId);
writeD(_x);
writeD(_y);
writeD(_z);
writeD(0x00); **/
void L2Client::ph_TargetSelected( class L2Client *pcls, L2GamePacket *p )
{
int party_idx = 0;
p->getPacketType();
unsigned int oid = p->readUInt();
unsigned int toid = p->readUInt();
/*int x = */p->readInt();
/*int y = */p->readInt();
/*int z = */p->readInt();
//
if( oid == pcls->usr.objectID )
{
pcls->usr.targetObjectID = toid;
//log_error( LOG_OK, "User TargetSelected\n" );
wchar_t wmes[32] = {0};
swprintf( wmes, 31, L"You target %u", toid );
pcls->addChatToTab( CHAT_DMG, wmes );
pcls->postUpdateUI( UPDATE_USER_TARGET );
}
else if( pcls->party.isInParty( oid, &party_idx ) )
{
//L2Player *partyMember = pcls->party.getPartyPlayer( party_idx );
//log_error( LOG_OK, "Party member [%S] target to %u\n", partyMember->charName, toid );
pcls->party.setPlayerTarget( oid, toid );
//wchar_t wmes[64] = {0};
//swprintf( wmes, 63, L"Party member [%s] changed target to %u", partyMember->charName, toid );
//pcls->addChatToTab( CHAT_DMG, wmes );
}
// update target in the world alse
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( oid, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->targetObjectID = toid;
//wchar_t wmes[256] = {0};
//swprintf( wmes, 255, L"Character [%s] selected target %u", pcls->world_chars.chars_array[idx]->charName, toid );
//pcls->addChatToTab( CHAT_DMG, wmes );
if( toid == pcls->usr.objectID )
{
//log_error( LOG_USERAI, "You are targeted by [%S]\n", pcls->world_chars.chars_array[idx]->charName );
wchar_t wmessage[256] = {0};
swprintf( wmessage, 255, L"You are targeted by [%s]", pcls->world_chars.chars_array[idx]->charName );
pcls->addChatToTab( CHAT_DMG, wmessage, NULL );
}
else if( pcls->party.isInParty( toid, &party_idx ) )
{
L2Player *partyMember = pcls->party.getPartyPlayer( party_idx );
wchar_t wmes[64] = {0};
swprintf( wmes, 63, L"Party member [%s] is on target of [%s]",
partyMember->charName, pcls->world_chars.chars_array[idx]->charName );
pcls->addChatToTab( CHAT_DMG, wmes );
}
} break;
}
}
}

View File

@@ -0,0 +1,55 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/**
writeC(0x24);
writeD(_targetObjId);
writeD(_x);
writeD(_y);
writeD(_z);
writeD(0x00); **/
void L2Client::ph_TargetUnselected( class L2Client *pcls, L2GamePacket *p )
{
int party_idx = 0;
p->getPacketType();
unsigned int oid = p->readUInt();
/*int x = */p->readInt();
/*int y = */p->readInt();
/*int z = */p->readInt();
//
if( oid == pcls->usr.objectID ) // update self target
{
pcls->usr.targetObjectID = 0;
pcls->usr.targetCurHp = 0.0;
pcls->usr.targetMaxHp = 0.0;
//log_error( LOG_OK, "User TargetUnselected\n" );
pcls->addChatToTab( CHAT_DMG, L"You unselect target" );
pcls->postUpdateUI( UPDATE_USER_TARGET );
}
else if( pcls->party.isInParty( oid, &party_idx ) ) // update target in party
{
//L2Player *partyMember = pcls->party.getPartyPlayer( party_idx );
pcls->party.setPlayerTarget( oid, 0 );
//log_error( LOG_OK, "Party member [%S] cancelled target\n", partyMember->charName );
//wchar_t wmes[256] = {0};
//swprintf( wmes, 255, L"Party member [%s] unselected target", partyMember->charName );
//pcls->addChatToTab( CHAT_DMG, wmes );
}
// someone in the world cancelled target, update target of object in the world
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( oid, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->targetObjectID = 0;
//wchar_t wmes[256] = {0};
//swprintf( wmes, 255, L"Character [%s] unselected target", pcls->world_chars.chars_array[idx]->charName );
//pcls->addChatToTab( CHAT_DMG, wmes );
} break;
}
}
}

View File

@@ -0,0 +1,71 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 19 [TeleportToLocation]
13 00
22
6D 08 00 10 // oid 268437613
3F 1D 01 00 // x 73023
DC CE 01 00 // y 118492
9D F1 FF FF // z -3683 **/
void L2Client::ph_TeleportToLocation( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
int x = p->readInt();
int y = p->readInt();
int z = p->readInt();
if( objectID == pcls->usr.objectID )
{
pcls->usr.stopMove();
pcls->skills.stopCasting();
//
// TODO: force clear all known PC/NPC/Items?
//
pcls->usr.x = x;
pcls->usr.y = y;
pcls->usr.z = z;
// update UI
pcls->addChatToTabFormat( CHAT_DMG, L"You teleport to (%d,%d,%d)", x, y, z );
// reply with ValidatePosition
pcls->send_ValidatePosition();
// send Appearing
pcls->send_Appearing();
return;
}
// some other object in the world teleported nearby? O_o
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->x = x;
pcls->world_chars.chars_array[idx]->y = y;
pcls->world_chars.chars_array[idx]->z = z;
pcls->world_chars.chars_array[idx]->lastMoveTickTime = GetTickCount();
// party member?
int party_idx = 0;
if( pcls->party.isInParty( objectID, &party_idx ) )
{
L2Player *member = pcls->party.getPartyPlayer( party_idx );
member->setXYZ( x, y, z );
}
} break;
case L2OT_NPC:
{
pcls->world_npcs.npcs_array[idx]->x = x;
pcls->world_npcs.npcs_array[idx]->y = y;
pcls->world_npcs.npcs_array[idx]->z = z;
pcls->world_npcs.npcs_array[idx]->lastMoveTickTime = GetTickCount();
} break;
}
}
else
{
log_error( LOG_WARNING, "TeleportToLocation cannot find objID [%u]\n", objectID );
}
}

View File

@@ -0,0 +1,23 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 7 [TradeDone]
07 00
1C // pcode
01 00 00 00 // confirmed ? 0x01 : 0x00 **/
void L2Client::ph_TradeDone( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
int num = p->readInt();
log_error( LOG_DEBUG, "TradeDone: %d\n", num );
if( num )
{
pcls->addChatToTabFormat( CHAT_SYS, L"Player %s confirmed trade.", pcls->tradep2pdlg->getPartnerName() );
}
else
{
pcls->addChatToTabFormat( CHAT_SYS, L"Player %s cancelled trade.", pcls->tradep2pdlg->getPartnerName() );
}
pcls->tradep2pdlg->tradeDone();
}

View File

@@ -0,0 +1,72 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 65 [TradeOtherAdd]
41 00
1B // pcode
01 00 // item cnt (always 1 on l2j)
04 00 // type1
C0 09 00 10 // oid
39 00 00 00 // iid
0D 00 00 00 // cnt
04 00 // type2
00 00 // 00
00 00 00 00 // b.part
00 00 // enchatnt
00 00 00 00 // 00 ??
FE FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // attribs **/
void L2Client::ph_TradeOtherAdd( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
int it_cnt = p->readH();
if( it_cnt != 1 )
{
log_error( LOG_ERROR, "TradeOtherAdd: items count != 1, some protocol error?\n" );
pcls->addChatToTab( CHAT_SYS, L"TradeOtherAdd: items count != 1, some protocol error?" );
return;
}
//
TradeItem it;
//
it.type1 = p->readH();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( pcls->getL2Version() < L2_VERSION_T23 )
it.count = p->readD(); // <= T2.2
else it.count = p->readQ(); // >= T2.3
it.type2 = p->readH();
/* 0x00 */ p->readH();
it.bodyPart = p->readD();
it.enchantLevel = p->readH();
/* 0x00 */ p->readD();
// attributes
if( pcls->getL2Version() < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
// process
pcls->tradep2pdlg->tradeOtherAdd( it );
}

View File

@@ -0,0 +1,72 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 65 [TradeOwnAdd]
41 00
1A // pcode
01 00 // count (always 1 on l2j)
04 00 // type1
D1 09 00 10 // oid
9A 29 00 00 // iid
01 00 00 00 // cnt
05 00 // type2
00 00 // 00
00 00 00 00 // b.part
00 00 // enchant
00 00 00 00 // 00
FE FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // attribs **/
void L2Client::ph_TradeOwnAdd( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
int it_cnt = p->readH();
if( it_cnt != 1 )
{
log_error( LOG_ERROR, "TradeOwnAdd: items count != 1, some protocol error?\n" );
pcls->addChatToTab( CHAT_SYS, L"TradeOwnAdd: items count != 1, some protocol error?" );
return;
}
//
TradeItem it;
//
it.type1 = p->readH();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( pcls->getL2Version() < L2_VERSION_T23 )
it.count = p->readD(); // <= T2.2
else it.count = p->readQ(); // >= T2.3
it.type2 = p->readH();
/* 0x00 */ p->readH();
it.bodyPart = p->readD();
it.enchantLevel = p->readH();
/* 0x00 */ p->readD();
// attributes
if( pcls->getL2Version() < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
// process
pcls->tradep2pdlg->tradeOwnAdd( it );
}

View File

@@ -0,0 +1,105 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/*
// then both (requester and receiver) receive
Server: Len 189 [TradeStart]
BD 00
14 // pcode
C5 09 00 10 // partner objectID
03 00 // items count (your inv)
/// for each item
04 00 // item type1
CF 09 00 10 // item oid
D4 15 00 00 // item iid
01 00 00 00 // item count
05 00 // item type2
00 00 // 00
00 00 00 00 // body part
00 00 // enchant
00 00 00 00 // 0000
FE FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // attribs
*/
void L2Client::ph_TradeStart( class L2Client *pcls, L2GamePacket *p )
{
unsigned char opcode = p->getPacketType();
if( opcode != 0x14 ) return;
int i = 0;
unsigned int partnerOID = p->readUInt();
int itemsCount = p->readH();
// check trade partner name
wchar_t partnerName[256] = {0};
WorldObjectTreeNode wotNode;
if( !pcls->world_tree.GetInfoByObjectID( partnerOID, &wotNode ) )
{
log_error( LOG_ERROR, "TradeStart: unknown name for player [%u]\n", partnerOID );
return;
}
if( !pcls->world_chars.chars_array[wotNode.getArrayIdx()] )
{
log_error( LOG_ERROR, "TradeStart: chars_array[%d] is NULL!\n", wotNode.getArrayIdx() );
return;
}
wcscpy( partnerName, pcls->world_chars.chars_array[wotNode.getArrayIdx()]->charName );
// create trade list
TradeItemsList *list = new TradeItemsList();
list->listID = partnerOID; // save partner OID as listID
// parse each item for our tradeable inventory
for( i=0; i<itemsCount; i++ )
{
TradeItem it;
//
it.type1 = p->readH();
it.objectID = p->readUInt();
it.itemID = p->readUInt();
if( pcls->getL2Version() < L2_VERSION_T23 )
it.count = p->readD(); // <= T2.2
else it.count = p->readQ(); // >= T2.3
it.type2 = p->readH();
/* 0x00 */ p->readH();
it.bodyPart = p->readD();
it.enchantLevel = p->readH();
/* 0x00 */ p->readD();
// attributes
if( pcls->getL2Version() < L2_VERSION_T23 )
{
it.attributeAtkType = p->readD();
it.attributeAtkValue = p->readD();
it.attributeDefFire = p->readD();
it.attributeDefWater = p->readD();
it.attributeDefWind = p->readD();
it.attributeDefEarth = p->readD();
it.attributeDefHoly = p->readD();
it.attributeDefUnholy = p->readD();
}
else
{
it.attributeAtkType = p->readH();
it.attributeAtkValue = p->readH();
it.attributeDefFire = p->readH();
it.attributeDefWater = p->readH();
it.attributeDefWind = p->readH();
it.attributeDefEarth = p->readH();
it.attributeDefHoly = p->readH();
it.attributeDefUnholy = p->readH();
}
// add item to list
list->addItem( it );
}
pcls->tradep2pdlg->tradeStart( list, partnerName );
// we can safely delete list now - list is copied to internal by tradep2pdlg
delete list;
list = NULL;
}

View File

@@ -0,0 +1,36 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
void L2Client::ph_UserInfo( class L2Client *pcls, L2GamePacket *p )
{
pcls->usr.parse_UserInfo( p, pcls->account.getL2Version() );
pcls->postUpdateUI( UPDATE_USER );
// bot IPC
// test if we registered in bot IPC, register or update info
if( pcls->botipc_index == -1 )
{
BotIPC *ipc = BotIPC::getInstance();
BOT_INFO binfo;
BotInfo_Initialize( &binfo, pcls->usr.charName, pcls->usr.objectID,
pcls->usr.classID, pcls->usr.level );
pcls->botipc_index = ipc->addBotInfo( &binfo );
if( pcls->botipc_index == -1 )
{
log_error( LOG_ERROR, "ph_UserInfo(): failed to register in Bot IPC!\n" );
}
else
{
log_error( LOG_DEBUG, "Registered in Bot IPC at index %d.\n", pcls->botipc_index );
}
}
else // already registered in BotIPC, should update
{
BotIPC *ipc = BotIPC::getInstance();
BOT_INFO binfo;
BotInfo_Initialize( &binfo, pcls->usr.charName, pcls->usr.objectID,
pcls->usr.classID, pcls->usr.level );
if( !ipc->setBotInfo( pcls->botipc_index, &binfo ) )
log_error( LOG_ERROR, "ph_UserInfo(): failed to update self in BotIPC!\n" );
}
}

View File

@@ -0,0 +1,55 @@
#include "stdafx.h"
#include "Logger.h"
#include "L2Client.h"
/** Server: Len 23 [ValidateLocation]
17 00
79
B2 16 00 10 // mob/npc objectID
91 AC 00 00 // x
C5 A4 00 00 // y
5D F2 FF FF // z
FA C5 00 00 // heading **/
void L2Client::ph_ValidateLocation( class L2Client *pcls, L2GamePacket *p )
{
p->getPacketType();
unsigned int objectID = p->readUInt();
int x = p->readInt();
int y = p->readInt();
int z = p->readInt();
//
if( pcls->usr.objectID == objectID )
{
pcls->usr.x = x;
pcls->usr.y = y;
pcls->usr.z = z;
pcls->usr.lastMoveTickTime = GetTickCount();
}
else
{
WorldObjectTreeNode wotNode;
if( pcls->world_tree.GetInfoByObjectID( objectID, &wotNode ) )
{
int idx = wotNode.getArrayIdx();
switch( wotNode.getObjectType() )
{
case L2OT_PC:
{
pcls->world_chars.chars_array[idx]->x = x;
pcls->world_chars.chars_array[idx]->y = y;
pcls->world_chars.chars_array[idx]->z = z;
pcls->world_chars.chars_array[idx]->lastMoveTickTime = GetTickCount();
} break;
case L2OT_NPC:
{
//
pcls->world_npcs.npcs_array[idx]->x = x;
pcls->world_npcs.npcs_array[idx]->y = y;
pcls->world_npcs.npcs_array[idx]->z = z;
pcls->world_npcs.npcs_array[idx]->lastMoveTickTime = GetTickCount();
} break;
}
}
else log_error( LOG_ERROR, "WOT cannot find objectID while ValidateLocation\n" );
}
}