01-23-2011, 19:08
PHP Code:
#include "StdAfx.h"
#include "DataMgrPoP.h"
#include "Values.h"
static CDataMgrPoP s_DataMgrPoP;
CDataMgrPoP* g_pDataMgrPoP = &s_DataMgrPoP;
static CPoPTimer s_Timer;
CDataMgrPoP::CDataMgrPoP(void) : m_Worker(m_IO)
{
m_pPipe = NULL;
m_Thread = boost::thread( boost::bind(&boost::asio::io_service::run, &m_IO) );
m_uCurrentLevel = 0;
m_uCurrentXP = 0;
#if !defined(_DEBUG) && !defined(_LOG)
CDataBuffer Doors(ValuesPoPDoors, sizeof(ValuesPoPDoors));
#else
std::string strData;
std::string strFile = GetCurrentDir();
strFile += "\\doors.bin";
if( !LoadFileData(strFile, strData) )
{
LOG_PRINT("WARNING: Unable to load file data '" << strFile << "'\n");
}
CDataBuffer Doors;
Doors.Write( strData.c_str(), strData.size() );
Doors.Seek(0, SEEK_SET);
#endif
while( !Doors.IsEOB() )
{
uint32 uDoorId;
uint32 uOpenTime;
uint32 uOpenDelay;
uint32 uCloseTime;
uint32 uCloseDelay;
Doors >> uDoorId;
Doors >> uOpenTime;
Doors >> uOpenDelay;
Doors >> uCloseTime;
Doors >> uCloseDelay;
boost::shared_ptr Door( new CPoPDoor(uDoorId, uOpenTime, uOpenDelay, uCloseTime, uCloseDelay, m_IO) );
m_vecDoors.push_back(Door);
}
// XP to next Level, Level
for(int i = 0; i < 15; i++)
m_vecLevels.push_back( std::make_pair((i + 1) * 20, i) ); // Till 300
for(int i = 15; i < 50; i++)
m_vecLevels.push_back( std::make_pair(300, i) ); // 300 but next level
// Skills
// 0A 0B 05 09 06 08 04 07 10 0E 0F 11 12 13 14
PoPUpgrade_t* pUpgrade = NULL;
pUpgrade = InitUpgrade(0x00, 0x01, 1); // Rewind & Other.
pUpgrade->vecFields[0] = 1;
pUpgrade = InitUpgrade(0x03, 0x03, 1); // Solid water & Other.
pUpgrade->vecFields[0] = 1;
pUpgrade = InitUpgrade(0x04, 0x0A, 1); // Time Power - 1 level.
pUpgrade = InitUpgrade(0x05, 0x0B, 1); // Flight Boost - 1 level
pUpgrade = InitUpgrade(0x06, 0x05, 1); // Flow Power - 1 level.
pUpgrade = InitUpgrade(0x07, 0x09, 1); // Heavy Kick - 1 level.
pUpgrade = InitUpgrade(0x08, 0x06, 1); // Double Health - 1 level.
pUpgrade = InitUpgrade(0x09, 0x08, 1); // Double Energy - 1 level.
pUpgrade = InitUpgrade(0x0A, 0x04, 1); // Aerial Boost - 1 level.
pUpgrade = InitUpgrade(0x0B, 0x07, 1); // Power Attack - 1 level.
pUpgrade = InitUpgrade(0x0C, 0x10, 4); // Stone Armor - 4 levels
pUpgrade = InitUpgrade(0x0D, 0x0E, 4); // Whirlwind - 4 levels
pUpgrade = InitUpgrade(0x0E, 0x0F, 4); // Ice Blast - 4 levels
pUpgrade = InitUpgrade(0x0F, 0x11, 4); // Trial of Flame - 4 levels
pUpgrade = InitUpgrade(0x10, 0x12, 4); // Health Upgrade - 4 levels
pUpgrade->vecFields[0] = 1; // Not 0 as default
pUpgrade = InitUpgrade(0x11, 0x13, 4); // Energy Slot - 4 levels
pUpgrade->vecFields[0] = 1; // Not 0 as default
pUpgrade = InitUpgrade(0x12, 0x14, 2); // Battle rage / Battle Fury - 2 levels.
}
CDataMgrPoP::~CDataMgrPoP(void)
{
m_IO.stop();
if( m_Thread.joinable() )
m_Thread.join();
}
bool CDataMgrPoP::LoadUpgrades()
{
std::string strSavePath = GetSaveGamePath(*g_puProdId);
std::string strUpgradeFile = strSavePath;
strUpgradeFile += "\\upgrades.ravcpa";
std::ifstream fUpgrades;
fUpgrades.open(strUpgradeFile.c_str(), std::ios::binary);
if( !fUpgrades.is_open() )
return false;
CDataBuffer Packet;
std::string strPacket;
std::string strData;
std::vector>::iterator itr;
for( itr = m_vecUpgrades.begin(); itr != m_vecUpgrades.end(); itr++ )
{
for( std::size_t i = 0; i< (*itr)->vecFields.size(); i++ )
{
uint8 uUpgrade;
fUpgrades.read( (char*)&uUpgrade, sizeof(uint8) );
if( fUpgrades.fail() )
break;
(*itr)->vecFields[i] = uUpgrade;
}
}
fUpgrades.close();
return true;
}
bool CDataMgrPoP::SaveUpgrades()
{
std::string strSavePath = GetSaveGamePath(*g_puProdId);
std::string strUpgradeFile = strSavePath;
strUpgradeFile += "\\upgrades.ravcpa";
std::ofstream fUpgrades;
fUpgrades.open(strUpgradeFile.c_str(), std::ios::binary);
if( !fUpgrades.is_open() )
return false;
std::vector>::iterator itr;
for( itr = m_vecUpgrades.begin(); itr != m_vecUpgrades.end(); itr++ )
{
for( std::size_t i = 0; i< (*itr)->vecFields.size(); i++ )
{
uint8 uUpgrade = (*itr)->vecFields[i];
fUpgrades.write( (char*)&uUpgrade, sizeof(uint8) );
}
}
fUpgrades.close();
return true;
}
PoPUpgrade_t* CDataMgrPoP::InitUpgrade(uint32 uClientId, uint32 uServerId, uint8 uFields)
{
PoPUpgrade_t* pUpgrade = new PoPUpgrade_t;
pUpgrade->uServerId = uServerId;
pUpgrade->uClientId = uClientId;
for( uint8 i = 0; i < uFields; i++ )
pUpgrade->vecFields.push_back(0); // Default is 0
m_vecUpgrades.push_back( boost::shared_ptr(pUpgrade) );
return pUpgrade;
}
PoPUpgrade_t* CDataMgrPoP::GetUpdatedByGameId( uint32 uGameId )
{
std::vector>::iterator itr;
for( itr = m_vecUpgrades.begin(); itr != m_vecUpgrades.end(); itr++ )
{
if( (*itr)->uClientId == uGameId )
return (*itr).get();
}
return NULL; // Not found.
}
PoPUpgrade_t* CDataMgrPoP::GetUpdatedByServerId( uint32 uServerId )
{
std::vector>::iterator itr;
for( itr = m_vecUpgrades.begin(); itr != m_vecUpgrades.end(); itr++ )
{
if( (*itr)->uServerId == uServerId )
return (*itr).get();
}
return NULL; // Not found.
}
PoPUpgrade_t* CDataMgrPoP::UnlockUpgrade(uint16 uGameId, uint16 uFieldIndex, uint8 uFlag, bool bUnlockNextLevel)
{
PoPUpgrade_t* pUpgrade = GetUpdatedByGameId(uGameId);
if(pUpgrade)
{
if( uFieldIndex >= pUpgrade->vecFields.size() )
return pUpgrade;
pUpgrade->vecFields[uFieldIndex] = uFlag;
if( bUnlockNextLevel )
{
if( uFieldIndex + 1 < pUpgrade->vecFields.size() )
pUpgrade->vecFields[uFieldIndex + 1] = 0x01;
}
}
return pUpgrade;
}
uint8 CDataMgrPoP::GetUpgradeLevel(uint8 uGameId)
{
uint8 uLevel = 0;
PoPUpgrade_t* pUpgrade = GetUpdatedByGameId(uGameId);
if(pUpgrade)
{
std::vector::iterator itr;
for( itr = pUpgrade->vecFields.begin(); itr != pUpgrade->vecFields.end(); itr++ )
{
if( (*itr) == 0x02 )
uLevel++;
}
}
return uLevel;
}
CPoPLever* CDataMgrPoP::CreateLever( uint32 uLeverId )
{
CPoPLever* pLever = new CPoPLever(m_IO, uLeverId);
m_vecLever.push_back( boost::shared_ptr(pLever) );
return pLever;
}
void CDataMgrPoP::DeleteLever( uint32 uLeverId )
{
std::vector>::iterator itr;
for(itr = m_vecLever.begin(); itr != m_vecLever.end(); itr++)
{
if( (*itr)->LeverId() == uLeverId )
{
m_vecLever.erase(itr);
return;
}
}
}
CPoPLever* CDataMgrPoP::GetLeverById( uint32 uLeverId )
{
std::vector>::iterator itr;
for(itr = m_vecLever.begin(); itr != m_vecLever.end(); itr++)
{
if( (*itr)->LeverId() == uLeverId )
return (*itr).get();
}
return NULL;
}
uint32 CDataMgrPoP::GetMaxXPPerLevel( uint32 uLevel )
{
std::vector>::iterator itr;
for( itr = m_vecLevels.begin(); itr != m_vecLevels.end(); itr++ )
{
if( (*itr).second == uLevel )
return (*itr).first;
}
return 0;
}
void CDataMgrPoP::OnConnect( CPipeInstance* pPipe )
{
m_pPipe = pPipe;
uint32 Temp32;
CDataBuffer Packet;
Packet << *g_puProdId;
Packet << (uint32)endian_swap((Temp32 = 0x000000001));
Packet << (uint32)endian_swap((Temp32 = 0x000000001));
std::string strPacket1 = MakePacket(0, Packet.Buffer());
std::string strPacket2 = MakePacket(6);
std::string strPacket3 = MakePacket(2);
pPipe->Write( strPacket1 );
pPipe->Write( strPacket2 );
pPipe->Write( strPacket3 );
s_Timer.Start();
}
void CDataMgrPoP::ProcessPacket( CPipeInstance* pPipe, std::string& strPacket )
{
m_pPipe = pPipe;
uint16 usPacketId = *((uint16*)(strPacket.c_str() + 3));
endian_swap(usPacketId);
std::string strData;
if( strPacket.size() > 5 )
{
#if defined(PRINT_PACKET)
LOG_PRINT("Packet: " << PrintPacket(strPacket) << "\n");
#endif
strData = strPacket.substr(5);
CDataBuffer Buffer(strData.c_str(), strData.size());
if( usPacketId == 0x0009 )
{
// Button
OnButtonStep(Buffer);
}
else if( usPacketId == 0x0008 )
{
// Area stuff
AreaLock(Buffer);
}
else if( usPacketId == 0x0007 )
{
// Area stuff
AreaUnlock(Buffer);
}
else if( usPacketId == 0x001A )
{
// Upgrades
GetUpgrades(Buffer);
}
else if( usPacketId == 0x0015 )
{
// Game start.
Upgrade(Buffer);
}
else if( usPacketId == 0x0017 )
{
// Info from game
UpdateGameInfo(Buffer);
}
else if( usPacketId == 0x0018 )
{
// XP Update
UpdateXP(Buffer);
}
else if( usPacketId == 0x000d )
{
// Open/Close door.
DoorEvent(Buffer);
}
else if( usPacketId == 0x0011 )
{
ObjectInit(Buffer);
}
else if( usPacketId == 0x0013 )
{
Lever(Buffer);
}
else if( usPacketId == 0x0012 )
{
OnLeverLock(Buffer);
}
else
{
if( usPacketId != 0x0005 && usPacketId != 0x0001d && usPacketId != 0x0004 && usPacketId != 0x0014 )
{
// Unknown Packet.
LOG_PRINT("Unknown Packet: " << PrintPacket(strPacket) << "\n");
}
}
/*
std::string strData;
strData.append("\x00\x00\x00\xA5\x00\x00\x00\x1E", 8);
std::string strPacket = MakePacket(0x19, strData);
pPipe->Write(strPacket);
*/
}
}
CPipeInstance* CDataMgrPoP::Pipe()
{
return m_pPipe;
}
void CDataMgrPoP::OnButtonStep(CDataBuffer& Buffer)
{
uint32 uDoorId;
Buffer >> uDoorId;
uint32 uDummy0;
Buffer >> uDummy0;
bool bSteppedOff;
Buffer >> bSteppedOff;
do_again:
std::vector>::iterator itr;
for( itr = m_vecDoors.begin(); itr != m_vecDoors.end(); itr++ )
{
if( (*itr)->DoorId() != uDoorId )
continue;
std::vector::iterator itrLock;
for( itrLock = m_vecLocked.begin(); itrLock != m_vecLocked.end(); itrLock++ )
{
if( *itrLock == uDoorId )
{
LOG_PRINT("Tried to enter locked area: " << (void*)uDoorId << "\n");
m_vecLocked.erase(itrLock);
return;
}
}
if( !bSteppedOff )
{
(*itr)->BeginOpen(s_Timer.Elapsed());
}
else
{
(*itr)->BeginClose(s_Timer.Elapsed());
}
return;
}
#if defined(CONFIG_SAFE_DOORS) && CONFIG_SAFE_DOORS
// In case a door doesn't exist, create a default one with 10sec close time, 1s open time.
CPoPDoor* pDoor = new CPoPDoor(uDoorId, 1000, 29, 10000, 29, m_IO);
m_vecDoors.push_back( boost::shared_ptr(pDoor) );
LOG_PRINT("Door not found, creating: " << (void*)uDoorId << "\n");
goto do_again;
#endif
LOG_PRINT("Door not found: " << (void*)uDoorId << "\n");
}
void CDataMgrPoP::AreaLock(CDataBuffer& Buffer)
{
uint32 uAreaId;
uint32 uDummy0;
uint16 uLocked1;
uint16 uLocked2;
uint16 uDummy2;
uint8 uDummy1;
uint16 uAreaFlag;
std::string strData;
std::string strPacket;
Buffer >> uAreaId;
/*
std::string strRequest;
strRequest.assign( Buffer.Buffer() + Buffer.Offset(), Buffer.Size() - Buffer.Offset() );
*/
//0dce2162 00000001 00000000 0000 0001, 000000000000a040000000000000803f0000d040000000000001000001
//591c0fc1 00000001 00000000 0000 0000, 0000803f 000080400 00000000 00080400 000003f0 00000000 1000 00001
//347f98b0 00000001 00000000 0000 0000, 00000000 0000c0400 00000000 00080400 00000410 00000000 0010 00001
//6fdec12a 00000001 00000000 0000 0000, 0000803f 0000a0400 00000000 00080400 00000410 00000000 1000 00101
//0d920314 00000001 00000000 0000 0002, 0000803f 0000a0400 00000000 000803f0 000803f0 00000000 1000 00001
//6ab6464e 00000001 00000000 0000 0002, 00000000 0000a0400 00000000 000003f0 000a0400 00000000 0010 00001
//31644747 00000001 00000000 0000 0000, 00000000 0000a0400 00000000 00080400 00000410 00000000 0010 00001
Buffer >> uDummy0; // 00000001
Buffer >> uDummy0; // 00000000
Buffer >> uLocked1; // 0000
endian_swap(uLocked1);
Buffer >> uLocked2; // 0000 or 0002
endian_swap(uLocked2);
Buffer >> uDummy0; // 00000000
Buffer >> uDummy0; // 00000000
Buffer >> uDummy0; // 00000000
Buffer >> uDummy0; // 00000000
Buffer >> uDummy0; // 00000000
Buffer >> uDummy0; // 00000000
Buffer >> uAreaFlag;
endian_swap(uAreaFlag);
if( (uLocked1 == 2 && uLocked2 == 1) || (uLocked1 == 0 && uLocked2 == 2) || (uLocked1 == 0 && uLocked2 == 1) )
{
LOG_PRINT("Locked Area: " << (void*)uAreaId << "\n");
m_vecLocked.push_back(uAreaId);
}
else
{
std::vector::iterator itrLock;
for( itrLock = m_vecLocked.begin(); itrLock != m_vecLocked.end(); itrLock++ )
{
if( *itrLock == uAreaId )
{
m_vecLocked.erase(itrLock);
LOG_PRINT("Unlocked Area: " << (void*)uAreaId << "\n");
break;
}
}
}
CDataBuffer Packet;
Packet << uAreaId;
if( uAreaFlag == 0x0000 )
{
Packet << endian_swap((uDummy2 = 2));
Packet << endian_swap((uDummy2 = 6));
Packet << (uDummy1 = 1);
Packet << endian_swap((uDummy2 = 3));
Packet << endian_swap((uDummy2 = 5));
m_vecLocked.push_back(uAreaId);
}
else if( uAreaFlag == 0x0100 )
{
Packet << endian_swap((uDummy2 = 1));
Packet << endian_swap((uDummy2 = 3));
Packet << endian_swap((uDummy2 = 5));
}
else if( uAreaFlag = 0x0001 )
{
Packet << endian_swap((uDummy2 = 1));
Packet << endian_swap((uDummy2 = 3));
Packet << endian_swap((uDummy2 = 2));
}
else
{
LOG_PRINT("WARNING: Needs to be implemented. (Missing: " << std::hex << std::setw(4) << std::setfill('0') << +(unsigned int)uAreaFlag << ")\n");
Packet << endian_swap((uDummy2 = 1));
Packet << endian_swap((uDummy2 = 3));
Packet << endian_swap((uDummy2 = 2));
}
strData.assign( Packet.Buffer(), Packet.Size() );
strPacket = MakePacket(0x0a, strData);
g_pDataMgrPoP->Pipe()->Write( strPacket );
LOG_PRINT("Area: " << Data_ConvertToHex(strPacket) << "\n");
}
void CDataMgrPoP::AreaUnlock(CDataBuffer& Buffer)
{
uint32 uAreaId;
Buffer >> uAreaId;
std::vector::iterator itrLock;
for( itrLock = m_vecLocked.begin(); itrLock != m_vecLocked.end(); itrLock++ )
{
if( *itrLock == uAreaId )
{
m_vecLocked.erase(itrLock);
break;
}
}
}
void CDataMgrPoP::GetUpgrades(CDataBuffer& Buffer)
{
// 010100000000000000000000000000000000000000000000000001000000010000000000
// 010100000000000000000000000000000000000000000000000001000000010000000000
// [18:52:02.0676] [S->C] 002400001b 010201000000000000010100000001000000010000000100000002020201020201000100
uint8 uDummy0;
Buffer >> uDummy0;
CDataBuffer Packet;
uint8 uTemp1;
std::string strData;
std::string strPacket;
/*
Packet << (uTemp1 = 1);
Packet << (uTemp1 = 1);
*/
std::vector>::iterator itr;
for( itr = m_vecUpgrades.begin(); itr != m_vecUpgrades.end(); itr++ )
{
for( std::size_t i = 0; i< (*itr)->vecFields.size(); i++ )
{
Packet << (uTemp1 = (*itr)->vecFields[i]);
}
}
strData.assign( Packet.Buffer(), Packet.Size() );
strPacket = MakePacket(0x1b, strData);
g_pDataMgrPoP->Pipe()->Write( strPacket );
LOG_PRINT("Skills: " << Data_ConvertToHex(strPacket) << "\n");
}
void CDataMgrPoP::UpdateXP(CDataBuffer& Buffer)
{
uint32 uAdd = 0;
Buffer >> uAdd;
endian_swap(uAdd);
CDataBuffer Packet;
std::string strData;
std::string strPacket;
m_uCurrentXP += uAdd;
uint32 uMaxXP = GetMaxXPPerLevel(m_uCurrentLevel);
if( m_uCurrentXP >= uMaxXP )
{
m_uCurrentLevel++;
m_uCurrentXP = 0;
Packet.Clear();
// If level goes up a new packet is sent
uint32 uCurrentXP = m_uCurrentXP;
uint32 uCurrentLevel = m_uCurrentLevel;
Packet << endian_swap(uCurrentXP);
Packet << endian_swap(uCurrentLevel);
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x19, strData);
g_pDataMgrPoP->Pipe()->Write( strPacket );
LOG_PRINT("XP Update: " << Data_ConvertToHex(strPacket) << "\n");
}
else
{
uint32 uCurrentXP = m_uCurrentXP;
uint32 uCurrentLevel = m_uCurrentLevel;
Packet << endian_swap(uCurrentXP);
Packet << endian_swap(uCurrentLevel);
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x19, strData);
g_pDataMgrPoP->Pipe()->Write( strPacket );
LOG_PRINT("XP Update: " << Data_ConvertToHex(strPacket) << "\n");
}
}
void CDataMgrPoP::UpdateGameInfo(CDataBuffer& Buffer)
{
// 009a000017 5c668002 0000 002b 0000 000a 00230000000000000014000000280000003c0000005000000064000000780000008c000000a0000000b4000000c8000000dc000000f000000104000001180000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c0000012c
uint32 uDummy0;
uint32 uCurrentXP;
uint32 uLevel;
Buffer >> uDummy0;
Buffer >> uCurrentXP;
endian_swap(uCurrentXP);
Buffer >> uLevel;
endian_swap(uLevel);
uint32 uMaxLevelXP = GetMaxXPPerLevel(uLevel);
if( uMaxLevelXP == 0 )
return; // Invalid Level.
m_uCurrentLevel = uLevel;
m_uCurrentXP = uCurrentXP;
}
void CDataMgrPoP::Upgrade( CDataBuffer& Buffer )
{
// Loose Upgrades
//[C->S] 000c000015 0000 0005 0000 0015 0000 0000
//[S->C] 000e000016 0004 0001 00 0002 0000 0000 0003 00
// Keep Upgrades
//[C->S] 000c000015 0000 0005 0000 0015 0000 0000
//[S->C] 000b000016 0003 0001 00 0000 0000 0300
// Upgrades.
//[C->S] 000c000015 0000 0000 0000 0011 0000 0002
//[S->C] 0006000016 0001 0013 0002
//[C->S] 000c000015 0000 0000 0000 0006 0000 0000
//[S->C] 0005000016 0001 0005 01
//[C->S] 000c000015 0000 0000 0000 0003 0000 0000
//[S->C] 0005000016 0001 0003 01
//[C->S] 000c000015 0000 0000 0000 0010 0000 0000
//[S->C] 0006000016 0001 0012 0000
uint16 uDummy0;
uint16 uGameId;
uint16 uFieldIndex;
uint16 uUpdate;
uint16 uTemp;
uint8 uTemp2;
CDataBuffer Packet;
std::string strData;
std::string strPacket;
Buffer >> uDummy0; // Ignored
Buffer >> uUpdate;
endian_swap(uUpdate);
Buffer >> uDummy0; // Ignored
if( uUpdate == 0x0005 )
{
Packet << endian_swap((uTemp = 0x0004));
Packet << endian_swap((uTemp = 0x0001));
Packet << (uTemp2 = 0x00);
Packet << endian_swap((uTemp = 0x0002));
Packet << endian_swap((uTemp = 0x0000));
Packet << endian_swap((uTemp = 0x0000));
Packet << endian_swap((uTemp = 0x0003));
Packet << (uTemp2 = 0x00);
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x16, strData);
g_pDataMgrPoP->Pipe()->Write( strPacket );
LOG_PRINT("New Upgrades: " << Data_ConvertToHex(strPacket) << "\n");
// Reset Upgrades, fuck you PALYIER?!
std::vector>::iterator itr;
for( itr = m_vecUpgrades.begin(); itr != m_vecUpgrades.end(); itr++ )
{
for(std::size_t i = 0; i < (*itr)->vecFields.size(); i++ )
(*itr)->vecFields[i] = 0x00;
if( (*itr)->uClientId == 0x00 )
(*itr)->vecFields[0] = 0x01;
else if( (*itr)->uClientId == 0x03 )
(*itr)->vecFields[0] = 0x01;
else if( (*itr)->uClientId == 0x10 )
(*itr)->vecFields[0] = 0x01;
else if( (*itr)->uClientId == 0x11 )
(*itr)->vecFields[0] = 0x01;
}
return;
}
Buffer >> uGameId; // Power id on client side.
endian_swap(uGameId);
Buffer >> uDummy0; // Ignored
Buffer >> uFieldIndex; // Described as level.
endian_swap(uFieldIndex);
PoPUpgrade_t* pUpgrade = GetUpdatedByGameId(uGameId);
if( !pUpgrade )
{
LOG_PRINT("WARNING: Upgrade '" << uGameId << "' not found, resulting default!\n");
Buffer << endian_swap((uTemp = 0x0004));
Buffer << endian_swap((uTemp = 0x0001));
Buffer << (uTemp2 = 0x00);
Buffer << endian_swap((uTemp = 0x0002));
Buffer << endian_swap((uTemp = 0x0000));
Buffer << endian_swap((uTemp = 0x0000));
Buffer << (uTemp2 = 0x00);
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x16, strData);
g_pDataMgrPoP->Pipe()->Write( strPacket );
LOG_PRINT("Upgrade: " << Data_ConvertToHex(strPacket) << "\n");
return;
}
/*
pUpgrade = InitUpgrade(0x04, 0x0A, 1); // Time Power - 1 level.
pUpgrade = InitUpgrade(0x06, 0x05, 1); // Flow Power - 1 level.
pUpgrade = InitUpgrade(0x05, 0x0B, 1); // Flight Boost - 1 level
pUpgrade = InitUpgrade(0x07, 0x09, 1); // Heavy Kick - 1 level.
pUpgrade = InitUpgrade(0x08, 0x06, 1); // Double Health - 1 level.
pUpgrade = InitUpgrade(0x09, 0x08, 1); // Double Energy - 1 level.
pUpgrade = InitUpgrade(0x0A, 0x04, 1); // Aerial Boost - 1 level.
pUpgrade = InitUpgrade(0x0B, 0x07, 1); // Power Attack - 1 level.
pUpgrade = InitUpgrade(0x0C, 0x10, 4); // Stone Armor - 4 levels
pUpgrade = InitUpgrade(0x0D, 0x0E, 4); // Whirlwind - 4 levels
pUpgrade = InitUpgrade(0x0E, 0x0F, 4); // Ice Blast - 4 levels
pUpgrade = InitUpgrade(0x0F, 0x11, 4); // Trial of Flame - 4 levels
pUpgrade = InitUpgrade(0x10, 0x12, 4); // Health Upgrade - 4 levels
pUpgrade = InitUpgrade(0x11, 0x13, 4); // Energy Slot - 4 levels
pUpgrade = InitUpgrade(0x12, 0x14, 2); // Battle rage / Battle Fury - 2 levels.
*/
// Only Health and Energy goes up
UnlockUpgrade(uGameId, uFieldIndex, 0x02, uGameId == 0x11 || uGameId == 0x10 ? true : false );
if( uGameId == 0x11 )
{
// Energy
if( uFieldIndex == 0 )
{
UnlockUpgrade(0x0D, 0, 0x01, false);
UnlockUpgrade(0x0E, 0, 0x01, false);
}
else if( uFieldIndex == 1 )
{
// Energy 2
if( GetUpgradeLevel(0x10) == 2 )
UnlockUpgrade(0x04, 0, 0x01, false); // Time Power
UnlockUpgrade(0x0B, 0, 0x01, false); // Power Attack 1
if( GetUpgradeLevel(0x0D) == 1 )
UnlockUpgrade(0x0D, 1, 0x01, false); // Whirlwind 2
if( GetUpgradeLevel(0x0E) == 1 )
UnlockUpgrade(0x0E, 1, 0x01, false); // Ice Blast 2
}
else if( uFieldIndex == 2 )
{
// Energy 3
if( GetUpgradeLevel(0x10) == 3 )
UnlockUpgrade(0x06, 0, 0x01, false); // Flow Power
if( GetUpgradeLevel(0x0B) == 1 )
UnlockUpgrade(0x07, 0, 0x01, false); // Heavy Kick
if( GetUpgradeLevel(0x0D) == 2 )
UnlockUpgrade(0x0D, 2, 0x01, false); // Whirlwind 3
if( GetUpgradeLevel(0x0E) == 2 )
UnlockUpgrade(0x0E, 2, 0x01, false); // Ice Blast 3
}
else if( uFieldIndex == 3 )
{
// Energy 4
if( GetUpgradeLevel(0x10) == 3 )
UnlockUpgrade(0x08, 0, 0x01, false); // Double Health
if( GetUpgradeLevel(0x07) == 1 )
UnlockUpgrade(0x05, 0, 0x01, false); // Power Attack 2
if( GetUpgradeLevel(0x0D) == 3 )
UnlockUpgrade(0x0D, 3, 0x01, false); // Whirlwind 4
if( GetUpgradeLevel(0x0E) == 3 )
UnlockUpgrade(0x0E, 3, 0x01, false); // Ice Blast 4
}
}
else if ( uGameId == 0x10 )
{
// Health
if( uFieldIndex == 0 )
{
// Health 1
UnlockUpgrade(0x0C, 0, 0x01, false);
UnlockUpgrade(0x0F, 0, 0x01, false);
}
else if( uFieldIndex == 1 )
{
// Health 2
if( GetUpgradeLevel(0x11) == 2 )
UnlockUpgrade(0x04, 0, 0x01, false); // Time Power
UnlockUpgrade(0x12, 0, 0x01, false); // Battle Rage 1
if( GetUpgradeLevel(0x0C) == 1 )
UnlockUpgrade(0x0C, 1, 0x01, false); // Stone Armor 2
if( GetUpgradeLevel(0x0F) == 1 )
UnlockUpgrade(0x0F, 1, 0x01, false); // Trail of Flame 2
}
else if( uFieldIndex == 2 )
{
// Health 3
if( GetUpgradeLevel(0x11) == 3 )
UnlockUpgrade(0x06, 0, 0x01, false); // Flow Power
if( GetUpgradeLevel(0x12) == 1 )
UnlockUpgrade(0x12, 1, 0x01, false); // Battle Fury
if( GetUpgradeLevel(0x0C) == 2 )
UnlockUpgrade(0x0C, 2, 0x01, false); // Stone Armor 2
if( GetUpgradeLevel(0x0F) == 2 )
UnlockUpgrade(0x0F, 2, 0x01, false); // Trail of Flame 2
}
else if( uFieldIndex == 3 )
{
// Health 4
if( GetUpgradeLevel(0x11) == 4 )
UnlockUpgrade(0x08, 0, 0x01, false); // Double Health
if( GetUpgradeLevel(0x12) == 2 )
UnlockUpgrade(0x0A, 0, 0x01, false); // Aerial Boost
if( GetUpgradeLevel(0x0C) == 3 )
UnlockUpgrade(0x0C, 3, 0x01, false); // Stone Armor 3
if( GetUpgradeLevel(0x0F) == 3 )
UnlockUpgrade(0x0F, 3, 0x01, false); // Trail of Flame 3
}
}
else if( uGameId == 0x0C )
{
// Stone Armor
for( uint8 i = (uFieldIndex + 1); i < pUpgrade->vecFields.size(); i++ )
{
if( GetUpgradeLevel(0x10) > i )
UnlockUpgrade(0x0C, i, 0x01, false);
}
}
else if( uGameId == 0x0F )
{
// Trail of Flames
for( uint8 i = (uFieldIndex + 1); i < pUpgrade->vecFields.size(); i++ )
{
if( GetUpgradeLevel(0x10) > i )
UnlockUpgrade(0x0F, i, 0x01, false);
}
}
else if( uGameId == 0x12 )
{
// Battle Rage
if( uFieldIndex == 0 )
{
if( GetUpgradeLevel(0x10) >= 2 )
UnlockUpgrade(0x12, 1, 0x01, false);
}
else if( uFieldIndex == 1 )
{
if( GetUpgradeLevel(0x10) > 3 )
UnlockUpgrade(0x0A, 0, 0x01, false);
}
}
else if( uGameId == 0x0D )
{
// Whirlwind
for( uint8 i = (uFieldIndex + 1); i < pUpgrade->vecFields.size(); i++ )
{
if( GetUpgradeLevel(0x11) > i )
UnlockUpgrade(0x0D, i, 0x01, false);
}
}
else if( uGameId == 0x0E )
{
// Ice Blast
for( uint8 i = (uFieldIndex + 1); i < pUpgrade->vecFields.size(); i++ )
{
if( GetUpgradeLevel(0x11) > i )
UnlockUpgrade(0x0E, i, 0x01, false);
}
}
else if( uGameId == 0x0B )
{
if( GetUpgradeLevel(0x11) >= 2 )
UnlockUpgrade(0x07, 0, 0x01, false); // Heavy Kick.
}
else if( uGameId == 0x07 )
{
if( GetUpgradeLevel(0x11) > 3 )
UnlockUpgrade(0x05, 0, 0x01, false); // Flight Boost
}
// These must be level 4 to unlock Double Energy.
if( GetUpgradeLevel(0x0F) == 4 && // Trail of Flame
GetUpgradeLevel(0x0C) == 4 && // Stone Armor
GetUpgradeLevel(0x0D) == 4 && // Whirlwind
GetUpgradeLevel(0x0E) == 4 // Ice Blast
)
{
// Enable Double Energy.
pUpgrade = GetUpdatedByGameId(0x09);
if( pUpgrade )
pUpgrade->vecFields[0] = 0x01;
}
// 0006000016 0001 0012 0100
Packet << endian_swap((uTemp = 1)); // 0001 OK
Packet << endian_swap((uTemp = (uint16)pUpgrade->uServerId));
if( pUpgrade->vecFields.size() == 1 || pUpgrade->vecFields.size() == 0 )
Packet << (uTemp2 = 1);
else
Packet << endian_swap((uTemp = (uint16)uFieldIndex));
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x16, strData);
g_pDataMgrPoP->Pipe()->Write( strPacket );
LOG_PRINT("Upgrade: " << Data_ConvertToHex(strPacket) << "\n");
}
void CDataMgrPoP::DoorEvent(CDataBuffer& Buffer)
{
// 000500000d 480e0856 01
uint32 uDoorId;
Buffer >> uDoorId;
bool bOpenEvent;
Buffer >> bOpenEvent;
if( bOpenEvent == true )
{
std::vector>::iterator itr;
for( itr = m_vecButtons.begin(); itr != m_vecButtons.end(); itr++ )
{
if( (*itr)->Id() == uDoorId )
{
(*itr)->Enter(s_Timer.Elapsed(), 2000);
return;
}
}
CPoPButton* pButton = new CPoPButton(m_IO, uDoorId);
m_vecButtons.push_back( boost::shared_ptr(pButton) );
pButton->Enter(s_Timer.Elapsed(), 2000);
}
else
{
std::vector>::iterator itr;
for( itr = m_vecButtons.begin(); itr != m_vecButtons.end(); itr++ )
{
if( (*itr)->Id() == uDoorId )
{
(*itr)->Leave(s_Timer.Elapsed(), 2000);
return;
}
}
}
}
void CDataMgrPoP::ObjectInit(CDataBuffer& Buffer)
{
// [C->S] 001f000011 4aca871b 000000000000000000000000000000000000000000000000000000
// [S->C] 000a000013 4aca871b 0001 0000 0000
uint32 uId;
Buffer >> uId;
CDataBuffer Packet;
std::string strData;
std::string strPacket;
uint16 uTemp;
Packet << uId;
Packet << endian_swap((uTemp = 0x0001));
Packet << endian_swap((uTemp = 0x0000));
Packet << endian_swap((uTemp = 0x0000));
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x13, strData);
m_pPipe->Write( strPacket );
LOG_PRINT("Sent Object Init: " << Data_ConvertToHex(strPacket) << "\n");
}
void CDataMgrPoP::Lever(CDataBuffer& Buffer)
{
uint32 uLeverId;
uint16 uPacketId1;
uint16 uPacketId2;
//uint8 uTemp1;
uint16 uTemp2;
CDataBuffer Packet;
std::string strData;
std::string strPacket;
Buffer >> uLeverId;
Buffer >> uPacketId1;
endian_swap(uPacketId1);
Buffer >> uPacketId2;
endian_swap(uPacketId2);
CPoPLever* pLever = GetLeverById(uLeverId);
if( uPacketId1 == 0x0001 && uPacketId2 == 0x0004 )
{
bool bEnter;
Buffer >> bEnter;
// Enter/Leave
if( bEnter )
{
pLever = CreateLever(uLeverId);
pLever->SetPlayerOnLever(true);
LOG_PRINT("Entered Lever.\n");
}
else
{
// Deleting isnt a good idea in case the direction was changed
// it would be forward after entering the lever again. So keep it alive :)
if( pLever )
pLever->SetPlayerOnLever(false);
LOG_PRINT("Left Lever.\n");
}
}
else if( uPacketId1 == 0x0001 && uPacketId2 == 0x0005 )
{
// Push
if(pLever)
pLever->Push();
}
else if( uPacketId1 == 0x0002 && uPacketId2 == 0x0005 )
{
// Direction was previously set to backward (0x0002 is state)
// Change direction and push.
// [C->S] [LEVER] 000c000013 4aca871b 0002 0005 01 0006 01
// 000f000013 33f4631b 0002 0005 01 0007 e8b40140
uint8 uTemp1;
uint16 uTemp2;
Buffer >> uTemp1;
Buffer >> uTemp2;
endian_swap(uTemp2);
// Moonwalk fix - That was funny shit :D
if( uTemp2 == 0x0007 )
{
pLever->SetDirection( k_eLeverDirectionBackward );
// 000a000013 33f4631b 0001 0002 0003
Packet << uLeverId;
Packet << endian_swap((uTemp2 = 0x0001));
Packet << endian_swap((uTemp2 = 0x0002));
Packet << endian_swap((uTemp2 = 0x0003));
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x0013, strData);
m_pPipe->Write(strPacket);
//LOG_PRINT("Lever Object Lock: " << ValueDB_ConvertToHex(strPacket) << "\n");
}
else
{
bool bForward;
Buffer >> bForward;
pLever->SetDirection( bForward ? k_eLeverDirectionForward : k_eLeverDirectionBackward );
}
}
else if( uPacketId1 == 0x0003 && uPacketId2 == 0x0005 )
{
// Direction was previously set to forward (0x0003 is state)
// 0012000013 5940c11a 0003 0005 01 0006 01 0007 e8b40140
// Change direction and push.
// [C->S] [LEVER] 000c000013 4aca871b 0002 0005 01 0006 01
// 000f000013 33f4631b 0002 0005 01 0007 e8b40140
uint8 uTemp1;
uint16 uTemp2;
Buffer >> uTemp1;
Buffer >> uTemp2;
Buffer >> uTemp1;
uint16 uObjectLock = 0x0006;
if( !Buffer.IsEOB() )
{
Buffer >> uObjectLock;
endian_swap(uObjectLock);
}
// Some relation to an object.
Packet << uLeverId;
Packet << endian_swap((uTemp2 = 0x0001));
Packet << endian_swap((uTemp2 = 0x0002));
Packet << endian_swap((uTemp2 = 0x0002));
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x0013, strData);
m_pPipe->Write(strPacket);
//LOG_PRINT("Lever Object Lock: " << ValueDB_ConvertToHex(strPacket) << "\n");
}
else if( uPacketId1 == 0x0002 && uPacketId2 == 0x0002 )
{
// 4aca871b 0002 0002 0000 0005 00
// Position (Forward).
// 0002 0002 0000 0008 0000 0001 // No Response.
// 0002 0002 0000 0005 00 // Response.
// 0002 0002 0000 0001 0001 // WTF PACKET
Buffer >> uTemp2;
Buffer >> uTemp2;
endian_swap(uTemp2);
if( uTemp2 == 0x0005 )
{
if( pLever )
{
//pLever->SetDirection( k_eLeverDirectionForward );
pLever->WaitForPositionChange();
}
}
else if( uTemp2 == 0x0008 )
{
// Direction result flag.
// 4aca871b 0001 0002 0001
Buffer >> uTemp2;
uint16 uPosition;
Buffer >> uPosition;
endian_swap(uPosition);
if( pLever )
pLever->SetPosition(uPosition);
}
else if( uTemp2 == 0x0001 )
{
}
else
{
LOG_PRINT("Unknown Packet for Lever: " << Data_ConvertToHex(strPacket) << "\n");
}
}
else if( uPacketId1 == 0x0003 && uPacketId2 == 0x0002 )
{
// Position (Backward)
Buffer >> uTemp2;
Buffer >> uTemp2;
endian_swap(uTemp2);
if( uTemp2 == 0x0008 )
{
Buffer >> uTemp2;
uint16 uPosition;
Buffer >> uPosition;
endian_swap(uPosition);
if(pLever)
{
//pLever->SetDirection( k_eLeverDirectionBackward );
pLever->WaitForPositionChange();
}
}
else
{
LOG_PRINT("Unknown Packet for Lever: " << Data_ConvertToHex(strPacket) << "\n");
}
}
else
{
LOG_PRINT("WARNING: Unknown Lever packet case: " << (void*)uPacketId1 << ", " << (void*)uPacketId2 << "\n");
}
}
void CDataMgrPoP::OnLeverLock(CDataBuffer& Buffer)
{
//[C->S] 0008000012 5940c11a00000003
//[C->S] 0008000012 54f2c0ae00000000
//[S->C] 000a000013 5940c11a000100000003
//[S->C] 000a000013 54f2c0ae000100000000
// This shit is sent when its supposed to be locked
// No need for management just reply :D
uint32 uLeverId;
uint16 uTemp1;
uint16 uLockFlag;
Buffer >> uLeverId;
Buffer >> uTemp1;
Buffer >> uLockFlag;
CDataBuffer Packet;
std::string strData;
std::string strPacket;
Packet << uLeverId;
Packet << endian_swap((uTemp1 = 0x0001));
Packet << endian_swap((uTemp1 = 0x0000));
Packet << uLockFlag;
strData.assign(Packet.Buffer(), Packet.Size());
strPacket = MakePacket(0x0013, strData);
m_pPipe->Write(strPacket);
LOG_PRINT("Lever Lock: " << Data_ConvertToHex(strPacket) << "\n");