Core/Items: Some work on hotfixes and SMSG_DB_REPLY

This commit is contained in:
Shauren
2012-01-31 14:02:59 +01:00
parent 37b66384f3
commit 1b676b1ccf
11 changed files with 328 additions and 166 deletions

View File

@@ -0,0 +1,42 @@
DROP TABLE IF EXISTS `hotfix_data`;
CREATE TABLE `hotfix_data` (
`entry` int(10) unsigned NOT NULL,
`type` int(10) unsigned NOT NULL DEFAULT '0',
`unk` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`entry`,`type`,`unk`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `hotfix_data`
--
INSERT INTO `hotfix_data` VALUES
(6948,1344507586,1322022853),
(44623,1344507586,1322022844),
(44625,1344507586,1322022844),
(44626,1344507586,1322022844),
(44632,1344507586,1322022844),
(44812,1344507586,1322022840),
(44834,1344507586,1322022840),
(44835,1344507586,1322022840),
(44836,1344507586,1322022840),
(44837,1344507586,1322022840),
(44838,1344507586,1322022840),
(44839,1344507586,1322022840),
(44840,1344507586,1322022840),
(44844,1344507586,1322022840),
(44853,1344507586,1322022840),
(44854,1344507586,1322022840),
(44855,1344507586,1322022840),
(44856,1344507586,1322022840),
(46784,1344507586,1322022840),
(46793,1344507586,1322022840),
(46796,1344507586,1322022840),
(46797,1344507586,1322022840),
(46887,1344507586,1322022840),
(46888,1344507586,1322022840),
(64488,1344507586,1322022853),
(69847,1344507586,1322022843),
(69847,1344507586,1322022846),
(72068,1344507586,1322022843),
(72068,1344507586,1322022846);

View File

@@ -9034,6 +9034,41 @@ void ObjectMgr::LoadFactionChangeReputations()
sLog->outString();
}
void ObjectMgr::LoadHotfixData()
{
uint32 oldMSTime = getMSTime();
QueryResult result = WorldDatabase.Query("SELECT entry, type, unk FROM hotfix_data");
if (!result)
{
sLog->outString(">> Loaded 0 hotfix info entries. DB table `hotfix_data` is empty.");
sLog->outString();
return;
}
uint32 count = 0;
_hotfixData.reserve(result->GetRowCount());
do
{
Field* fields = result->Fetch();
HotfixInfo info;
info.Entry = fields[0].GetUInt32();
info.Type = fields[1].GetUInt32();
info.Unk = fields[2].GetUInt32();
_hotfixData.push_back(info);
++count;
}
while (result->NextRow());
sLog->outString(">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry)
{
GameObjectTemplateContainer::const_iterator itr = GameObjectTemplateStore.find(entry);

View File

@@ -586,6 +586,15 @@ struct DungeonEncounter
typedef std::list<DungeonEncounter const*> DungeonEncounterList;
typedef UNORDERED_MAP<uint32, DungeonEncounterList> DungeonEncounterMap;
struct HotfixInfo
{
uint32 Type;
uint32 Unk;
uint32 Entry;
};
typedef std::vector<HotfixInfo> HotfixData;
class PlayerDumpReader;
class ObjectMgr
@@ -1196,6 +1205,9 @@ class ObjectMgr
void LoadFactionChangeSpells();
void LoadFactionChangeReputations();
void LoadHotfixData();
HotfixData const& GetHotfixData() const { return _hotfixData; }
private:
// first free id for selected id type
uint32 m_auctionid;
@@ -1349,6 +1361,8 @@ class ObjectMgr
GO_TO_CREATURE, // GO is dependant on creature
};
HotfixData _hotfixData;
};
#define sObjectMgr ACE_Singleton<ObjectMgr, ACE_Null_Mutex>::instance()

View File

@@ -971,6 +971,17 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
data << uint32(0);
SendPacket(&data);
data.Initialize(SMSG_HOTFIX_INFO);
HotfixData const& hotfix = sObjectMgr->GetHotfixData();
data << uint32(hotfix.size());
for (uint32 i = 0; i < hotfix.size(); ++i)
{
data << uint32(hotfix[i].Type);
data << uint32(hotfix[i].Unk);
data << uint32(hotfix[i].Entry);
}
SendPacket(&data);
pCurrChar->SendInitialPacketsBeforeAddToMap();
//Show cinematic at the first time that player login

View File

@@ -277,157 +277,165 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket & recv_data)
_player->DestroyItem(bag, slot, true);
}
// Only _static_ data send in this packet !!!
void WorldSession::HandleItemQuerySingleOpcode(WorldPacket & recv_data)
void WorldSession::SendItemDb2Reply(uint32 entry)
{
uint32 count, type;
recv_data >> count >> type;
if (type != DB2_REPLY_SPARSE && type != DB2_REPLY_ITEM)
return;
for (uint32 i = 0; i < count; ++i)
WorldPacket data(SMSG_DB_REPLY, 44);
data << uint32(DB2_REPLY_ITEM);
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(entry);
if (!proto)
{
uint32 item;
recv_data >> item;
recv_data.read_skip<uint64>();
WorldPacket data2(SMSG_DB_REPLY, 700);
ByteBuffer data;
data2 << uint32(type);
data2 << uint32(item);
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
if (proto)
{
data << uint32(item);
if (type == DB2_REPLY_ITEM)
{
data << uint32(proto->Class);
data << uint32(proto->SubClass);
data << int32(proto->Unk0);
data << uint32(proto->Material);
data << uint32(proto->DisplayInfoID);
data << uint32(proto->InventoryType);
data << uint32(proto->Sheath);
}
else if (type == DB2_REPLY_SPARSE)
{
data << uint32(proto->Quality);
data << uint32(proto->Flags);
data << uint32(proto->Flags2);
data << int32(proto->BuyPrice);
data << uint32(proto->SellPrice);
data << uint32(proto->InventoryType);
data << int32(proto->AllowableClass);
data << int32(proto->AllowableRace);
data << uint32(proto->ItemLevel);
data << uint32(proto->RequiredLevel);
data << uint32(proto->RequiredSkill);
data << uint32(proto->RequiredSkillRank);
data << uint32(proto->RequiredSpell);
data << uint32(proto->RequiredHonorRank);
data << uint32(proto->RequiredCityRank);
data << uint32(proto->RequiredReputationFaction);
data << uint32(proto->RequiredReputationRank);
data << int32(proto->MaxCount);
data << int32(proto->Stackable);
data << uint32(proto->ContainerSlots);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
data << uint32(proto->ItemStat[x].ItemStatType);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
data << int32(proto->ItemStat[x].ItemStatValue);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
data << int32(proto->ItemStat[x].ItemStatUnk1);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
data << int32(proto->ItemStat[x].ItemStatUnk2);
data << uint32(proto->ScalingStatDistribution);
data << uint32(proto->DamageType);
data << uint32(proto->Delay);
data << float(proto->RangedModRange);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
data << int32(proto->Spells[x].SpellId);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
data << uint32(proto->Spells[x].SpellTrigger);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
data << int32(proto->Spells[x].SpellCharges);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
data << int32(proto->Spells[x].SpellCooldown);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
data << uint32(proto->Spells[x].SpellCategory);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
data << int32(proto->Spells[x].SpellCategoryCooldown);
data << uint32(proto->Bonding);
// item name
std::string name = proto->Name1;
data << uint16(name.length() + 1);
data << name;
for (uint32 i = 0; i < 3; ++i) // other 3 names
data << uint16(0);
std::string desc = proto->Description;
data << uint16(desc.length() + 1);
data << desc;
data << uint32(proto->PageText);
data << uint32(proto->LanguageID);
data << uint32(proto->PageMaterial);
data << uint32(proto->StartQuest);
data << uint32(proto->LockID);
data << int32(proto->Material);
data << uint32(proto->Sheath);
data << int32(proto->RandomProperty);
data << int32(proto->RandomSuffix);
data << uint32(proto->ItemSet);
data << uint32(proto->MaxDurability);
data << uint32(proto->Area);
data << uint32(proto->Map);
data << uint32(proto->BagFamily);
data << uint32(proto->TotemCategory);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x)
data << uint32(proto->Socket[x].Color);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x)
data << uint32(proto->Socket[x].Content);
data << uint32(proto->socketBonus);
data << uint32(proto->GemProperties);
data << float(proto->ArmorDamageModifier);
data << int32(proto->Duration);
data << uint32(proto->ItemLimitCategory);
data << uint32(proto->HolidayId);
data << float(proto->StatScalingFactor); // StatScalingFactor
data << uint32(proto->Field130); // archaeology unk
data << uint32(proto->Field131); // archaeology findinds count
}
else
{
data << uint32(item | 0x80000000); // sometimes with | 0x80000000
data << uint32(0);
}
data2 << uint32(data.size());
data2.append(data);
}
data2 << uint32(type);
_player->GetSession()->SendPacket(&data2);
data << uint32(-1); // entry
data << uint32(1322512289); // some kind of flags
data << uint32(0); // size of next block
return;
}
data << uint32(entry);
data << uint32(1322512290); // flags
ByteBuffer buff;
buff << uint32(entry);
buff << uint32(proto->Class);
buff << uint32(proto->SubClass);
buff << int32(proto->Unk0);
buff << uint32(proto->Material);
buff << uint32(proto->DisplayInfoID);
buff << uint32(proto->InventoryType);
buff << uint32(proto->Sheath);
data << uint32(buff.size());
data.append(buff);
SendPacket(&data);
}
void WorldSession::SendItemSparseDb2Reply(uint32 entry)
{
WorldPacket data(SMSG_DB_REPLY, 526);
data << uint32(DB2_REPLY_SPARSE);
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(entry);
if (!proto)
{
data << uint32(-1); // entry
data << uint32(1322512289); // some kind of flags
data << uint32(0); // size of next block
return;
}
data << uint32(entry);
data << uint32(1322512290); // flags
ByteBuffer buff;
buff << uint32(entry);
buff << uint32(proto->Quality);
buff << uint32(proto->Flags);
buff << uint32(proto->Flags2);
buff << int32(proto->BuyPrice);
buff << uint32(proto->SellPrice);
buff << uint32(proto->InventoryType);
buff << int32(proto->AllowableClass);
buff << int32(proto->AllowableRace);
buff << uint32(proto->ItemLevel);
buff << uint32(proto->RequiredLevel);
buff << uint32(proto->RequiredSkill);
buff << uint32(proto->RequiredSkillRank);
buff << uint32(proto->RequiredSpell);
buff << uint32(proto->RequiredHonorRank);
buff << uint32(proto->RequiredCityRank);
buff << uint32(proto->RequiredReputationFaction);
buff << uint32(proto->RequiredReputationRank);
buff << int32(proto->MaxCount);
buff << int32(proto->Stackable);
buff << uint32(proto->ContainerSlots);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
buff << uint32(proto->ItemStat[x].ItemStatType);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
buff << int32(proto->ItemStat[x].ItemStatValue);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
buff << int32(proto->ItemStat[x].ItemStatUnk1);
for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
buff << int32(proto->ItemStat[x].ItemStatUnk2);
buff << uint32(proto->ScalingStatDistribution);
buff << uint32(proto->DamageType);
buff << uint32(proto->Delay);
buff << float(proto->RangedModRange);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
buff << int32(proto->Spells[x].SpellId);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
buff << uint32(proto->Spells[x].SpellTrigger);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
buff << int32(proto->Spells[x].SpellCharges);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
buff << int32(proto->Spells[x].SpellCooldown);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
buff << uint32(proto->Spells[x].SpellCategory);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
buff << int32(proto->Spells[x].SpellCategoryCooldown);
buff << uint32(proto->Bonding);
// item name
std::string name = proto->Name1;
buff << uint16(name.length());
if (name.length())
buff << name;
for (uint32 i = 0; i < 3; ++i) // other 3 names
buff << uint16(0);
std::string desc = proto->Description;
buff << uint16(desc.length());
if (desc.length())
buff << desc;
buff << uint32(proto->PageText);
buff << uint32(proto->LanguageID);
buff << uint32(proto->PageMaterial);
buff << uint32(proto->StartQuest);
buff << uint32(proto->LockID);
buff << int32(proto->Material);
buff << uint32(proto->Sheath);
buff << int32(proto->RandomProperty);
buff << int32(proto->RandomSuffix);
buff << uint32(proto->ItemSet);
buff << uint32(proto->MaxDurability);
buff << uint32(proto->Area);
buff << uint32(proto->Map);
buff << uint32(proto->BagFamily);
buff << uint32(proto->TotemCategory);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x)
buff << uint32(proto->Socket[x].Color);
for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x)
buff << uint32(proto->Socket[x].Content);
buff << uint32(proto->socketBonus);
buff << uint32(proto->GemProperties);
buff << float(proto->ArmorDamageModifier);
buff << int32(proto->Duration);
buff << uint32(proto->ItemLimitCategory);
buff << uint32(proto->HolidayId);
buff << float(proto->StatScalingFactor); // StatScalingFactor
buff << uint32(proto->Field130); // archaeology unk
buff << uint32(proto->Field131); // archaeology findinds count
data << uint32(buff.size());
data.append(buff);
SendPacket(&data);
}
void WorldSession::HandleReadItem(WorldPacket & recv_data)
@@ -731,7 +739,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
vendor->StopMoving();
uint8* bytes = (uint8*)&vendorGuid;
VendorItemData const* items = vendor->GetVendorItems();
if (!items)
{
@@ -744,13 +752,13 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
data.WriteByteMask(bytes[0]);
data.WriteByteMask(bytes[7]);
data.WriteByteMask(bytes[4]);
data.WriteByteSeq(bytes[2]);
data.WriteByteSeq(bytes[3]);
data << uint8(0); // count == 0, next will be error code
data << uint8(0xA0); // Only seen 0xA0 (160) so far ( should we send 0 here?)
data.WriteByteSeq(bytes[4]);
data.WriteByteSeq(bytes[7]);
data.WriteByteSeq(bytes[6]);
@@ -760,9 +768,9 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
uint8 itemCount = items->GetItemCount();
uint8 count = 0;
WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
data.WriteByteMask(bytes[5]);
data.WriteByteMask(bytes[6]);
data.WriteByteMask(bytes[1]);
@@ -771,23 +779,23 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
data.WriteByteMask(bytes[0]);
data.WriteByteMask(bytes[7]);
data.WriteByteMask(bytes[4]);
data.WriteByteSeq(bytes[2]);
data.WriteByteSeq(bytes[3]);
size_t countPos = data.wpos();
data << uint32(count);
data.WriteByteSeq(bytes[5]);
data.WriteByteSeq(bytes[0]);
data.WriteByteSeq(bytes[1]);
data << uint8(0xA0); // Only seen 0xA0 (160) so far
data.WriteByteSeq(bytes[4]);
data.WriteByteSeq(bytes[7]);
data.WriteByteSeq(bytes[6]);
float discountMod = _player->GetReputationPriceDiscount(vendor);

View File

@@ -1748,3 +1748,48 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket)
_player->SetPendingBind(0, 0);
}
void WorldSession::HandleRequestHotfix(WorldPacket& recvPacket)
{
uint32 type, count;
recvPacket >> type >> count;
ByteBuffer* guidBytes = new ByteBuffer[count];
BitStream* mask = new BitStream[count];
for (uint32 i = 0; i < count; ++i)
{
mask[i] = recvPacket.ReadBitStream(8);
guidBytes[i].resize(8); // damn c++ not allowing to use non-default constructor with new[]
}
uint32 entry;
uint64 guid;
for (uint32 i = 0; i < count; ++i)
{
recvPacket >> entry;
recvPacket.ReadXorByte(mask[i][7], guidBytes[i][2]);
recvPacket.ReadXorByte(mask[i][4], guidBytes[i][6]);
recvPacket.ReadXorByte(mask[i][1], guidBytes[i][3]);
recvPacket.ReadXorByte(mask[i][2], guidBytes[i][0]);
recvPacket.ReadXorByte(mask[i][3], guidBytes[i][5]);
recvPacket.ReadXorByte(mask[i][0], guidBytes[i][7]);
recvPacket.ReadXorByte(mask[i][6], guidBytes[i][1]);
recvPacket.ReadXorByte(mask[i][5], guidBytes[i][4]);
guid = BitConverter::ToUInt64(guidBytes[i]);
switch (type)
{
case DB2_REPLY_ITEM:
SendItemDb2Reply(entry);
break;
case DB2_REPLY_SPARSE:
SendItemSparseDb2Reply(entry);
break;
default:
break;
}
}
delete[] guidBytes;
delete[] mask;
}

View File

@@ -129,7 +129,6 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(SMSG_PET_NAME_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryOpcode );
DEFINE_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(CMSG_ITEM_QUERY_SINGLE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleItemQuerySingleOpcode );
DEFINE_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(CMSG_PAGE_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePageTextQueryOpcode );
DEFINE_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1380,7 +1379,9 @@ void InitOpcodes()
DEFINE_OPCODE_HANDLER(CMSG_RETURN_TO_GRAVEYARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReturnToGraveyard );
DEFINE_OPCODE_HANDLER(CMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomizeCharNameOpcode );
DEFINE_OPCODE_HANDLER(SMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_PLAYER_MOVE, STATUS_AUTHED, PROCESS_THREADSAFE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_PLAYER_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(CMSG_REQUEST_HOTFIX, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix );
DEFINE_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_REQUEST_SCORE_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); Need to send the response
#undef DEFINE_OPCODE_HANDLER

View File

@@ -228,7 +228,6 @@ enum Opcodes
CMSG_INITIATE_TRADE = 0x00,
CMSG_INSPECT = 0x9A7B,
CMSG_INSTANCE_LOCK_WARNING_RESPONSE = 0x8CF7,
CMSG_ITEM_QUERY_SINGLE = 0x0000,
CMSG_ITEM_REFUND = 0xCC3,
CMSG_ITEM_REFUND_INFO = 0x1C7E,
CMSG_ITEM_TEXT_QUERY = 0x4AEB,
@@ -378,6 +377,7 @@ enum Opcodes
CMSG_REQUEST_ACCOUNT_DATA = 0x8AF2,
CMSG_REQUEST_CATEGORY_COOLDOWNS = 0x00,
CMSG_REQUEST_CEMETERY_LIST = 0x00,
CMSG_REQUEST_HOTFIX = 0x8A8B,
CMSG_REQUEST_PARTY_MEMBER_STATS = 0x987E,
CMSG_REQUEST_PET_INFO = 0x9A47,
CMSG_REQUEST_RAID_INFO = 0xECF,
@@ -731,6 +731,7 @@ enum Opcodes
SMSG_GUILD_UPDATE_ROSTER = 0x00,
SMSG_GUILD_XP_UPDATE = 0x00,
SMSG_GUILDFINDER_SEARCH_RESULT = 0xE0CE,
SMSG_HOTFIX_INFO = 0xA04C,
SMSG_HIGHEST_THREAT_UPDATE = 0x5E7B,
SMSG_INIT_CURRENCY = 0x227E,
SMSG_INIT_WORLD_STATES = 0x9EDA,

View File

@@ -647,7 +647,8 @@ class WorldSession
void HandleSwapInvItemOpcode(WorldPacket& recvPacket);
void HandleDestroyItemOpcode(WorldPacket& recvPacket);
void HandleAutoEquipItemOpcode(WorldPacket& recvPacket);
void HandleItemQuerySingleOpcode(WorldPacket& recvPacket);
void SendItemDb2Reply(uint32 entry);
void SendItemSparseDb2Reply(uint32 entry);
void HandleSellItemOpcode(WorldPacket& recvPacket);
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
void HandleBuyItemOpcode(WorldPacket& recvPacket);
@@ -903,6 +904,7 @@ class WorldSession
void HandleEjectPassenger(WorldPacket& data);
void HandleEnterPlayerVehicle(WorldPacket& data);
void HandleUpdateProjectilePosition(WorldPacket& recvPacket);
void HandleRequestHotfix(WorldPacket& recvPacket);
private:
void InitializeQueryCallbackParameters();

View File

@@ -1747,6 +1747,9 @@ void World::SetInitialWorldSettings()
sLog->outString("Initializing Opcodes...");
InitOpcodes();
sLog->outString("Loading hotfix info...");
sObjectMgr->LoadHotfixData();
uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);
sLog->outString();
sLog->outString("WORLD: World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000) );

View File

@@ -198,10 +198,10 @@ class ByteBuffer
{
return ReadUInt8() ^ 1;
}
void ReadXorByte(uint32 bit, uint8& byte)
{
if (!bit)
if (!bit)
byte = 0;
else
byte = ReadUInt8() ^ bit;