mxoemu/Reality/Source/PlayerObjectHandlers.cpp
rajkosto 7c028d38a7 Merge branch 'master' of github.com:rajkosto/mxoemu
Conflicts:
	Reality/Source/Common.h
2010-09-03 06:37:03 +02:00

1056 lines
No EOL
29 KiB
C++

// ***************************************************************************
//
// Reality - The Matrix Online Server Emulator
// Copyright (C) 2006-2010 Rajko Stojadinovic
// http://mxoemu.info
//
// ---------------------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ---------------------------------------------------------------------------
//
// ***************************************************************************
#include "Common.h"
#include "PlayerObject.h"
#include "Log.h"
#include "Database/Database.h"
#include "GameServer.h"
#include "GameClient.h"
#include "Config.h"
#include <boost/algorithm/string.hpp>
using boost::iequals;
void PlayerObject::RPC_NullHandle( ByteBuffer &srcCmd )
{
return;
}
void PlayerObject::RPC_HandleReadyForSpawn( ByteBuffer &srcCmd )
{
if (!m_spawnedInWorld)
{
this->SpawnSelf();
}
}
void PlayerObject::ParseAdminCommand( string theCmd )
{
stringstream cmdStream;
cmdStream.str(theCmd);
string command;
cmdStream >> command;
if (cmdStream.fail())
return;
if (iequals(command, "teleportPlayer") || iequals(command, "bringPlayer"))
{
string playerName;
cmdStream >> playerName;
if (cmdStream.fail() || playerName.length() < 1)
return;
if (iequals(command, "teleportPlayer") && cmdStream.eof())
return;
PlayerObject* theTargetPlayer = NULL;
{
vector<uint32> allObjects = sObjMgr.getAllGOIds();
foreach(uint32 objId, allObjects)
{
PlayerObject* playerObj = NULL;
try
{
playerObj = sObjMgr.getGOPtr(objId);
}
catch (ObjectMgr::ObjectNotAvailable)
{
continue;
}
if (iequals(playerName,playerObj->getHandle()))
{
theTargetPlayer = playerObj;
break;
}
}
}
if (theTargetPlayer == NULL)
{
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("Player %1% is not online")%playerName).str()));
return;
}
LocationVector derp;
if (iequals(command, "teleportPlayer"))
{
double x,y,z;
cmdStream >> x;
if (cmdStream.eof() || cmdStream.fail())
return;
cmdStream >> y;
if (cmdStream.eof() || cmdStream.fail())
return;
cmdStream >> z;
if (cmdStream.fail())
return;
x*=100;
y*=100;
z*=100;
derp.ChangeCoords(x,y,z);
}
else if (iequals(command, "bringPlayer"))
{
LocationVector newPos = this->getPosition();
derp.ChangeCoords(newPos.x,newPos.y,newPos.z,newPos.getMxoRot());
}
theTargetPlayer->setPosition(derp);
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(sObjMgr.getGOId(theTargetPlayer)));
return;
}
else if (iequals(command, "teleportAll") || iequals(command, "bringAll"))
{
LocationVector derp;
if (iequals(command, "teleportAll"))
{
double x,y,z;
cmdStream >> x;
if (cmdStream.eof() || cmdStream.fail())
return;
cmdStream >> y;
if (cmdStream.eof() || cmdStream.fail())
return;
cmdStream >> z;
if (cmdStream.fail())
return;
x*=100;
y*=100;
z*=100;
derp.ChangeCoords(x,y,z);
}
else if (iequals(command, "bringAll"))
{
LocationVector newPos = this->getPosition();
derp.ChangeCoords(newPos.x,newPos.y,newPos.z,newPos.getMxoRot());
}
vector<uint32> allObjects = sObjMgr.getAllGOIds();
foreach(uint32 objId, allObjects)
{
PlayerObject* playerObj = NULL;
try
{
playerObj = sObjMgr.getGOPtr(objId);
}
catch (ObjectMgr::ObjectNotAvailable)
{
continue;
}
if (playerObj == NULL)
continue;
playerObj->setPosition(derp);
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(objId));
playerObj->PopulateWorld();
}
return;
}
else if (iequals(command, "set"))
{
string area;
cmdStream >> area;
if (cmdStream.fail())
return;
std::string s;
std::stringstream out;
out << int(m_district);
s = out.str();
double X,Y,Z;
X = this->getPosition().x;
Y = this->getPosition().y;
Z = this->getPosition().z;
string sql1 = (format("DELETE FROM `locations` Where `District` = '%1%' And `Command` = '%2%'") % s % area ).str();
string sql2 = (format("INSERT INTO `locations` SET `District` = '%1%', `Command` = '%2%', X = '%3%', Y = '%4%', Z = '%5%'") % s % area % X % Y % Z ).str();
if (sDatabase.Execute(sql1))
{
if (sDatabase.Execute(sql2))
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FFFF00}New location set, test it out.{/c}"));
}
else
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FF00FF}New location set, FAILED On INSERT.{/c}"));
}
}
else
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FF00FF}New location set, FAILED On DELETE.{/c}"));
}
return;
}
else if (iequals(command, "simTimeSet") || iequals(command, "simTimeInc"))
{
float newSimTime;
cmdStream >> newSimTime;
if (iequals(command,"simTimeSet"))
sGame.SetSimTime(newSimTime);
else
sGame.IncreaseSimTime(newSimTime);
sGame.AnnounceCommand(NULL,make_shared<BroadcastMsg>((format("Simtime set to %1%")%sGame.GetSimTime()).str()));
return;
}
else if (iequals(command, "setHL"))
{
string hardlineId;
cmdStream >> hardlineId;
if (cmdStream.fail())
return;
string hardlineName;
cmdStream >> hardlineName;
if (cmdStream.fail())
return;
std::string s;
std::stringstream out;
out << int(m_district);
s = out.str();
double X,Y,Z,O;
X = this->getPosition().x;
Y = this->getPosition().y;
Z = this->getPosition().z;
O = this->getPosition().rot;
string sql1 = (format("DELETE FROM `hardlines` WHERE `DistrictId` = '%1%' AND `HardlineId` = '%2%'") % s % hardlineId ).str();
string sql2 = (format("INSERT INTO `hardlines` SET `DistrictId` = '%1%', `HardlineId`='%2%',`X`='%3%',`Y`='%4%',`Z`= '%5%',`HardlineName`='%6%',`ROT`='%7%'") % s % hardlineId % X % Y % Z % hardlineName % O).str();
if (sDatabase.Execute(sql1))
{
if (sDatabase.Execute(sql2))
{
string msg1 = (format("{c:FFFF00}HardlineId:%1% Set to %2% at X:%3% Y:%4% Z:%5% O:%6%{/c}") % hardlineId % hardlineName % X % Y % Z % O ).str();
m_parent.QueueCommand(make_shared<SystemChatMsg>(msg1));
}
else
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FF00FF}New hardline set, FAILED On INSERT.{/c}"));
}
}
else
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FF00FF}New hardline set, FAILED On DELETE.{/c}"));
}
return;
}
else
{
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("Unrecognized server command %1%")%command).str()));
return;
}
}
void PlayerObject::ParsePlayerCommand( string theCmd )
{
stringstream cmdStream;
cmdStream.str(theCmd);
string command;
cmdStream >> command;
if (cmdStream.fail())
return;
using boost::erase_all;
if (iequals(command, "send") || iequals(command, "sendCmd"))
{
stringstream restOfStream;
restOfStream << cmdStream.rdbuf();
string hexStream = restOfStream.str();
erase_all(hexStream," ");
msgBaseClassPtr thePacket = make_shared<HexGenericMsg>(hexStream);
const ByteBuffer& dataBuf = thePacket->toBuf();
if (!dataBuf.count())
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("No bytes to send!"));
return;
}
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("Sending %1% bytes to you")%dataBuf.count()).str()));
if (iequals(command,"send"))
m_parent.QueueState(thePacket,true);
else
m_parent.QueueCommand(thePacket);
}
else if (iequals(command,"netstats"))
{
string theNetStats = m_parent.GetNetStats();
m_parent.QueueCommand(make_shared<SystemChatMsg>(theNetStats));
boost::replace_all(theNetStats,"\n"," ");
INFO_LOG(format("(%1%) %2%:%3% netstats: %4%")
% m_parent.Address()
% m_handle
% m_goId
% theNetStats );
}
else if (iequals(command, "gotoPos"))
{
double x,y,z;
cmdStream >> x;
if (cmdStream.eof() || cmdStream.fail())
return;
cmdStream >> y;
if (cmdStream.eof() || cmdStream.fail())
return;
cmdStream >> z;
if (cmdStream.fail())
return;
x*=100;
y*=100;
z*=100;
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FFFF00}Teleported...{/c}"));
LocationVector derp(x,y,z);
this->setPosition(derp);
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(m_goId));
return;
}
else if (iequals(command, "incX") || iequals(command, "incY") || iequals(command, "incZ"))
{
double incrementAmount=0;
if (cmdStream.eof())
incrementAmount = 1;
cmdStream >> incrementAmount;
if (cmdStream.fail())
incrementAmount = 1;
if (incrementAmount==0)
return;
incrementAmount*=100;
double newX,newY,newZ;
newX = this->getPosition().x;
newY = this->getPosition().y;
newZ = this->getPosition().z;
if (iequals(command, "incX"))
newX+=incrementAmount;
else if (iequals(command, "incY"))
newY+=incrementAmount;
else if (iequals(command,"incZ"))
newZ+=incrementAmount;
LocationVector newPos(newX,newY,newZ);
this->setPosition(newPos);
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(m_goId),true);
return;
}
else if (iequals(command, "goThru"))
{
double incrementAmount=0;
if (cmdStream.eof())
incrementAmount = 2;
cmdStream >> incrementAmount;
this->GoAhead(incrementAmount);
return;
}
else if (iequals(command, "random"))
{
//Random Object Id
uint32 randObjId = rand() % 0xFFFFFFFF;
uint16 randViewId = rand() % 0xFFFF;
//randObjId = 1310720002; //mara church middle door
sObjMgr.RandomObject(randObjId, &m_parent,this->getPosition().x, this->getPosition().y, this->getPosition().z, this->getPosition().rot );
m_parent.QueueState(make_shared<DoorAnimationMsg>(randObjId, randViewId, this->getPosition().x, this->getPosition().y, this->getPosition().z, this->getPosition().rot, 1));
return;
}
else if (iequals(command, "update"))
{
this->UpdateAppearance();
m_parent.QueueCommand(make_shared<SystemChatMsg>("Your appearance has been refreshed."));
return;
}
else if (iequals(command, "gotoPlayer"))
{
string playerName;
cmdStream >> playerName;
if (cmdStream.fail())
return;
PlayerObject* theTargetPlayer = NULL;
{
vector<uint32> allObjects = sObjMgr.getAllGOIds();
foreach(uint32 objId, allObjects)
{
PlayerObject* playerObj = NULL;
try
{
playerObj = sObjMgr.getGOPtr(objId);
}
catch (ObjectMgr::ObjectNotAvailable)
{
continue;
}
if (iequals(playerName,playerObj->getHandle()))
{
theTargetPlayer = playerObj;
break;
}
}
}
if (theTargetPlayer == NULL)
{
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("Player %1% is not online")%playerName).str()));
return;
}
this->setPosition(theTargetPlayer->getPosition());
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(m_goId));
return;
}
else if (iequals(command, "go"))
{
string area;
cmdStream >> area;
if (cmdStream.fail()) //Get list and whisper it but for now we just fail
return;
format sql = format("SELECT `X`,`Y`,`Z` FROM `locations` Where `District` = '%1%' And `Command` = '%2%' LIMIT 1") % int(getDistrict()) % area ;
scoped_ptr<QueryResult> result(sDatabase.Query(sql));
if (!result)
return;
else
{
Field *field = result->Fetch();
double newX = field[0].GetDouble();
double newY = field[1].GetDouble();
double newZ = field[2].GetDouble();
string message1 = (format("{c:00FF00}Welcome to %1%.{/c}") % area ).str();
m_parent.QueueCommand(make_shared<SystemChatMsg>(message1));
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FFFF00}You may have to wait a min or two for the client and server to sync if the area is complex...{/c}"));
LocationVector derp(newX,newY,newZ);
this->setPosition(derp);
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(m_goId));
return;
}
}
else
{
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("Unrecognized server command %1%")%command).str()));
return;
}
}
void PlayerObject::RPC_HandleChat( ByteBuffer &srcCmd )
{
uint16 stringLenPos = srcCmd.read<uint16>();
stringLenPos = swap16(stringLenPos);
if (stringLenPos != 8)
WARNING_LOG(format("(%1%) Chat packet stringLenPos not 8 but %2%, packet %3%") % m_parent.Address() % stringLenPos % Bin2Hex(srcCmd));
srcCmd.rpos(stringLenPos);
string theMessage = srcCmd.readString();
if (!theMessage.length())
return;
if (m_isAdmin && theMessage[0] == '!')
{
ParseAdminCommand(theMessage.substr(1));
return;
}
else if (theMessage[0] == '&')
{
ParsePlayerCommand(theMessage.substr(1));
return;
}
INFO_LOG(format("%1% says %2%") % m_handle % theMessage);
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("You said %1%") % theMessage).str()));
sGame.AnnounceCommand(&m_parent,make_shared<PlayerChatMsg>(m_handle,theMessage));
//m_parent.QueueCommand(make_shared<PlayerChatMsg>(m_handle,theMessage));
}
void PlayerObject::RPC_HandleWhisper( ByteBuffer &srcCmd )
{
uint8 thirdByte = srcCmd.read<uint8>();
if (thirdByte != 0)
WARNING_LOG(format("(%1%) Whisper packet third byte not 0 but %2%, packet %3%") % m_parent.Address() % uint32(thirdByte) % Bin2Hex(srcCmd));
uint16 messageLenPos = srcCmd.read<uint16>();
uint16 whisperCount = srcCmd.read<uint16>();
whisperCount = swap16(whisperCount); //big endian in packet
string theRecipient = srcCmd.readString();
string serverPrefix = sGame.GetChatPrefix() + string("+");
string::size_type prefixPos = theRecipient.find_first_of(serverPrefix);
if (prefixPos != string::npos)
theRecipient = theRecipient.substr(prefixPos+serverPrefix.length());
if (srcCmd.rpos() != messageLenPos)
WARNING_LOG(format("(%1%) Whisper packet size byte mismatch, packet %2%") % m_parent.Address() % Bin2Hex(srcCmd));
string theMessage = srcCmd.readString();
bool sentProperly=false;
vector<uint32> objectLists = sObjMgr.getAllGOIds();
foreach (int currObj, objectLists)
{
PlayerObject* targetPlayer = NULL;
try
{
targetPlayer = sObjMgr.getGOPtr(currObj);
}
catch (ObjectMgr::ObjectNotAvailable)
{
continue;
}
if (targetPlayer == NULL)
continue;
if (iequals(targetPlayer->getHandle(),theRecipient))
{
targetPlayer->getClient().QueueCommand(make_shared<WhisperMsg>(m_handle,theMessage));
sentProperly=true;
}
}
if (sentProperly)
{
INFO_LOG(format("%1% whispered to %2%: %3%") % m_handle % theRecipient % theMessage);
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("You whispered %1% to %2%")%theMessage%theRecipient).str()));
}
else
{
INFO_LOG(format("%1% sent whisper to disconnected player %2%: %3%") % m_handle % theRecipient % theMessage);
m_parent.QueueCommand(make_shared<SystemChatMsg>((format("%1% is not online")%theRecipient).str()));
}
}
void PlayerObject::RPC_HandleStopAnimation( ByteBuffer &srcCmd )
{
m_currAnimation = 0;
sGame.AnnounceStateUpdate(NULL,make_shared<AnimationStateMsg>(m_goId));
}
void PlayerObject::RPC_HandleStartAnimtion( ByteBuffer &srcCmd )
{
uint8 newAnimation = srcCmd.read<uint8>();
m_currAnimation = newAnimation;
sGame.AnnounceStateUpdate(NULL,make_shared<AnimationStateMsg>(m_goId));
}
void PlayerObject::RPC_HandleChangeMood( ByteBuffer &srcCmd )
{
uint8 newMood = srcCmd.read<uint8>();
m_currMood = newMood;
sGame.AnnounceStateUpdate(NULL,make_shared<AnimationStateMsg>(m_goId));
return;
}
void PlayerObject::RPC_HandlePerformEmote( ByteBuffer &srcCmd )
{
uint32 emoteId = srcCmd.read<uint32>();
uint32 emoteTarget = srcCmd.read<uint32>();
m_emoteCounter++;
sGame.AnnounceStateUpdate(NULL,make_shared<EmoteMsg>(m_goId,emoteId,m_emoteCounter));
DEBUG_LOG(format("(%1%) %2%:%3% doing emote %4% on target %5% at coords %6%,%7%,%8%")
% m_parent.Address()
% m_handle
% m_goId
% Bin2Hex((const byte*)&emoteId,sizeof(emoteId),0)
% Bin2Hex((const byte*)&emoteTarget,sizeof(emoteTarget),0)
% m_pos.x % m_pos.y % m_pos.z );
}
void PlayerObject::RPC_HandleDynamicObjInteraction( ByteBuffer &srcCmd )
{
uint16 viewId = srcCmd.read<uint16>();
uint16 objType = srcCmd.read<uint16>();
uint16 interaction = srcCmd.read<uint16>();
format debugStr =
format("(%s) %s:%d interacting with dynamic view id 0x%04x object type 0x%04x interaction %d")
% m_parent.Address()
% m_handle
% m_goId
% viewId
% objType
% int(interaction);
INFO_LOG( debugStr );
m_parent.QueueCommand(make_shared<SystemChatMsg>(debugStr.str()));
}
void PlayerObject::RPC_HandleStaticObjInteraction( ByteBuffer &srcCmd )
{
uint32 staticObjId = srcCmd.read<uint32>();
uint16 interaction = srcCmd.read<uint16>();
format debugStr =
format("(%s) %s:%d interacting with object id 0x%08x interaction %d")
% m_parent.Address()
% m_handle
% m_goId
% staticObjId
% int(interaction);
INFO_LOG( debugStr );
m_parent.QueueCommand(make_shared<SystemChatMsg>(debugStr.str()));
if (interaction == 0x03) //open door
{
LocationVector loc = this->getPosition();
scoped_ptr<QueryResult> resultDoorExists(sDatabase.Query(format("SELECT * FROM `doors` WHERE `DistrictId`='%1%' And `DoorId`='%2%' Limit 1") % (int)getDistrict() % staticObjId));
if (resultDoorExists == NULL)
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FFFF00}You are using a door not in the database yet, lets add it{/c}"));
format sqlDoorInsert =
format("INSERT INTO `doors` SET `DistrictId` = '%1%', `DoorId` = '%2%', X = '%3%', Y = '%4%', Z = '%5%', ROT = '%6%', FirstUser = '%7%'")
% (int)m_district
% staticObjId
% loc.x % loc.y % loc.z % loc.rot
% this->getHandle();
if (sDatabase.Execute(sqlDoorInsert))
{
format msg1 =
format("{c:00FF00}Door:0x%08x in District %d Set to Location X:%f Y:%f Z:%f O:%f{/c}")
% staticObjId
% (int)m_district
% loc.x % loc.y % loc.z % loc.rot;
m_parent.QueueCommand(make_shared<SystemChatMsg>(msg1.str()));
}
}
sObjMgr.OpenDoor(staticObjId, &m_parent);
//sGame.AnnounceStateUpdate(NULL,make_shared<DeleteDoorMsg>(staticObjId));
//sGame.AnnounceStateUpdate(NULL,make_shared<DeleteDoorMsg>(staticObjId));
//uint16 viewId = m_goId;// sObjMgr.getViewForGO(&m_parent,staticObjId);
//sGame.AnnounceStateUpdate(&m_parent,make_shared<DoorAnimationMsg>(staticObjId, viewId));
this->GoAhead(1);
return;
}
}
void PlayerObject::RPC_HandleJump( ByteBuffer &srcCmd )
{
LocationVector endPos;
if (endPos.fromDoubleBuf(srcCmd) == false)
{
WARNING_LOG(format("(%1%) %2%:%3% jump packet doesn't have endPos: %4%")
% m_parent.Address()
% m_handle
% m_goId
% Bin2Hex(srcCmd) );
return;
}
vector<byte> extraData(0x0B);
srcCmd.read(extraData);
uint32 theTimeStamp = srcCmd.read<uint32>();
/* DEBUG_LOG(format("(%1%) %2%:%3% jumping to %4%,%5%,%6% extra data %7% timestamp %8%")
% m_parent.Address()
% m_handle
% m_goId
% endPos.x % endPos.y % endPos.z
% Bin2Hex(&extraData[0],extraData.size())
% theTimeStamp );*/
this->setPosition(endPos);
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(m_goId));
}
void PlayerObject::RPC_HandleRegionLoadedNotification( ByteBuffer &srcCmd )
{
vector<byte> fourBytes(4);
srcCmd.read(fourBytes);
LocationVector loc;
if (!loc.fromFloatBuf(srcCmd))
throw ByteBuffer::out_of_range();
/* DEBUG_LOG(format("(%1%) %2%:%3% loaded region X:%4% Y:%5% Z:%6% extra: %7%")
% m_parent.Address()
% m_handle
% m_goId
% loc.x % loc.y % loc.z
% Bin2Hex(fourBytes));
*/
}
void PlayerObject::RPC_HandleReadyForWorldChange( ByteBuffer &srcCmd )
{
uint32 shouldBeZero = srcCmd.read<uint32>();
if (shouldBeZero != 0)
DEBUG_LOG(format("ReadyForWorldChange uint32 is %1%")%shouldBeZero);
m_district = 0x03;
InitializeWorld();
SpawnSelf();
}
void PlayerObject::RPC_HandleWho( ByteBuffer &srcCmd )
{
stringstream playerList;
vector<uint32> objects = sObjMgr.getAllGOIds();
playerList << "Players(" << objects.size() << ")";
playerList << " [ ";
foreach (uint32 objId, objects)
{
PlayerObject* pObj = NULL;
try
{
pObj = sObjMgr.getGOPtr(objId);
}
catch (ObjectMgr::ObjectNotAvailable)
{
continue;
}
if (pObj->getDistrict() == this->getDistrict())
{
playerList << pObj->getHandle() << " ";
}
}
playerList << "]";
m_parent.QueueCommand(make_shared<WhisperMsg>("PlayersInYourDistrict",playerList.str()));
}
void PlayerObject::RPC_HandleWhereAmI( ByteBuffer &srcCmd )
{
LocationVector clientSidePos;
if (clientSidePos.fromFloatBuf(srcCmd) == false)
throw ByteBuffer::out_of_range();
bool byte1Valid = false;
bool byte2Valid = false;
bool byte3Valid = false;
uint8 byte1,byte2,byte3;
if (srcCmd.remaining() >= sizeof(byte1))
{
byte1Valid=true;
srcCmd >> byte1;
}
if (srcCmd.remaining() >= sizeof(byte2))
{
byte2Valid=true;
srcCmd >> byte2;
}
if (srcCmd.remaining() >= sizeof(byte3))
{
byte3Valid=true;
srcCmd >> byte3;
}
INFO_LOG(format("(%1%) %2%:%3% requesting whereami clientPos %4%,%5%,%6% %7%:%8% %9%:%10% %11%:%12%")
% m_parent.Address()
% m_handle
% m_goId
% clientSidePos.x % clientSidePos.y % clientSidePos.z
% byte1Valid % uint32(byte1)
% byte2Valid % uint32(byte2)
% byte3Valid % uint32(byte3) );
m_parent.QueueCommand(make_shared<WhereAmIResponse>(m_pos));
//m_parent.QueueCommand(make_shared<HexGenericMsg>("8107"));
}
void PlayerObject::RPC_HandleGetPlayerDetails( ByteBuffer &srcCmd )
{
uint32 zeroInt = srcCmd.read<uint32>();
if (zeroInt != 0)
WARNING_LOG(format("Get player details zero int is %1%") % zeroInt );
uint16 playerNameStrLenPos = srcCmd.read<uint16>();
if (playerNameStrLenPos != srcCmd.rpos())
{
WARNING_LOG(format("Get player details strlenpos not %1% but %2%") % (int)srcCmd.rpos() % playerNameStrLenPos );
return;
}
srcCmd.rpos(playerNameStrLenPos);
string thePlayerName = srcCmd.readString();
vector<uint32> objectList = sObjMgr.getAllGOIds();
foreach(uint32 objId, objectList)
{
PlayerObject* targetPlayer = NULL;
try
{
targetPlayer = sObjMgr.getGOPtr(objId);
}
catch (ObjectMgr::ObjectNotAvailable)
{
continue;
}
if (targetPlayer == NULL)
continue;
if (targetPlayer->getHandle() == thePlayerName)
{
m_parent.QueueCommand(make_shared<PlayerDetailsMsg>(targetPlayer));
m_parent.QueueCommand(make_shared<PlayerBackgroundMsg>(targetPlayer->getBackground()));
break;
}
}
}
void PlayerObject::RPC_HandleGetBackground( ByteBuffer &srcCmd )
{
m_parent.QueueCommand(make_shared<BackgroundResponseMsg>(this->getBackground()));
}
void PlayerObject::RPC_HandleSetBackground( ByteBuffer &srcCmd )
{
uint16 backgroundStrLenPos = srcCmd.read<uint16>();
srcCmd.rpos(backgroundStrLenPos);
string theNewBackground = srcCmd.readString();
bool success = this->setBackground(theNewBackground);
if (success)
{
INFO_LOG(format("(%1%) %2%:%3% changed background to |%4%|")
% m_parent.Address()
% m_handle
% m_goId
% this->getBackground() );
}
else
{
WARNING_LOG(format("(%1%) %2%:%3% background sql query update failed")
% m_parent.Address()
% m_handle
% m_goId );
}
}
void PlayerObject::RPC_HandleHardlineTeleport( ByteBuffer &srcCmd )
{
uint8 hardlineYouAreUsing;
uint8 districtYouAreIn;
uint8 hardlineLocation;
uint8 hardlineDistrict;
//Get hardlineYouAreUsing
srcCmd >> hardlineYouAreUsing;
srcCmd.rpos(6);
//Get District you are currently in
srcCmd >> districtYouAreIn;
srcCmd.rpos(10);
//Get Hardline location
srcCmd >> hardlineLocation;
srcCmd.rpos(14);
//Get Hardline District
srcCmd >> hardlineDistrict;
format debugMsg =
format("You want to go to Hardline:%1% District:%2% From District:%3% Hardline:%4%")
% (int)hardlineLocation
% (int)hardlineDistrict
% (int)districtYouAreIn
% (int)hardlineYouAreUsing;
m_parent.QueueCommand(make_shared<SystemChatMsg>(debugMsg.str()));
//See if we need to add this HL to the DB
LocationVector loc = this->getPosition();
format sqlHLExists =
format("SELECT * FROM `hardlines` WHERE `DistrictId`='%1%' AND `HardlineId`='%2%' LIMIT 1")
% (int)districtYouAreIn
% (int)hardlineYouAreUsing;
scoped_ptr<QueryResult> resultHLExists(sDatabase.Query(sqlHLExists));
if (resultHLExists == NULL)
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FFFF00}You are at a hardline not in the database yet, lets add it so all can use it :){/c}"));
format sqlHLInsert =
format("INSERT INTO `hardlines` SET `DistrictId` = '%1%', `HardlineId` = '%2%', X = '%3%', Y = '%4%', Z = '%5%', ROT = '%6%', HardlineName = 'Tagged By %7%'")
% (int)districtYouAreIn
% (int)hardlineYouAreUsing
% loc.x % loc.y % loc.z % loc.rot
% this->getHandle();
if (sDatabase.Execute(sqlHLInsert))
{
format msg1 =
format("{c:00FF00}HardlineId:%1% in District %7% Set to Tagged By %2% at X:%3% Y:%4% Z:%5% O:%6%{/c}")
% (int)hardlineYouAreUsing
% this->getHandle()
% loc.x % loc.y % loc.z % loc.rot
% (int)districtYouAreIn;
m_parent.QueueCommand(make_shared<SystemChatMsg>(msg1.str()));
}
else
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FF00FF}New hardline set, FAILED On INSERT.{/c}"));
}
}
format sql =
format("SELECT `X`,`Y`,`Z`, `ROT`, `HardlineName` FROM `hardlines` Where `DistrictId` = '%1%' And `HardlineId` = '%2%' LIMIT 1")
% (int)hardlineDistrict
% (int)hardlineLocation;
scoped_ptr<QueryResult> result(sDatabase.Query(sql));
if (result == NULL)
{
m_parent.QueueCommand(make_shared<SystemChatMsg>("{c:FF0000}The hardline you selected is not in the database yet, go tag it...{/c}"));
}
else
{
Field *field = result->Fetch();
double newX = field[0].GetDouble();
double newY = field[1].GetDouble();
double newZ = field[2].GetDouble();
double newRot = field[3].GetDouble();
string newlocationName = field[4].GetString();
format message1 = format("{c:00FFFF}Welcome to %1%.{/c}") % newlocationName;
m_parent.QueueCommand(make_shared<SystemChatMsg>(message1.str()));
LocationVector newLoc(newX, newY, newZ);
newLoc.rot = newRot;
this->setPosition(newLoc);
sGame.AnnounceStateUpdate(NULL,make_shared<PositionStateMsg>(m_goId));
}
}
void PlayerObject::RPC_HandleObjectSelected( ByteBuffer &srcCmd )
{
uint16 viewId = srcCmd.read<uint16>();
uint16 objType = srcCmd.read<uint16>();
if (viewId || objType)
{
format msg =
format("(%s) %s:%d selected dynamic object view id %04x objType %04x")
% m_parent.Address() % m_handle % m_goId
% viewId % objType;
DEBUG_LOG(msg);
m_parent.QueueCommand(make_shared<SystemChatMsg>(msg.str()));
}
}
void PlayerObject::RPC_HandleJackoutRequest( ByteBuffer &srcCmd )
{
ByteBuffer extraData = ByteBuffer(&srcCmd.contents()[srcCmd.rpos()],srcCmd.remaining());
format msg =
format("(%s) %s:%d wants to jackout with extra data %s")
% m_parent.Address()
% m_handle
% m_goId
% Bin2Hex(extraData,0);
DEBUG_LOG(msg);
//effect
m_parent.QueueState(make_shared<JackoutEffectMsg>(m_goId));
//chat msg
m_parent.QueueCommand(make_shared<HexGenericMsg>("2E0700000000000000000000002300002E00000000000000000000000000000000000000"));
this->addEvent(EVENT_JACKOUT,boost::bind(&PlayerObject::jackoutEvent,this),10.0f); //schedule jackout in 10 seconds
}
void PlayerObject::jackoutEvent()
{
m_parent.QueueCommand(make_shared<HexGenericMsg>("80fd000000000000"));
m_parent.FlushQueue();
//hack, should see why client doesnt send jackout complete msg, instead of invalidating here
//m_parent.Invalidate();
}
void PlayerObject::RPC_HandleJackoutFinished( ByteBuffer &srcCmd )
{
//this doesn't get sent by client, even though it does on real server
ByteBuffer extraData = ByteBuffer(&srcCmd.contents()[srcCmd.rpos()],srcCmd.remaining());
format msg =
format("(%s) %s:%d jackout complete extra data %s")
% m_parent.Address()
% m_handle
% m_goId
% Bin2Hex(extraData,0);
DEBUG_LOG(msg);
m_parent.Invalidate();
}