Fixed player movement.

Fixed multinode taxi.
Removed some unhandled opcode spam.
This commit is contained in:
tomrus88 2009-08-09 18:08:14 +04:00
parent 6bf8eb346d
commit 1df1f7cff5
9 changed files with 142 additions and 30 deletions

View file

@ -110,7 +110,7 @@ bool Group::Create(const uint64 &guid, const char * name)
CharacterDatabase.PExecute("DELETE FROM groups WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid));
CharacterDatabase.PExecute("DELETE FROM group_member WHERE leaderGuid ='%u'", GUID_LOPART(m_leaderGuid));
CharacterDatabase.PExecute("INSERT INTO groups (leaderGuid,mainTank,mainAssistant,lootMethod,looterGuid,lootThreshold,icon1,icon2,icon3,icon4,icon5,icon6,icon7,icon8,isRaid,difficulty,raiddifficulty) "
"VALUES('%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u')",
"VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','" UI64FMTD "','%u','%u','%u')",
GUID_LOPART(m_leaderGuid), GUID_LOPART(m_mainTank), GUID_LOPART(m_mainAssistant), uint32(m_lootMethod),
GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6], m_targetIcons[7], isRaidGroup(), m_dungeonDifficulty, m_raidDifficulty);
}

View file

@ -1378,3 +1378,30 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data)
GetPlayer()->ApplyEnchantment(item, TEMP_ENCHANTMENT_SLOT, false);
item->ClearEnchantment(TEMP_ENCHANTMENT_SLOT);
}
void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data)
{
sLog.outDebug("WORLD: CMSG_ITEM_REFUND_INFO_REQUEST");
CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid;
recv_data >> guid; // item guid
Item *item = _player->GetItemByGuid(guid);
if(!item)
{
sLog.outDebug("Item refund: item not found!");
return;
}
if(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE))
{
sLog.outDebug("Item refund: item not refundable!");
return;
}
// refund system not implemented yet
}

View file

@ -109,8 +109,11 @@ enum ITEM_FLAGS
ITEM_FLAGS_OPENABLE = 0x00000004,
ITEM_FLAGS_WRAPPED = 0x00000008,
ITEM_FLAGS_BROKEN = 0x00000010, // appears red icon (like when item durability==0)
ITEM_FLAGS_TOTEM = 0x00000020, // ?
ITEM_FLAGS_USABLE = 0x00000040, // ?
ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper
ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not
ITEM_FLAGS_REFUNDABLE = 0x00001000, // item cost can be refunded within 2 hours after purchase
ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter
ITEM_FLAGS_PROSPECTABLE = 0x00040000,
ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000,
@ -118,6 +121,7 @@ enum ITEM_FLAGS
ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip
ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0
ITEM_FLAGS_BOA = 0x08000000, // bind on account (set in template for items that can binded in like way)
ITEM_FLAGS_ENCHANT_SCROLL = 0x10000000, // for enchant scrolls
ITEM_FLAGS_MILLABLE = 0x20000000
};

View file

@ -223,13 +223,19 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
return;
/* extract packet */
uint64 guid;
if(!recv_data.readPackGUID(guid))
return;
MovementInfo movementInfo;
movementInfo.guid = guid;
ReadMovementInfo(recv_data, &movementInfo);
/*----------------*/
if(recv_data.size() != recv_data.rpos())
{
sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos());
sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), opcode, recv_data.size() - recv_data.rpos());
KickPlayer();
return;
}
@ -289,17 +295,17 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
/*----------------------*/
/* process position-change */
recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2)
WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
data.append(mover->GetPackGUID()); // use mover guid
data.append(recv_data.contents(), recv_data.size());
WorldPacket data(opcode, recv_data.size());
movementInfo.time = getMSTime();
movementInfo.guid = mover->GetGUID();
WriteMovementInfo(&data, &movementInfo);
GetPlayer()->SendMessageToSet(&data, false);
if(plMover) // nothing is charmed, or player charmed
{
plMover->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
plMover->m_movementInfo = movementInfo;
plMover->UpdateFallInformationIfNeed(movementInfo, recv_data.GetOpcode());
plMover->UpdateFallInformationIfNeed(movementInfo, opcode);
if(plMover->isMovingOrTurning())
plMover->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
@ -344,26 +350,28 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode());
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4);
uint32 opcode = recv_data.GetOpcode();
sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
/* extract packet */
uint64 guid;
uint32 unk1;
float newspeed;
recv_data >> guid;
if(!recv_data.readPackGUID(guid))
return;
// now can skip not our packet
if(_player->GetGUID() != guid)
return;
// continue parse packet
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
recv_data >> unk1; // counter or moveEvent
MovementInfo movementInfo;
movementInfo.guid = guid;
ReadMovementInfo(recv_data, &movementInfo);
// recheck
@ -372,6 +380,13 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
recv_data >> newspeed;
/*----------------*/
if(recv_data.size() != recv_data.rpos())
{
sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), opcode, recv_data.size() - recv_data.rpos());
KickPlayer();
return;
}
// client ACK send one packet for mounted/run case and need skip all except last from its
// in other cases anti-cheat check can be fail in false case
UnitMoveType move_type;
@ -379,7 +394,6 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
uint16 opcode = recv_data.GetOpcode();
switch(opcode)
{
case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break;
@ -444,10 +458,10 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8);
uint64 old_mover_guid;
recv_data >> old_mover_guid;
if(!recv_data.readPackGUID(old_mover_guid))
return;
if(_player->m_mover->GetGUID() == old_mover_guid)
{
@ -456,7 +470,16 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
}
MovementInfo mi;
mi.guid = old_mover_guid;
ReadMovementInfo(recv_data, &mi);
if(recv_data.size() != recv_data.rpos())
{
sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos());
KickPlayer();
return;
}
_player->m_movementInfo = mi;
}
@ -470,8 +493,22 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
if(!vehicleGUID) // something wrong here...
return;
uint64 guid;
if(!recv_data.readPackGUID(guid))
return;
MovementInfo mi;
mi.guid = guid;
ReadMovementInfo(recv_data, &mi);
if(recv_data.size() != recv_data.rpos())
{
sLog.outError("MovementHandler: player %s (guid %d, account %u) sent a packet (opcode %u) that is " SIZEFMTD " bytes larger than it should be. Kicked as cheater.", _player->GetName(), _player->GetGUIDLow(), _player->GetSession()->GetAccountId(), recv_data.GetOpcode(), recv_data.size() - recv_data.rpos());
KickPlayer();
return;
}
_player->m_movementInfo = mi;
// using charm guid, because we don't have vehicle guid...

View file

@ -1229,7 +1229,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4B0*/ { "UMSG_UNKNOWN_1200", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4B1*/ { "UMSG_UNKNOWN_1201", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4B2*/ { "SMSG_UNKNOWN_1202", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4B3*/ { "CMSG_UNKNOWN_1203", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4B3*/ { "CMSG_ITEM_REFUND_INFO_REQUEST", STATUS_LOGGEDIN, &WorldSession::HandleItemRefundInfoRequest },
/*0x4B4*/ { "CMSG_UNKNOWN_1204", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4B5*/ { "SMSG_UNKNOWN_1205", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4B6*/ { "CMSG_UNKNOWN_1206", STATUS_NEVER, &WorldSession::Handle_NULL },
@ -1257,9 +1257,9 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4CC*/ { "UMSG_UNKNOWN_1228", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4CD*/ { "SMSG_UNKNOWN_1229", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4CE*/ { "SMSG_UNKNOWN_1230", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4CF*/ { "UMSG_UNKNOWN_1231", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4CF*/ { "CMSG_UNKNOWN_1231_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4D0*/ { "SMSG_UNKNOWN_1232", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4D1*/ { "UMSG_UNKNOWN_1233", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4D1*/ { "CMSG_UNKNOWN_1233_ACK", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x4D2*/ { "SMSG_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4D3*/ { "SMSG_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x4D4*/ { "SMSG_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide },

View file

@ -1237,7 +1237,7 @@ enum Opcodes
UMSG_UNKNOWN_1200 = 0x4B0, // not found
UMSG_UNKNOWN_1201 = 0x4B1, // not found
SMSG_UNKNOWN_1202 = 0x4B2, // refund something
CMSG_UNKNOWN_1203 = 0x4B3, // refund request?
CMSG_ITEM_REFUND_INFO_REQUEST = 0x4B3, // refund request?
CMSG_UNKNOWN_1204 = 0x4B4, // lua: ContainerRefundItemPurchase
SMSG_UNKNOWN_1205 = 0x4B5, // refund something
CMSG_UNKNOWN_1206 = 0x4B6, // CMSG, uint32
@ -1265,9 +1265,9 @@ enum Opcodes
UMSG_UNKNOWN_1228 = 0x4CC, // not found 3.2
SMSG_UNKNOWN_1229 = 0x4CD, // SMSG, any opcode?
SMSG_UNKNOWN_1230 = 0x4CE, // SMSG, movement related
UMSG_UNKNOWN_1231 = 0x4CF, // not found 3.2
CMSG_UNKNOWN_1231_ACK = 0x4CF, // movement related
SMSG_UNKNOWN_1232 = 0x4D0, // SMSG, movement related
UMSG_UNKNOWN_1233 = 0x4D1, // not found 3.2
CMSG_UNKNOWN_1233_ACK = 0x4D1, // movement related
SMSG_UNKNOWN_1234 = 0x4D2, // SMSG, movement related
SMSG_UNKNOWN_1235 = 0x4D3, // SMSG, movement related
SMSG_UNKNOWN_1236 = 0x4D4, // SMSG, movement related

View file

@ -158,14 +158,14 @@ bool WorldSession::SendLearnNewTaxiNode( Creature* unit )
void WorldSession::HandleActivateTaxiExpressOpcode ( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8+4+4);
CHECK_PACKET_SIZE(recv_data,8+4);
sLog.outDebug( "WORLD: Received CMSG_ACTIVATETAXIEXPRESS" );
uint64 guid;
uint32 node_count, _totalcost;
uint32 node_count;
recv_data >> guid >> _totalcost >> node_count;
recv_data >> guid >> node_count;
Creature *npc = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER);
if (!npc)
@ -174,7 +174,7 @@ void WorldSession::HandleActivateTaxiExpressOpcode ( WorldPacket & recv_data )
return;
}
// recheck
CHECK_PACKET_SIZE(recv_data,8+4+4+node_count*4);
CHECK_PACKET_SIZE(recv_data,8+4+node_count*4);
std::vector<uint32> nodes;

View file

@ -629,9 +629,6 @@ void WorldSession::SaveTutorialsData()
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
{
if(!data.readPackGUID(mi->guid))
return;
CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4);
data >> mi->flags;
data >> mi->unk1;
@ -680,6 +677,51 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
}
}
void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
{
data->appendPackGUID(mi->guid);
*data << mi->flags;
*data << mi->unk1;
*data << mi->time;
*data << mi->x;
*data << mi->y;
*data << mi->z;
*data << mi->o;
if(mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
{
data->appendPackGUID(mi->t_guid);
*data << mi->t_x;
*data << mi->t_y;
*data << mi->t_z;
*data << mi->t_o;
*data << mi->t_time;
*data << mi->t_seat;
}
if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))) || (mi->unk1 & 0x20))
{
*data << mi->s_pitch;
}
*data << mi->fallTime;
if(mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
{
*data << mi->j_unk;
*data << mi->j_sinAngle;
*data << mi->j_cosAngle;
*data << mi->j_xyspeed;
}
if(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE))
{
*data << mi->u_unk1;
}
}
void WorldSession::ReadAddonsInfo(WorldPacket &data)
{
if (data.rpos() + 4 > data.size())

View file

@ -110,6 +110,7 @@ class MANGOS_DLL_SPEC WorldSession
void SendAddonsInfo();
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi);
void WriteMovementInfo(WorldPacket *data, MovementInfo *mi);
void SendPacket(WorldPacket const* packet);
void SendNotification(const char *format,...) ATTR_PRINTF(2,3);
@ -667,6 +668,7 @@ class MANGOS_DLL_SPEC WorldSession
void HandleSocketOpcode(WorldPacket& recv_data);
void HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data);
void HandleItemRefundInfoRequest(WorldPacket& recv_data);
void HandleChannelVoiceOnOpcode(WorldPacket & recv_data);
void HandleVoiceSessionEnableOpcode(WorldPacket& recv_data);