From 33e72167a1b9b68dfd5268404ee0801b6c60139d Mon Sep 17 00:00:00 2001 From: Portgas Date: Tue, 5 Aug 2014 00:23:39 +0200 Subject: Core/Spells: Fixed Range Weapons durability loss --- src/server/game/Spells/Spell.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index bf518859b49..fedf591aa94 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4387,7 +4387,12 @@ void Spell::TakeAmmo() if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND) return; - if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN) + + if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN || + pItem->GetTemplate()->InventoryType == INVTYPE_RANGED || + pItem->GetTemplate()->InventoryType == INVTYPE_RANGEDRIGHT) + + if (roll_chance_f(sWorld->getRate(RATE_DURABILITY_LOSS_DAMAGE))) { if (pItem->GetMaxStackCount() == 1) { -- cgit v1.2.3 From 3c103f718d8a77da6bb3ae52187746c6fd09473e Mon Sep 17 00:00:00 2001 From: MitchesD Date: Sat, 4 Oct 2014 16:44:59 +0200 Subject: Scripts/Misc: fixed GameObjects chests in CoS and HoR Fixes https://github.com/TrinityCore/TrinityCore/issues/13246 --- .../CullingOfStratholme/instance_culling_of_stratholme.cpp | 2 +- .../scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/server') diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp index c25a061d622..cb3fa49216b 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp @@ -204,7 +204,7 @@ class instance_culling_of_stratholme : public InstanceMapScript if (state == DONE) { if (GameObject* go = instance->GetGameObject(_malGanisChestGUID)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); instance->SummonCreature(NPC_CHROMIE_3, ChromieSummonPos[1]); } break; diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp index d6c7b18eabd..880d032265a 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp @@ -91,7 +91,7 @@ class instance_halls_of_stone : public InstanceMapScript case GO_TRIBUNAL_CHEST_HERO: TribunalChestGUID = go->GetGUID(); if (GetBossState(DATA_BRANN_EVENT) == DONE) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); break; case GO_TRIBUNAL_SKY_FLOOR: TribunalSkyFloorGUID = go->GetGUID(); @@ -160,7 +160,7 @@ class instance_halls_of_stone : public InstanceMapScript if (state == DONE) { if (GameObject* go = instance->GetGameObject(TribunalChestGUID)) - go->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND); + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); } break; default: -- cgit v1.2.3 From 3d0c5cbf9a82c9d29dbb58c635beb2d15e8fe47a Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 4 Oct 2014 19:44:15 +0200 Subject: Core/SAI: Fix typo --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index a5edc9e63d3..9a9b803452a 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -202,13 +202,13 @@ void SmartAIMgr::LoadSmartAIFromDB() CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id); if (!creatureInfo) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) does not exist, skipped loading.", uint32(temp.entryOrGuid)); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); continue; } if (creatureInfo->AIName != "SmartAI") { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) is not using SmartAI, skipped loading.", uint32(temp.entryOrGuid)); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) is not using SmartAI, skipped loading.", uint32(abs(temp.entryOrGuid))); continue; } } -- cgit v1.2.3 From d08862a7928707258f8741d7cb368b4622abc08e Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 4 Oct 2014 20:18:02 +0200 Subject: Core/SAI: Added new error for is using other script as sai --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 9a9b803452a..76937fcd7af 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -156,6 +156,10 @@ void SmartAIMgr::LoadSmartAIFromDB() TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) is not using SmartAI, skipped loading.", uint32(temp.entryOrGuid)); continue; } + + std::string scriptName = sObjectMgr->GetScriptName(creatureInfo->ScriptID); + if (!scriptName.empty()) + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) is using other script", uint32(temp.entryOrGuid)); break; } case SMART_SCRIPT_TYPE_GAMEOBJECT: @@ -195,22 +199,26 @@ void SmartAIMgr::LoadSmartAIFromDB() CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid))); if (!creature) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid))); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); continue; } CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id); if (!creatureInfo) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); continue; } if (creatureInfo->AIName != "SmartAI") { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) is not using SmartAI, skipped loading.", uint32(abs(temp.entryOrGuid))); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); continue; } + + std::string scriptName = sObjectMgr->GetScriptName(creatureInfo->ScriptID); + if (!scriptName.empty()) + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is using other script", creature->id, uint32(abs(temp.entryOrGuid))); } temp.source_type = source_type; -- cgit v1.2.3 From ef92d31c49d6a55d1c33454bb50bb621dfad7137 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 4 Oct 2014 20:24:58 +0200 Subject: Revert "Core/SAI: Added new error for is using other script as sai" This reverts commit d08862a7928707258f8741d7cb368b4622abc08e. --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 76937fcd7af..ce8eed02b7e 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -156,10 +156,6 @@ void SmartAIMgr::LoadSmartAIFromDB() TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) is not using SmartAI, skipped loading.", uint32(temp.entryOrGuid)); continue; } - - std::string scriptName = sObjectMgr->GetScriptName(creatureInfo->ScriptID); - if (!scriptName.empty()) - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) is using other script", uint32(temp.entryOrGuid)); break; } case SMART_SCRIPT_TYPE_GAMEOBJECT: @@ -215,10 +211,6 @@ void SmartAIMgr::LoadSmartAIFromDB() TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); continue; } - - std::string scriptName = sObjectMgr->GetScriptName(creatureInfo->ScriptID); - if (!scriptName.empty()) - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is using other script", creature->id, uint32(abs(temp.entryOrGuid))); } temp.source_type = source_type; -- cgit v1.2.3 From 8a4abdaa67df5b1e26bb65662ebfbeebf49357da Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 4 Oct 2014 22:04:36 +0200 Subject: Core: Remove Whitespaces --- src/server/game/Achievements/AchievementMgr.h | 2 +- .../scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp | 2 +- src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index 282cc0d70c2..49b960dafff 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -371,7 +371,7 @@ class AchievementGlobalMgr { if (IsRealmCompleted(achievement, instanceId)) return; - + m_allCompletedAchievements[achievement->ID] = instanceId; } diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp index e6ffa3f8979..6ec69ee11af 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp @@ -72,7 +72,7 @@ public: struct boss_darkweaver_sythAI : public BossAI { boss_darkweaver_sythAI(Creature* creature) : BossAI(creature, DATA_DARKWEAVER_SYTH) - { + { Initialize(); } diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp index dd0e271a02d..23abf48233e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp @@ -117,7 +117,7 @@ public: void Reset() override { - ReliquaryGUID.Clear(); + ReliquaryGUID.Clear(); } void EnterCombat(Unit* /*who*/) override -- cgit v1.2.3 From f989c7182c4cc30f1d0ffdc566c7624a5e108a2f Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sun, 5 Oct 2014 01:56:16 +0200 Subject: Core/Misc: Added support for calculate zoneId/areaId for creature / gameoject table at loading (Slow server startup ca.3-4 sec.) --- sql/updates/world/2014_10_05_03_world.sql | 5 ++++ src/server/game/Globals/ObjectMgr.cpp | 28 ++++++++++++++++++++++ src/server/game/World/World.cpp | 3 +++ src/server/game/World/World.h | 2 ++ .../Database/Implementation/WorldDatabase.cpp | 2 ++ .../shared/Database/Implementation/WorldDatabase.h | 2 ++ src/server/worldserver/worldserver.conf.dist | 14 +++++++++++ 7 files changed, 56 insertions(+) create mode 100644 sql/updates/world/2014_10_05_03_world.sql (limited to 'src/server') diff --git a/sql/updates/world/2014_10_05_03_world.sql b/sql/updates/world/2014_10_05_03_world.sql new file mode 100644 index 00000000000..30603214312 --- /dev/null +++ b/sql/updates/world/2014_10_05_03_world.sql @@ -0,0 +1,5 @@ +ALTER TABLE `creature` ADD `zoneId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Zone Identifier' AFTER `map`; +ALTER TABLE `creature` ADD `areaId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Area Identifier' AFTER `zoneId`; + +ALTER TABLE `gameobject` ADD `zoneId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Zone Identifier' AFTER `map`; +ALTER TABLE `gameobject` ADD `areaId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Area Identifier' AFTER `zoneId`; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 15c55a11be6..400a885d923 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1734,6 +1734,20 @@ void ObjectMgr::LoadCreatures() data.orientation = Position::NormalizeOrientation(data.orientation); } + if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA)) + { + uint32 zoneId = sMapMgr->GetZoneId(data.mapid, data.posX, data.posY, data.posZ); + uint32 areaId = sMapMgr->GetAreaId(data.mapid, data.posX, data.posY, data.posZ); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA); + + stmt->setUInt32(0, zoneId); + stmt->setUInt32(1, areaId); + stmt->setUInt64(2, guid); + + WorldDatabase.Execute(stmt); + } + // Add to grid if not managed by the game event or pool system if (gameEvent == 0 && PoolId == 0) AddCreatureToGrid(guid, &data); @@ -2046,6 +2060,20 @@ void ObjectMgr::LoadGameobjects() data.phaseMask = 1; } + if (sWorld->getBoolConfig(CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA)) + { + uint32 zoneId = sMapMgr->GetZoneId(data.mapid, data.posX, data.posY, data.posZ); + uint32 areaId = sMapMgr->GetAreaId(data.mapid, data.posX, data.posY, data.posZ); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA); + + stmt->setUInt32(0, zoneId); + stmt->setUInt32(1, areaId); + stmt->setUInt64(2, guid); + + WorldDatabase.Execute(stmt); + } + if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system AddGameobjectToGrid(guid, &data); ++count; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a197ea7caa8..903e14f7506 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1261,6 +1261,9 @@ void World::LoadConfigSettings(bool reload) // AHBot m_int_configs[CONFIG_AHBOT_UPDATE_INTERVAL] = sConfigMgr->GetIntDefault("AuctionHouseBot.Update.Interval", 20); + m_bool_configs[CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Creature.Zone.Area.Data", false); + m_bool_configs[CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA] = sConfigMgr->GetBoolDefault("Calculate.Gameoject.Zone.Area.Data", false); + // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 9987b8ab62c..b9c30302f4d 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -158,6 +158,8 @@ enum WorldBoolConfigs CONFIG_INSTANCES_RESET_ANNOUNCE, CONFIG_IP_BASED_ACTION_LOGGING, CONFIG_ALLOW_TRACK_BOTH_RESOURCES, + CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA, + CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA, BOOL_CONFIG_VALUE_COUNT }; diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index e83901c8557..2adb575b780 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -89,4 +89,6 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC); + PrepareStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA, "UPDATE creature SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, "UPDATE gameobject SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h index 8a5bd206021..a398b412c50 100644 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ b/src/server/shared/Database/Implementation/WorldDatabase.h @@ -110,6 +110,8 @@ enum WorldDatabaseStatements WORLD_SEL_DISABLES, WORLD_INS_DISABLES, WORLD_DEL_DISABLES, + WORLD_UPD_CREATURE_ZONE_AREA_DATA, + WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, MAX_WORLDDATABASE_STATEMENTS }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 3fec13684da..c09d451592d 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2649,6 +2649,20 @@ PlayerDump.DisallowOverwrite = 1 UI.ShowQuestLevelsInDialogs = 0 +# +# Calculate.Creature.Zone.Area.Data +# Description: Calculate at loading creature zoneId / areaId and save in creature table (WARNING: SLOW WORLD SERVER STARTUP) +# Default: 0 - (Do not show) + +Calculate.Creature.Zone.Area.Data = 0 + +# +# Calculate.Gameoject.Zone.Area.Data +# Description: Calculate at loading gameobject zoneId / areaId and save in gameobject table (WARNING: SLOW WORLD SERVER STARTUP) +# Default: 0 - (Do not show) + +Calculate.Gameoject.Zone.Area.Data = 0 + # ################################################################################################### -- cgit v1.2.3 From adefe39bf6acada75f39597116abc10015380068 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sun, 5 Oct 2014 03:21:26 +0200 Subject: DB/Brewfest: Added missing brewfest spawn in shatttath --- sql/updates/world/2014_10_05_04_world.sql | 71 +++++++++++++++++++++++++++++++ src/server/game/Globals/ObjectMgr.cpp | 10 +++-- 2 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 sql/updates/world/2014_10_05_04_world.sql (limited to 'src/server') diff --git a/sql/updates/world/2014_10_05_04_world.sql b/sql/updates/world/2014_10_05_04_world.sql new file mode 100644 index 00000000000..ed32e268a87 --- /dev/null +++ b/sql/updates/world/2014_10_05_04_world.sql @@ -0,0 +1,71 @@ +SET @CGUID :=74960; +SET @OGUID :=21104; + +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+12; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES +(@CGUID+0 , 24545, 530, 1, 1, -1882.759, 5575.42, -12.3448, 4.677482, 120, 0, 0), -- Thunderbrew "Apprentice" (Area: Shattrath City) +(@CGUID+1 , 24484, 530, 1, 1, -1872.835, 5560.321, -12.3448, 2.748216, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43910 - Brewfest Reveler - Gnome) +(@CGUID+2 , 24484, 530, 1, 1, -1878.838, 5562.812, -12.3448, 5.889809, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43909 - Brewfest Reveler - Dwarf) +(@CGUID+3 , 24484, 530, 1, 1, -1878.618, 5556.088, -12.3448, 3.259485, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43910 - Brewfest Reveler - Gnome) +(@CGUID+4 , 24484, 530, 1, 1, -1897.398, 5558.127, -12.3448, 1.710423, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44004 - Brewfest Reveler - Goblin - Female) +(@CGUID+5 , 24484, 530, 1, 1, -1899.819, 5560.333, -12.3448, 0.3665192, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44003 - Brewfest Reveler - Goblin - Male) +(@CGUID+6 , 24484, 530, 1, 1, -1921.889, 5554.328, -12.34481, 0.04066804, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43916 - Brewfest Reveler - Troll) +(@CGUID+7 , 24484, 530, 1, 1, -1916.578, 5551.592, -12.34481, 2.666002, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43917 - Brewfest Reveler - Undead) +(@CGUID+8 , 24484, 530, 1, 1, -1924.595, 5549.645, -12.3448, 1.046868, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 43914 - Brewfest Reveler - Orc) +(@CGUID+9 , 24484, 530, 1, 1, -1897.494, 5562.316, -12.3448, 4.433136, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44003 - Brewfest Reveler - Goblin - Male) +(@CGUID+10, 24501, 530, 1, 1, -1926.787, 5562.968, -12.3448, 5.061455, 120, 0, 0), -- Drohn's Distillery Apprentice (Area: Shattrath City) +(@CGUID+11, 24484, 530, 1, 1, -1895.234, 5560.195, -12.34481, 2.80998, 120, 0, 0), -- Brewfest Reveler (Area: Shattrath City) (Auras: 44003 - Brewfest Reveler - Goblin - Male) +(@CGUID+12, 23511, 530, 1, 1, -1906.297, 5569.852, -12.3448, 4.974188, 120, 0, 0); -- Gordok Brew Apprentice (Area: Shattrath City) + +DELETE FROM `creature_addon` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+12; +INSERT INTO `creature_addon` (`guid`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES +(@CGUID+1 , 0, 0x0, 0x101, '43910'), -- Brewfest Reveler - 43910 - Brewfest Reveler - Gnome +(@CGUID+2 , 0, 0x0, 0x101, '43909'), -- Brewfest Reveler - 43909 - Brewfest Reveler - Dwarf +(@CGUID+3 , 0, 0x0, 0x101, '43910'), -- Brewfest Reveler - 43910 - Brewfest Reveler - Gnome +(@CGUID+4 , 0, 0x0, 0x101, '44004'), -- Brewfest Reveler - 44004 - Brewfest Reveler - Goblin - Female +(@CGUID+5 , 0, 0x0, 0x101, '44003'), -- Brewfest Reveler - 44003 - Brewfest Reveler - Goblin - Male +(@CGUID+6 , 0, 0x0, 0x101, '43916'), -- Brewfest Reveler - 43916 - Brewfest Reveler - Troll +(@CGUID+7 , 0, 0x0, 0x101, '43917'), -- Brewfest Reveler - 43917 - Brewfest Reveler - Undead +(@CGUID+8 , 0, 0x0, 0x101, '43914'), -- Brewfest Reveler - 43914 - Brewfest Reveler - Orc +(@CGUID+9 , 0, 0x0, 0x101, '44003'), -- Brewfest Reveler - 44003 - Brewfest Reveler - Goblin - Male +(@CGUID+11, 0, 0x0, 0x101, '44003'); -- Brewfest Reveler - 44003 - Brewfest Reveler - Goblin - Male + +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+8; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(@OGUID+0, 186259, 530, 1, 1, -1875.389, 5579.114, -12.42814, 1.605702, 0, 0, 0, 1, 120, 255, 1), -- Thunderbrew Festive Wagon (Area: Shattrath City) +(@OGUID+1, 180037, 530, 1, 1, -1909.218, 5569.716, -12.42814, 4.97419, 0, 0, 0, 1, 120, 255, 1), -- Haybail 01 (Area: Shattrath City) +(@OGUID+2, 180037, 530, 1, 1, -1906.963, 5573.009, -12.42814, 3.47321, 0, 0, 0, 1, 120, 255, 1), -- Haybail 01 (Area: Shattrath City) +(@OGUID+3, 178666, 530, 1, 1, -1882.575, 5582.089, -12.42814, 3.141593, 0, 0, 0, 1, 120, 255, 1), -- Gypsy Wagon (Area: Shattrath City) +(@OGUID+4, 178666, 530, 1, 1, -1928.171, 5567.508, -12.42814, 3.38594, 0, 0, 0, 1, 120, 255, 1), -- Gypsy Wagon (Area: Shattrath City) +(@OGUID+5, 186255, 530, 1, 1, -1920.9, 5568.442, -12.42814, 1.884953, 0, 0, 0, 1, 120, 255, 1), -- Drohn's Distillery Festive Wagon (Area: Shattrath City) +(@OGUID+6, 186257, 530, 1, 1, -1900.552, 5575.883, -12.42814, 1.937312, 0, 0, 0, 1, 120, 255, 1), -- Gordok Festive Wagon (Area: Shattrath City) +(@OGUID+7, 180037, 530, 1, 1, -1893.456, 5576.866, -12.42814, 4.223697, 0, 0, 0, 1, 120, 255, 1), -- Haybail 01 (Area: Shattrath City) +(@OGUID+8, 180037, 530, 1, 1, -1904.326, 5571.048, -12.42814, 1.902409, 0, 0, 0, 1, 120, 255, 1); -- Haybail 01 (Area: Shattrath City) + +DELETE FROM `game_event_creature` WHERE `eventEntry`=24 AND `guid` BETWEEN @CGUID+0 AND @CGUID+12; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(24, @CGUID+0), +(24, @CGUID+1), +(24, @CGUID+2), +(24, @CGUID+3), +(24, @CGUID+4), +(24, @CGUID+5), +(24, @CGUID+6), +(24, @CGUID+7), +(24, @CGUID+8), +(24, @CGUID+9), +(24, @CGUID+10), +(24, @CGUID+11), +(24, @CGUID+12); + +DELETE FROM `game_event_gameobject` WHERE `eventEntry`=24 AND `guid` BETWEEN @OGUID+0 AND @OGUID+8; +INSERT INTO `game_event_gameobject` (`eventEntry`, `guid`) VALUES +(24, @OGUID+0), +(24, @OGUID+1), +(24, @OGUID+2), +(24, @OGUID+3), +(24, @OGUID+4), +(24, @OGUID+5), +(24, @OGUID+6), +(24, @OGUID+7), +(24, @OGUID+8); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 400a885d923..0fc8bcc73d3 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1736,8 +1736,9 @@ void ObjectMgr::LoadCreatures() if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA)) { - uint32 zoneId = sMapMgr->GetZoneId(data.mapid, data.posX, data.posY, data.posZ); - uint32 areaId = sMapMgr->GetAreaId(data.mapid, data.posX, data.posY, data.posZ); + uint32 zoneId = 0; + uint32 areaId = 0; + sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA); @@ -2062,8 +2063,9 @@ void ObjectMgr::LoadGameobjects() if (sWorld->getBoolConfig(CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA)) { - uint32 zoneId = sMapMgr->GetZoneId(data.mapid, data.posX, data.posY, data.posZ); - uint32 areaId = sMapMgr->GetAreaId(data.mapid, data.posX, data.posY, data.posZ); + uint32 zoneId = 0; + uint32 areaId = 0; + sMapMgr->GetZoneAndAreaId(zoneId, areaId, data.mapid, data.posX, data.posY, data.posZ); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA); -- cgit v1.2.3 From a3192b1ae3006563145dd9d4d3522857274e6d33 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sun, 5 Oct 2014 03:50:45 +0200 Subject: Core: Fix warning --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index ce8eed02b7e..4b93c35787c 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -195,7 +195,7 @@ void SmartAIMgr::LoadSmartAIFromDB() CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid))); if (!creature) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid))); continue; } -- cgit v1.2.3 From b4a6aa1de0aba7609a796f030545361806fa0bc3 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 04:09:06 +0200 Subject: Core/Authserver: Added friend related battle.net opcode definitions --- .../Server/BattlenetPackets/BattlenetPackets.h | 1 + .../Server/BattlenetPackets/BattlenetPacketsBase.h | 2 +- .../Server/BattlenetPackets/FriendsPackets.h | 59 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/server/authserver/Server/BattlenetPackets/FriendsPackets.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h index 15c609b3ba4..7eca508bd11 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h @@ -21,5 +21,6 @@ #include "AuthenticationPackets.h" #include "ConnectionPackets.h" #include "WoWRealmPackets.h" +#include "FriendsPackets.h" #endif // BattlenetPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h index af02eb91f43..8ab6ca0f341 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h @@ -37,7 +37,7 @@ namespace Battlenet AUTHENTICATION = 0, CONNECTION = 1, WOWREALM = 2, - FRIEND = 3, + FRIENDS = 3, PRESENCE = 4, CHAT = 5, SUPPORT = 7, diff --git a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h new file mode 100644 index 00000000000..6aa0d5810c5 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef FriendsPackets_h__ +#define FriendsPackets_h__ + +#include "BattlenetPacketsBase.h" + +namespace Battlenet +{ + namespace Friends + { + enum Opcode + { + CMSG_FRIEND_INVITE = 0x01, // Not implemented + CMSG_FRIEND_INVITE_RESPONSE = 0x02, // Not implemented + CMSG_FRIEND_REMOVE = 0x04, // Not implemented + CMSG_FRIEND_NOTE = 0x05, // Not implemented + CMSG_TOONS_OF_FRIEND_REQUEST = 0x06, // Not implemented + CMSG_BLOCK_ADD = 0x08, // Not implemented + CMSG_BLOCK_REMOVE = 0x0A, // Not implemented + CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented + CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Not implemented + CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Not implemented + CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Not implemented + CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, // Not implemented + CMSG_SEND_RID_FRIEND_INVITE = 0x16, // Not implemented + + SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented + SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented + SMSG_TOONS_OF_FRIEND_NOTIFY = 0x06, // Not implemented + SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented + SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented + SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented + SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Not implemented + SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Not implemented + SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Not implemented + SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, // Not implemented + SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented + SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented + }; + } +} + +#endif // FriendsPackets_h__ -- cgit v1.2.3 From f4a62a178d594c779c59323833a06e3dae004b0c Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 12:17:17 +0200 Subject: Core/Authserver: Added battle.net presence channel opcode definitions --- .../Server/BattlenetPackets/BattlenetPackets.h | 1 + .../Server/BattlenetPackets/FriendsPackets.h | 2 +- .../Server/BattlenetPackets/PresencePackets.h | 39 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/server/authserver/Server/BattlenetPackets/PresencePackets.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h index 7eca508bd11..1ef5d2edf82 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h @@ -22,5 +22,6 @@ #include "ConnectionPackets.h" #include "WoWRealmPackets.h" #include "FriendsPackets.h" +#include "PresencePackets.h" #endif // BattlenetPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h index 6aa0d5810c5..305fa1a601e 100644 --- a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h @@ -38,7 +38,7 @@ namespace Battlenet CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Not implemented CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Not implemented CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, // Not implemented - CMSG_SEND_RID_FRIEND_INVITE = 0x16, // Not implemented + CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented diff --git a/src/server/authserver/Server/BattlenetPackets/PresencePackets.h b/src/server/authserver/Server/BattlenetPackets/PresencePackets.h new file mode 100644 index 00000000000..56ebfc1ba43 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/PresencePackets.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef PresencePackets_h__ +#define PresencePackets_h__ + +#include "BattlenetPacketsBase.h" + +namespace Battlenet +{ + namespace Presence + { + enum Opcode + { + CMSG_UPDATE_REQUEST = 0x0, + CMSG_STATISTIC_SUBSCRIBE = 0x2, + + SMSG_UPDATE_NOTIFY = 0x0, + SMSG_FIELD_SPEC_ANNOUNCE = 0x1, + SMSG_STATISTICS_UPDATE = 0x3 + }; + } +} + +#endif // PresencePackets_h__ -- cgit v1.2.3 From 92d22ee3f9e6b824deb4cb7df2521706061d606f Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 12:24:38 +0200 Subject: Core/Authserver: Added battle.net support channel opcode definitions --- .../Server/BattlenetPackets/BattlenetPackets.h | 2 ++ .../Server/BattlenetPackets/PresencePackets.h | 10 +++---- .../Server/BattlenetPackets/SupportPackets.h | 34 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/server/authserver/Server/BattlenetPackets/SupportPackets.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h index 1ef5d2edf82..b7825a79c73 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h @@ -24,4 +24,6 @@ #include "FriendsPackets.h" #include "PresencePackets.h" +#include "SupportPackets.h" + #endif // BattlenetPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/PresencePackets.h b/src/server/authserver/Server/BattlenetPackets/PresencePackets.h index 56ebfc1ba43..baf2715f564 100644 --- a/src/server/authserver/Server/BattlenetPackets/PresencePackets.h +++ b/src/server/authserver/Server/BattlenetPackets/PresencePackets.h @@ -26,12 +26,12 @@ namespace Battlenet { enum Opcode { - CMSG_UPDATE_REQUEST = 0x0, - CMSG_STATISTIC_SUBSCRIBE = 0x2, + CMSG_UPDATE_REQUEST = 0x0, // Not implemented + CMSG_STATISTIC_SUBSCRIBE = 0x2, // Not implemented - SMSG_UPDATE_NOTIFY = 0x0, - SMSG_FIELD_SPEC_ANNOUNCE = 0x1, - SMSG_STATISTICS_UPDATE = 0x3 + SMSG_UPDATE_NOTIFY = 0x0, // Not implemented + SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented + SMSG_STATISTICS_UPDATE = 0x3 // Not implemented }; } } diff --git a/src/server/authserver/Server/BattlenetPackets/SupportPackets.h b/src/server/authserver/Server/BattlenetPackets/SupportPackets.h new file mode 100644 index 00000000000..4821ce7caa0 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/SupportPackets.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SupportPackets_h__ +#define SupportPackets_h__ + +#include "BattlenetPacketsBase.h" + +namespace Battlenet +{ + namespace Support + { + enum Opcode + { + CMSG_COMPLAINT_REQUEST = 0x0 // Not implemented + }; + } +} + +#endif // SupportPackets_h__ -- cgit v1.2.3 From 4beef458f818b6d49b5fd34c29f5333a63fbd9c7 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 12:39:12 +0200 Subject: Core/Authserver: Added battle.net achievement channel opcode definitions --- .../Server/BattlenetPackets/AchievementPackets.h | 42 ++++++++++++++++++++++ .../Server/BattlenetPackets/BattlenetPackets.h | 1 + 2 files changed, 43 insertions(+) create mode 100644 src/server/authserver/Server/BattlenetPackets/AchievementPackets.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h b/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h new file mode 100644 index 00000000000..99c55d8fdc2 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AchievementPackets_h__ +#define AchievementPackets_h__ + +#include "BattlenetPacketsBase.h" + +namespace Battlenet +{ + namespace Achievement + { + enum Opcode + { + CMSG_LISTEN_REQUEST = 0x0, // Not implemented + CMSG_CRITERIA_FLUSH_REQUEST = 0x3, // Not implemented + CMSG_CHANGE_TROPHY_CASE_REQUEST = 0x5, // Not implemented + + SMSG_DATA = 0x2, // Not implemented + SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented + SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented + SMSG_CHANGE_TROPHY_CASE_RESULE = 0x6 // Not implemented + }; + } +} + +#endif // AchievementPackets_h__ + diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h index b7825a79c73..80ff9b7ebdc 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h @@ -25,5 +25,6 @@ #include "PresencePackets.h" #include "SupportPackets.h" +#include "AchievementPackets.h" #endif // BattlenetPackets_h__ -- cgit v1.2.3 From 24943462888ff80a84085d68f1eeba9931c5e110 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 13:05:36 +0200 Subject: Core/Authserver: Added battle.net cache channel opcode definitions --- .../Server/BattlenetPackets/AchievementPackets.h | 2 +- .../Server/BattlenetPackets/BattlenetPackets.h | 4 +- .../Server/BattlenetPackets/CachePackets.h | 43 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/server/authserver/Server/BattlenetPackets/CachePackets.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h b/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h index 99c55d8fdc2..69a03c7e16d 100644 --- a/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h @@ -33,7 +33,7 @@ namespace Battlenet SMSG_DATA = 0x2, // Not implemented SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented - SMSG_CHANGE_TROPHY_CASE_RESULE = 0x6 // Not implemented + SMSG_CHANGE_TROPHY_CASE_RESULT = 0x6 // Not implemented }; } } diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h index 80ff9b7ebdc..48e7a470ec5 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h @@ -23,8 +23,10 @@ #include "WoWRealmPackets.h" #include "FriendsPackets.h" #include "PresencePackets.h" - +//#include "ChatPackets.h" #include "SupportPackets.h" #include "AchievementPackets.h" +#include "CachePackets.h" +//#include "ProfilePackets.h" #endif // BattlenetPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/CachePackets.h b/src/server/authserver/Server/BattlenetPackets/CachePackets.h new file mode 100644 index 00000000000..6354201dc4c --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/CachePackets.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef CachePackets_h__ +#define CachePackets_h__ + +#include "BattlenetPacketsBase.h" + +namespace Battlenet +{ + namespace Cache + { + enum Opcode + { + CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented + CMSG_CONNECT_REQUEST = 0x4, // Not implemented + CMSG_DATA_CHUNK = 0x7, // Not implemented + SMSG_GET_STREAM_ITEMS_REQUEST = 0x9, // Not implemented + + SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented + SMSG_CONNECT_RESPONSE = 0x4, // Not implemented + SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented + SMSG_RESULT = 0x8, // Not implemented + SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9 // Not implemented + }; + } +} + +#endif // CachePackets_h__ -- cgit v1.2.3 From 6501da3c94319b7e563ab406b39f85750c83273e Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 5 Oct 2014 13:55:56 +0200 Subject: Core/Instances: Add assert to track down a crash Instance reset times are supposed to be initialized on server startup and then only updated when they expire. Refers to #11904 --- src/server/game/Instances/InstanceSaveMgr.cpp | 4 ++-- src/server/game/Instances/InstanceSaveMgr.h | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index 370d02631ba..8d5ae53f737 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -389,7 +389,7 @@ void InstanceSaveManager::LoadResetTimes() if (oldresettime != newresettime) CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%u' AND difficulty = '%u'", uint32(newresettime), mapid, difficulty); - SetResetTimeFor(mapid, difficulty, newresettime); + InitializeResetTimeFor(mapid, difficulty, newresettime); } while (result->NextRow()); } @@ -426,7 +426,7 @@ void InstanceSaveManager::LoadResetTimes() CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); } - SetResetTimeFor(mapid, difficulty, t); + InitializeResetTimeFor(mapid, difficulty, t); // schedule the global reset/warning uint8 type; diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index 1bab66be1b8..60aeee25e1c 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -191,11 +191,20 @@ class InstanceSaveManager return itr != m_resetTimeByMapDifficulty.end() ? itr->second : 0; } - void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t) + // Use this on startup when initializing reset times + void InitializeResetTimeFor(uint32 mapid, Difficulty d, time_t t) { m_resetTimeByMapDifficulty[MAKE_PAIR32(mapid, d)] = t; } + // Use this only when updating existing reset times + void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t) + { + ResetTimeByMapDifficultyMap::iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d)); + ASSERT(itr != m_resetTimeByMapDifficulty.end()); + itr->second = t; + } + ResetTimeByMapDifficultyMap const& GetResetTimeMap() const { return m_resetTimeByMapDifficulty; -- cgit v1.2.3 From dd26efa40b19412cc80ac7efddcc84d2170cc190 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 16:21:27 +0200 Subject: Core/Authserver: Refactored handling battle.net client packets --- .../authserver/Server/BattlenetPacketFactory.h | 75 ++++++++++++++ .../BattlenetPackets/AuthenticationPackets.cpp | 21 +++- .../BattlenetPackets/AuthenticationPackets.h | 3 + .../Server/BattlenetPackets/BattlenetPacketsBase.h | 2 + .../Server/BattlenetPackets/ConnectionPackets.cpp | 31 ++++++ .../Server/BattlenetPackets/ConnectionPackets.h | 39 +++++++ .../Server/BattlenetPackets/WoWRealmPackets.cpp | 16 +++ .../Server/BattlenetPackets/WoWRealmPackets.h | 14 +++ src/server/authserver/Server/BattlenetSession.cpp | 115 +++++++-------------- src/server/authserver/Server/BattlenetSession.h | 18 ++-- 10 files changed, 246 insertions(+), 88 deletions(-) create mode 100644 src/server/authserver/Server/BattlenetPacketFactory.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPacketFactory.h b/src/server/authserver/Server/BattlenetPacketFactory.h new file mode 100644 index 00000000000..fa7b907ec79 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPacketFactory.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef BattlenetPacketFactory_h__ +#define BattlenetPacketFactory_h__ + +#include "BattlenetPackets.h" +#include + +namespace Battlenet +{ + class PacketFactory + { + typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream); + + public: + ClientPacket* Create(PacketHeader const& header, BitStream& stream) + { + auto creator = _creators.find(header); + if (creator == _creators.end()) + return nullptr; + + ClientPacket* packet = creator->second(header, stream); + packet->Read(); + return packet; + } + + static PacketFactory& Instance() + { + static PacketFactory instance; + return instance; + } + + private: + PacketFactory() + { + _creators[PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION)] = &New; + _creators[PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION)] = &New; + _creators[PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION)] = &New; + + _creators[PacketHeader(Connection::CMSG_PING, CONNECTION)] = &New; + _creators[PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION)] = &New; + _creators[PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION)] = &New; + + _creators[PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM)] = &New; + _creators[PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM)] = &New; + } + + template + static ClientPacket* New(PacketHeader const& header, BitStream& stream) + { + return new PacketType(header, stream); + } + + std::map _creators; + }; +} + +#define sBattlenetPacketFactory Battlenet::PacketFactory::Instance() + +#endif // BattlenetPacketFactory_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp index 58560e663de..ae2db016972 100644 --- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp @@ -50,6 +50,11 @@ std::string Battlenet::Authentication::LogonRequest::ToString() const return stream.str(); } +void Battlenet::Authentication::LogonRequest::CallHandler(Session* session) const +{ + session->HandleLogonRequest(*this); +} + void Battlenet::Authentication::ResumeRequest::Read() { Program = _stream.ReadFourCC(); @@ -77,13 +82,18 @@ std::string Battlenet::Authentication::ResumeRequest::ToString() const for (Component const& component : Components) stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; - stream << std::endl << "Battlenet::Authentication::ResumeRequest Login: " << Login; - stream << std::endl << "Battlenet::Authentication::ResumeRequest Region: " << uint32(Region); - stream << std::endl << "Battlenet::Authentication::ResumeRequest GameAccountName: " << GameAccountName; + stream << std::endl << "Login: " << Login; + stream << std::endl << "Region: " << uint32(Region); + stream << std::endl << "GameAccountName: " << GameAccountName; return stream.str(); } +void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session) const +{ + session->HandleResumeRequest(*this); +} + Battlenet::Authentication::ProofRequest::~ProofRequest() { for (size_t i = 0; i < Modules.size(); ++i) @@ -143,6 +153,11 @@ std::string Battlenet::Authentication::ProofResponse::ToString() const return stream.str(); } +void Battlenet::Authentication::ProofResponse::CallHandler(Session* session) const +{ + session->HandleProofResponse(*this); +} + Battlenet::Authentication::LogonResponse::~LogonResponse() { for (ModuleInfo* m : Modules) diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h index 5f079db65b3..90dd4a35b1c 100644 --- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h @@ -47,6 +47,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; + void CallHandler(Session* session) const override; std::string Program; std::string Platform; @@ -65,6 +66,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; + void CallHandler(Session* session) const override; std::string Program; std::string Platform; @@ -87,6 +89,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; + void CallHandler(Session* session) const override; std::vector Modules; }; diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h index 8ab6ca0f341..2aa07314771 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h @@ -31,6 +31,7 @@ using boost::asio::ip::tcp; namespace Battlenet { class BitStream; + class Session; enum Channel { @@ -100,6 +101,7 @@ namespace Battlenet ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { } void Write() override final { ASSERT(!"Write not implemented for this packet."); } + virtual void CallHandler(Session* session) const = 0; }; class ServerPacket : public Packet diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp index 9f53961c6ab..f0c3f3ea5e6 100644 --- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp @@ -15,8 +15,39 @@ * with this program. If not, see . */ +#include "BattlenetSession.h" #include "ConnectionPackets.h" +std::string Battlenet::Connection::Ping::ToString() const +{ + return "Battlenet::Connection::Ping"; +} + +void Battlenet::Connection::Ping::CallHandler(Session* session) const +{ + session->HandlePing(*this); +} + +std::string Battlenet::Connection::EnableEncryption::ToString() const +{ + return "Battlenet::Connection::EnableEncryption"; +} + +void Battlenet::Connection::EnableEncryption::CallHandler(Session* session) const +{ + session->HandleEnableEncryption(*this); +} + +std::string Battlenet::Connection::LogoutRequest::ToString() const +{ + return "Battlenet::Connection::LogoutRequest"; +} + +void Battlenet::Connection::LogoutRequest::CallHandler(Session* session) const +{ + session->HandleLogoutRequest(*this); +} + std::string Battlenet::Connection::Pong::ToString() const { return "Battlenet::Connection::Pong"; diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h index 50ec9416ec1..cc25f73f810 100644 --- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h @@ -39,6 +39,45 @@ namespace Battlenet SMSG_STUN_SERVERS = 0x4 // Not implemented }; + class Ping final : public ClientPacket + { + public: + Ping(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_PING, CONNECTION) && "Invalid packet header for Ping"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class EnableEncryption final : public ClientPacket + { + public: + EnableEncryption(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_ENABLE_ENCRYPTION, CONNECTION) && "Invalid packet header for EnableEncryption"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class LogoutRequest final : public ClientPacket + { + public: + LogoutRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_LOGOUT_REQUEST, CONNECTION) && "Invalid packet header for LogoutRequest"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + class Pong final : public ServerPacket { public: diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp b/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp index c1341e18c7d..1b20a3a7f85 100644 --- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp @@ -16,9 +16,20 @@ */ #include "WoWRealmPackets.h" +#include "BattlenetSession.h" #include #include +std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const +{ + return "Battlenet::WoWRealm::ListSubscribeRequest"; +} + +void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) const +{ + session->HandleListSubscribeRequest(*this); +} + Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse() { for (ServerPacket* realmData : RealmData) @@ -131,6 +142,11 @@ std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const return stream.str().c_str(); } +void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) const +{ + session->HandleJoinRequestV2(*this); +} + void Battlenet::WoWRealm::JoinResponseV2::Write() { _stream.Write(0, 27); diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h b/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h index 881ddd3186a..1e4228cb26a 100644 --- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h @@ -39,6 +39,19 @@ namespace Battlenet SMSG_JOIN_RESPONSE_V2 = 0x8 }; + class ListSubscribeRequest final : public ClientPacket + { + public: + ListSubscribeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM) && "Invalid packet header for ListSubscribeRequest"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + class JoinRequestV2 final : public ClientPacket { public: @@ -49,6 +62,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; + void CallHandler(Session* session) const override; uint32 ClientSeed; RealmId Realm; diff --git a/src/server/authserver/Server/BattlenetSession.cpp b/src/server/authserver/Server/BattlenetSession.cpp index 2242a3ee4eb..865e51c1a07 100644 --- a/src/server/authserver/Server/BattlenetSession.cpp +++ b/src/server/authserver/Server/BattlenetSession.cpp @@ -17,6 +17,7 @@ #include "AuthCodes.h" #include "BattlenetBitStream.h" +#include "BattlenetPacketFactory.h" #include "BattlenetSessionManager.h" #include "Database/DatabaseEnv.h" #include "HmacHash.h" @@ -24,27 +25,6 @@ #include "RealmList.h" #include "SHA256.h" #include -#include - -std::map InitHandlers() -{ - std::map handlers; - - handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_LOGON_REQUEST, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleLogonRequest; - handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_RESUME_REQUEST, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleResumeRequest; - handlers[Battlenet::PacketHeader(Battlenet::Authentication::CMSG_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Session::HandleProofResponse; - - handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_PING, Battlenet::CONNECTION)] = &Battlenet::Session::HandlePing; - handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_ENABLE_ENCRYPTION, Battlenet::CONNECTION)] = &Battlenet::Session::HandleEnableEncryption; - handlers[Battlenet::PacketHeader(Battlenet::Connection::CMSG_LOGOUT_REQUEST, Battlenet::CONNECTION)] = &Battlenet::Session::HandleLogoutRequest; - - handlers[Battlenet::PacketHeader(Battlenet::WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, Battlenet::WOWREALM)] = &Battlenet::Session::HandleListSubscribeRequest; - handlers[Battlenet::PacketHeader(Battlenet::WoWRealm::CMSG_JOIN_REQUEST_V2, Battlenet::WOWREALM)] = &Battlenet::Session::HandleJoinRequestV2; - - return handlers; -} - -std::map Handlers = InitHandlers(); Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODULE_COUNT] = { @@ -109,7 +89,12 @@ void Battlenet::Session::_SetVSFields(std::string const& pstr) LoginDatabase.Execute(stmt); } -bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& packet) +void Battlenet::Session::LogUnhandledPacket(ClientPacket const& packet) +{ + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::LogUnhandledPacket %s", packet.ToString().c_str()); +} + +void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& info) { // Verify that this IP is not in the ip_banned table LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); @@ -123,18 +108,15 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac complete->SetAuthResult(LOGIN_BANNED); AsyncWrite(complete); TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort()); - return true; + return; } - Authentication::LogonRequest info(header, packet); - info.Read(); - if (info.Program != "WoW") { Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_INVALID_PROGRAM); AsyncWrite(complete); - return true; + return; } if (!sBattlenetMgr->HasPlatform(info.Platform)) @@ -142,7 +124,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_INVALID_OS); AsyncWrite(complete); - return true; + return; } if (!sBattlenetMgr->HasPlatform(info.Locale)) @@ -150,7 +132,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); AsyncWrite(complete); - return true; + return; } for (Component const& component : info.Components) @@ -171,7 +153,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac } AsyncWrite(complete); - return true; + return; } if (component.Platform == "base") @@ -192,7 +174,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); AsyncWrite(complete); - return true; + return; } Field* fields = result->Fetch(); @@ -209,7 +191,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); AsyncWrite(complete); - return true; + return; } } else @@ -234,7 +216,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); AsyncWrite(complete); - return true; + return; } } } @@ -256,7 +238,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac complete->SetAuthResult(LOGIN_BANNED); AsyncWrite(complete); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); - return true; + return; } else { @@ -264,7 +246,7 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac complete->SetAuthResult(LOGIN_SUSPENDED); AsyncWrite(complete); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); - return true; + return; } } @@ -314,16 +296,10 @@ bool Battlenet::Session::HandleLogonRequest(PacketHeader& header, BitStream& pac // if has authenticator, send Token module request->Modules.push_back(thumbprint); AsyncWrite(request); - return true; } -bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& packet) +void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& reconnect) { - Authentication::ResumeRequest reconnect(header, packet); - reconnect.Read(); - - TC_LOG_DEBUG("server.battlenet", "%s", reconnect.ToString().c_str()); - _accountName = reconnect.Login; _locale = reconnect.Locale; _os = reconnect.Platform; @@ -341,7 +317,7 @@ bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& pa Authentication::ResumeResponse* resume = new Authentication::ResumeResponse(); resume->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); AsyncWrite(resume); - return false; + return; } Field* fields = result->Fetch(); @@ -370,20 +346,16 @@ bool Battlenet::Session::HandleResumeRequest(PacketHeader& header, BitStream& pa request->Modules.push_back(thumbprint); request->Modules.push_back(resume); AsyncWrite(request); - return true; } -bool Battlenet::Session::HandleProofResponse(PacketHeader& header, BitStream& packet) +void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proof) { - Authentication::ProofResponse proof(header, packet); - proof.Read(); - if (_modulesWaitingForData.size() < proof.Modules.size()) { Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_CORRUPTED_MODULE); AsyncWrite(complete); - return true; + return; } ServerPacket* response = nullptr; @@ -402,32 +374,29 @@ bool Battlenet::Session::HandleProofResponse(PacketHeader& header, BitStream& pa } AsyncWrite(response); - return true; + return; } -bool Battlenet::Session::HandlePing(PacketHeader& /*header*/, BitStream& /*packet*/) +void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/) { AsyncWrite(new Connection::Pong()); - return true; } -bool Battlenet::Session::HandleEnableEncryption(PacketHeader& /*header*/, BitStream& /*packet*/) +void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption const& /*enableEncryption*/) { _crypt.Init(&K); - return true; } -bool Battlenet::Session::HandleLogoutRequest(PacketHeader& /*header*/, BitStream& /*packet*/) +void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); stmt->setString(0, ""); stmt->setBool(1, false); stmt->setUInt32(2, _accountId); LoginDatabase.Execute(stmt); - return true; } -bool Battlenet::Session::HandleListSubscribeRequest(PacketHeader& /*header*/, BitStream& /*packet*/) +void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/) { sRealmList->UpdateIfNeed(); @@ -491,21 +460,17 @@ bool Battlenet::Session::HandleListSubscribeRequest(PacketHeader& /*header*/, Bi counts->RealmData.push_back(new WoWRealm::ListComplete()); AsyncWrite(counts); - return true; } -bool Battlenet::Session::HandleJoinRequestV2(PacketHeader& header, BitStream& packet) +void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join) { - WoWRealm::JoinRequestV2 join(header, packet); - join.Read(); - WoWRealm::JoinResponseV2* result = new WoWRealm::JoinResponseV2(); Realm const* realm = sRealmList->GetRealm(join.Realm); if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE)) { result->Response = WoWRealm::JoinResponseV2::FAILURE; AsyncWrite(result); - return true; + return; } result->ServerSeed = uint32(rand32()); @@ -535,22 +500,21 @@ bool Battlenet::Session::HandleJoinRequestV2(PacketHeader& header, BitStream& pa result->IPv4.emplace_back(realm->LocalAddress, realm->port); AsyncWrite(result); - return true; } void Battlenet::Session::ReadHandler() { - BitStream packet(std::move(GetReadBuffer())); - _crypt.DecryptRecv(packet.GetBuffer(), packet.GetSize()); + BitStream stream(std::move(GetReadBuffer())); + _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize()); - while (!packet.IsRead()) + while (!stream.IsRead()) { try { PacketHeader header; - header.Opcode = packet.Read(6); - if (packet.Read(1)) - header.Channel = packet.Read(4); + header.Opcode = stream.Read(6); + if (stream.Read(1)) + header.Channel = stream.Read(4); if (header.Channel != AUTHENTICATION && !_authed) { @@ -559,12 +523,11 @@ void Battlenet::Session::ReadHandler() return; } - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", header.ToString().c_str()); - std::map::const_iterator itr = Handlers.find(header); - if (itr != Handlers.end()) + if (ClientPacket* packet = sBattlenetPacketFactory.Create(header, stream)) { - if ((this->*(itr->second))(header, packet)) - break; + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", packet->ToString().c_str()); + packet->CallHandler(this); + delete packet; } else { @@ -572,7 +535,7 @@ void Battlenet::Session::ReadHandler() break; } - packet.AlignToNextByte(); + stream.AlignToNextByte(); } catch (BitStreamPositionException const& e) { diff --git a/src/server/authserver/Server/BattlenetSession.h b/src/server/authserver/Server/BattlenetSession.h index c3e4afee19b..2798949de1c 100644 --- a/src/server/authserver/Server/BattlenetSession.h +++ b/src/server/authserver/Server/BattlenetSession.h @@ -59,21 +59,21 @@ namespace Battlenet explicit Session(tcp::socket&& socket); ~Session(); - typedef bool(Session::*PacketHandler)(PacketHeader& socket, BitStream& packet); + void LogUnhandledPacket(ClientPacket const& packet); // Authentication - bool HandleLogonRequest(PacketHeader& header, BitStream& packet); - bool HandleResumeRequest(PacketHeader& header, BitStream& packet); - bool HandleProofResponse(PacketHeader& header, BitStream& packet); + void HandleLogonRequest(Authentication::LogonRequest const& logonRequest); + void HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest); + void HandleProofResponse(Authentication::ProofResponse const& proofResponse); // Connection - bool HandlePing(PacketHeader& header, BitStream& packet); - bool HandleEnableEncryption(PacketHeader& header, BitStream& packet); - bool HandleLogoutRequest(PacketHeader& header, BitStream& packet); + void HandlePing(Connection::Ping const& ping); + void HandleEnableEncryption(Connection::EnableEncryption const& enableEncryption); + void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest); // WoWRealm - bool HandleListSubscribeRequest(PacketHeader& header, BitStream& packet); - bool HandleJoinRequestV2(PacketHeader& header, BitStream& packet); + void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest); + void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest); void Start() override; -- cgit v1.2.3 From 238b1947099a89b43d76fbfbb37afb47109adda1 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 16:36:19 +0200 Subject: Core/Authserver: Added battle.net profile channel opcode definitions --- .../Server/BattlenetPackets/BattlenetPackets.h | 2 +- .../Server/BattlenetPackets/ProfilePackets.h | 44 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/server/authserver/Server/BattlenetPackets/ProfilePackets.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h index 48e7a470ec5..3ceee794d03 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h @@ -27,6 +27,6 @@ #include "SupportPackets.h" #include "AchievementPackets.h" #include "CachePackets.h" -//#include "ProfilePackets.h" +#include "ProfilePackets.h" #endif // BattlenetPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/ProfilePackets.h b/src/server/authserver/Server/BattlenetPackets/ProfilePackets.h new file mode 100644 index 00000000000..d08fa4883c5 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/ProfilePackets.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ProfilePackets_h__ +#define ProfilePackets_h__ + +#include "BattlenetPacketsBase.h" + +namespace Battlenet +{ + namespace Profile + { + enum Opcode + { + CMSG_READ_REQUEST = 0x0, // Not implemented + CMSG_ADDRESS_QUERY_REQUEST = 0x1, // Not implemented + CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST = 0x2, // Not implemented + CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST = 0x3, // Not implemented + CMSG_CHANGE_SETTINGS = 0x5, // Not implemented + + SMSG_READ_RESPONSE = 0x0, // Not implemented + SMSG_ADDRESS_QUERY_RESPONSE = 0x1, // Not implemented + SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE = 0x2, // Not implemented + SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE = 0x3, // Not implemented + SMSG_SETTINGS_AVAILABLE = 0x4 // Not implemented + }; + } +} + +#endif // ProfilePackets_h__ -- cgit v1.2.3 From b8b7b503ba2db40c4fe97cb5ffaab5e2cb0e2766 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 5 Oct 2014 17:57:01 +0200 Subject: Core/Authserver: Added battle.net chat channel opcode definitions --- .../Server/BattlenetPackets/BattlenetPackets.h | 2 +- .../Server/BattlenetPackets/ChatPackets.h | 63 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/server/authserver/Server/BattlenetPackets/ChatPackets.h (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h index 3ceee794d03..d4cd8600266 100644 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h @@ -23,7 +23,7 @@ #include "WoWRealmPackets.h" #include "FriendsPackets.h" #include "PresencePackets.h" -//#include "ChatPackets.h" +#include "ChatPackets.h" #include "SupportPackets.h" #include "AchievementPackets.h" #include "CachePackets.h" diff --git a/src/server/authserver/Server/BattlenetPackets/ChatPackets.h b/src/server/authserver/Server/BattlenetPackets/ChatPackets.h new file mode 100644 index 00000000000..ee11a1b732e --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/ChatPackets.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ChatPackets_h__ +#define ChatPackets_h__ + +#include "BattlenetPacketsBase.h" + +namespace Battlenet +{ + namespace Chat + { + enum Opcode + { + CMSG_JOIN_REQUEST_2 = 0x00, // Not implemented + CMSG_LEAVE_REQUEST = 0x02, // Not implemented + CMSG_INVITE_REQUEST = 0x03, // Not implemented + CMSG_CREATE_AND_INVITE_REQUEST = 0x0A, // Not implemented + CMSG_MESSAGE_SEND = 0x0B, // Not implemented + CMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented + CMSG_REPORT_SPAM_REQUEST = 0x0E, // Not implemented + CMSG_WHISPER_SEND = 0x13, // Not implemented + CMSG_ENUM_CATEGORY_DESCRIPTIONS = 0x15, // Not implemented + CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented + CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented + CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Not implemented + + SMSG_MEMBERSHIP_CHANGE_NOTIFY = 0x01, // Not implemented + SMSG_INVITE_NOTIFY = 0x04, // Not implemented + SMSG_INVITE_CANCELED = 0x07, // Not implemented + SMSG_MESSAGE_RECV = 0x0B, // Not implemented + SMSG_MESSAGE_UNDELIVERABLE = 0x0C, // Not implemented + SMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented + SMSG_INVITE_FAILURE = 0x0F, // Not implemented + SMSG_SYSTEM_MESSAGE = 0x10, // Not implemented + SMSG_MESSAGE_BLOCKED = 0x12, // Not implemented + SMSG_WHISPER_RECV = 0x13, // Not implemented + SMSG_WHISPER_UNDELIVERABLE = 0x14, // Not implemented + SMSG_CATEGORY_DESCRIPTIONS = 0x16, // Not implemented + SMSG_CONFERENCE_DESCRIPTIONS = 0x18, // Not implemented + SMSG_CONFERENCE_MEMBER_COUNTS = 0x1A, // Not implemented + SMSG_JOIN_NOTIFY_2 = 0x1B, // Not implemented + SMSG_MODIFY_CHANNEL_LIST_RESPONSE = 0x1C, // Not implemented + SMSG_CONFIG_CHANGED = 0x1D // Not implemented + }; + } +} + +#endif // ChatPackets_h__ -- cgit v1.2.3 From 1b2b3278971aadba7778ef49b299c0c202b38af7 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sun, 5 Oct 2014 20:18:26 +0200 Subject: Misc: Update some conf values/texts --- src/server/worldserver/worldserver.conf.dist | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/server') diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index c09d451592d..ecdc8cf4b98 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -230,9 +230,9 @@ GridUnload = 1 # SocketTimeOutTime # Description: Time (in milliseconds) after which a connection being idle on the character # selection screen is disconnected. -# Default: 900000 - (15 minutes) +# Default: 90000 - (90 seconds) -SocketTimeOutTime = 900000 +SocketTimeOutTime = 90000 # # SessionAddDelay @@ -288,7 +288,7 @@ PlayerSave.Stats.SaveOnlyOnLogout = 1 # # mmap.enablePathFinding -# Description: Enable/Disable pathfinding using mmaps - experimental. +# Description: Enable/Disable pathfinding using mmaps - recommended. # Default: 0 - (Disabled) # 1 - (Enabled) @@ -2034,9 +2034,9 @@ AutoBroadcast.Center = 0 # # AutoBroadcast.Timer # Description: Timer (in milliseconds) for auto broadcasts. -# Default: 60000 - (60 seconds) +# Default: 60000 - (10 minutes) -AutoBroadcast.Timer = 60000 +AutoBroadcast.Timer = 600000 # ################################################################################################### -- cgit v1.2.3 From 986c1e7d2a742ff4cd83154d967a4264cb85c441 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sun, 5 Oct 2014 20:37:45 +0200 Subject: Update worldserver.conf.dist stupid mistake.... --- src/server/worldserver/worldserver.conf.dist | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/server') diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index ecdc8cf4b98..ac307a254e9 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -230,9 +230,9 @@ GridUnload = 1 # SocketTimeOutTime # Description: Time (in milliseconds) after which a connection being idle on the character # selection screen is disconnected. -# Default: 90000 - (90 seconds) +# Default: 900000 - (15 minutes) -SocketTimeOutTime = 90000 +SocketTimeOutTime = 900000 # # SessionAddDelay @@ -266,9 +266,9 @@ ChangeWeatherInterval = 600000 # # PlayerSaveInterval # Description: Time (in milliseconds) for player save interval. -# Default: 900000 - (15 min) +# Default: 90000 - (90 seconds) -PlayerSaveInterval = 900000 +PlayerSaveInterval = 90000 # # PlayerSave.Stats.MinLevel -- cgit v1.2.3 From ee274a792cfeeabb6574a897bd764dc1fcc70596 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 5 Oct 2014 17:21:17 -0500 Subject: Authserver/BattleNet: Added some initial work in the Friends (3) and Presence (4) Battle.net channels --- .../authserver/Server/BattlenetPacketFactory.h | 8 + .../Server/BattlenetPackets/FriendsPackets.cpp | 180 +++++++++++++++++++++ .../Server/BattlenetPackets/FriendsPackets.h | 107 +++++++++++- .../Server/BattlenetPackets/PresencePackets.cpp | 50 ++++++ .../Server/BattlenetPackets/PresencePackets.h | 26 +++ 5 files changed, 369 insertions(+), 2 deletions(-) create mode 100644 src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp create mode 100644 src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPacketFactory.h b/src/server/authserver/Server/BattlenetPacketFactory.h index fa7b907ec79..a0cbd8f5913 100644 --- a/src/server/authserver/Server/BattlenetPacketFactory.h +++ b/src/server/authserver/Server/BattlenetPacketFactory.h @@ -58,6 +58,14 @@ namespace Battlenet _creators[PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM)] = &New; _creators[PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM)] = &New; + + _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS)] = &New; + // _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS)] = &New; + // _creators[PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS)] = &New; + _creators[PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS)] = &New; + + // _creators[PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE)] = &New; + // _creators[PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE)] = &New; } template diff --git a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp new file mode 100644 index 00000000000..336755acd4c --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "BattlenetSession.h" +#include "FriendsPackets.h" + +void Battlenet::Friends::SocialnetworkCheckConnected::Read() +{ + SocialNetworkId = _stream.Read(32); +} + +std::string Battlenet::Friends::SocialnetworkCheckConnected::ToString() const +{ + return "Battlenet::Friends::SocialnetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); +} + +void Battlenet::Friends::SocialnetworkCheckConnected::CallHandler(Session* session) const +{ + SocialNetworkCheckConnectedResult* result = new SocialNetworkCheckConnectedResult(SocialNetworkId); + session->AsyncWrite(result); +} + +void Battlenet::Friends::SocialnetworkConnect::Read() +{ + int32 unk1 = _stream.Read(32); + uint32 size1 = _stream.Read(9); + auto data1 = _stream.ReadBytes(size1); + uint32 size2 = _stream.Read(7); + auto data2 = _stream.ReadBytes(size2); +} + +std::string Battlenet::Friends::SocialnetworkConnect::ToString() const +{ + return "Battlenet::Friends::SocialnetworkConnect"; +} + +void Battlenet::Friends::SocialnetworkConnect::CallHandler(Session* session) const +{ + +} + +std::string Battlenet::Friends::SocialNetworkConnectResult::ToString() const +{ + return "Battlenet::Friends::SocialNetworkConnectResult"; +} + +void Battlenet::Friends::SocialNetworkConnectResult::Write() +{ + +} + +std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const +{ + return "Battlenet::Friends::SocialNetworkCheckConnectedResult"; +} + +void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() +{ + _stream.Write(0, 23); // Ignored + volatile uint16 res = 0; + _stream.Write(res, 16); // Unknown + _stream.Write(SocialNetworkId, 32); +} + +void Battlenet::Friends::GetFriendsOfFriend::Read() +{ + uint8 unk = _stream.Read(2); + uint32 unk1 = _stream.Read(32); +} + +std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const +{ + return "Battlenet::Friends::GetFriendsOfFriend"; +} + +void Battlenet::Friends::GetFriendsOfFriend::CallHandler(Session* session) const +{ + +} + +void Battlenet::Friends::RealIdFriendInvite::Read() +{ + _stream.Read(32); + uint8 type = _stream.Read(3); + + switch (type) + { + case 0: + { + _stream.Read(32); // Presence Id? + break; + } + case 1: // GameAccount? + { + _stream.Read(8); + _stream.Read(32); + _stream.Read(32); + uint8 size = _stream.Read(7); // Only if *(a1 + 16) <= 0x64 + _stream.ReadBytes(size); + break; + } + case 2: + Email = _stream.ReadString(9, 3); + break; + case 3: + { + _stream.Read(32); + break; + } + case 4: + { + _stream.Read(64); + _stream.Read(32); + break; + } + } + + _stream.Read(1); + + if (_stream.Read(1)) + Message = _stream.ReadString(9); + + _stream.Read(32); +} + +std::string Battlenet::Friends::RealIdFriendInvite::ToString() const +{ + return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message; +} + +void Battlenet::Friends::RealIdFriendInvite::CallHandler(Session* session) const +{ + FriendInviteResult* result = new FriendInviteResult(); + session->AsyncWrite(result); +} + +std::string Battlenet::Friends::FriendInviteResult::ToString() const +{ + return "Battlenet::Friends::RealIdFriendInviteResult"; +} + +void Battlenet::Friends::FriendInviteResult::Write() +{ + bool hasNames = false; + _stream.Write(hasNames, 1); + if (hasNames) + { + _stream.WriteString("Testing1", 8); + _stream.WriteString("Testing2", 8); + } + _stream.Write(5, 32); + + _stream.Write(0, 0xC); // Ignored + + _stream.Write(1, 16); + + bool moreInfo = true; + _stream.Write(moreInfo, 1); + if (moreInfo) + { + _stream.Write(0, 8); + _stream.Write(4, 32); + _stream.Write(3, 32); + _stream.WriteString("Testing3", 7, 2); + } +} diff --git a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h index 305fa1a601e..e58fbdff180 100644 --- a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h +++ b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h @@ -37,7 +37,7 @@ namespace Battlenet CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Not implemented CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Not implemented CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Not implemented - CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, // Not implemented + CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented @@ -49,10 +49,113 @@ namespace Battlenet SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Not implemented SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Not implemented SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Not implemented - SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, // Not implemented + SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented }; + + class SocialnetworkConnect final : public ClientPacket + { + public: + SocialnetworkConnect(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS) && "Invalid packet header for SocialnetworkConnect"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class SocialNetworkConnectResult final : public ServerPacket + { + public: + SocialNetworkConnectResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS)) + { + } + + void Write() override; + std::string ToString() const override; + }; + + class SocialnetworkCheckConnected final : public ClientPacket + { + public: + SocialnetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + uint32 SocialNetworkId; + }; + + class SocialNetworkCheckConnectedResult final : public ServerPacket + { + public: + SocialNetworkCheckConnectedResult(uint32 socialNetworkId) : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), SocialNetworkId(socialNetworkId) + { + } + + void Write() override; + std::string ToString() const override; + + uint32 SocialNetworkId; + }; + + class GetFriendsOfFriend final : public ClientPacket + { + public: + GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class FriendsOfFriend final : public ServerPacket + { + public: + FriendsOfFriend() : ServerPacket(PacketHeader(SMSG_FRIENDS_OF_FRIEND, FRIENDS)) + { + } + + void Write() override; + std::string ToString() const override; + }; + + class RealIdFriendInvite final : public ClientPacket + { + public: + RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + std::string Email; + std::string Message; + }; + + class FriendInviteResult final : public ServerPacket + { + public: + FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS)) + { + } + + void Write() override; + std::string ToString() const override; + }; } } diff --git a/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp b/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp new file mode 100644 index 00000000000..77671a7f053 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "BattlenetSession.h" +#include "PresencePackets.h" + +f +void Battlenet::Presence::UpdateRequest::Read() +{ + +} + +std::string Battlenet::Presence::UpdateRequest::ToString() const +{ + return "Battlenet::Presence::UpdateRequest"; +} + +void Battlenet::Presence::UpdateRequest::CallHandler(Session* session) const +{ + +} + +void Battlenet::Presence::StatisticSubscribe::Read() +{ + +} + +std::string Battlenet::Presence::StatisticSubscribe::ToString() const +{ + return "Battlenet::Presence::StatisticSubscribe"; +} + +void Battlenet::Presence::StatisticSubscribe::CallHandler(Session* session) const +{ + +} diff --git a/src/server/authserver/Server/BattlenetPackets/PresencePackets.h b/src/server/authserver/Server/BattlenetPackets/PresencePackets.h index baf2715f564..0a934f2c2ca 100644 --- a/src/server/authserver/Server/BattlenetPackets/PresencePackets.h +++ b/src/server/authserver/Server/BattlenetPackets/PresencePackets.h @@ -33,6 +33,32 @@ namespace Battlenet SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented SMSG_STATISTICS_UPDATE = 0x3 // Not implemented }; + + class UpdateRequest final : public ClientPacket + { + public: + UpdateRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_UPDATE_REQUEST, PRESENCE) && "Invalid packet header for UpdateRequest"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class StatisticSubscribe final : public ClientPacket + { + public: + StatisticSubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_STATISTIC_SUBSCRIBE, PRESENCE) && "Invalid packet header for StatisticSubscribe"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; } } -- cgit v1.2.3 From 7b02e5fc78a9a08639892e053fe79404baecdd14 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 5 Oct 2014 17:22:26 -0500 Subject: Authserver/Battle.net: Fixed a typo --- src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp b/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp index 77671a7f053..46ce7fa1b36 100644 --- a/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp @@ -18,7 +18,7 @@ #include "BattlenetSession.h" #include "PresencePackets.h" -f + void Battlenet::Presence::UpdateRequest::Read() { -- cgit v1.2.3 From 43f0b67e99ed96df7dd9bbc64d5ffbcf8af2511f Mon Sep 17 00:00:00 2001 From: Aokromes Date: Mon, 6 Oct 2014 16:29:30 +0200 Subject: Update worldserver.conf.dist Match the rest of the conf. --- src/server/worldserver/worldserver.conf.dist | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/server') diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index fce136bc21a..6c3972de421 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -3288,6 +3288,8 @@ Currency.ConquestPointsDefaultWeekCap = 1350 Currency.ConquestPointsArenaReward = 180 # +################################################################################################### + ################################################################################################### # PACKET SPOOF PROTECTION SETTINGS # -- cgit v1.2.3 From 0fb9ba4f2848cf5a7e263e1b9d58cf101d063e85 Mon Sep 17 00:00:00 2001 From: DDuarte Date: Mon, 6 Oct 2014 21:59:56 +0100 Subject: Core/Players: Update gold cap > As of Patch 4.0.1, the gold cap is 999,999 --- src/server/game/Entities/Player/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0b7f358a1d3..330914cd851 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -151,7 +151,7 @@ uint32 const MasterySpells[MAX_CLASSES] = 87491, // Druid }; -uint64 const MAX_MONEY_AMOUNT = static_cast(std::numeric_limits::max()); +uint64 const MAX_MONEY_AMOUNT = 9999999999ULL; // == PlayerTaxi ================================================ -- cgit v1.2.3 From def151bb18b31e829ebe3761ff857990fca92a7e Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Tue, 7 Oct 2014 21:49:50 +0200 Subject: Core/SAI: Fix text over errors --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 4b93c35787c..9979891e2e6 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1183,7 +1183,18 @@ bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused uint32 entry = 0; if (e.entryOrGuid >= 0) - entry = uint32(e.entryOrGuid); + { + switch (e.GetEventType()) + { + case SMART_EVENT_TEXT_OVER: + entry = e.event.textOver.creatureEntry; + id = e.event.textOver.textGroupID; + break; + default: + entry = uint32(e.entryOrGuid); + break; + } + } else { entry = uint32(abs(e.entryOrGuid)); @@ -1202,7 +1213,7 @@ bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused if (error) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.source_type, e.GetActionType(), id); + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType(), id); return false; } -- cgit v1.2.3 From db88bf02b54fd3596a2bf90cfc3ad55cd42b158d Mon Sep 17 00:00:00 2001 From: jackpoz Date: Tue, 7 Oct 2014 22:15:01 +0200 Subject: Core/LFG: Fix Leader flag being ignored Fix bug added in 5ca00bc14d38c5ad49f0ab4500af52e645133826 that removed Leader flag of LFG without ever adding it back, giving leadership to players who didn't want it. --- src/server/game/DungeonFinding/LFGMgr.cpp | 28 ++++++++++++---------------- src/server/game/DungeonFinding/LFGMgr.h | 2 +- 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'src/server') diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index c1f2fe33889..ac6de073543 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -770,10 +770,9 @@ void LFGMgr::GetCompatibleDungeons(LfgDungeonSet& dungeons, GuidSet const& playe Check if a group can be formed with the given group roles @param[in] groles Map of roles to check - @param[in] removeLeaderFlag Determines if we have to remove leader flag (only used first call, Default = true) @return True if roles are compatible */ -bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true*/) +bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles) { if (groles.empty()) return false; @@ -782,21 +781,18 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true uint8 tank = 0; uint8 healer = 0; - if (removeLeaderFlag) - for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it) - it->second &= ~PLAYER_ROLE_LEADER; - for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it) { - if (it->second == PLAYER_ROLE_NONE) + uint8 role = it->second & ~PLAYER_ROLE_LEADER; + if (role == PLAYER_ROLE_NONE) return false; - if (it->second & PLAYER_ROLE_DAMAGE) + if (role & PLAYER_ROLE_DAMAGE) { - if (it->second != PLAYER_ROLE_DAMAGE) + if (role != PLAYER_ROLE_DAMAGE) { it->second -= PLAYER_ROLE_DAMAGE; - if (CheckGroupRoles(groles, false)) + if (CheckGroupRoles(groles)) return true; it->second += PLAYER_ROLE_DAMAGE; } @@ -806,12 +802,12 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true damage++; } - if (it->second & PLAYER_ROLE_HEALER) + if (role & PLAYER_ROLE_HEALER) { - if (it->second != PLAYER_ROLE_HEALER) + if (role != PLAYER_ROLE_HEALER) { it->second -= PLAYER_ROLE_HEALER; - if (CheckGroupRoles(groles, false)) + if (CheckGroupRoles(groles)) return true; it->second += PLAYER_ROLE_HEALER; } @@ -821,12 +817,12 @@ bool LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true healer++; } - if (it->second & PLAYER_ROLE_TANK) + if (role & PLAYER_ROLE_TANK) { - if (it->second != PLAYER_ROLE_TANK) + if (role != PLAYER_ROLE_TANK) { it->second -= PLAYER_ROLE_TANK; - if (CheckGroupRoles(groles, false)) + if (CheckGroupRoles(groles)) return true; it->second += PLAYER_ROLE_TANK; } diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index b75686945a5..e368791c134 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -411,7 +411,7 @@ class LFGMgr /// Checks if all players are queued bool AllQueued(GuidList const& check); /// Checks if given roles match, modifies given roles map with new roles - static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); + static bool CheckGroupRoles(LfgRolesMap &groles); /// Checks if given players are ignoring each other static bool HasIgnore(ObjectGuid guid1, ObjectGuid guid2); /// Sends queue status to player -- cgit v1.2.3 From ec784be893123a20534ad72b3adc0411e90b031a Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Tue, 7 Oct 2014 22:56:23 +0200 Subject: Core/SAI: Ingore text valid errors for SMART_TARGET_CREATURE_DISTANCE / SMART_TARGET_CREATURE_RANGE / SMART_TARGET_CLOSEST_CREATURE --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 9979891e2e6..80ca1b27be4 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1184,15 +1184,23 @@ bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused if (e.entryOrGuid >= 0) { - switch (e.GetEventType()) + if (e.GetEventType() == SMART_EVENT_TEXT_OVER) { - case SMART_EVENT_TEXT_OVER: - entry = e.event.textOver.creatureEntry; - id = e.event.textOver.textGroupID; - break; - default: - entry = uint32(e.entryOrGuid); - break; + entry = e.event.textOver.creatureEntry; + id = e.event.textOver.textGroupID; + } + else + { + switch (e.GetTargetType()) + { + case SMART_TARGET_CREATURE_DISTANCE: + case SMART_TARGET_CREATURE_RANGE: + case SMART_TARGET_CLOSEST_CREATURE: + return true; // ignore + default: + entry = uint32(e.entryOrGuid); + break; + } } } else @@ -1213,7 +1221,7 @@ bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused if (error) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType(), id); + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id); return false; } -- cgit v1.2.3 From b781a4dc332b7d37bcae7e908f08ca2171c0e30b Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 8 Oct 2014 17:59:27 +0200 Subject: Core/Logging: Replaced direct calls to GetCounter() in logs with ToString() --- src/server/game/Battlegrounds/ArenaTeam.cpp | 6 +- src/server/game/Battlegrounds/Battleground.cpp | 44 +++++------ .../game/Battlegrounds/BattlegroundQueue.cpp | 8 +- src/server/game/DungeonFinding/LFGMgr.cpp | 88 +++++++++++----------- src/server/game/DungeonFinding/LFGScripts.cpp | 4 +- src/server/game/Handlers/CharacterHandler.cpp | 2 +- src/server/game/Handlers/LFGHandler.cpp | 12 +-- src/server/game/Handlers/PetitionsHandler.cpp | 2 +- src/server/game/Maps/Map.cpp | 4 +- src/server/scripts/Commands/cs_debug.cpp | 22 +++--- src/server/shared/Logging/Log.cpp | 2 +- src/server/shared/Logging/Log.h | 2 +- 12 files changed, 98 insertions(+), 98 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index ef3d4e26865..6831cc42f49 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -120,7 +120,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid) // Check if player is already in a similar arena team if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromDB(playerGuid, GetType()) != 0) { - TC_LOG_DEBUG("bg.arena", "Arena: Player %s (guid: %u) already has an arena team of type %u", playerName.c_str(), playerGuid.GetCounter(), GetType()); + TC_LOG_DEBUG("bg.arena", "Arena: %s %s already has an arena team of type %u", playerGuid.ToString().c_str(), playerName.c_str(), GetType()); return false; } @@ -179,7 +179,7 @@ bool ArenaTeam::AddMember(ObjectGuid playerGuid) player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1); } - TC_LOG_INFO("bg.arena", "Player: %s [GUID: %u] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), playerGuid.GetCounter(), GetType(), GetId(), GetName().c_str()); + TC_LOG_INFO("bg.arena", "Player: %s [%s] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), playerGuid.ToString().c_str(), GetType(), GetId(), GetName().c_str()); return true; } @@ -245,7 +245,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result) // Delete member if character information is missing if (newMember.Name.empty()) { - TC_LOG_ERROR("sql.sql", "ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, newMember.Guid.GetCounter()); + TC_LOG_ERROR("sql.sql", "ArenaTeam %u has member with empty name - probably %s doesn't exist, deleting him from memberlist!", arenaTeamId, newMember.Guid.ToString().c_str()); DelMember(newMember.Guid, true); continue; } diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 3fb91ee4a74..99b1f240e5e 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -566,8 +566,8 @@ Player* Battleground::_GetPlayer(ObjectGuid guid, bool offlineRemove, char const { player = ObjectAccessor::FindPlayer(guid); if (!player) - TC_LOG_ERROR("bg.battleground", "Battleground::%s: player (GUID: %u) not found for BG (map: %u, instance id: %u)!", - context, guid.GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::%s: player (%s) not found for BG (map: %u, instance id: %u)!", + context, guid.ToString().c_str(), m_MapId, m_InstanceID); } return player; } @@ -1385,8 +1385,8 @@ void Battleground::DoorClose(uint32 type) } } else - TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: door gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::DoorClose: door gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID); } void Battleground::DoorOpen(uint32 type) @@ -1397,8 +1397,8 @@ void Battleground::DoorOpen(uint32 type) obj->SetGoState(GO_STATE_ACTIVE); } else - TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: door gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::DoorOpen: door gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID); } GameObject* Battleground::GetBGObject(uint32 type, bool logError) @@ -1407,11 +1407,11 @@ GameObject* Battleground::GetBGObject(uint32 type, bool logError) if (!obj) { if (logError) - TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID); else - TC_LOG_INFO("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_INFO("bg.battleground", "Battleground::GetBGObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID); } return obj; } @@ -1422,11 +1422,11 @@ Creature* Battleground::GetBGCreature(uint32 type, bool logError) if (!creature) { if (logError) - TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID); else - TC_LOG_INFO("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_INFO("bg.battleground", "Battleground::GetBGCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID); } return creature; } @@ -1507,8 +1507,8 @@ bool Battleground::DelCreature(uint32 type) return true; } - TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: creature (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgCreatures[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::DelCreature: creature (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgCreatures[type].ToString().c_str(), m_MapId, m_InstanceID); BgCreatures[type].Clear(); return false; } @@ -1525,8 +1525,8 @@ bool Battleground::DelObject(uint32 type) BgObjects[type].Clear(); return true; } - TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: gameobject (type: %u, GUID: %u) not found for BG (map: %u, instance id: %u)!", - type, BgObjects[type].GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::DelObject: gameobject (type: %u, %s) not found for BG (map: %u, instance id: %u)!", + type, BgObjects[type].ToString().c_str(), m_MapId, m_InstanceID); BgObjects[type].Clear(); return false; } @@ -1640,8 +1640,8 @@ void Battleground::HandleTriggerBuff(ObjectGuid go_guid) index--; if (index < 0) { - TC_LOG_ERROR("bg.battleground", "Battleground::HandleTriggerBuff: cannot find buff gameobject (GUID: %u, entry: %u, type: %u) in internal data for BG (map: %u, instance id: %u)!", - go_guid.GetCounter(), obj->GetEntry(), obj->GetGoType(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::HandleTriggerBuff: cannot find buff gameobject (%s, entry: %u, type: %u) in internal data for BG (map: %u, instance id: %u)!", + go_guid.ToString().c_str(), obj->GetEntry(), obj->GetGoType(), m_MapId, m_InstanceID); return; } @@ -1764,8 +1764,8 @@ int32 Battleground::GetObjectType(ObjectGuid guid) for (uint32 i = 0; i < BgObjects.size(); ++i) if (BgObjects[i] == guid) return i; - TC_LOG_ERROR("bg.battleground", "Battleground::GetObjectType: player used gameobject (GUID: %u) which is not in internal data for BG (map: %u, instance id: %u), cheating?", - guid.GetCounter(), m_MapId, m_InstanceID); + TC_LOG_ERROR("bg.battleground", "Battleground::GetObjectType: player used gameobject (%s) which is not in internal data for BG (map: %u, instance id: %u), cheating?", + guid.ToString().c_str(), m_MapId, m_InstanceID); return -1; } diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 46fbd43bfbb..a3b0051e697 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -293,7 +293,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) std::string playerName = "Unknown"; if (Player* player = ObjectAccessor::FindPlayer(guid)) playerName = player->GetName(); - TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player %s (GUID: %u)", playerName.c_str(), guid.GetCounter()); + TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: couldn't find player %s (%s)", playerName.c_str(), guid.ToString().c_str()); return; } @@ -328,10 +328,10 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) //player can't be in queue without group, but just in case if (bracket_id == -1) { - TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: ERROR Cannot find groupinfo for player GUID: %u", guid.GetCounter()); + TC_LOG_ERROR("bg.battleground", "BattlegroundQueue: ERROR Cannot find groupinfo for %s", guid.ToString().c_str()); return; } - TC_LOG_DEBUG("bg.battleground", "BattlegroundQueue: Removing player GUID %u, from bracket_id %u", guid.GetCounter(), (uint32)bracket_id); + TC_LOG_DEBUG("bg.battleground", "BattlegroundQueue: Removing %s, from bracket_id %u", guid.ToString().c_str(), (uint32)bracket_id); // ALL variables are correctly set // We can ignore leveling up in queue - it should not cause crash @@ -361,7 +361,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) { if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(group->ArenaTeamId)) { - TC_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %u by opponents rating: %u", guid.GetCounter(), group->OpponentsTeamRating); + TC_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %s by opponents rating: %u", guid.ToString().c_str(), group->OpponentsTeamRating); if (Player* player = ObjectAccessor::FindPlayer(guid)) at->MemberLost(player, group->OpponentsMatchmakerRating); else diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index ac6de073543..7d662c2fc75 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -492,8 +492,8 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const // Can't join. Send result if (joinData.result != LFG_JOIN_OK) { - TC_LOG_DEBUG("lfg.join", "%u joining with %u members. Result: %u, Dungeons: %s", - guid.GetCounter(), grp ? grp->GetMembersCount() : 1, joinData.result, ConcatenateDungeons(dungeons).c_str()); + TC_LOG_DEBUG("lfg.join", "%s joining with %u members. Result: %u, Dungeons: %s", + guid.ToString().c_str(), grp ? grp->GetMembersCount() : 1, joinData.result, ConcatenateDungeons(dungeons).c_str()); if (!dungeons.empty()) // Only should show lockmap when have no dungeons available joinData.lockmap.clear(); @@ -505,7 +505,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const if (isRaid) { - TC_LOG_DEBUG("lfg.join", "%u trying to join raid browser and it's disabled.", guid.GetCounter()); + TC_LOG_DEBUG("lfg.join", "%s trying to join raid browser and it's disabled.", guid.ToString().c_str()); return; } @@ -571,7 +571,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const debugNames.append(player->GetName()); } - TC_LOG_DEBUG("lfg.join", "%u joined (%s), Members: %s. Dungeons (%u): %s", guid.GetCounter(), + TC_LOG_DEBUG("lfg.join", "%s joined (%s), Members: %s. Dungeons (%u): %s", guid.ToString().c_str(), grp ? "group" : "player", debugNames.c_str(), uint32(dungeons.size()), ConcatenateDungeons(dungeons).c_str()); } @@ -585,7 +585,7 @@ void LFGMgr::LeaveLfg(ObjectGuid guid) { ObjectGuid gguid = guid.IsGroup() ? guid : GetGroup(guid); - TC_LOG_DEBUG("lfg.leave", "%u left (%s)", guid.GetCounter(), guid == gguid ? "group" : "player"); + TC_LOG_DEBUG("lfg.leave", "%s left (%s)", guid.ToString().c_str(), guid == gguid ? "group" : "player"); LfgState state = GetState(guid); switch (state) @@ -939,7 +939,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, ObjectGuid guid, bool accept) LfgProposalPlayer& player = itProposalPlayer->second; player.accept = LfgAnswer(accept); - TC_LOG_DEBUG("lfg.proposal.update", "Player %u, Proposal %u, Selection: %u", guid.GetCounter(), proposalId, accept); + TC_LOG_DEBUG("lfg.proposal.update", "%s, Proposal %u, Selection: %u", guid.ToString().c_str(), proposalId, accept); if (!accept) { RemoveProposal(itProposal, LFG_UPDATETYPE_PROPOSAL_DECLINED); @@ -1067,12 +1067,12 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate if (it->second.accept == LFG_ANSWER_DENY) { updateData.updateType = type; - TC_LOG_DEBUG("lfg.proposal.remove", "%u didn't accept. Removing from queue and compatible cache", guid.GetCounter()); + TC_LOG_DEBUG("lfg.proposal.remove", "%s didn't accept. Removing from queue and compatible cache", guid.ToString().c_str()); } else { updateData.updateType = LFG_UPDATETYPE_REMOVED_FROM_QUEUE; - TC_LOG_DEBUG("lfg.proposal.remove", "%u in same group that someone that didn't accept. Removing from queue and compatible cache", guid.GetCounter()); + TC_LOG_DEBUG("lfg.proposal.remove", "%s in same group that someone that didn't accept. Removing from queue and compatible cache", guid.ToString().c_str()); } RestoreState(guid, "Proposal Fail (didn't accepted or in group with someone that didn't accept"); @@ -1086,7 +1086,7 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate } else { - TC_LOG_DEBUG("lfg.proposal.remove", "Readding %u to queue.", guid.GetCounter()); + TC_LOG_DEBUG("lfg.proposal.remove", "Readding %s to queue.", guid.ToString().c_str()); SetState(guid, LFG_STATE_QUEUED); if (gguid != guid) { @@ -1319,13 +1319,13 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId) uint32 gDungeonId = GetDungeon(gguid); if (gDungeonId != dungeonId) { - TC_LOG_DEBUG("lfg.dungeon.finish", "Group %u finished dungeon %u but queued for %u", gguid.GetCounter(), dungeonId, gDungeonId); + TC_LOG_DEBUG("lfg.dungeon.finish", "Group %s finished dungeon %u but queued for %u", gguid.ToString().c_str(), dungeonId, gDungeonId); return; } if (GetState(gguid) == LFG_STATE_FINISHED_DUNGEON) // Shouldn't happen. Do not reward multiple times { - TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u already rewarded", gguid.GetCounter()); + TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s already rewarded", gguid.ToString().c_str()); return; } @@ -1337,7 +1337,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId) ObjectGuid guid = (*it); if (GetState(guid) == LFG_STATE_FINISHED_DUNGEON) { - TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u already rewarded", gguid.GetCounter(), guid.GetCounter()); + TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s already rewarded", gguid.ToString().c_str(), guid.ToString().c_str()); continue; } @@ -1353,14 +1353,14 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId) if (!dungeon || (dungeon->type != LFG_TYPE_RANDOM && !dungeon->seasonal)) { - TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u dungeon %u is not random or seasonal", gguid.GetCounter(), guid.GetCounter(), rDungeonId); + TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s dungeon %u is not random or seasonal", gguid.ToString().c_str(), guid.ToString().c_str(), rDungeonId); continue; } Player* player = ObjectAccessor::FindPlayer(guid); if (!player || !player->IsInWorld()) { - TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u not found in world", gguid.GetCounter(), guid.GetCounter()); + TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s not found in world", gguid.ToString().c_str(), guid.ToString().c_str()); continue; } @@ -1369,7 +1369,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId) if (player->GetMapId() != mapId) { - TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u is in map %u and should be in %u to get reward", gguid.GetCounter(), guid.GetCounter(), player->GetMapId(), mapId); + TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s is in map %u and should be in %u to get reward", gguid.ToString().c_str(), guid.ToString().c_str(), player->GetMapId(), mapId); continue; } @@ -1400,7 +1400,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId) } // Give rewards - TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %u, Player: %u done dungeon %u, %s previously done.", gguid.GetCounter(), guid.GetCounter(), GetDungeon(gguid), done? " " : " not"); + TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s done dungeon %u, %s previously done.", gguid.ToString().c_str(), guid.ToString().c_str(), GetDungeon(gguid), done ? " " : " not"); LfgPlayerRewardData data = LfgPlayerRewardData(dungeon->Entry(), GetDungeon(gguid, false), done, quest); player->GetSession()->SendLfgPlayerReward(data); } @@ -1466,12 +1466,12 @@ LfgState LFGMgr::GetState(ObjectGuid guid) if (guid.IsGroup()) { state = GroupsStore[guid].GetState(); - TC_LOG_TRACE("lfg.data.group.state.get", "Group: %u, State: %u", guid.GetCounter(), state); + TC_LOG_TRACE("lfg.data.group.state.get", "Group: %s, State: %u", guid.ToString().c_str(), state); } else { state = PlayersStore[guid].GetState(); - TC_LOG_TRACE("lfg.data.player.state.get", "Player: %u, State: %u", guid.GetCounter(), state); + TC_LOG_TRACE("lfg.data.player.state.get", "Player: %s, State: %u", guid.ToString().c_str(), state); } return state; @@ -1483,12 +1483,12 @@ LfgState LFGMgr::GetOldState(ObjectGuid guid) if (guid.IsGroup()) { state = GroupsStore[guid].GetOldState(); - TC_LOG_TRACE("lfg.data.group.oldstate.get", "Group: %u, Old state: %u", guid.GetCounter(), state); + TC_LOG_TRACE("lfg.data.group.oldstate.get", "Group: %s, Old state: %u", guid.ToString().c_str(), state); } else { state = PlayersStore[guid].GetOldState(); - TC_LOG_TRACE("lfg.data.player.oldstate.get", "Player: %u, Old state: %u", guid.GetCounter(), state); + TC_LOG_TRACE("lfg.data.player.oldstate.get", "Player: %s, Old state: %u", guid.ToString().c_str(), state); } return state; @@ -1497,7 +1497,7 @@ LfgState LFGMgr::GetOldState(ObjectGuid guid) uint32 LFGMgr::GetDungeon(ObjectGuid guid, bool asId /*= true */) { uint32 dungeon = GroupsStore[guid].GetDungeon(asId); - TC_LOG_TRACE("lfg.data.group.dungeon.get", "Group: %u, asId: %u, Dungeon: %u", guid.GetCounter(), asId, dungeon); + TC_LOG_TRACE("lfg.data.group.dungeon.get", "Group: %s, asId: %u, Dungeon: %u", guid.ToString().c_str(), asId, dungeon); return dungeon; } @@ -1509,7 +1509,7 @@ uint32 LFGMgr::GetDungeonMapId(ObjectGuid guid) if (LFGDungeonData const* dungeon = GetLFGDungeon(dungeonId)) mapId = dungeon->map; - TC_LOG_TRACE("lfg.data.group.dungeon.map", "Group: %u, MapId: %u (DungeonId: %u)", guid.GetCounter(), mapId, dungeonId); + TC_LOG_TRACE("lfg.data.group.dungeon.map", "Group: %s, MapId: %u (DungeonId: %u)", guid.ToString().c_str(), mapId, dungeonId); return mapId; } @@ -1517,30 +1517,30 @@ uint32 LFGMgr::GetDungeonMapId(ObjectGuid guid) uint8 LFGMgr::GetRoles(ObjectGuid guid) { uint8 roles = PlayersStore[guid].GetRoles(); - TC_LOG_TRACE("lfg.data.player.role.get", "Player: %u, Role: %u", guid.GetCounter(), roles); + TC_LOG_TRACE("lfg.data.player.role.get", "Player: %s, Role: %u", guid.ToString().c_str(), roles); return roles; } const std::string& LFGMgr::GetComment(ObjectGuid guid) { - TC_LOG_TRACE("lfg.data.player.comment.get", "Player: %u, Comment: %s", guid.GetCounter(), PlayersStore[guid].GetComment().c_str()); + TC_LOG_TRACE("lfg.data.player.comment.get", "Player: %s, Comment: %s", guid.ToString().c_str(), PlayersStore[guid].GetComment().c_str()); return PlayersStore[guid].GetComment(); } LfgDungeonSet const& LFGMgr::GetSelectedDungeons(ObjectGuid guid) { - TC_LOG_TRACE("lfg.data.player.dungeons.selected.get", "Player: %u, Selected Dungeons: %s", guid.GetCounter(), ConcatenateDungeons(PlayersStore[guid].GetSelectedDungeons()).c_str()); + TC_LOG_TRACE("lfg.data.player.dungeons.selected.get", "Player: %s, Selected Dungeons: %s", guid.ToString().c_str(), ConcatenateDungeons(PlayersStore[guid].GetSelectedDungeons()).c_str()); return PlayersStore[guid].GetSelectedDungeons(); } LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid) { - TC_LOG_TRACE("lfg.data.player.dungeons.locked.get", "Player: %u, LockedDungeons.", guid.GetCounter()); + TC_LOG_TRACE("lfg.data.player.dungeons.locked.get", "Player: %s, LockedDungeons.", guid.ToString().c_str()); LfgLockMap lock; Player* player = ObjectAccessor::FindPlayer(guid); if (!player) { - TC_LOG_WARN("lfg.data.player.dungeons.locked.get", "Player: %u not ingame while retrieving his LockedDungeons.", guid.GetCounter()); + TC_LOG_WARN("lfg.data.player.dungeons.locked.get", "Player: %s not ingame while retrieving his LockedDungeons.", guid.ToString().c_str()); return lock; } @@ -1606,7 +1606,7 @@ LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid) uint8 LFGMgr::GetKicksLeft(ObjectGuid guid) { uint8 kicks = GroupsStore[guid].GetKicksLeft(); - TC_LOG_TRACE("lfg.data.group.kickleft.get", "Group: %u, Kicks left: %u", guid.GetCounter(), kicks); + TC_LOG_TRACE("lfg.data.group.kickleft.get", "Group: %s, Kicks left: %u", guid.ToString().c_str(), kicks); return kicks; } @@ -1615,8 +1615,8 @@ void LFGMgr::RestoreState(ObjectGuid guid, char const* debugMsg) if (guid.IsGroup()) { LfgGroupData& data = GroupsStore[guid]; - TC_LOG_TRACE("lfg.data.group.state.restore", "Group: %u (%s), State: %s, Old state: %s", - guid.GetCounter(), debugMsg, GetStateString(data.GetState()).c_str(), + TC_LOG_TRACE("lfg.data.group.state.restore", "Group: %s (%s), State: %s, Old state: %s", + guid.ToString().c_str(), debugMsg, GetStateString(data.GetState()).c_str(), GetStateString(data.GetOldState()).c_str()); data.RestoreState(); @@ -1624,8 +1624,8 @@ void LFGMgr::RestoreState(ObjectGuid guid, char const* debugMsg) else { LfgPlayerData& data = PlayersStore[guid]; - TC_LOG_TRACE("lfg.data.player.state.restore", "Player: %u (%s), State: %s, Old state: %s", - guid.GetCounter(), debugMsg, GetStateString(data.GetState()).c_str(), + TC_LOG_TRACE("lfg.data.player.state.restore", "Player: %s (%s), State: %s, Old state: %s", + guid.ToString().c_str(), debugMsg, GetStateString(data.GetState()).c_str(), GetStateString(data.GetOldState()).c_str()); data.RestoreState(); @@ -1637,8 +1637,8 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state) if (guid.IsGroup()) { LfgGroupData& data = GroupsStore[guid]; - TC_LOG_TRACE("lfg.data.group.state.set", "Group: %u, New state: %s, Previous: %s, Old state: %s", - guid.GetCounter(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(), + TC_LOG_TRACE("lfg.data.group.state.set", "Group: %s, New state: %s, Previous: %s, Old state: %s", + guid.ToString().c_str(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(), GetStateString(data.GetOldState()).c_str()); data.SetState(state); @@ -1646,8 +1646,8 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state) else { LfgPlayerData& data = PlayersStore[guid]; - TC_LOG_TRACE("lfg.data.player.state.set", "Player: %u, New state: %s, Previous: %s, OldState: %s", - guid.GetCounter(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(), + TC_LOG_TRACE("lfg.data.player.state.set", "Player: %s, New state: %s, Previous: %s, OldState: %s", + guid.ToString().c_str(), GetStateString(state).c_str(), GetStateString(data.GetState()).c_str(), GetStateString(data.GetOldState()).c_str()); data.SetState(state); @@ -1656,37 +1656,37 @@ void LFGMgr::SetState(ObjectGuid guid, LfgState state) void LFGMgr::SetDungeon(ObjectGuid guid, uint32 dungeon) { - TC_LOG_TRACE("lfg.data.group.dungeon.set", "Group: %u, Dungeon: %u", guid.GetCounter(), dungeon); + TC_LOG_TRACE("lfg.data.group.dungeon.set", "Group: %s, Dungeon: %u", guid.ToString().c_str(), dungeon); GroupsStore[guid].SetDungeon(dungeon); } void LFGMgr::SetRoles(ObjectGuid guid, uint8 roles) { - TC_LOG_TRACE("lfg.data.player.role.set", "Player: %u, Roles: %u", guid.GetCounter(), roles); + TC_LOG_TRACE("lfg.data.player.role.set", "Player: %s, Roles: %u", guid.ToString().c_str(), roles); PlayersStore[guid].SetRoles(roles); } void LFGMgr::SetComment(ObjectGuid guid, std::string const& comment) { - TC_LOG_TRACE("lfg.data.player.comment.set", "Player: %u, Comment: %s", guid.GetCounter(), comment.c_str()); + TC_LOG_TRACE("lfg.data.player.comment.set", "Player: %s, Comment: %s", guid.ToString().c_str(), comment.c_str()); PlayersStore[guid].SetComment(comment); } void LFGMgr::SetSelectedDungeons(ObjectGuid guid, LfgDungeonSet const& dungeons) { - TC_LOG_TRACE("lfg.data.player.dungeon.selected.set", "Player: %u, Dungeons: %s", guid.GetCounter(), ConcatenateDungeons(dungeons).c_str()); + TC_LOG_TRACE("lfg.data.player.dungeon.selected.set", "Player: %s, Dungeons: %s", guid.ToString().c_str(), ConcatenateDungeons(dungeons).c_str()); PlayersStore[guid].SetSelectedDungeons(dungeons); } void LFGMgr::DecreaseKicksLeft(ObjectGuid guid) { GroupsStore[guid].DecreaseKicksLeft(); - TC_LOG_TRACE("lfg.data.group.kicksleft.decrease", "Group: %u, Kicks: %u", guid.GetCounter(), GroupsStore[guid].GetKicksLeft()); + TC_LOG_TRACE("lfg.data.group.kicksleft.decrease", "Group: %s, Kicks: %u", guid.ToString().c_str(), GroupsStore[guid].GetKicksLeft()); } void LFGMgr::RemovePlayerData(ObjectGuid guid) { - TC_LOG_TRACE("lfg.data.player.remove", "Player: %u", guid.GetCounter()); + TC_LOG_TRACE("lfg.data.player.remove", "Player: %s", guid.ToString().c_str()); LfgPlayerDataContainer::iterator it = PlayersStore.find(guid); if (it != PlayersStore.end()) PlayersStore.erase(it); @@ -1694,7 +1694,7 @@ void LFGMgr::RemovePlayerData(ObjectGuid guid) void LFGMgr::RemoveGroupData(ObjectGuid guid) { - TC_LOG_TRACE("lfg.data.group.remove", "Group: %u", guid.GetCounter()); + TC_LOG_TRACE("lfg.data.group.remove", "Group: %s", guid.ToString().c_str()); LfgGroupDataContainer::iterator it = GroupsStore.find(guid); if (it == GroupsStore.end()) return; @@ -1717,7 +1717,7 @@ void LFGMgr::RemoveGroupData(ObjectGuid guid) uint8 LFGMgr::GetTeam(ObjectGuid guid) { uint8 team = PlayersStore[guid].GetTeam(); - TC_LOG_TRACE("lfg.data.player.team.get", "Player: %u, Team: %u", guid.GetCounter(), team); + TC_LOG_TRACE("lfg.data.player.team.get", "Player: %s, Team: %u", guid.ToString().c_str(), team); return team; } diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 3a6b1eb0b71..68ea1cd1030 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -60,8 +60,8 @@ void LFGPlayerScript::OnLogin(Player* player, bool /*loginFirst*/) ObjectGuid gguid2 = group->GetGUID(); if (gguid != gguid2) { - TC_LOG_ERROR("lfg", "%s on group %u but LFG has group %u saved... Fixing.", - player->GetSession()->GetPlayerInfo().c_str(), gguid2.GetCounter(), gguid.GetCounter()); + TC_LOG_ERROR("lfg", "%s on group %s but LFG has group %s saved... Fixing.", + player->GetSession()->GetPlayerInfo().c_str(), gguid2.ToString().c_str(), gguid.ToString().c_str()); sLFGMgr->SetupGroupMember(guid, group->GetGUID()); } } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index be8c4916e7c..3ad355ba6d4 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -759,7 +759,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData) { std::string dump; if (PlayerDumpWriter().GetDump(guid.GetCounter(), dump)) - sLog->outCharDump(dump.c_str(), accountId, guid.GetCounter(), name.c_str()); + sLog->outCharDump(dump.c_str(), accountId, guid.GetRawValue(), name.c_str()); } sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid); diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 65b4ef66c04..3c7f116c8f6 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -123,8 +123,8 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recvData) return; } ObjectGuid gguid = group->GetGUID(); - TC_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES: Group %u, Player %s, Roles: %u", - gguid.GetCounter(), GetPlayerInfo().c_str(), roles); + TC_LOG_DEBUG("lfg", "CMSG_LFG_SET_ROLES: Group %s, Player %s, Roles: %u", + gguid.ToString().c_str(), GetPlayerInfo().c_str(), roles); sLFGMgr->UpdateRoleCheck(gguid, guid, roles); } @@ -387,8 +387,8 @@ void WorldSession::SendLfgUpdateParty(const lfg::LfgUpdateData& updateData) void WorldSession::SendLfgRoleChosen(ObjectGuid guid, uint8 roles) { - TC_LOG_DEBUG("lfg", "SMSG_LFG_ROLE_CHOSEN %s guid: %u roles: %u", - GetPlayerInfo().c_str(), guid.GetCounter(), roles); + TC_LOG_DEBUG("lfg", "SMSG_LFG_ROLE_CHOSEN %s guid: %s roles: %u", + GetPlayerInfo().c_str(), guid.ToString().c_str(), roles); WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4); data << uint64(guid); // Guid @@ -535,10 +535,10 @@ void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot) } } TC_LOG_DEBUG("lfg", "SMSG_LFG_BOOT_PROPOSAL_UPDATE %s inProgress: %u - " - "didVote: %u - agree: %u - victim: %u votes: %u - agrees: %u - left: %u - " + "didVote: %u - agree: %u - victim: %s votes: %u - agrees: %u - left: %u - " "needed: %u - reason %s", GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), - uint8(playerVote == lfg::LFG_ANSWER_AGREE), boot.victim.GetCounter(), votesNum, agreeNum, + uint8(playerVote == lfg::LFG_ANSWER_AGREE), boot.victim.ToString().c_str(), votesNum, agreeNum, secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str()); WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length()); data << uint8(boot.inProgress); // Vote in progress diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index d8063c707d0..f838dccde36 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -263,7 +263,7 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData) if (!result) { - TC_LOG_DEBUG("entities.player.items", "Petition %u is not found for player %u %s", petitionguid.GetCounter(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str()); + TC_LOG_DEBUG("entities.player.items", "Petition %s is not found for player %u %s", petitionguid.ToString().c_str(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str()); return; } Field* fields = result->Fetch(); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 904e2f5ff5b..ca8771dd0bb 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2942,7 +2942,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) InstanceGroupBind* groupBind = group->GetBoundInstance(this); if (playerBind && playerBind->save != mapSave) { - TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %d and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().GetCounter(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); + TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); if (groupBind) TC_LOG_ERROR("maps", "InstanceMap::Add: the group is bound to the instance %s %d, %d, %d, %d, %d, %d", GetMapName(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset()); //ASSERT(false); @@ -2956,7 +2956,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) // cannot jump to a different instance without resetting it if (groupBind->save != mapSave) { - TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %d which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().GetCounter(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); + TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %s which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().ToString().c_str(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); TC_LOG_ERROR("maps", "MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount()); if (groupBind->save) TC_LOG_ERROR("maps", "GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount()); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 6a810070347..d3d012e70d5 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -558,10 +558,10 @@ public: for (uint8 j = 0; j < bag->GetBagSize(); ++j) if (Item* item2 = bag->GetItemByPos(j)) if (item2->GetState() == state) - handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item2->GetSlot(), item2->GetGUIDLow(), item2->GetOwnerGUID().GetCounter()); + handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str()); } else if (item->GetState() == state) - handler->PSendSysMessage("bag: 255 slot: %d guid: %d owner: %d", item->GetSlot(), item->GetGUIDLow(), item->GetOwnerGUID().GetCounter()); + handler->PSendSysMessage("bag: 255 slot: %d %s owner: %s", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str()); } } } @@ -623,14 +623,14 @@ public: if (item->GetOwnerGUID() != player->GetGUID()) { - handler->PSendSysMessage("The item with slot %d and itemguid %d does have non-matching owner guid (%d) and player guid (%d) !", item->GetSlot(), item->GetGUIDLow(), item->GetOwnerGUID().GetCounter(), player->GetGUIDLow()); + handler->PSendSysMessage("The item with slot %d %s does have non-matching owner guid %s and %s!", item->GetSlot(), item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str()); error = true; continue; } if (Bag* container = item->GetContainer()) { - handler->PSendSysMessage("The item with slot %d and guid %d has a container (slot: %d, guid: %d) but shouldn't!", item->GetSlot(), item->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow()); + handler->PSendSysMessage("The item with slot %d %s has a container (slot: %d, %s) but shouldn't!", item->GetSlot(), item->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str()); error = true; continue; } @@ -683,7 +683,7 @@ public: if (item2->GetOwnerGUID() != player->GetGUID()) { - handler->PSendSysMessage("The item in bag %d at slot %d and with itemguid %d, the owner's guid (%d) and the player's guid (%d) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), item2->GetOwnerGUID().GetCounter(), player->GetGUIDLow()); + handler->PSendSysMessage("The item in bag %d at slot %d and %s, the owner (%s) and the player (%s) don't match!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), item2->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str()); error = true; continue; } @@ -691,14 +691,14 @@ public: Bag* container = item2->GetContainer(); if (!container) { - handler->PSendSysMessage("The item in bag %d at slot %d with guid %d has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow()); + handler->PSendSysMessage("The item in bag %d at slot %d %s has no container!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str()); error = true; continue; } if (container != bag) { - handler->PSendSysMessage("The item in bag %d at slot %d with guid %d has a different container(slot %d guid %d)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUIDLow(), container->GetSlot(), container->GetGUIDLow()); + handler->PSendSysMessage("The item in bag %d at slot %d %s has a different container(slot %d %s)!", bag->GetSlot(), item2->GetSlot(), item2->GetGUID().ToString().c_str(), container->GetSlot(), container->GetGUID().ToString().c_str()); error = true; continue; } @@ -745,14 +745,14 @@ public: if (item->GetOwnerGUID() != player->GetGUID()) { - handler->PSendSysMessage("queue(%zu): For the item with guid %d, the owner's guid (%d) and the player's guid (%d) don't match!", i, item->GetGUIDLow(), item->GetOwnerGUID().GetCounter(), player->GetGUIDLow()); + handler->PSendSysMessage("queue(%zu): For the item %s, the owner (%s) and the player (%s) don't match!", i, item->GetGUID().ToString().c_str(), item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str()); error = true; continue; } if (item->GetQueuePos() != i) { - handler->PSendSysMessage("queue(%zu): For the item with guid %d, the queuepos doesn't match it's position in the queue!", i, item->GetGUIDLow()); + handler->PSendSysMessage("queue(%zu): For the item %s, the queuepos doesn't match it's position in the queue!", i, item->GetGUID().ToString().c_str()); error = true; continue; } @@ -764,14 +764,14 @@ public: if (test == NULL) { - handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow()); + handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for %s are incorrect, the player doesn't have any item at that position!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str()); error = true; continue; } if (test != item) { - handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the item with guid %d are incorrect, an item which guid is %d is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow()); + handler->PSendSysMessage("queue(%zu): The bag(%d) and slot(%d) values for the %s are incorrect, %s is there instead!", i, item->GetBagSlot(), item->GetSlot(), item->GetGUID().ToString().c_str(), test->GetGUID().ToString().c_str()); error = true; continue; } diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index a7b6b418cc4..3305b364f0f 100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -334,7 +334,7 @@ bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLog return true; } -void Log::outCharDump(char const* str, uint32 accountId, uint32 guid, char const* name) +void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const* name) { if (!str || !ShouldLog("entities.player.dump", LOG_LEVEL_INFO)) return; diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index 78e7e012bbe..e2d4baa5f0e 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -62,7 +62,7 @@ class Log void outMessage(std::string const& f, LogLevel level, char const* str, ...) ATTR_PRINTF(4, 5); void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4); - void outCharDump(char const* str, uint32 account_id, uint32 guid, char const* name); + void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name); void SetRealmId(uint32 id); -- cgit v1.2.3 From 2e455eee86e69265712dda4f0e82056765961d41 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 8 Oct 2014 20:24:55 +0200 Subject: Core/Entities: Removed the possibility to teleport non-player objects to different maps --- src/server/game/Entities/Creature/Creature.cpp | 10 ---------- src/server/game/Entities/Creature/Creature.h | 2 -- src/server/game/Entities/Transport/Transport.cpp | 14 +------------- 3 files changed, 1 insertion(+), 25 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 8b338351ab4..9f28305e3cf 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2410,16 +2410,6 @@ std::string const & Creature::GetNameForLocaleIdx(LocaleConstant loc_idx) const return GetName(); } -//Do not if this works or not, moving creature to another map is very dangerous -void Creature::FarTeleportTo(Map* map, float X, float Y, float Z, float O) -{ - CleanupBeforeRemoveFromMap(false); - GetMap()->RemoveFromMap(this, false); - Relocate(X, Y, Z, O); - SetMap(map); - GetMap()->AddToMap(this); -} - uint32 Creature::GetPetAutoSpellOnPos(uint8 pos) const { if (pos >= MAX_SPELL_CHARM || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 4cebe5b03b3..43ae3d81348 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -671,8 +671,6 @@ class Creature : public Unit, public GridObject, public MapObject float m_SightDistance, m_CombatDistance; - void FarTeleportTo(Map* map, float X, float Y, float Z, float O); - bool m_isTempWorldObject; //true when possessed // Handling caster facing during spellcast diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 777cd992c71..67d90afda60 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -608,19 +608,6 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl switch (obj->GetTypeId()) { - case TYPEID_UNIT: - if (!obj->ToUnit()->GetOwnerGUID().IsPlayer()) // pets should be teleported with player - obj->ToCreature()->FarTeleportTo(newMap, destX, destY, destZ, destO); - break; - case TYPEID_GAMEOBJECT: - { - GameObject* go = obj->ToGameObject(); - go->GetMap()->RemoveFromMap(go, false); - go->Relocate(destX, destY, destZ, destO); - go->SetMap(newMap); - newMap->AddToMap(go); - break; - } case TYPEID_PLAYER: if (!obj->ToPlayer()->TeleportTo(newMapid, destX, destY, destZ, destO, TELE_TO_NOT_LEAVE_TRANSPORT)) RemovePassenger(obj); @@ -629,6 +616,7 @@ bool Transport::TeleportTransport(uint32 newMapid, float x, float y, float z, fl obj->AddObjectToRemoveList(); break; default: + RemovePassenger(obj); break; } } -- cgit v1.2.3 From de7b503cc41c8107b928077bcd689706463162da Mon Sep 17 00:00:00 2001 From: yesitsme Date: Thu, 9 Oct 2014 00:04:04 +0200 Subject: Core/SmartScripts: Fix multiple target_types Checking the worldobjects GUID against the iterators GUID instead of pointer to worldobject against pointer to iterator, as 2 different pointers may point to the same object. Closes #12670 --- src/server/game/AI/SmartScripts/SmartScript.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 620d28ce379..b877a4ca2c0 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2458,7 +2458,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (!IsCreature(*itr)) continue; - if (me && me == *itr) + if (me && me->GetGUID() == (*itr)->GetGUID()) continue; if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist)) @@ -2477,7 +2477,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (!IsCreature(*itr)) continue; - if (me && me == *itr) + if (me && me->GetGUID() == (*itr)->GetGUID()) continue; if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature) @@ -2496,7 +2496,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (!IsGameObject(*itr)) continue; - if (go && go == *itr) + if (go && go->GetGUID() == (*itr)->GetGUID()) continue; if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry) @@ -2515,7 +2515,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (!IsGameObject(*itr)) continue; - if (go && go == *itr) + if (go && go->GetGUID() == (*itr)->GetGUID()) continue; if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist)) -- cgit v1.2.3 From 9e7a9ff6e19926d51a747eac172ec1723ad5561c Mon Sep 17 00:00:00 2001 From: MitchesD Date: Thu, 9 Oct 2014 16:42:08 +0200 Subject: Scripts/Dalaran: remove unneeded script --- src/server/scripts/Northrend/zone_dalaran.cpp | 47 +-------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) (limited to 'src/server') diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp index fb5e63a2301..27d3e6dadc6 100644 --- a/src/server/scripts/Northrend/zone_dalaran.cpp +++ b/src/server/scripts/Northrend/zone_dalaran.cpp @@ -128,50 +128,6 @@ public: } }; -/*###### -## npc_hira_snowdawn -######*/ - -enum HiraSnowdawn -{ - SPELL_COLD_WEATHER_FLYING = 54197 -}; - -#define GOSSIP_TEXT_TRAIN_HIRA "I seek training to ride a steed." - -class npc_hira_snowdawn : public CreatureScript -{ -public: - npc_hira_snowdawn() : CreatureScript("npc_hira_snowdawn") { } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (!creature->IsVendor() || !creature->IsTrainer()) - return false; - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_TRAIN_HIRA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); - - if (player->getLevel() >= 80 && player->HasSpell(SPELL_COLD_WEATHER_FLYING)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRAIN) - player->GetSession()->SendTrainerList(creature->GetGUID()); - - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } -}; - enum MinigobData { ZONE_DALARAN = 4395, @@ -284,7 +240,6 @@ class npc_minigob_manabonk : public CreatureScript void AddSC_dalaran() { - new npc_mageguard_dalaran; - new npc_hira_snowdawn; + new npc_mageguard_dalaran(); new npc_minigob_manabonk(); } -- cgit v1.2.3 From ba676f8c3e4b80c9a7ee12146965c16c532b95ae Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Thu, 9 Oct 2014 18:54:09 +0200 Subject: Core/Spells: Added new error log for spell linked --- src/server/game/Spells/SpellMgr.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/server') diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 55d955428b1..b853cf82b00 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2330,6 +2330,14 @@ void SpellMgr::LoadSpellLinked() TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_linked_spell` does not exist", abs(trigger)); continue; } + + if (effect >= 0) + for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) + { + if (spellInfo->Effects[j].CalcValue() == abs(effect)) + TC_LOG_ERROR("sql.sql", "Spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), j); + } + spellInfo = GetSpellInfo(abs(effect)); if (!spellInfo) { -- cgit v1.2.3 From 67f9d916cbd920ee72b3e9036e13d0725b38566e Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 9 Oct 2014 23:01:31 +0200 Subject: Build: Fixed game & collision depending on each other for linking --- src/server/collision/Management/MMapFactory.cpp | 8 ------- src/server/collision/Management/VMapManager2.cpp | 16 ++++++------- src/server/collision/Management/VMapManager2.h | 17 ++++++++++++++ src/server/game/Conditions/DisableMgr.cpp | 29 ++++++++++++++++-------- src/server/game/Conditions/DisableMgr.h | 11 +++------ src/server/game/Maps/Map.cpp | 3 ++- src/server/game/Movement/PathGenerator.cpp | 4 ++-- src/server/game/World/World.cpp | 7 ++++++ src/server/scripts/Commands/cs_misc.cpp | 3 ++- src/server/scripts/Commands/cs_mmaps.cpp | 3 ++- src/tools/mmaps_generator/MapBuilder.cpp | 8 ------- src/tools/mmaps_generator/PathCommon.h | 2 +- 12 files changed, 64 insertions(+), 47 deletions(-) (limited to 'src/server') diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp index b08cd92d638..51f016f6e96 100644 --- a/src/server/collision/Management/MMapFactory.cpp +++ b/src/server/collision/Management/MMapFactory.cpp @@ -17,9 +17,7 @@ */ #include "MMapFactory.h" -#include "World.h" #include "Config.h" -#include "DisableMgr.h" namespace MMAP { @@ -35,12 +33,6 @@ namespace MMAP return g_MMapManager; } - bool MMapFactory::IsPathfindingEnabled(uint32 mapId) - { - return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) - && !DisableMgr::IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING); - } - void MMapFactory::clear() { if (g_MMapManager) diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 484fdcd8ea4..18d7a3849bb 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -25,8 +25,6 @@ #include "ModelInstance.h" #include "WorldModel.h" #include -#include "DisableMgr.h" -#include "DBCStores.h" #include "Log.h" #include "VMapDefinitions.h" @@ -36,6 +34,8 @@ namespace VMAP { VMapManager2::VMapManager2() { + GetLiquidFlagsPtr = &GetLiquidFlagsDummy; + IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy; } VMapManager2::~VMapManager2(void) @@ -134,7 +134,7 @@ namespace VMAP bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) { - if (!isLineOfSightCalcEnabled() || DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS)) + if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) return true; InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); @@ -157,7 +157,7 @@ namespace VMAP */ bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist) { - if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS)) + if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree != iInstanceMapTrees.end()) @@ -187,7 +187,7 @@ namespace VMAP float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist) { - if (isHeightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_HEIGHT)) + if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT)) { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree != iInstanceMapTrees.end()) @@ -206,7 +206,7 @@ namespace VMAP bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const { - if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_AREAFLAG)) + if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) { InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree != iInstanceMapTrees.end()) @@ -224,7 +224,7 @@ namespace VMAP bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const { - if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LIQUIDSTATUS)) + if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) { InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree != iInstanceMapTrees.end()) @@ -236,7 +236,7 @@ namespace VMAP floor = info.ground_Z; ASSERT(floor < std::numeric_limits::max()); type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc - if (reqLiquidType && !(GetLiquidFlags(type) & reqLiquidType)) + if (reqLiquidType && !(GetLiquidFlagsPtr(type) & reqLiquidType)) return false; if (info.hitInstance->GetLiquidLevel(pos, info, level)) return true; diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h index 04292e7d8e4..9c419270b5a 100644 --- a/src/server/collision/Management/VMapManager2.h +++ b/src/server/collision/Management/VMapManager2.h @@ -66,6 +66,14 @@ namespace VMAP typedef std::unordered_map InstanceTreeMap; typedef std::unordered_map ModelFileMap; + enum DisableTypes + { + VMAP_DISABLE_AREAFLAG = 0x1, + VMAP_DISABLE_HEIGHT = 0x2, + VMAP_DISABLE_LOS = 0x4, + VMAP_DISABLE_LIQUIDSTATUS = 0x8 + }; + class VMapManager2 : public IVMapManager { protected: @@ -78,6 +86,9 @@ namespace VMAP bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY); /* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */ + static uint32 GetLiquidFlagsDummy(uint32) { return 0; } + static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; } + public: // public for debug G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const; @@ -114,6 +125,12 @@ namespace VMAP virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override; public: void getInstanceMapTree(InstanceTreeMap &instanceMapTree); + + typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType); + GetLiquidFlagsFn GetLiquidFlagsPtr; + + typedef bool(*IsVMAPDisabledForFn)(uint32 entry, uint8 flags); + IsVMAPDisabledForFn IsVMAPDisabledForPtr; }; } diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp index 3f325be1e83..eb50545b510 100644 --- a/src/server/game/Conditions/DisableMgr.cpp +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -21,8 +21,8 @@ #include "ObjectMgr.h" #include "OutdoorPvP.h" #include "SpellMgr.h" -#include "VMapManager2.h" #include "Player.h" +#include "World.h" namespace DisableMgr { @@ -193,28 +193,28 @@ void LoadDisables() switch (mapEntry->map_type) { case MAP_COMMON: - if (flags & VMAP_DISABLE_AREAFLAG) + if (flags & VMAP::VMAP_DISABLE_AREAFLAG) TC_LOG_INFO("misc", "Areaflag disabled for world map %u.", entry); - if (flags & VMAP_DISABLE_LIQUIDSTATUS) + if (flags & VMAP::VMAP_DISABLE_LIQUIDSTATUS) TC_LOG_INFO("misc", "Liquid status disabled for world map %u.", entry); break; case MAP_INSTANCE: case MAP_RAID: - if (flags & VMAP_DISABLE_HEIGHT) + if (flags & VMAP::VMAP_DISABLE_HEIGHT) TC_LOG_INFO("misc", "Height disabled for instance map %u.", entry); - if (flags & VMAP_DISABLE_LOS) + if (flags & VMAP::VMAP_DISABLE_LOS) TC_LOG_INFO("misc", "LoS disabled for instance map %u.", entry); break; case MAP_BATTLEGROUND: - if (flags & VMAP_DISABLE_HEIGHT) + if (flags & VMAP::VMAP_DISABLE_HEIGHT) TC_LOG_INFO("misc", "Height disabled for battleground map %u.", entry); - if (flags & VMAP_DISABLE_LOS) + if (flags & VMAP::VMAP_DISABLE_LOS) TC_LOG_INFO("misc", "LoS disabled for battleground map %u.", entry); break; case MAP_ARENA: - if (flags & VMAP_DISABLE_HEIGHT) + if (flags & VMAP::VMAP_DISABLE_HEIGHT) TC_LOG_INFO("misc", "Height disabled for arena map %u.", entry); - if (flags & VMAP_DISABLE_LOS) + if (flags & VMAP::VMAP_DISABLE_LOS) TC_LOG_INFO("misc", "LoS disabled for arena map %u.", entry); break; default: @@ -387,4 +387,15 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags return false; } +bool IsVMAPDisabledFor(uint32 entry, uint8 flags) +{ + return IsDisabledFor(DISABLE_TYPE_VMAP, entry, NULL, flags); +} + +bool IsPathfindingEnabled(uint32 mapId) +{ + return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) + && !IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING); +} + } // Namespace diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h index 0930da78547..f6c65abe90a 100644 --- a/src/server/game/Conditions/DisableMgr.h +++ b/src/server/game/Conditions/DisableMgr.h @@ -19,6 +19,7 @@ #ifndef TRINITY_DISABLEMGR_H #define TRINITY_DISABLEMGR_H +#include "VMapManager2.h" #include "Define.h" class Unit; @@ -49,14 +50,6 @@ enum SpellDisableTypes SPELL_DISABLE_LOS) }; -enum VmapDisableTypes -{ - VMAP_DISABLE_AREAFLAG = 0x1, - VMAP_DISABLE_HEIGHT = 0x2, - VMAP_DISABLE_LOS = 0x4, - VMAP_DISABLE_LIQUIDSTATUS = 0x8 -}; - enum MMapDisableTypes { MMAP_DISABLE_PATHFINDING = 0x0 @@ -67,6 +60,8 @@ namespace DisableMgr void LoadDisables(); bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0); void CheckQuestDisables(); + bool IsVMAPDisabledFor(uint32 entry, uint8 flags); + bool IsPathfindingEnabled(uint32 mapId); } #endif //TRINITY_DISABLEMGR_H diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index ca8771dd0bb..37563acd74a 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -20,6 +20,7 @@ #include "Battleground.h" #include "MMapFactory.h" #include "CellImpl.h" +#include "DisableMgr.h" #include "DynamicTree.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" @@ -119,7 +120,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { - if (!MMAP::MMapFactory::IsPathfindingEnabled(GetId())) + if (!DisableMgr::IsPathfindingEnabled(GetId())) return; bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index cbf88b68028..afd1f73c785 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -22,7 +22,7 @@ #include "MMapFactory.h" #include "MMapManager.h" #include "Log.h" - +#include "DisableMgr.h" #include "DetourCommon.h" #include "DetourNavMeshQuery.h" @@ -38,7 +38,7 @@ PathGenerator::PathGenerator(const Unit* owner) : TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow()); uint32 mapId = _sourceUnit->GetMapId(); - if (MMAP::MMapFactory::IsPathfindingEnabled(mapId)) + if (DisableMgr::IsPathfindingEnabled(mapId)) { MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); _navMesh = mmap->GetNavMesh(mapId); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 903e14f7506..fae613797e9 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1283,6 +1283,13 @@ void World::SetInitialWorldSettings() ///- Initialize detour memory management dtAllocSetCustom(dtCustomAlloc, dtCustomFree); + ///- Initialize VMapManager function pointers (to untangle game/collision circular deps) + if (VMAP::VMapManager2* vmmgr2 = dynamic_cast(VMAP::VMapFactory::createOrGetVMapManager())) + { + vmmgr2->GetLiquidFlagsPtr = &GetLiquidFlags; + vmmgr2->IsVMAPDisabledForPtr = &DisableMgr::IsVMAPDisabledFor; + } + ///- Initialize config settings LoadConfigSettings(); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index b4b9928d6f8..a7716d3230b 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -35,6 +35,7 @@ #include "LFG.h" #include "GroupMgr.h" #include "MMapFactory.h" +#include "DisableMgr.h" class misc_commandscript : public CommandScript { @@ -186,7 +187,7 @@ public: uint32 haveMap = Map::ExistMap(mapId, gridX, gridY) ? 1 : 0; uint32 haveVMap = Map::ExistVMap(mapId, gridX, gridY) ? 1 : 0; - uint32 haveMMap = (MMAP::MMapFactory::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0; + uint32 haveMMap = (DisableMgr::IsPathfindingEnabled(mapId) && MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0; if (haveVMap) { diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 0be5994e8ed..bba14eb8332 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -25,6 +25,7 @@ #include "ScriptMgr.h" #include "Chat.h" +#include "DisableMgr.h" #include "ObjectMgr.h" #include "Player.h" #include "PointMovementGenerator.h" @@ -209,7 +210,7 @@ public: { uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId(); handler->PSendSysMessage("mmap stats:"); - handler->PSendSysMessage(" global mmap pathfinding is %sabled", MMAP::MMapFactory::IsPathfindingEnabled(mapId) ? "en" : "dis"); + handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis"); MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager(); handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount()); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 885dd24d760..2f8b35fd52d 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -27,14 +27,6 @@ #include "DetourNavMesh.h" #include "DetourCommon.h" -#include "DisableMgr.h" - -uint32 GetLiquidFlags(uint32 /*liquidType*/) { return 0; } -namespace DisableMgr -{ - bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/ /*= 0*/) { return false; } -} - #define MMAP_MAGIC 0x4d4d4150 // 'MMAP' #define MMAP_VERSION 5 diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 8285fef74f2..694e40dacde 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -62,7 +62,7 @@ namespace MMAP if (*++filter == '\0') // wildcard at end of filter means all remaing chars match return true; - while (true) + for (;;) { if (*filter == *str) break; -- cgit v1.2.3 From 889e82ebe483f316f89171dd1f7cb74312e3e00b Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Fri, 10 Oct 2014 19:30:57 +0200 Subject: Core: Fix non pch build --- src/server/collision/Management/VMapManager2.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/server') diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 18d7a3849bb..b9ac7e204da 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -27,6 +27,7 @@ #include #include "Log.h" #include "VMapDefinitions.h" +#include "Errors.h" using G3D::Vector3; -- cgit v1.2.3 From 03732846fe0d38e7ce969b029e63f09395eb1de2 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Fri, 10 Oct 2014 22:42:48 +0200 Subject: Core: Fix non pch build --- src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp index ae2db016972..dd8e04564af 100644 --- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp @@ -16,6 +16,7 @@ */ #include "AuthenticationPackets.h" +#include "BattlenetSession.h" #include "Util.h" void Battlenet::Authentication::LogonRequest::Read() -- cgit v1.2.3 From a04393f5542cc02b1af0e4259d98cc40080972d1 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 10 Oct 2014 23:19:40 +0200 Subject: Core/Auth: Moved battle.net handling to separate project --- src/server/CMakeLists.txt | 1 + src/server/authserver/CMakeLists.txt | 1 - src/server/authserver/Main.cpp | 13 - src/server/authserver/PrecompiledHeaders/authPCH.h | 3 - src/server/authserver/Realms/RealmList.cpp | 14 - src/server/authserver/Realms/RealmList.h | 6 - .../authserver/Server/BattlenetBitStream.cpp | 30 - src/server/authserver/Server/BattlenetBitStream.h | 243 ----- src/server/authserver/Server/BattlenetManager.cpp | 96 -- src/server/authserver/Server/BattlenetManager.h | 116 --- .../authserver/Server/BattlenetPacketCrypt.cpp | 42 - .../authserver/Server/BattlenetPacketCrypt.h | 36 - .../authserver/Server/BattlenetPacketFactory.h | 83 -- .../Server/BattlenetPackets/AchievementPackets.h | 42 - .../BattlenetPackets/AuthenticationPackets.h | 196 ---- .../Server/BattlenetPackets/BattlenetPackets.h | 32 - .../BattlenetPackets/BattlenetPacketsBase.cpp | 38 - .../Server/BattlenetPackets/BattlenetPacketsBase.h | 121 --- .../Server/BattlenetPackets/CachePackets.h | 43 - .../Server/BattlenetPackets/ChatPackets.h | 63 -- .../Server/BattlenetPackets/ConnectionPackets.cpp | 54 -- .../Server/BattlenetPackets/ConnectionPackets.h | 94 -- .../Server/BattlenetPackets/FriendsPackets.cpp | 180 ---- .../Server/BattlenetPackets/FriendsPackets.h | 162 ---- .../Server/BattlenetPackets/PresencePackets.cpp | 50 - .../Server/BattlenetPackets/PresencePackets.h | 65 -- .../Server/BattlenetPackets/ProfilePackets.h | 44 - .../Server/BattlenetPackets/SupportPackets.h | 34 - .../Server/BattlenetPackets/WoWRealmPackets.cpp | 202 ---- .../Server/BattlenetPackets/WoWRealmPackets.h | 172 ---- src/server/authserver/Server/BattlenetSession.cpp | 1004 -------------------- src/server/authserver/Server/BattlenetSession.h | 128 --- .../authserver/Server/BattlenetSessionManager.cpp | 37 - .../authserver/Server/BattlenetSessionManager.h | 71 -- src/server/bnetserver/Authentication/AuthCodes.cpp | 55 ++ src/server/bnetserver/Authentication/AuthCodes.h | 128 +++ .../Authentication/BattlenetPacketCrypt.cpp | 42 + .../Authentication/BattlenetPacketCrypt.h | 36 + src/server/bnetserver/CMakeLists.txt | 115 +++ src/server/bnetserver/Main.cpp | 238 +++++ src/server/bnetserver/Packets/AchievementPackets.h | 42 + .../bnetserver/Packets/AuthenticationPackets.cpp | 319 +++++++ .../bnetserver/Packets/AuthenticationPackets.h | 196 ++++ src/server/bnetserver/Packets/BitStream.cpp | 30 + src/server/bnetserver/Packets/BitStream.h | 243 +++++ src/server/bnetserver/Packets/CachePackets.h | 43 + src/server/bnetserver/Packets/ChatPackets.h | 63 ++ .../bnetserver/Packets/ConnectionPackets.cpp | 54 ++ src/server/bnetserver/Packets/ConnectionPackets.h | 94 ++ src/server/bnetserver/Packets/FriendsPackets.cpp | 179 ++++ src/server/bnetserver/Packets/FriendsPackets.h | 162 ++++ src/server/bnetserver/Packets/PacketFactory.h | 83 ++ src/server/bnetserver/Packets/Packets.h | 32 + src/server/bnetserver/Packets/PacketsBase.cpp | 38 + src/server/bnetserver/Packets/PacketsBase.h | 120 +++ src/server/bnetserver/Packets/PresencePackets.cpp | 48 + src/server/bnetserver/Packets/PresencePackets.h | 65 ++ src/server/bnetserver/Packets/ProfilePackets.h | 44 + src/server/bnetserver/Packets/SupportPackets.h | 34 + src/server/bnetserver/Packets/WoWRealmPackets.cpp | 202 ++++ src/server/bnetserver/Packets/WoWRealmPackets.h | 173 ++++ .../bnetserver/PrecompiledHeaders/bnetPCH.cpp | 1 + src/server/bnetserver/PrecompiledHeaders/bnetPCH.h | 10 + src/server/bnetserver/Realms/RealmList.cpp | 207 ++++ src/server/bnetserver/Realms/RealmList.h | 113 +++ src/server/bnetserver/Server/ComponentManager.cpp | 55 ++ src/server/bnetserver/Server/ComponentManager.h | 61 ++ src/server/bnetserver/Server/ModuleManager.cpp | 57 ++ src/server/bnetserver/Server/ModuleManager.h | 94 ++ src/server/bnetserver/Server/Session.cpp | 1000 +++++++++++++++++++ src/server/bnetserver/Server/Session.h | 128 +++ src/server/bnetserver/Server/SessionManager.cpp | 37 + src/server/bnetserver/Server/SessionManager.h | 71 ++ src/server/bnetserver/bnetserver.conf.dist | 257 +++++ src/server/bnetserver/bnetserver.ico | Bin 0 -> 136606 bytes src/server/bnetserver/bnetserver.rc | 94 ++ src/server/bnetserver/resource.h | 15 + 77 files changed, 5079 insertions(+), 3515 deletions(-) delete mode 100644 src/server/authserver/Server/BattlenetBitStream.cpp delete mode 100644 src/server/authserver/Server/BattlenetBitStream.h delete mode 100644 src/server/authserver/Server/BattlenetManager.cpp delete mode 100644 src/server/authserver/Server/BattlenetManager.h delete mode 100644 src/server/authserver/Server/BattlenetPacketCrypt.cpp delete mode 100644 src/server/authserver/Server/BattlenetPacketCrypt.h delete mode 100644 src/server/authserver/Server/BattlenetPacketFactory.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/AchievementPackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp delete mode 100644 src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/CachePackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/ChatPackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp delete mode 100644 src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp delete mode 100644 src/server/authserver/Server/BattlenetPackets/FriendsPackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp delete mode 100644 src/server/authserver/Server/BattlenetPackets/PresencePackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/ProfilePackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/SupportPackets.h delete mode 100644 src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp delete mode 100644 src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h delete mode 100644 src/server/authserver/Server/BattlenetSession.cpp delete mode 100644 src/server/authserver/Server/BattlenetSession.h delete mode 100644 src/server/authserver/Server/BattlenetSessionManager.cpp delete mode 100644 src/server/authserver/Server/BattlenetSessionManager.h create mode 100644 src/server/bnetserver/Authentication/AuthCodes.cpp create mode 100644 src/server/bnetserver/Authentication/AuthCodes.h create mode 100644 src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp create mode 100644 src/server/bnetserver/Authentication/BattlenetPacketCrypt.h create mode 100644 src/server/bnetserver/CMakeLists.txt create mode 100644 src/server/bnetserver/Main.cpp create mode 100644 src/server/bnetserver/Packets/AchievementPackets.h create mode 100644 src/server/bnetserver/Packets/AuthenticationPackets.cpp create mode 100644 src/server/bnetserver/Packets/AuthenticationPackets.h create mode 100644 src/server/bnetserver/Packets/BitStream.cpp create mode 100644 src/server/bnetserver/Packets/BitStream.h create mode 100644 src/server/bnetserver/Packets/CachePackets.h create mode 100644 src/server/bnetserver/Packets/ChatPackets.h create mode 100644 src/server/bnetserver/Packets/ConnectionPackets.cpp create mode 100644 src/server/bnetserver/Packets/ConnectionPackets.h create mode 100644 src/server/bnetserver/Packets/FriendsPackets.cpp create mode 100644 src/server/bnetserver/Packets/FriendsPackets.h create mode 100644 src/server/bnetserver/Packets/PacketFactory.h create mode 100644 src/server/bnetserver/Packets/Packets.h create mode 100644 src/server/bnetserver/Packets/PacketsBase.cpp create mode 100644 src/server/bnetserver/Packets/PacketsBase.h create mode 100644 src/server/bnetserver/Packets/PresencePackets.cpp create mode 100644 src/server/bnetserver/Packets/PresencePackets.h create mode 100644 src/server/bnetserver/Packets/ProfilePackets.h create mode 100644 src/server/bnetserver/Packets/SupportPackets.h create mode 100644 src/server/bnetserver/Packets/WoWRealmPackets.cpp create mode 100644 src/server/bnetserver/Packets/WoWRealmPackets.h create mode 100644 src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp create mode 100644 src/server/bnetserver/PrecompiledHeaders/bnetPCH.h create mode 100644 src/server/bnetserver/Realms/RealmList.cpp create mode 100644 src/server/bnetserver/Realms/RealmList.h create mode 100644 src/server/bnetserver/Server/ComponentManager.cpp create mode 100644 src/server/bnetserver/Server/ComponentManager.h create mode 100644 src/server/bnetserver/Server/ModuleManager.cpp create mode 100644 src/server/bnetserver/Server/ModuleManager.h create mode 100644 src/server/bnetserver/Server/Session.cpp create mode 100644 src/server/bnetserver/Server/Session.h create mode 100644 src/server/bnetserver/Server/SessionManager.cpp create mode 100644 src/server/bnetserver/Server/SessionManager.h create mode 100644 src/server/bnetserver/bnetserver.conf.dist create mode 100644 src/server/bnetserver/bnetserver.ico create mode 100644 src/server/bnetserver/bnetserver.rc create mode 100644 src/server/bnetserver/resource.h (limited to 'src/server') diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 05cbe51b15d..ea2ad3abac7 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -25,6 +25,7 @@ if( SERVERS ) add_subdirectory(game) add_subdirectory(collision) add_subdirectory(authserver) + add_subdirectory(bnetserver) add_subdirectory(scripts) add_subdirectory(worldserver) else() diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt index ae706973ff7..b40b8c906f4 100644 --- a/src/server/authserver/CMakeLists.txt +++ b/src/server/authserver/CMakeLists.txt @@ -58,7 +58,6 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/Authentication ${CMAKE_CURRENT_SOURCE_DIR}/Realms ${CMAKE_CURRENT_SOURCE_DIR}/Server - ${CMAKE_CURRENT_SOURCE_DIR}/Server/BattlenetPackets ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${VALGRIND_INCLUDE_DIR} diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index e614b2b79fa..5f08ebe3127 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -25,8 +25,6 @@ */ #include "AuthSocketMgr.h" -#include "BattlenetManager.h" -#include "BattlenetSessionManager.h" #include "Common.h" #include "Config.h" #include "DatabaseEnv.h" @@ -117,18 +115,9 @@ int main(int argc, char** argv) return 1; } - int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119); - if (bnport < 0 || bnport > 0xFFFF) - { - TC_LOG_ERROR("server.authserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport); - StopDB(); - return 1; - } - std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); sAuthSocketMgr.StartNetwork(_ioService, bindIp, port); - sBattlenetSessionMgr.StartNetwork(_ioService, bindIp, bnport); // Set signal handlers boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); @@ -145,8 +134,6 @@ int main(int argc, char** argv) _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); _dbPingTimer.async_wait(KeepDatabaseAliveHandler); - sBattlenetMgr->Load(); - // Start the io service worker loop _ioService.run(); diff --git a/src/server/authserver/PrecompiledHeaders/authPCH.h b/src/server/authserver/PrecompiledHeaders/authPCH.h index b509f8caaa0..90424161344 100644 --- a/src/server/authserver/PrecompiledHeaders/authPCH.h +++ b/src/server/authserver/PrecompiledHeaders/authPCH.h @@ -2,9 +2,6 @@ #include "Configuration/Config.h" #include "Database/DatabaseEnv.h" #include "Log.h" -#include "BattlenetManager.h" #include "RealmList.h" #include "ByteBuffer.h" -#include "BattlenetPackets.h" #include "AuthSession.h" -#include "BattlenetSession.h" diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp index 2110dc1fecc..662a015dc65 100644 --- a/src/server/authserver/Realms/RealmList.cpp +++ b/src/server/authserver/Realms/RealmList.cpp @@ -19,7 +19,6 @@ #include #include "Common.h" #include "RealmList.h" -#include "BattlenetManager.h" #include "Database/DatabaseEnv.h" #include "Util.h" @@ -193,16 +192,3 @@ void RealmList::UpdateRealms(bool init) while (result->NextRow()); } } - -Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const -{ - auto itr = std::find_if(m_realms.begin(), m_realms.end(), [id](RealmMap::value_type const& pair) - { - return pair.second.Region == id.Region && pair.second.Battlegroup == id.Battlegroup && pair.second.m_ID == id.Index; - }); - - if (itr != m_realms.end()) - return &itr->second; - - return NULL; -} diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h index 0063b1a60c8..f7a98cda686 100644 --- a/src/server/authserver/Realms/RealmList.h +++ b/src/server/authserver/Realms/RealmList.h @@ -60,11 +60,6 @@ struct Realm ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const; }; -namespace Battlenet -{ - struct RealmId; -} - /// Storage object for the list of realms on the server class RealmList { @@ -88,7 +83,6 @@ public: RealmMap::const_iterator begin() const { return m_realms.begin(); } RealmMap::const_iterator end() const { return m_realms.end(); } uint32 size() const { return m_realms.size(); } - Realm const* GetRealm(Battlenet::RealmId const& id) const; private: RealmList(); diff --git a/src/server/authserver/Server/BattlenetBitStream.cpp b/src/server/authserver/Server/BattlenetBitStream.cpp deleted file mode 100644 index 712c9e58f08..00000000000 --- a/src/server/authserver/Server/BattlenetBitStream.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetBitStream.h" - -template<> -bool Battlenet::BitStream::Read(uint32 /*bitCount*/) -{ - return Read(1) != 0; -} - -template<> -void Battlenet::BitStream::Write(bool value, uint32 /*bitCount*/) -{ - Write(value ? 1 : 0, 1); -} diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h deleted file mode 100644 index 3601c3b0b0c..00000000000 --- a/src/server/authserver/Server/BattlenetBitStream.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __BATTLENETBITSTREAM_H__ -#define __BATTLENETBITSTREAM_H__ - -#include "Common.h" -#include "ByteConverter.h" -#include "MessageBuffer.h" -#include -#include -#include -#include - -namespace Battlenet -{ - class BitStreamPositionException : public std::exception - { - static uint32 const MessageSize = 128; - - public: - BitStreamPositionException(bool read, uint32 operationSize, uint32 position, uint32 streamSize) - { - memset(_message, 0, MessageSize); - snprintf(_message, MessageSize, "Attempted to %s more bits (%u) %s stream than %s (%u)\n", - (read ? "read" : "write"), - operationSize + position, - (read ? "from" : "to"), - (read ? "exist" : "allowed"), - streamSize); - } - - char const* what() const throw() - { - return _message; - } - - private: - char _message[MessageSize]; - }; - - class BitStream - { - public: - static uint32 const MaxSize = 0x4000; - - // length : The maximum number of bytes to read - BitStream(uint32 length) : _writePos(length * 8), _readPos(0) - { - _buffer.resize(length, 0); - } - - BitStream(MessageBuffer&& buffer) : _writePos(buffer.GetActiveSize() * 8), _readPos(0), _buffer(buffer.Move()) - { - } - - BitStream() : _writePos(0), _readPos(0) - { - _buffer.reserve(0x1000); - } - - void AlignToNextByte() - { - _readPos = (_readPos + 7) & ~7; - _writePos = (_writePos + 7) & ~7; - } - - std::string ReadString(uint32 bitCount, int32 baseLength = 0) - { - uint32 len = Read(bitCount) + baseLength; - AlignToNextByte(); - std::string str(reinterpret_cast(&_buffer[_readPos >> 3]), len); - _readPos += len * 8; - return str; - } - - std::unique_ptr ReadBytes(uint32 count) - { - AlignToNextByte(); - if (_readPos + count * 8 > _writePos) - throw BitStreamPositionException(true, count * 8, _readPos, _writePos); - - std::unique_ptr buf(new uint8[count]); - memcpy(buf.get(), &_buffer[_readPos >> 3], count); - _readPos += count * 8; - return buf; - } - - float ReadFloat() - { - uint32 val = Read(32); - return *reinterpret_cast(&val); - } - - std::string ReadFourCC() - { - uint32 fcc = Read(32); - EndianConvertReverse(fcc); - size_t len = 4; - while (!(fcc & 0xFF)) - { - fcc >>= 8; - --len; - } - - return std::string(reinterpret_cast(&fcc), len); - } - - template - T Read(uint32 bitCount) - { - static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type"); - - if (_readPos + bitCount > _writePos) - throw BitStreamPositionException(true, bitCount, _readPos, _writePos); - - uint64 ret = 0; - while (bitCount != 0) - { - uint32 bitPos = (_readPos & 7); - uint32 bitsLeftInByte = 8 - bitPos; - if (bitsLeftInByte >= bitCount) - bitsLeftInByte = bitCount; - - bitCount -= bitsLeftInByte; - ret |= (uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount; - _readPos += bitsLeftInByte; - } - - return static_cast(ret); - } - - void WriteString(std::string const& str, uint32 bitCount, int32 baseLength = 0) - { - Write(str.length() + baseLength, bitCount); - WriteBytes(str.c_str(), str.length()); - } - - template - void WriteBytes(T* data, uint32 count) - { - AlignToNextByte(); - if (!count || !data) - return; - - if ((_writePos >> 3) + count > MaxSize) - throw BitStreamPositionException(false, count * 8, _writePos, MaxSize * 8); - - _buffer.resize(_buffer.size() + count); - memcpy(&_buffer[_writePos >> 3], data, count); - _writePos += count * 8; - } - - void WriteFloat(float value) - { - uint32 intVal = *reinterpret_cast(&value); - Write(intVal, 32); - } - - void WriteFourCC(std::string const& fcc) - { - uint32 intVal = *(uint32*)fcc.c_str(); - size_t len = fcc.length(); - EndianConvertReverse(intVal); - // Add padding - while (len++ < 4) - intVal >>= 8; - - Write(intVal, 32); - } - - template - void Write(T value, uint32 bitCount) - { - static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type"); - - if (_writePos + bitCount > 8 * MaxSize) - throw BitStreamPositionException(false, bitCount, _writePos, MaxSize * 8); - - while (bitCount != 0) - { - uint32 bitPos = (_writePos & 7); - uint32 bitsLeftInByte = 8 - bitPos; - if (bitsLeftInByte >= bitCount) - bitsLeftInByte = bitCount; - - bitCount -= bitsLeftInByte; - - uint8 firstHalf = (uint8)(~(((uint8)(1 << bitsLeftInByte) - 1) << bitPos)); - uint8 secondHalf = (uint8)((((uint8)(1 << bitsLeftInByte) - 1) & (uint8)(value >> bitCount)) << bitPos); - - if (_buffer.size() > (_writePos >> 3)) - _buffer[_writePos >> 3] = (uint8)((_buffer[_writePos >> 3] & firstHalf) | secondHalf); - else - _buffer.push_back(secondHalf); - - _writePos += bitsLeftInByte; - } - } - - void SetReadPos(uint32 bits) - { - if (bits > _writePos) - throw BitStreamPositionException(true, bits, 0, _writePos); - - _readPos = bits; - } - - bool IsRead() const { return _readPos >= _writePos; } - - uint8* GetBuffer() { return _buffer.data(); } - uint8 const* GetBuffer() const { return _buffer.data(); } - - size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; } - - private: - uint32 _writePos; - uint32 _readPos; - std::vector _buffer; - }; - - template<> - bool BitStream::Read(uint32 bitCount); - - template<> - void BitStream::Write(bool value, uint32 bitCount); -} - -#endif // __BATTLENETBITSTREAM_H__ diff --git a/src/server/authserver/Server/BattlenetManager.cpp b/src/server/authserver/Server/BattlenetManager.cpp deleted file mode 100644 index f470c365b56..00000000000 --- a/src/server/authserver/Server/BattlenetManager.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetManager.h" -#include "DatabaseEnv.h" - -BattlenetMgr::~BattlenetMgr() -{ - for (Battlenet::Component* component : _components) - delete component; - - for (auto const& m : _modules) - delete m.second; -} - -void BattlenetMgr::Load() -{ - LoadComponents(); - LoadModules(); -} - -void BattlenetMgr::LoadComponents() -{ - QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components"); - if (result) - { - do - { - Field* fields = result->Fetch(); - Battlenet::Component* component = new Battlenet::Component(); - component->Program = fields[0].GetString(); - component->Platform = fields[1].GetString(); - component->Build = fields[2].GetUInt32(); - - _components.insert(component); - _programs.insert(component->Program); - _platforms.insert(component->Platform); - - } while (result->NextRow()); - } -} - -void BattlenetMgr::LoadModules() -{ - QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules"); - if (result) - { - do - { - Field* fields = result->Fetch(); - Battlenet::ModuleInfo* module = new Battlenet::ModuleInfo(); - module->Type = fields[2].GetString(); - HexStrToByteArray(fields[0].GetString(), module->ModuleId); - std::string data = fields[4].GetString(); - module->DataSize = data.length() / 2; - if (module->DataSize) - { - module->Data = new uint8[data.length() / 2]; - HexStrToByteArray(data, module->Data); - } - - _modules[{ fields[3].GetString(), fields[1].GetString() }] = module; - } while (result->NextRow()); - } -} - -bool BattlenetMgr::HasComponent(Battlenet::Component const* component) const -{ - for (Battlenet::Component const* c : _components) - if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build) - return true; - - return false; -} - -Battlenet::ModuleInfo* BattlenetMgr::CreateModule(std::string const& os, std::string const& name) const -{ - Battlenet::ModuleKey key { os, name }; - ASSERT(_modules.count(key)); - - return new Battlenet::ModuleInfo(*_modules.at(key)); -} diff --git a/src/server/authserver/Server/BattlenetManager.h b/src/server/authserver/Server/BattlenetManager.h deleted file mode 100644 index bd01619ef06..00000000000 --- a/src/server/authserver/Server/BattlenetManager.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __BATTLENETMANAGER_H__ -#define __BATTLENETMANAGER_H__ - -#include "Define.h" -#include -#include -#include -#include - -namespace Battlenet -{ - struct Component - { - std::string Program; - std::string Platform; - uint32 Build; - }; - - struct ModuleKey - { - std::string Platform; - std::string Name; - - bool operator<(ModuleKey const& right) const - { - int32 res = Platform.compare(right.Platform); - if (res < 0) - return true; - else if (res > 0) - return false; - - return Name < right.Name; - } - }; - - struct ModuleInfo - { - ModuleInfo() : Region("EU"), DataSize(0), Data(nullptr) { } - ModuleInfo(ModuleInfo const& right) : Type(right.Type), Region(right.Region), DataSize(right.DataSize), Data(nullptr) - { - memcpy(ModuleId, right.ModuleId, 32); - if (DataSize) - { - Data = new uint8[DataSize]; - memcpy(Data, right.Data, DataSize); - } - } - ~ModuleInfo() - { - delete Data; - } - - std::string Type; - std::string Region; - uint8 ModuleId[32]; - uint32 DataSize; - uint8* Data; - }; - - struct RealmId - { - uint8 Region; - uint8 Battlegroup; - uint32 Index; - uint32 Build; - }; -} - -class BattlenetMgr -{ - BattlenetMgr() { } - ~BattlenetMgr(); - -public: - void Load(); - bool HasComponent(Battlenet::Component const* component) const; - bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; } - bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; } - Battlenet::ModuleInfo* CreateModule(std::string const& os, std::string const& name) const; - - static BattlenetMgr* instance() - { - static BattlenetMgr instance; - return &instance; - } - -private: - void LoadComponents(); - void LoadModules(); - - std::set _components; - std::set _programs; - std::set _platforms; - std::map _modules; -}; - -#define sBattlenetMgr BattlenetMgr::instance() - -#endif // __BATTLENETMANAGER_H__ diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.cpp b/src/server/authserver/Server/BattlenetPacketCrypt.cpp deleted file mode 100644 index de4cf73f71c..00000000000 --- a/src/server/authserver/Server/BattlenetPacketCrypt.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetPacketCrypt.h" -#include "Cryptography/HmacHash.h" -#include "Cryptography/BigNumber.h" - -Battlenet::PacketCrypt::PacketCrypt() : ::PacketCrypt(SHA256_DIGEST_LENGTH) -{ -} - -void Battlenet::PacketCrypt::Init(BigNumber* K) -{ - uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x68, 0xE0, 0xC7, 0x2E, 0xDD, 0xD6, 0xD2, 0xF3, 0x1E, 0x5A, 0xB1, 0x55, 0xB1, 0x8B, 0x63, 0x1E }; - uint8 ClientDecryptionKey[SEED_KEY_SIZE] = { 0xDE, 0xA9, 0x65, 0xAE, 0x54, 0x3A, 0x1E, 0x93, 0x9E, 0x69, 0x0C, 0xAA, 0x68, 0xDE, 0x78, 0x39 }; - - HmacSha256 serverEncryptHmac(K->GetNumBytes(), K->AsByteArray().get()); - serverEncryptHmac.UpdateData(ServerEncryptionKey, SEED_KEY_SIZE); - serverEncryptHmac.Finalize(); - - HmacSha256 clientDecryptHmac(K->GetNumBytes(), K->AsByteArray().get()); - clientDecryptHmac.UpdateData(ClientDecryptionKey, SEED_KEY_SIZE); - clientDecryptHmac.Finalize(); - - _clientDecrypt.Init(clientDecryptHmac.GetDigest()); - _serverEncrypt.Init(serverEncryptHmac.GetDigest()); - _initialized = true; -} diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.h b/src/server/authserver/Server/BattlenetPacketCrypt.h deleted file mode 100644 index dde687651d3..00000000000 --- a/src/server/authserver/Server/BattlenetPacketCrypt.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef __BATTLENETPACKETCRYPT_H__ -#define __BATTLENETPACKETCRYPT_H__ - -#include "PacketCrypt.h" - -class BigNumber; - -namespace Battlenet -{ - class PacketCrypt : public ::PacketCrypt - { - public: - PacketCrypt(); - - void Init(BigNumber* K) override; - }; -} - -#endif // __BATTLENETPACKETCRYPT_H__ diff --git a/src/server/authserver/Server/BattlenetPacketFactory.h b/src/server/authserver/Server/BattlenetPacketFactory.h deleted file mode 100644 index a0cbd8f5913..00000000000 --- a/src/server/authserver/Server/BattlenetPacketFactory.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BattlenetPacketFactory_h__ -#define BattlenetPacketFactory_h__ - -#include "BattlenetPackets.h" -#include - -namespace Battlenet -{ - class PacketFactory - { - typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream); - - public: - ClientPacket* Create(PacketHeader const& header, BitStream& stream) - { - auto creator = _creators.find(header); - if (creator == _creators.end()) - return nullptr; - - ClientPacket* packet = creator->second(header, stream); - packet->Read(); - return packet; - } - - static PacketFactory& Instance() - { - static PacketFactory instance; - return instance; - } - - private: - PacketFactory() - { - _creators[PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION)] = &New; - _creators[PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION)] = &New; - _creators[PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION)] = &New; - - _creators[PacketHeader(Connection::CMSG_PING, CONNECTION)] = &New; - _creators[PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION)] = &New; - _creators[PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION)] = &New; - - _creators[PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM)] = &New; - _creators[PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM)] = &New; - - _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS)] = &New; - // _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS)] = &New; - // _creators[PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS)] = &New; - _creators[PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS)] = &New; - - // _creators[PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE)] = &New; - // _creators[PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE)] = &New; - } - - template - static ClientPacket* New(PacketHeader const& header, BitStream& stream) - { - return new PacketType(header, stream); - } - - std::map _creators; - }; -} - -#define sBattlenetPacketFactory Battlenet::PacketFactory::Instance() - -#endif // BattlenetPacketFactory_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h b/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h deleted file mode 100644 index 69a03c7e16d..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/AchievementPackets.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef AchievementPackets_h__ -#define AchievementPackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Achievement - { - enum Opcode - { - CMSG_LISTEN_REQUEST = 0x0, // Not implemented - CMSG_CRITERIA_FLUSH_REQUEST = 0x3, // Not implemented - CMSG_CHANGE_TROPHY_CASE_REQUEST = 0x5, // Not implemented - - SMSG_DATA = 0x2, // Not implemented - SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented - SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented - SMSG_CHANGE_TROPHY_CASE_RESULT = 0x6 // Not implemented - }; - } -} - -#endif // AchievementPackets_h__ - diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h deleted file mode 100644 index 90dd4a35b1c..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef AuthenticationPackets_h__ -#define AuthenticationPackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Authentication - { - enum Opcode - { - CMSG_LOGON_REQUEST = 0x0, - CMSG_RESUME_REQUEST = 0x1, - CMSG_PROOF_RESPONSE = 0x2, - - SMSG_LOGON_RESPONSE = 0x0, - SMSG_RESUME_RESPONSE = 0x1, - SMSG_PROOF_REQUEST = 0x2, - SMSG_PATCH = 0x3, // Not implemented - SMSG_AUTHORIZED_LICENSES = 0x4 // Not implemented - }; - - class LogonRequest final : public ClientPacket - { - public: - LogonRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST, AUTHENTICATION) && "Invalid packet header for LogonRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - - std::string Program; - std::string Platform; - std::string Locale; - std::vector Components; - std::string Login; - }; - - class ResumeRequest final : public ClientPacket - { - public: - ResumeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_RESUME_REQUEST, AUTHENTICATION) && "Invalid packet header for ResumeRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - - std::string Program; - std::string Platform; - std::string Locale; - std::vector Components; - std::string Login; - uint8 Region; - std::string GameAccountName; - }; - - class ProofResponse final : public ClientPacket - { - public: - ProofResponse(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_PROOF_RESPONSE, AUTHENTICATION) && "Invalid packet header for ProofResponse"); - } - - ~ProofResponse(); - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - - std::vector Modules; - }; - - class ProofRequest final : public ServerPacket - { - public: - ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { } - ~ProofRequest(); - - void Write() override; - std::string ToString() const override; - - std::vector Modules; - }; - - class ResponseFailure - { - public: - enum Result - { - UPDATE = 0, - FAILURE = 1, - VERSION_CHECK_DISCONNECT = 2 - }; - - ResponseFailure() : ResultValue(UPDATE), Error(AUTH_OK), Wait(0) { } - - Result ResultValue; - AuthResult Error; - int32 Wait; - }; - - class Regulator - { - public: - enum Info - { - NONE = 0, - LEAKY_BUCKET = 1 - }; - - Regulator() : Type(LEAKY_BUCKET), Threshold(25000000), Rate(1000) { } - - Info Type; - uint32 Threshold; - uint32 Rate; - }; - - class LogonResponse final : public ServerPacket - { - public: - LogonResponse() : ServerPacket(PacketHeader(SMSG_LOGON_RESPONSE, AUTHENTICATION)), - PingTimeout(120000), FirstName(""), LastName(""), AccountId(0), Region(2), Flags(0), - GameAccountRegion(2), GameAccountName(""), FailedLogins(0) - { - } - - ~LogonResponse(); - - void Write() override; - std::string ToString() const override; - - std::vector Modules; - void SetAuthResult(AuthResult result); - ResponseFailure Result; - - int32 PingTimeout; - Regulator RegulatorRules; - std::string FirstName; - std::string LastName; - uint32 AccountId; - uint8 Region; - uint64 Flags; - uint8 GameAccountRegion; - std::string GameAccountName; - uint64 GameAccountFlags; - - uint32 FailedLogins; - }; - - class ResumeResponse final : public ServerPacket - { - public: - ResumeResponse() : ServerPacket(PacketHeader(SMSG_RESUME_RESPONSE, AUTHENTICATION)), PingTimeout(120000) - { - } - - ~ResumeResponse(); - - void Write() override; - std::string ToString() const override; - - std::vector Modules; - void SetAuthResult(AuthResult result); - ResponseFailure Result; - - int32 PingTimeout; - Regulator RegulatorRules; - }; - } -} - -#endif // AuthenticationPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h deleted file mode 100644 index d4cd8600266..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPackets.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BattlenetPackets_h__ -#define BattlenetPackets_h__ - -#include "AuthenticationPackets.h" -#include "ConnectionPackets.h" -#include "WoWRealmPackets.h" -#include "FriendsPackets.h" -#include "PresencePackets.h" -#include "ChatPackets.h" -#include "SupportPackets.h" -#include "AchievementPackets.h" -#include "CachePackets.h" -#include "ProfilePackets.h" - -#endif // BattlenetPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp b/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp deleted file mode 100644 index 034bb8ba0a4..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetPackets.h" -#include - -std::string Battlenet::PacketHeader::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel; - return stream.str(); -} - -Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream()) -{ - _stream.Write(header.Opcode, 6); - _stream.Write(1, 1); - _stream.Write(header.Channel, 4); -} - -Battlenet::ServerPacket::~ServerPacket() -{ - delete &_stream; -} diff --git a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h b/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h deleted file mode 100644 index 2aa07314771..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/BattlenetPacketsBase.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BattlenetPacketsBase_h__ -#define BattlenetPacketsBase_h__ - -#include "AuthCodes.h" -#include "BattlenetBitStream.h" -#include "BattlenetManager.h" -#include "Define.h" -#include "Errors.h" -#include -#include - -using boost::asio::ip::tcp; - -namespace Battlenet -{ - class BitStream; - class Session; - - enum Channel - { - AUTHENTICATION = 0, - CONNECTION = 1, - WOWREALM = 2, - FRIENDS = 3, - PRESENCE = 4, - CHAT = 5, - SUPPORT = 7, - ACHIEVEMENT = 8, - CACHE = 11, - PROFILE = 14 - }; - - struct PacketHeader - { - PacketHeader(uint32 opcode, uint32 channel) : Opcode(opcode), Channel(channel) { } - PacketHeader() : Opcode(0), Channel(AUTHENTICATION) { } - - uint32 Opcode; - int32 Channel; - - bool operator<(PacketHeader const& right) const - { - if (Opcode < right.Opcode) - return true; - if (Opcode > right.Opcode) - return false; - - return Channel < right.Channel; - } - - bool operator==(PacketHeader const& right) const - { - return Opcode == right.Opcode && Channel == right.Channel; - } - - std::string ToString() const; - }; - - class Packet - { - public: - Packet(PacketHeader const& header, BitStream& stream) : _header(header), _stream(stream) { } - virtual ~Packet() { } - - PacketHeader const& GetHeader() const { return _header; } - - virtual void Write() = 0; - virtual void Read() = 0; - - virtual std::string ToString() const = 0; - - protected: - PacketHeader _header; - BitStream& _stream; - - private: - Packet(Packet const& right); - Packet& operator=(Packet const& right); - }; - - class ClientPacket : public Packet - { - public: - ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { } - - void Write() override final { ASSERT(!"Write not implemented for this packet."); } - virtual void CallHandler(Session* session) const = 0; - }; - - class ServerPacket : public Packet - { - public: - ServerPacket(PacketHeader const& header); - ~ServerPacket(); - - void Read() override final { ASSERT(!"Read not implemented for server packets."); } - - uint8* GetData() { return _stream.GetBuffer(); } - uint8 const* GetData() const { return _stream.GetBuffer(); } - size_t GetSize() const { return _stream.GetSize(); } - }; -} - -#endif // BattlenetPacketsBase_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/CachePackets.h b/src/server/authserver/Server/BattlenetPackets/CachePackets.h deleted file mode 100644 index 6354201dc4c..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/CachePackets.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef CachePackets_h__ -#define CachePackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Cache - { - enum Opcode - { - CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented - CMSG_CONNECT_REQUEST = 0x4, // Not implemented - CMSG_DATA_CHUNK = 0x7, // Not implemented - SMSG_GET_STREAM_ITEMS_REQUEST = 0x9, // Not implemented - - SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented - SMSG_CONNECT_RESPONSE = 0x4, // Not implemented - SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented - SMSG_RESULT = 0x8, // Not implemented - SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9 // Not implemented - }; - } -} - -#endif // CachePackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/ChatPackets.h b/src/server/authserver/Server/BattlenetPackets/ChatPackets.h deleted file mode 100644 index ee11a1b732e..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/ChatPackets.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ChatPackets_h__ -#define ChatPackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Chat - { - enum Opcode - { - CMSG_JOIN_REQUEST_2 = 0x00, // Not implemented - CMSG_LEAVE_REQUEST = 0x02, // Not implemented - CMSG_INVITE_REQUEST = 0x03, // Not implemented - CMSG_CREATE_AND_INVITE_REQUEST = 0x0A, // Not implemented - CMSG_MESSAGE_SEND = 0x0B, // Not implemented - CMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented - CMSG_REPORT_SPAM_REQUEST = 0x0E, // Not implemented - CMSG_WHISPER_SEND = 0x13, // Not implemented - CMSG_ENUM_CATEGORY_DESCRIPTIONS = 0x15, // Not implemented - CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented - CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented - CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Not implemented - - SMSG_MEMBERSHIP_CHANGE_NOTIFY = 0x01, // Not implemented - SMSG_INVITE_NOTIFY = 0x04, // Not implemented - SMSG_INVITE_CANCELED = 0x07, // Not implemented - SMSG_MESSAGE_RECV = 0x0B, // Not implemented - SMSG_MESSAGE_UNDELIVERABLE = 0x0C, // Not implemented - SMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented - SMSG_INVITE_FAILURE = 0x0F, // Not implemented - SMSG_SYSTEM_MESSAGE = 0x10, // Not implemented - SMSG_MESSAGE_BLOCKED = 0x12, // Not implemented - SMSG_WHISPER_RECV = 0x13, // Not implemented - SMSG_WHISPER_UNDELIVERABLE = 0x14, // Not implemented - SMSG_CATEGORY_DESCRIPTIONS = 0x16, // Not implemented - SMSG_CONFERENCE_DESCRIPTIONS = 0x18, // Not implemented - SMSG_CONFERENCE_MEMBER_COUNTS = 0x1A, // Not implemented - SMSG_JOIN_NOTIFY_2 = 0x1B, // Not implemented - SMSG_MODIFY_CHANNEL_LIST_RESPONSE = 0x1C, // Not implemented - SMSG_CONFIG_CHANGED = 0x1D // Not implemented - }; - } -} - -#endif // ChatPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp deleted file mode 100644 index f0c3f3ea5e6..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetSession.h" -#include "ConnectionPackets.h" - -std::string Battlenet::Connection::Ping::ToString() const -{ - return "Battlenet::Connection::Ping"; -} - -void Battlenet::Connection::Ping::CallHandler(Session* session) const -{ - session->HandlePing(*this); -} - -std::string Battlenet::Connection::EnableEncryption::ToString() const -{ - return "Battlenet::Connection::EnableEncryption"; -} - -void Battlenet::Connection::EnableEncryption::CallHandler(Session* session) const -{ - session->HandleEnableEncryption(*this); -} - -std::string Battlenet::Connection::LogoutRequest::ToString() const -{ - return "Battlenet::Connection::LogoutRequest"; -} - -void Battlenet::Connection::LogoutRequest::CallHandler(Session* session) const -{ - session->HandleLogoutRequest(*this); -} - -std::string Battlenet::Connection::Pong::ToString() const -{ - return "Battlenet::Connection::Pong"; -} diff --git a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h b/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h deleted file mode 100644 index cc25f73f810..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/ConnectionPackets.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ConnectionPackets_h__ -#define ConnectionPackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Connection - { - enum Opcode - { - CMSG_PING = 0x0, - CMSG_ENABLE_ENCRYPTION = 0x5, - CMSG_LOGOUT_REQUEST = 0x6, - CMSG_DISCONNECT_REQUEST = 0x7, // Not implemented - CMSG_CONNECTION_CLOSING = 0x9, // Not implemented - - SMSG_PONG = 0x0, - SMSG_BOOM = 0x1, // Not implemented - SMSG_REGULATOR_UPDATE = 0x2, // Not implemented - SMSG_SERVER_VERSION = 0x3, // Not implemented - SMSG_STUN_SERVERS = 0x4 // Not implemented - }; - - class Ping final : public ClientPacket - { - public: - Ping(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_PING, CONNECTION) && "Invalid packet header for Ping"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - - class EnableEncryption final : public ClientPacket - { - public: - EnableEncryption(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_ENABLE_ENCRYPTION, CONNECTION) && "Invalid packet header for EnableEncryption"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - - class LogoutRequest final : public ClientPacket - { - public: - LogoutRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_LOGOUT_REQUEST, CONNECTION) && "Invalid packet header for LogoutRequest"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - - class Pong final : public ServerPacket - { - public: - Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION)) - { - } - - void Write() override { } - std::string ToString() const override; - }; - } -} - -#endif // ConnectionPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp deleted file mode 100644 index 336755acd4c..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetSession.h" -#include "FriendsPackets.h" - -void Battlenet::Friends::SocialnetworkCheckConnected::Read() -{ - SocialNetworkId = _stream.Read(32); -} - -std::string Battlenet::Friends::SocialnetworkCheckConnected::ToString() const -{ - return "Battlenet::Friends::SocialnetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); -} - -void Battlenet::Friends::SocialnetworkCheckConnected::CallHandler(Session* session) const -{ - SocialNetworkCheckConnectedResult* result = new SocialNetworkCheckConnectedResult(SocialNetworkId); - session->AsyncWrite(result); -} - -void Battlenet::Friends::SocialnetworkConnect::Read() -{ - int32 unk1 = _stream.Read(32); - uint32 size1 = _stream.Read(9); - auto data1 = _stream.ReadBytes(size1); - uint32 size2 = _stream.Read(7); - auto data2 = _stream.ReadBytes(size2); -} - -std::string Battlenet::Friends::SocialnetworkConnect::ToString() const -{ - return "Battlenet::Friends::SocialnetworkConnect"; -} - -void Battlenet::Friends::SocialnetworkConnect::CallHandler(Session* session) const -{ - -} - -std::string Battlenet::Friends::SocialNetworkConnectResult::ToString() const -{ - return "Battlenet::Friends::SocialNetworkConnectResult"; -} - -void Battlenet::Friends::SocialNetworkConnectResult::Write() -{ - -} - -std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const -{ - return "Battlenet::Friends::SocialNetworkCheckConnectedResult"; -} - -void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() -{ - _stream.Write(0, 23); // Ignored - volatile uint16 res = 0; - _stream.Write(res, 16); // Unknown - _stream.Write(SocialNetworkId, 32); -} - -void Battlenet::Friends::GetFriendsOfFriend::Read() -{ - uint8 unk = _stream.Read(2); - uint32 unk1 = _stream.Read(32); -} - -std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const -{ - return "Battlenet::Friends::GetFriendsOfFriend"; -} - -void Battlenet::Friends::GetFriendsOfFriend::CallHandler(Session* session) const -{ - -} - -void Battlenet::Friends::RealIdFriendInvite::Read() -{ - _stream.Read(32); - uint8 type = _stream.Read(3); - - switch (type) - { - case 0: - { - _stream.Read(32); // Presence Id? - break; - } - case 1: // GameAccount? - { - _stream.Read(8); - _stream.Read(32); - _stream.Read(32); - uint8 size = _stream.Read(7); // Only if *(a1 + 16) <= 0x64 - _stream.ReadBytes(size); - break; - } - case 2: - Email = _stream.ReadString(9, 3); - break; - case 3: - { - _stream.Read(32); - break; - } - case 4: - { - _stream.Read(64); - _stream.Read(32); - break; - } - } - - _stream.Read(1); - - if (_stream.Read(1)) - Message = _stream.ReadString(9); - - _stream.Read(32); -} - -std::string Battlenet::Friends::RealIdFriendInvite::ToString() const -{ - return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message; -} - -void Battlenet::Friends::RealIdFriendInvite::CallHandler(Session* session) const -{ - FriendInviteResult* result = new FriendInviteResult(); - session->AsyncWrite(result); -} - -std::string Battlenet::Friends::FriendInviteResult::ToString() const -{ - return "Battlenet::Friends::RealIdFriendInviteResult"; -} - -void Battlenet::Friends::FriendInviteResult::Write() -{ - bool hasNames = false; - _stream.Write(hasNames, 1); - if (hasNames) - { - _stream.WriteString("Testing1", 8); - _stream.WriteString("Testing2", 8); - } - _stream.Write(5, 32); - - _stream.Write(0, 0xC); // Ignored - - _stream.Write(1, 16); - - bool moreInfo = true; - _stream.Write(moreInfo, 1); - if (moreInfo) - { - _stream.Write(0, 8); - _stream.Write(4, 32); - _stream.Write(3, 32); - _stream.WriteString("Testing3", 7, 2); - } -} diff --git a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h b/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h deleted file mode 100644 index e58fbdff180..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/FriendsPackets.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef FriendsPackets_h__ -#define FriendsPackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Friends - { - enum Opcode - { - CMSG_FRIEND_INVITE = 0x01, // Not implemented - CMSG_FRIEND_INVITE_RESPONSE = 0x02, // Not implemented - CMSG_FRIEND_REMOVE = 0x04, // Not implemented - CMSG_FRIEND_NOTE = 0x05, // Not implemented - CMSG_TOONS_OF_FRIEND_REQUEST = 0x06, // Not implemented - CMSG_BLOCK_ADD = 0x08, // Not implemented - CMSG_BLOCK_REMOVE = 0x0A, // Not implemented - CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented - CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Not implemented - CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Not implemented - CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Not implemented - CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, - CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented - - SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented - SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented - SMSG_TOONS_OF_FRIEND_NOTIFY = 0x06, // Not implemented - SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented - SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented - SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented - SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Not implemented - SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Not implemented - SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Not implemented - SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, - SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented - SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented - }; - - class SocialnetworkConnect final : public ClientPacket - { - public: - SocialnetworkConnect(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS) && "Invalid packet header for SocialnetworkConnect"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - - class SocialNetworkConnectResult final : public ServerPacket - { - public: - SocialNetworkConnectResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS)) - { - } - - void Write() override; - std::string ToString() const override; - }; - - class SocialnetworkCheckConnected final : public ClientPacket - { - public: - SocialnetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - - uint32 SocialNetworkId; - }; - - class SocialNetworkCheckConnectedResult final : public ServerPacket - { - public: - SocialNetworkCheckConnectedResult(uint32 socialNetworkId) : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), SocialNetworkId(socialNetworkId) - { - } - - void Write() override; - std::string ToString() const override; - - uint32 SocialNetworkId; - }; - - class GetFriendsOfFriend final : public ClientPacket - { - public: - GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - - class FriendsOfFriend final : public ServerPacket - { - public: - FriendsOfFriend() : ServerPacket(PacketHeader(SMSG_FRIENDS_OF_FRIEND, FRIENDS)) - { - } - - void Write() override; - std::string ToString() const override; - }; - - class RealIdFriendInvite final : public ClientPacket - { - public: - RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - - std::string Email; - std::string Message; - }; - - class FriendInviteResult final : public ServerPacket - { - public: - FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS)) - { - } - - void Write() override; - std::string ToString() const override; - }; - } -} - -#endif // FriendsPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp b/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp deleted file mode 100644 index 46ce7fa1b36..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/PresencePackets.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetSession.h" -#include "PresencePackets.h" - - -void Battlenet::Presence::UpdateRequest::Read() -{ - -} - -std::string Battlenet::Presence::UpdateRequest::ToString() const -{ - return "Battlenet::Presence::UpdateRequest"; -} - -void Battlenet::Presence::UpdateRequest::CallHandler(Session* session) const -{ - -} - -void Battlenet::Presence::StatisticSubscribe::Read() -{ - -} - -std::string Battlenet::Presence::StatisticSubscribe::ToString() const -{ - return "Battlenet::Presence::StatisticSubscribe"; -} - -void Battlenet::Presence::StatisticSubscribe::CallHandler(Session* session) const -{ - -} diff --git a/src/server/authserver/Server/BattlenetPackets/PresencePackets.h b/src/server/authserver/Server/BattlenetPackets/PresencePackets.h deleted file mode 100644 index 0a934f2c2ca..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/PresencePackets.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef PresencePackets_h__ -#define PresencePackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Presence - { - enum Opcode - { - CMSG_UPDATE_REQUEST = 0x0, // Not implemented - CMSG_STATISTIC_SUBSCRIBE = 0x2, // Not implemented - - SMSG_UPDATE_NOTIFY = 0x0, // Not implemented - SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented - SMSG_STATISTICS_UPDATE = 0x3 // Not implemented - }; - - class UpdateRequest final : public ClientPacket - { - public: - UpdateRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_UPDATE_REQUEST, PRESENCE) && "Invalid packet header for UpdateRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - - class StatisticSubscribe final : public ClientPacket - { - public: - StatisticSubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_STATISTIC_SUBSCRIBE, PRESENCE) && "Invalid packet header for StatisticSubscribe"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - } -} - -#endif // PresencePackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/ProfilePackets.h b/src/server/authserver/Server/BattlenetPackets/ProfilePackets.h deleted file mode 100644 index d08fa4883c5..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/ProfilePackets.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef ProfilePackets_h__ -#define ProfilePackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Profile - { - enum Opcode - { - CMSG_READ_REQUEST = 0x0, // Not implemented - CMSG_ADDRESS_QUERY_REQUEST = 0x1, // Not implemented - CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST = 0x2, // Not implemented - CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST = 0x3, // Not implemented - CMSG_CHANGE_SETTINGS = 0x5, // Not implemented - - SMSG_READ_RESPONSE = 0x0, // Not implemented - SMSG_ADDRESS_QUERY_RESPONSE = 0x1, // Not implemented - SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE = 0x2, // Not implemented - SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE = 0x3, // Not implemented - SMSG_SETTINGS_AVAILABLE = 0x4 // Not implemented - }; - } -} - -#endif // ProfilePackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/SupportPackets.h b/src/server/authserver/Server/BattlenetPackets/SupportPackets.h deleted file mode 100644 index 4821ce7caa0..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/SupportPackets.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef SupportPackets_h__ -#define SupportPackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace Support - { - enum Opcode - { - CMSG_COMPLAINT_REQUEST = 0x0 // Not implemented - }; - } -} - -#endif // SupportPackets_h__ diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp b/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp deleted file mode 100644 index 1b20a3a7f85..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "WoWRealmPackets.h" -#include "BattlenetSession.h" -#include -#include - -std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const -{ - return "Battlenet::WoWRealm::ListSubscribeRequest"; -} - -void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) const -{ - session->HandleListSubscribeRequest(*this); -} - -Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse() -{ - for (ServerPacket* realmData : RealmData) - delete realmData; -} - -void Battlenet::WoWRealm::ListSubscribeResponse::Write() -{ - _stream.Write(Response, 1); - if (Response == SUCCESS) - { - _stream.Write(CharacterCounts.size(), 7); - for (CharacterCountEntry const& entry : CharacterCounts) - { - _stream.Write(entry.Realm.Battlegroup, 8); - _stream.Write(entry.Realm.Index, 32); - _stream.Write(entry.Realm.Region, 8); - _stream.Write(entry.CharacterCount, 16); - } - - for (ServerPacket* realmData : RealmData) - { - realmData->Write(); - _stream.WriteBytes(realmData->GetData(), realmData->GetSize()); - } - } - else - _stream.Write(ResponseCode, 8); -} - -std::string Battlenet::WoWRealm::ListSubscribeResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::ListSubscribeResponse"; - - if (Response == SUCCESS) - { - stream << " Realms " << CharacterCounts.size(); - - for (CharacterCountEntry const& entry : CharacterCounts) - stream << std::endl << "Region " << uint32(entry.Realm.Region) << " Battlegroup " << uint32(entry.Realm.Region) << " Index " << entry.Realm.Index << " Characters " << entry.CharacterCount; - - for (ServerPacket* realmData : RealmData) - stream << std::endl << realmData->ToString(); - } - else - stream << " Failure"; - - return stream.str().c_str(); -} - -void Battlenet::WoWRealm::ListUpdate::Write() -{ - _stream.Write(UpdateState, 1); - if (UpdateState == UPDATE) - { - _stream.Write(Type + -std::numeric_limits::min(), 32); - _stream.WriteFloat(Population); - _stream.Write(Flags, 8); - _stream.Write(Lock, 8); - _stream.Write(Timezone, 32); - _stream.Write(!Version.empty(), 1); - if (!Version.empty()) - { - _stream.WriteString(Version, 5); - _stream.Write(Build, 32); - - boost::asio::ip::address_v4::bytes_type ip = Address.address().to_v4().to_bytes(); - uint16 port = Address.port(); - - EndianConvertReverse(ip); - EndianConvertReverse(port); - - _stream.WriteBytes(ip.data(), 4); - _stream.WriteBytes(&port, 2); - } - - _stream.WriteString(Name, 10); - } - - _stream.Write(Battlegroup, 8); - _stream.Write(Index, 32); - _stream.Write(Region, 8); -} - -std::string Battlenet::WoWRealm::ListUpdate::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::ListUpdate Timezone " << Timezone << " Population " << Population << " Lock " << uint32(Lock) << " Type " << Type << " Name " << Name - << " Flags " << uint32(Flags) << " Region " << uint32(Region) << " Battlegroup " << uint32(Battlegroup) << " Index " << Index; - - if (!Version.empty()) - stream << " Version " << Version; - - return stream.str().c_str(); -} - -void Battlenet::WoWRealm::JoinRequestV2::Read() -{ - Realm.Battlegroup = _stream.Read(8); - Realm.Index = _stream.Read(32); - Realm.Region = _stream.Read(8); - ClientSeed = _stream.Read(32); -} - -std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index; - return stream.str().c_str(); -} - -void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) const -{ - session->HandleJoinRequestV2(*this); -} - -void Battlenet::WoWRealm::JoinResponseV2::Write() -{ - _stream.Write(0, 27); - _stream.Write(Response, 1); - if (Response == SUCCESS) - { - _stream.Write(ServerSeed, 32); - _stream.Write(IPv6.size(), 5); - for (tcp::endpoint const& addr : IPv6) - { - boost::asio::ip::address_v6::bytes_type ip = addr.address().to_v6().to_bytes(); - uint16 port = addr.port(); - - EndianConvertReverse(port); - - _stream.WriteBytes(ip.data(), 16); - _stream.WriteBytes(&port, 2); - } - - _stream.Write(IPv4.size(), 5); - for (tcp::endpoint const& addr : IPv4) - { - boost::asio::ip::address_v4::bytes_type ip = addr.address().to_v4().to_bytes(); - uint16 port = addr.port(); - - EndianConvertReverse(port); - - _stream.WriteBytes(ip.data(), 4); - _stream.WriteBytes(&port, 2); - } - } - else - _stream.Write(ResponseCode, 8); -} - -std::string Battlenet::WoWRealm::JoinResponseV2::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::WoWRealm::JoinResponseV2"; - if (Response == SUCCESS) - { - stream << " ServerSeed " << ServerSeed << " IPv4 Addresses " << IPv4.size() << " IPv6 Addresses " << IPv6.size(); - for (tcp::endpoint const& addr : IPv4) - stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast(addr); - - for (tcp::endpoint const& addr : IPv6) - stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast(addr); - } - else - stream << " Failure"; - - return stream.str().c_str(); -} diff --git a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h b/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h deleted file mode 100644 index 1e4228cb26a..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/WoWRealmPackets.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef WoWRealmPackets_h__ -#define WoWRealmPackets_h__ - -#include "BattlenetPacketsBase.h" - -namespace Battlenet -{ - namespace WoWRealm - { - enum Opcode - { - CMSG_LIST_SUBSCRIBE_REQUEST = 0x0, - CMSG_LIST_UNSUBSCRIBE = 0x1, // Not implemented - CMSG_JOIN_REQUEST_V2 = 0x8, - CMSG_MULTI_LOGON_REQUEST_V2 = 0x9, // Not implemented - - SMSG_LIST_SUBSCRIBE_RESPONSE = 0x0, - SMSG_LIST_UPDATE = 0x2, - SMSG_LIST_COMPLETE = 0x3, - SMSG_TOON_READY = 0x6, // Not implemented - SMSG_TOON_LOGGED_OUT = 0x7, // Not implemented - SMSG_JOIN_RESPONSE_V2 = 0x8 - }; - - class ListSubscribeRequest final : public ClientPacket - { - public: - ListSubscribeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM) && "Invalid packet header for ListSubscribeRequest"); - } - - void Read() override { } - std::string ToString() const override; - void CallHandler(Session* session) const override; - }; - - class JoinRequestV2 final : public ClientPacket - { - public: - JoinRequestV2(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_JOIN_REQUEST_V2, WOWREALM) && "Invalid packet header for RealmJoinRequest"); - } - - void Read() override; - std::string ToString() const override; - void CallHandler(Session* session) const override; - - uint32 ClientSeed; - RealmId Realm; - }; - - class ListSubscribeResponse final : public ServerPacket - { - public: - enum Result - { - SUCCESS = 0, - FAILURE = 1 - }; - - ListSubscribeResponse() : ServerPacket(PacketHeader(SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM)), - Response(SUCCESS), ResponseCode(26) - { - } - - ~ListSubscribeResponse(); - - struct CharacterCountEntry - { - RealmId Realm; - uint32 CharacterCount; - }; - - void Write() override; - std::string ToString() const override; - - Result Response; - uint8 ResponseCode; - std::vector CharacterCounts; - std::vector RealmData; - }; - - class ListUpdate final : public ServerPacket - { - public: - enum State - { - DELETED = 0, - UPDATE = 1 - }; - - ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)), UpdateState(UPDATE), - Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), - Flags(0), Region(0), Battlegroup(0), Index(0), Build(0) - { - } - - void Write() override; - std::string ToString() const override; - - int UpdateState; - uint32 Timezone; - float Population; - uint8 Lock; - uint32 Type; - std::string Name; - std::string Version; - tcp::endpoint Address; - uint8 Flags; - uint8 Region; - uint8 Battlegroup; - uint32 Index; - uint32 Build; - }; - - class ListComplete final : public ServerPacket - { - public: - ListComplete() : ServerPacket(PacketHeader(SMSG_LIST_COMPLETE, WOWREALM)) - { - } - - void Write() override { } - std::string ToString() const override { return "Battlenet::WoWRealm::ListComplete"; } - }; - - class JoinResponseV2 final : public ServerPacket - { - public: - enum Result - { - SUCCESS = 0, - FAILURE = 1 - }; - - JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)), - ServerSeed(0), Response(SUCCESS), ResponseCode(26) - { - } - - void Write() override; - std::string ToString() const override; - - Result Response; - uint8 ResponseCode; - uint32 ServerSeed; - std::vector IPv4; - std::vector IPv6; - }; - } -} - -#endif // WoWRealmPackets_h__ diff --git a/src/server/authserver/Server/BattlenetSession.cpp b/src/server/authserver/Server/BattlenetSession.cpp deleted file mode 100644 index 865e51c1a07..00000000000 --- a/src/server/authserver/Server/BattlenetSession.cpp +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "AuthCodes.h" -#include "BattlenetBitStream.h" -#include "BattlenetPacketFactory.h" -#include "BattlenetSessionManager.h" -#include "Database/DatabaseEnv.h" -#include "HmacHash.h" -#include "Log.h" -#include "RealmList.h" -#include "SHA256.h" -#include - -Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODULE_COUNT] = -{ - &Battlenet::Session::HandlePasswordModule, - &Battlenet::Session::UnhandledModule, - &Battlenet::Session::UnhandledModule, - &Battlenet::Session::HandleSelectGameAccountModule, - &Battlenet::Session::HandleRiskFingerprintModule, - &Battlenet::Session::HandleResumeModule, -}; - -Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountId(0), _accountName(), _locale(), - _os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), - _reconnectProof(), _crypt(), _authed(false) -{ - static uint8 const N_Bytes[] = - { - 0xAB, 0x24, 0x43, 0x63, 0xA9, 0xC2, 0xA6, 0xC3, 0x3B, 0x37, 0xE4, 0x61, 0x84, 0x25, 0x9F, 0x8B, - 0x3F, 0xCB, 0x8A, 0x85, 0x27, 0xFC, 0x3D, 0x87, 0xBE, 0xA0, 0x54, 0xD2, 0x38, 0x5D, 0x12, 0xB7, - 0x61, 0x44, 0x2E, 0x83, 0xFA, 0xC2, 0x21, 0xD9, 0x10, 0x9F, 0xC1, 0x9F, 0xEA, 0x50, 0xE3, 0x09, - 0xA6, 0xE5, 0x5E, 0x23, 0xA7, 0x77, 0xEB, 0x00, 0xC7, 0xBA, 0xBF, 0xF8, 0x55, 0x8A, 0x0E, 0x80, - 0x2B, 0x14, 0x1A, 0xA2, 0xD4, 0x43, 0xA9, 0xD4, 0xAF, 0xAD, 0xB5, 0xE1, 0xF5, 0xAC, 0xA6, 0x13, - 0x1C, 0x69, 0x78, 0x64, 0x0B, 0x7B, 0xAF, 0x9C, 0xC5, 0x50, 0x31, 0x8A, 0x23, 0x08, 0x01, 0xA1, - 0xF5, 0xFE, 0x31, 0x32, 0x7F, 0xE2, 0x05, 0x82, 0xD6, 0x0B, 0xED, 0x4D, 0x55, 0x32, 0x41, 0x94, - 0x29, 0x6F, 0x55, 0x7D, 0xE3, 0x0F, 0x77, 0x19, 0xE5, 0x6C, 0x30, 0xEB, 0xDE, 0xF6, 0xA7, 0x86 - }; - - N.SetBinary(N_Bytes, sizeof(N_Bytes)); - g.SetDword(2); - - SHA256Hash sha; - sha.UpdateBigNumbers(&N, &g, NULL); - sha.Finalize(); - k.SetBinary(sha.GetDigest(), sha.GetLength()); -} - -Battlenet::Session::~Session() -{ - sBattlenetSessionMgr.RemoveSession(this); - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::OnClose"); -} - -void Battlenet::Session::_SetVSFields(std::string const& pstr) -{ - s.SetRand(uint32(BufferSizes::SRP_6_S) * 8); - - BigNumber p; - p.SetHexStr(pstr.c_str()); - - SHA256Hash sha; - sha.UpdateBigNumbers(&s, &p, NULL); - sha.Finalize(); - BigNumber x; - x.SetBinary(sha.GetDigest(), sha.GetLength()); - v = g.ModExp(x, N); - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_VS_FIELDS); - stmt->setString(0, v.AsHexStr()); - stmt->setString(1, s.AsHexStr()); - stmt->setString(2, _accountName); - - LoginDatabase.Execute(stmt); -} - -void Battlenet::Session::LogUnhandledPacket(ClientPacket const& packet) -{ - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::LogUnhandledPacket %s", packet.ToString().c_str()); -} - -void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& info) -{ - // Verify that this IP is not in the ip_banned table - LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); - - std::string ip_address = GetRemoteIpAddress().to_string(); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED); - stmt->setString(0, ip_address); - if (PreparedQueryResult result = LoginDatabase.Query(stmt)) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_BANNED); - AsyncWrite(complete); - TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort()); - return; - } - - if (info.Program != "WoW") - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_INVALID_PROGRAM); - AsyncWrite(complete); - return; - } - - if (!sBattlenetMgr->HasPlatform(info.Platform)) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_INVALID_OS); - AsyncWrite(complete); - return; - } - - if (!sBattlenetMgr->HasPlatform(info.Locale)) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); - AsyncWrite(complete); - return; - } - - for (Component const& component : info.Components) - { - if (!sBattlenetMgr->HasComponent(&component)) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - if (!sBattlenetMgr->HasProgram(component.Program)) - complete->SetAuthResult(AUTH_INVALID_PROGRAM); - else if (!sBattlenetMgr->HasPlatform(component.Platform)) - complete->SetAuthResult(AUTH_INVALID_OS); - else - { - if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build)) - complete->SetAuthResult(AUTH_REGION_BAD_VERSION); - else - complete->SetAuthResult(AUTH_USE_GRUNT_LOGON); - } - - AsyncWrite(complete); - return; - } - - if (component.Platform == "base") - _build = component.Build; - } - - _accountName = info.Login; - _locale = info.Locale; - _os = info.Platform; - - Utf8ToUpperOnlyLatin(_accountName); - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); - stmt->setString(0, _accountName); - - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (!result) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - AsyncWrite(complete); - return; - } - - Field* fields = result->Fetch(); - - _accountId = fields[1].GetUInt32(); - - // If the IP is 'locked', check that the player comes indeed from the correct IP address - if (fields[2].GetUInt8() == 1) // if ip is locked - { - TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str()); - - if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); - AsyncWrite(complete); - return; - } - } - else - { - TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is not locked to ip", _accountName.c_str()); - std::string accountCountry = fields[3].GetString(); - if (accountCountry.empty() || accountCountry == "00") - TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is not locked to country", _accountName.c_str()); - else if (!accountCountry.empty()) - { - uint32 ip = inet_addr(ip_address.c_str()); - EndianConvertReverse(ip); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); - stmt->setUInt32(0, ip); - if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt)) - { - std::string loginCountry = (*sessionCountryQuery)[0].GetString(); - TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str()); - if (loginCountry != accountCountry) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); - AsyncWrite(complete); - return; - } - } - } - } - - //set expired bans to inactive - LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_EXPIRED_BANS)); - - // If the account is banned, reject the logon attempt - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN); - stmt->setUInt32(0, _accountId); - PreparedQueryResult banresult = LoginDatabase.Query(stmt); - if (banresult) - { - Field* fields = banresult->Fetch(); - if (fields[0].GetUInt32() == fields[1].GetUInt32()) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_BANNED); - AsyncWrite(complete); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); - return; - } - else - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_SUSPENDED); - AsyncWrite(complete); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); - return; - } - } - - SHA256Hash sha; - sha.UpdateData(_accountName); - sha.Finalize(); - - I.SetBinary(sha.GetDigest(), sha.GetLength()); - - ModuleInfo* password = sBattlenetMgr->CreateModule(_os, "Password"); - ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint"); - - std::string pStr = fields[0].GetString(); - - std::string databaseV = fields[5].GetString(); - std::string databaseS = fields[6].GetString(); - - if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2) - _SetVSFields(pStr); - else - { - s.SetHexStr(databaseS.c_str()); - v.SetHexStr(databaseV.c_str()); - } - - b.SetRand(128 * 8); - B = ((v * k) + g.ModExp(b, N)) % N; - BigNumber unk; - unk.SetRand(128 * 8); - - BitStream passwordData; - uint8 state = 0; - passwordData.WriteBytes(&state, 1); - passwordData.WriteBytes(I.AsByteArray(32).get(), 32); - passwordData.WriteBytes(s.AsByteArray(32).get(), 32); - passwordData.WriteBytes(B.AsByteArray(128).get(), 128); - passwordData.WriteBytes(unk.AsByteArray(128).get(), 128); - - password->DataSize = passwordData.GetSize(); - password->Data = new uint8[password->DataSize]; - memcpy(password->Data, passwordData.GetBuffer(), password->DataSize); - - _modulesWaitingForData.push(MODULE_PASSWORD); - - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(password); - // if has authenticator, send Token module - request->Modules.push_back(thumbprint); - AsyncWrite(request); -} - -void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& reconnect) -{ - _accountName = reconnect.Login; - _locale = reconnect.Locale; - _os = reconnect.Platform; - auto baseComponent = std::find_if(reconnect.Components.begin(), reconnect.Components.end(), [](Component const& c) { return c.Program == "base"; }); - if (baseComponent != reconnect.Components.end()) - _build = baseComponent->Build; - - Utf8ToUpperOnlyLatin(_accountName); - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); - stmt->setString(0, _accountName); - stmt->setString(1, reconnect.GameAccountName); - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (!result) - { - Authentication::ResumeResponse* resume = new Authentication::ResumeResponse(); - resume->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - AsyncWrite(resume); - return; - } - - Field* fields = result->Fetch(); - - _accountId = fields[0].GetUInt32(); - K.SetHexStr(fields[1].GetString().c_str()); - _gameAccountId = fields[2].GetUInt32(); - _gameAccountName = reconnect.GameAccountName; - - ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint"); - ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume"); - BitStream resumeData; - uint8 state = 0; - _reconnectProof.SetRand(16 * 8); - - resumeData.WriteBytes(&state, 1); - resumeData.WriteBytes(_reconnectProof.AsByteArray().get(), 16); - - resume->DataSize = resumeData.GetSize(); - resume->Data = new uint8[resume->DataSize]; - memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); - - _modulesWaitingForData.push(MODULE_RESUME); - - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(thumbprint); - request->Modules.push_back(resume); - AsyncWrite(request); -} - -void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proof) -{ - if (_modulesWaitingForData.size() < proof.Modules.size()) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - AsyncWrite(complete); - return; - } - - ServerPacket* response = nullptr; - for (size_t i = 0; i < proof.Modules.size(); ++i) - { - if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proof.Modules[i], &response)) - break; - - _modulesWaitingForData.pop(); - } - - if (!response) - { - response = new Authentication::LogonResponse(); - static_cast(response)->SetAuthResult(AUTH_INTERNAL_ERROR); - } - - AsyncWrite(response); - return; -} - -void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/) -{ - AsyncWrite(new Connection::Pong()); -} - -void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption const& /*enableEncryption*/) -{ - _crypt.Init(&K); -} - -void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/) -{ - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); - stmt->setString(0, ""); - stmt->setBool(1, false); - stmt->setUInt32(2, _accountId); - LoginDatabase.Execute(stmt); -} - -void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/) -{ - sRealmList->UpdateIfNeed(); - - WoWRealm::ListSubscribeResponse* counts = new WoWRealm::ListSubscribeResponse(); - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS); - stmt->setUInt32(0, _gameAccountId); - - if (PreparedQueryResult countResult = LoginDatabase.Query(stmt)) - { - do - { - Field* fields = countResult->Fetch(); - uint32 build = fields[4].GetUInt32(); - counts->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() }); - } while (countResult->NextRow()); - } - - for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) - { - Realm const& realm = i->second; - - uint32 flag = realm.flag; - RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild); - if (realm.gamebuild != _build) - { - if (!buildInfo) - continue; - - flag |= REALM_FLAG_OFFLINE | REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for - } - - if (!buildInfo) - flag &= ~REALM_FLAG_SPECIFYBUILD; - - WoWRealm::ListUpdate* update = new WoWRealm::ListUpdate(); - update->Timezone = realm.timezone; - update->Population = realm.populationLevel; - update->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; - update->Type = realm.icon; - update->Name = realm.name; - - if (flag & REALM_FLAG_SPECIFYBUILD) - { - std::ostringstream version; - version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; - - update->Version = version.str(); - update->Address = realm.GetAddressForClient(GetRemoteIpAddress()); - update->Build = buildInfo->Build; - } - - update->Flags = flag; - update->Region = realm.Region; - update->Battlegroup = realm.Battlegroup; - update->Index = realm.m_ID; - - counts->RealmData.push_back(update); - } - - counts->RealmData.push_back(new WoWRealm::ListComplete()); - - AsyncWrite(counts); -} - -void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join) -{ - WoWRealm::JoinResponseV2* result = new WoWRealm::JoinResponseV2(); - Realm const* realm = sRealmList->GetRealm(join.Realm); - if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE)) - { - result->Response = WoWRealm::JoinResponseV2::FAILURE; - AsyncWrite(result); - return; - } - - result->ServerSeed = uint32(rand32()); - - uint8 sessionKey[40]; - HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get()); - hmac.UpdateData((uint8*)"WoW\0", 4); - hmac.UpdateData((uint8*)&join.ClientSeed, 4); - hmac.UpdateData((uint8*)&result->ServerSeed, 4); - hmac.Finalize(); - - memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength()); - - HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get()); - hmac2.UpdateData((uint8*)"WoW\0", 4); - hmac2.UpdateData((uint8*)&result->ServerSeed, 4); - hmac2.UpdateData((uint8*)&join.ClientSeed, 4); - hmac2.Finalize(); - - memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength()); - - LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u", - ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountId); - - result->IPv4.emplace_back(realm->ExternalAddress, realm->port); - if (realm->ExternalAddress != realm->LocalAddress) - result->IPv4.emplace_back(realm->LocalAddress, realm->port); - - AsyncWrite(result); -} - -void Battlenet::Session::ReadHandler() -{ - BitStream stream(std::move(GetReadBuffer())); - _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize()); - - while (!stream.IsRead()) - { - try - { - PacketHeader header; - header.Opcode = stream.Read(6); - if (stream.Read(1)) - header.Channel = stream.Read(4); - - if (header.Channel != AUTHENTICATION && !_authed) - { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Received not allowed packet %s", header.ToString().c_str()); - CloseSocket(); - return; - } - - if (ClientPacket* packet = sBattlenetPacketFactory.Create(header, stream)) - { - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", packet->ToString().c_str()); - packet->CallHandler(this); - delete packet; - } - else - { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Unhandled opcode %s", header.ToString().c_str()); - break; - } - - stream.AlignToNextByte(); - } - catch (BitStreamPositionException const& e) - { - TC_LOG_ERROR("server.battlenet", "Battlenet::Session::ReadDataHandler Exception: %s", e.what()); - CloseSocket(); - return; - } - } - - GetReadBuffer().Resize(size_t(BufferSizes::Read)); - AsyncRead(); -} - -void Battlenet::Session::Start() -{ - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::Start"); - AsyncRead(); -} - -void Battlenet::Session::AsyncWrite(ServerPacket* packet) -{ - if (!IsOpen()) - { - delete packet; - return; - } - - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncWrite %s", packet->ToString().c_str()); - - packet->Write(); - - MessageBuffer buffer; - buffer.Write(packet->GetData(), packet->GetSize()); - delete packet; - - std::unique_lock guard(_writeLock); - - _crypt.EncryptSend(buffer.GetReadPointer(), buffer.GetActiveSize()); - - QueuePacket(std::move(buffer), guard); -} - -inline void ReplaceResponse(Battlenet::ServerPacket** oldResponse, Battlenet::ServerPacket* newResponse) -{ - if (*oldResponse) - delete *oldResponse; - - *oldResponse = newResponse; -} - -bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacket** response) -{ - if (dataStream->GetSize() != 1 + 128 + 32 + 128) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); - return false; - } - - if (dataStream->Read(8) != 2) // State - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); - return false; - } - - - BigNumber A, clientM1, clientChallenge; - A.SetBinary(dataStream->ReadBytes(128).get(), 128); - clientM1.SetBinary(dataStream->ReadBytes(32).get(), 32); - clientChallenge.SetBinary(dataStream->ReadBytes(128).get(), 128); - - if (A.isZero()) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); - return false; - } - - SHA256Hash sha; - sha.UpdateBigNumbers(&A, &B, NULL); - sha.Finalize(); - - BigNumber u; - u.SetBinary(sha.GetDigest(), sha.GetLength()); - - BigNumber S = ((A * v.ModExp(u, N)) % N).ModExp(b, N); - - uint8 S_bytes[128]; - memcpy(S_bytes, S.AsByteArray(128).get(), 128); - - uint8 part1[64]; - uint8 part2[64]; - - for (int i = 0; i < 64; ++i) - { - part1[i] = S_bytes[i * 2]; - part2[i] = S_bytes[i * 2 + 1]; - } - - SHA256Hash part1sha, part2sha; - part1sha.UpdateData(part1, 64); - part1sha.Finalize(); - part2sha.UpdateData(part2, 64); - part2sha.Finalize(); - - uint8 sessionKey[SHA256_DIGEST_LENGTH * 2]; - for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) - { - sessionKey[i * 2] = part1sha.GetDigest()[i]; - sessionKey[i * 2 + 1] = part2sha.GetDigest()[i]; - } - - K.SetBinary(sessionKey, SHA256_DIGEST_LENGTH * 2); - - BigNumber M1; - - uint8 hash[SHA256_DIGEST_LENGTH]; - sha.Initialize(); - sha.UpdateBigNumbers(&N, NULL); - sha.Finalize(); - memcpy(hash, sha.GetDigest(), sha.GetLength()); - - sha.Initialize(); - sha.UpdateBigNumbers(&g, NULL); - sha.Finalize(); - - for (int i = 0; i < sha.GetLength(); ++i) - hash[i] ^= sha.GetDigest()[i]; - - SHA256Hash shaI; - shaI.UpdateData(ByteArrayToHexStr(I.AsByteArray().get(), 32)); - shaI.Finalize(); - - // Concat all variables for M1 hash - sha.Initialize(); - sha.UpdateData(hash, SHA256_DIGEST_LENGTH); - sha.UpdateData(shaI.GetDigest(), shaI.GetLength()); - sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); - sha.Finalize(); - - M1.SetBinary(sha.GetDigest(), sha.GetLength()); - - if (memcmp(M1.AsByteArray().get(), clientM1.AsByteArray().get(), 32)) - { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); - stmt->setString(0, _accountName); - LoginDatabase.Execute(stmt); - - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - ReplaceResponse(response, complete); - return false; - } - - uint64 numAccounts = 0; - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS); - stmt->setUInt32(0, _accountId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (result) - numAccounts = result->GetRowCount(); - - if (!numAccounts) - { - Authentication::LogonResponse* noAccounts = new Authentication::LogonResponse(); - noAccounts->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, noAccounts); - return false; - } - - Field* fields = result->Fetch(); - - //set expired game account bans to inactive - LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); - - BigNumber M; - sha.Initialize(); - sha.UpdateBigNumbers(&A, &M1, &K, NULL); - sha.Finalize(); - M.SetBinary(sha.GetDigest(), sha.GetLength()); - - BigNumber serverProof; - serverProof.SetRand(128 * 8); // just send garbage, server signature check is patched out in client - - BitStream stream; - ModuleInfo* password = sBattlenetMgr->CreateModule(_os, "Password"); - uint8 state = 3; - - stream.WriteBytes(&state, 1); - stream.WriteBytes(M.AsByteArray(32).get(), 32); - stream.WriteBytes(serverProof.AsByteArray(128).get(), 128); - - password->DataSize = stream.GetSize(); - password->Data = new uint8[password->DataSize]; - memcpy(password->Data, stream.GetBuffer(), password->DataSize); - - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(password); - if (numAccounts > 1) - { - BitStream accounts; - state = 0; - accounts.WriteBytes(&state, 1); - accounts.Write(numAccounts, 8); - do - { - fields = result->Fetch(); - std::ostringstream name; - std::string originalName = fields[1].GetString(); - if (originalName.find('#') != std::string::npos) - name << "WoW" << uint32(fields[0].GetUInt8()); - else - name << originalName; - - accounts.Write(2, 8); - accounts.WriteString(name.str(), 8); - } while (result->NextRow()); - - ModuleInfo* selectGameAccount = sBattlenetMgr->CreateModule(_os, "SelectGameAccount"); - selectGameAccount->DataSize = accounts.GetSize(); - selectGameAccount->Data = new uint8[selectGameAccount->DataSize]; - memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize); - request->Modules.push_back(selectGameAccount); - _modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT); - } - else - { - if (fields[4].GetBool()) - { - delete request; - - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - if (fields[2].GetUInt32() == fields[3].GetUInt32()) - { - complete->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); - } - else - { - complete->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::AuthChallenge] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); - } - - ReplaceResponse(response, complete); - return false; - } - - _gameAccountId = fields[0].GetUInt32(); - _gameAccountName = fields[1].GetString(); - - request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint")); - _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); - } - - ReplaceResponse(response, request); - return true; -} - -bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response) -{ - if (dataStream->Read(8) != 1) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); - return false; - } - - dataStream->Read(8); - std::string account = dataStream->ReadString(8); - if (account.empty()) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, complete); - return false; - } - - PreparedStatement* stmt; - if (account.substr(0, 3) != "WoW") - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT); - stmt->setString(0, account); - } - else - { - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED); - stmt->setUInt8(0, atol(account.substr(3).c_str())); - } - - stmt->setUInt32(1, _accountId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - if (!result) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, complete); - return false; - } - - Field* fields = result->Fetch(); - if (fields[4].GetBool()) - { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - if (fields[2].GetUInt32() == fields[3].GetUInt32()) - { - complete->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); - } - else - { - complete->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); - } - - ReplaceResponse(response, complete); - return false; - } - - _gameAccountId = fields[0].GetUInt32(); - _gameAccountName = fields[1].GetString(); - - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(sBattlenetMgr->CreateModule(_os, "RiskFingerprint")); - ReplaceResponse(response, request); - - _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); - return true; -} - -bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response) -{ - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - if (dataStream->Read(8) == 1) - { - complete->AccountId = _accountId; - complete->GameAccountName = _gameAccountName; - complete->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_FAILED_LOGINS); - stmt->setUInt32(0, _accountId); - if (PreparedQueryResult failedLoginsResult = LoginDatabase.Query(stmt)) - complete->FailedLogins = (*failedLoginsResult)[0].GetUInt32(); - - SQLTransaction trans = LoginDatabase.BeginTransaction(); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO); - stmt->setString(0, GetRemoteIpAddress().to_string()); - stmt->setUInt8(1, GetLocaleByName(_locale)); - stmt->setString(2, _os); - stmt->setUInt32(3, _accountId); - trans->Append(stmt); - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); - stmt->setString(0, K.AsHexStr()); - stmt->setBool(1, true); - stmt->setUInt32(2, _accountId); - trans->Append(stmt); - - LoginDatabase.CommitTransaction(trans); - - _authed = true; - sBattlenetSessionMgr.AddSession(this); - } - else - complete->SetAuthResult(AUTH_BAD_VERSION_HASH); - - ReplaceResponse(response, complete); - return true; -} - -bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket** response) -{ - if (dataStream->Read(8) != 1) - { - Authentication::ResumeResponse* complete = new Authentication::ResumeResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); - return false; - } - - static uint8 const ResumeClient = 0; - static uint8 const ResumeServer = 1; - - std::unique_ptr clientChallenge = dataStream->ReadBytes(16); - std::unique_ptr clientProof = dataStream->ReadBytes(32); - std::unique_ptr serverChallenge = _reconnectProof.AsByteArray(16); - std::unique_ptr sessionKey = K.AsByteArray(64); - - HmacSha256 clientPart(64, sessionKey.get()); - clientPart.UpdateData(&ResumeClient, 1); - clientPart.UpdateData(clientChallenge.get(), 16); - clientPart.UpdateData(serverChallenge.get(), 16); - clientPart.Finalize(); - - HmacSha256 serverPart(64, sessionKey.get()); - serverPart.UpdateData(&ResumeServer, 1); - serverPart.UpdateData(serverChallenge.get(), 16); - serverPart.UpdateData(clientChallenge.get(), 16); - serverPart.Finalize(); - - uint8 newSessionKey[64]; - memcpy(&newSessionKey[0], clientPart.GetDigest(), clientPart.GetLength()); - memcpy(&newSessionKey[32], serverPart.GetDigest(), serverPart.GetLength()); - - K.SetBinary(newSessionKey, 64); - - HmacSha256 proof(64, newSessionKey); - proof.UpdateData(&ResumeClient, 1); - proof.UpdateData(clientChallenge.get(), 16); - proof.UpdateData(serverChallenge.get(), 16); - proof.Finalize(); - - if (memcmp(proof.GetDigest(), clientProof.get(), serverPart.GetLength())) - { - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); - stmt->setString(0, _accountName); - LoginDatabase.Execute(stmt); - - TC_LOG_DEBUG("server.battlenet", "[Battlenet::Resume] Invalid proof!"); - Authentication::ResumeResponse* result = new Authentication::ResumeResponse(); - result->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - ReplaceResponse(response, result); - return false; - } - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); - stmt->setString(0, K.AsHexStr()); - stmt->setBool(1, true); - stmt->setUInt32(2, _accountId); - LoginDatabase.Execute(stmt); - - HmacSha256 serverProof(64, newSessionKey); - serverProof.UpdateData(&ResumeServer, 1); - serverProof.UpdateData(serverChallenge.get(), 16); - serverProof.UpdateData(clientChallenge.get(), 16); - serverProof.Finalize(); - - ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume"); - - BitStream resumeData; - uint8 state = 2; - resumeData.WriteBytes(&state, 1); - resumeData.WriteBytes(serverProof.GetDigest(), serverProof.GetLength()); - - resume->DataSize = resumeData.GetSize(); - resume->Data = new uint8[resume->DataSize]; - memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); - - Authentication::ResumeResponse* result = new Authentication::ResumeResponse(); - result->Modules.push_back(resume); - ReplaceResponse(response, result); - _authed = true; - sBattlenetSessionMgr.AddSession(this); - return true; -} - -bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response) -{ - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); - return false; -} diff --git a/src/server/authserver/Server/BattlenetSession.h b/src/server/authserver/Server/BattlenetSession.h deleted file mode 100644 index 2798949de1c..00000000000 --- a/src/server/authserver/Server/BattlenetSession.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef _BATTLENETSOCKET_H -#define _BATTLENETSOCKET_H - -#include "BattlenetPackets.h" -#include "BattlenetPacketCrypt.h" -#include "Socket.h" -#include "BigNumber.h" -#include -#include - -using boost::asio::ip::tcp; - -namespace Battlenet -{ - struct PacketHeader; - class BitStream; - - enum ModuleType - { - MODULE_PASSWORD, - MODULE_TOKEN, - MODULE_THUMBPRINT, - MODULE_SELECT_GAME_ACCOUNT, - MODULE_RISK_FINGERPRINT, - MODULE_RESUME, - - MODULE_COUNT - }; - - enum class BufferSizes : uint32 - { - SRP_6_V = 0x80, - SRP_6_S = 0x20, - Read = 0x4000 - }; - - class Session : public Socket - { - typedef Socket BattlenetSocket; - - public: - explicit Session(tcp::socket&& socket); - ~Session(); - - void LogUnhandledPacket(ClientPacket const& packet); - - // Authentication - void HandleLogonRequest(Authentication::LogonRequest const& logonRequest); - void HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest); - void HandleProofResponse(Authentication::ProofResponse const& proofResponse); - - // Connection - void HandlePing(Connection::Ping const& ping); - void HandleEnableEncryption(Connection::EnableEncryption const& enableEncryption); - void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest); - - // WoWRealm - void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest); - void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest); - - void Start() override; - - void AsyncWrite(ServerPacket* packet); - - protected: - void ReadHandler() override; - - private: - void _SetVSFields(std::string const& rI); - - typedef bool(Session::*ModuleHandler)(BitStream* dataStream, ServerPacket** response); - static ModuleHandler const ModuleHandlers[MODULE_COUNT]; - - bool HandlePasswordModule(BitStream* dataStream, ServerPacket** response); - bool HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response); - bool HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response); - bool HandleResumeModule(BitStream* dataStream, ServerPacket** response); - bool UnhandledModule(BitStream* dataStream, ServerPacket** response); - - uint32 _accountId; - std::string _accountName; - std::string _locale; - std::string _os; - uint32 _build; - uint32 _gameAccountId; - std::string _gameAccountName; - AccountTypes _accountSecurityLevel; - - BigNumber N; - BigNumber g; - BigNumber k; - - BigNumber I; - BigNumber s; - BigNumber v; - - BigNumber b; - BigNumber B; - BigNumber K; // session key - - BigNumber _reconnectProof; - - std::queue _modulesWaitingForData; - - PacketCrypt _crypt; - bool _authed; - }; - -} - -#endif // _BATTLENETSOCKET_H diff --git a/src/server/authserver/Server/BattlenetSessionManager.cpp b/src/server/authserver/Server/BattlenetSessionManager.cpp deleted file mode 100644 index 91ba2b65094..00000000000 --- a/src/server/authserver/Server/BattlenetSessionManager.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "BattlenetSessionManager.h" - -bool Battlenet::SessionManager::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) -{ - if (!BaseSocketMgr::StartNetwork(service, bindIp, port)) - return false; - - _acceptor->AsyncAcceptManaged(&OnSocketAccept); - return true; -} - -NetworkThread* Battlenet::SessionManager::CreateThreads() const -{ - return new NetworkThread[GetNetworkThreadCount()]; -} - -void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock) -{ - sBattlenetSessionMgr.OnSocketOpen(std::forward(sock)); -} diff --git a/src/server/authserver/Server/BattlenetSessionManager.h b/src/server/authserver/Server/BattlenetSessionManager.h deleted file mode 100644 index b5a54438ef1..00000000000 --- a/src/server/authserver/Server/BattlenetSessionManager.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef BattlenetSessionManager_h__ -#define BattlenetSessionManager_h__ - -#include "BattlenetSession.h" -#include "SocketMgr.h" - -namespace Battlenet -{ -#pragma pack(push, 1) - - struct SessionInfo - { - uint32 AccountId; - uint32 GameAccountIndex; - - bool operator<(SessionInfo const& right) const - { - return memcmp(this, &right, sizeof(SessionInfo)) < 0; - } - }; - -#pragma pack(pop) - - class SessionManager : SocketMgr - { - typedef SocketMgr BaseSocketMgr; - - public: - static SessionManager& Instance() - { - static SessionManager instance; - return instance; - } - - bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) override; - - // noop for now, will be needed later to broadcast realmlist updates for example - void AddSession(Session* /*session*/) { } - - void RemoveSession(Session* /*session*/) { } - - protected: - NetworkThread* CreateThreads() const override; - - private: - static void OnSocketAccept(tcp::socket&& sock); - - std::map _sessions; - }; -} - -#define sBattlenetSessionMgr Battlenet::SessionManager::Instance() - -#endif // BattlenetSessionManager_h__ diff --git a/src/server/bnetserver/Authentication/AuthCodes.cpp b/src/server/bnetserver/Authentication/AuthCodes.cpp new file mode 100644 index 00000000000..908bc30b719 --- /dev/null +++ b/src/server/bnetserver/Authentication/AuthCodes.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AuthCodes.h" +#include + +namespace AuthHelper +{ + static RealmBuildInfo const PostBcAcceptedClientBuilds[] = + { + {15595, 4, 3, 4, ' '}, + {14545, 4, 2, 2, ' '}, + {13623, 4, 0, 6, 'a'}, + {13930, 3, 3, 5, 'a'}, // 3.3.5a China Mainland build + {12340, 3, 3, 5, 'a'}, + {11723, 3, 3, 3, 'a'}, + {11403, 3, 3, 2, ' '}, + {11159, 3, 3, 0, 'a'}, + {10505, 3, 2, 2, 'a'}, + {9947, 3, 1, 3, ' '}, + {8606, 2, 4, 3, ' '}, + {6141, 1, 12, 3, ' '}, + {6005, 1, 12, 2, ' '}, + {5875, 1, 12, 1, ' '}, + {0, 0, 0, 0, ' '} // terminator + }; + + RealmBuildInfo const* GetBuildInfo(int build) + { + for (int i = 0; PostBcAcceptedClientBuilds[i].Build; ++i) + if (PostBcAcceptedClientBuilds[i].Build == build) + return &PostBcAcceptedClientBuilds[i]; + + return nullptr; + } + + bool IsBuildSupportingBattlenet(int build) + { + return build >= 15595; + } +} diff --git a/src/server/bnetserver/Authentication/AuthCodes.h b/src/server/bnetserver/Authentication/AuthCodes.h new file mode 100644 index 00000000000..3c3b002551c --- /dev/null +++ b/src/server/bnetserver/Authentication/AuthCodes.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef _AUTHCODES_H +#define _AUTHCODES_H + +enum GameAccountFlags +{ + GAMEACCOUNT_FLAG_GM = 0x00000001, + GAMEACCOUNT_FLAG_NOKICK = 0x00000002, + GAMEACCOUNT_FLAG_COLLECTOR = 0x00000004, + GAMEACCOUNT_FLAG_WOW_TRIAL = 0x00000008, + GAMEACCOUNT_FLAG_CANCELLED = 0x00000010, + GAMEACCOUNT_FLAG_IGR = 0x00000020, + GAMEACCOUNT_FLAG_WHOLESALER = 0x00000040, + GAMEACCOUNT_FLAG_PRIVILEGED = 0x00000080, + GAMEACCOUNT_FLAG_EU_FORBID_ELV = 0x00000100, + GAMEACCOUNT_FLAG_EU_FORBID_BILLING = 0x00000200, + GAMEACCOUNT_FLAG_WOW_RESTRICTED = 0x00000400, + GAMEACCOUNT_FLAG_REFERRAL = 0x00000800, + GAMEACCOUNT_FLAG_BLIZZARD = 0x00001000, + GAMEACCOUNT_FLAG_RECURRING_BILLING = 0x00002000, + GAMEACCOUNT_FLAG_NOELECTUP = 0x00004000, + GAMEACCOUNT_FLAG_KR_CERTIFICATE = 0x00008000, + GAMEACCOUNT_FLAG_EXPANSION_COLLECTOR = 0x00010000, + GAMEACCOUNT_FLAG_DISABLE_VOICE = 0x00020000, + GAMEACCOUNT_FLAG_DISABLE_VOICE_SPEAK = 0x00040000, + GAMEACCOUNT_FLAG_REFERRAL_RESURRECT = 0x00080000, + GAMEACCOUNT_FLAG_EU_FORBID_CC = 0x00100000, + GAMEACCOUNT_FLAG_OPENBETA_DELL = 0x00200000, + GAMEACCOUNT_FLAG_PROPASS = 0x00400000, + GAMEACCOUNT_FLAG_PROPASS_LOCK = 0x00800000, + GAMEACCOUNT_FLAG_PENDING_UPGRADE = 0x01000000, + GAMEACCOUNT_FLAG_RETAIL_FROM_TRIAL = 0x02000000, + GAMEACCOUNT_FLAG_EXPANSION2_COLLECTOR = 0x04000000, + GAMEACCOUNT_FLAG_OVERMIND_LINKED = 0x08000000, + GAMEACCOUNT_FLAG_DEMOS = 0x10000000, + GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000, +}; + +namespace Battlenet +{ + enum AuthResult + { + AUTH_OK = 0, + AUTH_INTERNAL_ERROR = 100, + AUTH_CORRUPTED_MODULE = 101, + AUTH_NO_BATTLETAGS = 102, + AUTH_BAD_SERVER_PROOF = 103, + AUTH_UNKNOWN_ACCOUNT = 104, + AUTH_CLOSED = 105, + AUTH_LOGIN_TIMEOUT = 106, + AUTH_NO_GAME_ACCOUNTS = 107, + AUTH_INVALID_TOKEN = 108, + AUTH_INVALID_PROGRAM = 109, + AUTH_INVALID_OS = 110, + AUTH_UNSUPPORTED_LANGUAGE = 111, + AUTH_REGION_BAD_VERSION = 112, + AUTH_TEMP_OUTAGE = 113, + AUTH_CANT_DOWNLOAD_MODULE = 114, + AUTH_DUPLICATE_LOGON = 115, + AUTH_BAD_CREDENTIALS_2 = 116, + AUTH_VERSION_CHECK_SUCCEEDED = 117, + AUTH_BAD_VERSION_HASH = 118, + AUTH_CANT_RETRIEVE_PORTAL_LIST = 119, + AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120, + AUTH_DARK_PORTAL_FILE_CORRUPTED = 121, + AUTH_BATTLENET_MAINTENANCE = 122, + AUTH_LOGON_TOO_FAST = 123, + AUTH_USE_GRUNT_LOGON = 124, + AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140, + AUTH_ACCOUNT_LOCKED = 141, + + LOGIN_SERVER_BUSY = 200, + LOGIN_NO_GAME_ACCOUNT = 201, + LOGIN_BANNED = 202, + LOGIN_SUSPENDED = 203, + LOGIN_GAME_ACCOUNT_LOCKED = 204, + LOGIN_ALREADY_ONLINE = 205, + LOGIN_NOTIME = 206, + LOGIN_EXPIRED = 207, + LOGIN_EXPIRED_2 = 208, + LOGIN_PARENTALCONTROL = 209, + LOGIN_TRIAL_EXPIRED = 210, + LOGIN_ANTI_INDULGENCE = 211, + LOGIN_INCORRECT_REGION = 212, + LOGIN_LOCKED_ENFORCED = 213, + LOGIN_CHARGEBACK = 214, + LOGIN_IGR_WITHOUT_BNET = 215, + LOGIN_UNLOCKABLE_LOCK = 216, + LOGIN_IGR_REQUIRED = 217, + LOGIN_PAYMENT_CHANGED = 218, + LOGIN_INVALID_PAYMENT = 219, + LOGIN_INVALID_ACCOUNT_STATE = 220 + }; +} + +struct RealmBuildInfo +{ + int Build; + int MajorVersion; + int MinorVersion; + int BugfixVersion; + int HotfixVersion; +}; + +namespace AuthHelper +{ + RealmBuildInfo const* GetBuildInfo(int build); + bool IsBuildSupportingBattlenet(int build); +} + +#endif diff --git a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp new file mode 100644 index 00000000000..de4cf73f71c --- /dev/null +++ b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "BattlenetPacketCrypt.h" +#include "Cryptography/HmacHash.h" +#include "Cryptography/BigNumber.h" + +Battlenet::PacketCrypt::PacketCrypt() : ::PacketCrypt(SHA256_DIGEST_LENGTH) +{ +} + +void Battlenet::PacketCrypt::Init(BigNumber* K) +{ + uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x68, 0xE0, 0xC7, 0x2E, 0xDD, 0xD6, 0xD2, 0xF3, 0x1E, 0x5A, 0xB1, 0x55, 0xB1, 0x8B, 0x63, 0x1E }; + uint8 ClientDecryptionKey[SEED_KEY_SIZE] = { 0xDE, 0xA9, 0x65, 0xAE, 0x54, 0x3A, 0x1E, 0x93, 0x9E, 0x69, 0x0C, 0xAA, 0x68, 0xDE, 0x78, 0x39 }; + + HmacSha256 serverEncryptHmac(K->GetNumBytes(), K->AsByteArray().get()); + serverEncryptHmac.UpdateData(ServerEncryptionKey, SEED_KEY_SIZE); + serverEncryptHmac.Finalize(); + + HmacSha256 clientDecryptHmac(K->GetNumBytes(), K->AsByteArray().get()); + clientDecryptHmac.UpdateData(ClientDecryptionKey, SEED_KEY_SIZE); + clientDecryptHmac.Finalize(); + + _clientDecrypt.Init(clientDecryptHmac.GetDigest()); + _serverEncrypt.Init(serverEncryptHmac.GetDigest()); + _initialized = true; +} diff --git a/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h new file mode 100644 index 00000000000..a09d3417dfe --- /dev/null +++ b/src/server/bnetserver/Authentication/BattlenetPacketCrypt.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef BattlenetPacketCrypt_h__ +#define BattlenetPacketCrypt_h__ + +#include "PacketCrypt.h" + +class BigNumber; + +namespace Battlenet +{ + class PacketCrypt : public ::PacketCrypt + { + public: + PacketCrypt(); + + void Init(BigNumber* K) override; + }; +} +#endif // BattlenetPacketCrypt_h__ + diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt new file mode 100644 index 00000000000..3fa4abf034a --- /dev/null +++ b/src/server/bnetserver/CMakeLists.txt @@ -0,0 +1,115 @@ +# Copyright (C) 2008-2014 TrinityCore +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +########### authserver ############### + +file(GLOB_RECURSE sources_authentication Authentication/*.cpp Authentication/*.h) +file(GLOB_RECURSE sources_realms Realms/*.cpp Realms/*.h) +file(GLOB_RECURSE sources_server Server/*.cpp Server/*.h) +file(GLOB_RECURSE sources_packets Packets/*.cpp Packets/*.h) +file(GLOB sources_localdir *.cpp *.h) + +if (USE_COREPCH) + set(bnetserver_PCH_HDR PrecompiledHeaders/bnetPCH.h) + set(bnetserver_PCH_SRC PrecompiledHeaders/bnetPCH.cpp) +endif() + +set(bnetserver_SRCS + ${bnetserver_SRCS} + ${sources_authentication} + ${sources_realms} + ${sources_server} + ${sources_packets} + ${sources_localdir} +) + +if( WIN32 ) + set(bnetserver_SRCS + ${bnetserver_SRCS} + ${sources_windows_Debugging} + ) + if ( MSVC ) + set(bnetserver_SRCS + ${bnetserver_SRCS} + bnetserver.rc + ) + endif () +endif() + +include_directories( + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/src/server/shared + ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration + ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging + ${CMAKE_SOURCE_DIR}/src/server/shared/Packets + ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography + ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Networking + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/Authentication + ${CMAKE_CURRENT_SOURCE_DIR}/Realms + ${CMAKE_CURRENT_SOURCE_DIR}/Server + ${CMAKE_CURRENT_SOURCE_DIR}/Packets + ${MYSQL_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} + ${VALGRIND_INCLUDE_DIR} +) + +add_executable(bnetserver + ${bnetserver_SRCS} + ${bnetserver_PCH_SRC} +) + +add_dependencies(bnetserver revision.h) + +if( NOT WIN32 ) + set_target_properties(bnetserver PROPERTIES + COMPILE_DEFINITIONS _TRINITY_BNET_CONFIG="${CONF_DIR}/bnetserver.conf" + ) +endif() + +target_link_libraries(bnetserver + shared + ${MYSQL_LIBRARY} + ${OPENSSL_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES} +) + +if( WIN32 ) + if ( MSVC ) + add_custom_command(TARGET bnetserver + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/ + ) + elseif ( MINGW ) + add_custom_command(TARGET bnetserver + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bnetserver.conf.dist ${CMAKE_BINARY_DIR}/bin/ + ) + endif() +endif() + +if( UNIX ) + install(TARGETS bnetserver DESTINATION bin) + install(FILES bnetserver.conf.dist DESTINATION ${CONF_DIR}) +elseif( WIN32 ) + install(TARGETS bnetserver DESTINATION "${CMAKE_INSTALL_PREFIX}") + install(FILES bnetserver.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}") +endif() + +# Generate precompiled header +if (USE_COREPCH) + add_cxx_pch(bnetserver ${bnetserver_PCH_HDR} ${bnetserver_PCH_SRC}) +endif() diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp new file mode 100644 index 00000000000..cb9bab97841 --- /dev/null +++ b/src/server/bnetserver/Main.cpp @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** +* @file main.cpp +* @brief Authentication Server main program +* +* This file contains the main program for the +* authentication server +*/ + +#include "ComponentManager.h" +#include "ModuleManager.h" +#include "SessionManager.h" +#include "Common.h" +#include "Config.h" +#include "DatabaseEnv.h" +#include "Log.h" +#include "ProcessPriority.h" +#include "RealmList.h" +#include "SystemConfig.h" +#include "Util.h" +#include +#include +#include +#include +#include +#include + +using boost::asio::ip::tcp; +using namespace boost::program_options; + +#ifndef _TRINITY_BNET_CONFIG +# define _TRINITY_BNET_CONFIG "authserver.conf" +#endif + +bool StartDB(); +void StopDB(); +void SignalHandler(const boost::system::error_code& error, int signalNumber); +void KeepDatabaseAliveHandler(const boost::system::error_code& error); +variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile); + +boost::asio::io_service _ioService; +boost::asio::deadline_timer _dbPingTimer(_ioService); +uint32 _dbPingInterval; +LoginDatabaseWorkerPool LoginDatabase; + +int main(int argc, char** argv) +{ + std::string configFile = _TRINITY_BNET_CONFIG; + auto vm = GetConsoleArguments(argc, argv, configFile); + // exit if help is enabled + if (vm.count("help")) + return 0; + + std::string configError; + if (!sConfigMgr->LoadInitial(configFile, configError)) + { + printf("Error in config file: %s\n", configError.c_str()); + return 1; + } + + TC_LOG_INFO("server.bnetserver", "%s (bnetserver)", _FULLVERSION); + TC_LOG_INFO("server.bnetserver", " to stop.\n"); + TC_LOG_INFO("server.bnetserver", "Using configuration file %s.", configFile.c_str()); + TC_LOG_INFO("server.bnetserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); + TC_LOG_INFO("server.bnetserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); + + // authserver PID file creation + std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); + if (!pidFile.empty()) + { + if (uint32 pid = CreatePIDFile(pidFile)) + TC_LOG_INFO("server.bnetserver", "Daemon PID: %u\n", pid); + else + { + TC_LOG_ERROR("server.bnetserver", "Cannot create PID file %s.\n", pidFile.c_str()); + return 1; + } + } + + // Initialize the database connection + if (!StartDB()) + return 1; + + // Get the list of realms for the server + sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20)); + + if (sRealmList->size() == 0) + { + TC_LOG_ERROR("server.bnetserver", "No valid realms specified."); + StopDB(); + return 1; + } + + // Start the listening port (acceptor) for auth connections + int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119); + if (bnport < 0 || bnport > 0xFFFF) + { + TC_LOG_ERROR("server.bnetserver", "Specified battle.net port (%d) out of allowed range (1-65535)", bnport); + StopDB(); + return 1; + } + + std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); + + sSessionMgr.StartNetwork(_ioService, bindIp, bnport); + + // Set signal handlers + boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); +#if PLATFORM == PLATFORM_WINDOWS + signals.add(SIGBREAK); +#endif + signals.async_wait(SignalHandler); + + // Set process priority according to configuration settings + SetProcessPriority("server.bnetserver"); + + // Enabled a timed callback for handling the database keep alive ping + _dbPingInterval = sConfigMgr->GetIntDefault("MaxPingTime", 30); + _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); + _dbPingTimer.async_wait(KeepDatabaseAliveHandler); + + sComponentMgr->Load(); + sModuleMgr->Load(); + + // Start the io service worker loop + _ioService.run(); + + // Close the Database Pool and library + StopDB(); + + TC_LOG_INFO("server.bnetserver", "Halting process..."); + return 0; +} + + +/// Initialize connection to the database +bool StartDB() +{ + MySQL::Library_Init(); + + std::string dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); + if (dbstring.empty()) + { + TC_LOG_ERROR("server.authserver", "Database not specified"); + return false; + } + + int32 worker_threads = sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1); + if (worker_threads < 1 || worker_threads > 32) + { + TC_LOG_ERROR("server.authserver", "Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1."); + worker_threads = 1; + } + + int32 synch_threads = sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1); + if (synch_threads < 1 || synch_threads > 32) + { + TC_LOG_ERROR("server.authserver", "Improper value specified for LoginDatabase.SynchThreads, defaulting to 1."); + synch_threads = 1; + } + + // NOTE: While authserver is singlethreaded you should keep synch_threads == 1. Increasing it is just silly since only 1 will be used ever. + if (!LoginDatabase.Open(dbstring, uint8(worker_threads), uint8(synch_threads))) + { + TC_LOG_ERROR("server.authserver", "Cannot connect to database"); + return false; + } + + TC_LOG_INFO("server.authserver", "Started auth database connection pool."); + sLog->SetRealmId(0); // Enables DB appenders when realm is set. + return true; +} + +/// Close the connection to the database +void StopDB() +{ + LoginDatabase.Close(); + MySQL::Library_End(); +} + +void SignalHandler(const boost::system::error_code& error, int /*signalNumber*/) +{ + if (!error) + _ioService.stop(); +} + +void KeepDatabaseAliveHandler(const boost::system::error_code& error) +{ + if (!error) + { + TC_LOG_INFO("server.authserver", "Ping MySQL to keep connection alive"); + LoginDatabase.KeepAlive(); + + _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); + _dbPingTimer.async_wait(KeepDatabaseAliveHandler); + } +} + +variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile) +{ + options_description all("Allowed options"); + all.add_options() + ("help,h", "print usage message") + ("config,c", value(&configFile)->default_value(_TRINITY_BNET_CONFIG), "use as configuration file") + ; + variables_map variablesMap; + try + { + store(command_line_parser(argc, argv).options(all).allow_unregistered().run(), variablesMap); + notify(variablesMap); + } + catch (std::exception& e) { + std::cerr << e.what() << "\n"; + } + + if (variablesMap.count("help")) { + std::cout << all << "\n"; + } + + return variablesMap; +} diff --git a/src/server/bnetserver/Packets/AchievementPackets.h b/src/server/bnetserver/Packets/AchievementPackets.h new file mode 100644 index 00000000000..99a0f19d0a2 --- /dev/null +++ b/src/server/bnetserver/Packets/AchievementPackets.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AchievementPackets_h__ +#define AchievementPackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Achievement + { + enum Opcode + { + CMSG_LISTEN_REQUEST = 0x0, // Not implemented + CMSG_CRITERIA_FLUSH_REQUEST = 0x3, // Not implemented + CMSG_CHANGE_TROPHY_CASE_REQUEST = 0x5, // Not implemented + + SMSG_DATA = 0x2, // Not implemented + SMSG_CRITERIA_FLUSH_RESPONSE = 0x3, // Not implemented + SMSG_ACHIEVEMENT_HANDLE_UPDATE = 0x4, // Not implemented + SMSG_CHANGE_TROPHY_CASE_RESULT = 0x6 // Not implemented + }; + } +} + +#endif // AchievementPackets_h__ + diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp new file mode 100644 index 00000000000..ae2db016972 --- /dev/null +++ b/src/server/bnetserver/Packets/AuthenticationPackets.cpp @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AuthenticationPackets.h" +#include "Util.h" + +void Battlenet::Authentication::LogonRequest::Read() +{ + Program = _stream.ReadFourCC(); + Platform = _stream.ReadFourCC(); + Locale = _stream.ReadFourCC(); + + Components.resize(_stream.Read(6)); + for (size_t i = 0; i < Components.size(); ++i) + { + Component& component = Components[i]; + component.Program = _stream.ReadFourCC(); + component.Platform = _stream.ReadFourCC(); + component.Build = _stream.Read(32); + } + + if (_stream.Read(1)) + Login = _stream.ReadString(9, 3); +} + +std::string Battlenet::Authentication::LogonRequest::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::LogonRequest Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; + for (Component const& component : Components) + stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; + + if (!Login.empty()) + stream << std::endl << "Battlenet::Authentication::LogonRequest Login: " << Login; + + return stream.str(); +} + +void Battlenet::Authentication::LogonRequest::CallHandler(Session* session) const +{ + session->HandleLogonRequest(*this); +} + +void Battlenet::Authentication::ResumeRequest::Read() +{ + Program = _stream.ReadFourCC(); + Platform = _stream.ReadFourCC(); + Locale = _stream.ReadFourCC(); + + Components.resize(_stream.Read(6)); + for (size_t i = 0; i < Components.size(); ++i) + { + Component& component = Components[i]; + component.Program = _stream.ReadFourCC(); + component.Platform = _stream.ReadFourCC(); + component.Build = _stream.Read(32); + } + + Login = _stream.ReadString(9, 3); + Region = _stream.Read(8); + GameAccountName = _stream.ReadString(5, 1); +} + +std::string Battlenet::Authentication::ResumeRequest::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::ResumeRequest Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; + for (Component const& component : Components) + stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; + + stream << std::endl << "Login: " << Login; + stream << std::endl << "Region: " << uint32(Region); + stream << std::endl << "GameAccountName: " << GameAccountName; + + return stream.str(); +} + +void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session) const +{ + session->HandleResumeRequest(*this); +} + +Battlenet::Authentication::ProofRequest::~ProofRequest() +{ + for (size_t i = 0; i < Modules.size(); ++i) + delete Modules[i]; +} + +void Battlenet::Authentication::ProofRequest::Write() +{ + _stream.Write(Modules.size(), 3); + for (ModuleInfo const* info : Modules) + { + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + _stream.Write(info->DataSize, 10); + _stream.WriteBytes(info->Data, info->DataSize); + } +} + +std::string Battlenet::Authentication::ProofRequest::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::ProofRequest modules " << Modules.size(); + for (ModuleInfo const* module : Modules) + stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); + + return stream.str(); +} + +Battlenet::Authentication::ProofResponse::~ProofResponse() +{ + for (size_t i = 0; i < Modules.size(); ++i) + delete Modules[i]; +} + +void Battlenet::Authentication::ProofResponse::Read() +{ + Modules.resize(_stream.Read(3)); + for (size_t i = 0; i < Modules.size(); ++i) + { + BitStream*& dataStream = Modules[i]; + dataStream = new BitStream(_stream.Read(10)); + memcpy(dataStream->GetBuffer(), _stream.ReadBytes(dataStream->GetSize()).get(), dataStream->GetSize()); + } +} + +std::string Battlenet::Authentication::ProofResponse::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::ProofResponse Modules " << Modules.size(); + for (BitStream* module : Modules) + { + std::string hexStr = ByteArrayToHexStr(module->GetBuffer(), module->GetSize()); + stream << std::endl << "Battlenet::Authentication::ProofResponse::ModuleData Size: " << module->GetSize() << ", Data: " << hexStr; + } + + return stream.str(); +} + +void Battlenet::Authentication::ProofResponse::CallHandler(Session* session) const +{ + session->HandleProofResponse(*this); +} + +Battlenet::Authentication::LogonResponse::~LogonResponse() +{ + for (ModuleInfo* m : Modules) + delete m; +} + +void Battlenet::Authentication::LogonResponse::Write() +{ + _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); + if (Result.ResultValue == ResponseFailure::UPDATE) + { + _stream.Write(Modules.size(), 3); + for (size_t i = 0; i < Modules.size(); ++i) + { + ModuleInfo* info = Modules[i]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + _stream.Write(info->DataSize, 10); + _stream.WriteBytes(info->Data, info->DataSize); + } + + _stream.Write(PingTimeout + std::numeric_limits::min(), 32); + _stream.Write(1, 1); // RegulatorRules != NULL (not a pointer for us, always write) + // if written == 1 + { + _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); + if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) + { + _stream.Write(RegulatorRules.Threshold, 32); + _stream.Write(RegulatorRules.Rate, 32); + } + } + + _stream.WriteString(FirstName, 8); // First name + _stream.WriteString(LastName, 8); // Last name - not set for WoW + + _stream.Write(AccountId, 32); + _stream.Write(Region, 8); + _stream.Write(Flags, 64); + + _stream.Write(GameAccountRegion, 8); + _stream.WriteString(GameAccountName, 5, -1); + _stream.Write(GameAccountFlags, 64); + + _stream.Write(FailedLogins, 32); + } + else + { + _stream.Write(!Modules.empty(), 1); + if (!Modules.empty()) + { + ModuleInfo* info = Modules[0]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + } + + _stream.Write(Result.ResultValue, 2); + if (Result.ResultValue == ResponseFailure::FAILURE) + { + _stream.Write(Result.Error, 16); + _stream.Write(Result.Wait + std::numeric_limits::min(), 32); + } + } +} + +std::string Battlenet::Authentication::LogonResponse::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::LogonResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout + << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate + << " FirstName " << FirstName << " LastName " << LastName << " AccountId " << AccountId << " Region " << uint32(Region) << " GameAccountName " << GameAccountName + << " GameAccountFlags " << GameAccountFlags << " FailedLogins " << FailedLogins << " Modules " << Modules.size(); + + for (ModuleInfo const* module : Modules) + stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); + + return stream.str(); +} + +void Battlenet::Authentication::LogonResponse::SetAuthResult(AuthResult result) +{ + Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; + Result.Error = result; +} + +Battlenet::Authentication::ResumeResponse::~ResumeResponse() +{ + for (ModuleInfo* m : Modules) + delete m; +} + +void Battlenet::Authentication::ResumeResponse::Write() +{ + _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); + if (Result.ResultValue == ResponseFailure::UPDATE) + { + _stream.Write(Modules.size(), 3); + for (size_t i = 0; i < Modules.size(); ++i) + { + ModuleInfo* info = Modules[i]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + _stream.Write(info->DataSize, 10); + _stream.WriteBytes(info->Data, info->DataSize); + } + + _stream.Write(PingTimeout + std::numeric_limits::min(), 32); + _stream.Write(1, 1); // RegulatorRules != NULL (not a pointer for us, always write) + // if written == 1 + { + _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); + if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) + { + _stream.Write(RegulatorRules.Threshold, 32); + _stream.Write(RegulatorRules.Rate, 32); + } + } + } + else + { + _stream.Write(!Modules.empty(), 1); + if (!Modules.empty()) + { + ModuleInfo* info = Modules[0]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + } + + _stream.Write(Result.ResultValue, 2); + if (Result.ResultValue == ResponseFailure::FAILURE) + { + _stream.Write(Result.Error, 16); + _stream.Write(Result.Wait + std::numeric_limits::min(), 32); + } + } +} + +std::string Battlenet::Authentication::ResumeResponse::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Authentication::ResumeResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout + << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate + << " Modules " << Modules.size(); + + for (ModuleInfo const* module : Modules) + stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); + + return stream.str(); +} + +void Battlenet::Authentication::ResumeResponse::SetAuthResult(AuthResult result) +{ + Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; + Result.Error = result; +} diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h new file mode 100644 index 00000000000..8003e13db24 --- /dev/null +++ b/src/server/bnetserver/Packets/AuthenticationPackets.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef AuthenticationPackets_h__ +#define AuthenticationPackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Authentication + { + enum Opcode + { + CMSG_LOGON_REQUEST = 0x0, + CMSG_RESUME_REQUEST = 0x1, + CMSG_PROOF_RESPONSE = 0x2, + + SMSG_LOGON_RESPONSE = 0x0, + SMSG_RESUME_RESPONSE = 0x1, + SMSG_PROOF_REQUEST = 0x2, + SMSG_PATCH = 0x3, // Not implemented + SMSG_AUTHORIZED_LICENSES = 0x4 // Not implemented + }; + + class LogonRequest final : public ClientPacket + { + public: + LogonRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_LOGON_REQUEST, AUTHENTICATION) && "Invalid packet header for LogonRequest"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + std::string Program; + std::string Platform; + std::string Locale; + std::vector Components; + std::string Login; + }; + + class ResumeRequest final : public ClientPacket + { + public: + ResumeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_RESUME_REQUEST, AUTHENTICATION) && "Invalid packet header for ResumeRequest"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + std::string Program; + std::string Platform; + std::string Locale; + std::vector Components; + std::string Login; + uint8 Region; + std::string GameAccountName; + }; + + class ProofResponse final : public ClientPacket + { + public: + ProofResponse(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_PROOF_RESPONSE, AUTHENTICATION) && "Invalid packet header for ProofResponse"); + } + + ~ProofResponse(); + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + std::vector Modules; + }; + + class ProofRequest final : public ServerPacket + { + public: + ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { } + ~ProofRequest(); + + void Write() override; + std::string ToString() const override; + + std::vector Modules; + }; + + class ResponseFailure + { + public: + enum Result + { + UPDATE = 0, + FAILURE = 1, + VERSION_CHECK_DISCONNECT = 2 + }; + + ResponseFailure() : ResultValue(UPDATE), Error(AUTH_OK), Wait(0) { } + + Result ResultValue; + AuthResult Error; + int32 Wait; + }; + + class Regulator + { + public: + enum Info + { + NONE = 0, + LEAKY_BUCKET = 1 + }; + + Regulator() : Type(LEAKY_BUCKET), Threshold(25000000), Rate(1000) { } + + Info Type; + uint32 Threshold; + uint32 Rate; + }; + + class LogonResponse final : public ServerPacket + { + public: + LogonResponse() : ServerPacket(PacketHeader(SMSG_LOGON_RESPONSE, AUTHENTICATION)), + PingTimeout(120000), FirstName(""), LastName(""), AccountId(0), Region(2), Flags(0), + GameAccountRegion(2), GameAccountName(""), FailedLogins(0) + { + } + + ~LogonResponse(); + + void Write() override; + std::string ToString() const override; + + std::vector Modules; + void SetAuthResult(AuthResult result); + ResponseFailure Result; + + int32 PingTimeout; + Regulator RegulatorRules; + std::string FirstName; + std::string LastName; + uint32 AccountId; + uint8 Region; + uint64 Flags; + uint8 GameAccountRegion; + std::string GameAccountName; + uint64 GameAccountFlags; + + uint32 FailedLogins; + }; + + class ResumeResponse final : public ServerPacket + { + public: + ResumeResponse() : ServerPacket(PacketHeader(SMSG_RESUME_RESPONSE, AUTHENTICATION)), PingTimeout(120000) + { + } + + ~ResumeResponse(); + + void Write() override; + std::string ToString() const override; + + std::vector Modules; + void SetAuthResult(AuthResult result); + ResponseFailure Result; + + int32 PingTimeout; + Regulator RegulatorRules; + }; + } +} + +#endif // AuthenticationPackets_h__ diff --git a/src/server/bnetserver/Packets/BitStream.cpp b/src/server/bnetserver/Packets/BitStream.cpp new file mode 100644 index 00000000000..5f002f6b1d9 --- /dev/null +++ b/src/server/bnetserver/Packets/BitStream.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "BitStream.h" + +template<> +bool Battlenet::BitStream::Read(uint32 /*bitCount*/) +{ + return Read(1) != 0; +} + +template<> +void Battlenet::BitStream::Write(bool value, uint32 /*bitCount*/) +{ + Write(value ? 1 : 0, 1); +} diff --git a/src/server/bnetserver/Packets/BitStream.h b/src/server/bnetserver/Packets/BitStream.h new file mode 100644 index 00000000000..952ec5a39e2 --- /dev/null +++ b/src/server/bnetserver/Packets/BitStream.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef BitStream_h__ +#define BitStream_h__ + +#include "Common.h" +#include "ByteConverter.h" +#include "MessageBuffer.h" +#include +#include +#include +#include + +namespace Battlenet +{ + class BitStreamPositionException : public std::exception + { + static uint32 const MessageSize = 128; + + public: + BitStreamPositionException(bool read, uint32 operationSize, uint32 position, uint32 streamSize) + { + memset(_message, 0, MessageSize); + snprintf(_message, MessageSize, "Attempted to %s more bits (%u) %s stream than %s (%u)\n", + (read ? "read" : "write"), + operationSize + position, + (read ? "from" : "to"), + (read ? "exist" : "allowed"), + streamSize); + } + + char const* what() const throw() + { + return _message; + } + + private: + char _message[MessageSize]; + }; + + class BitStream + { + public: + static uint32 const MaxSize = 0x4000; + + // length : The maximum number of bytes to read + BitStream(uint32 length) : _writePos(length * 8), _readPos(0) + { + _buffer.resize(length, 0); + } + + BitStream(MessageBuffer&& buffer) : _writePos(buffer.GetActiveSize() * 8), _readPos(0), _buffer(buffer.Move()) + { + } + + BitStream() : _writePos(0), _readPos(0) + { + _buffer.reserve(0x1000); + } + + void AlignToNextByte() + { + _readPos = (_readPos + 7) & ~7; + _writePos = (_writePos + 7) & ~7; + } + + std::string ReadString(uint32 bitCount, int32 baseLength = 0) + { + uint32 len = Read(bitCount) + baseLength; + AlignToNextByte(); + std::string str(reinterpret_cast(&_buffer[_readPos >> 3]), len); + _readPos += len * 8; + return str; + } + + std::unique_ptr ReadBytes(uint32 count) + { + AlignToNextByte(); + if (_readPos + count * 8 > _writePos) + throw BitStreamPositionException(true, count * 8, _readPos, _writePos); + + std::unique_ptr buf(new uint8[count]); + memcpy(buf.get(), &_buffer[_readPos >> 3], count); + _readPos += count * 8; + return buf; + } + + float ReadFloat() + { + uint32 val = Read(32); + return *reinterpret_cast(&val); + } + + std::string ReadFourCC() + { + uint32 fcc = Read(32); + EndianConvertReverse(fcc); + size_t len = 4; + while (!(fcc & 0xFF)) + { + fcc >>= 8; + --len; + } + + return std::string(reinterpret_cast(&fcc), len); + } + + template + T Read(uint32 bitCount) + { + static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type"); + + if (_readPos + bitCount > _writePos) + throw BitStreamPositionException(true, bitCount, _readPos, _writePos); + + uint64 ret = 0; + while (bitCount != 0) + { + uint32 bitPos = (_readPos & 7); + uint32 bitsLeftInByte = 8 - bitPos; + if (bitsLeftInByte >= bitCount) + bitsLeftInByte = bitCount; + + bitCount -= bitsLeftInByte; + ret |= (uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount; + _readPos += bitsLeftInByte; + } + + return static_cast(ret); + } + + void WriteString(std::string const& str, uint32 bitCount, int32 baseLength = 0) + { + Write(str.length() + baseLength, bitCount); + WriteBytes(str.c_str(), str.length()); + } + + template + void WriteBytes(T* data, uint32 count) + { + AlignToNextByte(); + if (!count || !data) + return; + + if ((_writePos >> 3) + count > MaxSize) + throw BitStreamPositionException(false, count * 8, _writePos, MaxSize * 8); + + _buffer.resize(_buffer.size() + count); + memcpy(&_buffer[_writePos >> 3], data, count); + _writePos += count * 8; + } + + void WriteFloat(float value) + { + uint32 intVal = *reinterpret_cast(&value); + Write(intVal, 32); + } + + void WriteFourCC(std::string const& fcc) + { + uint32 intVal = *(uint32*)fcc.c_str(); + size_t len = fcc.length(); + EndianConvertReverse(intVal); + // Add padding + while (len++ < 4) + intVal >>= 8; + + Write(intVal, 32); + } + + template + void Write(T value, uint32 bitCount) + { + static_assert(std::is_integral::value || std::is_enum::value, "T must be an integer type"); + + if (_writePos + bitCount > 8 * MaxSize) + throw BitStreamPositionException(false, bitCount, _writePos, MaxSize * 8); + + while (bitCount != 0) + { + uint32 bitPos = (_writePos & 7); + uint32 bitsLeftInByte = 8 - bitPos; + if (bitsLeftInByte >= bitCount) + bitsLeftInByte = bitCount; + + bitCount -= bitsLeftInByte; + + uint8 firstHalf = (uint8)(~(((uint8)(1 << bitsLeftInByte) - 1) << bitPos)); + uint8 secondHalf = (uint8)((((uint8)(1 << bitsLeftInByte) - 1) & (uint8)(value >> bitCount)) << bitPos); + + if (_buffer.size() > (_writePos >> 3)) + _buffer[_writePos >> 3] = (uint8)((_buffer[_writePos >> 3] & firstHalf) | secondHalf); + else + _buffer.push_back(secondHalf); + + _writePos += bitsLeftInByte; + } + } + + void SetReadPos(uint32 bits) + { + if (bits > _writePos) + throw BitStreamPositionException(true, bits, 0, _writePos); + + _readPos = bits; + } + + bool IsRead() const { return _readPos >= _writePos; } + + uint8* GetBuffer() { return _buffer.data(); } + uint8 const* GetBuffer() const { return _buffer.data(); } + + size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; } + + private: + uint32 _writePos; + uint32 _readPos; + std::vector _buffer; + }; + + template<> + bool BitStream::Read(uint32 bitCount); + + template<> + void BitStream::Write(bool value, uint32 bitCount); +} + +#endif // BitStream_h__ diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h new file mode 100644 index 00000000000..2e473df4e72 --- /dev/null +++ b/src/server/bnetserver/Packets/CachePackets.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef CachePackets_h__ +#define CachePackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Cache + { + enum Opcode + { + CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented + CMSG_CONNECT_REQUEST = 0x4, // Not implemented + CMSG_DATA_CHUNK = 0x7, // Not implemented + SMSG_GET_STREAM_ITEMS_REQUEST = 0x9, // Not implemented + + SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented + SMSG_CONNECT_RESPONSE = 0x4, // Not implemented + SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented + SMSG_RESULT = 0x8, // Not implemented + SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9 // Not implemented + }; + } +} + +#endif // CachePackets_h__ diff --git a/src/server/bnetserver/Packets/ChatPackets.h b/src/server/bnetserver/Packets/ChatPackets.h new file mode 100644 index 00000000000..fc4b638754c --- /dev/null +++ b/src/server/bnetserver/Packets/ChatPackets.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ChatPackets_h__ +#define ChatPackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Chat + { + enum Opcode + { + CMSG_JOIN_REQUEST_2 = 0x00, // Not implemented + CMSG_LEAVE_REQUEST = 0x02, // Not implemented + CMSG_INVITE_REQUEST = 0x03, // Not implemented + CMSG_CREATE_AND_INVITE_REQUEST = 0x0A, // Not implemented + CMSG_MESSAGE_SEND = 0x0B, // Not implemented + CMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented + CMSG_REPORT_SPAM_REQUEST = 0x0E, // Not implemented + CMSG_WHISPER_SEND = 0x13, // Not implemented + CMSG_ENUM_CATEGORY_DESCRIPTIONS = 0x15, // Not implemented + CMSG_ENUM_CONFERENCE_DESCRIPTIONS = 0x17, // Not implemented + CMSG_ENUM_CONFERENCE_MEMBER_COUNTS = 0x19, // Not implemented + CMSG_MODIFY_CHANNEL_LIST_REQUEST = 0x1B, // Not implemented + + SMSG_MEMBERSHIP_CHANGE_NOTIFY = 0x01, // Not implemented + SMSG_INVITE_NOTIFY = 0x04, // Not implemented + SMSG_INVITE_CANCELED = 0x07, // Not implemented + SMSG_MESSAGE_RECV = 0x0B, // Not implemented + SMSG_MESSAGE_UNDELIVERABLE = 0x0C, // Not implemented + SMSG_DATAGRAM_CONNECTION_UPDATE = 0x0D, // Not implemented + SMSG_INVITE_FAILURE = 0x0F, // Not implemented + SMSG_SYSTEM_MESSAGE = 0x10, // Not implemented + SMSG_MESSAGE_BLOCKED = 0x12, // Not implemented + SMSG_WHISPER_RECV = 0x13, // Not implemented + SMSG_WHISPER_UNDELIVERABLE = 0x14, // Not implemented + SMSG_CATEGORY_DESCRIPTIONS = 0x16, // Not implemented + SMSG_CONFERENCE_DESCRIPTIONS = 0x18, // Not implemented + SMSG_CONFERENCE_MEMBER_COUNTS = 0x1A, // Not implemented + SMSG_JOIN_NOTIFY_2 = 0x1B, // Not implemented + SMSG_MODIFY_CHANNEL_LIST_RESPONSE = 0x1C, // Not implemented + SMSG_CONFIG_CHANGED = 0x1D // Not implemented + }; + } +} + +#endif // ChatPackets_h__ diff --git a/src/server/bnetserver/Packets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/ConnectionPackets.cpp new file mode 100644 index 00000000000..0449ecbb756 --- /dev/null +++ b/src/server/bnetserver/Packets/ConnectionPackets.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Session.h" +#include "ConnectionPackets.h" + +std::string Battlenet::Connection::Ping::ToString() const +{ + return "Battlenet::Connection::Ping"; +} + +void Battlenet::Connection::Ping::CallHandler(Session* session) const +{ + session->HandlePing(*this); +} + +std::string Battlenet::Connection::EnableEncryption::ToString() const +{ + return "Battlenet::Connection::EnableEncryption"; +} + +void Battlenet::Connection::EnableEncryption::CallHandler(Session* session) const +{ + session->HandleEnableEncryption(*this); +} + +std::string Battlenet::Connection::LogoutRequest::ToString() const +{ + return "Battlenet::Connection::LogoutRequest"; +} + +void Battlenet::Connection::LogoutRequest::CallHandler(Session* session) const +{ + session->HandleLogoutRequest(*this); +} + +std::string Battlenet::Connection::Pong::ToString() const +{ + return "Battlenet::Connection::Pong"; +} diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h new file mode 100644 index 00000000000..f3fa4852d07 --- /dev/null +++ b/src/server/bnetserver/Packets/ConnectionPackets.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ConnectionPackets_h__ +#define ConnectionPackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Connection + { + enum Opcode + { + CMSG_PING = 0x0, + CMSG_ENABLE_ENCRYPTION = 0x5, + CMSG_LOGOUT_REQUEST = 0x6, + CMSG_DISCONNECT_REQUEST = 0x7, // Not implemented + CMSG_CONNECTION_CLOSING = 0x9, // Not implemented + + SMSG_PONG = 0x0, + SMSG_BOOM = 0x1, // Not implemented + SMSG_REGULATOR_UPDATE = 0x2, // Not implemented + SMSG_SERVER_VERSION = 0x3, // Not implemented + SMSG_STUN_SERVERS = 0x4 // Not implemented + }; + + class Ping final : public ClientPacket + { + public: + Ping(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_PING, CONNECTION) && "Invalid packet header for Ping"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class EnableEncryption final : public ClientPacket + { + public: + EnableEncryption(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_ENABLE_ENCRYPTION, CONNECTION) && "Invalid packet header for EnableEncryption"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class LogoutRequest final : public ClientPacket + { + public: + LogoutRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_LOGOUT_REQUEST, CONNECTION) && "Invalid packet header for LogoutRequest"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class Pong final : public ServerPacket + { + public: + Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION)) + { + } + + void Write() override { } + std::string ToString() const override; + }; + } +} + +#endif // ConnectionPackets_h__ diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp new file mode 100644 index 00000000000..784d6980777 --- /dev/null +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Session.h" +#include "FriendsPackets.h" + +void Battlenet::Friends::SocialnetworkCheckConnected::Read() +{ + SocialNetworkId = _stream.Read(32); +} + +std::string Battlenet::Friends::SocialnetworkCheckConnected::ToString() const +{ + return "Battlenet::Friends::SocialnetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); +} + +void Battlenet::Friends::SocialnetworkCheckConnected::CallHandler(Session* session) const +{ + SocialNetworkCheckConnectedResult* result = new SocialNetworkCheckConnectedResult(SocialNetworkId); + session->AsyncWrite(result); +} + +void Battlenet::Friends::SocialnetworkConnect::Read() +{ + int32 unk1 = _stream.Read(32); + uint32 size1 = _stream.Read(9); + auto data1 = _stream.ReadBytes(size1); + uint32 size2 = _stream.Read(7); + auto data2 = _stream.ReadBytes(size2); +} + +std::string Battlenet::Friends::SocialnetworkConnect::ToString() const +{ + return "Battlenet::Friends::SocialnetworkConnect"; +} + +void Battlenet::Friends::SocialnetworkConnect::CallHandler(Session* session) const +{ + session->LogUnhandledPacket(*this); +} + +std::string Battlenet::Friends::SocialNetworkConnectResult::ToString() const +{ + return "Battlenet::Friends::SocialNetworkConnectResult"; +} + +void Battlenet::Friends::SocialNetworkConnectResult::Write() +{ +} + +std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const +{ + return "Battlenet::Friends::SocialNetworkCheckConnectedResult"; +} + +void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() +{ + _stream.Write(0, 23); // Ignored + volatile uint16 res = 0; + _stream.Write(res, 16); // Unknown + _stream.Write(SocialNetworkId, 32); +} + +void Battlenet::Friends::GetFriendsOfFriend::Read() +{ + uint8 unk = _stream.Read(2); + uint32 unk1 = _stream.Read(32); +} + +std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const +{ + return "Battlenet::Friends::GetFriendsOfFriend"; +} + +void Battlenet::Friends::GetFriendsOfFriend::CallHandler(Session* session) const +{ + session->LogUnhandledPacket(*this); +} + +void Battlenet::Friends::RealIdFriendInvite::Read() +{ + _stream.Read(32); + uint8 type = _stream.Read(3); + + switch (type) + { + case 0: + { + _stream.Read(32); // Presence Id? + break; + } + case 1: // GameAccount? + { + _stream.Read(8); + _stream.Read(32); + _stream.Read(32); + uint8 size = _stream.Read(7); // Only if *(a1 + 16) <= 0x64 + _stream.ReadBytes(size); + break; + } + case 2: + Email = _stream.ReadString(9, 3); + break; + case 3: + { + _stream.Read(32); + break; + } + case 4: + { + _stream.Read(64); + _stream.Read(32); + break; + } + } + + _stream.Read(1); + + if (_stream.Read(1)) + Message = _stream.ReadString(9); + + _stream.Read(32); +} + +std::string Battlenet::Friends::RealIdFriendInvite::ToString() const +{ + return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message; +} + +void Battlenet::Friends::RealIdFriendInvite::CallHandler(Session* session) const +{ + FriendInviteResult* result = new FriendInviteResult(); + session->AsyncWrite(result); +} + +std::string Battlenet::Friends::FriendInviteResult::ToString() const +{ + return "Battlenet::Friends::RealIdFriendInviteResult"; +} + +void Battlenet::Friends::FriendInviteResult::Write() +{ + bool hasNames = false; + _stream.Write(hasNames, 1); + if (hasNames) + { + _stream.WriteString("Testing1", 8); + _stream.WriteString("Testing2", 8); + } + _stream.Write(5, 32); + + _stream.Write(0, 0xC); // Ignored + + _stream.Write(1, 16); + + bool moreInfo = true; + _stream.Write(moreInfo, 1); + if (moreInfo) + { + _stream.Write(0, 8); + _stream.Write(4, 32); + _stream.Write(3, 32); + _stream.WriteString("Testing3", 7, 2); + } +} diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h new file mode 100644 index 00000000000..a0ef6f4a63f --- /dev/null +++ b/src/server/bnetserver/Packets/FriendsPackets.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef FriendsPackets_h__ +#define FriendsPackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Friends + { + enum Opcode + { + CMSG_FRIEND_INVITE = 0x01, // Not implemented + CMSG_FRIEND_INVITE_RESPONSE = 0x02, // Not implemented + CMSG_FRIEND_REMOVE = 0x04, // Not implemented + CMSG_FRIEND_NOTE = 0x05, // Not implemented + CMSG_TOONS_OF_FRIEND_REQUEST = 0x06, // Not implemented + CMSG_BLOCK_ADD = 0x08, // Not implemented + CMSG_BLOCK_REMOVE = 0x0A, // Not implemented + CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented + CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Not implemented + CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Not implemented + CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Not implemented + CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, + CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented + + SMSG_FRIEND_INVITE_NOTIFY = 0x01, // Not implemented + SMSG_FRIEND_INVITE_RESULT = 0x03, // Not implemented + SMSG_TOONS_OF_FRIEND_NOTIFY = 0x06, // Not implemented + SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented + SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented + SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented + SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Not implemented + SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Not implemented + SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Not implemented + SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, + SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented + SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented + }; + + class SocialnetworkConnect final : public ClientPacket + { + public: + SocialnetworkConnect(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS) && "Invalid packet header for SocialnetworkConnect"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class SocialNetworkConnectResult final : public ServerPacket + { + public: + SocialNetworkConnectResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS)) + { + } + + void Write() override; + std::string ToString() const override; + }; + + class SocialnetworkCheckConnected final : public ClientPacket + { + public: + SocialnetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + uint32 SocialNetworkId; + }; + + class SocialNetworkCheckConnectedResult final : public ServerPacket + { + public: + SocialNetworkCheckConnectedResult(uint32 socialNetworkId) : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), SocialNetworkId(socialNetworkId) + { + } + + void Write() override; + std::string ToString() const override; + + uint32 SocialNetworkId; + }; + + class GetFriendsOfFriend final : public ClientPacket + { + public: + GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class FriendsOfFriend final : public ServerPacket + { + public: + FriendsOfFriend() : ServerPacket(PacketHeader(SMSG_FRIENDS_OF_FRIEND, FRIENDS)) + { + } + + void Write() override; + std::string ToString() const override; + }; + + class RealIdFriendInvite final : public ClientPacket + { + public: + RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + std::string Email; + std::string Message; + }; + + class FriendInviteResult final : public ServerPacket + { + public: + FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS)) + { + } + + void Write() override; + std::string ToString() const override; + }; + } +} + +#endif // FriendsPackets_h__ diff --git a/src/server/bnetserver/Packets/PacketFactory.h b/src/server/bnetserver/Packets/PacketFactory.h new file mode 100644 index 00000000000..4ae6338cfd7 --- /dev/null +++ b/src/server/bnetserver/Packets/PacketFactory.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef PacketFactory_h__ +#define PacketFactory_h__ + +#include "Packets.h" +#include + +namespace Battlenet +{ + class PacketFactory + { + typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream); + + public: + ClientPacket* Create(PacketHeader const& header, BitStream& stream) + { + auto creator = _creators.find(header); + if (creator == _creators.end()) + return nullptr; + + ClientPacket* packet = creator->second(header, stream); + packet->Read(); + return packet; + } + + static PacketFactory& Instance() + { + static PacketFactory instance; + return instance; + } + + private: + PacketFactory() + { + _creators[PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION)] = &New; + _creators[PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION)] = &New; + _creators[PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION)] = &New; + + _creators[PacketHeader(Connection::CMSG_PING, CONNECTION)] = &New; + _creators[PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION)] = &New; + _creators[PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION)] = &New; + + _creators[PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM)] = &New; + _creators[PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM)] = &New; + + _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS)] = &New; + _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS)] = &New; + _creators[PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS)] = &New; + _creators[PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS)] = &New; + + _creators[PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE)] = &New; + _creators[PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE)] = &New; + } + + template + static ClientPacket* New(PacketHeader const& header, BitStream& stream) + { + return new PacketType(header, stream); + } + + std::map _creators; + }; +} + +#define sPacketFactory Battlenet::PacketFactory::Instance() + +#endif // PacketFactory_h__ diff --git a/src/server/bnetserver/Packets/Packets.h b/src/server/bnetserver/Packets/Packets.h new file mode 100644 index 00000000000..f62ba6f65cd --- /dev/null +++ b/src/server/bnetserver/Packets/Packets.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef Packets_h__ +#define Packets_h__ + +#include "AuthenticationPackets.h" +#include "ConnectionPackets.h" +#include "WoWRealmPackets.h" +#include "FriendsPackets.h" +#include "PresencePackets.h" +#include "ChatPackets.h" +#include "SupportPackets.h" +#include "AchievementPackets.h" +#include "CachePackets.h" +#include "ProfilePackets.h" + +#endif // Packets_h__ diff --git a/src/server/bnetserver/Packets/PacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp new file mode 100644 index 00000000000..6471337060c --- /dev/null +++ b/src/server/bnetserver/Packets/PacketsBase.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Packets.h" +#include + +std::string Battlenet::PacketHeader::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel; + return stream.str(); +} + +Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream()) +{ + _stream.Write(header.Opcode, 6); + _stream.Write(1, 1); + _stream.Write(header.Channel, 4); +} + +Battlenet::ServerPacket::~ServerPacket() +{ + delete &_stream; +} diff --git a/src/server/bnetserver/Packets/PacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h new file mode 100644 index 00000000000..839a10548e9 --- /dev/null +++ b/src/server/bnetserver/Packets/PacketsBase.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef PacketsBase_h__ +#define PacketsBase_h__ + +#include "AuthCodes.h" +#include "BitStream.h" +#include "Define.h" +#include "Errors.h" +#include +#include + +using boost::asio::ip::tcp; + +namespace Battlenet +{ + class BitStream; + class Session; + + enum Channel + { + AUTHENTICATION = 0, + CONNECTION = 1, + WOWREALM = 2, + FRIENDS = 3, + PRESENCE = 4, + CHAT = 5, + SUPPORT = 7, + ACHIEVEMENT = 8, + CACHE = 11, + PROFILE = 14 + }; + + struct PacketHeader + { + PacketHeader(uint32 opcode, uint32 channel) : Opcode(opcode), Channel(channel) { } + PacketHeader() : Opcode(0), Channel(AUTHENTICATION) { } + + uint32 Opcode; + int32 Channel; + + bool operator<(PacketHeader const& right) const + { + if (Opcode < right.Opcode) + return true; + if (Opcode > right.Opcode) + return false; + + return Channel < right.Channel; + } + + bool operator==(PacketHeader const& right) const + { + return Opcode == right.Opcode && Channel == right.Channel; + } + + std::string ToString() const; + }; + + class Packet + { + public: + Packet(PacketHeader const& header, BitStream& stream) : _header(header), _stream(stream) { } + virtual ~Packet() { } + + PacketHeader const& GetHeader() const { return _header; } + + virtual void Write() = 0; + virtual void Read() = 0; + + virtual std::string ToString() const = 0; + + protected: + PacketHeader _header; + BitStream& _stream; + + private: + Packet(Packet const& right); + Packet& operator=(Packet const& right); + }; + + class ClientPacket : public Packet + { + public: + ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { } + + void Write() override final { ASSERT(!"Write not implemented for this packet."); } + virtual void CallHandler(Session* session) const = 0; + }; + + class ServerPacket : public Packet + { + public: + ServerPacket(PacketHeader const& header); + ~ServerPacket(); + + void Read() override final { ASSERT(!"Read not implemented for server packets."); } + + uint8* GetData() { return _stream.GetBuffer(); } + uint8 const* GetData() const { return _stream.GetBuffer(); } + size_t GetSize() const { return _stream.GetSize(); } + }; +} + +#endif // PacketsBase_h__ diff --git a/src/server/bnetserver/Packets/PresencePackets.cpp b/src/server/bnetserver/Packets/PresencePackets.cpp new file mode 100644 index 00000000000..da49f41af76 --- /dev/null +++ b/src/server/bnetserver/Packets/PresencePackets.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Session.h" +#include "PresencePackets.h" + +void Battlenet::Presence::UpdateRequest::Read() +{ + +} + +std::string Battlenet::Presence::UpdateRequest::ToString() const +{ + return "Battlenet::Presence::UpdateRequest"; +} + +void Battlenet::Presence::UpdateRequest::CallHandler(Session* session) const +{ + session->LogUnhandledPacket(*this); +} + +void Battlenet::Presence::StatisticSubscribe::Read() +{ +} + +std::string Battlenet::Presence::StatisticSubscribe::ToString() const +{ + return "Battlenet::Presence::StatisticSubscribe"; +} + +void Battlenet::Presence::StatisticSubscribe::CallHandler(Session* session) const +{ + session->LogUnhandledPacket(*this); +} diff --git a/src/server/bnetserver/Packets/PresencePackets.h b/src/server/bnetserver/Packets/PresencePackets.h new file mode 100644 index 00000000000..c934228a3cb --- /dev/null +++ b/src/server/bnetserver/Packets/PresencePackets.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef PresencePackets_h__ +#define PresencePackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Presence + { + enum Opcode + { + CMSG_UPDATE_REQUEST = 0x0, // Not implemented + CMSG_STATISTIC_SUBSCRIBE = 0x2, // Not implemented + + SMSG_UPDATE_NOTIFY = 0x0, // Not implemented + SMSG_FIELD_SPEC_ANNOUNCE = 0x1, // Not implemented + SMSG_STATISTICS_UPDATE = 0x3 // Not implemented + }; + + class UpdateRequest final : public ClientPacket + { + public: + UpdateRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_UPDATE_REQUEST, PRESENCE) && "Invalid packet header for UpdateRequest"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class StatisticSubscribe final : public ClientPacket + { + public: + StatisticSubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_STATISTIC_SUBSCRIBE, PRESENCE) && "Invalid packet header for StatisticSubscribe"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + } +} + +#endif // PresencePackets_h__ diff --git a/src/server/bnetserver/Packets/ProfilePackets.h b/src/server/bnetserver/Packets/ProfilePackets.h new file mode 100644 index 00000000000..bf413471f62 --- /dev/null +++ b/src/server/bnetserver/Packets/ProfilePackets.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ProfilePackets_h__ +#define ProfilePackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Profile + { + enum Opcode + { + CMSG_READ_REQUEST = 0x0, // Not implemented + CMSG_ADDRESS_QUERY_REQUEST = 0x1, // Not implemented + CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST = 0x2, // Not implemented + CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST = 0x3, // Not implemented + CMSG_CHANGE_SETTINGS = 0x5, // Not implemented + + SMSG_READ_RESPONSE = 0x0, // Not implemented + SMSG_ADDRESS_QUERY_RESPONSE = 0x1, // Not implemented + SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE = 0x2, // Not implemented + SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE = 0x3, // Not implemented + SMSG_SETTINGS_AVAILABLE = 0x4 // Not implemented + }; + } +} + +#endif // ProfilePackets_h__ diff --git a/src/server/bnetserver/Packets/SupportPackets.h b/src/server/bnetserver/Packets/SupportPackets.h new file mode 100644 index 00000000000..43f51bd564e --- /dev/null +++ b/src/server/bnetserver/Packets/SupportPackets.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SupportPackets_h__ +#define SupportPackets_h__ + +#include "PacketsBase.h" + +namespace Battlenet +{ + namespace Support + { + enum Opcode + { + CMSG_COMPLAINT_REQUEST = 0x0 // Not implemented + }; + } +} + +#endif // SupportPackets_h__ diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp new file mode 100644 index 00000000000..6845fc914b1 --- /dev/null +++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "WoWRealmPackets.h" +#include "Session.h" +#include +#include + +std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const +{ + return "Battlenet::WoWRealm::ListSubscribeRequest"; +} + +void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) const +{ + session->HandleListSubscribeRequest(*this); +} + +Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse() +{ + for (ServerPacket* realmData : RealmData) + delete realmData; +} + +void Battlenet::WoWRealm::ListSubscribeResponse::Write() +{ + _stream.Write(Response, 1); + if (Response == SUCCESS) + { + _stream.Write(CharacterCounts.size(), 7); + for (CharacterCountEntry const& entry : CharacterCounts) + { + _stream.Write(entry.Realm.Battlegroup, 8); + _stream.Write(entry.Realm.Index, 32); + _stream.Write(entry.Realm.Region, 8); + _stream.Write(entry.CharacterCount, 16); + } + + for (ServerPacket* realmData : RealmData) + { + realmData->Write(); + _stream.WriteBytes(realmData->GetData(), realmData->GetSize()); + } + } + else + _stream.Write(ResponseCode, 8); +} + +std::string Battlenet::WoWRealm::ListSubscribeResponse::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::ListSubscribeResponse"; + + if (Response == SUCCESS) + { + stream << " Realms " << CharacterCounts.size(); + + for (CharacterCountEntry const& entry : CharacterCounts) + stream << std::endl << "Region " << uint32(entry.Realm.Region) << " Battlegroup " << uint32(entry.Realm.Region) << " Index " << entry.Realm.Index << " Characters " << entry.CharacterCount; + + for (ServerPacket* realmData : RealmData) + stream << std::endl << realmData->ToString(); + } + else + stream << " Failure"; + + return stream.str().c_str(); +} + +void Battlenet::WoWRealm::ListUpdate::Write() +{ + _stream.Write(UpdateState, 1); + if (UpdateState == UPDATE) + { + _stream.Write(Type + -std::numeric_limits::min(), 32); + _stream.WriteFloat(Population); + _stream.Write(Flags, 8); + _stream.Write(Lock, 8); + _stream.Write(Timezone, 32); + _stream.Write(!Version.empty(), 1); + if (!Version.empty()) + { + _stream.WriteString(Version, 5); + _stream.Write(Build, 32); + + boost::asio::ip::address_v4::bytes_type ip = Address.address().to_v4().to_bytes(); + uint16 port = Address.port(); + + EndianConvertReverse(ip); + EndianConvertReverse(port); + + _stream.WriteBytes(ip.data(), 4); + _stream.WriteBytes(&port, 2); + } + + _stream.WriteString(Name, 10); + } + + _stream.Write(Battlegroup, 8); + _stream.Write(Index, 32); + _stream.Write(Region, 8); +} + +std::string Battlenet::WoWRealm::ListUpdate::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::ListUpdate Timezone " << Timezone << " Population " << Population << " Lock " << uint32(Lock) << " Type " << Type << " Name " << Name + << " Flags " << uint32(Flags) << " Region " << uint32(Region) << " Battlegroup " << uint32(Battlegroup) << " Index " << Index; + + if (!Version.empty()) + stream << " Version " << Version; + + return stream.str().c_str(); +} + +void Battlenet::WoWRealm::JoinRequestV2::Read() +{ + Realm.Battlegroup = _stream.Read(8); + Realm.Index = _stream.Read(32); + Realm.Region = _stream.Read(8); + ClientSeed = _stream.Read(32); +} + +std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index; + return stream.str().c_str(); +} + +void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) const +{ + session->HandleJoinRequestV2(*this); +} + +void Battlenet::WoWRealm::JoinResponseV2::Write() +{ + _stream.Write(0, 27); + _stream.Write(Response, 1); + if (Response == SUCCESS) + { + _stream.Write(ServerSeed, 32); + _stream.Write(IPv6.size(), 5); + for (tcp::endpoint const& addr : IPv6) + { + boost::asio::ip::address_v6::bytes_type ip = addr.address().to_v6().to_bytes(); + uint16 port = addr.port(); + + EndianConvertReverse(port); + + _stream.WriteBytes(ip.data(), 16); + _stream.WriteBytes(&port, 2); + } + + _stream.Write(IPv4.size(), 5); + for (tcp::endpoint const& addr : IPv4) + { + boost::asio::ip::address_v4::bytes_type ip = addr.address().to_v4().to_bytes(); + uint16 port = addr.port(); + + EndianConvertReverse(port); + + _stream.WriteBytes(ip.data(), 4); + _stream.WriteBytes(&port, 2); + } + } + else + _stream.Write(ResponseCode, 8); +} + +std::string Battlenet::WoWRealm::JoinResponseV2::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::JoinResponseV2"; + if (Response == SUCCESS) + { + stream << " ServerSeed " << ServerSeed << " IPv4 Addresses " << IPv4.size() << " IPv6 Addresses " << IPv6.size(); + for (tcp::endpoint const& addr : IPv4) + stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast(addr); + + for (tcp::endpoint const& addr : IPv6) + stream << std::endl << "Battlenet::WoWRealm::JoinResponseV2::Address " << boost::lexical_cast(addr); + } + else + stream << " Failure"; + + return stream.str().c_str(); +} diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h new file mode 100644 index 00000000000..4ce5ea68835 --- /dev/null +++ b/src/server/bnetserver/Packets/WoWRealmPackets.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef WoWRealmPackets_h__ +#define WoWRealmPackets_h__ + +#include "PacketsBase.h" +#include "RealmList.h" + +namespace Battlenet +{ + namespace WoWRealm + { + enum Opcode + { + CMSG_LIST_SUBSCRIBE_REQUEST = 0x0, + CMSG_LIST_UNSUBSCRIBE = 0x1, // Not implemented + CMSG_JOIN_REQUEST_V2 = 0x8, + CMSG_MULTI_LOGON_REQUEST_V2 = 0x9, // Not implemented + + SMSG_LIST_SUBSCRIBE_RESPONSE = 0x0, + SMSG_LIST_UPDATE = 0x2, + SMSG_LIST_COMPLETE = 0x3, + SMSG_TOON_READY = 0x6, // Not implemented + SMSG_TOON_LOGGED_OUT = 0x7, // Not implemented + SMSG_JOIN_RESPONSE_V2 = 0x8 + }; + + class ListSubscribeRequest final : public ClientPacket + { + public: + ListSubscribeRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM) && "Invalid packet header for ListSubscribeRequest"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + + class JoinRequestV2 final : public ClientPacket + { + public: + JoinRequestV2(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_JOIN_REQUEST_V2, WOWREALM) && "Invalid packet header for RealmJoinRequest"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) const override; + + uint32 ClientSeed; + RealmId Realm; + }; + + class ListSubscribeResponse final : public ServerPacket + { + public: + enum Result + { + SUCCESS = 0, + FAILURE = 1 + }; + + ListSubscribeResponse() : ServerPacket(PacketHeader(SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM)), + Response(SUCCESS), ResponseCode(26) + { + } + + ~ListSubscribeResponse(); + + struct CharacterCountEntry + { + RealmId Realm; + uint32 CharacterCount; + }; + + void Write() override; + std::string ToString() const override; + + Result Response; + uint8 ResponseCode; + std::vector CharacterCounts; + std::vector RealmData; + }; + + class ListUpdate final : public ServerPacket + { + public: + enum State + { + DELETED = 0, + UPDATE = 1 + }; + + ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)), UpdateState(UPDATE), + Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), + Flags(0), Region(0), Battlegroup(0), Index(0), Build(0) + { + } + + void Write() override; + std::string ToString() const override; + + int UpdateState; + uint32 Timezone; + float Population; + uint8 Lock; + uint32 Type; + std::string Name; + std::string Version; + tcp::endpoint Address; + uint8 Flags; + uint8 Region; + uint8 Battlegroup; + uint32 Index; + uint32 Build; + }; + + class ListComplete final : public ServerPacket + { + public: + ListComplete() : ServerPacket(PacketHeader(SMSG_LIST_COMPLETE, WOWREALM)) + { + } + + void Write() override { } + std::string ToString() const override { return "Battlenet::WoWRealm::ListComplete"; } + }; + + class JoinResponseV2 final : public ServerPacket + { + public: + enum Result + { + SUCCESS = 0, + FAILURE = 1 + }; + + JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)), + ServerSeed(0), Response(SUCCESS), ResponseCode(26) + { + } + + void Write() override; + std::string ToString() const override; + + Result Response; + uint8 ResponseCode; + uint32 ServerSeed; + std::vector IPv4; + std::vector IPv6; + }; + } +} + +#endif // WoWRealmPackets_h__ diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp new file mode 100644 index 00000000000..60b1d41a1a8 --- /dev/null +++ b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.cpp @@ -0,0 +1 @@ +#include "bnetPCH.h" diff --git a/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h new file mode 100644 index 00000000000..82cd5393489 --- /dev/null +++ b/src/server/bnetserver/PrecompiledHeaders/bnetPCH.h @@ -0,0 +1,10 @@ +#include "Common.h" +#include "Configuration/Config.h" +#include "Database/DatabaseEnv.h" +#include "Log.h" +#include "ComponentManager.h" +#include "ModuleManager.h" +#include "RealmList.h" +#include "ByteBuffer.h" +#include "Packets.h" +#include "Session.h" diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp new file mode 100644 index 00000000000..60d40f98edf --- /dev/null +++ b/src/server/bnetserver/Realms/RealmList.cpp @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include +#include "Common.h" +#include "RealmList.h" +#include "Database/DatabaseEnv.h" +#include "Util.h" + +ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const +{ + ip::address realmIp; + + // Attempt to send best address for client + if (clientAddr.is_loopback()) + { + // Try guessing if realm is also connected locally + if (LocalAddress.is_loopback() || ExternalAddress.is_loopback()) + realmIp = clientAddr; + else + { + // Assume that user connecting from the machine that authserver is located on + // has all realms available in his local network + realmIp = LocalAddress; + } + } + else + { + if (clientAddr.is_v4() && + (clientAddr.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()) == + (LocalAddress.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong())) + { + realmIp = LocalAddress; + } + else + realmIp = ExternalAddress; + } + + ip::tcp::endpoint endpoint(realmIp, port); + + // Return external IP + return endpoint; +} + +RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)), _resolver(nullptr) +{ +} + +RealmList::~RealmList() +{ + delete _resolver; +} + +// Load the realm list from the database +void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval) +{ + _resolver = new boost::asio::ip::tcp::resolver(ioService); + m_UpdateInterval = updateInterval; + + // Get the content of the realmlist table in the database + UpdateRealms(true); +} + +void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr, + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup) +{ + // Create new if not exist or update existed + Realm& realm = m_realms[name]; + + realm.m_ID = id; + realm.name = name; + realm.icon = icon; + realm.flag = flag; + realm.timezone = timezone; + realm.allowedSecurityLevel = allowedSecurityLevel; + realm.populationLevel = population; + + // Append port to IP address. + + realm.ExternalAddress = address; + realm.LocalAddress = localAddr; + realm.LocalSubnetMask = localSubmask; + realm.port = port; + realm.gamebuild = build; + realm.Region = region; + realm.Battlegroup = battlegroup; +} + +void RealmList::UpdateIfNeed() +{ + // maybe disabled or updated recently + if (!m_UpdateInterval || m_NextUpdateTime > time(NULL)) + return; + + m_NextUpdateTime = time(NULL) + m_UpdateInterval; + + // Clears Realm list + m_realms.clear(); + + // Get the content of the realmlist table in the database + UpdateRealms(); +} + +void RealmList::UpdateRealms(bool init) +{ + TC_LOG_INFO("server.authserver", "Updating Realm List..."); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + // Circle through results and add them to the realm map + if (result) + { + do + { + try + { + boost::asio::ip::tcp::resolver::iterator end; + + Field* fields = result->Fetch(); + uint32 realmId = fields[0].GetUInt32(); + std::string name = fields[1].GetString(); + boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), ""); + + boost::system::error_code ec; + boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); + if (endPoint == end || ec) + { + TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str()); + return; + } + + ip::address externalAddress = (*endPoint).endpoint().address(); + + boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), ""); + endPoint = _resolver->resolve(localAddressQuery, ec); + if (endPoint == end || ec) + { + TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str()); + return; + } + + ip::address localAddress = (*endPoint).endpoint().address(); + + boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), ""); + endPoint = _resolver->resolve(localSubmaskQuery, ec); + if (endPoint == end || ec) + { + TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str()); + return; + } + + ip::address localSubmask = (*endPoint).endpoint().address(); + + uint16 port = fields[5].GetUInt16(); + uint8 icon = fields[6].GetUInt8(); + RealmFlags flag = RealmFlags(fields[7].GetUInt8()); + uint8 timezone = fields[8].GetUInt8(); + uint8 allowedSecurityLevel = fields[9].GetUInt8(); + float pop = fields[10].GetFloat(); + uint32 build = fields[11].GetUInt32(); + uint8 region = fields[12].GetUInt8(); + uint8 battlegroup = fields[13].GetUInt8(); + + UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, + (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup); + + if (init) + TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port); + } + catch (std::exception& ex) + { + TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); + ASSERT(false); + } + } + while (result->NextRow()); + } +} + +Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const +{ + auto itr = std::find_if(m_realms.begin(), m_realms.end(), [id](RealmMap::value_type const& pair) + { + return pair.second.Region == id.Region && pair.second.Battlegroup == id.Battlegroup && pair.second.m_ID == id.Index; + }); + + if (itr != m_realms.end()) + return &itr->second; + + return NULL; +} diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h new file mode 100644 index 00000000000..502fef80ee7 --- /dev/null +++ b/src/server/bnetserver/Realms/RealmList.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef _REALMLIST_H +#define _REALMLIST_H + +#include +#include +#include +#include "Common.h" + +using namespace boost::asio; + +enum RealmFlags +{ + REALM_FLAG_NONE = 0x00, + REALM_FLAG_INVALID = 0x01, + REALM_FLAG_OFFLINE = 0x02, + REALM_FLAG_SPECIFYBUILD = 0x04, + REALM_FLAG_UNK1 = 0x08, + REALM_FLAG_UNK2 = 0x10, + REALM_FLAG_RECOMMENDED = 0x20, + REALM_FLAG_NEW = 0x40, + REALM_FLAG_FULL = 0x80 +}; + +// Storage object for a realm +struct Realm +{ + ip::address ExternalAddress; + ip::address LocalAddress; + ip::address LocalSubnetMask; + uint16 port; + std::string name; + uint8 icon; + RealmFlags flag; + uint8 timezone; + uint32 m_ID; + AccountTypes allowedSecurityLevel; + float populationLevel; + uint32 gamebuild; + uint8 Region; + uint8 Battlegroup; + + ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const; +}; + +namespace Battlenet +{ + struct RealmId + { + uint8 Region; + uint8 Battlegroup; + uint32 Index; + uint32 Build; + }; +} + +/// Storage object for the list of realms on the server +class RealmList +{ +public: + typedef std::map RealmMap; + + static RealmList* instance() + { + static RealmList instance; + return &instance; + } + + ~RealmList(); + + void Initialize(boost::asio::io_service& ioService, uint32 updateInterval); + + void UpdateIfNeed(); + + void AddRealm(const Realm& NewRealm) { m_realms[NewRealm.name] = NewRealm; } + + RealmMap::const_iterator begin() const { return m_realms.begin(); } + RealmMap::const_iterator end() const { return m_realms.end(); } + uint32 size() const { return m_realms.size(); } + Realm const* GetRealm(Battlenet::RealmId const& id) const; + +private: + RealmList(); + + void UpdateRealms(bool init = false); + void UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr, + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup); + + RealmMap m_realms; + uint32 m_UpdateInterval; + time_t m_NextUpdateTime; + boost::asio::ip::tcp::resolver* _resolver; +}; + +#define sRealmList RealmList::instance() +#endif diff --git a/src/server/bnetserver/Server/ComponentManager.cpp b/src/server/bnetserver/Server/ComponentManager.cpp new file mode 100644 index 00000000000..be1f22022f4 --- /dev/null +++ b/src/server/bnetserver/Server/ComponentManager.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ComponentManager.h" +#include "DatabaseEnv.h" + +Battlenet::ComponentMgr::~ComponentMgr() +{ + for (Component* component : _components) + delete component; +} + +void Battlenet::ComponentMgr::Load() +{ + QueryResult result = LoginDatabase.Query("SELECT Program, Platform, Build FROM battlenet_components"); + if (result) + { + do + { + Field* fields = result->Fetch(); + Component* component = new Component(); + component->Program = fields[0].GetString(); + component->Platform = fields[1].GetString(); + component->Build = fields[2].GetUInt32(); + + _components.insert(component); + _programs.insert(component->Program); + _platforms.insert(component->Platform); + + } while (result->NextRow()); + } +} + +bool Battlenet::ComponentMgr::HasComponent(Battlenet::Component const* component) const +{ + for (Component const* c : _components) + if (component->Program == c->Program && component->Platform == c->Platform && component->Build == c->Build) + return true; + + return false; +} diff --git a/src/server/bnetserver/Server/ComponentManager.h b/src/server/bnetserver/Server/ComponentManager.h new file mode 100644 index 00000000000..865cfca7f62 --- /dev/null +++ b/src/server/bnetserver/Server/ComponentManager.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ComponentManager_h__ +#define ComponentManager_h__ + +#include "Define.h" +#include +#include +#include + +namespace Battlenet +{ + struct Component + { + std::string Program; + std::string Platform; + uint32 Build; + }; + + class ComponentMgr + { + ComponentMgr() { } + ~ComponentMgr(); + + public: + void Load(); + bool HasComponent(Component const* component) const; + bool HasProgram(std::string const& program) const { return _programs.count(program) != 0; } + bool HasPlatform(std::string const& platform) const { return _platforms.count(platform) != 0; } + + static ComponentMgr* instance() + { + static ComponentMgr instance; + return &instance; + } + + private: + std::set _components; + std::set _programs; + std::set _platforms; + }; +} + +#define sComponentMgr Battlenet::ComponentMgr::instance() + +#endif // ComponentManager_h__ diff --git a/src/server/bnetserver/Server/ModuleManager.cpp b/src/server/bnetserver/Server/ModuleManager.cpp new file mode 100644 index 00000000000..8dc43136739 --- /dev/null +++ b/src/server/bnetserver/Server/ModuleManager.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ModuleManager.h" +#include "DatabaseEnv.h" + +Battlenet::ModuleManager::~ModuleManager() +{ + for (auto const& m : _modules) + delete m.second; +} + +void Battlenet::ModuleManager::Load() +{ + QueryResult result = LoginDatabase.Query("SELECT `Hash`, `Name`, `Type`, `System`, `Data` FROM battlenet_modules"); + if (result) + { + do + { + Field* fields = result->Fetch(); + ModuleInfo* module = new ModuleInfo(); + module->Type = fields[2].GetString(); + HexStrToByteArray(fields[0].GetString(), module->ModuleId); + std::string data = fields[4].GetString(); + module->DataSize = data.length() / 2; + if (module->DataSize) + { + module->Data = new uint8[data.length() / 2]; + HexStrToByteArray(data, module->Data); + } + + _modules[{ fields[3].GetString(), fields[1].GetString() }] = module; + } while (result->NextRow()); + } +} + +Battlenet::ModuleInfo* Battlenet::ModuleManager::CreateModule(std::string const& os, std::string const& name) const +{ + ModuleKey key { os, name }; + ASSERT(_modules.count(key)); + + return new ModuleInfo(*_modules.at(key)); +} diff --git a/src/server/bnetserver/Server/ModuleManager.h b/src/server/bnetserver/Server/ModuleManager.h new file mode 100644 index 00000000000..36ffb2fec3f --- /dev/null +++ b/src/server/bnetserver/Server/ModuleManager.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef ModuleManager_h__ +#define ModuleManager_h__ + +#include "Define.h" +#include +#include +#include + +namespace Battlenet +{ + struct ModuleKey + { + std::string Platform; + std::string Name; + + bool operator<(ModuleKey const& right) const + { + int32 res = Platform.compare(right.Platform); + if (res < 0) + return true; + else if (res > 0) + return false; + + return Name < right.Name; + } + }; + + struct ModuleInfo + { + ModuleInfo() : Region("EU"), DataSize(0), Data(nullptr) { } + ModuleInfo(ModuleInfo const& right) : Type(right.Type), Region(right.Region), DataSize(right.DataSize), Data(nullptr) + { + memcpy(ModuleId, right.ModuleId, 32); + if (DataSize) + { + Data = new uint8[DataSize]; + memcpy(Data, right.Data, DataSize); + } + } + ~ModuleInfo() + { + delete Data; + } + + std::string Type; + std::string Region; + uint8 ModuleId[32]; + uint32 DataSize; + uint8* Data; + }; + + class ModuleManager + { + ModuleManager() { } + ~ModuleManager(); + + public: + void Load(); + ModuleInfo* CreateModule(std::string const& os, std::string const& name) const; + + static ModuleManager* instance() + { + static ModuleManager instance; + return &instance; + } + + private: + void LoadComponents(); + void LoadModules(); + + std::map _modules; + }; +} + +#define sModuleMgr Battlenet::ModuleManager::instance() + +#endif // ModuleManager_h__ diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp new file mode 100644 index 00000000000..8935d520c40 --- /dev/null +++ b/src/server/bnetserver/Server/Session.cpp @@ -0,0 +1,1000 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "AuthCodes.h" +#include "BitStream.h" +#include "PacketFactory.h" +#include "SessionManager.h" +#include "Database/DatabaseEnv.h" +#include "HmacHash.h" +#include "Log.h" +#include "RealmList.h" +#include "SHA256.h" +#include + +Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODULE_COUNT] = +{ + &Battlenet::Session::HandlePasswordModule, + &Battlenet::Session::UnhandledModule, + &Battlenet::Session::UnhandledModule, + &Battlenet::Session::HandleSelectGameAccountModule, + &Battlenet::Session::HandleRiskFingerprintModule, + &Battlenet::Session::HandleResumeModule, +}; + +Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountId(0), _accountName(), _locale(), + _os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), + _reconnectProof(), _crypt(), _authed(false) +{ + static uint8 const N_Bytes[] = + { + 0xAB, 0x24, 0x43, 0x63, 0xA9, 0xC2, 0xA6, 0xC3, 0x3B, 0x37, 0xE4, 0x61, 0x84, 0x25, 0x9F, 0x8B, + 0x3F, 0xCB, 0x8A, 0x85, 0x27, 0xFC, 0x3D, 0x87, 0xBE, 0xA0, 0x54, 0xD2, 0x38, 0x5D, 0x12, 0xB7, + 0x61, 0x44, 0x2E, 0x83, 0xFA, 0xC2, 0x21, 0xD9, 0x10, 0x9F, 0xC1, 0x9F, 0xEA, 0x50, 0xE3, 0x09, + 0xA6, 0xE5, 0x5E, 0x23, 0xA7, 0x77, 0xEB, 0x00, 0xC7, 0xBA, 0xBF, 0xF8, 0x55, 0x8A, 0x0E, 0x80, + 0x2B, 0x14, 0x1A, 0xA2, 0xD4, 0x43, 0xA9, 0xD4, 0xAF, 0xAD, 0xB5, 0xE1, 0xF5, 0xAC, 0xA6, 0x13, + 0x1C, 0x69, 0x78, 0x64, 0x0B, 0x7B, 0xAF, 0x9C, 0xC5, 0x50, 0x31, 0x8A, 0x23, 0x08, 0x01, 0xA1, + 0xF5, 0xFE, 0x31, 0x32, 0x7F, 0xE2, 0x05, 0x82, 0xD6, 0x0B, 0xED, 0x4D, 0x55, 0x32, 0x41, 0x94, + 0x29, 0x6F, 0x55, 0x7D, 0xE3, 0x0F, 0x77, 0x19, 0xE5, 0x6C, 0x30, 0xEB, 0xDE, 0xF6, 0xA7, 0x86 + }; + + N.SetBinary(N_Bytes, sizeof(N_Bytes)); + g.SetDword(2); + + SHA256Hash sha; + sha.UpdateBigNumbers(&N, &g, NULL); + sha.Finalize(); + k.SetBinary(sha.GetDigest(), sha.GetLength()); +} + +Battlenet::Session::~Session() +{ + sSessionMgr.RemoveSession(this); + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::OnClose"); +} + +void Battlenet::Session::_SetVSFields(std::string const& pstr) +{ + s.SetRand(uint32(BufferSizes::SRP_6_S) * 8); + + BigNumber p; + p.SetHexStr(pstr.c_str()); + + SHA256Hash sha; + sha.UpdateBigNumbers(&s, &p, NULL); + sha.Finalize(); + BigNumber x; + x.SetBinary(sha.GetDigest(), sha.GetLength()); + v = g.ModExp(x, N); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_VS_FIELDS); + stmt->setString(0, v.AsHexStr()); + stmt->setString(1, s.AsHexStr()); + stmt->setString(2, _accountName); + + LoginDatabase.Execute(stmt); +} + +void Battlenet::Session::LogUnhandledPacket(ClientPacket const& packet) +{ + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::LogUnhandledPacket %s", packet.ToString().c_str()); +} + +void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& info) +{ + // Verify that this IP is not in the ip_banned table + LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); + + std::string ip_address = GetRemoteIpAddress().to_string(); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED); + stmt->setString(0, ip_address); + if (PreparedQueryResult result = LoginDatabase.Query(stmt)) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(LOGIN_BANNED); + AsyncWrite(complete); + TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort()); + return; + } + + if (info.Program != "WoW") + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_INVALID_PROGRAM); + AsyncWrite(complete); + return; + } + + if (!sComponentMgr->HasPlatform(info.Platform)) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_INVALID_OS); + AsyncWrite(complete); + return; + } + + if (!sComponentMgr->HasPlatform(info.Locale)) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); + AsyncWrite(complete); + return; + } + + for (Component const& component : info.Components) + { + if (!sComponentMgr->HasComponent(&component)) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + if (!sComponentMgr->HasProgram(component.Program)) + complete->SetAuthResult(AUTH_INVALID_PROGRAM); + else if (!sComponentMgr->HasPlatform(component.Platform)) + complete->SetAuthResult(AUTH_INVALID_OS); + else + { + if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build)) + complete->SetAuthResult(AUTH_REGION_BAD_VERSION); + else + complete->SetAuthResult(AUTH_USE_GRUNT_LOGON); + } + + AsyncWrite(complete); + return; + } + + if (component.Platform == "base") + _build = component.Build; + } + + _accountName = info.Login; + _locale = info.Locale; + _os = info.Platform; + + Utf8ToUpperOnlyLatin(_accountName); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); + stmt->setString(0, _accountName); + + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (!result) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + AsyncWrite(complete); + return; + } + + Field* fields = result->Fetch(); + + _accountId = fields[1].GetUInt32(); + + // If the IP is 'locked', check that the player comes indeed from the correct IP address + if (fields[2].GetUInt8() == 1) // if ip is locked + { + TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str()); + + if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); + AsyncWrite(complete); + return; + } + } + else + { + TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountName.c_str()); + std::string accountCountry = fields[3].GetString(); + if (accountCountry.empty() || accountCountry == "00") + TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountName.c_str()); + else if (!accountCountry.empty()) + { + uint32 ip = inet_addr(ip_address.c_str()); + EndianConvertReverse(ip); + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); + stmt->setUInt32(0, ip); + if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt)) + { + std::string loginCountry = (*sessionCountryQuery)[0].GetString(); + TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str()); + if (loginCountry != accountCountry) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); + AsyncWrite(complete); + return; + } + } + } + } + + //set expired bans to inactive + LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_EXPIRED_BANS)); + + // If the account is banned, reject the logon attempt + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN); + stmt->setUInt32(0, _accountId); + PreparedQueryResult banresult = LoginDatabase.Query(stmt); + if (banresult) + { + Field* fields = banresult->Fetch(); + if (fields[0].GetUInt32() == fields[1].GetUInt32()) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(LOGIN_BANNED); + AsyncWrite(complete); + TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); + return; + } + else + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(LOGIN_SUSPENDED); + AsyncWrite(complete); + TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); + return; + } + } + + SHA256Hash sha; + sha.UpdateData(_accountName); + sha.Finalize(); + + I.SetBinary(sha.GetDigest(), sha.GetLength()); + + ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password"); + ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint"); + + std::string pStr = fields[0].GetString(); + + std::string databaseV = fields[5].GetString(); + std::string databaseS = fields[6].GetString(); + + if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2) + _SetVSFields(pStr); + else + { + s.SetHexStr(databaseS.c_str()); + v.SetHexStr(databaseV.c_str()); + } + + b.SetRand(128 * 8); + B = ((v * k) + g.ModExp(b, N)) % N; + BigNumber unk; + unk.SetRand(128 * 8); + + BitStream passwordData; + uint8 state = 0; + passwordData.WriteBytes(&state, 1); + passwordData.WriteBytes(I.AsByteArray(32).get(), 32); + passwordData.WriteBytes(s.AsByteArray(32).get(), 32); + passwordData.WriteBytes(B.AsByteArray(128).get(), 128); + passwordData.WriteBytes(unk.AsByteArray(128).get(), 128); + + password->DataSize = passwordData.GetSize(); + password->Data = new uint8[password->DataSize]; + memcpy(password->Data, passwordData.GetBuffer(), password->DataSize); + + _modulesWaitingForData.push(MODULE_PASSWORD); + + Authentication::ProofRequest* request = new Authentication::ProofRequest(); + request->Modules.push_back(password); + // if has authenticator, send Token module + request->Modules.push_back(thumbprint); + AsyncWrite(request); +} + +void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& reconnect) +{ + _accountName = reconnect.Login; + _locale = reconnect.Locale; + _os = reconnect.Platform; + auto baseComponent = std::find_if(reconnect.Components.begin(), reconnect.Components.end(), [](Component const& c) { return c.Program == "base"; }); + if (baseComponent != reconnect.Components.end()) + _build = baseComponent->Build; + + Utf8ToUpperOnlyLatin(_accountName); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); + stmt->setString(0, _accountName); + stmt->setString(1, reconnect.GameAccountName); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (!result) + { + Authentication::ResumeResponse* resume = new Authentication::ResumeResponse(); + resume->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + AsyncWrite(resume); + return; + } + + Field* fields = result->Fetch(); + + _accountId = fields[0].GetUInt32(); + K.SetHexStr(fields[1].GetString().c_str()); + _gameAccountId = fields[2].GetUInt32(); + _gameAccountName = reconnect.GameAccountName; + + ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint"); + ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume"); + BitStream resumeData; + uint8 state = 0; + _reconnectProof.SetRand(16 * 8); + + resumeData.WriteBytes(&state, 1); + resumeData.WriteBytes(_reconnectProof.AsByteArray().get(), 16); + + resume->DataSize = resumeData.GetSize(); + resume->Data = new uint8[resume->DataSize]; + memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); + + _modulesWaitingForData.push(MODULE_RESUME); + + Authentication::ProofRequest* request = new Authentication::ProofRequest(); + request->Modules.push_back(thumbprint); + request->Modules.push_back(resume); + AsyncWrite(request); +} + +void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proof) +{ + if (_modulesWaitingForData.size() < proof.Modules.size()) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + AsyncWrite(complete); + return; + } + + ServerPacket* response = nullptr; + for (size_t i = 0; i < proof.Modules.size(); ++i) + { + if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proof.Modules[i], &response)) + break; + + _modulesWaitingForData.pop(); + } + + if (!response) + { + response = new Authentication::LogonResponse(); + static_cast(response)->SetAuthResult(AUTH_INTERNAL_ERROR); + } + + AsyncWrite(response); + return; +} + +void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/) +{ + AsyncWrite(new Connection::Pong()); +} + +void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption const& /*enableEncryption*/) +{ + _crypt.Init(&K); +} + +void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); + stmt->setString(0, ""); + stmt->setBool(1, false); + stmt->setUInt32(2, _accountId); + LoginDatabase.Execute(stmt); +} + +void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/) +{ + sRealmList->UpdateIfNeed(); + + WoWRealm::ListSubscribeResponse* counts = new WoWRealm::ListSubscribeResponse(); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS); + stmt->setUInt32(0, _gameAccountId); + + if (PreparedQueryResult countResult = LoginDatabase.Query(stmt)) + { + do + { + Field* fields = countResult->Fetch(); + uint32 build = fields[4].GetUInt32(); + counts->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() }); + } while (countResult->NextRow()); + } + + for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) + { + Realm const& realm = i->second; + + uint32 flag = realm.flag & ~REALM_FLAG_SPECIFYBUILD; + RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild); + if (realm.gamebuild != _build) + { + flag |= REALM_FLAG_INVALID; + if (buildInfo) + flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for + } + + WoWRealm::ListUpdate* update = new WoWRealm::ListUpdate(); + update->Timezone = realm.timezone; + update->Population = realm.populationLevel; + update->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; + update->Type = realm.icon; + update->Name = realm.name; + + if (flag & REALM_FLAG_SPECIFYBUILD) + { + std::ostringstream version; + version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; + + update->Version = version.str(); + update->Address = realm.GetAddressForClient(GetRemoteIpAddress()); + update->Build = buildInfo->Build; + } + + update->Flags = flag; + update->Region = realm.Region; + update->Battlegroup = realm.Battlegroup; + update->Index = realm.m_ID; + + counts->RealmData.push_back(update); + } + + counts->RealmData.push_back(new WoWRealm::ListComplete()); + + AsyncWrite(counts); +} + +void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join) +{ + WoWRealm::JoinResponseV2* result = new WoWRealm::JoinResponseV2(); + Realm const* realm = sRealmList->GetRealm(join.Realm); + if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE)) + { + result->Response = WoWRealm::JoinResponseV2::FAILURE; + AsyncWrite(result); + return; + } + + result->ServerSeed = uint32(rand32()); + + uint8 sessionKey[40]; + HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get()); + hmac.UpdateData((uint8*)"WoW\0", 4); + hmac.UpdateData((uint8*)&join.ClientSeed, 4); + hmac.UpdateData((uint8*)&result->ServerSeed, 4); + hmac.Finalize(); + + memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength()); + + HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get()); + hmac2.UpdateData((uint8*)"WoW\0", 4); + hmac2.UpdateData((uint8*)&result->ServerSeed, 4); + hmac2.UpdateData((uint8*)&join.ClientSeed, 4); + hmac2.Finalize(); + + memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength()); + + LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u", + ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountId); + + result->IPv4.emplace_back(realm->ExternalAddress, realm->port); + if (realm->ExternalAddress != realm->LocalAddress) + result->IPv4.emplace_back(realm->LocalAddress, realm->port); + + AsyncWrite(result); +} + +void Battlenet::Session::ReadHandler() +{ + BitStream stream(std::move(GetReadBuffer())); + _crypt.DecryptRecv(stream.GetBuffer(), stream.GetSize()); + + while (!stream.IsRead()) + { + try + { + PacketHeader header; + header.Opcode = stream.Read(6); + if (stream.Read(1)) + header.Channel = stream.Read(4); + + if (header.Channel != AUTHENTICATION && !_authed) + { + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Received not allowed packet %s", header.ToString().c_str()); + CloseSocket(); + return; + } + + if (ClientPacket* packet = sPacketFactory.Create(header, stream)) + { + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", packet->ToString().c_str()); + packet->CallHandler(this); + delete packet; + } + else + { + TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Unhandled opcode %s", header.ToString().c_str()); + break; + } + + stream.AlignToNextByte(); + } + catch (BitStreamPositionException const& e) + { + TC_LOG_ERROR("server.battlenet", "Battlenet::Session::ReadDataHandler Exception: %s", e.what()); + CloseSocket(); + return; + } + } + + GetReadBuffer().Resize(size_t(BufferSizes::Read)); + AsyncRead(); +} + +void Battlenet::Session::Start() +{ + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::Start"); + AsyncRead(); +} + +void Battlenet::Session::AsyncWrite(ServerPacket* packet) +{ + if (!IsOpen()) + { + delete packet; + return; + } + + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncWrite %s", packet->ToString().c_str()); + + packet->Write(); + + MessageBuffer buffer; + buffer.Write(packet->GetData(), packet->GetSize()); + delete packet; + + std::unique_lock guard(_writeLock); + + _crypt.EncryptSend(buffer.GetReadPointer(), buffer.GetActiveSize()); + + QueuePacket(std::move(buffer), guard); +} + +inline void ReplaceResponse(Battlenet::ServerPacket** oldResponse, Battlenet::ServerPacket* newResponse) +{ + if (*oldResponse) + delete *oldResponse; + + *oldResponse = newResponse; +} + +bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacket** response) +{ + if (dataStream->GetSize() != 1 + 128 + 32 + 128) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, complete); + return false; + } + + if (dataStream->Read(8) != 2) // State + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, complete); + return false; + } + + + BigNumber A, clientM1, clientChallenge; + A.SetBinary(dataStream->ReadBytes(128).get(), 128); + clientM1.SetBinary(dataStream->ReadBytes(32).get(), 32); + clientChallenge.SetBinary(dataStream->ReadBytes(128).get(), 128); + + if (A.isZero()) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, complete); + return false; + } + + SHA256Hash sha; + sha.UpdateBigNumbers(&A, &B, NULL); + sha.Finalize(); + + BigNumber u; + u.SetBinary(sha.GetDigest(), sha.GetLength()); + + BigNumber S = ((A * v.ModExp(u, N)) % N).ModExp(b, N); + + uint8 S_bytes[128]; + memcpy(S_bytes, S.AsByteArray(128).get(), 128); + + uint8 part1[64]; + uint8 part2[64]; + + for (int i = 0; i < 64; ++i) + { + part1[i] = S_bytes[i * 2]; + part2[i] = S_bytes[i * 2 + 1]; + } + + SHA256Hash part1sha, part2sha; + part1sha.UpdateData(part1, 64); + part1sha.Finalize(); + part2sha.UpdateData(part2, 64); + part2sha.Finalize(); + + uint8 sessionKey[SHA256_DIGEST_LENGTH * 2]; + for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) + { + sessionKey[i * 2] = part1sha.GetDigest()[i]; + sessionKey[i * 2 + 1] = part2sha.GetDigest()[i]; + } + + K.SetBinary(sessionKey, SHA256_DIGEST_LENGTH * 2); + + BigNumber M1; + + uint8 hash[SHA256_DIGEST_LENGTH]; + sha.Initialize(); + sha.UpdateBigNumbers(&N, NULL); + sha.Finalize(); + memcpy(hash, sha.GetDigest(), sha.GetLength()); + + sha.Initialize(); + sha.UpdateBigNumbers(&g, NULL); + sha.Finalize(); + + for (int i = 0; i < sha.GetLength(); ++i) + hash[i] ^= sha.GetDigest()[i]; + + SHA256Hash shaI; + shaI.UpdateData(ByteArrayToHexStr(I.AsByteArray().get(), 32)); + shaI.Finalize(); + + // Concat all variables for M1 hash + sha.Initialize(); + sha.UpdateData(hash, SHA256_DIGEST_LENGTH); + sha.UpdateData(shaI.GetDigest(), shaI.GetLength()); + sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); + sha.Finalize(); + + M1.SetBinary(sha.GetDigest(), sha.GetLength()); + + if (memcmp(M1.AsByteArray().get(), clientM1.AsByteArray().get(), 32)) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); + stmt->setString(0, _accountName); + LoginDatabase.Execute(stmt); + + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + ReplaceResponse(response, complete); + return false; + } + + uint64 numAccounts = 0; + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS); + stmt->setUInt32(0, _accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (result) + numAccounts = result->GetRowCount(); + + if (!numAccounts) + { + Authentication::LogonResponse* noAccounts = new Authentication::LogonResponse(); + noAccounts->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); + ReplaceResponse(response, noAccounts); + return false; + } + + Field* fields = result->Fetch(); + + //set expired game account bans to inactive + LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS)); + + BigNumber M; + sha.Initialize(); + sha.UpdateBigNumbers(&A, &M1, &K, NULL); + sha.Finalize(); + M.SetBinary(sha.GetDigest(), sha.GetLength()); + + BigNumber serverProof; + serverProof.SetRand(128 * 8); // just send garbage, server signature check is patched out in client + + BitStream stream; + ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password"); + uint8 state = 3; + + stream.WriteBytes(&state, 1); + stream.WriteBytes(M.AsByteArray(32).get(), 32); + stream.WriteBytes(serverProof.AsByteArray(128).get(), 128); + + password->DataSize = stream.GetSize(); + password->Data = new uint8[password->DataSize]; + memcpy(password->Data, stream.GetBuffer(), password->DataSize); + + Authentication::ProofRequest* request = new Authentication::ProofRequest(); + request->Modules.push_back(password); + if (numAccounts > 1) + { + BitStream accounts; + state = 0; + accounts.WriteBytes(&state, 1); + accounts.Write(numAccounts, 8); + do + { + fields = result->Fetch(); + std::ostringstream name; + std::string originalName = fields[1].GetString(); + if (originalName.find('#') != std::string::npos) + name << "WoW" << uint32(fields[0].GetUInt8()); + else + name << originalName; + + accounts.Write(2, 8); + accounts.WriteString(name.str(), 8); + } while (result->NextRow()); + + ModuleInfo* selectGameAccount = sModuleMgr->CreateModule(_os, "SelectGameAccount"); + selectGameAccount->DataSize = accounts.GetSize(); + selectGameAccount->Data = new uint8[selectGameAccount->DataSize]; + memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize); + request->Modules.push_back(selectGameAccount); + _modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT); + } + else + { + if (fields[4].GetBool()) + { + delete request; + + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + if (fields[2].GetUInt32() == fields[3].GetUInt32()) + { + complete->SetAuthResult(LOGIN_BANNED); + TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + } + else + { + complete->SetAuthResult(LOGIN_SUSPENDED); + TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + } + + ReplaceResponse(response, complete); + return false; + } + + _gameAccountId = fields[0].GetUInt32(); + _gameAccountName = fields[1].GetString(); + + request->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); + _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); + } + + ReplaceResponse(response, request); + return true; +} + +bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response) +{ + if (dataStream->Read(8) != 1) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, complete); + return false; + } + + dataStream->Read(8); + std::string account = dataStream->ReadString(8); + if (account.empty()) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); + ReplaceResponse(response, complete); + return false; + } + + PreparedStatement* stmt; + if (account.substr(0, 3) != "WoW") + { + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT); + stmt->setString(0, account); + } + else + { + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED); + stmt->setUInt8(0, atol(account.substr(3).c_str())); + } + + stmt->setUInt32(1, _accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (!result) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); + ReplaceResponse(response, complete); + return false; + } + + Field* fields = result->Fetch(); + if (fields[4].GetBool()) + { + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + if (fields[2].GetUInt32() == fields[3].GetUInt32()) + { + complete->SetAuthResult(LOGIN_BANNED); + TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + } + else + { + complete->SetAuthResult(LOGIN_SUSPENDED); + TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + } + + ReplaceResponse(response, complete); + return false; + } + + _gameAccountId = fields[0].GetUInt32(); + _gameAccountName = fields[1].GetString(); + + Authentication::ProofRequest* request = new Authentication::ProofRequest(); + request->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); + ReplaceResponse(response, request); + + _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); + return true; +} + +bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response) +{ + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + if (dataStream->Read(8) == 1) + { + complete->AccountId = _accountId; + complete->GameAccountName = _gameAccountName; + complete->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_FAILED_LOGINS); + stmt->setUInt32(0, _accountId); + if (PreparedQueryResult failedLoginsResult = LoginDatabase.Query(stmt)) + complete->FailedLogins = (*failedLoginsResult)[0].GetUInt32(); + + SQLTransaction trans = LoginDatabase.BeginTransaction(); + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO); + stmt->setString(0, GetRemoteIpAddress().to_string()); + stmt->setUInt8(1, GetLocaleByName(_locale)); + stmt->setString(2, _os); + stmt->setUInt32(3, _accountId); + trans->Append(stmt); + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); + stmt->setString(0, K.AsHexStr()); + stmt->setBool(1, true); + stmt->setUInt32(2, _accountId); + trans->Append(stmt); + + LoginDatabase.CommitTransaction(trans); + + _authed = true; + sSessionMgr.AddSession(this); + } + else + complete->SetAuthResult(AUTH_BAD_VERSION_HASH); + + ReplaceResponse(response, complete); + return true; +} + +bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket** response) +{ + if (dataStream->Read(8) != 1) + { + Authentication::ResumeResponse* complete = new Authentication::ResumeResponse(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, complete); + return false; + } + + static uint8 const ResumeClient = 0; + static uint8 const ResumeServer = 1; + + std::unique_ptr clientChallenge = dataStream->ReadBytes(16); + std::unique_ptr clientProof = dataStream->ReadBytes(32); + std::unique_ptr serverChallenge = _reconnectProof.AsByteArray(16); + std::unique_ptr sessionKey = K.AsByteArray(64); + + HmacSha256 clientPart(64, sessionKey.get()); + clientPart.UpdateData(&ResumeClient, 1); + clientPart.UpdateData(clientChallenge.get(), 16); + clientPart.UpdateData(serverChallenge.get(), 16); + clientPart.Finalize(); + + HmacSha256 serverPart(64, sessionKey.get()); + serverPart.UpdateData(&ResumeServer, 1); + serverPart.UpdateData(serverChallenge.get(), 16); + serverPart.UpdateData(clientChallenge.get(), 16); + serverPart.Finalize(); + + uint8 newSessionKey[64]; + memcpy(&newSessionKey[0], clientPart.GetDigest(), clientPart.GetLength()); + memcpy(&newSessionKey[32], serverPart.GetDigest(), serverPart.GetLength()); + + K.SetBinary(newSessionKey, 64); + + HmacSha256 proof(64, newSessionKey); + proof.UpdateData(&ResumeClient, 1); + proof.UpdateData(clientChallenge.get(), 16); + proof.UpdateData(serverChallenge.get(), 16); + proof.Finalize(); + + if (memcmp(proof.GetDigest(), clientProof.get(), serverPart.GetLength())) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS); + stmt->setString(0, _accountName); + LoginDatabase.Execute(stmt); + + TC_LOG_DEBUG("server.battlenet", "[Battlenet::Resume] Invalid proof!"); + Authentication::ResumeResponse* result = new Authentication::ResumeResponse(); + result->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + ReplaceResponse(response, result); + return false; + } + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); + stmt->setString(0, K.AsHexStr()); + stmt->setBool(1, true); + stmt->setUInt32(2, _accountId); + LoginDatabase.Execute(stmt); + + HmacSha256 serverProof(64, newSessionKey); + serverProof.UpdateData(&ResumeServer, 1); + serverProof.UpdateData(serverChallenge.get(), 16); + serverProof.UpdateData(clientChallenge.get(), 16); + serverProof.Finalize(); + + ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume"); + + BitStream resumeData; + uint8 state = 2; + resumeData.WriteBytes(&state, 1); + resumeData.WriteBytes(serverProof.GetDigest(), serverProof.GetLength()); + + resume->DataSize = resumeData.GetSize(); + resume->Data = new uint8[resume->DataSize]; + memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); + + Authentication::ResumeResponse* result = new Authentication::ResumeResponse(); + result->Modules.push_back(resume); + ReplaceResponse(response, result); + _authed = true; + sSessionMgr.AddSession(this); + return true; +} + +bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response) +{ + Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, complete); + return false; +} diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h new file mode 100644 index 00000000000..41caadbab3f --- /dev/null +++ b/src/server/bnetserver/Server/Session.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef Session_h__ +#define Session_h__ + +#include "Packets.h" +#include "BattlenetPacketCrypt.h" +#include "Socket.h" +#include "BigNumber.h" +#include +#include + +using boost::asio::ip::tcp; + +namespace Battlenet +{ + struct PacketHeader; + class BitStream; + + enum ModuleType + { + MODULE_PASSWORD, + MODULE_TOKEN, + MODULE_THUMBPRINT, + MODULE_SELECT_GAME_ACCOUNT, + MODULE_RISK_FINGERPRINT, + MODULE_RESUME, + + MODULE_COUNT + }; + + enum class BufferSizes : uint32 + { + SRP_6_V = 0x80, + SRP_6_S = 0x20, + Read = 0x4000 + }; + + class Session : public Socket + { + typedef Socket BattlenetSocket; + + public: + explicit Session(tcp::socket&& socket); + ~Session(); + + void LogUnhandledPacket(ClientPacket const& packet); + + // Authentication + void HandleLogonRequest(Authentication::LogonRequest const& logonRequest); + void HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest); + void HandleProofResponse(Authentication::ProofResponse const& proofResponse); + + // Connection + void HandlePing(Connection::Ping const& ping); + void HandleEnableEncryption(Connection::EnableEncryption const& enableEncryption); + void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest); + + // WoWRealm + void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest); + void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest); + + void Start() override; + + void AsyncWrite(ServerPacket* packet); + + protected: + void ReadHandler() override; + + private: + void _SetVSFields(std::string const& rI); + + typedef bool(Session::*ModuleHandler)(BitStream* dataStream, ServerPacket** response); + static ModuleHandler const ModuleHandlers[MODULE_COUNT]; + + bool HandlePasswordModule(BitStream* dataStream, ServerPacket** response); + bool HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response); + bool HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response); + bool HandleResumeModule(BitStream* dataStream, ServerPacket** response); + bool UnhandledModule(BitStream* dataStream, ServerPacket** response); + + uint32 _accountId; + std::string _accountName; + std::string _locale; + std::string _os; + uint32 _build; + uint32 _gameAccountId; + std::string _gameAccountName; + AccountTypes _accountSecurityLevel; + + BigNumber N; + BigNumber g; + BigNumber k; + + BigNumber I; + BigNumber s; + BigNumber v; + + BigNumber b; + BigNumber B; + BigNumber K; // session key + + BigNumber _reconnectProof; + + std::queue _modulesWaitingForData; + + PacketCrypt _crypt; + bool _authed; + }; + +} + +#endif // Session_h__ diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp new file mode 100644 index 00000000000..d8b6bfca8d1 --- /dev/null +++ b/src/server/bnetserver/Server/SessionManager.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "SessionManager.h" + +bool Battlenet::SessionManager::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) +{ + if (!BaseSocketMgr::StartNetwork(service, bindIp, port)) + return false; + + _acceptor->AsyncAcceptManaged(&OnSocketAccept); + return true; +} + +NetworkThread* Battlenet::SessionManager::CreateThreads() const +{ + return new NetworkThread[GetNetworkThreadCount()]; +} + +void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock) +{ + sSessionMgr.OnSocketOpen(std::forward(sock)); +} diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h new file mode 100644 index 00000000000..10e7196e4d8 --- /dev/null +++ b/src/server/bnetserver/Server/SessionManager.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SessionManager_h__ +#define SessionManager_h__ + +#include "Session.h" +#include "SocketMgr.h" + +namespace Battlenet +{ +#pragma pack(push, 1) + + struct SessionInfo + { + uint32 AccountId; + uint32 GameAccountIndex; + + bool operator<(SessionInfo const& right) const + { + return memcmp(this, &right, sizeof(SessionInfo)) < 0; + } + }; + +#pragma pack(pop) + + class SessionManager : SocketMgr + { + typedef SocketMgr BaseSocketMgr; + + public: + static SessionManager& Instance() + { + static SessionManager instance; + return instance; + } + + bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) override; + + // noop for now, will be needed later to broadcast realmlist updates for example + void AddSession(Session* /*session*/) { } + + void RemoveSession(Session* /*session*/) { } + + protected: + NetworkThread* CreateThreads() const override; + + private: + static void OnSocketAccept(tcp::socket&& sock); + + std::map _sessions; + }; +} + +#define sSessionMgr Battlenet::SessionManager::Instance() + +#endif // SessionManager_h__ diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist new file mode 100644 index 00000000000..e0ef6982353 --- /dev/null +++ b/src/server/bnetserver/bnetserver.conf.dist @@ -0,0 +1,257 @@ +############################################### +# Trinity Core Auth Server configuration file # +############################################### +[authserver] + +################################################################################################### +# SECTION INDEX +# +# EXAMPLE CONFIG +# AUTH SERVER SETTINGS +# MYSQL SETTINGS +# LOGGING SYSTEM SETTINGS +# +################################################################################################### + +################################################################################################### +# EXAMPLE CONFIG +# +# Variable +# Description: Brief description what the variable is doing. +# Important: Annotation for important things about this variable. +# Example: "Example, i.e. if the value is a string" +# Default: 10 - (Enabled|Comment|Variable name in case of grouped config options) +# 0 - (Disabled|Comment|Variable name in case of grouped config options) +# +# Note to developers: +# - Copy this example to keep the formatting. +# - Line breaks should be at column 100. +################################################################################################### + +################################################################################################### +# AUTH SERVER SETTINGS +# +# LogsDir +# Description: Logs directory setting. +# Important: LogsDir needs to be quoted, as the string might contain space characters. +# Logs directory must exists, or log file creation will be disabled. +# Default: "" - (Log files will be stored in the current path) + +LogsDir = "" + +# +# MaxPingTime +# Description: Time (in minutes) between database pings. +# Default: 30 + +MaxPingTime = 30 + +# +# RealmServerPort +# Description: TCP port to reach the auth server. +# Default: 3724 + +RealmServerPort = 3724 + +# +# BattlenetPort +# Description: TCP port to reach the auth server for battle.net connections. +# Default: 1119 + +BattlenetPort = 1119 + +# +# +# BindIP +# Description: Bind auth server to IP/hostname +# Default: "0.0.0.0" - (Bind to all IPs on the system) + +BindIP = "0.0.0.0" + +# +# PidFile +# Description: Auth server PID file. +# Example: "./authserver.pid" - (Enabled) +# Default: "" - (Disabled) + +PidFile = "" + +# +# UseProcessors +# Description: Processors mask for Windows and Linux based multi-processor systems. +# Example: A computer with 2 CPUs: +# 1 - 1st CPU only, 2 - 2nd CPU only, 3 - 1st and 2nd CPU, because 1 | 2 is 3 +# Default: 0 - (Selected by OS) +# 1+ - (Bit mask value of selected processors) + +UseProcessors = 0 + +# +# ProcessPriority +# Description: Process priority setting for Windows and Linux based systems. +# Details: On Linux, a nice value of -15 is used. (requires superuser). On Windows, process is set to HIGH class. +# Default: 0 - (Normal) +# 1 - (High) + +ProcessPriority = 0 + +# +# RealmsStateUpdateDelay +# Description: Time (in seconds) between realm list updates. +# Default: 20 - (Enabled) +# 0 - (Disabled) + +RealmsStateUpdateDelay = 20 + +# +# WrongPass.MaxCount +# Description: Number of login attemps with wrong password before the account or IP will be +# banned. +# Default: 0 - (Disabled) +# 1+ - (Enabled) + +WrongPass.MaxCount = 0 + +# +# WrongPass.BanTime +# Description: Time (in seconds) for banning account or IP for invalid login attempts. +# Default: 600 - (10 minutes) +# 0 - (Permanent ban) + +WrongPass.BanTime = 600 + +# +# WrongPass.BanType +# Description: Ban type for invalid login attempts. +# Default: 0 - (Ban IP) +# 1 - (Ban Account) + +WrongPass.BanType = 0 + +# +################################################################################################### + +################################################################################################### +# MYSQL SETTINGS +# +# LoginDatabaseInfo +# Description: Database connection settings for the realm server. +# Example: "hostname;port;username;password;database" +# ".;somenumber;username;password;database" - (Use named pipes on Windows +# "enable-named-pipe" to [mysqld] +# section my.ini) +# ".;/path/to/unix_socket;username;password;database" - (use Unix sockets on +# Unix/Linux) +# Default: "127.0.0.1;3306;trinity;trinity;auth" + +LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" + +# +# LoginDatabase.WorkerThreads +# Description: The amount of worker threads spawned to handle asynchronous (delayed) MySQL +# statements. Each worker thread is mirrored with its own connection to the +# Default: 1 + +LoginDatabase.WorkerThreads = 1 + +# +# Wrong.Password.Login.Logging +# Description: Additionally log attempted wrong password logging +# Default: 0 - (Disabled) +# 1 - (Enabled) + +Wrong.Password.Login.Logging = 0 +# +################################################################################################### + +################################################################################################### +# +# LOGGING SYSTEM SETTINGS +# +# Appender config values: Given a appender "name" +# Appender.name +# Description: Defines 'where to log' +# Format: Type,LogLevel,Flags,optional1,optional2,optional3 +# +# Type +# 0 - (None) +# 1 - (Console) +# 2 - (File) +# 3 - (DB) +# +# LogLevel +# 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# Flags: +# 0 - None +# 1 - Prefix Timestamp to the text +# 2 - Prefix Log Level to the text +# 4 - Prefix Log Filter type to the text +# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2) +# 16 - Make a backup of existing file before overwrite (Only used with Mode = w) +# +# Colors (read as optional1 if Type = Console) +# Format: "fatal error warn info debug trace" +# 0 - BLACK +# 1 - RED +# 2 - GREEN +# 3 - BROWN +# 4 - BLUE +# 5 - MAGENTA +# 6 - CYAN +# 7 - GREY +# 8 - YELLOW +# 9 - LRED +# 10 - LGREEN +# 11 - LBLUE +# 12 - LMAGENTA +# 13 - LCYAN +# 14 - WHITE +# Example: "13 11 9 5 3 1" +# +# File: Name of the file (read as optional1 if Type = File) +# Allows to use one "%s" to create dynamic files +# +# Mode: Mode to open the file (read as optional2 if Type = File) +# a - (Append) +# w - (Overwrite) +# +# MaxFileSize: Maximum file size of the log file before creating a new log file +# (read as optional3 if Type = File) +# Size is measured in bytes expressed in a 64-bit unsigned integer. +# Maximum value is 4294967295 (4 gb). Leave blank for no limit. +# NOTE: Does not work with dynamic filenames. +# Example: 536870912 (512 mb) +# + +Appender.Console=1,2,0 +Appender.Auth=2,2,0,Auth.log,w + +# Logger config values: Given a logger "name" +# Logger.name +# Description: Defines 'What to log' +# Format: LogLevel,AppenderList +# +# LogLevel +# 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# AppenderList: List of appenders linked to logger +# (Using spaces as separator). +# + +Logger.root=3,Console Auth + +# +################################################################################################### diff --git a/src/server/bnetserver/bnetserver.ico b/src/server/bnetserver/bnetserver.ico new file mode 100644 index 00000000000..da318f48a8c Binary files /dev/null and b/src/server/bnetserver/bnetserver.ico differ diff --git a/src/server/bnetserver/bnetserver.rc b/src/server/bnetserver/bnetserver.rc new file mode 100644 index 00000000000..f030203fdcd --- /dev/null +++ b/src/server/bnetserver/bnetserver.rc @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "resource.h" +#include "revision.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "windows.h" //"afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APPICON ICON "bnetserver.ico" + +///////////////////////////////////////////////////////////////////////////// +// Neutre (Par défaut système) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUSD) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION + +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + +#ifndef _DEBUG + FILEFLAGS 0 +#else + #define VER_PRERELEASE VS_FF_PRERELEASE + #define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD + #define VER_DEBUG 0 + FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) +#endif + +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP + +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080004b0" + BEGIN + VALUE "CompanyName", VER_COMPANYNAME_STR + VALUE "FileDescription", "TrinityCore Battle.net Server Daemon" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "bnetserver" + VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "OriginalFilename", "bnetserver.exe" + VALUE "ProductName", "TrinityCore Battle.net Server" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x800, 1200 + END +END +#endif diff --git a/src/server/bnetserver/resource.h b/src/server/bnetserver/resource.h new file mode 100644 index 00000000000..7dc5cb9ef7b --- /dev/null +++ b/src/server/bnetserver/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by TrinityCore.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif -- cgit v1.2.3 From f52e921521b7a29b5ec971875d4be1a44f2f839c Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 10 Oct 2014 23:22:11 +0200 Subject: Core/Config: Removed bnet port from authserver and authserver port from bnet config giles --- src/server/authserver/authserver.conf.dist | 7 ------- src/server/bnetserver/bnetserver.conf.dist | 11 ++--------- 2 files changed, 2 insertions(+), 16 deletions(-) (limited to 'src/server') diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index e0ef6982353..b7dee9ac08b 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -53,13 +53,6 @@ MaxPingTime = 30 RealmServerPort = 3724 -# -# BattlenetPort -# Description: TCP port to reach the auth server for battle.net connections. -# Default: 1119 - -BattlenetPort = 1119 - # # # BindIP diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist index e0ef6982353..2ca57cea20c 100644 --- a/src/server/bnetserver/bnetserver.conf.dist +++ b/src/server/bnetserver/bnetserver.conf.dist @@ -46,13 +46,6 @@ LogsDir = "" MaxPingTime = 30 -# -# RealmServerPort -# Description: TCP port to reach the auth server. -# Default: 3724 - -RealmServerPort = 3724 - # # BattlenetPort # Description: TCP port to reach the auth server for battle.net connections. @@ -231,7 +224,7 @@ Wrong.Password.Login.Logging = 0 # Appender.Console=1,2,0 -Appender.Auth=2,2,0,Auth.log,w +Appender.Bnet=2,2,0,Bnet.log,w # Logger config values: Given a logger "name" # Logger.name @@ -251,7 +244,7 @@ Appender.Auth=2,2,0,Auth.log,w # (Using spaces as separator). # -Logger.root=3,Console Auth +Logger.root=3,Console Bnet # ################################################################################################### -- cgit v1.2.3 From cb06ac47b3fda8c6a8f13bb4f6e28cb18f84ade8 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 10 Oct 2014 23:28:34 +0200 Subject: Removed a file that somehow came back - I blame magic. --- .../BattlenetPackets/AuthenticationPackets.cpp | 320 --------------------- 1 file changed, 320 deletions(-) delete mode 100644 src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp (limited to 'src/server') diff --git a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp b/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp deleted file mode 100644 index dd8e04564af..00000000000 --- a/src/server/authserver/Server/BattlenetPackets/AuthenticationPackets.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "AuthenticationPackets.h" -#include "BattlenetSession.h" -#include "Util.h" - -void Battlenet::Authentication::LogonRequest::Read() -{ - Program = _stream.ReadFourCC(); - Platform = _stream.ReadFourCC(); - Locale = _stream.ReadFourCC(); - - Components.resize(_stream.Read(6)); - for (size_t i = 0; i < Components.size(); ++i) - { - Component& component = Components[i]; - component.Program = _stream.ReadFourCC(); - component.Platform = _stream.ReadFourCC(); - component.Build = _stream.Read(32); - } - - if (_stream.Read(1)) - Login = _stream.ReadString(9, 3); -} - -std::string Battlenet::Authentication::LogonRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::LogonRequest Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; - for (Component const& component : Components) - stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; - - if (!Login.empty()) - stream << std::endl << "Battlenet::Authentication::LogonRequest Login: " << Login; - - return stream.str(); -} - -void Battlenet::Authentication::LogonRequest::CallHandler(Session* session) const -{ - session->HandleLogonRequest(*this); -} - -void Battlenet::Authentication::ResumeRequest::Read() -{ - Program = _stream.ReadFourCC(); - Platform = _stream.ReadFourCC(); - Locale = _stream.ReadFourCC(); - - Components.resize(_stream.Read(6)); - for (size_t i = 0; i < Components.size(); ++i) - { - Component& component = Components[i]; - component.Program = _stream.ReadFourCC(); - component.Platform = _stream.ReadFourCC(); - component.Build = _stream.Read(32); - } - - Login = _stream.ReadString(9, 3); - Region = _stream.Read(8); - GameAccountName = _stream.ReadString(5, 1); -} - -std::string Battlenet::Authentication::ResumeRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ResumeRequest Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; - for (Component const& component : Components) - stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; - - stream << std::endl << "Login: " << Login; - stream << std::endl << "Region: " << uint32(Region); - stream << std::endl << "GameAccountName: " << GameAccountName; - - return stream.str(); -} - -void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session) const -{ - session->HandleResumeRequest(*this); -} - -Battlenet::Authentication::ProofRequest::~ProofRequest() -{ - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; -} - -void Battlenet::Authentication::ProofRequest::Write() -{ - _stream.Write(Modules.size(), 3); - for (ModuleInfo const* info : Modules) - { - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.Write(info->DataSize, 10); - _stream.WriteBytes(info->Data, info->DataSize); - } -} - -std::string Battlenet::Authentication::ProofRequest::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ProofRequest modules " << Modules.size(); - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} - -Battlenet::Authentication::ProofResponse::~ProofResponse() -{ - for (size_t i = 0; i < Modules.size(); ++i) - delete Modules[i]; -} - -void Battlenet::Authentication::ProofResponse::Read() -{ - Modules.resize(_stream.Read(3)); - for (size_t i = 0; i < Modules.size(); ++i) - { - BitStream*& dataStream = Modules[i]; - dataStream = new BitStream(_stream.Read(10)); - memcpy(dataStream->GetBuffer(), _stream.ReadBytes(dataStream->GetSize()).get(), dataStream->GetSize()); - } -} - -std::string Battlenet::Authentication::ProofResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ProofResponse Modules " << Modules.size(); - for (BitStream* module : Modules) - { - std::string hexStr = ByteArrayToHexStr(module->GetBuffer(), module->GetSize()); - stream << std::endl << "Battlenet::Authentication::ProofResponse::ModuleData Size: " << module->GetSize() << ", Data: " << hexStr; - } - - return stream.str(); -} - -void Battlenet::Authentication::ProofResponse::CallHandler(Session* session) const -{ - session->HandleProofResponse(*this); -} - -Battlenet::Authentication::LogonResponse::~LogonResponse() -{ - for (ModuleInfo* m : Modules) - delete m; -} - -void Battlenet::Authentication::LogonResponse::Write() -{ - _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); - if (Result.ResultValue == ResponseFailure::UPDATE) - { - _stream.Write(Modules.size(), 3); - for (size_t i = 0; i < Modules.size(); ++i) - { - ModuleInfo* info = Modules[i]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.Write(info->DataSize, 10); - _stream.WriteBytes(info->Data, info->DataSize); - } - - _stream.Write(PingTimeout + std::numeric_limits::min(), 32); - _stream.Write(1, 1); // RegulatorRules != NULL (not a pointer for us, always write) - // if written == 1 - { - _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); - if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) - { - _stream.Write(RegulatorRules.Threshold, 32); - _stream.Write(RegulatorRules.Rate, 32); - } - } - - _stream.WriteString(FirstName, 8); // First name - _stream.WriteString(LastName, 8); // Last name - not set for WoW - - _stream.Write(AccountId, 32); - _stream.Write(Region, 8); - _stream.Write(Flags, 64); - - _stream.Write(GameAccountRegion, 8); - _stream.WriteString(GameAccountName, 5, -1); - _stream.Write(GameAccountFlags, 64); - - _stream.Write(FailedLogins, 32); - } - else - { - _stream.Write(!Modules.empty(), 1); - if (!Modules.empty()) - { - ModuleInfo* info = Modules[0]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - } - - _stream.Write(Result.ResultValue, 2); - if (Result.ResultValue == ResponseFailure::FAILURE) - { - _stream.Write(Result.Error, 16); - _stream.Write(Result.Wait + std::numeric_limits::min(), 32); - } - } -} - -std::string Battlenet::Authentication::LogonResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::LogonResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout - << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate - << " FirstName " << FirstName << " LastName " << LastName << " AccountId " << AccountId << " Region " << uint32(Region) << " GameAccountName " << GameAccountName - << " GameAccountFlags " << GameAccountFlags << " FailedLogins " << FailedLogins << " Modules " << Modules.size(); - - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} - -void Battlenet::Authentication::LogonResponse::SetAuthResult(AuthResult result) -{ - Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; - Result.Error = result; -} - -Battlenet::Authentication::ResumeResponse::~ResumeResponse() -{ - for (ModuleInfo* m : Modules) - delete m; -} - -void Battlenet::Authentication::ResumeResponse::Write() -{ - _stream.Write(Result.ResultValue != ResponseFailure::UPDATE, 1); - if (Result.ResultValue == ResponseFailure::UPDATE) - { - _stream.Write(Modules.size(), 3); - for (size_t i = 0; i < Modules.size(); ++i) - { - ModuleInfo* info = Modules[i]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - _stream.Write(info->DataSize, 10); - _stream.WriteBytes(info->Data, info->DataSize); - } - - _stream.Write(PingTimeout + std::numeric_limits::min(), 32); - _stream.Write(1, 1); // RegulatorRules != NULL (not a pointer for us, always write) - // if written == 1 - { - _stream.Write(RegulatorRules.Type == Regulator::LEAKY_BUCKET, 1); - if (RegulatorRules.Type == Regulator::LEAKY_BUCKET) - { - _stream.Write(RegulatorRules.Threshold, 32); - _stream.Write(RegulatorRules.Rate, 32); - } - } - } - else - { - _stream.Write(!Modules.empty(), 1); - if (!Modules.empty()) - { - ModuleInfo* info = Modules[0]; - _stream.WriteBytes(info->Type.c_str(), 4); - _stream.WriteFourCC(info->Region); - _stream.WriteBytes(info->ModuleId, 32); - } - - _stream.Write(Result.ResultValue, 2); - if (Result.ResultValue == ResponseFailure::FAILURE) - { - _stream.Write(Result.Error, 16); - _stream.Write(Result.Wait + std::numeric_limits::min(), 32); - } - } -} - -std::string Battlenet::Authentication::ResumeResponse::ToString() const -{ - std::ostringstream stream; - stream << "Battlenet::Authentication::ResumeResponse AuthResult " << Result.Error << " PingTimeout " << PingTimeout - << " RegulatorRules.Threshold " << RegulatorRules.Threshold << " RegulatorRules.Rate " << RegulatorRules.Rate - << " Modules " << Modules.size(); - - for (ModuleInfo const* module : Modules) - stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); - - return stream.str(); -} - -void Battlenet::Authentication::ResumeResponse::SetAuthResult(AuthResult result) -{ - Result.ResultValue = result != AUTH_OK ? ResponseFailure::FAILURE : ResponseFailure::UPDATE; - Result.Error = result; -} -- cgit v1.2.3 From 00603772df8dfbbbcc0050813cde1b50619685d6 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 10 Oct 2014 23:48:01 +0200 Subject: Core/Battle.net: Added missing includes and changed default config file name --- src/server/bnetserver/Main.cpp | 2 +- .../bnetserver/Packets/AuthenticationPackets.h | 2 + src/server/bnetserver/Server/Session.cpp | 304 ++++++++++----------- 3 files changed, 155 insertions(+), 153 deletions(-) (limited to 'src/server') diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index cb9bab97841..e208f3cd1d9 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -46,7 +46,7 @@ using boost::asio::ip::tcp; using namespace boost::program_options; #ifndef _TRINITY_BNET_CONFIG -# define _TRINITY_BNET_CONFIG "authserver.conf" +# define _TRINITY_BNET_CONFIG "bnetserver.conf" #endif bool StartDB(); diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h index 8003e13db24..72e598b858e 100644 --- a/src/server/bnetserver/Packets/AuthenticationPackets.h +++ b/src/server/bnetserver/Packets/AuthenticationPackets.h @@ -19,6 +19,8 @@ #define AuthenticationPackets_h__ #include "PacketsBase.h" +#include "ComponentManager.h" +#include "ModuleManager.h" namespace Battlenet { diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 8935d520c40..1d8e0136af3 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -94,7 +94,7 @@ void Battlenet::Session::LogUnhandledPacket(ClientPacket const& packet) TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::LogUnhandledPacket %s", packet.ToString().c_str()); } -void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& info) +void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& logonRequest) { // Verify that this IP is not in the ip_banned table LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS)); @@ -104,55 +104,55 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& stmt->setString(0, ip_address); if (PreparedQueryResult result = LoginDatabase.Query(stmt)) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_BANNED); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(LOGIN_BANNED); + AsyncWrite(logonResponse); TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort()); return; } - if (info.Program != "WoW") + if (logonRequest.Program != "WoW") { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_INVALID_PROGRAM); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM); + AsyncWrite(logonResponse); return; } - if (!sComponentMgr->HasPlatform(info.Platform)) + if (!sComponentMgr->HasPlatform(logonRequest.Platform)) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_INVALID_OS); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_INVALID_OS); + AsyncWrite(logonResponse); return; } - if (!sComponentMgr->HasPlatform(info.Locale)) + if (!sComponentMgr->HasPlatform(logonRequest.Locale)) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); + AsyncWrite(logonResponse); return; } - for (Component const& component : info.Components) + for (Component const& component : logonRequest.Components) { if (!sComponentMgr->HasComponent(&component)) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); if (!sComponentMgr->HasProgram(component.Program)) - complete->SetAuthResult(AUTH_INVALID_PROGRAM); + logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM); else if (!sComponentMgr->HasPlatform(component.Platform)) - complete->SetAuthResult(AUTH_INVALID_OS); + logonResponse->SetAuthResult(AUTH_INVALID_OS); else { if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build)) - complete->SetAuthResult(AUTH_REGION_BAD_VERSION); + logonResponse->SetAuthResult(AUTH_REGION_BAD_VERSION); else - complete->SetAuthResult(AUTH_USE_GRUNT_LOGON); + logonResponse->SetAuthResult(AUTH_USE_GRUNT_LOGON); } - AsyncWrite(complete); + AsyncWrite(logonResponse); return; } @@ -160,9 +160,9 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& _build = component.Build; } - _accountName = info.Login; - _locale = info.Locale; - _os = info.Platform; + _accountName = logonRequest.Login; + _locale = logonRequest.Locale; + _os = logonRequest.Platform; Utf8ToUpperOnlyLatin(_accountName); stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO); @@ -171,9 +171,9 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + AsyncWrite(logonResponse); return; } @@ -188,9 +188,9 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED); + AsyncWrite(logonResponse); return; } } @@ -213,9 +213,9 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str()); if (loginCountry != accountCountry) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_ACCOUNT_LOCKED); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED); + AsyncWrite(logonResponse); return; } } @@ -234,17 +234,17 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& Field* fields = banresult->Fetch(); if (fields[0].GetUInt32() == fields[1].GetUInt32()) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_BANNED); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(LOGIN_BANNED); + AsyncWrite(logonResponse); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); return; } else { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_SUSPENDED); - AsyncWrite(complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(LOGIN_SUSPENDED); + AsyncWrite(logonResponse); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); return; } @@ -291,32 +291,32 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& _modulesWaitingForData.push(MODULE_PASSWORD); - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(password); + Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); + proofRequest->Modules.push_back(password); // if has authenticator, send Token module - request->Modules.push_back(thumbprint); - AsyncWrite(request); + proofRequest->Modules.push_back(thumbprint); + AsyncWrite(proofRequest); } -void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& reconnect) +void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const& resumeRequest) { - _accountName = reconnect.Login; - _locale = reconnect.Locale; - _os = reconnect.Platform; - auto baseComponent = std::find_if(reconnect.Components.begin(), reconnect.Components.end(), [](Component const& c) { return c.Program == "base"; }); - if (baseComponent != reconnect.Components.end()) + _accountName = resumeRequest.Login; + _locale = resumeRequest.Locale; + _os = resumeRequest.Platform; + auto baseComponent = std::find_if(resumeRequest.Components.begin(), resumeRequest.Components.end(), [](Component const& c) { return c.Program == "base"; }); + if (baseComponent != resumeRequest.Components.end()) _build = baseComponent->Build; Utf8ToUpperOnlyLatin(_accountName); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); stmt->setString(0, _accountName); - stmt->setString(1, reconnect.GameAccountName); + stmt->setString(1, resumeRequest.GameAccountName); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { - Authentication::ResumeResponse* resume = new Authentication::ResumeResponse(); - resume->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - AsyncWrite(resume); + Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); + resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + AsyncWrite(resumeResponse); return; } @@ -325,7 +325,7 @@ void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const _accountId = fields[0].GetUInt32(); K.SetHexStr(fields[1].GetString().c_str()); _gameAccountId = fields[2].GetUInt32(); - _gameAccountName = reconnect.GameAccountName; + _gameAccountName = resumeRequest.GameAccountName; ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint"); ModuleInfo* resume = sModuleMgr->CreateModule(_os, "Resume"); @@ -342,15 +342,15 @@ void Battlenet::Session::HandleResumeRequest(Authentication::ResumeRequest const _modulesWaitingForData.push(MODULE_RESUME); - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(thumbprint); - request->Modules.push_back(resume); - AsyncWrite(request); + Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); + proofRequest->Modules.push_back(thumbprint); + proofRequest->Modules.push_back(resume); + AsyncWrite(proofRequest); } -void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proof) +void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const& proofResponse) { - if (_modulesWaitingForData.size() < proof.Modules.size()) + if (_modulesWaitingForData.size() < proofResponse.Modules.size()) { Authentication::LogonResponse* complete = new Authentication::LogonResponse(); complete->SetAuthResult(AUTH_CORRUPTED_MODULE); @@ -359,9 +359,9 @@ void Battlenet::Session::HandleProofResponse(Authentication::ProofResponse const } ServerPacket* response = nullptr; - for (size_t i = 0; i < proof.Modules.size(); ++i) + for (size_t i = 0; i < proofResponse.Modules.size(); ++i) { - if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proof.Modules[i], &response)) + if (!(this->*(ModuleHandlers[_modulesWaitingForData.front()]))(proofResponse.Modules[i], &response)) break; _modulesWaitingForData.pop(); @@ -400,7 +400,7 @@ void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeReque { sRealmList->UpdateIfNeed(); - WoWRealm::ListSubscribeResponse* counts = new WoWRealm::ListSubscribeResponse(); + WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse(); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS); stmt->setUInt32(0, _gameAccountId); @@ -411,7 +411,7 @@ void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeReque { Field* fields = countResult->Fetch(); uint32 build = fields[4].GetUInt32(); - counts->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() }); + listSubscribeResponse->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() }); } while (countResult->NextRow()); } @@ -428,62 +428,62 @@ void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeReque flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for } - WoWRealm::ListUpdate* update = new WoWRealm::ListUpdate(); - update->Timezone = realm.timezone; - update->Population = realm.populationLevel; - update->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; - update->Type = realm.icon; - update->Name = realm.name; + WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); + listUpdate->Timezone = realm.timezone; + listUpdate->Population = realm.populationLevel; + listUpdate->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; + listUpdate->Type = realm.icon; + listUpdate->Name = realm.name; if (flag & REALM_FLAG_SPECIFYBUILD) { std::ostringstream version; version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; - update->Version = version.str(); - update->Address = realm.GetAddressForClient(GetRemoteIpAddress()); - update->Build = buildInfo->Build; + listUpdate->Version = version.str(); + listUpdate->Address = realm.GetAddressForClient(GetRemoteIpAddress()); + listUpdate->Build = buildInfo->Build; } - update->Flags = flag; - update->Region = realm.Region; - update->Battlegroup = realm.Battlegroup; - update->Index = realm.m_ID; + listUpdate->Flags = flag; + listUpdate->Region = realm.Region; + listUpdate->Battlegroup = realm.Battlegroup; + listUpdate->Index = realm.m_ID; - counts->RealmData.push_back(update); + listSubscribeResponse->RealmData.push_back(listUpdate); } - counts->RealmData.push_back(new WoWRealm::ListComplete()); + listSubscribeResponse->RealmData.push_back(new WoWRealm::ListComplete()); - AsyncWrite(counts); + AsyncWrite(listSubscribeResponse); } -void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join) +void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest) { - WoWRealm::JoinResponseV2* result = new WoWRealm::JoinResponseV2(); - Realm const* realm = sRealmList->GetRealm(join.Realm); + WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2(); + Realm const* realm = sRealmList->GetRealm(joinRequest.Realm); if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE)) { - result->Response = WoWRealm::JoinResponseV2::FAILURE; - AsyncWrite(result); + joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE; + AsyncWrite(joinResponse); return; } - result->ServerSeed = uint32(rand32()); + joinResponse->ServerSeed = uint32(rand32()); uint8 sessionKey[40]; HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get()); hmac.UpdateData((uint8*)"WoW\0", 4); - hmac.UpdateData((uint8*)&join.ClientSeed, 4); - hmac.UpdateData((uint8*)&result->ServerSeed, 4); + hmac.UpdateData((uint8*)&joinRequest.ClientSeed, 4); + hmac.UpdateData((uint8*)&joinResponse->ServerSeed, 4); hmac.Finalize(); memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength()); HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get()); hmac2.UpdateData((uint8*)"WoW\0", 4); - hmac2.UpdateData((uint8*)&result->ServerSeed, 4); - hmac2.UpdateData((uint8*)&join.ClientSeed, 4); + hmac2.UpdateData((uint8*)&joinResponse->ServerSeed, 4); + hmac2.UpdateData((uint8*)&joinRequest.ClientSeed, 4); hmac2.Finalize(); memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength()); @@ -491,11 +491,11 @@ void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u", ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountId); - result->IPv4.emplace_back(realm->ExternalAddress, realm->port); + joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->port); if (realm->ExternalAddress != realm->LocalAddress) - result->IPv4.emplace_back(realm->LocalAddress, realm->port); + joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->port); - AsyncWrite(result); + AsyncWrite(joinResponse); } void Battlenet::Session::ReadHandler() @@ -586,17 +586,17 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke { if (dataStream->GetSize() != 1 + 128 + 32 + 128) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, logonResponse); return false; } if (dataStream->Read(8) != 2) // State { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, logonResponse); return false; } @@ -608,9 +608,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke if (A.isZero()) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, logonResponse); return false; } @@ -684,9 +684,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke stmt->setString(0, _accountName); LoginDatabase.Execute(stmt); - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - ReplaceResponse(response, complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + ReplaceResponse(response, logonResponse); return false; } @@ -699,9 +699,9 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke if (!numAccounts) { - Authentication::LogonResponse* noAccounts = new Authentication::LogonResponse(); - noAccounts->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, noAccounts); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); + ReplaceResponse(response, logonResponse); return false; } @@ -731,8 +731,8 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke password->Data = new uint8[password->DataSize]; memcpy(password->Data, stream.GetBuffer(), password->DataSize); - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(password); + Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); + proofRequest->Modules.push_back(password); if (numAccounts > 1) { BitStream accounts; @@ -757,39 +757,39 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke selectGameAccount->DataSize = accounts.GetSize(); selectGameAccount->Data = new uint8[selectGameAccount->DataSize]; memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize); - request->Modules.push_back(selectGameAccount); + proofRequest->Modules.push_back(selectGameAccount); _modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT); } else { if (fields[4].GetBool()) { - delete request; + delete proofRequest; - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); if (fields[2].GetUInt32() == fields[3].GetUInt32()) { - complete->SetAuthResult(LOGIN_BANNED); + logonResponse->SetAuthResult(LOGIN_BANNED); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } else { - complete->SetAuthResult(LOGIN_SUSPENDED); + logonResponse->SetAuthResult(LOGIN_SUSPENDED); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } - ReplaceResponse(response, complete); + ReplaceResponse(response, logonResponse); return false; } _gameAccountId = fields[0].GetUInt32(); _gameAccountName = fields[1].GetString(); - request->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); + proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); } - ReplaceResponse(response, request); + ReplaceResponse(response, proofRequest); return true; } @@ -797,9 +797,9 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se { if (dataStream->Read(8) != 1) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, logonResponse); return false; } @@ -807,9 +807,9 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se std::string account = dataStream->ReadString(8); if (account.empty()) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); - ReplaceResponse(response, complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT); + ReplaceResponse(response, logonResponse); return false; } @@ -838,28 +838,28 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se Field* fields = result->Fetch(); if (fields[4].GetBool()) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); if (fields[2].GetUInt32() == fields[3].GetUInt32()) { - complete->SetAuthResult(LOGIN_BANNED); + logonResponse->SetAuthResult(LOGIN_BANNED); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } else { - complete->SetAuthResult(LOGIN_SUSPENDED); + logonResponse->SetAuthResult(LOGIN_SUSPENDED); TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } - ReplaceResponse(response, complete); + ReplaceResponse(response, logonResponse); return false; } _gameAccountId = fields[0].GetUInt32(); _gameAccountName = fields[1].GetString(); - Authentication::ProofRequest* request = new Authentication::ProofRequest(); - request->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); - ReplaceResponse(response, request); + Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest(); + proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint")); + ReplaceResponse(response, proofRequest); _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT); return true; @@ -867,16 +867,16 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); if (dataStream->Read(8) == 1) { - complete->AccountId = _accountId; - complete->GameAccountName = _gameAccountName; - complete->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; + logonResponse->AccountId = _accountId; + logonResponse->GameAccountName = _gameAccountName; + logonResponse->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_FAILED_LOGINS); stmt->setUInt32(0, _accountId); if (PreparedQueryResult failedLoginsResult = LoginDatabase.Query(stmt)) - complete->FailedLogins = (*failedLoginsResult)[0].GetUInt32(); + logonResponse->FailedLogins = (*failedLoginsResult)[0].GetUInt32(); SQLTransaction trans = LoginDatabase.BeginTransaction(); @@ -899,9 +899,9 @@ bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, Serv sSessionMgr.AddSession(this); } else - complete->SetAuthResult(AUTH_BAD_VERSION_HASH); + logonResponse->SetAuthResult(AUTH_BAD_VERSION_HASH); - ReplaceResponse(response, complete); + ReplaceResponse(response, logonResponse); return true; } @@ -909,9 +909,9 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* { if (dataStream->Read(8) != 1) { - Authentication::ResumeResponse* complete = new Authentication::ResumeResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); + Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); + resumeResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, resumeResponse); return false; } @@ -954,9 +954,9 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* LoginDatabase.Execute(stmt); TC_LOG_DEBUG("server.battlenet", "[Battlenet::Resume] Invalid proof!"); - Authentication::ResumeResponse* result = new Authentication::ResumeResponse(); - result->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); - ReplaceResponse(response, result); + Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); + resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + ReplaceResponse(response, resumeResponse); return false; } @@ -983,9 +983,9 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* resume->Data = new uint8[resume->DataSize]; memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); - Authentication::ResumeResponse* result = new Authentication::ResumeResponse(); - result->Modules.push_back(resume); - ReplaceResponse(response, result); + Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); + resumeResponse->Modules.push_back(resume); + ReplaceResponse(response, resumeResponse); _authed = true; sSessionMgr.AddSession(this); return true; @@ -993,8 +993,8 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response) { - Authentication::LogonResponse* complete = new Authentication::LogonResponse(); - complete->SetAuthResult(AUTH_CORRUPTED_MODULE); - ReplaceResponse(response, complete); + Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); + logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, logonResponse); return false; } -- cgit v1.2.3 From 0a897616dae34a26af4be516f25cc3c916905340 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 11 Oct 2014 05:33:08 +0200 Subject: Core/SAI: Added new error for wrong target orientation value --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 80ca1b27be4..40f37acf1f7 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -295,6 +295,10 @@ void SmartAIMgr::LoadSmartAIFromDB() bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) { + if (std::abs(e.target.o) > 2 * float(M_PI)) + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has abs(`target.o`) > 2*PI (orientation is expressed in radians)", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE) return true; // AI template has special handling switch (e.GetTargetType()) -- cgit v1.2.3 From 06afdeffcb30f67e8e85eef6488f784b5a9ac12c Mon Sep 17 00:00:00 2001 From: Intra Date: Fri, 10 Oct 2014 19:40:58 +0200 Subject: Adjust random movement wait time and implement variable wait times --- .../game/Movement/MovementGenerators/RandomMovementGenerator.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index dbe8c8b0329..2f40beb9d8d 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -99,7 +99,10 @@ void RandomMovementGenerator::_setRandomLocation(Creature* creature) if (is_air_ok) i_nextMoveTime.Reset(0); else - i_nextMoveTime.Reset(urand(500, 10000)); + if (roll_chance_i(50)) + i_nextMoveTime.Reset(urand(5000, 10000)); + else + i_nextMoveTime.Reset(urand(50, 400)); creature->AddUnitState(UNIT_STATE_ROAMING_MOVE); -- cgit v1.2.3 From 56cf7ff2a8f1e0a710544ec6300a21cfa44c0f73 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 11 Oct 2014 15:13:30 +0200 Subject: Core/Battle.net: Implemented updating realm list after initial login --- src/server/authserver/Realms/RealmList.cpp | 10 +- src/server/authserver/Realms/RealmList.h | 4 +- src/server/bnetserver/Main.cpp | 9 +- src/server/bnetserver/Packets/FriendsPackets.cpp | 22 ++-- src/server/bnetserver/Packets/FriendsPackets.h | 11 +- src/server/bnetserver/Packets/PacketFactory.h | 5 +- src/server/bnetserver/Packets/WoWRealmPackets.cpp | 20 +++- src/server/bnetserver/Packets/WoWRealmPackets.h | 21 +++- src/server/bnetserver/Realms/RealmList.cpp | 133 +++++++++++++--------- src/server/bnetserver/Realms/RealmList.h | 74 ++++++------ src/server/bnetserver/Server/Session.cpp | 110 +++++++++++------- src/server/bnetserver/Server/Session.h | 15 +++ src/server/bnetserver/Server/SessionManager.cpp | 12 ++ src/server/bnetserver/Server/SessionManager.h | 20 +++- src/server/bnetserver/bnetserver.conf.dist | 4 +- 15 files changed, 283 insertions(+), 187 deletions(-) (limited to 'src/server') diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp index 662a015dc65..15302c74ac6 100644 --- a/src/server/authserver/Realms/RealmList.cpp +++ b/src/server/authserver/Realms/RealmList.cpp @@ -77,7 +77,7 @@ void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInte } void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr, - ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup) + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build) { // Create new if not exist or update existed Realm& realm = m_realms[name]; @@ -90,15 +90,11 @@ void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address cons realm.allowedSecurityLevel = allowedSecurityLevel; realm.populationLevel = population; - // Append port to IP address. - realm.ExternalAddress = address; realm.LocalAddress = localAddr; realm.LocalSubnetMask = localSubmask; realm.port = port; realm.gamebuild = build; - realm.Region = region; - realm.Battlegroup = battlegroup; } void RealmList::UpdateIfNeed() @@ -174,11 +170,9 @@ void RealmList::UpdateRealms(bool init) uint8 allowedSecurityLevel = fields[9].GetUInt8(); float pop = fields[10].GetFloat(); uint32 build = fields[11].GetUInt32(); - uint8 region = fields[12].GetUInt8(); - uint8 battlegroup = fields[13].GetUInt8(); UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, - (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup); + (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build); if (init) TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port); diff --git a/src/server/authserver/Realms/RealmList.h b/src/server/authserver/Realms/RealmList.h index f7a98cda686..9d5771144a9 100644 --- a/src/server/authserver/Realms/RealmList.h +++ b/src/server/authserver/Realms/RealmList.h @@ -54,8 +54,6 @@ struct Realm AccountTypes allowedSecurityLevel; float populationLevel; uint32 gamebuild; - uint8 Region; - uint8 Battlegroup; ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const; }; @@ -89,7 +87,7 @@ private: void UpdateRealms(bool init = false); void UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr, - ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup); + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build); RealmMap m_realms; uint32 m_UpdateInterval; diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index e208f3cd1d9..5e0d728d724 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -99,14 +99,7 @@ int main(int argc, char** argv) return 1; // Get the list of realms for the server - sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20)); - - if (sRealmList->size() == 0) - { - TC_LOG_ERROR("server.bnetserver", "No valid realms specified."); - StopDB(); - return 1; - } + sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10)); // Start the listening port (acceptor) for auth connections int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119); diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp index 784d6980777..cd920e91c9c 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -18,23 +18,22 @@ #include "Session.h" #include "FriendsPackets.h" -void Battlenet::Friends::SocialnetworkCheckConnected::Read() +void Battlenet::Friends::SocialNetworkCheckConnected::Read() { SocialNetworkId = _stream.Read(32); } -std::string Battlenet::Friends::SocialnetworkCheckConnected::ToString() const +std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const { - return "Battlenet::Friends::SocialnetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); + return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); } -void Battlenet::Friends::SocialnetworkCheckConnected::CallHandler(Session* session) const +void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session) const { - SocialNetworkCheckConnectedResult* result = new SocialNetworkCheckConnectedResult(SocialNetworkId); - session->AsyncWrite(result); + session->HandleSocialNetworkCheckConnected(*this); } -void Battlenet::Friends::SocialnetworkConnect::Read() +void Battlenet::Friends::SocialNetworkConnect::Read() { int32 unk1 = _stream.Read(32); uint32 size1 = _stream.Read(9); @@ -43,12 +42,12 @@ void Battlenet::Friends::SocialnetworkConnect::Read() auto data2 = _stream.ReadBytes(size2); } -std::string Battlenet::Friends::SocialnetworkConnect::ToString() const +std::string Battlenet::Friends::SocialNetworkConnect::ToString() const { - return "Battlenet::Friends::SocialnetworkConnect"; + return "Battlenet::Friends::SocialNetworkConnect"; } -void Battlenet::Friends::SocialnetworkConnect::CallHandler(Session* session) const +void Battlenet::Friends::SocialNetworkConnect::CallHandler(Session* session) const { session->LogUnhandledPacket(*this); } @@ -70,8 +69,7 @@ std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() co void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() { _stream.Write(0, 23); // Ignored - volatile uint16 res = 0; - _stream.Write(res, 16); // Unknown + _stream.Write(0, 16); // Unknown _stream.Write(SocialNetworkId, 32); } diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h index a0ef6f4a63f..ec20f202098 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.h +++ b/src/server/bnetserver/Packets/FriendsPackets.h @@ -54,10 +54,10 @@ namespace Battlenet SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented }; - class SocialnetworkConnect final : public ClientPacket + class SocialNetworkConnect final : public ClientPacket { public: - SocialnetworkConnect(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + SocialNetworkConnect(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS) && "Invalid packet header for SocialnetworkConnect"); } @@ -78,10 +78,10 @@ namespace Battlenet std::string ToString() const override; }; - class SocialnetworkCheckConnected final : public ClientPacket + class SocialNetworkCheckConnected final : public ClientPacket { public: - SocialnetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + SocialNetworkCheckConnected(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS) && "Invalid packet header for SocialNetworkCheckConnected"); } @@ -96,7 +96,8 @@ namespace Battlenet class SocialNetworkCheckConnectedResult final : public ServerPacket { public: - SocialNetworkCheckConnectedResult(uint32 socialNetworkId) : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), SocialNetworkId(socialNetworkId) + SocialNetworkCheckConnectedResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), + SocialNetworkId(0) { } diff --git a/src/server/bnetserver/Packets/PacketFactory.h b/src/server/bnetserver/Packets/PacketFactory.h index 4ae6338cfd7..418e56abea4 100644 --- a/src/server/bnetserver/Packets/PacketFactory.h +++ b/src/server/bnetserver/Packets/PacketFactory.h @@ -57,10 +57,11 @@ namespace Battlenet _creators[PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION)] = &New; _creators[PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM)] = &New; + _creators[PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM)] = &New; _creators[PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM)] = &New; - _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS)] = &New; - _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS)] = &New; + _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS)] = &New; + _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS)] = &New; _creators[PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS)] = &New; _creators[PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS)] = &New; diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp index 6845fc914b1..95176963c18 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.cpp +++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp @@ -30,6 +30,16 @@ void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) co session->HandleListSubscribeRequest(*this); } +std::string Battlenet::WoWRealm::ListUnsubscribe::ToString() const +{ + return "Battlenet::WoWRealm::ListUnsubscribe"; +} + +void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session) const +{ + session->HandleListUnsubscribe(*this); +} + Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse() { for (ServerPacket* realmData : RealmData) @@ -95,7 +105,7 @@ void Battlenet::WoWRealm::ListUpdate::Write() if (!Version.empty()) { _stream.WriteString(Version, 5); - _stream.Write(Build, 32); + _stream.Write(Id.Build, 32); boost::asio::ip::address_v4::bytes_type ip = Address.address().to_v4().to_bytes(); uint16 port = Address.port(); @@ -110,16 +120,16 @@ void Battlenet::WoWRealm::ListUpdate::Write() _stream.WriteString(Name, 10); } - _stream.Write(Battlegroup, 8); - _stream.Write(Index, 32); - _stream.Write(Region, 8); + _stream.Write(Id.Battlegroup, 8); + _stream.Write(Id.Index, 32); + _stream.Write(Id.Region, 8); } std::string Battlenet::WoWRealm::ListUpdate::ToString() const { std::ostringstream stream; stream << "Battlenet::WoWRealm::ListUpdate Timezone " << Timezone << " Population " << Population << " Lock " << uint32(Lock) << " Type " << Type << " Name " << Name - << " Flags " << uint32(Flags) << " Region " << uint32(Region) << " Battlegroup " << uint32(Battlegroup) << " Index " << Index; + << " Flags " << uint32(Flags) << " Region " << uint32(Id.Region) << " Battlegroup " << uint32(Id.Battlegroup) << " Index " << Id.Index; if (!Version.empty()) stream << " Version " << Version; diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h index 4ce5ea68835..a27601f7478 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.h +++ b/src/server/bnetserver/Packets/WoWRealmPackets.h @@ -53,6 +53,19 @@ namespace Battlenet void CallHandler(Session* session) const override; }; + class ListUnsubscribe final : public ClientPacket + { + public: + ListUnsubscribe(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_LIST_UNSUBSCRIBE, WOWREALM) && "Invalid packet header for ListUnsubscribe"); + } + + void Read() override { } + std::string ToString() const override; + void CallHandler(Session* session) const override; + }; + class JoinRequestV2 final : public ClientPacket { public: @@ -110,8 +123,7 @@ namespace Battlenet }; ListUpdate() : ServerPacket(PacketHeader(SMSG_LIST_UPDATE, WOWREALM)), UpdateState(UPDATE), - Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), - Flags(0), Region(0), Battlegroup(0), Index(0), Build(0) + Timezone(0), Population(0.0f), Lock(0), Type(0), Name(""), Version(""), Flags(0) { } @@ -127,10 +139,7 @@ namespace Battlenet std::string Version; tcp::endpoint Address; uint8 Flags; - uint8 Region; - uint8 Battlegroup; - uint32 Index; - uint32 Build; + RealmId Id; }; class ListComplete final : public ServerPacket diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp index 60d40f98edf..6e2c1e99e56 100644 --- a/src/server/bnetserver/Realms/RealmList.cpp +++ b/src/server/bnetserver/Realms/RealmList.cpp @@ -18,9 +18,10 @@ #include #include "Common.h" -#include "RealmList.h" #include "Database/DatabaseEnv.h" +#include "SessionManager.h" #include "Util.h" +#include "RealmList.h" ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const { @@ -51,73 +52,71 @@ ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) cons realmIp = ExternalAddress; } - ip::tcp::endpoint endpoint(realmIp, port); + ip::tcp::endpoint endpoint(realmIp, Port); // Return external IP return endpoint; } -RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL)), _resolver(nullptr) +RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr) { } RealmList::~RealmList() { + delete _updateTimer; delete _resolver; } // Load the realm list from the database void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval) { + _updateInterval = updateInterval; + _updateTimer = new boost::asio::deadline_timer(ioService); _resolver = new boost::asio::ip::tcp::resolver(ioService); - m_UpdateInterval = updateInterval; // Get the content of the realmlist table in the database - UpdateRealms(true); + UpdateRealms(boost::system::error_code()); } -void RealmList::UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr, - ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup) +template +inline void UpdateField(FieldType& out, FieldType const& in, bool& changed) { - // Create new if not exist or update existed - Realm& realm = m_realms[name]; - - realm.m_ID = id; - realm.name = name; - realm.icon = icon; - realm.flag = flag; - realm.timezone = timezone; - realm.allowedSecurityLevel = allowedSecurityLevel; - realm.populationLevel = population; - - // Append port to IP address. - - realm.ExternalAddress = address; - realm.LocalAddress = localAddr; - realm.LocalSubnetMask = localSubmask; - realm.port = port; - realm.gamebuild = build; - realm.Region = region; - realm.Battlegroup = battlegroup; + if (out != in) + { + out = in; + changed = true; + } } -void RealmList::UpdateIfNeed() +void RealmList::UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr, + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, + float population) { - // maybe disabled or updated recently - if (!m_UpdateInterval || m_NextUpdateTime > time(NULL)) - return; - - m_NextUpdateTime = time(NULL) + m_UpdateInterval; - - // Clears Realm list - m_realms.clear(); - - // Get the content of the realmlist table in the database - UpdateRealms(); + // Create new if not exist or update existed + Realm& realm = _realms[id]; + + realm.Keep = true; + realm.Updated = false; + + realm.Id = id; + UpdateField(realm.Name, name, realm.Updated); + UpdateField(realm.Type, icon, realm.Updated); + UpdateField(realm.Flags, flag, realm.Updated); + UpdateField(realm.Timezone, timezone, realm.Updated); + UpdateField(realm.AllowedSecurityLevel, allowedSecurityLevel, realm.Updated); + UpdateField(realm.PopulationLevel, population, realm.Updated); + UpdateField(realm.ExternalAddress, address, realm.Updated); + UpdateField(realm.LocalAddress, localAddr, realm.Updated); + UpdateField(realm.LocalSubnetMask, localSubmask, realm.Updated); + UpdateField(realm.Port, port, realm.Updated); } -void RealmList::UpdateRealms(bool init) +void RealmList::UpdateRealms(boost::system::error_code const& error) { + if (error) + return; + TC_LOG_INFO("server.authserver", "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); @@ -133,7 +132,6 @@ void RealmList::UpdateRealms(bool init) boost::asio::ip::tcp::resolver::iterator end; Field* fields = result->Fetch(); - uint32 realmId = fields[0].GetUInt32(); std::string name = fields[1].GetString(); boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), ""); @@ -142,7 +140,7 @@ void RealmList::UpdateRealms(bool init) if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str()); - return; + continue; } ip::address externalAddress = (*endPoint).endpoint().address(); @@ -152,7 +150,7 @@ void RealmList::UpdateRealms(bool init) if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str()); - return; + continue; } ip::address localAddress = (*endPoint).endpoint().address(); @@ -162,7 +160,7 @@ void RealmList::UpdateRealms(bool init) if (endPoint == end || ec) { TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str()); - return; + continue; } ip::address localSubmask = (*endPoint).endpoint().address(); @@ -173,15 +171,17 @@ void RealmList::UpdateRealms(bool init) uint8 timezone = fields[8].GetUInt8(); uint8 allowedSecurityLevel = fields[9].GetUInt8(); float pop = fields[10].GetFloat(); + uint32 realmId = fields[0].GetUInt32(); uint32 build = fields[11].GetUInt32(); uint8 region = fields[12].GetUInt8(); uint8 battlegroup = fields[13].GetUInt8(); - UpdateRealm(realmId, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, - (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop, build, region, battlegroup); + Battlenet::RealmId id{ region, battlegroup, realmId, build }; - if (init) - TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[name].ExternalAddress.to_string().c_str(), port); + UpdateRealm(id, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, + (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); + + //TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[id].ExternalAddress.to_string().c_str(), port); } catch (std::exception& ex) { @@ -191,16 +191,41 @@ void RealmList::UpdateRealms(bool init) } while (result->NextRow()); } + + std::vector updatedRealms; + std::vector deletedRealms; + + for (RealmMap::value_type const& pair : _realms) + { + if (pair.second.Updated) + updatedRealms.push_back(&pair.second); + if (!pair.second.Keep) + deletedRealms.push_back(pair.first); + } + + for (Battlenet::RealmId const& deleted : deletedRealms) + _realms.erase(deleted); + + if (!updatedRealms.empty() || !deletedRealms.empty()) + { + sSessionMgr.LockedForEach([&updatedRealms, &deletedRealms](Battlenet::Session* session) + { + if (session->IsSubscribedToRealmListUpdates()) + session->UpdateRealms(updatedRealms, deletedRealms); + }); + } + + if (_updateInterval) + { + _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval)); + _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1)); + } } Realm const* RealmList::GetRealm(Battlenet::RealmId const& id) const { - auto itr = std::find_if(m_realms.begin(), m_realms.end(), [id](RealmMap::value_type const& pair) - { - return pair.second.Region == id.Region && pair.second.Battlegroup == id.Battlegroup && pair.second.m_ID == id.Index; - }); - - if (itr != m_realms.end()) + auto itr = _realms.find(id); + if (itr != _realms.end()) return &itr->second; return NULL; diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h index 502fef80ee7..c7108101056 100644 --- a/src/server/bnetserver/Realms/RealmList.h +++ b/src/server/bnetserver/Realms/RealmList.h @@ -39,43 +39,55 @@ enum RealmFlags REALM_FLAG_FULL = 0x80 }; -// Storage object for a realm -struct Realm -{ - ip::address ExternalAddress; - ip::address LocalAddress; - ip::address LocalSubnetMask; - uint16 port; - std::string name; - uint8 icon; - RealmFlags flag; - uint8 timezone; - uint32 m_ID; - AccountTypes allowedSecurityLevel; - float populationLevel; - uint32 gamebuild; - uint8 Region; - uint8 Battlegroup; - - ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const; -}; +#pragma pack(push, 1) namespace Battlenet { struct RealmId { + RealmId() : Region(0), Battlegroup(0), Index(0), Build(0) { } + RealmId(uint8 region, uint8 battlegroup, uint32 index, uint32 build) + : Region(region), Battlegroup(battlegroup), Index(index), Build(build) { } + uint8 Region; uint8 Battlegroup; uint32 Index; uint32 Build; + + bool operator<(RealmId const& r) const + { + return memcmp(this, &r, sizeof(RealmId) - sizeof(Build)) < 0; + } }; } +#pragma pack(pop) + +// Storage object for a realm +struct Realm +{ + Battlenet::RealmId Id; + ip::address ExternalAddress; + ip::address LocalAddress; + ip::address LocalSubnetMask; + uint16 Port; + std::string Name; + uint8 Type; + RealmFlags Flags; + uint8 Timezone; + AccountTypes AllowedSecurityLevel; + float PopulationLevel; + bool Updated; + bool Keep; + + ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const; +}; + /// Storage object for the list of realms on the server class RealmList { public: - typedef std::map RealmMap; + typedef std::map RealmMap; static RealmList* instance() { @@ -87,25 +99,19 @@ public: void Initialize(boost::asio::io_service& ioService, uint32 updateInterval); - void UpdateIfNeed(); - - void AddRealm(const Realm& NewRealm) { m_realms[NewRealm.name] = NewRealm; } - - RealmMap::const_iterator begin() const { return m_realms.begin(); } - RealmMap::const_iterator end() const { return m_realms.end(); } - uint32 size() const { return m_realms.size(); } + RealmMap const& GetRealms() const { return _realms; } Realm const* GetRealm(Battlenet::RealmId const& id) const; private: RealmList(); - void UpdateRealms(bool init = false); - void UpdateRealm(uint32 id, const std::string& name, ip::address const& address, ip::address const& localAddr, - ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population, uint32 build, uint8 region, uint8 battlegroup); + void UpdateRealms(boost::system::error_code const& error); + void UpdateRealm(Battlenet::RealmId const& id, const std::string& name, ip::address const& address, ip::address const& localAddr, + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population); - RealmMap m_realms; - uint32 m_UpdateInterval; - time_t m_NextUpdateTime; + RealmMap _realms; + uint32 _updateInterval; + boost::asio::deadline_timer* _updateTimer; boost::asio::ip::tcp::resolver* _resolver; }; diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 1d8e0136af3..301a6b9bae1 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -38,7 +38,7 @@ Battlenet::Session::ModuleHandler const Battlenet::Session::ModuleHandlers[MODUL Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _accountId(0), _accountName(), _locale(), _os(), _build(0), _gameAccountId(0), _gameAccountName(), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), - _reconnectProof(), _crypt(), _authed(false) + _reconnectProof(), _crypt(), _authed(false), _subscribedToRealmListUpdates(false) { static uint8 const N_Bytes[] = { @@ -398,8 +398,6 @@ void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /* void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/) { - sRealmList->UpdateIfNeed(); - WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse(); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS); @@ -411,58 +409,29 @@ void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeReque { Field* fields = countResult->Fetch(); uint32 build = fields[4].GetUInt32(); - listSubscribeResponse->CharacterCounts.push_back({ { fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0) }, fields[0].GetUInt8() }); + listSubscribeResponse->CharacterCounts.push_back({ RealmId(fields[2].GetUInt8(), fields[3].GetUInt8(), fields[1].GetUInt32(), (_build != build ? build : 0)), fields[0].GetUInt8() }); } while (countResult->NextRow()); } - for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) - { - Realm const& realm = i->second; - - uint32 flag = realm.flag & ~REALM_FLAG_SPECIFYBUILD; - RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild); - if (realm.gamebuild != _build) - { - flag |= REALM_FLAG_INVALID; - if (buildInfo) - flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for - } - - WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); - listUpdate->Timezone = realm.timezone; - listUpdate->Population = realm.populationLevel; - listUpdate->Lock = (realm.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; - listUpdate->Type = realm.icon; - listUpdate->Name = realm.name; - - if (flag & REALM_FLAG_SPECIFYBUILD) - { - std::ostringstream version; - version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; - - listUpdate->Version = version.str(); - listUpdate->Address = realm.GetAddressForClient(GetRemoteIpAddress()); - listUpdate->Build = buildInfo->Build; - } - - listUpdate->Flags = flag; - listUpdate->Region = realm.Region; - listUpdate->Battlegroup = realm.Battlegroup; - listUpdate->Index = realm.m_ID; - - listSubscribeResponse->RealmData.push_back(listUpdate); - } + for (RealmList::RealmMap::value_type const& i : sRealmList->GetRealms()) + listSubscribeResponse->RealmData.push_back(BuildListUpdate(&i.second)); listSubscribeResponse->RealmData.push_back(new WoWRealm::ListComplete()); AsyncWrite(listSubscribeResponse); + _subscribedToRealmListUpdates = true; +} + +void Battlenet::Session::HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& /*listUnsubscribe*/) +{ + _subscribedToRealmListUpdates = false; } void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest) { WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2(); Realm const* realm = sRealmList->GetRealm(joinRequest.Realm); - if (!realm || realm->flag & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE)) + if (!realm || realm->Flags & (REALM_FLAG_INVALID | REALM_FLAG_OFFLINE)) { joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE; AsyncWrite(joinResponse); @@ -491,13 +460,20 @@ void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& join LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u", ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountId); - joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->port); + joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->Port); if (realm->ExternalAddress != realm->LocalAddress) - joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->port); + joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->Port); AsyncWrite(joinResponse); } +void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected) +{ + Friends::SocialNetworkCheckConnectedResult* socialNetworkCheckConnectedResult = new Friends::SocialNetworkCheckConnectedResult(); + socialNetworkCheckConnectedResult->SocialNetworkId = socialNetworkCheckConnected.SocialNetworkId; + AsyncWrite(socialNetworkCheckConnectedResult); +} + void Battlenet::Session::ReadHandler() { BitStream stream(std::move(GetReadBuffer())); @@ -998,3 +974,49 @@ bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket ReplaceResponse(response, logonResponse); return false; } + +void Battlenet::Session::UpdateRealms(std::vector& realms, std::vector& deletedRealms) +{ + for (Realm const* realm : realms) + AsyncWrite(BuildListUpdate(realm)); + + for (RealmId& deleted : deletedRealms) + { + WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); + listUpdate->UpdateState = WoWRealm::ListUpdate::DELETED; + listUpdate->Id = deleted; + AsyncWrite(listUpdate); + } +} + +Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const* realm) const +{ + uint32 flag = realm->Flags & ~REALM_FLAG_SPECIFYBUILD; + RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm->Id.Build); + if (realm->Id.Build != _build) + { + flag |= REALM_FLAG_INVALID; + if (buildInfo) + flag |= REALM_FLAG_SPECIFYBUILD; // tell the client what build the realm is for + } + + WoWRealm::ListUpdate* listUpdate = new WoWRealm::ListUpdate(); + listUpdate->Timezone = realm->Timezone; + listUpdate->Population = realm->PopulationLevel; + listUpdate->Lock = (realm->AllowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; + listUpdate->Type = realm->Type; + listUpdate->Name = realm->Name; + + if (flag & REALM_FLAG_SPECIFYBUILD) + { + std::ostringstream version; + version << buildInfo->MajorVersion << '.' << buildInfo->MinorVersion << '.' << buildInfo->BugfixVersion << '.' << buildInfo->Build; + + listUpdate->Version = version.str(); + listUpdate->Address = realm->GetAddressForClient(GetRemoteIpAddress()); + } + + listUpdate->Flags = flag; + listUpdate->Id = realm->Id; + return listUpdate; +} diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 41caadbab3f..7def3c70460 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -25,6 +25,7 @@ #include #include +struct Realm; using boost::asio::ip::tcp; namespace Battlenet @@ -73,12 +74,23 @@ namespace Battlenet // WoWRealm void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest); + void HandleListUnsubscribe(WoWRealm::ListUnsubscribe const& listUnsubscribe); void HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest); + // Friends + void HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected); + void Start() override; + void UpdateRealms(std::vector& realms, std::vector& deletedRealms); + void AsyncWrite(ServerPacket* packet); + uint32 GetAccountId() const { return _accountId; } + uint32 GetGameAccountId() const { return _gameAccountId; } + + bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; } + protected: void ReadHandler() override; @@ -94,6 +106,8 @@ namespace Battlenet bool HandleResumeModule(BitStream* dataStream, ServerPacket** response); bool UnhandledModule(BitStream* dataStream, ServerPacket** response); + WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const; + uint32 _accountId; std::string _accountName; std::string _locale; @@ -121,6 +135,7 @@ namespace Battlenet PacketCrypt _crypt; bool _authed; + bool _subscribedToRealmListUpdates; }; } diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp index d8b6bfca8d1..caa17364038 100644 --- a/src/server/bnetserver/Server/SessionManager.cpp +++ b/src/server/bnetserver/Server/SessionManager.cpp @@ -35,3 +35,15 @@ void Battlenet::SessionManager::OnSocketAccept(tcp::socket&& sock) { sSessionMgr.OnSocketOpen(std::forward(sock)); } + +void Battlenet::SessionManager::AddSession(Session* session) +{ + std::unique_lock lock(_sessionMutex); + _sessions[{ session->GetAccountId(), session->GetGameAccountId() }] = session; +} + +void Battlenet::SessionManager::RemoveSession(Session* session) +{ + std::unique_lock lock(_sessionMutex); + _sessions.erase({ session->GetAccountId(), session->GetGameAccountId() }); +} diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h index 10e7196e4d8..4f8e0d9fa97 100644 --- a/src/server/bnetserver/Server/SessionManager.h +++ b/src/server/bnetserver/Server/SessionManager.h @@ -20,6 +20,8 @@ #include "Session.h" #include "SocketMgr.h" +#include +#include namespace Battlenet { @@ -28,7 +30,7 @@ namespace Battlenet struct SessionInfo { uint32 AccountId; - uint32 GameAccountIndex; + uint32 GameAccountId; bool operator<(SessionInfo const& right) const { @@ -41,6 +43,7 @@ namespace Battlenet class SessionManager : SocketMgr { typedef SocketMgr BaseSocketMgr; + typedef std::map SessionMap; public: static SessionManager& Instance() @@ -52,9 +55,17 @@ namespace Battlenet bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) override; // noop for now, will be needed later to broadcast realmlist updates for example - void AddSession(Session* /*session*/) { } + void AddSession(Session* /*session*/); - void RemoveSession(Session* /*session*/) { } + void RemoveSession(Session* /*session*/); + + template + void LockedForEach(Iterator iterator) + { + boost::shared_lock lock(_sessionMutex); + for (SessionMap::value_type const& pair : _sessions) + iterator(pair.second); + } protected: NetworkThread* CreateThreads() const override; @@ -62,7 +73,8 @@ namespace Battlenet private: static void OnSocketAccept(tcp::socket&& sock); - std::map _sessions; + SessionMap _sessions; + boost::shared_mutex _sessionMutex; }; } diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist index 2ca57cea20c..ac02a06c918 100644 --- a/src/server/bnetserver/bnetserver.conf.dist +++ b/src/server/bnetserver/bnetserver.conf.dist @@ -91,10 +91,10 @@ ProcessPriority = 0 # # RealmsStateUpdateDelay # Description: Time (in seconds) between realm list updates. -# Default: 20 - (Enabled) +# Default: 10 # 0 - (Disabled) -RealmsStateUpdateDelay = 20 +RealmsStateUpdateDelay = 10 # # WrongPass.MaxCount -- cgit v1.2.3 From 26e4b67e851d92475e603e7073b2558427c6d23f Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 11 Oct 2014 15:16:06 +0200 Subject: Core/Battle.net: Removed remaining authserver references --- src/server/bnetserver/CMakeLists.txt | 2 +- src/server/bnetserver/Main.cpp | 15 +++++++-------- src/server/bnetserver/Realms/RealmList.cpp | 14 +++++++------- 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'src/server') diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt index 3fa4abf034a..9d99ac7f0c5 100644 --- a/src/server/bnetserver/CMakeLists.txt +++ b/src/server/bnetserver/CMakeLists.txt @@ -8,7 +8,7 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -########### authserver ############### +########### bnetserver ############### file(GLOB_RECURSE sources_authentication Authentication/*.cpp Authentication/*.h) file(GLOB_RECURSE sources_realms Realms/*.cpp Realms/*.h) diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index 5e0d728d724..ff891304bd3 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -81,7 +81,7 @@ int main(int argc, char** argv) TC_LOG_INFO("server.bnetserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); TC_LOG_INFO("server.bnetserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); - // authserver PID file creation + // bnetserver PID file creation std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); if (!pidFile.empty()) { @@ -151,32 +151,31 @@ bool StartDB() std::string dbstring = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); if (dbstring.empty()) { - TC_LOG_ERROR("server.authserver", "Database not specified"); + TC_LOG_ERROR("server.bnetserver", "Database not specified"); return false; } int32 worker_threads = sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1); if (worker_threads < 1 || worker_threads > 32) { - TC_LOG_ERROR("server.authserver", "Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1."); + TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.WorkerThreads, defaulting to 1."); worker_threads = 1; } int32 synch_threads = sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1); if (synch_threads < 1 || synch_threads > 32) { - TC_LOG_ERROR("server.authserver", "Improper value specified for LoginDatabase.SynchThreads, defaulting to 1."); + TC_LOG_ERROR("server.bnetserver", "Improper value specified for LoginDatabase.SynchThreads, defaulting to 1."); synch_threads = 1; } - // NOTE: While authserver is singlethreaded you should keep synch_threads == 1. Increasing it is just silly since only 1 will be used ever. if (!LoginDatabase.Open(dbstring, uint8(worker_threads), uint8(synch_threads))) { - TC_LOG_ERROR("server.authserver", "Cannot connect to database"); + TC_LOG_ERROR("server.bnetserver", "Cannot connect to database"); return false; } - TC_LOG_INFO("server.authserver", "Started auth database connection pool."); + TC_LOG_INFO("server.bnetserver", "Started auth database connection pool."); sLog->SetRealmId(0); // Enables DB appenders when realm is set. return true; } @@ -198,7 +197,7 @@ void KeepDatabaseAliveHandler(const boost::system::error_code& error) { if (!error) { - TC_LOG_INFO("server.authserver", "Ping MySQL to keep connection alive"); + TC_LOG_INFO("server.bnetserver", "Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp index 6e2c1e99e56..8d6edb12b5c 100644 --- a/src/server/bnetserver/Realms/RealmList.cpp +++ b/src/server/bnetserver/Realms/RealmList.cpp @@ -35,7 +35,7 @@ ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) cons realmIp = clientAddr; else { - // Assume that user connecting from the machine that authserver is located on + // Assume that user connecting from the machine that bnetserver is located on // has all realms available in his local network realmIp = LocalAddress; } @@ -117,7 +117,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) if (error) return; - TC_LOG_INFO("server.authserver", "Updating Realm List..."); + TC_LOG_INFO("server.bnetserver", "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); @@ -139,7 +139,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); if (endPoint == end || ec) { - TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[2].GetString().c_str()); + TC_LOG_ERROR("server.bnetserver", "Could not resolve address %s", fields[2].GetString().c_str()); continue; } @@ -149,7 +149,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) endPoint = _resolver->resolve(localAddressQuery, ec); if (endPoint == end || ec) { - TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[3].GetString().c_str()); + TC_LOG_ERROR("server.bnetserver", "Could not resolve address %s", fields[3].GetString().c_str()); continue; } @@ -159,7 +159,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) endPoint = _resolver->resolve(localSubmaskQuery, ec); if (endPoint == end || ec) { - TC_LOG_ERROR("server.authserver", "Could not resolve address %s", fields[4].GetString().c_str()); + TC_LOG_ERROR("server.bnetserver", "Could not resolve address %s", fields[4].GetString().c_str()); continue; } @@ -181,11 +181,11 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) UpdateRealm(id, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); - //TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[id].ExternalAddress.to_string().c_str(), port); + //TC_LOG_INFO("server.bnetserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[id].ExternalAddress.to_string().c_str(), port); } catch (std::exception& ex) { - TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); + TC_LOG_ERROR("server.bnetserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); ASSERT(false); } } -- cgit v1.2.3 From 90a2acfbdf4865130e031fe53625d8b91aff3d76 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sat, 11 Oct 2014 18:52:01 +0200 Subject: Core/SAI: changed multiple validation checks --- src/server/game/AI/SmartScripts/SmartScript.cpp | 49 +++---- src/server/game/AI/SmartScripts/SmartScript.h | 15 --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 141 ++++++++++----------- src/server/game/AI/SmartScripts/SmartScriptMgr.h | 38 ++++-- 4 files changed, 115 insertions(+), 128 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index b877a4ca2c0..f3060972288 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -83,13 +83,13 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3 { for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i) { - SMART_EVENT eventType = SMART_EVENT((*i).GetEventType()); + SMART_EVENT eventType = SMART_EVENT(i->GetEventType()); if (eventType == SMART_EVENT_LINK)//special handling continue; - if (eventType == e/* && (!(*i).event.event_phase_mask || IsInPhase((*i).event.event_phase_mask)) && !((*i).event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && (*i).runOnce)*/) + if (eventType == e /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/) { - ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type); + ConditionList conds = sConditionMgr->GetConditionsForSmartEvent(i->entryOrGuid, i->event_id, i->source_type); ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject()); if (sConditionMgr->IsObjectMeetToConditions(info, conds)) @@ -167,7 +167,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { if (IsCreature(*itr)) - sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker())? GetLastInvoker() : 0); + sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0); else if (IsPlayer(*itr) && me) { Unit* templastInvoker = GetLastInvoker(); @@ -2252,8 +2252,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (e.link && e.link != e.event_id) { - SmartScriptHolder linked = FindLinkedEvent(e.link); - if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK) + SmartScriptHolder& linked = SmartAIMgr::FindLinkedEvent(mEvents, e.link); + if (linked) ProcessEvent(linked, unit, var0, var1, bvar, spell, gob); else TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link); @@ -2461,7 +2461,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (me && me->GetGUID() == (*itr)->GetGUID()) continue; - if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist)) + if ((!e.target.unitRange.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(*itr, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist))) l->push_back(*itr); } @@ -2480,7 +2480,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (me && me->GetGUID() == (*itr)->GetGUID()) continue; - if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature) + if (!e.target.unitDistance.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) l->push_back(*itr); } @@ -2499,7 +2499,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (go && go->GetGUID() == (*itr)->GetGUID()) continue; - if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry) + if (!e.target.goDistance.entry || (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) l->push_back(*itr); } @@ -2518,7 +2518,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (go && go->GetGUID() == (*itr)->GetGUID()) continue; - if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist)) + if ((!e.target.goRange.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(*itr, float(e.target.goRange.minDist), float(e.target.goRange.maxDist))) l->push_back(*itr); } @@ -2527,32 +2527,28 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* } case SMART_TARGET_CREATURE_GUID: { - Creature* target = NULL; if (!scriptTrigger && !baseObject) { TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker"); break; } - target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid); - - if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)) - l->push_back(target); + if (Creature* target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid)) + if (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry) + l->push_back(target); break; } case SMART_TARGET_GAMEOBJECT_GUID: { - GameObject* target = NULL; if (!scriptTrigger && !baseObject) { TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker"); break; } - target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid); - - if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)) - l->push_back(target); + if (GameObject* target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid)) + if (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry) + l->push_back(target); break; } case SMART_TARGET_PLAYER_RANGE: @@ -2591,26 +2587,21 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* } case SMART_TARGET_CLOSEST_CREATURE: { - Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead); - if (target) + if (Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead)) l->push_back(target); break; } case SMART_TARGET_CLOSEST_GAMEOBJECT: { - GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100)); - if (target) + if (GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100))) l->push_back(target); break; } case SMART_TARGET_CLOSEST_PLAYER: { if (me) - { - Player* target = me->SelectNearestPlayer((float)e.target.playerDistance.dist); - if (target) + if (Player* target = me->SelectNearestPlayer(float(e.target.playerDistance.dist))) l->push_back(target); - } break; } case SMART_TARGET_OWNER_OR_SUMMONER: @@ -2643,7 +2634,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (me) if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0)) l->push_back(target); - break; } case SMART_TARGET_CLOSEST_FRIENDLY: @@ -2651,7 +2641,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* if (me) if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0)) l->push_back(target); - break; } case SMART_TARGET_POSITION: diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 02bc1a2b487..b59b62c5697 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -257,21 +257,6 @@ class SmartScript } } } - SmartScriptHolder FindLinkedEvent(uint32 link) - { - if (!mEvents.empty()) - { - for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i) - { - if (i->event_id == link) - { - return (*i); - } - } - } - SmartScriptHolder s; - return s; - } }; #endif diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 40f37acf1f7..e8742b6cdef 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -91,7 +91,6 @@ void SmartWaypointMgr::LoadFromDB() while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u SmartAI waypoint paths (total %u waypoints) in %u ms", count, total, GetMSTimeDiffToNow(oldMSTime)); - } SmartWaypointMgr::~SmartWaypointMgr() @@ -192,23 +191,23 @@ void SmartAIMgr::LoadSmartAIFromDB() } else { - CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid))); + CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid))); if (!creature) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid))); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid))); continue; } CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id); if (!creatureInfo) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid))); continue; } if (creatureInfo->AIName != "SmartAI") { - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid))); continue; } } @@ -263,26 +262,29 @@ void SmartAIMgr::LoadSmartAIFromDB() } while (result->NextRow()); - // TO-DO: Find better way - for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; i++) + // Post Loading Validation + for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; ++i) { - for (auto itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr) + for (SmartAIEventMap::iterator itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr) { - for (auto e : mEventMap[i][itr->first]) + for (SmartScriptHolder const& e : itr->second) { - bool found = false; - if (e.link && e.link != e.event_id) + if (e.link) { - for (auto linked : mEventMap[i][itr->first]) + if (!FindLinkedEvent(itr->second, e.link)) { - if (linked.event_id == e.link) - if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK) - found = true; + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid.", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.link); } + } - if (!found) - TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid", - e.entryOrGuid, e.GetScriptType(), e.event_id, e.link); + if (e.GetEventType() == SMART_EVENT_LINK) + { + if (!FindLinkedSourceEvent(itr->second, e.event_id)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Source Event not found or invalid. Event will never trigger.", + e.entryOrGuid, e.GetScriptType(), e.event_id); + } } } } @@ -301,6 +303,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE) return true; // AI template has special handling + switch (e.GetTargetType()) { case SMART_TARGET_CREATURE_DISTANCE: @@ -379,27 +382,38 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetEventType()); return false; } + // in SMART_SCRIPT_TYPE_TIMED_ACTIONLIST all event types are overriden by core if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && !(SmartAIEventMask[e.event.type][1] & SmartAITypeMask[e.GetScriptType()][1])) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u", e.entryOrGuid, e.GetEventType(), e.GetScriptType()); return false; } + if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetActionType()); return false; } + if (e.event.event_phase_mask > SMART_EVENT_PHASE_ALL) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask); return false; } + if (e.event.event_flags > SMART_EVENT_FLAGS_ALL) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags); return false; } + + if (e.link && e.link == e.event_id) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d SourceType %u, Event %u, Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); + return false; + } + if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST) { e.event.type = SMART_EVENT_UPDATE_OOC;//force default OOC, can change when calling the script! @@ -411,8 +425,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } else { - uint32 type = e.event.type; - switch (type) + switch (e.GetEventType()) { case SMART_EVENT_UPDATE: case SMART_EVENT_UPDATE_IC: @@ -572,17 +585,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; } case SMART_EVENT_TEXT_OVER: - //if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group! - break; - case SMART_EVENT_LINK: - { - if (e.link && e.link == e.event_id) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); + if (!IsTextValid(e, e.event.textOver.textGroupID)) return false; - } break; - } case SMART_EVENT_DUMMY_EFFECT: { if (!IsSpellValid(e, e.event.dummy.spell)) @@ -690,6 +695,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } break; + case SMART_EVENT_LINK: case SMART_EVENT_GO_STATE_CHANGED: case SMART_EVENT_GO_EVENT_INFORM: case SMART_EVENT_TIMED_EVENT_TRIGGERED: @@ -733,14 +739,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) switch (e.GetActionType()) { case SMART_ACTION_TALK: - { - if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE) - { - if (!IsTextValid(e, e.action.talk.textGroupID)) - return false; - } + case SMART_ACTION_SIMPLE_TALK: + if (!IsTextValid(e, e.action.talk.textGroupID)) + return false; break; - } case SMART_ACTION_SET_FACTION: if (e.action.faction.factionID && !sFactionTemplateStore.LookupEntry(e.action.faction.factionID)) { @@ -820,7 +822,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) if (!IsSpellValid(e, e.action.cast.spell)) return false; - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell); + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell); for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) { if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2)) @@ -983,10 +985,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) if (!NotNULL(e, e.action.item.count)) return false; - CacheSpellContainerBounds sBounds = GetCreditItemSpellContainerBounds(e.action.item.entry); + CacheSpellContainerBounds sBounds = GetCreateItemSpellContainerBounds(e.action.item.entry); for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr) TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Create Item: There is a create item spell for item %u (SpellId: %u effect: %u)", - e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second); + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second); break; } case SMART_ACTION_TELEPORT: @@ -1150,7 +1152,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_SET_NPC_FLAG: case SMART_ACTION_ADD_NPC_FLAG: case SMART_ACTION_REMOVE_NPC_FLAG: - case SMART_ACTION_SIMPLE_TALK: case SMART_ACTION_CROSS_CAST: case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST: case SMART_ACTION_RANDOM_MOVE: @@ -1181,49 +1182,45 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return true; } -bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused +bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) { - bool error = false; + if (e.GetScriptType() != SMART_SCRIPT_TYPE_CREATURE) + return true; + uint32 entry = 0; - if (e.entryOrGuid >= 0) + if (e.GetEventType() == SMART_EVENT_TEXT_OVER) { - if (e.GetEventType() == SMART_EVENT_TEXT_OVER) - { - entry = e.event.textOver.creatureEntry; - id = e.event.textOver.textGroupID; - } - else - { - switch (e.GetTargetType()) - { - case SMART_TARGET_CREATURE_DISTANCE: - case SMART_TARGET_CREATURE_RANGE: - case SMART_TARGET_CLOSEST_CREATURE: - return true; // ignore - default: - entry = uint32(e.entryOrGuid); - break; - } - } + entry = e.event.textOver.creatureEntry; } else { - entry = uint32(abs(e.entryOrGuid)); - CreatureData const* data = sObjectMgr->GetCreatureData(entry); - if (!data) + switch (e.GetTargetType()) { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; + case SMART_TARGET_CREATURE_DISTANCE: + case SMART_TARGET_CREATURE_RANGE: + case SMART_TARGET_CLOSEST_CREATURE: + return true; // ignore + default: + if (e.entryOrGuid < 0) + { + entry = uint32(std::abs(e.entryOrGuid)); + CreatureData const* data = sObjectMgr->GetCreatureData(entry); + if (!data) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + else + entry = data->id; + } + else + entry = uint32(e.entryOrGuid); + break; } - else - entry = data->id; } if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id))) - error = true; - - if (error) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id); return false; @@ -1285,7 +1282,7 @@ CacheSpellContainerBounds SmartAIMgr::GetKillCreditSpellContainerBounds(uint32 k return KillCreditSpellStore.equal_range(killCredit); } -CacheSpellContainerBounds SmartAIMgr::GetCreditItemSpellContainerBounds(uint32 itemId) const +CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 itemId) const { return CreateItemSpellStore.equal_range(itemId); } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 249c63f5cf6..9bb34d1347e 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1347,6 +1347,8 @@ struct SmartScriptHolder bool active; bool runOnce; bool enableTimed; + + operator bool() const { return entryOrGuid != 0; } }; typedef std::unordered_map WPPath; @@ -1469,6 +1471,30 @@ class SmartAIMgr } } + static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId) + { + SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), + [eventId](SmartScriptHolder& source) { return source.link == eventId; }); + + if (itr != list.end()) + return *itr; + + static SmartScriptHolder SmartScriptHolderDummy; + return SmartScriptHolderDummy; + } + + static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link) + { + SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), + [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; }); + + if (itr != list.end()) + return *itr; + + static SmartScriptHolder SmartScriptHolderDummy; + return SmartScriptHolderDummy; + } + private: //event stores SmartAIEventMap mEventMap[SMART_SCRIPT_TYPE_MAX]; @@ -1476,16 +1502,6 @@ class SmartAIMgr bool IsEventValid(SmartScriptHolder& e); bool IsTargetValid(SmartScriptHolder const& e); - /*inline bool IsTargetValid(SmartScriptHolder e, int32 target) - { - if (target < SMART_TARGET_NONE || target >= SMART_TARGET_END) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Target type %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), target); - return false; - } - return true; - }*/ - bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max) { if (max < min) @@ -1615,7 +1631,7 @@ class SmartAIMgr CacheSpellContainerBounds GetSummonCreatureSpellContainerBounds(uint32 creatureEntry) const; CacheSpellContainerBounds GetSummonGameObjectSpellContainerBounds(uint32 gameObjectEntry) const; CacheSpellContainerBounds GetKillCreditSpellContainerBounds(uint32 killCredit) const; - CacheSpellContainerBounds GetCreditItemSpellContainerBounds(uint32 itemId) const; + CacheSpellContainerBounds GetCreateItemSpellContainerBounds(uint32 itemId) const; CacheSpellContainer SummonCreatureSpellStore; CacheSpellContainer SummonGameObjectSpellStore; -- cgit v1.2.3 From 1e181d70217e731e05220f26e8b5d4201fba04d7 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 11 Oct 2014 18:56:58 +0200 Subject: Core:/SAI: Added better error log output in 0a897616dae34a26af4be516f25cc3c916905340 --- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index e8742b6cdef..0f0dcbc557a 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -298,8 +298,8 @@ void SmartAIMgr::LoadSmartAIFromDB() bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) { if (std::abs(e.target.o) > 2 * float(M_PI)) - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has abs(`target.o`) > 2*PI (orientation is expressed in radians)", - e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has abs(`target.o` = %f) > 2*PI (orientation is expressed in radians)", + e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.target.o); if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE) return true; // AI template has special handling -- cgit v1.2.3 From 103fd9cb6363dab26ee22e102facde1182fbf37e Mon Sep 17 00:00:00 2001 From: DDuarte Date: Sat, 11 Oct 2014 20:40:09 +0100 Subject: Scripts/GO: Remove go_field_repair_bot_74A Replaced by SAI in c05a4189e29f52e648103f07859f8b3bcf8e --- .../MovementGenerators/RandomMovementGenerator.cpp | 2 ++ src/server/scripts/World/go_scripts.cpp | 20 -------------------- 2 files changed, 2 insertions(+), 20 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 2f40beb9d8d..2e859a7a56f 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -99,10 +99,12 @@ void RandomMovementGenerator::_setRandomLocation(Creature* creature) if (is_air_ok) i_nextMoveTime.Reset(0); else + { if (roll_chance_i(50)) i_nextMoveTime.Reset(urand(5000, 10000)); else i_nextMoveTime.Reset(urand(50, 400)); + } creature->AddUnitState(UNIT_STATE_ROAMING_MOVE); diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 63562436196..e35f7c9b70e 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -24,7 +24,6 @@ go_ethereum_stasis go_sacred_fire_of_life go_shrine_of_the_birds go_southfury_moonstone -go_field_repair_bot_74A go_orb_of_command go_resonite_cask go_tablet_of_madness @@ -93,24 +92,6 @@ public: } }; -/*###### -## go_field_repair_bot_74A -######*/ - -class go_field_repair_bot_74A : public GameObjectScript -{ -public: - go_field_repair_bot_74A() : GameObjectScript("go_field_repair_bot_74A") { } - - bool OnGossipHello(Player* player, GameObject* /*go*/) override - { - if (player->HasSkill(SKILL_ENGINEERING) && player->GetBaseSkillValue(SKILL_ENGINEERING) >= 300 && !player->HasSpell(22704)) - player->CastSpell(player, 22864, false); - - return true; - } -}; - /*###### ## go_gilded_brazier (Paladin First Trail quest (9678)) ######*/ @@ -1284,7 +1265,6 @@ void AddSC_go_scripts() { new go_cat_figurine(); new go_barov_journal(); - new go_field_repair_bot_74A(); new go_gilded_brazier(); new go_orb_of_command(); new go_shrine_of_the_birds(); -- cgit v1.2.3 From cbabfe99200be41be0f6362756d044b653065171 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 11 Oct 2014 22:45:01 +0200 Subject: Core/Battle.net: Handle ConnectionClosing --- .../bnetserver/Packets/AuthenticationPackets.cpp | 6 +- .../bnetserver/Packets/AuthenticationPackets.h | 30 +++++----- .../bnetserver/Packets/ConnectionPackets.cpp | 60 ++++++++++++++++++- src/server/bnetserver/Packets/ConnectionPackets.h | 69 ++++++++++++++++++++-- src/server/bnetserver/Packets/FriendsPackets.cpp | 14 +---- src/server/bnetserver/Packets/FriendsPackets.h | 8 +-- src/server/bnetserver/Packets/PacketFactory.h | 2 + src/server/bnetserver/Packets/PacketsBase.cpp | 6 ++ src/server/bnetserver/Packets/PacketsBase.h | 8 ++- src/server/bnetserver/Packets/PresencePackets.cpp | 10 ---- src/server/bnetserver/Packets/PresencePackets.h | 2 - src/server/bnetserver/Packets/WoWRealmPackets.cpp | 6 +- src/server/bnetserver/Packets/WoWRealmPackets.h | 6 +- src/server/bnetserver/Server/Session.cpp | 8 ++- src/server/bnetserver/Server/Session.h | 1 + 15 files changed, 172 insertions(+), 64 deletions(-) (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp index ae2db016972..c1362cd5f03 100644 --- a/src/server/bnetserver/Packets/AuthenticationPackets.cpp +++ b/src/server/bnetserver/Packets/AuthenticationPackets.cpp @@ -50,7 +50,7 @@ std::string Battlenet::Authentication::LogonRequest::ToString() const return stream.str(); } -void Battlenet::Authentication::LogonRequest::CallHandler(Session* session) const +void Battlenet::Authentication::LogonRequest::CallHandler(Session* session) { session->HandleLogonRequest(*this); } @@ -89,7 +89,7 @@ std::string Battlenet::Authentication::ResumeRequest::ToString() const return stream.str(); } -void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session) const +void Battlenet::Authentication::ResumeRequest::CallHandler(Session* session) { session->HandleResumeRequest(*this); } @@ -153,7 +153,7 @@ std::string Battlenet::Authentication::ProofResponse::ToString() const return stream.str(); } -void Battlenet::Authentication::ProofResponse::CallHandler(Session* session) const +void Battlenet::Authentication::ProofResponse::CallHandler(Session* session) { session->HandleProofResponse(*this); } diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h index 72e598b858e..c698d3125cf 100644 --- a/src/server/bnetserver/Packets/AuthenticationPackets.h +++ b/src/server/bnetserver/Packets/AuthenticationPackets.h @@ -49,7 +49,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; std::string Program; std::string Platform; @@ -68,7 +68,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; std::string Program; std::string Platform; @@ -91,23 +91,11 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; std::vector Modules; }; - class ProofRequest final : public ServerPacket - { - public: - ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { } - ~ProofRequest(); - - void Write() override; - std::string ToString() const override; - - std::vector Modules; - }; - class ResponseFailure { public: @@ -192,6 +180,18 @@ namespace Battlenet int32 PingTimeout; Regulator RegulatorRules; }; + + class ProofRequest final : public ServerPacket + { + public: + ProofRequest() : ServerPacket(PacketHeader(SMSG_PROOF_REQUEST, AUTHENTICATION)) { } + ~ProofRequest(); + + void Write() override; + std::string ToString() const override; + + std::vector Modules; + }; } } diff --git a/src/server/bnetserver/Packets/ConnectionPackets.cpp b/src/server/bnetserver/Packets/ConnectionPackets.cpp index 0449ecbb756..aa934cb631a 100644 --- a/src/server/bnetserver/Packets/ConnectionPackets.cpp +++ b/src/server/bnetserver/Packets/ConnectionPackets.cpp @@ -23,7 +23,7 @@ std::string Battlenet::Connection::Ping::ToString() const return "Battlenet::Connection::Ping"; } -void Battlenet::Connection::Ping::CallHandler(Session* session) const +void Battlenet::Connection::Ping::CallHandler(Session* session) { session->HandlePing(*this); } @@ -33,7 +33,7 @@ std::string Battlenet::Connection::EnableEncryption::ToString() const return "Battlenet::Connection::EnableEncryption"; } -void Battlenet::Connection::EnableEncryption::CallHandler(Session* session) const +void Battlenet::Connection::EnableEncryption::CallHandler(Session* session) { session->HandleEnableEncryption(*this); } @@ -43,11 +43,65 @@ std::string Battlenet::Connection::LogoutRequest::ToString() const return "Battlenet::Connection::LogoutRequest"; } -void Battlenet::Connection::LogoutRequest::CallHandler(Session* session) const +void Battlenet::Connection::LogoutRequest::CallHandler(Session* session) { session->HandleLogoutRequest(*this); } +void Battlenet::Connection::DisconnectRequest::Read() +{ + Timeout = _stream.Read(16); + Tick = _stream.Read(32); +} + +std::string Battlenet::Connection::DisconnectRequest::ToString() const +{ + std::ostringstream str; + str << "Battlenet::Connection::DisconnectRequest Timeout: " << Timeout << ", Tick: " << Tick; + return str.str(); +} + +void Battlenet::Connection::ConnectionClosing::Read() +{ + Reason = _stream.Read(4); + if (_stream.Read(1)) // HasHeader + { + Header.Opcode = _stream.Read(6); + if (_stream.Read(1)) + Header.Channel = _stream.Read(4); + } + + Now = _stream.Read(32); + _stream.Read(25); + auto bytes = _stream.ReadBytes(_stream.Read(8)); // BadData + Packets.resize(_stream.Read(6)); + for (size_t i = 0; i < Packets.size(); ++i) + { + PacketInfo& info = Packets[i]; + info.CommandName = _stream.ReadFourCC(); + info.LayerId = _stream.Read(16); + info.Channel = _stream.ReadFourCC(); + info.Timestamp = _stream.Read(32); + info.Size = _stream.Read(16); + } +} + +std::string Battlenet::Connection::ConnectionClosing::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Connection::ConnectionClosing Reason: " << Reason << ", Now: " << Now << ", Packet history size: " << Packets.size(); + for (PacketInfo const& packet : Packets) + stream << std::endl << "Battlenet::Connection::ConnectionClosing::PacketInfo LayerId: " << packet.LayerId + << ", Channel: " << packet.Channel << ", CommandName: " << packet.CommandName << ", Size: " << packet.Size << ", Timestamp: " << packet.Timestamp; + + return stream.str(); +} + +void Battlenet::Connection::ConnectionClosing::CallHandler(Session* session) +{ + session->HandleConnectionClosing(*this); +} + std::string Battlenet::Connection::Pong::ToString() const { return "Battlenet::Connection::Pong"; diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h index f3fa4852d07..8572cd5d854 100644 --- a/src/server/bnetserver/Packets/ConnectionPackets.h +++ b/src/server/bnetserver/Packets/ConnectionPackets.h @@ -29,8 +29,8 @@ namespace Battlenet CMSG_PING = 0x0, CMSG_ENABLE_ENCRYPTION = 0x5, CMSG_LOGOUT_REQUEST = 0x6, - CMSG_DISCONNECT_REQUEST = 0x7, // Not implemented - CMSG_CONNECTION_CLOSING = 0x9, // Not implemented + CMSG_DISCONNECT_REQUEST = 0x7, // Not handled + CMSG_CONNECTION_CLOSING = 0x9, SMSG_PONG = 0x0, SMSG_BOOM = 0x1, // Not implemented @@ -49,7 +49,7 @@ namespace Battlenet void Read() override { } std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; }; class EnableEncryption final : public ClientPacket @@ -62,7 +62,7 @@ namespace Battlenet void Read() override { } std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; }; class LogoutRequest final : public ClientPacket @@ -75,7 +75,66 @@ namespace Battlenet void Read() override { } std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; + }; + + class DisconnectRequest final : public ClientPacket + { + public: + DisconnectRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_DISCONNECT_REQUEST, CONNECTION) && "Invalid packet header for DisconnectRequest"); + } + + void Read() override; + std::string ToString() const override; + + uint16 Timeout; + uint32 Tick; + }; + + class ConnectionClosing final : public ClientPacket + { + public: + enum ClosingReason + { + PACKET_TOO_LARGE, + PACKET_CORRUPT, + PACKET_INVALID, + PACKET_INCORRECT, + HEADER_CORRUPT, + HEADER_IGNORED, + HEADER_INCORRECT, + PACKET_REJECTED, + CHANNEL_UNHANDLED, + COMMAND_UNHANDLED, + COMMAND_BAD_PERMISSIONS, + DIRECT_CALL, + TIMEOUT, + }; + + struct PacketInfo + { + uint16 LayerId; + std::string Channel; + uint32 Timestamp; + std::string CommandName; + uint16 Size; + }; + + ConnectionClosing(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_CONNECTION_CLOSING, CONNECTION) && "Invalid packet header for ConnectionClosing"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session) override; + + PacketHeader Header; + ClosingReason Reason; + std::vector Packets; + time_t Now; }; class Pong final : public ServerPacket diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp index cd920e91c9c..7a4bd7dd64f 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -28,7 +28,7 @@ std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); } -void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session) const +void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session) { session->HandleSocialNetworkCheckConnected(*this); } @@ -47,11 +47,6 @@ std::string Battlenet::Friends::SocialNetworkConnect::ToString() const return "Battlenet::Friends::SocialNetworkConnect"; } -void Battlenet::Friends::SocialNetworkConnect::CallHandler(Session* session) const -{ - session->LogUnhandledPacket(*this); -} - std::string Battlenet::Friends::SocialNetworkConnectResult::ToString() const { return "Battlenet::Friends::SocialNetworkConnectResult"; @@ -84,11 +79,6 @@ std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const return "Battlenet::Friends::GetFriendsOfFriend"; } -void Battlenet::Friends::GetFriendsOfFriend::CallHandler(Session* session) const -{ - session->LogUnhandledPacket(*this); -} - void Battlenet::Friends::RealIdFriendInvite::Read() { _stream.Read(32); @@ -139,7 +129,7 @@ std::string Battlenet::Friends::RealIdFriendInvite::ToString() const return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message; } -void Battlenet::Friends::RealIdFriendInvite::CallHandler(Session* session) const +void Battlenet::Friends::RealIdFriendInvite::CallHandler(Session* session) { FriendInviteResult* result = new FriendInviteResult(); session->AsyncWrite(result); diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h index ec20f202098..a35b02e616d 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.h +++ b/src/server/bnetserver/Packets/FriendsPackets.h @@ -59,12 +59,11 @@ namespace Battlenet public: SocialNetworkConnect(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { - ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS) && "Invalid packet header for SocialnetworkConnect"); + ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS) && "Invalid packet header for SocialNetworkConnect"); } void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; }; class SocialNetworkConnectResult final : public ServerPacket @@ -88,7 +87,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; uint32 SocialNetworkId; }; @@ -117,7 +116,6 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; }; class FriendsOfFriend final : public ServerPacket @@ -141,7 +139,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; std::string Email; std::string Message; diff --git a/src/server/bnetserver/Packets/PacketFactory.h b/src/server/bnetserver/Packets/PacketFactory.h index 418e56abea4..9d710101332 100644 --- a/src/server/bnetserver/Packets/PacketFactory.h +++ b/src/server/bnetserver/Packets/PacketFactory.h @@ -55,6 +55,8 @@ namespace Battlenet _creators[PacketHeader(Connection::CMSG_PING, CONNECTION)] = &New; _creators[PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION)] = &New; _creators[PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION)] = &New; + _creators[PacketHeader(Connection::CMSG_DISCONNECT_REQUEST, CONNECTION)] = &New; + _creators[PacketHeader(Connection::CMSG_CONNECTION_CLOSING, CONNECTION)] = &New; _creators[PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM)] = &New; _creators[PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM)] = &New; diff --git a/src/server/bnetserver/Packets/PacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp index 6471337060c..7eee6a6a9ba 100644 --- a/src/server/bnetserver/Packets/PacketsBase.cpp +++ b/src/server/bnetserver/Packets/PacketsBase.cpp @@ -36,3 +36,9 @@ Battlenet::ServerPacket::~ServerPacket() { delete &_stream; } + +void Battlenet::ClientPacket::CallHandler(Session* session) +{ + session->LogUnhandledPacket(*this); + _handled = false; +} diff --git a/src/server/bnetserver/Packets/PacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h index 839a10548e9..a225c3ebfa1 100644 --- a/src/server/bnetserver/Packets/PacketsBase.h +++ b/src/server/bnetserver/Packets/PacketsBase.h @@ -97,10 +97,14 @@ namespace Battlenet class ClientPacket : public Packet { public: - ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { } + ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream), _handled(true) { } void Write() override final { ASSERT(!"Write not implemented for this packet."); } - virtual void CallHandler(Session* session) const = 0; + virtual void CallHandler(Session* session); + bool WasHandled() const { return _handled; } + + private: + bool _handled; }; class ServerPacket : public Packet diff --git a/src/server/bnetserver/Packets/PresencePackets.cpp b/src/server/bnetserver/Packets/PresencePackets.cpp index da49f41af76..b72bf8daca8 100644 --- a/src/server/bnetserver/Packets/PresencePackets.cpp +++ b/src/server/bnetserver/Packets/PresencePackets.cpp @@ -28,11 +28,6 @@ std::string Battlenet::Presence::UpdateRequest::ToString() const return "Battlenet::Presence::UpdateRequest"; } -void Battlenet::Presence::UpdateRequest::CallHandler(Session* session) const -{ - session->LogUnhandledPacket(*this); -} - void Battlenet::Presence::StatisticSubscribe::Read() { } @@ -41,8 +36,3 @@ std::string Battlenet::Presence::StatisticSubscribe::ToString() const { return "Battlenet::Presence::StatisticSubscribe"; } - -void Battlenet::Presence::StatisticSubscribe::CallHandler(Session* session) const -{ - session->LogUnhandledPacket(*this); -} diff --git a/src/server/bnetserver/Packets/PresencePackets.h b/src/server/bnetserver/Packets/PresencePackets.h index c934228a3cb..45b8f3e0e82 100644 --- a/src/server/bnetserver/Packets/PresencePackets.h +++ b/src/server/bnetserver/Packets/PresencePackets.h @@ -44,7 +44,6 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; }; class StatisticSubscribe final : public ClientPacket @@ -57,7 +56,6 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; }; } } diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp index 95176963c18..4d11dd0a11f 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.cpp +++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp @@ -25,7 +25,7 @@ std::string Battlenet::WoWRealm::ListSubscribeRequest::ToString() const return "Battlenet::WoWRealm::ListSubscribeRequest"; } -void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) const +void Battlenet::WoWRealm::ListSubscribeRequest::CallHandler(Session* session) { session->HandleListSubscribeRequest(*this); } @@ -35,7 +35,7 @@ std::string Battlenet::WoWRealm::ListUnsubscribe::ToString() const return "Battlenet::WoWRealm::ListUnsubscribe"; } -void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session) const +void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session) { session->HandleListUnsubscribe(*this); } @@ -152,7 +152,7 @@ std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const return stream.str().c_str(); } -void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) const +void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) { session->HandleJoinRequestV2(*this); } diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h index a27601f7478..fe211d6fea4 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.h +++ b/src/server/bnetserver/Packets/WoWRealmPackets.h @@ -50,7 +50,7 @@ namespace Battlenet void Read() override { } std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; }; class ListUnsubscribe final : public ClientPacket @@ -63,7 +63,7 @@ namespace Battlenet void Read() override { } std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; }; class JoinRequestV2 final : public ClientPacket @@ -76,7 +76,7 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) const override; + void CallHandler(Session* session) override; uint32 ClientSeed; RealmId Realm; diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 301a6b9bae1..42d5b6a5a06 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -396,6 +396,10 @@ void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /* LoginDatabase.Execute(stmt); } +void Battlenet::Session::HandleConnectionClosing(Connection::ConnectionClosing const& /*connectionClosing*/) +{ +} + void Battlenet::Session::HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& /*listSubscribeRequest*/) { WoWRealm::ListSubscribeResponse* listSubscribeResponse = new WoWRealm::ListSubscribeResponse(); @@ -497,8 +501,10 @@ void Battlenet::Session::ReadHandler() if (ClientPacket* packet = sPacketFactory.Create(header, stream)) { - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", packet->ToString().c_str()); packet->CallHandler(this); + if (packet->WasHandled()) + TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", packet->ToString().c_str()); + delete packet; } else diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 7def3c70460..3f5e53389b8 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -71,6 +71,7 @@ namespace Battlenet void HandlePing(Connection::Ping const& ping); void HandleEnableEncryption(Connection::EnableEncryption const& enableEncryption); void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest); + void HandleConnectionClosing(Connection::ConnectionClosing const& connectionClosing); // WoWRealm void HandleListSubscribeRequest(WoWRealm::ListSubscribeRequest const& listSubscribeRequest); -- cgit v1.2.3 From 665b1daab713c4fca0b553ca5939090fbdd448be Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 11 Oct 2014 23:40:51 +0200 Subject: Core/PacketIO: Removed PacketFilter::DropHighBytes --- src/server/game/Server/WorldSession.cpp | 6 ++---- src/server/game/Server/WorldSession.h | 1 - src/server/game/Server/WorldSocket.cpp | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 428e0582867..4c183939460 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -56,8 +56,7 @@ std::string const DefaultPlayerName = ""; bool MapSessionFilter::Process(WorldPacket* packet) { - Opcodes opcode = DropHighBytes(packet->GetOpcode()); - OpcodeHandler const* opHandle = opcodeTable[opcode]; + OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()]; //let's check if our opcode can be really processed in Map::Update() if (opHandle->ProcessingPlace == PROCESS_INPLACE) @@ -79,8 +78,7 @@ bool MapSessionFilter::Process(WorldPacket* packet) //OR packet handler is not thread-safe! bool WorldSessionFilter::Process(WorldPacket* packet) { - Opcodes opcode = DropHighBytes(packet->GetOpcode()); - OpcodeHandler const* opHandle = opcodeTable[opcode]; + OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()]; //check if packet handler is supposed to be safe if (opHandle->ProcessingPlace == PROCESS_INPLACE) return true; diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 4ec407f5254..02a185b0b63 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -144,7 +144,6 @@ public: virtual bool Process(WorldPacket* /*packet*/) { return true; } virtual bool ProcessLogout() const { return true; } - static Opcodes DropHighBytes(Opcodes opcode) { return Opcodes(opcode & 0xFFFF); } protected: WorldSession* const m_pSession; diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index f37354f7e65..83b67f426e0 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -162,7 +162,7 @@ bool WorldSocket::ReadDataHandler() { ClientPktHeader* header = reinterpret_cast(_headerBuffer.GetReadPointer()); - Opcodes opcode = PacketFilter::DropHighBytes(Opcodes(header->cmd)); + Opcodes opcode(header->cmd); std::string opcodeName = GetOpcodeNameForLogging(opcode); -- cgit v1.2.3 From 0f83c6ac323f2a1bd0b7e9e19c2687f9cf0d1e84 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 11 Oct 2014 23:49:31 +0200 Subject: Build fix --- src/server/game/Server/WorldSocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 83b67f426e0..abcf446dd8d 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -162,7 +162,7 @@ bool WorldSocket::ReadDataHandler() { ClientPktHeader* header = reinterpret_cast(_headerBuffer.GetReadPointer()); - Opcodes opcode(header->cmd); + Opcodes opcode = Opcodes(header->cmd); std::string opcodeName = GetOpcodeNameForLogging(opcode); -- cgit v1.2.3 From 241fdc49a7c49bdf627aeb0d14b0e6540090a81a Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sun, 12 Oct 2014 02:02:40 +0200 Subject: Core: Fix non pch build --- src/server/bnetserver/Packets/AuthenticationPackets.cpp | 1 + src/server/bnetserver/Packets/PacketsBase.cpp | 1 + src/server/bnetserver/Realms/RealmList.h | 1 + 3 files changed, 3 insertions(+) (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.cpp b/src/server/bnetserver/Packets/AuthenticationPackets.cpp index c1362cd5f03..f5704f67153 100644 --- a/src/server/bnetserver/Packets/AuthenticationPackets.cpp +++ b/src/server/bnetserver/Packets/AuthenticationPackets.cpp @@ -16,6 +16,7 @@ */ #include "AuthenticationPackets.h" +#include "Session.h" #include "Util.h" void Battlenet::Authentication::LogonRequest::Read() diff --git a/src/server/bnetserver/Packets/PacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp index 7eee6a6a9ba..6845fbfb0f0 100644 --- a/src/server/bnetserver/Packets/PacketsBase.cpp +++ b/src/server/bnetserver/Packets/PacketsBase.cpp @@ -16,6 +16,7 @@ */ #include "Packets.h" +#include "Session.h" #include std::string Battlenet::PacketHeader::ToString() const diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h index c7108101056..a4d3d77ff56 100644 --- a/src/server/bnetserver/Realms/RealmList.h +++ b/src/server/bnetserver/Realms/RealmList.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "Common.h" using namespace boost::asio; -- cgit v1.2.3 From d0db99961f78a950d24cd23250a9438be29ed4ab Mon Sep 17 00:00:00 2001 From: Sovak Date: Sun, 12 Oct 2014 12:38:04 +0200 Subject: Core/PacketIO: Restored client opcode handler check lost in ace->boost transition --- src/server/game/Server/WorldSocket.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/server') diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index abcf446dd8d..15f311b5d10 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -213,6 +213,17 @@ bool WorldSocket::ReadDataHandler() return false; } + // prevent invalid memory access/crash with custom opcodes + if (opcode >= NUM_OPCODE_HANDLERS) + return false; + + OpcodeHandler const* handler = opcodeTable[opcode]; + if (!handler || handler->Status == STATUS_UNHANDLED) + { + TC_LOG_ERROR("network.opcode", "No defined handler for opcode %s sent by %s", GetOpcodeNameForLogging(packet.GetOpcode()).c_str(), _worldSession->GetPlayerInfo().c_str()); + return false; + } + // Our Idle timer will reset on any non PING opcodes. // Catches people idling on the login screen and any lingering ingame connections. _worldSession->ResetTimeOutTime(); -- cgit v1.2.3 From c2a39ce36ab41f56cce6f9b31de7835c5f90bd82 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 12 Oct 2014 15:32:25 +0200 Subject: Core/PacketIO: Let packets that have a handler in array through to worldsession update --- src/server/game/Server/WorldSocket.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 15f311b5d10..bff343bdcb1 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -215,13 +215,16 @@ bool WorldSocket::ReadDataHandler() // prevent invalid memory access/crash with custom opcodes if (opcode >= NUM_OPCODE_HANDLERS) + { + CloseSocket(); return false; + } OpcodeHandler const* handler = opcodeTable[opcode]; - if (!handler || handler->Status == STATUS_UNHANDLED) + if (!handler) { TC_LOG_ERROR("network.opcode", "No defined handler for opcode %s sent by %s", GetOpcodeNameForLogging(packet.GetOpcode()).c_str(), _worldSession->GetPlayerInfo().c_str()); - return false; + return true; } // Our Idle timer will reset on any non PING opcodes. -- cgit v1.2.3 From 7679ecd7b3f9cff718023bee80eb6558fdf17b6e Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 12 Oct 2014 15:34:01 +0200 Subject: Core/Battle.net: Improved logging - use separate filters instead of throwing everything to one logger --- src/server/bnetserver/Packets/FriendsPackets.cpp | 12 ++--- src/server/bnetserver/Packets/FriendsPackets.h | 1 - src/server/bnetserver/Packets/WoWRealmPackets.cpp | 14 ++++-- src/server/bnetserver/Packets/WoWRealmPackets.h | 2 +- src/server/bnetserver/Realms/RealmList.cpp | 20 +++++---- src/server/bnetserver/Server/Session.cpp | 55 ++++++++++++++--------- src/server/bnetserver/Server/Session.h | 5 ++- src/server/bnetserver/bnetserver.conf.dist | 3 ++ 8 files changed, 66 insertions(+), 46 deletions(-) (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp index 7a4bd7dd64f..ec7078f9b02 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -117,10 +117,10 @@ void Battlenet::Friends::RealIdFriendInvite::Read() } _stream.Read(1); - + if (_stream.Read(1)) Message = _stream.ReadString(9); - + _stream.Read(32); } @@ -129,12 +129,6 @@ std::string Battlenet::Friends::RealIdFriendInvite::ToString() const return "Battlenet::Friends::RealIdFriendInvite Mail: " + Email + " Message: " + Message; } -void Battlenet::Friends::RealIdFriendInvite::CallHandler(Session* session) -{ - FriendInviteResult* result = new FriendInviteResult(); - session->AsyncWrite(result); -} - std::string Battlenet::Friends::FriendInviteResult::ToString() const { return "Battlenet::Friends::RealIdFriendInviteResult"; @@ -150,7 +144,7 @@ void Battlenet::Friends::FriendInviteResult::Write() _stream.WriteString("Testing2", 8); } _stream.Write(5, 32); - + _stream.Write(0, 0xC); // Ignored _stream.Write(1, 16); diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h index a35b02e616d..692ab5a860b 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.h +++ b/src/server/bnetserver/Packets/FriendsPackets.h @@ -139,7 +139,6 @@ namespace Battlenet void Read() override; std::string ToString() const override; - void CallHandler(Session* session) override; std::string Email; std::string Message; diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp index 4d11dd0a11f..beeeb14895c 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.cpp +++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp @@ -128,11 +128,17 @@ void Battlenet::WoWRealm::ListUpdate::Write() std::string Battlenet::WoWRealm::ListUpdate::ToString() const { std::ostringstream stream; - stream << "Battlenet::WoWRealm::ListUpdate Timezone " << Timezone << " Population " << Population << " Lock " << uint32(Lock) << " Type " << Type << " Name " << Name - << " Flags " << uint32(Flags) << " Region " << uint32(Id.Region) << " Battlegroup " << uint32(Id.Battlegroup) << " Index " << Id.Index; + stream << "Battlenet::WoWRealm::ListUpdate"; + if (UpdateState == UPDATE) + { + stream << " Timezone: " << Timezone << " Population: " << Population << " Lock: " << uint32(Lock) << " Type: " << Type << " Name: " << Name + << " Flags: " << uint32(Flags) << " Region: " << uint32(Id.Region) << " Battlegroup: " << uint32(Id.Battlegroup) << " Index: " << Id.Index; - if (!Version.empty()) - stream << " Version " << Version; + if (!Version.empty()) + stream << " Version: " << Version; + } + else + stream << " Delete realm [Region: " << uint32(Id.Region) << " Battlegroup : " << uint32(Id.Battlegroup) << " Index : " << Id.Index << "]"; return stream.str().c_str(); } diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h index fe211d6fea4..403ca71279f 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.h +++ b/src/server/bnetserver/Packets/WoWRealmPackets.h @@ -163,7 +163,7 @@ namespace Battlenet }; JoinResponseV2() : ServerPacket(PacketHeader(SMSG_JOIN_RESPONSE_V2, WOWREALM)), - ServerSeed(0), Response(SUCCESS), ResponseCode(26) + Response(SUCCESS), ResponseCode(26), ServerSeed(0) { } diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp index 8d6edb12b5c..2bf93e12cb3 100644 --- a/src/server/bnetserver/Realms/RealmList.cpp +++ b/src/server/bnetserver/Realms/RealmList.cpp @@ -97,7 +97,6 @@ void RealmList::UpdateRealm(Battlenet::RealmId const& id, const std::string& nam Realm& realm = _realms[id]; realm.Keep = true; - realm.Updated = false; realm.Id = id; UpdateField(realm.Name, name, realm.Updated); @@ -117,7 +116,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) if (error) return; - TC_LOG_INFO("server.bnetserver", "Updating Realm List..."); + TC_LOG_DEBUG("realmlist", "Updating Realm List..."); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); PreparedQueryResult result = LoginDatabase.Query(stmt); @@ -139,7 +138,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); if (endPoint == end || ec) { - TC_LOG_ERROR("server.bnetserver", "Could not resolve address %s", fields[2].GetString().c_str()); + TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[2].GetString().c_str()); continue; } @@ -149,7 +148,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) endPoint = _resolver->resolve(localAddressQuery, ec); if (endPoint == end || ec) { - TC_LOG_ERROR("server.bnetserver", "Could not resolve address %s", fields[3].GetString().c_str()); + TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[3].GetString().c_str()); continue; } @@ -159,7 +158,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) endPoint = _resolver->resolve(localSubmaskQuery, ec); if (endPoint == end || ec) { - TC_LOG_ERROR("server.bnetserver", "Could not resolve address %s", fields[4].GetString().c_str()); + TC_LOG_ERROR("realmlist", "Could not resolve address %s", fields[4].GetString().c_str()); continue; } @@ -181,11 +180,11 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) UpdateRealm(id, name, externalAddress, localAddress, localSubmask, port, icon, flag, timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); - //TC_LOG_INFO("server.bnetserver", "Added realm \"%s\" at %s:%u.", name.c_str(), m_realms[id].ExternalAddress.to_string().c_str(), port); + TC_LOG_TRACE("realmlist", "Realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); } catch (std::exception& ex) { - TC_LOG_ERROR("server.bnetserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); + TC_LOG_ERROR("realmlist", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); ASSERT(false); } } @@ -195,12 +194,15 @@ void RealmList::UpdateRealms(boost::system::error_code const& error) std::vector updatedRealms; std::vector deletedRealms; - for (RealmMap::value_type const& pair : _realms) + for (RealmMap::value_type& pair : _realms) { if (pair.second.Updated) updatedRealms.push_back(&pair.second); - if (!pair.second.Keep) + else if (!pair.second.Keep) deletedRealms.push_back(pair.first); + + pair.second.Updated = false; + pair.second.Keep = false; } for (Battlenet::RealmId const& deleted : deletedRealms) diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 42d5b6a5a06..fa678165cf3 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -64,7 +64,6 @@ Battlenet::Session::Session(tcp::socket&& socket) : Socket(std::move(socket)), _ Battlenet::Session::~Session() { sSessionMgr.RemoveSession(this); - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::OnClose"); } void Battlenet::Session::_SetVSFields(std::string const& pstr) @@ -91,7 +90,7 @@ void Battlenet::Session::_SetVSFields(std::string const& pstr) void Battlenet::Session::LogUnhandledPacket(ClientPacket const& packet) { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::LogUnhandledPacket %s", packet.ToString().c_str()); + TC_LOG_DEBUG("session.packets", "%s Received unhandled packet %s", GetClientInfo().c_str(), packet.ToString().c_str()); } void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& logonRequest) @@ -107,7 +106,7 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(LOGIN_BANNED); AsyncWrite(logonResponse); - TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort()); return; } @@ -184,7 +183,7 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& // If the IP is 'locked', check that the player comes indeed from the correct IP address if (fields[2].GetUInt8() == 1) // if ip is locked { - TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str()); if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0) { @@ -196,10 +195,10 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& } else { - TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountName.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountName.c_str()); std::string accountCountry = fields[3].GetString(); if (accountCountry.empty() || accountCountry == "00") - TC_LOG_DEBUG("server.battlenet", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountName.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountName.c_str()); else if (!accountCountry.empty()) { uint32 ip = inet_addr(ip_address.c_str()); @@ -210,7 +209,7 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt)) { std::string loginCountry = (*sessionCountryQuery)[0].GetString(); - TC_LOG_DEBUG("server.battlenet", "[Battlenet::AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str()); + TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str()); if (loginCountry != accountCountry) { Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); @@ -237,7 +236,7 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(LOGIN_BANNED); AsyncWrite(logonResponse); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); return; } else @@ -245,7 +244,7 @@ void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(LOGIN_SUSPENDED); AsyncWrite(logonResponse); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str()); return; } } @@ -494,7 +493,7 @@ void Battlenet::Session::ReadHandler() if (header.Channel != AUTHENTICATION && !_authed) { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Received not allowed packet %s", header.ToString().c_str()); + TC_LOG_DEBUG("session.packets", "%s Received not allowed %s. Client has not authed yet.", GetClientInfo().c_str(), header.ToString().c_str()); CloseSocket(); return; } @@ -503,13 +502,13 @@ void Battlenet::Session::ReadHandler() { packet->CallHandler(this); if (packet->WasHandled()) - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::ReadDataHandler %s", packet->ToString().c_str()); + TC_LOG_TRACE("session.packets", "%s Received %s", GetClientInfo().c_str(), packet->ToString().c_str()); delete packet; } else { - TC_LOG_DEBUG("server.battlenet", "Battlenet::Session::ReadDataHandler Unhandled opcode %s", header.ToString().c_str()); + TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str()); break; } @@ -517,7 +516,7 @@ void Battlenet::Session::ReadHandler() } catch (BitStreamPositionException const& e) { - TC_LOG_ERROR("server.battlenet", "Battlenet::Session::ReadDataHandler Exception: %s", e.what()); + TC_LOG_ERROR("session.packets", "%s Exception thrown during packet processing %s", GetClientInfo().c_str(), e.what()); CloseSocket(); return; } @@ -529,7 +528,7 @@ void Battlenet::Session::ReadHandler() void Battlenet::Session::Start() { - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::Start"); + TC_LOG_TRACE("session", "Accepted connection from %s", GetRemoteIpAddress().to_string().c_str()); AsyncRead(); } @@ -541,7 +540,7 @@ void Battlenet::Session::AsyncWrite(ServerPacket* packet) return; } - TC_LOG_TRACE("server.battlenet", "Battlenet::Session::AsyncWrite %s", packet->ToString().c_str()); + TC_LOG_TRACE("session.packets", "%s Sending %s", GetClientInfo().c_str(), packet->ToString().c_str()); packet->Write(); @@ -752,12 +751,12 @@ bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacke if (fields[2].GetUInt32() == fields[3].GetUInt32()) { logonResponse->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } else { logonResponse->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } ReplaceResponse(response, logonResponse); @@ -824,12 +823,12 @@ bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, Se if (fields[2].GetUInt32() == fields[3].GetUInt32()) { logonResponse->SetAuthResult(LOGIN_BANNED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } else { logonResponse->SetAuthResult(LOGIN_SUSPENDED); - TC_LOG_DEBUG("server.battlenet", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); + TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str()); } ReplaceResponse(response, logonResponse); @@ -935,7 +934,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* stmt->setString(0, _accountName); LoginDatabase.Execute(stmt); - TC_LOG_DEBUG("server.battlenet", "[Battlenet::Resume] Invalid proof!"); + TC_LOG_DEBUG("session", "[Battlenet::Resume] Invalid proof!"); Authentication::ResumeResponse* resumeResponse = new Authentication::ResumeResponse(); resumeResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); ReplaceResponse(response, resumeResponse); @@ -975,6 +974,7 @@ bool Battlenet::Session::HandleResumeModule(BitStream* dataStream, ServerPacket* bool Battlenet::Session::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response) { + TC_LOG_ERROR("session.packets", "Unhandled module."); Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse(); logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE); ReplaceResponse(response, logonResponse); @@ -1026,3 +1026,18 @@ Battlenet::WoWRealm::ListUpdate* Battlenet::Session::BuildListUpdate(Realm const listUpdate->Id = realm->Id; return listUpdate; } + +std::string Battlenet::Session::GetClientInfo() const +{ + std::ostringstream stream; + stream << '[' << GetRemoteIpAddress() << ':' << GetRemotePort(); + if (!_accountName.empty()) + stream << ", Account: " << _accountName; + + if (!_gameAccountName.empty()) + stream << ", Game account: " << _gameAccountName; + + stream << ']'; + + return stream.str(); +} diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 3f5e53389b8..764ef7e0c73 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -85,14 +85,14 @@ namespace Battlenet void UpdateRealms(std::vector& realms, std::vector& deletedRealms); - void AsyncWrite(ServerPacket* packet); - uint32 GetAccountId() const { return _accountId; } uint32 GetGameAccountId() const { return _gameAccountId; } bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; } protected: + void AsyncWrite(ServerPacket* packet); + void ReadHandler() override; private: @@ -108,6 +108,7 @@ namespace Battlenet bool UnhandledModule(BitStream* dataStream, ServerPacket** response); WoWRealm::ListUpdate* BuildListUpdate(Realm const* realm) const; + std::string GetClientInfo() const; uint32 _accountId; std::string _accountName; diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist index ac02a06c918..84456c117b3 100644 --- a/src/server/bnetserver/bnetserver.conf.dist +++ b/src/server/bnetserver/bnetserver.conf.dist @@ -245,6 +245,9 @@ Appender.Bnet=2,2,0,Bnet.log,w # Logger.root=3,Console Bnet +Logger.realmlist=3,Console Bnet +Logger.session=3,Console Bnet +Logger.session.packets=3,Console Bnet # ################################################################################################### -- cgit v1.2.3 From 679e663df1d595b06d568c169b1fe19234fe8ff1 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Herrera Date: Sun, 12 Oct 2014 10:32:49 -0500 Subject: Bnet/Friends: Send the "proper" error message in SocialNetworkCheckConnectedResult --- src/server/bnetserver/Packets/FriendsPackets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp index ec7078f9b02..42036c3d7a4 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -64,7 +64,7 @@ std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() co void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() { _stream.Write(0, 23); // Ignored - _stream.Write(0, 16); // Unknown + _stream.Write(4601, 16); // Result, 4601 = The Facebook add friend service is unavailable right now. Please try again later. _stream.Write(SocialNetworkId, 32); } -- cgit v1.2.3 From 5f2252e86317531b284272cc3c38971f16f29cd6 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 12 Oct 2014 18:59:01 +0200 Subject: Core/Authserver: Removed battle.net authresult enum from authserver --- src/server/authserver/Authentication/AuthCodes.h | 57 ------------------------ 1 file changed, 57 deletions(-) (limited to 'src/server') diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index c42a11007d8..bc7f0c43f17 100644 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -104,63 +104,6 @@ enum GameAccountFlags GAMEACCOUNT_FLAG_DEATH_KNIGHT_OK = 0x20000000, }; -namespace Battlenet -{ - enum AuthResult - { - AUTH_OK = 0, - AUTH_INTERNAL_ERROR = 100, - AUTH_CORRUPTED_MODULE = 101, - AUTH_NO_BATTLETAGS = 102, - AUTH_BAD_SERVER_PROOF = 103, - AUTH_UNKNOWN_ACCOUNT = 104, - AUTH_CLOSED = 105, - AUTH_LOGIN_TIMEOUT = 106, - AUTH_NO_GAME_ACCOUNTS = 107, - AUTH_INVALID_TOKEN = 108, - AUTH_INVALID_PROGRAM = 109, - AUTH_INVALID_OS = 110, - AUTH_UNSUPPORTED_LANGUAGE = 111, - AUTH_REGION_BAD_VERSION = 112, - AUTH_TEMP_OUTAGE = 113, - AUTH_CANT_DOWNLOAD_MODULE = 114, - AUTH_DUPLICATE_LOGON = 115, - AUTH_BAD_CREDENTIALS_2 = 116, - AUTH_VERSION_CHECK_SUCCEEDED = 117, - AUTH_BAD_VERSION_HASH = 118, - AUTH_CANT_RETRIEVE_PORTAL_LIST = 119, - AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120, - AUTH_DARK_PORTAL_FILE_CORRUPTED = 121, - AUTH_BATTLENET_MAINTENANCE = 122, - AUTH_LOGON_TOO_FAST = 123, - AUTH_USE_GRUNT_LOGON = 124, - AUTH_NO_GAME_ACCOUNTS_IN_REGION = 140, - AUTH_ACCOUNT_LOCKED = 141, - - LOGIN_SERVER_BUSY = 200, - LOGIN_NO_GAME_ACCOUNT = 201, - LOGIN_BANNED = 202, - LOGIN_SUSPENDED = 203, - LOGIN_GAME_ACCOUNT_LOCKED = 204, - LOGIN_ALREADY_ONLINE = 205, - LOGIN_NOTIME = 206, - LOGIN_EXPIRED = 207, - LOGIN_EXPIRED_2 = 208, - LOGIN_PARENTALCONTROL = 209, - LOGIN_TRIAL_EXPIRED = 210, - LOGIN_ANTI_INDULGENCE = 211, - LOGIN_INCORRECT_REGION = 212, - LOGIN_LOCKED_ENFORCED = 213, - LOGIN_CHARGEBACK = 214, - LOGIN_IGR_WITHOUT_BNET = 215, - LOGIN_UNLOCKABLE_LOCK = 216, - LOGIN_IGR_REQUIRED = 217, - LOGIN_PAYMENT_CHANGED = 218, - LOGIN_INVALID_PAYMENT = 219, - LOGIN_INVALID_ACCOUNT_STATE = 220 - }; -} - enum ExpansionFlags { POST_BC_EXP_FLAG = 0x2, -- cgit v1.2.3 From 68293aa9b21877d62d2085bca32e43686e5ede4d Mon Sep 17 00:00:00 2001 From: Kittnz Date: Sun, 12 Oct 2014 19:23:40 +0200 Subject: Core/Misc: Fix current player state when logging out Sit should only be apply'd when player is standing. For example when sitting on a chair when logging out, player should stay on the chair until fully logged out and not sit on the floor. --- src/server/game/Handlers/MiscHandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index bede3b4323c..50fde106824 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -414,7 +414,8 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) // not set flags if player can't free move to prevent lost state at logout cancel if (GetPlayer()->CanFreeMove()) { - GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT); + if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND) + GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT); WorldPacket data(SMSG_FORCE_MOVE_ROOT, (8+4)); // guess size data << GetPlayer()->GetPackGUID(); -- cgit v1.2.3 From bb046ce4ed59708fa002f0b7399c1412e6b1de42 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 12 Oct 2014 20:01:27 +0200 Subject: Core/Maps: Apply const-correctness to GridMap::loadData() --- src/server/game/Maps/Map.cpp | 2 +- src/server/game/Maps/Map.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 37563acd74a..7f350df2280 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1586,7 +1586,7 @@ GridMap::~GridMap() unloadData(); } -bool GridMap::loadData(char* filename) +bool GridMap::loadData(const char* filename) { // Unload old data if exist unloadData(); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 87434d555aa..e2e9fa1f706 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -200,7 +200,7 @@ class GridMap public: GridMap(); ~GridMap(); - bool loadData(char* filaname); + bool loadData(const char* filename); void unloadData(); uint16 getArea(float x, float y) const; -- cgit v1.2.3 From cf521de9cb4da0c3a490684875196f7187d9b4cd Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 12 Oct 2014 20:58:25 +0200 Subject: Battle.net/Packets: Added packet name mapping for logging --- src/server/bnetserver/Packets/FriendsPackets.cpp | 69 +++---- src/server/bnetserver/Packets/FriendsPackets.h | 70 +++---- src/server/bnetserver/Packets/PacketFactory.h | 86 -------- src/server/bnetserver/Packets/PacketManager.cpp | 242 +++++++++++++++++++++++ src/server/bnetserver/Packets/PacketManager.h | 105 ++++++++++ src/server/bnetserver/Packets/PacketsBase.cpp | 3 +- src/server/bnetserver/Packets/PacketsBase.h | 8 +- src/server/bnetserver/Packets/WoWRealmPackets.h | 2 +- src/server/bnetserver/Server/Session.cpp | 37 +++- src/server/bnetserver/Server/Session.h | 2 +- 10 files changed, 428 insertions(+), 196 deletions(-) delete mode 100644 src/server/bnetserver/Packets/PacketFactory.h create mode 100644 src/server/bnetserver/Packets/PacketManager.cpp create mode 100644 src/server/bnetserver/Packets/PacketManager.h (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp index 42036c3d7a4..14c5fb3a665 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -18,65 +18,30 @@ #include "Session.h" #include "FriendsPackets.h" -void Battlenet::Friends::SocialNetworkCheckConnected::Read() -{ - SocialNetworkId = _stream.Read(32); -} - -std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const -{ - return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); -} - -void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session) -{ - session->HandleSocialNetworkCheckConnected(*this); -} - -void Battlenet::Friends::SocialNetworkConnect::Read() -{ - int32 unk1 = _stream.Read(32); - uint32 size1 = _stream.Read(9); - auto data1 = _stream.ReadBytes(size1); - uint32 size2 = _stream.Read(7); - auto data2 = _stream.ReadBytes(size2); -} - -std::string Battlenet::Friends::SocialNetworkConnect::ToString() const -{ - return "Battlenet::Friends::SocialNetworkConnect"; -} - -std::string Battlenet::Friends::SocialNetworkConnectResult::ToString() const -{ - return "Battlenet::Friends::SocialNetworkConnectResult"; -} - -void Battlenet::Friends::SocialNetworkConnectResult::Write() +void Battlenet::Friends::GetFriendsOfFriend::Read() { + uint8 unk = _stream.Read(2); + uint32 unk1 = _stream.Read(32); } -std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const +std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const { - return "Battlenet::Friends::SocialNetworkCheckConnectedResult"; + return "Battlenet::Friends::GetFriendsOfFriend"; } -void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() +void Battlenet::Friends::SocialNetworkCheckConnected::Read() { - _stream.Write(0, 23); // Ignored - _stream.Write(4601, 16); // Result, 4601 = The Facebook add friend service is unavailable right now. Please try again later. - _stream.Write(SocialNetworkId, 32); + SocialNetworkId = _stream.Read(32); } -void Battlenet::Friends::GetFriendsOfFriend::Read() +std::string Battlenet::Friends::SocialNetworkCheckConnected::ToString() const { - uint8 unk = _stream.Read(2); - uint32 unk1 = _stream.Read(32); + return "Battlenet::Friends::SocialNetworkCheckConnected SocialNetworkId " + std::to_string(SocialNetworkId); } -std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const +void Battlenet::Friends::SocialNetworkCheckConnected::CallHandler(Session* session) { - return "Battlenet::Friends::GetFriendsOfFriend"; + session->HandleSocialNetworkCheckConnected(*this); } void Battlenet::Friends::RealIdFriendInvite::Read() @@ -159,3 +124,15 @@ void Battlenet::Friends::FriendInviteResult::Write() _stream.WriteString("Testing3", 7, 2); } } + +std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() const +{ + return "Battlenet::Friends::SocialNetworkCheckConnectedResult"; +} + +void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() +{ + _stream.Write(0, 23); // Ignored + _stream.Write(Result, 16); + _stream.Write(SocialNetworkId, 32); +} diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h index 692ab5a860b..ea4d6d2ea92 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.h +++ b/src/server/bnetserver/Packets/FriendsPackets.h @@ -34,9 +34,9 @@ namespace Battlenet CMSG_BLOCK_ADD = 0x08, // Not implemented CMSG_BLOCK_REMOVE = 0x0A, // Not implemented CMSG_GET_FRIENDS_OF_FRIEND = 0x0B, // Not implemented - CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Not implemented - CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Not implemented - CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Not implemented + CMSG_GET_SOCIAL_NETWORK_FRIENDS = 0x0D, // Won't support + CMSG_SOCIAL_NETWORK_CONNECT = 0x0F, // Won't support + CMSG_SOCIAL_NETWORK_DISCONNECT = 0x11, // Won't support CMSG_SOCIAL_NETWORK_CHECK_CONNECTED = 0x13, CMSG_REALID_FRIEND_INVITE = 0x16, // Not implemented @@ -46,37 +46,26 @@ namespace Battlenet SMSG_BLOCK_INVITE_NOTIFY = 0x07, // Not implemented SMSG_BLOCK_ADD_FAILURE = 0x09, // Not implemented SMSG_FRIENDS_OF_FRIEND = 0x0C, // Not implemented - SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Not implemented - SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Not implemented - SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Not implemented + SMSG_SOCIAL_NETWORK_FRIENDS = 0x0E, // Won't support + SMSG_SOCIAL_NETWORK_CONNECT_RESULT = 0x10, // Won't support + SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT = 0x12, // Won't support SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT = 0x14, SMSG_MAX_FRIENDS_NOTIFY = 0x15, // Not implemented SMSG_FRIENDS_LIST_NOTIFY_3 = 0x18 // Not implemented }; - class SocialNetworkConnect final : public ClientPacket + class GetFriendsOfFriend final : public ClientPacket { public: - SocialNetworkConnect(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { - ASSERT(header == PacketHeader(CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS) && "Invalid packet header for SocialNetworkConnect"); + ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend"); } void Read() override; std::string ToString() const override; }; - class SocialNetworkConnectResult final : public ServerPacket - { - public: - SocialNetworkConnectResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS)) - { - } - - void Write() override; - std::string ToString() const override; - }; - class SocialNetworkCheckConnected final : public ClientPacket { public: @@ -92,29 +81,29 @@ namespace Battlenet uint32 SocialNetworkId; }; - class SocialNetworkCheckConnectedResult final : public ServerPacket + class RealIdFriendInvite final : public ClientPacket { public: - SocialNetworkCheckConnectedResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), - SocialNetworkId(0) + RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { + ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite"); } - void Write() override; + void Read() override; std::string ToString() const override; - uint32 SocialNetworkId; + std::string Email; + std::string Message; }; - class GetFriendsOfFriend final : public ClientPacket + class FriendInviteResult final : public ServerPacket { public: - GetFriendsOfFriend(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS)) { - ASSERT(header == PacketHeader(CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS) && "Invalid packet header for GetFriendsOfFriend"); } - void Read() override; + void Write() override; std::string ToString() const override; }; @@ -129,30 +118,19 @@ namespace Battlenet std::string ToString() const override; }; - class RealIdFriendInvite final : public ClientPacket - { - public: - RealIdFriendInvite(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) - { - ASSERT(header == PacketHeader(CMSG_REALID_FRIEND_INVITE, FRIENDS) && "Invalid packet header for RealIdFriendInvite"); - } - - void Read() override; - std::string ToString() const override; - - std::string Email; - std::string Message; - }; - - class FriendInviteResult final : public ServerPacket + class SocialNetworkCheckConnectedResult final : public ServerPacket { public: - FriendInviteResult() : ServerPacket(PacketHeader(SMSG_FRIEND_INVITE_RESULT, FRIENDS)) + SocialNetworkCheckConnectedResult() : ServerPacket(PacketHeader(SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS)), + Result(4601), SocialNetworkId(0) // 4601 = The Facebook add friend service is unavailable right now. Please try again later. { } void Write() override; std::string ToString() const override; + + uint16 Result; + uint32 SocialNetworkId; }; } } diff --git a/src/server/bnetserver/Packets/PacketFactory.h b/src/server/bnetserver/Packets/PacketFactory.h deleted file mode 100644 index 9d710101332..00000000000 --- a/src/server/bnetserver/Packets/PacketFactory.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef PacketFactory_h__ -#define PacketFactory_h__ - -#include "Packets.h" -#include - -namespace Battlenet -{ - class PacketFactory - { - typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream); - - public: - ClientPacket* Create(PacketHeader const& header, BitStream& stream) - { - auto creator = _creators.find(header); - if (creator == _creators.end()) - return nullptr; - - ClientPacket* packet = creator->second(header, stream); - packet->Read(); - return packet; - } - - static PacketFactory& Instance() - { - static PacketFactory instance; - return instance; - } - - private: - PacketFactory() - { - _creators[PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION)] = &New; - _creators[PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION)] = &New; - _creators[PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION)] = &New; - - _creators[PacketHeader(Connection::CMSG_PING, CONNECTION)] = &New; - _creators[PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION)] = &New; - _creators[PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION)] = &New; - _creators[PacketHeader(Connection::CMSG_DISCONNECT_REQUEST, CONNECTION)] = &New; - _creators[PacketHeader(Connection::CMSG_CONNECTION_CLOSING, CONNECTION)] = &New; - - _creators[PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM)] = &New; - _creators[PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM)] = &New; - _creators[PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM)] = &New; - - _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS)] = &New; - _creators[PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS)] = &New; - _creators[PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS)] = &New; - _creators[PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS)] = &New; - - _creators[PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE)] = &New; - _creators[PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE)] = &New; - } - - template - static ClientPacket* New(PacketHeader const& header, BitStream& stream) - { - return new PacketType(header, stream); - } - - std::map _creators; - }; -} - -#define sPacketFactory Battlenet::PacketFactory::Instance() - -#endif // PacketFactory_h__ diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp new file mode 100644 index 00000000000..af31b596192 --- /dev/null +++ b/src/server/bnetserver/Packets/PacketManager.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "PacketManager.h" + +Battlenet::ClientPacket* Battlenet::PacketManager::CreateClientPacket(PacketHeader const& header, BitStream& stream) +{ + auto packetInfo = _clientPacketTable.find(header); + if (packetInfo == _clientPacketTable.end()) + return nullptr; + + if (!packetInfo->second.Constructor) + return nullptr; + + ClientPacket* packet = packetInfo->second.Constructor(header, stream); + packet->Read(); + return packet; +} + +char const* Battlenet::PacketManager::GetClientPacketName(PacketHeader const& header) +{ + auto packetInfo = _clientPacketTable.find(header); + if (packetInfo == _clientPacketTable.end()) + return nullptr; + + return packetInfo->second.Name; +} + +char const* Battlenet::PacketManager::GetServerPacketName(PacketHeader const& header) +{ + auto packetInfo = _serverPacketTable.find(header); + if (packetInfo == _serverPacketTable.end()) + return nullptr; + + return packetInfo->second.Name; +} + +bool Battlenet::PacketManager::IsHandled(PacketHeader const& header) +{ + auto packetInfo = _clientPacketTable.find(header); + if (packetInfo == _clientPacketTable.end()) + return false; + + return packetInfo->second.HasHandler; +} + +Battlenet::PacketManager::PacketManager() +{ + RegisterAuthenticationPackets(); + RegisterConnectionPackets(); + RegisterWoWRealmPackets(); + RegisterFriendsPackets(); + RegisterPresencePackets(); + RegisterChatPackets(); + RegisterSupportPackets(); + RegisterCachePackets(); + RegisterAchievementPackets(); + RegisterProfilePackets(); +} + +#define REGISTER_CLIENT_PACKET(header, packetClass) RegisterClientPacket(header, #packetClass) +#define REGISTER_SERVER_PACKET(header, packetClass) RegisterPacketName(_serverPacketTable, header, #packetClass) +#define REGISTER_CLIENT_PACKET_NAME(header, name) RegisterPacketName(_clientPacketTable, header, name) +#define REGISTER_SERVER_PACKET_NAME(header, name) RegisterPacketName(_serverPacketTable, header, name) + +void Battlenet::PacketManager::RegisterAuthenticationPackets() +{ + REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_LOGON_REQUEST, AUTHENTICATION), Authentication::LogonRequest); + REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_RESUME_REQUEST, AUTHENTICATION), Authentication::ResumeRequest); + REGISTER_CLIENT_PACKET(PacketHeader(Authentication::CMSG_PROOF_RESPONSE, AUTHENTICATION), Authentication::ProofResponse); + + REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_LOGON_RESPONSE, AUTHENTICATION), Authentication::LogonResponse); + REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_RESUME_RESPONSE, AUTHENTICATION), Authentication::ResumeResponse); + REGISTER_SERVER_PACKET(PacketHeader(Authentication::SMSG_PROOF_REQUEST, AUTHENTICATION), Authentication::ProofRequest); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_PATCH, AUTHENTICATION), "Authentication::Patch"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Authentication::SMSG_AUTHORIZED_LICENSES, AUTHENTICATION), "Authentication::AuthorizedLicenses"); +} + +void Battlenet::PacketManager::RegisterConnectionPackets() +{ + REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_PING, CONNECTION), Connection::Ping); + REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_ENABLE_ENCRYPTION, CONNECTION), Connection::EnableEncryption); + REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_LOGOUT_REQUEST, CONNECTION), Connection::LogoutRequest); + REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_DISCONNECT_REQUEST, CONNECTION), Connection::DisconnectRequest); + REGISTER_CLIENT_PACKET(PacketHeader(Connection::CMSG_CONNECTION_CLOSING, CONNECTION), Connection::ConnectionClosing); + + REGISTER_SERVER_PACKET(PacketHeader(Connection::SMSG_PONG, CONNECTION), Connection::Pong); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_BOOM, CONNECTION), "Connection::Boom"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_REGULATOR_UPDATE, CONNECTION), "Connection::RegulatorUpdate"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_SERVER_VERSION, CONNECTION), "Connection::ServerVersion"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Connection::SMSG_STUN_SERVERS, CONNECTION), "Connection::STUNServers"); +} + +void Battlenet::PacketManager::RegisterWoWRealmPackets() +{ + REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_SUBSCRIBE_REQUEST, WOWREALM), WoWRealm::ListSubscribeRequest); + REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_LIST_UNSUBSCRIBE, WOWREALM), WoWRealm::ListUnsubscribe); + REGISTER_CLIENT_PACKET(PacketHeader(WoWRealm::CMSG_JOIN_REQUEST_V2, WOWREALM), WoWRealm::JoinRequestV2); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(WoWRealm::CMSG_MULTI_LOGON_REQUEST_V2, WOWREALM), "WoWRealm::MultiLogonRequestV2"); + + REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM), WoWRealm::ListSubscribeResponse); + REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_UPDATE, WOWREALM), WoWRealm::ListUpdate); + REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_COMPLETE, WOWREALM), WoWRealm::ListComplete); + REGISTER_SERVER_PACKET_NAME(PacketHeader(WoWRealm::SMSG_TOON_READY, WOWREALM), "WoWRealm::ToonReady"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(WoWRealm::SMSG_TOON_LOGGED_OUT, WOWREALM), "WoWRealm::ToonLoggedOut"); + REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_JOIN_RESPONSE_V2, WOWREALM), WoWRealm::JoinResponseV2); +} + +void Battlenet::PacketManager::RegisterFriendsPackets() +{ + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE, FRIENDS), "Friends::FriendInvite"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_INVITE_RESPONSE, FRIENDS), "Friends::FriendInviteResponse"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_REMOVE, FRIENDS), "Friends::FriendRemove"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_FRIEND_NOTE, FRIENDS), "Friends::FriendNote"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_TOONS_OF_FRIEND_REQUEST, FRIENDS), "Friends::ToonsOfFriendRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_ADD, FRIENDS), "Friends::BlockAdd"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_BLOCK_REMOVE, FRIENDS), "Friends::BlockRemove"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), "Friends::GetFriendsOfFriend"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_GET_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::GetSocialNetworkFriends"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CONNECT, FRIENDS), "Friends::SocialNetworkConnect"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_DISCONNECT, FRIENDS), "Friends::SocialNetworkDisconnect"); + REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_SOCIAL_NETWORK_CHECK_CONNECTED, FRIENDS), Friends::SocialNetworkCheckConnected); + REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_GET_FRIENDS_OF_FRIEND, FRIENDS), Friends::GetFriendsOfFriend); + REGISTER_CLIENT_PACKET(PacketHeader(Friends::CMSG_REALID_FRIEND_INVITE, FRIENDS), Friends::RealIdFriendInvite); + + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIEND_INVITE_NOTIFY, FRIENDS), "Friends::FriendInviteNotify"); + REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_FRIEND_INVITE_RESULT, FRIENDS), Friends::FriendInviteResult); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_TOONS_OF_FRIEND_NOTIFY, FRIENDS), "Friends::ToonsOfFriendNotify"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_INVITE_NOTIFY, FRIENDS), "Friends::BlockInviteNotify"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_BLOCK_ADD_FAILURE, FRIENDS), "Friends::BlockAddFailure"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_OF_FRIEND, FRIENDS), "Friends::FriendsOfFriend"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_FRIENDS, FRIENDS), "Friends::SocialNetworkFriends"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CONNECT_RESULT, FRIENDS), "Friends::SocialNetworkConnectResult"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_DISCONNECT_RESULT, FRIENDS), "Friends::SocialNetworkDisconnectResult"); + REGISTER_SERVER_PACKET(PacketHeader(Friends::SMSG_SOCIAL_NETWORK_CHECK_CONNECTED_RESULT, FRIENDS), Friends::SocialNetworkCheckConnectedResult); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_MAX_FRIENDS_NOTIFY, FRIENDS), "Friends::MaxFriendsNotify"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Friends::SMSG_FRIENDS_LIST_NOTIFY_3, FRIENDS), "Friends::FriendsListNotify3"); +} + +void Battlenet::PacketManager::RegisterPresencePackets() +{ + REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_UPDATE_REQUEST, PRESENCE), Presence::UpdateRequest); + REGISTER_CLIENT_PACKET(PacketHeader(Presence::CMSG_STATISTIC_SUBSCRIBE, PRESENCE), Presence::StatisticSubscribe); + + REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_UPDATE_NOTIFY, PRESENCE), "Presence::UpdateNotify"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_FIELD_SPEC_ANNOUNCE, PRESENCE), "Presence::FieldSpecAnnounce"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Presence::SMSG_STATISTICS_UPDATE, PRESENCE), "Presence::StatisticsUpdate"); +} + +void Battlenet::PacketManager::RegisterChatPackets() +{ + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_JOIN_REQUEST_2, CHAT), "Chat::JoinRequest2"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_LEAVE_REQUEST, CHAT), "Chat::LeaveRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_INVITE_REQUEST, CHAT), "Chat::InviteRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_CREATE_AND_INVITE_REQUEST, CHAT), "Chat::CreateAndInviteRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MESSAGE_SEND, CHAT), "Chat::MessageSend"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_REPORT_SPAM_REQUEST, CHAT), "Chat::ReportSpamRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_WHISPER_SEND, CHAT), "Chat::WhisperSend"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CATEGORY_DESCRIPTIONS, CHAT), "Chat::EnumCategoryDescriptions"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::EnumConferenceDescriptions"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_ENUM_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::EnumConferenceMemberCounts"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Chat::CMSG_MODIFY_CHANNEL_LIST_REQUEST, CHAT), "Chat::ModifyChannelListRequest"); + + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MEMBERSHIP_CHANGE_NOTIFY, CHAT), "Chat::MembershipChangeNotify"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_NOTIFY, CHAT), "Chat::InviteNotify"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_CANCELED, CHAT), "Chat::InviteCanceled"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_RECV, CHAT), "Chat::MessageRecv"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_UNDELIVERABLE, CHAT), "Chat::MessageUndeliverable"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_DATAGRAM_CONNECTION_UPDATE, CHAT), "Chat::DatagramConnectionUpdate"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_INVITE_FAILURE, CHAT), "Chat::InviteFailed"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_SYSTEM_MESSAGE, CHAT), "Chat::SystemMessage"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MESSAGE_BLOCKED, CHAT), "Chat::MessageBlocked"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_RECV, CHAT), "Chat::WhisperRecv"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_WHISPER_UNDELIVERABLE, CHAT), "Chat::WhisperUndeliverable"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CATEGORY_DESCRIPTIONS, CHAT), "Chat::CategoryDescriptions"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_DESCRIPTIONS, CHAT), "Chat::ConferenceDescriptions"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFERENCE_MEMBER_COUNTS, CHAT), "Chat::ConferenceMemberCounts"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_JOIN_NOTIFY_2, CHAT), "Chat::JoinNotify2"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_MODIFY_CHANNEL_LIST_RESPONSE, CHAT), "Chat::ModifyChannelListResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Chat::SMSG_CONFIG_CHANGED, CHAT), "Chat::ConfigChanged"); +} + +void Battlenet::PacketManager::RegisterSupportPackets() +{ + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Support::CMSG_COMPLAINT_REQUEST, SUPPORT), "Support::ComplaintRequest"); +} + +void Battlenet::PacketManager::RegisterAchievementPackets() +{ + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_LISTEN_REQUEST, ACHIEVEMENT), "Achievement::ListenRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CRITERIA_FLUSH_REQUEST, ACHIEVEMENT), "Achievement::CriteriaFlushRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Achievement::CMSG_CHANGE_TROPHY_CASE_REQUEST, ACHIEVEMENT), "Achievement::ChangeTrophyCaseRequest"); + + REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_DATA, ACHIEVEMENT), "Achievement::Data"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CRITERIA_FLUSH_RESPONSE, ACHIEVEMENT), "Achievement::CriteriaFlushResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_ACHIEVEMENT_HANDLE_UPDATE, ACHIEVEMENT), "Achievement::AchievementHandleUpdate"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Achievement::SMSG_CHANGE_TROPHY_CASE_RESULT, ACHIEVEMENT), "Achievement::ChangeTrophyCaseResult"); +} + +void Battlenet::PacketManager::RegisterCachePackets() +{ + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_GATEWAY_LOOKUP_REQUEST, CACHE), "Cache::GatewayLookupRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_CONNECT_REQUEST, CACHE), "Cache::ConnectRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_DATA_CHUNK, CACHE), "Cache::DataChunk"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_REQUEST, CACHE), "Cache::GetStreamItemsRequest"); + + REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GATEWAY_LOOKUP_RESPONSE, CACHE), "Cache::GatewayLookupResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_CONNECT_RESPONSE, CACHE), "Cache::ConnectResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_PUBLISH_LIST_RESPONSE, CACHE), "Cache::PublishListResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_RESULT, CACHE), "Cache::Result"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE), "Cache::GetStreamItemsResponse"); +} + +void Battlenet::PacketManager::RegisterProfilePackets() +{ + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_READ_REQUEST, PROFILE), "Profile::ReadRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_ADDRESS_QUERY_REQUEST, PROFILE), "Profile::AddressQueryRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_HANDLE_TO_NAME_REQUEST, PROFILE), "Profile::ResolveHandleToToonNameRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_RESOLVE_TOON_NAME_TO_HANDLE_REQUEST, PROFILE), "Profile::ResolveToonNameToHandleRequest"); + REGISTER_CLIENT_PACKET_NAME(PacketHeader(Profile::CMSG_CHANGE_SETTINGS, PROFILE), "Profile::ChangeSettings"); + + REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_READ_RESPONSE, PROFILE), "Profile::ReadResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_ADDRESS_QUERY_RESPONSE, PROFILE), "Profile::AddressQueryResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_HANDLE_TO_NAME_RESPONSE, PROFILE), "Profile::ResolveHandleToToonNameResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_RESOLVE_TOON_NAME_TO_HANDLE_RESPONSE, PROFILE), "Profile::ResolveToonNameToHandleResponse"); + REGISTER_SERVER_PACKET_NAME(PacketHeader(Profile::SMSG_SETTINGS_AVAILABLE, PROFILE), "Profile::SettingsAvailable"); +} diff --git a/src/server/bnetserver/Packets/PacketManager.h b/src/server/bnetserver/Packets/PacketManager.h new file mode 100644 index 00000000000..1e64e6a502c --- /dev/null +++ b/src/server/bnetserver/Packets/PacketManager.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef PacketManager_h__ +#define PacketManager_h__ + +#include "Packets.h" +#include +#include + +template +struct has_call_handler +{ + template struct test_has_call_handler { }; + template static char Test(test_has_call_handler*); + template static int Test(...); + static const bool value = sizeof(Test(nullptr)) == sizeof(char); +}; + +namespace Battlenet +{ + class PacketManager + { + typedef ClientPacket*(*PacketCreateFn)(PacketHeader const& header, BitStream& stream); + + struct PacketInfo + { + PacketCreateFn Constructor; + char const* Name; + bool HasHandler; + }; + + PacketManager(); + + void RegisterAuthenticationPackets(); + void RegisterConnectionPackets(); + void RegisterWoWRealmPackets(); + void RegisterFriendsPackets(); + void RegisterPresencePackets(); + void RegisterChatPackets(); + void RegisterSupportPackets(); + void RegisterAchievementPackets(); + void RegisterCachePackets(); + void RegisterProfilePackets(); + + template + static ClientPacket* New(PacketHeader const& header, BitStream& stream) + { + return new PacketType(header, stream); + } + + void RegisterPacketName(std::map& packetTable, PacketHeader const& header, char const* name) + { + PacketInfo& info = packetTable[header]; + info.Constructor = nullptr; + info.Name = name; + info.HasHandler = false; + } + + template + void RegisterClientPacket(PacketHeader const& header, char const* name) + { + PacketInfo& info = _clientPacketTable[header]; + info.Constructor = &New; + info.Name = name; + info.HasHandler = has_call_handler::value; + } + + public: + ClientPacket* CreateClientPacket(PacketHeader const& header, BitStream& stream); + + char const* GetClientPacketName(PacketHeader const& header); + char const* GetServerPacketName(PacketHeader const& header); + + bool IsHandled(PacketHeader const& header); + + static PacketManager& Instance() + { + static PacketManager instance; + return instance; + } + + private: + std::map _clientPacketTable; + std::map _serverPacketTable; + }; +} + +#define sPacketManager Battlenet::PacketManager::Instance() + +#endif // PacketManager_h__ diff --git a/src/server/bnetserver/Packets/PacketsBase.cpp b/src/server/bnetserver/Packets/PacketsBase.cpp index 6845fbfb0f0..fd3bebcf471 100644 --- a/src/server/bnetserver/Packets/PacketsBase.cpp +++ b/src/server/bnetserver/Packets/PacketsBase.cpp @@ -40,6 +40,5 @@ Battlenet::ServerPacket::~ServerPacket() void Battlenet::ClientPacket::CallHandler(Session* session) { - session->LogUnhandledPacket(*this); - _handled = false; + session->LogUnhandledPacket(GetHeader()); } diff --git a/src/server/bnetserver/Packets/PacketsBase.h b/src/server/bnetserver/Packets/PacketsBase.h index a225c3ebfa1..0f86621d6a6 100644 --- a/src/server/bnetserver/Packets/PacketsBase.h +++ b/src/server/bnetserver/Packets/PacketsBase.h @@ -97,14 +97,10 @@ namespace Battlenet class ClientPacket : public Packet { public: - ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream), _handled(true) { } + ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { } - void Write() override final { ASSERT(!"Write not implemented for this packet."); } + void Write() override final { ASSERT(!"Write not implemented for client packets."); } virtual void CallHandler(Session* session); - bool WasHandled() const { return _handled; } - - private: - bool _handled; }; class ServerPacket : public Packet diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h index 403ca71279f..2b1390a9067 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.h +++ b/src/server/bnetserver/Packets/WoWRealmPackets.h @@ -28,7 +28,7 @@ namespace Battlenet enum Opcode { CMSG_LIST_SUBSCRIBE_REQUEST = 0x0, - CMSG_LIST_UNSUBSCRIBE = 0x1, // Not implemented + CMSG_LIST_UNSUBSCRIBE = 0x1, CMSG_JOIN_REQUEST_V2 = 0x8, CMSG_MULTI_LOGON_REQUEST_V2 = 0x9, // Not implemented diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index fa678165cf3..7090c1f0ca7 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -17,7 +17,7 @@ #include "AuthCodes.h" #include "BitStream.h" -#include "PacketFactory.h" +#include "PacketManager.h" #include "SessionManager.h" #include "Database/DatabaseEnv.h" #include "HmacHash.h" @@ -88,9 +88,9 @@ void Battlenet::Session::_SetVSFields(std::string const& pstr) LoginDatabase.Execute(stmt); } -void Battlenet::Session::LogUnhandledPacket(ClientPacket const& packet) +void Battlenet::Session::LogUnhandledPacket(PacketHeader const& header) { - TC_LOG_DEBUG("session.packets", "%s Received unhandled packet %s", GetClientInfo().c_str(), packet.ToString().c_str()); + TC_LOG_DEBUG("session.packets", "%s Received unhandled packet %s", GetClientInfo().c_str(), sPacketManager.GetClientPacketName(header)); } void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest const& logonRequest) @@ -477,6 +477,22 @@ void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetwor AsyncWrite(socialNetworkCheckConnectedResult); } +inline std::string PacketToStringHelper(Battlenet::ClientPacket const* packet) +{ + if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE)) + return packet->ToString(); + + return sPacketManager.GetClientPacketName(packet->GetHeader()); +} + +inline std::string PacketToStringHelper(Battlenet::ServerPacket const* packet) +{ + if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE)) + return packet->ToString(); + + return sPacketManager.GetServerPacketName(packet->GetHeader()); +} + void Battlenet::Session::ReadHandler() { BitStream stream(std::move(GetReadBuffer())); @@ -498,14 +514,19 @@ void Battlenet::Session::ReadHandler() return; } - if (ClientPacket* packet = sPacketFactory.Create(header, stream)) + if (ClientPacket* packet = sPacketManager.CreateClientPacket(header, stream)) { - packet->CallHandler(this); - if (packet->WasHandled()) - TC_LOG_TRACE("session.packets", "%s Received %s", GetClientInfo().c_str(), packet->ToString().c_str()); + if (sPacketManager.IsHandled(header)) + TC_LOG_DEBUG("session.packets", "%s Received %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str()); + packet->CallHandler(this); delete packet; } + else if (sPacketManager.GetClientPacketName(header)) + { + LogUnhandledPacket(header); + break; + } else { TC_LOG_DEBUG("session.packets", "%s Received unknown %s", GetClientInfo().c_str(), header.ToString().c_str()); @@ -540,7 +561,7 @@ void Battlenet::Session::AsyncWrite(ServerPacket* packet) return; } - TC_LOG_TRACE("session.packets", "%s Sending %s", GetClientInfo().c_str(), packet->ToString().c_str()); + TC_LOG_DEBUG("session.packets", "%s Sending %s", GetClientInfo().c_str(), PacketToStringHelper(packet).c_str()); packet->Write(); diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index 764ef7e0c73..b2546c70cc6 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -60,7 +60,7 @@ namespace Battlenet explicit Session(tcp::socket&& socket); ~Session(); - void LogUnhandledPacket(ClientPacket const& packet); + void LogUnhandledPacket(PacketHeader const& header); // Authentication void HandleLogonRequest(Authentication::LogonRequest const& logonRequest); -- cgit v1.2.3 From 1ef31ba752ed2ab7bcc30c11265d217b383dec4b Mon Sep 17 00:00:00 2001 From: Shauren Date: Mon, 13 Oct 2014 17:22:24 +0200 Subject: Battle.net: Implemented cache stream items --- sql/base/auth_database.sql | 23 ++++++- sql/updates/auth/2014_10_13_00_auth_434.sql | 24 +++++++ src/server/bnetserver/Packets/CachePackets.cpp | 83 +++++++++++++++++++++++++ src/server/bnetserver/Packets/CachePackets.h | 37 ++++++++++- src/server/bnetserver/Packets/PacketManager.cpp | 4 +- src/server/bnetserver/Server/ModuleManager.cpp | 3 +- src/server/bnetserver/Server/Session.cpp | 11 ++++ src/server/bnetserver/Server/Session.h | 3 + src/server/bnetserver/Server/SessionManager.cpp | 2 + src/server/bnetserver/Server/SessionManager.h | 2 + 10 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 sql/updates/auth/2014_10_13_00_auth_434.sql create mode 100644 src/server/bnetserver/Packets/CachePackets.cpp (limited to 'src/server') diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index e5f45f9ff5c..5513c23bb95 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -241,7 +241,7 @@ CREATE TABLE `battlenet_modules` ( `Type` varchar(8) NOT NULL, `System` varchar(8) NOT NULL, `Data` text, - PRIMARY KEY (`Hash`), + PRIMARY KEY (`Name`,`System`), UNIQUE KEY `uk_name_type_system` (`Name`,`Type`,`System`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -276,7 +276,26 @@ INSERT INTO `battlenet_modules` VALUES ('bfe4ceb47700aa872e815e007e27df955d4cd4bc1fe731039ee6498ce209f368','Resume','auth','Win',NULL), ('00ffd88a437afbb88d7d4b74be2e3b43601605ee229151aa9f4bebb29ef66280','Resume','auth','Mac',NULL), ('898166926805f897804bdbbf40662c9d768590a51a0b26c40dbcdf332ba11974','Resume','auth','Wn64',NULL), -('304627d437c38500c0b5ca0c6220eeade91390e52a2b005ff3f7754afa1f93cd','Resume','auth','Mc64',NULL); +('304627d437c38500c0b5ca0c6220eeade91390e52a2b005ff3f7754afa1f93cd','Resume','auth','Mc64',NULL), +('cc654428261322763f4cada5b7f4b3b67660e85639bea916986b3f366fe8adc2','ERRS','xml','enGB','AA6C50D3'), +('2753d31092f1978bdd78ebd4fae2d189364ad7108ceb22fbf1413be1f43bef04','PFTY','pfty','zhCN','DF6C50D3'), +('5813f318f7e40a07a7cdfeeec9827942e6fdc5ccee0d4171148443e429ad0ead','PFTY','pfty','ruRU','DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enSG','DF6C50D3'), +('870f53d10b4e1b09d6b622cd5671ba4ff1ad69512dfa2c676072c52e45c7f0f9','PFTY','pfty','esES','DF6C50D3'), +('305bbdab1953e65974a249e276867e13ad2c3cabca3668983cb5ed406251bb7b','PFTY','pfty','frFR','DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enGB','DF6C50D3'), +('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38','PFTY','pfty','csCZ','DF6C50D3'), +('a8c77051991b1a6c5dfe412e9f46d8f584349996fbde37c4f2a527c192163502','PFTY','pfty','plPL','DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enUS','DF6C50D3'), +('7466b2db3f03768aa2527535d4b3c6c9ef9e8fb07c6db88b1019f3d25a2942e8','PFTY','pfty','koKR','DF6C50D3'), +('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38','PFTY','pfty','jaJP','DF6C50D3'), +('3e381d4f83201f4e3c482eb74da12e5ff9dd924da2413d8fb33f5eea9a02c2c2','PFTY','pfty','zhTW','DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enTH','DF6C50D3'), +('b72e65b6b34d8f859e79b5f28952e26553a796d5e1d75c2b5930bc0daeaa728c','PFTY','pfty','itIT','DF6C50D3'), +('e8b82becbe0a0a1bbb5561df69320edbd770897a8deaab23caa6736255e0dc33','PFTY','pfty','esMX','DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03','PFTY','pfty','enAU','DF6C50D3'), +('0a3f6f3f0535ea21dbe620085192afc796203047e270e0e1b76f15a739fe1797','PFTY','pfty','ptBR','DF6C50D3'), +('047329d08d433da2622e9fc2ee96c8dd8f35e7770699d07cf74855b9c8ea9125','PFTY','pfty','deDE','DF6C50D3'); /*!40000 ALTER TABLE `battlenet_modules` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/auth/2014_10_13_00_auth_434.sql b/sql/updates/auth/2014_10_13_00_auth_434.sql new file mode 100644 index 00000000000..e7c984d70f6 --- /dev/null +++ b/sql/updates/auth/2014_10_13_00_auth_434.sql @@ -0,0 +1,24 @@ +ALTER TABLE `battlenet_modules` + DROP PRIMARY KEY, + ADD PRIMARY KEY (`Name`, `System`); +DELETE FROM `battlenet_modules` WHERE `Name` IN ('ERRS','PFTY'); +INSERT INTO `battlenet_modules` (`Hash`,`Name`,`Type`,`System`,`Data`) VALUES +('cc654428261322763f4cada5b7f4b3b67660e85639bea916986b3f366fe8adc2', 'ERRS', 'xml', 'enGB', 'AA6C50D3'), +('2753d31092f1978bdd78ebd4fae2d189364ad7108ceb22fbf1413be1f43bef04', 'PFTY', 'pfty', 'zhCN', 'DF6C50D3'), +('5813f318f7e40a07a7cdfeeec9827942e6fdc5ccee0d4171148443e429ad0ead', 'PFTY', 'pfty', 'ruRU', 'DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enSG', 'DF6C50D3'), +('870f53d10b4e1b09d6b622cd5671ba4ff1ad69512dfa2c676072c52e45c7f0f9', 'PFTY', 'pfty', 'esES', 'DF6C50D3'), +('305bbdab1953e65974a249e276867e13ad2c3cabca3668983cb5ed406251bb7b', 'PFTY', 'pfty', 'frFR', 'DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enGB', 'DF6C50D3'), +('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38', 'PFTY', 'pfty', 'csCZ', 'DF6C50D3'), +('a8c77051991b1a6c5dfe412e9f46d8f584349996fbde37c4f2a527c192163502', 'PFTY', 'pfty', 'plPL', 'DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enUS', 'DF6C50D3'), +('7466b2db3f03768aa2527535d4b3c6c9ef9e8fb07c6db88b1019f3d25a2942e8', 'PFTY', 'pfty', 'koKR', 'DF6C50D3'), +('a2ec4b41148214037a2e89a2e557af716d085241b81f5244494bdc77a891ca38', 'PFTY', 'pfty', 'jaJP', 'DF6C50D3'), +('3e381d4f83201f4e3c482eb74da12e5ff9dd924da2413d8fb33f5eea9a02c2c2', 'PFTY', 'pfty', 'zhTW', 'DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enTH', 'DF6C50D3'), +('b72e65b6b34d8f859e79b5f28952e26553a796d5e1d75c2b5930bc0daeaa728c', 'PFTY', 'pfty', 'itIT', 'DF6C50D3'), +('e8b82becbe0a0a1bbb5561df69320edbd770897a8deaab23caa6736255e0dc33', 'PFTY', 'pfty', 'esMX', 'DF6C50D3'), +('83663d54444eadad40d43725e59bde8eda10276e76fc3c4e6f2ca56332ee8f03', 'PFTY', 'pfty', 'enAU', 'DF6C50D3'), +('0a3f6f3f0535ea21dbe620085192afc796203047e270e0e1b76f15a739fe1797', 'PFTY', 'pfty', 'ptBR', 'DF6C50D3'), +('047329d08d433da2622e9fc2ee96c8dd8f35e7770699d07cf74855b9c8ea9125', 'PFTY', 'pfty', 'deDE', 'DF6C50D3'); diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp new file mode 100644 index 00000000000..cd5aa05fed6 --- /dev/null +++ b/src/server/bnetserver/Packets/CachePackets.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "CachePackets.h" + +void Battlenet::Cache::GetStreamItemsRequest::Read() +{ + if (_stream.Read(1)) + { + _stream.Read(11); // padding + ItemName = _stream.ReadFourCC(); + Channel = _stream.ReadFourCC(); + } + else + _stream.Read(16); + + _stream.Read(1); // StreamDirection + ReferenceTime = _stream.Read(32) - std::numeric_limits::min(); + Locale = _stream.ReadFourCC(); + Index = _stream.Read(32); + _stream.Read(6); // Module count, always 0 +} + +std::string Battlenet::Cache::GetStreamItemsRequest::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Cache::GetStreamItemsRequest Channel: " << Channel << ", ItemName: " << ItemName + << ", Locale: " << Locale << ", Index: " << Index; + return stream.str(); +} + +void Battlenet::Cache::GetStreamItemsRequest::CallHandler(Session* session) +{ + session->HandleGetStreamItemsRequest(*this); +} + +Battlenet::Cache::GetStreamItemsResponse::~GetStreamItemsResponse() +{ + for (size_t i = 0; i < Modules.size(); ++i) + delete Modules[i]; +} + +void Battlenet::Cache::GetStreamItemsResponse::Write() +{ + _stream.Write(0, 16); + _stream.Write(Modules.size(), 6); + for (ModuleInfo const* info : Modules) + { + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + _stream.WriteBytes(info->Data, 4); + } + + _stream.Write(Index, 32); + _stream.Write(0, 17); // padding + _stream.Write(1, 16); + _stream.Write(0, 2); +} + +std::string Battlenet::Cache::GetStreamItemsResponse::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::Cache::GetStreamItemsResponse modules " << Modules.size(); + for (ModuleInfo const* module : Modules) + stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); + + return stream.str(); +} diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h index 2e473df4e72..ba4153fe623 100644 --- a/src/server/bnetserver/Packets/CachePackets.h +++ b/src/server/bnetserver/Packets/CachePackets.h @@ -29,7 +29,7 @@ namespace Battlenet CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented CMSG_CONNECT_REQUEST = 0x4, // Not implemented CMSG_DATA_CHUNK = 0x7, // Not implemented - SMSG_GET_STREAM_ITEMS_REQUEST = 0x9, // Not implemented + CMSG_GET_STREAM_ITEMS_REQUEST = 0x9, // Not implemented SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented SMSG_CONNECT_RESPONSE = 0x4, // Not implemented @@ -37,6 +37,41 @@ namespace Battlenet SMSG_RESULT = 0x8, // Not implemented SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9 // Not implemented }; + + class GetStreamItemsRequest final : public ClientPacket + { + public: + GetStreamItemsRequest(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_GET_STREAM_ITEMS_REQUEST, CACHE) && "Invalid packet header for GetStreamItemsRequest"); + } + + void Read() override; + std::string ToString() const override; + void CallHandler(Session* session); + + std::string Channel; + std::string ItemName; + std::string Locale; + uint32 Index; + int32 ReferenceTime; + }; + + class GetStreamItemsResponse final : public ServerPacket + { + public: + GetStreamItemsResponse() : ServerPacket(PacketHeader(SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE)) + { + } + + ~GetStreamItemsResponse(); + + void Write() override; + std::string ToString() const override; + + uint32 Index; + std::vector Modules; + }; } } diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp index af31b596192..019cf48ac30 100644 --- a/src/server/bnetserver/Packets/PacketManager.cpp +++ b/src/server/bnetserver/Packets/PacketManager.cpp @@ -217,13 +217,13 @@ void Battlenet::PacketManager::RegisterCachePackets() REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_GATEWAY_LOOKUP_REQUEST, CACHE), "Cache::GatewayLookupRequest"); REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_CONNECT_REQUEST, CACHE), "Cache::ConnectRequest"); REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::CMSG_DATA_CHUNK, CACHE), "Cache::DataChunk"); - REGISTER_CLIENT_PACKET_NAME(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_REQUEST, CACHE), "Cache::GetStreamItemsRequest"); + REGISTER_CLIENT_PACKET(PacketHeader(Cache::CMSG_GET_STREAM_ITEMS_REQUEST, CACHE), Cache::GetStreamItemsRequest); REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GATEWAY_LOOKUP_RESPONSE, CACHE), "Cache::GatewayLookupResponse"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_CONNECT_RESPONSE, CACHE), "Cache::ConnectResponse"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_PUBLISH_LIST_RESPONSE, CACHE), "Cache::PublishListResponse"); REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_RESULT, CACHE), "Cache::Result"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE), "Cache::GetStreamItemsResponse"); + REGISTER_SERVER_PACKET(PacketHeader(Cache::SMSG_GET_STREAM_ITEMS_RESPONSE, CACHE), Cache::GetStreamItemsResponse); } void Battlenet::PacketManager::RegisterProfilePackets() diff --git a/src/server/bnetserver/Server/ModuleManager.cpp b/src/server/bnetserver/Server/ModuleManager.cpp index 8dc43136739..05cee2ff42e 100644 --- a/src/server/bnetserver/Server/ModuleManager.cpp +++ b/src/server/bnetserver/Server/ModuleManager.cpp @@ -51,7 +51,8 @@ void Battlenet::ModuleManager::Load() Battlenet::ModuleInfo* Battlenet::ModuleManager::CreateModule(std::string const& os, std::string const& name) const { ModuleKey key { os, name }; - ASSERT(_modules.count(key)); + if (!_modules.count(key)) + return nullptr; return new ModuleInfo(*_modules.at(key)); } diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp index 7090c1f0ca7..9a5f60b296e 100644 --- a/src/server/bnetserver/Server/Session.cpp +++ b/src/server/bnetserver/Server/Session.cpp @@ -477,6 +477,17 @@ void Battlenet::Session::HandleSocialNetworkCheckConnected(Friends::SocialNetwor AsyncWrite(socialNetworkCheckConnectedResult); } +void Battlenet::Session::HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest) +{ + if (ModuleInfo* module = sModuleMgr->CreateModule(getStreamItemsRequest.Locale, getStreamItemsRequest.ItemName)) + { + Cache::GetStreamItemsResponse* getStreamItemsResponse = new Cache::GetStreamItemsResponse(); + getStreamItemsResponse->Index = getStreamItemsRequest.Index; + getStreamItemsResponse->Modules.push_back(module); + AsyncWrite(getStreamItemsResponse); + } +} + inline std::string PacketToStringHelper(Battlenet::ClientPacket const* packet) { if (sLog->ShouldLog("session.packets", LOG_LEVEL_TRACE)) diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index b2546c70cc6..a2c587841a4 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -81,6 +81,9 @@ namespace Battlenet // Friends void HandleSocialNetworkCheckConnected(Friends::SocialNetworkCheckConnected const& socialNetworkCheckConnected); + // Cache + void HandleGetStreamItemsRequest(Cache::GetStreamItemsRequest const& getStreamItemsRequest); + void Start() override; void UpdateRealms(std::vector& realms, std::vector& deletedRealms); diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp index caa17364038..8dcee55ec6c 100644 --- a/src/server/bnetserver/Server/SessionManager.cpp +++ b/src/server/bnetserver/Server/SessionManager.cpp @@ -40,10 +40,12 @@ void Battlenet::SessionManager::AddSession(Session* session) { std::unique_lock lock(_sessionMutex); _sessions[{ session->GetAccountId(), session->GetGameAccountId() }] = session; + _sessionsByAccountId[session->GetAccountId()].push_back(session); } void Battlenet::SessionManager::RemoveSession(Session* session) { std::unique_lock lock(_sessionMutex); _sessions.erase({ session->GetAccountId(), session->GetGameAccountId() }); + _sessionsByAccountId[session->GetAccountId()].remove(session); } diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h index 4f8e0d9fa97..bbd78c052d2 100644 --- a/src/server/bnetserver/Server/SessionManager.h +++ b/src/server/bnetserver/Server/SessionManager.h @@ -44,6 +44,7 @@ namespace Battlenet { typedef SocketMgr BaseSocketMgr; typedef std::map SessionMap; + typedef std::map> SessionByAccountMap; public: static SessionManager& Instance() @@ -74,6 +75,7 @@ namespace Battlenet static void OnSocketAccept(tcp::socket&& sock); SessionMap _sessions; + SessionByAccountMap _sessionsByAccountId; boost::shared_mutex _sessionMutex; }; } -- cgit v1.2.3 From 86e3737d1158d99f181454564046e2b634238cd7 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 13 Oct 2014 22:37:44 +0200 Subject: Core/Movement: Fix evade issue Fix evade issue happening when an evading creature assists another one, causing it to stay in evading state forever. Fix #4943 --- src/server/game/Entities/Creature/Creature.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/server') diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 9f28305e3cf..b8fd0195038 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1876,6 +1876,9 @@ void Creature::CallForHelp(float radius) bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const { + if (IsInEvadeMode()) + return false; + // is it true? if (!HasReactState(REACT_AGGRESSIVE)) return false; -- cgit v1.2.3 From 0fa1024dbdec9f04a0761447633a4dd4c712bfe2 Mon Sep 17 00:00:00 2001 From: Nyeriah Date: Tue, 14 Oct 2014 02:43:54 -0300 Subject: Scripts/Icecrown Citadel: Register Rotface's summons so they can be despawned later --- src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/server') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index 5e55256ae59..d5c07fb6942 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -178,6 +178,8 @@ class boss_rotface : public CreatureScript if (summon->GetEntry() == NPC_VILE_GAS_STALKER) if (Creature* professor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE))) professor->CastSpell(summon, SPELL_VILE_GAS_H, true); + + summons.Summon(summon); } void UpdateAI(uint32 diff) override -- cgit v1.2.3 From cc27497ea7793cbedff2065028fcc8b3aab28f58 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 14 Oct 2014 16:53:44 +0200 Subject: Battle.net: Removed not implemented comment from stream items opcodes --- src/server/bnetserver/Packets/CachePackets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h index ba4153fe623..4d9987a0f0e 100644 --- a/src/server/bnetserver/Packets/CachePackets.h +++ b/src/server/bnetserver/Packets/CachePackets.h @@ -29,13 +29,13 @@ namespace Battlenet CMSG_GATEWAY_LOOKUP_REQUEST = 0x2, // Not implemented CMSG_CONNECT_REQUEST = 0x4, // Not implemented CMSG_DATA_CHUNK = 0x7, // Not implemented - CMSG_GET_STREAM_ITEMS_REQUEST = 0x9, // Not implemented + CMSG_GET_STREAM_ITEMS_REQUEST = 0x9, SMSG_GATEWAY_LOOKUP_RESPONSE = 0x3, // Not implemented SMSG_CONNECT_RESPONSE = 0x4, // Not implemented SMSG_PUBLISH_LIST_RESPONSE = 0x7, // Not implemented SMSG_RESULT = 0x8, // Not implemented - SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9 // Not implemented + SMSG_GET_STREAM_ITEMS_RESPONSE = 0x9 }; class GetStreamItemsRequest final : public ClientPacket -- cgit v1.2.3 From 8fdc7a6286624462ff31f7b4779142efdb0b45d2 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Tue, 14 Oct 2014 18:35:46 +0200 Subject: Scripts/ToC: fixed typo introduced in cfc0c50b5e3bc84310417c5146ce0d5901e39fc5 * also update anub arak position to sniffed values Closes #13323 --- .../TrialOfTheCrusader/boss_anubarak_trial.cpp | 1 - .../instance_trial_of_the_crusader.cpp | 25 ++++++---------------- .../TrialOfTheCrusader/trial_of_the_crusader.cpp | 19 ++++++---------- .../TrialOfTheCrusader/trial_of_the_crusader.h | 16 ++++++-------- 4 files changed, 19 insertions(+), 42 deletions(-) (limited to 'src/server') diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index d5bd2bcae7e..072dbd81fd8 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -212,7 +212,6 @@ class boss_anubarak_trial : public CreatureScript } void MoveInLineOfSight(Unit* /*who*/) override - { if (!_intro) { diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index 79fb154d6e3..e3ad891fdc7 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -68,15 +68,10 @@ class instance_trial_of_the_crusader : public InstanceMapScript else player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW, 0); - // make sure Anub'arak isnt missing and floor is destroyed after a crash + // make sure Anub'arak isnt missing if (GetBossState(BOSS_LICH_KING) == DONE && TrialCounter && GetBossState(BOSS_ANUBARAK) != DONE) - { - if (Creature* anubArak = ObjectAccessor::GetCreature(*player, GetGuidData(NPC_ANUBARAK))) - anubArak = player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); - - if (GameObject* floor = ObjectAccessor::GetGameObject(*player, GetGuidData(GO_ARGENT_COLISEUM_FLOOR))) - floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); - } + if (!ObjectAccessor::GetCreature(*player, GetGuidData(NPC_ANUBARAK))) + player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); } void OpenDoor(ObjectGuid guid) @@ -160,23 +155,15 @@ class instance_trial_of_the_crusader : public InstanceMapScript switch (go->GetEntry()) { case GO_CRUSADERS_CACHE_10: - if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL) - CrusadersCacheGUID = go->GetGUID(); - break; case GO_CRUSADERS_CACHE_25: - if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL) - CrusadersCacheGUID = go->GetGUID(); - break; case GO_CRUSADERS_CACHE_10_H: - if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC) - CrusadersCacheGUID = go->GetGUID(); - break; case GO_CRUSADERS_CACHE_25_H: - if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC) - CrusadersCacheGUID = go->GetGUID(); + CrusadersCacheGUID = go->GetGUID(); break; case GO_ARGENT_COLISEUM_FLOOR: FloorGUID = go->GetGUID(); + if (GetBossState(BOSS_LICH_KING) == DONE) + go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); break; case GO_MAIN_GATE_DOOR: MainGateDoorGUID = go->GetGUID(); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index d8ec322c57c..885017c24dd 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -207,11 +207,8 @@ class npc_announcer_toc10 : public CreatureScript creature->CastSpell(creature, SPELL_CORPSE_TELEPORT, false); creature->CastSpell(creature, SPELL_DESTROY_FLOOR_KNOCKUP, false); - Creature* anubArak = ObjectAccessor::GetCreature(*creature, instance->GetGuidData(NPC_ANUBARAK)); - if (!anubArak || !anubArak->IsAlive()) - anubArak = creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); - - instance->SetBossState(BOSS_ANUBARAK, NOT_STARTED); + if (!ObjectAccessor::GetCreature(*creature, instance->GetGuidData(NPC_ANUBARAK))) + creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); if (creature->IsVisible()) creature->SetVisible(false); @@ -319,19 +316,15 @@ class boss_lich_king_toc : public CreatureScript case 5080: { if (GameObject* go = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(GO_ARGENT_COLISEUM_FLOOR))) - { - go->SetDisplayId(DISPLAYID_DESTROYED_FLOOR); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN); - go->SetGoState(GO_STATE_ACTIVE); - } + go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED); me->CastSpell(me, SPELL_CORPSE_TELEPORT, false); me->CastSpell(me, SPELL_DESTROY_FLOOR_KNOCKUP, false); _instance->SetBossState(BOSS_LICH_KING, DONE); - Creature* temp = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK)); - if (!temp || !temp->IsAlive()) - temp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + + if (!ObjectAccessor::GetCreature(*me, _instance->GetGuidData(NPC_ANUBARAK))) + me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); _instance->SetData(TYPE_EVENT, 0); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h index cf08fb75228..e37148aa508 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h @@ -42,9 +42,7 @@ enum SpellIds enum MiscData { - DESPAWN_TIME = 1200000, - - DISPLAYID_DESTROYED_FLOOR = 9060 + DESPAWN_TIME = 1200000 }; const Position ToCSpawnLoc[]= @@ -133,7 +131,7 @@ const Position LichKingLoc[]= const Position AnubarakLoc[]= { - {787.932556f, 133.289780f, 142.612152f, 0}, // 0 - Anub'arak start location + {783.9305f, 132.9722f, 142.6711f, 3.141593f}, // 0 - Anub'arak Spawn Location (sniffed) {695.240051f, 137.834824f, 142.200000f, 0}, // 1 - Anub'arak move point location {694.886353f, 102.484665f, 142.119614f, 0}, // 3 - Nerub Spawn {694.500671f, 185.363968f, 142.117905f, 0}, // 5 - Nerub Spawn @@ -232,13 +230,13 @@ enum CreatureIds NPC_HORDE_WARLOCK = 34450, NPC_HORDE_WARRIOR = 34453, - NPC_LIGHTBANE = 34497, - NPC_DARKBANE = 34496, + NPC_LIGHTBANE = 34497, + NPC_DARKBANE = 34496, - NPC_DARK_ESSENCE = 34567, - NPC_LIGHT_ESSENCE = 34568, + NPC_DARK_ESSENCE = 34567, + NPC_LIGHT_ESSENCE = 34568, - NPC_ANUBARAK = 34564 + NPC_ANUBARAK = 34564 }; enum GameObjectIds -- cgit v1.2.3 From f6e4105306412769318f5eacf7ebcec21721a241 Mon Sep 17 00:00:00 2001 From: Exodius Date: Wed, 15 Oct 2014 19:34:09 +0200 Subject: Core/Spells: Fix Ebon Plague and Wandering Plague Ebon Plague fix by @Unholychick Wandering Plague fix by @tobmaps Thanks to @maxxx for Ebon Plague correction. --- src/server/game/Spells/SpellMgr.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index b853cf82b00..99c8b017a3c 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3195,6 +3195,9 @@ void SpellMgr::LoadSpellInfoCorrections() case 16835: spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21); break; + case 65142: // Ebon Plague + spellInfo->AttributesEx3 &= ~SPELL_ATTR3_STACK_FOR_DIFF_CASTERS; + break; case 51735: // Ebon Plague case 51734: case 51726: @@ -3224,6 +3227,7 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_MODIFY_THREAT_PERCENT; spellInfo->Effects[EFFECT_1].BasePoints = -6; // -5% break; + case 50526: // Wandering Plague case 63675: // Improved Devouring Plague spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS; break; @@ -3328,7 +3332,7 @@ void SpellMgr::LoadSpellInfoCorrections() break; case 51798: // Brewfest - Relay Race - Intro - Quest Complete case 47134: // Quest Complete - //! HACK: This spell break quest complete for alliance and on retail not used °_O + //! HACK: This spell break quest complete for alliance and on retail not used °_O spellInfo->Effects[EFFECT_0].Effect = 0; break; // ULDUAR SPELLS -- cgit v1.2.3 From 993e072813e3cef03cc945b46593bbdce2a241ee Mon Sep 17 00:00:00 2001 From: ShinDarth Date: Sat, 11 Oct 2014 16:09:48 +0200 Subject: Core/LootMgr: improved logs of missing *_loot_templates --- src/server/game/Loot/LootMgr.cpp | 22 +++++++++++----------- src/server/game/Loot/LootMgr.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index fd9a91ebb6a..921058ac502 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -272,9 +272,9 @@ void LootStore::ReportUnusedIds(LootIdSet const& lootIdSet) const TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d isn't %s and not referenced from loot, and thus useless.", GetName(), *itr, GetEntryName()); } -void LootStore::ReportNonExistingId(uint32 id) const +void LootStore::ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const { - TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d (%s) does not exist but is used as loot id in DB.", GetName(), id, GetEntryName()); + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist but it is used by %s %d", GetName(), lootId, ownerType, ownerId); } // @@ -1218,7 +1218,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo if (item->reference > 0) { if (!LootTemplates_Reference.GetLootFor(item->reference)) - LootTemplates_Reference.ReportNonExistingId(item->reference); + LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid); else if (ref_set) ref_set->erase(item->reference); } @@ -1230,7 +1230,7 @@ void LootTemplate::LootGroup::CheckLootRefs(LootTemplateMap const& /*store*/, Lo if (item->reference > 0) { if (!LootTemplates_Reference.GetLootFor(item->reference)) - LootTemplates_Reference.ReportNonExistingId(item->reference); + LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid); else if (ref_set) ref_set->erase(item->reference); } @@ -1431,7 +1431,7 @@ void LootTemplate::CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_se if (item->reference > 0) { if (!LootTemplates_Reference.GetLootFor(item->reference)) - LootTemplates_Reference.ReportNonExistingId(item->reference); + LootTemplates_Reference.ReportNonExistingId(item->reference, "Reference", item->itemid); else if (ref_set) ref_set->erase(item->reference); } @@ -1525,7 +1525,7 @@ void LoadLootTemplates_Creature() if (uint32 lootid = itr->second.lootid) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Creature.ReportNonExistingId(lootid); + LootTemplates_Creature.ReportNonExistingId(lootid, "Creature", itr->second.Entry); else lootIdSetUsed.insert(lootid); } @@ -1558,7 +1558,7 @@ void LoadLootTemplates_Disenchant() if (uint32 lootid = itr->second.DisenchantID) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Disenchant.ReportNonExistingId(lootid); + LootTemplates_Disenchant.ReportNonExistingId(lootid, "Item", itr->second.ItemId); else lootIdSetUsed.insert(lootid); } @@ -1616,7 +1616,7 @@ void LoadLootTemplates_Gameobject() if (uint32 lootid = itr->second.GetLootId()) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Gameobject.ReportNonExistingId(lootid); + LootTemplates_Gameobject.ReportNonExistingId(lootid, "Gameobject", itr->second.entry); else lootIdSetUsed.insert(lootid); } @@ -1703,7 +1703,7 @@ void LoadLootTemplates_Pickpocketing() if (uint32 lootid = itr->second.pickpocketLootId) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Pickpocketing.ReportNonExistingId(lootid); + LootTemplates_Pickpocketing.ReportNonExistingId(lootid, "Creature", itr->second.Entry); else lootIdSetUsed.insert(lootid); } @@ -1790,7 +1790,7 @@ void LoadLootTemplates_Skinning() if (uint32 lootid = itr->second.SkinLootId) { if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Skinning.ReportNonExistingId(lootid); + LootTemplates_Skinning.ReportNonExistingId(lootid, "Creature", itr->second.Entry); else lootIdSetUsed.insert(lootid); } @@ -1834,7 +1834,7 @@ void LoadLootTemplates_Spell() // ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example if (!(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) || (spellInfo->Attributes & SPELL_ATTR0_TRADESPELL)) { - LootTemplates_Spell.ReportNonExistingId(spell_id); + LootTemplates_Spell.ReportNonExistingId(spell_id, "Spell", spellInfo->Id); } } else diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 1685996fd03..7d8309f43a6 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -216,7 +216,7 @@ class LootStore uint32 LoadAndCollectLootIds(LootIdSet& ids_set); void CheckLootRefs(LootIdSet* ref_set = NULL) const; // check existence reference and remove it from ref_set void ReportUnusedIds(LootIdSet const& ids_set) const; - void ReportNonExistingId(uint32 id) const; + void ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const; bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); } bool HaveQuestLootFor(uint32 loot_id) const; -- cgit v1.2.3 From ee5eaab598e445e3926edf6e12b1b2b4477c2594 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Thu, 16 Oct 2014 22:47:02 +0200 Subject: Core/Players: Fix players not being notified if on loading screen Fix packets not being sent to players on loading screen even if the system supports these packets to be queued and sent till the player is in world. There might be additional cases where this applies, please report back if you find any. Fixes #11339 --- src/server/game/Accounts/AccountMgr.cpp | 2 +- src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 12 +++---- src/server/game/Battlefield/Battlefield.cpp | 2 +- src/server/game/Battlegrounds/Arena.cpp | 2 +- src/server/game/Battlegrounds/ArenaTeam.cpp | 10 +++--- src/server/game/Battlegrounds/Battleground.cpp | 1 + .../game/Battlegrounds/BattlegroundQueue.cpp | 10 +++--- src/server/game/Calendar/CalendarMgr.cpp | 18 +++++----- src/server/game/Chat/Channels/Channel.cpp | 10 +++--- src/server/game/Chat/Chat.cpp | 4 +-- src/server/game/DungeonFinding/LFGMgr.cpp | 22 ++++++------ src/server/game/DungeonFinding/LFGScripts.cpp | 2 +- src/server/game/Entities/Creature/Creature.cpp | 2 +- src/server/game/Entities/GameObject/GameObject.cpp | 2 +- src/server/game/Entities/Player/Player.cpp | 9 ++--- src/server/game/Entities/Player/SocialMgr.cpp | 2 +- src/server/game/Globals/ObjectAccessor.cpp | 5 +++ src/server/game/Globals/ObjectAccessor.h | 3 ++ src/server/game/Globals/ObjectMgr.cpp | 8 ++--- src/server/game/Grids/Notifiers/GridNotifiers.cpp | 2 +- src/server/game/Groups/Group.cpp | 40 +++++++++++----------- src/server/game/Guilds/Guild.cpp | 8 ++--- src/server/game/Guilds/Guild.h | 3 +- src/server/game/Handlers/ChatHandler.cpp | 2 +- src/server/game/Handlers/GroupHandler.cpp | 6 ++-- src/server/game/Handlers/LFGHandler.cpp | 4 +-- src/server/game/Handlers/MailHandler.cpp | 4 +-- src/server/game/Handlers/MiscHandler.cpp | 2 +- src/server/game/Handlers/PetitionsHandler.cpp | 8 ++--- src/server/game/Handlers/QueryHandler.cpp | 2 +- src/server/game/Mails/Mail.cpp | 2 +- src/server/scripts/Commands/cs_group.cpp | 2 +- src/server/scripts/Commands/cs_ticket.cpp | 28 ++++++--------- 33 files changed, 119 insertions(+), 120 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 0c90dde5ea8..79b9557fc2b 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -84,7 +84,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId) ObjectGuid guid(HIGHGUID_PLAYER, (*result)[0].GetUInt32()); // Kick if player is online - if (Player* p = ObjectAccessor::FindPlayer(guid)) + if (Player* p = ObjectAccessor::FindConnectedPlayer(guid)) { WorldSession* s = p->GetSession(); s->KickPlayer(); // mark session to remove at next session list update diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 8955fc9014f..53267a6e565 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -93,7 +93,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& uint32 bidderAccId = 0; ObjectGuid bidderGuid(HIGHGUID_PLAYER, auction->bidder); - Player* bidder = ObjectAccessor::FindPlayer(bidderGuid); + Player* bidder = ObjectAccessor::FindConnectedPlayer(bidderGuid); // data for gm.log std::string bidderName; bool logGmTrade = false; @@ -157,7 +157,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTransaction& trans) { ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner); - Player* owner = ObjectAccessor::FindPlayer(owner_guid); + Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid); uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid); // owner exist (online or offline) if (owner || owner_accId) @@ -169,7 +169,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTrans void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransaction& trans) { ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner); - Player* owner = ObjectAccessor::FindPlayer(owner_guid); + Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid); uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid); // owner exist if (owner || owner_accId) @@ -200,7 +200,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti return; ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner); - Player* owner = ObjectAccessor::FindPlayer(owner_guid); + Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid); uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid); // owner exist if (owner || owner_accId) @@ -223,7 +223,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans) { ObjectGuid oldBidder_guid(HIGHGUID_PLAYER, auction->bidder); - Player* oldBidder = ObjectAccessor::FindPlayer(oldBidder_guid); + Player* oldBidder = ObjectAccessor::FindConnectedPlayer(oldBidder_guid); uint32 oldBidder_accId = 0; if (!oldBidder) @@ -245,7 +245,7 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans) { ObjectGuid bidder_guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder); - Player* bidder = ObjectAccessor::FindPlayer(bidder_guid); + Player* bidder = ObjectAccessor::FindConnectedPlayer(bidder_guid); uint32 bidder_accId = 0; if (!bidder) diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 76b6e66b219..8b7ed103190 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -421,7 +421,7 @@ void Battlefield::BroadcastPacketToQueue(WorldPacket& data) const { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_PlayersInQueue[team].begin(); itr != m_PlayersInQueue[team].end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(*itr)) player->SendDirectMessage(&data); } diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index f523ec6a09b..6b631a5d357 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -177,7 +177,7 @@ void Arena::EndBattleground(uint32 winner) if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) for (auto const& score : PlayerScores) - if (Player* player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, score.first))) + if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, score.first))) { TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3), diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 6831cc42f49..19617a8dff2 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -410,7 +410,7 @@ void ArenaTeam::Roster(WorldSession* session) for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { - player = ObjectAccessor::FindPlayer(itr->Guid); + player = ObjectAccessor::FindConnectedPlayer(itr->Guid); data << uint64(itr->Guid); // guid data << uint8((player ? 1 : 0)); // online flag @@ -467,7 +467,7 @@ void ArenaTeam::NotifyStatsChanged() // This is called after a rated match ended // Updates arena team stats for every member of the team (not only the ones who participated!) for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(itr->Guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(itr->Guid)) SendStats(player->GetSession()); } @@ -514,7 +514,7 @@ void ArenaTeamMember::ModifyMatchmakerRating(int32 mod, uint32 /*slot*/) void ArenaTeam::BroadcastPacket(WorldPacket* packet) { for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer(itr->Guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(itr->Guid)) player->GetSession()->SendPacket(packet); } @@ -625,7 +625,7 @@ uint32 ArenaTeam::GetAverageMMR(Group* group) const for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) { // Skip if player is not online - if (!ObjectAccessor::FindPlayer(itr->Guid)) + if (!ObjectAccessor::FindConnectedPlayer(itr->Guid)) continue; // Skip if player is not member of group @@ -713,7 +713,7 @@ void ArenaTeam::FinishGame(int32 mod) // Check if rating related achivements are met for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr) - if (Player* member = ObjectAccessor::FindPlayer(itr->Guid)) + if (Player* member = ObjectAccessor::FindConnectedPlayer(itr->Guid)) member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING, Stats.Rating, Type); } diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 99b1f240e5e..7032610cad5 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -564,6 +564,7 @@ Player* Battleground::_GetPlayer(ObjectGuid guid, bool offlineRemove, char const Player* player = NULL; if (!offlineRemove) { + // should this be ObjectAccessor::FindConnectedPlayer() to return players teleporting ? player = ObjectAccessor::FindPlayer(guid); if (!player) TC_LOG_ERROR("bg.battleground", "Battleground::%s: player (%s) not found for BG (map: %u, instance id: %u)!", diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index a3b0051e697..3993ec0a9ba 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -362,7 +362,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(group->ArenaTeamId)) { TC_LOG_DEBUG("bg.battleground", "UPDATING memberLost's personal arena rating for %s by opponents rating: %u", guid.ToString().c_str(), group->OpponentsTeamRating); - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) at->MemberLost(player, group->OpponentsMatchmakerRating); else at->OfflineMemberLost(guid, group->OpponentsMatchmakerRating); @@ -385,7 +385,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) { // remove next player, this is recursive // first send removal information - if (Player* plr2 = ObjectAccessor::FindPlayer(group->Players.begin()->first)) + if (Player* plr2 = ObjectAccessor::FindConnectedPlayer(group->Players.begin()->first)) { Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(group->BgTypeId); BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(group->BgTypeId, group->ArenaType); @@ -449,7 +449,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, for (std::map::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr) { // get the player - Player* player = ObjectAccessor::FindPlayer(itr->first); + Player* player = ObjectAccessor::FindConnectedPlayer(itr->first); // if offline, skip him, this should not happen - player is removed from queue when he logs out if (!player) continue; @@ -980,7 +980,7 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { - Player* player = ObjectAccessor::FindPlayer(m_PlayerGuid); + Player* player = ObjectAccessor::FindConnectedPlayer(m_PlayerGuid); // player logged off (we should do nothing, he is correctly removed from queue in another procedure) if (!player) return true; @@ -1023,7 +1023,7 @@ void BGQueueInviteEvent::Abort(uint64 /*e_time*/) */ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { - Player* player = ObjectAccessor::FindPlayer(m_PlayerGuid); + Player* player = ObjectAccessor::FindConnectedPlayer(m_PlayerGuid); if (!player) // player logged off (we should do nothing, he is correctly removed from queue in another procedure) return true; diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index d85f3e7e9c5..2a5fd677c09 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -350,7 +350,7 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(ObjectGuid guid) if (CalendarEvent* event = GetEvent(itr->first)) // NULL check added as attempt to fix #11512 events.insert(event); - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr) if ((*itr)->GetGuildId() == player->GetGuildId()) events.insert(*itr); @@ -424,7 +424,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) bool hasStatusTime = statusTime != 946684800; // 01/01/2000 00:00:00 ObjectGuid invitee = invite.GetInviteeGUID(); - Player* player = ObjectAccessor::FindPlayer(invitee); + Player* player = ObjectAccessor::FindConnectedPlayer(invitee); uint8 level = player ? player->getLevel() : Player::GetLevelFromDB(invitee); @@ -441,7 +441,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const& invite) if (!calendarEvent) // Pre-invite { - if (Player* playerSender = ObjectAccessor::FindPlayer(invite.GetSenderGUID())) + if (Player* playerSender = ObjectAccessor::FindConnectedPlayer(invite.GetSenderGUID())) playerSender->SendDirectMessage(&data); } else @@ -538,13 +538,13 @@ void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEven guild->BroadcastPacket(&data); } else - if (Player* player = ObjectAccessor::FindPlayer(invite.GetInviteeGUID())) + if (Player* player = ObjectAccessor::FindConnectedPlayer(invite.GetInviteeGUID())) player->SendDirectMessage(&data); } void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarSendEventType sendType) { - Player* player = ObjectAccessor::FindPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(guid); if (!player) return; @@ -590,7 +590,7 @@ void CalendarMgr::SendCalendarEvent(ObjectGuid guid, CalendarEvent const& calend void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEvent const& calendarEvent, CalendarInviteStatus status) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { WorldPacket data(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, 8 + 4 + 4 + 1); data << uint64(calendarEvent.GetEventId()); @@ -604,7 +604,7 @@ void CalendarMgr::SendCalendarEventInviteRemoveAlert(ObjectGuid guid, CalendarEv void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { WorldPacket data(SMSG_CALENDAR_CLEAR_PENDING_ACTION, 0); player->SendDirectMessage(&data); @@ -613,7 +613,7 @@ void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid) void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= NULL*/) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { WorldPacket data(SMSG_CALENDAR_COMMAND_RESULT, 0); data << uint32(0); @@ -646,7 +646,7 @@ void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEve // Send packet to all invitees if event is non-guild, in other case only to non-guild invitees (packet was broadcasted for them) CalendarInviteStore invites = _invites[calendarEvent.GetEventId()]; for (CalendarInviteStore::iterator itr = invites.begin(); itr != invites.end(); ++itr) - if (Player* player = ObjectAccessor::FindPlayer((*itr)->GetInviteeGUID())) + if (Player* player = ObjectAccessor::FindConnectedPlayer((*itr)->GetInviteeGUID())) if (!calendarEvent.IsGuildEvent() || (calendarEvent.IsGuildEvent() && player->GetGuildId() != calendarEvent.GetGuildId())) player->SendDirectMessage(&packet); } diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 654ce8da2b9..cc2d3279daa 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -543,7 +543,7 @@ void Channel::List(Player const* player) uint32 count = 0; for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) { - Player* member = ObjectAccessor::FindPlayer(i->first); + Player* member = ObjectAccessor::FindConnectedPlayer(i->first); // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all @@ -621,7 +621,7 @@ void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang) } WorldPacket data; - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); else ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, _name); @@ -723,7 +723,7 @@ void Channel::SetOwner(ObjectGuid guid, bool exclaim) void Channel::SendToAll(WorldPacket* data, ObjectGuid guid) { for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) - if (Player* player = ObjectAccessor::FindPlayer(i->first)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first)) if (!guid || !player->GetSocial()->HasIgnore(guid.GetCounter())) player->GetSession()->SendPacket(data); } @@ -732,13 +732,13 @@ void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who) { for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i) if (i->first != who) - if (Player* player = ObjectAccessor::FindPlayer(i->first)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first)) player->GetSession()->SendPacket(data); } void Channel::SendToOne(WorldPacket* data, ObjectGuid who) { - if (Player* player = ObjectAccessor::FindPlayer(who)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(who)) player->GetSession()->SendPacket(data); } diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 4099b3ac3fd..30405128ab8 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -747,7 +747,7 @@ Player* ChatHandler::getSelectedPlayer() if (!selected) return m_session->GetPlayer(); - return ObjectAccessor::FindPlayer(selected); + return ObjectAccessor::FindConnectedPlayer(selected); } Unit* ChatHandler::getSelectedUnit() @@ -792,7 +792,7 @@ Player* ChatHandler::getSelectedPlayerOrSelf() return m_session->GetPlayer(); // first try with selected target - Player* targetPlayer = ObjectAccessor::FindPlayer(selected); + Player* targetPlayer = ObjectAccessor::FindConnectedPlayer(selected); // if the target is not a player, then return self if (!targetPlayer) targetPlayer = m_session->GetPlayer(); diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 7d662c2fc75..c2042e9664b 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1358,7 +1358,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId) } Player* player = ObjectAccessor::FindPlayer(guid); - if (!player || !player->IsInWorld()) + if (!player) { TC_LOG_DEBUG("lfg.dungeon.finish", "Group: %s, Player: %s not found in world", gguid.ToString().c_str(), guid.ToString().c_str()); continue; @@ -1771,56 +1771,56 @@ ObjectGuid LFGMgr::GetLeader(ObjectGuid guid) bool LFGMgr::HasIgnore(ObjectGuid guid1, ObjectGuid guid2) { - Player* plr1 = ObjectAccessor::FindPlayer(guid1); - Player* plr2 = ObjectAccessor::FindPlayer(guid2); + Player* plr1 = ObjectAccessor::FindConnectedPlayer(guid1); + Player* plr2 = ObjectAccessor::FindConnectedPlayer(guid2); return plr1 && plr2 && (plr1->GetSocial()->HasIgnore(guid2.GetCounter()) || plr2->GetSocial()->HasIgnore(guid1.GetCounter())); } void LFGMgr::SendLfgRoleChosen(ObjectGuid guid, ObjectGuid pguid, uint8 roles) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgRoleChosen(pguid, roles); } void LFGMgr::SendLfgRoleCheckUpdate(ObjectGuid guid, LfgRoleCheck const& roleCheck) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgRoleCheckUpdate(roleCheck); } void LFGMgr::SendLfgUpdatePlayer(ObjectGuid guid, LfgUpdateData const& data) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgUpdatePlayer(data); } void LFGMgr::SendLfgUpdateParty(ObjectGuid guid, LfgUpdateData const& data) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgUpdateParty(data); } void LFGMgr::SendLfgJoinResult(ObjectGuid guid, LfgJoinResultData const& data) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgJoinResult(data); } void LFGMgr::SendLfgBootProposalUpdate(ObjectGuid guid, LfgPlayerBoot const& boot) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgBootProposalUpdate(boot); } void LFGMgr::SendLfgUpdateProposal(ObjectGuid guid, LfgProposal const& proposal) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgUpdateProposal(proposal); } void LFGMgr::SendLfgQueueStatus(ObjectGuid guid, LfgQueueStatusData const& data) { - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) player->GetSession()->SendLfgQueueStatus(data); } diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 68ea1cd1030..774f814ffb4 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -184,7 +184,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, ObjectGuid guid, RemoveMethod } if (isLFG && state != LFG_STATE_FINISHED_DUNGEON) // Need more players to finish the dungeon - if (Player* leader = ObjectAccessor::FindPlayer(sLFGMgr->GetLeader(gguid))) + if (Player* leader = ObjectAccessor::FindConnectedPlayer(sLFGMgr->GetLeader(gguid))) leader->GetSession()->SendLfgOfferContinue(sLFGMgr->GetDungeon(gguid, false)); } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index b8fd0195038..8adc98b3766 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -871,7 +871,7 @@ Player* Creature::GetLootRecipient() const { if (!m_lootRecipient) return NULL; - return ObjectAccessor::FindPlayer(m_lootRecipient); + return ObjectAccessor::FindConnectedPlayer(m_lootRecipient); } Group* Creature::GetLootRecipientGroup() const diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 98b49c46f83..290ac87181d 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2111,7 +2111,7 @@ Player* GameObject::GetLootRecipient() const { if (!m_lootRecipient) return NULL; - return ObjectAccessor::FindPlayer(m_lootRecipient); + return ObjectAccessor::FindConnectedPlayer(m_lootRecipient); } Group* GameObject::GetLootRecipientGroup() const diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0a2dc3366d7..74863b7e6f2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4814,11 +4814,8 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe { if (Player* pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, (*resultFriends)[0].GetUInt32()))) { - if (pFriend->IsInWorld()) - { - pFriend->GetSocial()->RemoveFromSocialList(guid, false); - sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false); - } + pFriend->GetSocial()->RemoveFromSocialList(guid, false); + sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false); } } while (resultFriends->NextRow()); } @@ -21123,7 +21120,7 @@ void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type) ObjectGuid petitionguid = ObjectGuid(HIGHGUID_ITEM, fields[1].GetUInt32()); // send update if charter owner in game - Player* owner = ObjectAccessor::FindPlayer(ownerguid); + Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid); if (owner) owner->GetSession()->SendPetitionQueryOpcode(petitionguid); } while (result->NextRow()); diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index 498cdfecf6e..55e48e0623c 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -294,7 +294,7 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet) if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND)) { Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, itr->first)); - if (!target || !target->IsInWorld()) + if (!target) continue; WorldSession* session = target->GetSession(); diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 50b006a89bd..105ffc0be94 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -203,6 +203,11 @@ Player* ObjectAccessor::FindPlayer(ObjectGuid guid) return GetObjectInWorld(guid, (Player*)NULL); } +Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid guid) +{ + return HashMapHolder::Find(guid); +} + Unit* ObjectAccessor::FindUnit(ObjectGuid guid) { return GetObjectInWorld(guid, (Unit*)NULL); diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 95d0b70f429..b0e3eb58529 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -169,6 +169,9 @@ class ObjectAccessor static Unit* FindUnit(ObjectGuid); static Player* FindPlayerByName(std::string const& name); + // this returns Player even if he is not in world, for example teleporting + static Player* FindConnectedPlayer(ObjectGuid); + // when using this, you must use the hashmapholder's lock static HashMapHolder::MapType const& GetPlayers() { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 0fc8bcc73d3..d27596fc990 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2136,7 +2136,7 @@ ObjectGuid ObjectMgr::GetPlayerGUIDByName(std::string const& name) const bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid guid, std::string& name) const { // prevent DB access for online player - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { name = player->GetName(); return true; @@ -2160,7 +2160,7 @@ bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid guid, std::string& name) const uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid guid) const { // prevent DB access for online player - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { return Player::TeamForRace(player->getRace()); } @@ -2183,7 +2183,7 @@ uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid guid) const uint32 ObjectMgr::GetPlayerAccountIdByGUID(ObjectGuid guid) const { // prevent DB access for online player - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { return player->GetSession()->GetAccountId(); } @@ -5510,7 +5510,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) Player* player = NULL; if (serverUp) - player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, m->receiver)); + player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, m->receiver)); if (player && player->m_mailsLoaded) { // this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 854e5cffe5d..8c8ac52d91f 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -73,7 +73,7 @@ void VisibleNotifier::SendToSelf() if (it->IsPlayer()) { Player* player = ObjectAccessor::FindPlayer(*it); - if (player && player->IsInWorld() && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) + if (player && !player->isNeedNotify(NOTIFY_VISIBILITY_CHANGED)) player->UpdateVisibilityOf(&i_player); } } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index b203ccb8bb9..9854feaffba 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -495,7 +495,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R // remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG/BF allow 1 member group) if (GetMembersCount() > ((isBGGroup() || isLFGGroup() || isBFGroup()) ? 1u : 2u)) { - Player* player = ObjectAccessor::FindPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(guid); if (player) { // Battleground group handling @@ -579,7 +579,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R { for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) { - if (ObjectAccessor::FindPlayer(itr->guid)) + if (ObjectAccessor::FindConnectedPlayer(itr->guid)) { ChangeLeader(itr->guid); break; @@ -591,7 +591,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R if (isLFGGroup() && GetMembersCount() == 1) { - Player* leader = ObjectAccessor::FindPlayer(GetLeaderGUID()); + Player* leader = ObjectAccessor::FindConnectedPlayer(GetLeaderGUID()); uint32 mapId = sLFGMgr->GetDungeonMapId(GetGUID()); if (!mapId || !leader || (leader->IsAlive() && leader->GetMapId() != mapId)) { @@ -620,7 +620,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid) if (slot == m_memberSlots.end()) return; - Player* newLeader = ObjectAccessor::FindPlayer(slot->guid); + Player* newLeader = ObjectAccessor::FindConnectedPlayer(slot->guid); // Don't allow switching leader to offline players if (!newLeader) @@ -668,7 +668,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid) CharacterDatabase.CommitTransaction(trans); } - if (Player* oldLeader = ObjectAccessor::FindPlayer(m_leaderGuid)) + if (Player* oldLeader = ObjectAccessor::FindConnectedPlayer(m_leaderGuid)) oldLeader->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); newLeader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); @@ -688,7 +688,7 @@ void Group::Disband(bool hideDestroy /* = false */) Player* player; for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { - player = ObjectAccessor::FindPlayer(citr->guid); + player = ObjectAccessor::FindConnectedPlayer(citr->guid); if (!player) continue; @@ -786,7 +786,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r) for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr) { - Player* p = ObjectAccessor::FindPlayer(itr->first); + Player* p = ObjectAccessor::FindConnectedPlayer(itr->first); if (!p || !p->GetSession()) continue; @@ -832,7 +832,7 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) { - Player* p = ObjectAccessor::FindPlayer(itr->first); + Player* p = ObjectAccessor::FindConnectedPlayer(itr->first); if (!p || !p->GetSession()) continue; @@ -855,7 +855,7 @@ void Group::SendLootRollWon(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) { - Player* p = ObjectAccessor::FindPlayer(itr->first); + Player* p = ObjectAccessor::FindConnectedPlayer(itr->first); if (!p || !p->GetSession()) continue; @@ -875,7 +875,7 @@ void Group::SendLootAllPassed(Roll const& roll) for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr) { - Player* player = ObjectAccessor::FindPlayer(itr->first); + Player* player = ObjectAccessor::FindConnectedPlayer(itr->first); if (!player || !player->GetSession()) continue; @@ -967,7 +967,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) { for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr) { - Player* p = ObjectAccessor::FindPlayer(itr->first); + Player* p = ObjectAccessor::FindConnectedPlayer(itr->first); if (!p || !p->GetSession()) continue; @@ -1110,7 +1110,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) //Broadcast Pass and Send Rollstart for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr) { - Player* p = ObjectAccessor::FindPlayer(itr->first); + Player* p = ObjectAccessor::FindConnectedPlayer(itr->first); if (!p || !p->GetSession()) continue; @@ -1173,7 +1173,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) //Broadcast Pass and Send Rollstart for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr) { - Player* p = ObjectAccessor::FindPlayer(itr->first); + Player* p = ObjectAccessor::FindConnectedPlayer(itr->first); if (!p || !p->GetSession()) continue; @@ -1340,7 +1340,7 @@ void Group::CountTheRoll(Rolls::iterator rollI) } } SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, ROLL_NEED, *roll); - player = ObjectAccessor::FindPlayer(maxguid); + player = ObjectAccessor::FindConnectedPlayer(maxguid); if (player && player->GetSession()) { @@ -1389,7 +1389,7 @@ void Group::CountTheRoll(Rolls::iterator rollI) } } SendLootRollWon(ObjectGuid::Empty, maxguid, maxresul, rollvote, *roll); - player = ObjectAccessor::FindPlayer(maxguid); + player = ObjectAccessor::FindConnectedPlayer(maxguid); if (player && player->GetSession()) { @@ -1506,7 +1506,7 @@ void Group::SendUpdate() void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot) { - Player* player = ObjectAccessor::FindPlayer(playerGUID); + Player* player = ObjectAccessor::FindConnectedPlayer(playerGUID); if (!player || !player->GetSession() || player->GetGroup() != this) return; @@ -1541,7 +1541,7 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot) if (slot->guid == citr->guid) continue; - Player* member = ObjectAccessor::FindPlayer(citr->guid); + Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid); uint8 onlineState = (member && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0); @@ -1619,7 +1619,7 @@ void Group::OfflineReadyCheck() { for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { - Player* player = ObjectAccessor::FindPlayer(citr->guid); + Player* player = ObjectAccessor::FindConnectedPlayer(citr->guid); if (!player || !player->GetSession()) { WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9); @@ -1702,7 +1702,7 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group) } // In case the moved player is online, update the player object with the new sub group references - if (Player* player = ObjectAccessor::FindPlayer(guid)) + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { if (player->GetGroup() == this) player->GetGroupRef().setSubGroup(group); @@ -2127,7 +2127,7 @@ void Group::BroadcastGroupUpdate(void) for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { Player* pp = ObjectAccessor::FindPlayer(citr->guid); - if (pp && pp->IsInWorld()) + if (pp) { pp->ForceValuesUpdateAtIndex(UNIT_FIELD_BYTES_2); pp->ForceValuesUpdateAtIndex(UNIT_FIELD_FACTIONTEMPLATE); diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 8261811d8e0..c655be6291f 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2150,7 +2150,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin WorldPacket data; ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player* player = itr->second->FindPlayer()) + if (Player* player = itr->second->FindConnectedPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow())) player->GetSession()->SendPacket(&data); @@ -2161,7 +2161,7 @@ void Guild::BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const { for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (itr->second->IsRank(rankId)) - if (Player* player = itr->second->FindPlayer()) + if (Player* player = itr->second->FindConnectedPlayer()) player->GetSession()->SendPacket(packet); } @@ -2208,7 +2208,7 @@ void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 max // Members handling bool Guild::AddMember(ObjectGuid guid, uint8 rankId) { - Player* player = ObjectAccessor::FindPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(guid); // Player cannot be in guild if (player) { @@ -2285,7 +2285,7 @@ bool Guild::AddMember(ObjectGuid guid, uint8 rankId) void Guild::DeleteMember(ObjectGuid guid, bool isDisbanding, bool isKicked, bool canDeleteGuild) { uint32 lowguid = guid.GetCounter(); - Player* player = ObjectAccessor::FindPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(guid); // Guild master can be deleted when loading guild and guid doesn't exist in characters table // or when he is removed from guild by gm command diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index f0daa257ae6..94bd5d39a2f 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -342,6 +342,7 @@ private: void ResetValues(); inline Player* FindPlayer() const { return ObjectAccessor::FindPlayer(m_guid); } + inline Player* FindConnectedPlayer() const { return ObjectAccessor::FindConnectedPlayer(m_guid); } private: uint32 m_guildId; @@ -723,7 +724,7 @@ public: void BroadcastWorker(Do& _do, Player* except = NULL) { for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) - if (Player* player = itr->second->FindPlayer()) + if (Player* player = itr->second->FindConnectedPlayer()) if (player != except) _do(player); } diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index b33f2364683..c4539680b82 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -605,7 +605,7 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) recvData >> iguid; recvData >> unk; // probably related to spam reporting - Player* player = ObjectAccessor::FindPlayer(iguid); + Player* player = ObjectAccessor::FindConnectedPlayer(iguid); if (!player || !player->GetSession()) return; diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index a7ce1f8533a..632f28da48f 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -257,7 +257,7 @@ void WorldSession::HandleGroupDeclineOpcode(WorldPacket & /*recvData*/) return; // Remember leader if online (group pointer will be invalid if group gets disbanded) - Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); + Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID()); // uninvite, group can be deleted GetPlayer()->UninviteFromGroup(); @@ -372,7 +372,7 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) ObjectGuid guid; recvData >> guid; - Player* player = ObjectAccessor::FindPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(guid); Group* group = GetPlayer()->GetGroup(); if (!group || !player) @@ -551,7 +551,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData) if (guid.IsPlayer()) { - Player* target = ObjectAccessor::FindPlayer(guid); + Player* target = ObjectAccessor::FindConnectedPlayer(guid); if (!target || target->IsHostileTo(GetPlayer())) return; diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index 3c7f116c8f6..f6954b8fd0f 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -424,7 +424,7 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck) data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles - Player* player = ObjectAccessor::FindPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(guid); data << uint8(player ? player->getLevel() : 0); // Level for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it) @@ -437,7 +437,7 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck) data << uint64(guid); // Guid data << uint8(roles > 0); // Ready data << uint32(roles); // Roles - player = ObjectAccessor::FindPlayer(guid); + player = ObjectAccessor::FindConnectedPlayer(guid); data << uint8(player ? player->getLevel() : 0);// Level } } diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 6ea3ae69786..b79cbecda10 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -144,7 +144,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) return; } - Player* receiver = ObjectAccessor::FindPlayer(receiverGuid); + Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid); uint32 receiverTeam = 0; uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails @@ -500,7 +500,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail { ObjectGuid sender_guid(HIGHGUID_PLAYER, m->sender); - Player* receiver = ObjectAccessor::FindPlayer(sender_guid); + Player* receiver = ObjectAccessor::FindConnectedPlayer(sender_guid); uint32 sender_accId = 0; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 50fde106824..a9e69ff3f8d 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -591,7 +591,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std else { Player* pFriend = ObjectAccessor::FindPlayer(friendGuid); - if (pFriend && pFriend->IsInWorld() && pFriend->IsVisibleGloballyFor(GetPlayer())) + if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer())) friendResult = FRIEND_ADDED_ONLINE; else friendResult = FRIEND_ADDED_OFFLINE; diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index f838dccde36..1e6dc1adbb9 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -555,7 +555,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) SendPacket(&data); // update for owner if online - if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid)) + if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerGuid)) owner->GetSession()->SendPacket(&data); return; } @@ -585,7 +585,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs); // update for owner if online - if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid)) + if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerGuid)) owner->GetSession()->SendPacket(&data); } @@ -609,7 +609,7 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData) Field* fields = result->Fetch(); ObjectGuid ownerguid(HIGHGUID_PLAYER, 0, fields[0].GetUInt32()); - Player* owner = ObjectAccessor::FindPlayer(ownerguid); + Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid); if (owner) // petition owner online { WorldPacket data(MSG_PETITION_DECLINE, 8); @@ -630,7 +630,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) recvData >> petitionguid; // petition guid recvData >> plguid; // player guid - player = ObjectAccessor::FindPlayer(plguid); + player = ObjectAccessor::FindConnectedPlayer(plguid); if (!player) return; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 661ecf4652e..929f34c67de 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -33,7 +33,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) { - Player* player = ObjectAccessor::FindPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(guid); CharacterNameData const* nameData = sWorld->GetCharacterNameData(guid); WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+10)); diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index 2459e468c25..820a54b9760 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -131,7 +131,7 @@ void MailDraft::deleteIncludedItems(SQLTransaction& trans, bool inDB /*= false*/ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, SQLTransaction& trans) { ObjectGuid receiverGuid(HIGHGUID_PLAYER, receiver_guid); - Player* receiver = ObjectAccessor::FindPlayer(receiverGuid); + Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid); uint32 rc_account = 0; if (!receiver) diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp index e39aca6f6a7..a558d977b85 100644 --- a/src/server/scripts/Commands/cs_group.cpp +++ b/src/server/scripts/Commands/cs_group.cpp @@ -343,7 +343,7 @@ public: // Check if iterator is online. If is... Player* p = ObjectAccessor::FindPlayer((*itr).guid); - if (p && p->IsInWorld()) + if (p) { // ... than, it prints information like "is online", where he is, etc... onlineState = "online"; diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index 674658f41ff..23858ce67e6 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -162,12 +162,9 @@ public: // Inform player, who submitted this ticket, that it is closed if (Player* submitter = ticket->GetPlayer()) { - if (submitter->IsInWorld()) - { - WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4); - data << uint32(GMTICKET_RESPONSE_TICKET_DELETED); - submitter->GetSession()->SendPacket(&data); - } + WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4); + data << uint32(GMTICKET_RESPONSE_TICKET_DELETED); + submitter->GetSession()->SendPacket(&data); } return true; } @@ -232,8 +229,7 @@ public: } if (Player* player = ticket->GetPlayer()) - if (player->IsInWorld()) - ticket->SendResponse(player->GetSession()); + ticket->SendResponse(player->GetSession()); SQLTransaction trans = SQLTransaction(NULL); ticket->SetCompleted(); @@ -273,13 +269,10 @@ public: if (Player* player = ticket->GetPlayer()) { - if (player->IsInWorld()) - { - // Force abandon ticket - WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4); - data << uint32(GMTICKET_RESPONSE_TICKET_DELETED); - player->GetSession()->SendPacket(&data); - } + // Force abandon ticket + WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4); + data << uint32(GMTICKET_RESPONSE_TICKET_DELETED); + player->GetSession()->SendPacket(&data); } return true; @@ -301,8 +294,7 @@ public: ticket->SetEscalatedStatus(TICKET_IN_ESCALATION_QUEUE); if (Player* player = ticket->GetPlayer()) - if (player->IsInWorld()) - sTicketMgr->SendTicket(player->GetSession(), ticket); + sTicketMgr->SendTicket(player->GetSession(), ticket); sTicketMgr->UpdateLastChange(); return true; @@ -372,7 +364,7 @@ public: // Get security level of player, whom this ticket is assigned to uint32 security = SEC_PLAYER; Player* assignedPlayer = ticket->GetAssignedPlayer(); - if (assignedPlayer && assignedPlayer->IsInWorld()) + if (assignedPlayer) security = assignedPlayer->GetSession()->GetSecurity(); else { -- cgit v1.2.3 From f773a9e05340d4de7dd16d0e375a12611c3995b6 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 17 Oct 2014 22:48:06 +0200 Subject: Core: Implemented IPC (Inter-process communication) between worldserver and bnetserver using ZeroMQ library. * Implemented ToonReady and ToonLoggedOut battle.net packets --- CMakeLists.txt | 1 + cmake/macros/FindZMQ.cmake | 75 +++ dep/CMakeLists.txt | 1 + dep/PackageList.txt | 4 + dep/zmqpp/CMakeLists.txt | 31 + dep/zmqpp/zmqpp/compatibility.hpp | 97 +++ dep/zmqpp/zmqpp/context.cpp | 54 ++ dep/zmqpp/zmqpp/context.hpp | 184 ++++++ dep/zmqpp/zmqpp/context_options.hpp | 26 + dep/zmqpp/zmqpp/exception.hpp | 87 +++ dep/zmqpp/zmqpp/frame.cpp | 95 +++ dep/zmqpp/zmqpp/frame.hpp | 58 ++ dep/zmqpp/zmqpp/inet.hpp | 171 +++++ dep/zmqpp/zmqpp/message.cpp | 454 +++++++++++++ dep/zmqpp/zmqpp/message.hpp | 253 ++++++++ dep/zmqpp/zmqpp/poller.cpp | 182 ++++++ dep/zmqpp/zmqpp/poller.hpp | 186 ++++++ dep/zmqpp/zmqpp/socket.cpp | 758 ++++++++++++++++++++++ dep/zmqpp/zmqpp/socket.hpp | 500 ++++++++++++++ dep/zmqpp/zmqpp/socket_options.hpp | 80 +++ dep/zmqpp/zmqpp/socket_types.hpp | 148 +++++ dep/zmqpp/zmqpp/zmqpp.cpp | 30 + dep/zmqpp/zmqpp/zmqpp.hpp | 111 ++++ src/server/CMakeLists.txt | 1 + src/server/bnetserver/CMakeLists.txt | 6 + src/server/bnetserver/Main.cpp | 16 +- src/server/bnetserver/Packets/BitStream.h | 12 +- src/server/bnetserver/Packets/FriendsPackets.cpp | 2 +- src/server/bnetserver/Packets/PacketManager.cpp | 4 +- src/server/bnetserver/Packets/WoWRealmPackets.cpp | 52 +- src/server/bnetserver/Packets/WoWRealmPackets.h | 27 + src/server/bnetserver/Realms/RealmList.cpp | 24 +- src/server/bnetserver/Realms/RealmList.h | 11 +- src/server/bnetserver/Realms/WorldListener.cpp | 109 ++++ src/server/bnetserver/Realms/WorldListener.h | 63 ++ src/server/bnetserver/Server/Session.h | 2 +- src/server/bnetserver/Server/SessionManager.cpp | 19 + src/server/bnetserver/Server/SessionManager.h | 3 + src/server/bnetserver/bnetserver.conf.dist | 7 + src/server/collision/CMakeLists.txt | 1 + src/server/game/AuctionHouse/AuctionHouseMgr.cpp | 2 +- src/server/game/CMakeLists.txt | 3 + src/server/game/Chat/Chat.cpp | 2 +- src/server/game/Handlers/CharacterHandler.cpp | 7 +- src/server/game/Handlers/MiscHandler.cpp | 2 +- src/server/game/Server/BattlenetServerManager.cpp | 66 ++ src/server/game/Server/BattlenetServerManager.h | 55 ++ src/server/game/Server/WorldSession.cpp | 12 +- src/server/game/Server/WorldSocket.cpp | 4 +- src/server/game/World/World.cpp | 12 +- src/server/game/World/World.h | 3 +- src/server/ipc/CMakeLists.txt | 24 + src/server/ipc/Commands.cpp | 81 +++ src/server/ipc/Commands.h | 83 +++ src/server/ipc/ZMQTask.cpp | 93 +++ src/server/ipc/ZMQTask.h | 52 ++ src/server/ipc/ZmqContext.cpp | 52 ++ src/server/ipc/ZmqContext.h | 55 ++ src/server/ipc/ZmqListener.cpp | 69 ++ src/server/ipc/ZmqListener.h | 51 ++ src/server/ipc/ZmqMux.cpp | 67 ++ src/server/ipc/ZmqMux.h | 47 ++ src/server/ipc/ZmqWorker.cpp | 70 ++ src/server/ipc/ZmqWorker.h | 44 ++ src/server/scripts/CMakeLists.txt | 1 + src/server/scripts/Commands/cs_gm.cpp | 2 +- src/server/scripts/Commands/cs_misc.cpp | 2 +- src/server/scripts/Commands/cs_rbac.cpp | 2 +- src/server/scripts/Commands/cs_ticket.cpp | 6 +- src/server/worldserver/CMakeLists.txt | 6 + src/server/worldserver/Main.cpp | 49 +- src/server/worldserver/worldserver.conf.dist | 21 + 72 files changed, 4922 insertions(+), 68 deletions(-) create mode 100644 cmake/macros/FindZMQ.cmake create mode 100644 dep/zmqpp/CMakeLists.txt create mode 100644 dep/zmqpp/zmqpp/compatibility.hpp create mode 100644 dep/zmqpp/zmqpp/context.cpp create mode 100644 dep/zmqpp/zmqpp/context.hpp create mode 100644 dep/zmqpp/zmqpp/context_options.hpp create mode 100644 dep/zmqpp/zmqpp/exception.hpp create mode 100644 dep/zmqpp/zmqpp/frame.cpp create mode 100644 dep/zmqpp/zmqpp/frame.hpp create mode 100644 dep/zmqpp/zmqpp/inet.hpp create mode 100644 dep/zmqpp/zmqpp/message.cpp create mode 100644 dep/zmqpp/zmqpp/message.hpp create mode 100644 dep/zmqpp/zmqpp/poller.cpp create mode 100644 dep/zmqpp/zmqpp/poller.hpp create mode 100644 dep/zmqpp/zmqpp/socket.cpp create mode 100644 dep/zmqpp/zmqpp/socket.hpp create mode 100644 dep/zmqpp/zmqpp/socket_options.hpp create mode 100644 dep/zmqpp/zmqpp/socket_types.hpp create mode 100644 dep/zmqpp/zmqpp/zmqpp.cpp create mode 100644 dep/zmqpp/zmqpp/zmqpp.hpp create mode 100644 src/server/bnetserver/Realms/WorldListener.cpp create mode 100644 src/server/bnetserver/Realms/WorldListener.h create mode 100644 src/server/game/Server/BattlenetServerManager.cpp create mode 100644 src/server/game/Server/BattlenetServerManager.h create mode 100644 src/server/ipc/CMakeLists.txt create mode 100644 src/server/ipc/Commands.cpp create mode 100644 src/server/ipc/Commands.h create mode 100644 src/server/ipc/ZMQTask.cpp create mode 100644 src/server/ipc/ZMQTask.h create mode 100644 src/server/ipc/ZmqContext.cpp create mode 100644 src/server/ipc/ZmqContext.h create mode 100644 src/server/ipc/ZmqListener.cpp create mode 100644 src/server/ipc/ZmqListener.h create mode 100644 src/server/ipc/ZmqMux.cpp create mode 100644 src/server/ipc/ZmqMux.h create mode 100644 src/server/ipc/ZmqWorker.cpp create mode 100644 src/server/ipc/ZmqWorker.h (limited to 'src/server') diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e91c7da4ec..905d92996bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ set(OPENSSL_EXPECTED_VERSION 1.0.0) find_package(PCHSupport) find_package(OpenSSL REQUIRED) find_package(Threads REQUIRED) +find_package(ZMQ REQUIRED) include(ConfigureBoost) find_package(MySQL REQUIRED) diff --git a/cmake/macros/FindZMQ.cmake b/cmake/macros/FindZMQ.cmake new file mode 100644 index 00000000000..6039dd56e2c --- /dev/null +++ b/cmake/macros/FindZMQ.cmake @@ -0,0 +1,75 @@ +# +# Find the ZMQ includes and library +# + +# This module defines +# ZMQ_INCLUDE_DIR, where to find zmq.h +# ZMQ_LIBRARY, the library needed to use ZMQ +# ZMQ_FOUND, if false, you cannot build anything that requires ZMQ. + +set(ZMQ_FOUND 0) + +if (PLATFORM EQUAL 64) + set(ZMQ_REGISTRY_PATH + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ (x64);DisplayIcon]" + ) +else() + set(ZMQ_REGISTRY_PATH + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayIcon]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayIcon]" + ) +endif() + +find_path(ZMQ_INCLUDE_DIR + NAMES + zmq.h + HINTS + "${ZMQ_REGISTRY_PATH}/include" + PATHS + /usr/include + /usr/local/include +) + +if (MSVC) + # Read registry key holding version + if (PLATFORM EQUAL 64) + get_filename_component(ZMQ_NAME "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ (x64);DisplayVersion]" NAME) + else() + get_filename_component(ZMQ_NAME "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayVersion]" NAME) + if (${ZMQ_NAME} MATCHES "registry") # if key was not found, the string "registry" is returned + get_filename_component(ZMQ_NAME "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ZeroMQ;DisplayVersion]" NAME) + endif() + endif() + + # Replace dots with underscores + string(REGEX REPLACE "\\." "_" ZMQ_NAME ${ZMQ_NAME}) + + # Get Visual studio version number + string(REGEX REPLACE "Visual Studio ([0-9]+).*" "\\1" ZMQ_VS_VERSION ${CMAKE_GENERATOR}) + + # Format ZMQ library file name + set(ZMQ_LIBRARY_NAME "libzmq-v${ZMQ_VS_VERSION}0-mt-${ZMQ_NAME}") +endif() + +find_library(ZMQ_LIBRARY + NAMES + zmq + ${ZMQ_LIBRARY_NAME} + HINTS + "${ZMQ_REGISTRY_PATH}/lib" + PATHS + /lib + /usr/lib + /usr/local/lib +) + +if (ZMQ_INCLUDE_DIR AND ZMQ_LIBRARY) + set(ZMQ_FOUND 1) + message(STATUS "Found ZMQ library: ${ZMQ_LIBRARY}") + message(STATUS "Found ZMQ headers: ${ZMQ_INCLUDE_DIR}") +else() + message(FATAL_ERROR "Could not find ZMQ libraries/headers! Please install ZMQ with libraries and headers") +endif() + +# show the ZMQ_INCLUDE_DIR and ZMQ_LIBRARY variables only in the advanced view +mark_as_advanced(ZMQ_INCLUDE_DIR ZMQ_LIBRARY ZMQ_FOUND) diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt index 8ae2e7ac6d7..e304171560b 100644 --- a/dep/CMakeLists.txt +++ b/dep/CMakeLists.txt @@ -36,6 +36,7 @@ endif() if(SERVERS) add_subdirectory(gsoap) + add_subdirectory(zmqpp) endif() if(TOOLS) diff --git a/dep/PackageList.txt b/dep/PackageList.txt index 6c17867a929..aac1e5eb7b1 100644 --- a/dep/PackageList.txt +++ b/dep/PackageList.txt @@ -39,3 +39,7 @@ recastnavigation (Recast is state of the art navigation mesh construction toolse StormLib (a pack of modules, written in C++, which are able to read and also to write files from/to the MPQ archives) http://www.zezula.net/en/mpq/stormlib.html Version: 8.04 + +zmqpp (C++ binding for 0mq/zmq is a 'high-level' library that hides most of the c-style interface core 0mq provides.) + https://github.com/zeromq/zmqpp + Version: 3.2.0 17e9f6afa98f56ecac1e3f3eecbfc112357a6732 diff --git a/dep/zmqpp/CMakeLists.txt b/dep/zmqpp/CMakeLists.txt new file mode 100644 index 00000000000..6b6bd35b6e7 --- /dev/null +++ b/dep/zmqpp/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (C) 2008-2014 TrinityCore +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources_zmqpp zmqpp/*.cpp zmqpp/*.hpp zmqpp/*.h) + +set(zmqpp_STAT_SRCS + ${sources_zmqpp} +) + +include_directories(${ZMQ_INCLUDE_DIR}) + +add_library(zmqpp STATIC + ${zmqpp_STAT_SRCS} +) + +if (WIN32) + add_definitions(-DBUILD_VERSION=\\"3.2.0\\") +else() + add_definitions(-DBUILD_VERSION='"3.2.0"') +endif() + +add_definitions(-DBUILD_VERSION_MAJOR=3) +add_definitions(-DBUILD_VERSION_MINOR=2) +add_definitions(-DBUILD_VERSION_REVISION=0) diff --git a/dep/zmqpp/zmqpp/compatibility.hpp b/dep/zmqpp/zmqpp/compatibility.hpp new file mode 100644 index 00000000000..103b2c82ebd --- /dev/null +++ b/dep/zmqpp/zmqpp/compatibility.hpp @@ -0,0 +1,97 @@ +/** + * \file + * + * \date 10 Sep 2011 + * \author ron + * \author Ben Gray (\@benjamg) + * + * A fair number of C++0x (or more accurately C++11) features are used in this + * library and as this project is used where I work on older compilers this + * file was created to help. + * + * C++ features and their workaround where not supported: + * \li lambda functions - disabled, these are only used in the test anyway. + * \li typesafe enums - replaced with enum where comparisons needed. + * \li nullptr - defined to null. + * + * As of the port to version 3.1 (libzmqpp version 1.1.0) this file will also + * be used to maintain compatablity with multiple versions of 0mq + */ + +#ifndef ZMQPP_COMPATIBILITY_HPP_ +#define ZMQPP_COMPATIBILITY_HPP_ + +#include +#include + +// Currently we require at least 0mq version 2.2.x +#define ZMQPP_REQUIRED_ZMQ_MAJOR 2 +#define ZMQPP_REQUIRED_ZMQ_MINOR 2 + +#if (ZMQ_VERSION_MAJOR < ZMQPP_REQUIRED_ZMQ_MAJOR) || ((ZMQ_VERSION_MAJOR == ZMQPP_REQUIRED_ZMQ_MAJOR) && (ZMQ_VERSION_MINOR < ZMQPP_REQUIRED_ZMQ_MINOR)) +#error zmqpp requires a later version of 0mq +#endif + +// Experimental feature support +#if (ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR == 0) +#define ZMQ_EXPERIMENTAL_LABELS +#endif + +// Deal with older versions of gcc +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ == 4 + +// Deal with older gcc not supporting C++0x typesafe enum class name {} comparison +#if __GNUC_MINOR__ < 4 +#define ZMQPP_COMPARABLE_ENUM enum +#endif + +#if __GNUC_MINOR__ == 4 +#if __GNUC_PATCHLEVEL__ < 1 +#undef ZMQPP_COMPARABLE_ENUM +#define ZMQPP_COMPARABLE_ENUM enum +#endif // if __GNUC_PATCHLEVEL__ < 1 +#endif // if __GNUC_MINOR__ == 4 + +// Deal with older gcc not supporting C++0x lambda function +#if __GNUC_MINOR__ < 5 +#define ZMQPP_IGNORE_LAMBDA_FUNCTION_TESTS +#define ZMQPP_EXPLICITLY_DELETED +#endif // if __GNUC_MINOR__ < 5 + +// Deal with older gcc not supporting C++0x nullptr +#if __GNUC_MINOR__ < 6 +#define nullptr NULL +#define NOEXCEPT +#endif // if __GNUC_MINOR__ < 6 + +#endif // if __GNUC_ == 4 +#endif // if defined(__GNUC__) && !defined(__clang__) + +#if defined(_MSC_VER) +#define NOEXCEPT throw() +#if _MSC_VER < 1800 +#define ZMQPP_EXPLICITLY_DELETED +#endif // if _MSC_VER < 1800 +#if _MSC_VER < 1600 +#define nullptr NULL +#define ZMQPP_IGNORE_LAMBDA_FUNCTION_TESTS +#define ZMQPP_COMPARABLE_ENUM enum +#endif // if _MSC_VER < 1600 +#endif // if defined(_MSC_VER) + +// Generic state, assume a modern compiler +#ifndef ZMQPP_COMPARABLE_ENUM +#define ZMQPP_COMPARABLE_ENUM enum class +#endif + +#ifndef ZMQPP_EXPLICITLY_DELETED +#define ZMQPP_EXPLICITLY_DELETED = delete +#endif + +#ifndef NOEXCEPT +#define NOEXCEPT noexcept +#endif + +#endif /* ZMQPP_COMPATIBILITY_HPP_ */ + diff --git a/dep/zmqpp/zmqpp/context.cpp b/dep/zmqpp/zmqpp/context.cpp new file mode 100644 index 00000000000..32c657199dc --- /dev/null +++ b/dep/zmqpp/zmqpp/context.cpp @@ -0,0 +1,54 @@ +/** + * \file + * + * \date 9 Aug 2011 + * \author Ben Gray (\@benjamg) + */ + +#include "context.hpp" + +namespace zmqpp +{ + +void context::terminate() +{ + int result; + do + { +#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) + result = zmq_term(_context); +#else + result = zmq_ctx_destroy(_context); +#endif + } while (result != 0 && zmq_errno() == EINTR); + if (result != 0) { throw zmq_internal_exception(); } + _context = nullptr; +} + +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) +void context::set(context_option const option, int const value) +{ + if (nullptr == _context) { throw invalid_instance("context is invalid"); } + + if (0 != zmq_ctx_set(_context, static_cast(option), value)) + { + throw zmq_internal_exception(); + } +} + +int context::get(context_option const option) +{ + if (nullptr == _context) { throw invalid_instance("context is invalid"); } + + int result = zmq_ctx_get(_context, static_cast(option)); + + if (result < 0) + { + throw zmq_internal_exception(); + } + + return result; +} +#endif + +} diff --git a/dep/zmqpp/zmqpp/context.hpp b/dep/zmqpp/zmqpp/context.hpp new file mode 100644 index 00000000000..3ffaf791440 --- /dev/null +++ b/dep/zmqpp/zmqpp/context.hpp @@ -0,0 +1,184 @@ +/** + * \file + * + * \date 9 Aug 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_CONTEXT_HPP_ +#define ZMQPP_CONTEXT_HPP_ + +#include + +#include + +#include "compatibility.hpp" +#include "exception.hpp" +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) +#include "context_options.hpp" +#endif + +namespace zmqpp +{ + +/*! + * The context class represents internal zmq context and io threads. + * + * By default the context class will create one thread, however this can be + * overridden in the constructor. + * + * The context class is the only object that can be considered thread safe. + * + * All sockets using endpoints other than inproc require the context to have + * at least one thread. + * + * This class is c++0x move supporting and cannot be copied. + */ +class context +{ +public: + +#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) + /*! + * Initialise the 0mq context. + * + * If only inproc is used then the context may be created with zero threads. + * Any inproc endpoint using sockets must be created using the same context. + * + * The context is thread safe an may be used anywhere in your application, + * however there is no requirement (other than inproc restrictions) for you + * to do this. + * + * \param threads an integer argument for the number of required threads. Defaults to 1. + */ + context(int const& threads = 1) +#else + /*! + * Initialise the 0mq context. + * + * The context is thread safe an may be used anywhere in your application, + * however there is no requirement (other than inproc restrictions) for you + * to do this. + */ + context() +#endif + : _context(nullptr) + { +#if (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) + _context = zmq_init(threads); +#else + _context = zmq_ctx_new(); +#endif + + if (nullptr == _context) + { + throw zmq_internal_exception(); + } + } + + /*! + * Closes the 0mq context. + * + * Any blocking calls other than a socket close will return with an error. + * + * If there are open sockets will block while zmq internal buffers are + * processed up to a limit specified by that sockets linger option. + */ + ~context() NOEXCEPT + { + if (nullptr != _context) + { + terminate(); + } + } + + /*! + * Move supporting constructor. + * + * Allows zero-copy move semantics to be used with this class. + * + * \param source a rvalue instance of the object who's internals we wish to steal. + */ + context(context&& source) NOEXCEPT + : _context(source._context) + { + source._context = nullptr; + } + + /*! + * Move supporting operator. + * + * Allows zero-copy move semantics to be used with this class. + * + * \param source an rvalue instance of the context who's internals we wish to steal. + */ + context& operator=(context&& source) NOEXCEPT + { + std::swap( _context, source._context ); + return *this; + } + + /*! + * Terminate the current context. + * + * Any blocking calls other than a socket close will return with an error. + * + * If there are open sockets will block while zmq internal buffers are + * processed up to a limit specified by that sockets linger option. + */ + void terminate(); + +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) + /*! + * Set the value of an option in the underlaying zmq context. + * + * \param option a valid ::context_option + * \param value to set the option to + */ + void set(context_option const option, int const value); + + /*! + * Get a context option from the underlaying zmq context. + * + * \param option a valid ::context_option + * \return context option value + */ + int get(context_option const option); +#endif + + /*! + * Validity checking of the context + * + * Checks if the underlying 0mq context for this instance is valid. + * + * Contexts should always be valid unless people are doing 'fun' things with + * std::move. + * + * \return boolean true if the object is valid. + */ + operator bool() const NOEXCEPT + { + return nullptr != _context; + } + + /*! + * Access to the raw 0mq context + * + * \return void pointer to the underlying 0mq context. + */ + operator void*() const NOEXCEPT + { + return _context; + } + +private: + void* _context; + + // No copy - private and not implemented + context(context const&) ZMQPP_EXPLICITLY_DELETED; + context& operator=(context const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; +}; + +} + +#endif /* ZMQPP_CONTEXT_HPP_ */ diff --git a/dep/zmqpp/zmqpp/context_options.hpp b/dep/zmqpp/zmqpp/context_options.hpp new file mode 100644 index 00000000000..b2e2cf4805f --- /dev/null +++ b/dep/zmqpp/zmqpp/context_options.hpp @@ -0,0 +1,26 @@ +/** + * \file + * + * \date 3 Jul 2013 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_CONTEXT_OPTIONS_HPP_ +#define ZMQPP_CONTEXT_OPTIONS_HPP_ + +namespace zmqpp +{ + +/** \todo Expand the information on the options to make it actually useful. */ +/*! + * \brief possible Context options in zmq + */ + +enum class context_option { + io_threads = ZMQ_IO_THREADS, /*!< I/O thread count */ + max_sockets = ZMQ_MAX_SOCKETS, /*!< Maximum supported sockets */ +}; + +} + +#endif /* ZMQPP_CONTEXT_OPTIONS_HPP_ */ diff --git a/dep/zmqpp/zmqpp/exception.hpp b/dep/zmqpp/zmqpp/exception.hpp new file mode 100644 index 00000000000..a0b234769ce --- /dev/null +++ b/dep/zmqpp/zmqpp/exception.hpp @@ -0,0 +1,87 @@ +/** + * \file + * + * \date 9 Aug 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_EXCEPTION_HPP_ +#define ZMQPP_EXCEPTION_HPP_ + +#include +#include + +#include + +namespace zmqpp +{ + +/** \todo Have a larger variety of exceptions with better state debug information */ + +/*! + * Represents the base zmqpp exception. + * + * All zmqpp runtime exceptions are children of this class. + * The class itself does not provide any special access fields but it only + * for convince when catching exceptions. + * + * The class extends std::runtime_error. + * + */ +class exception : public std::runtime_error +{ +public: + /*! + * Standard exception constructor. + * + * \param message a string representing the error message. + */ + exception(std::string const& message) + : std::runtime_error(message) + { } +}; + +/*! + * Represents an attempt to use an invalid object. + * + * Objects may be invalid initially or after a shutdown or close. + */ +class invalid_instance : public exception +{ +public: + invalid_instance(std::string const& message) + : exception(message) + { } +}; + +/*! + * Represents internal zmq errors. + * + * Any error response from the zmq bindings will be wrapped in this error. + * + * The class provides access to the zmq error number via zmq_error(). + */ +class zmq_internal_exception : public exception +{ +public: + /*! + * Uses the zmq functions to pull out error messages and numbers. + */ + zmq_internal_exception() + : exception(zmq_strerror(zmq_errno())) + , _error(zmq_errno()) + { } + + /*! + * Retrieve the zmq error number associated with this exception. + * \return zmq error number + */ + int zmq_error() const { return _error; } + +private: + int _error; +}; + +} + +#endif /* ZMQPP_EXCEPTION_HPP_ */ diff --git a/dep/zmqpp/zmqpp/frame.cpp b/dep/zmqpp/zmqpp/frame.cpp new file mode 100644 index 00000000000..4c512ae1010 --- /dev/null +++ b/dep/zmqpp/zmqpp/frame.cpp @@ -0,0 +1,95 @@ +/** + * \file + * + * \date 8 Jan 2014 + * \author Ben Gray (\@benjamg) + */ + +#include +#include + +#include "exception.hpp" +#include "frame.hpp" + +namespace zmqpp { + +frame::frame() + : _sent( false ) +{ + if( 0 != zmq_msg_init( &_msg ) ) + { + throw zmq_internal_exception(); + } +} + +frame::frame(size_t const size) + : _sent( false ) +{ + if( 0 != zmq_msg_init_size( &_msg, size ) ) + { + throw zmq_internal_exception(); + } +} + +frame::frame(void const* part, size_t const size) + : _sent( false ) +{ + if( 0 != zmq_msg_init_size( &_msg, size ) ) + { + throw zmq_internal_exception(); + } + + void* msg_data = zmq_msg_data( &_msg ); + memcpy( msg_data, part, size ); +} + +frame::frame(void* part, size_t const size, zmq_free_fn *ffn, void *hint) + : _sent( false ) +{ + if( 0 != zmq_msg_init_data( &_msg, part, size, ffn, hint ) ) + { + throw zmq_internal_exception(); + } +} + +frame::~frame() +{ +#ifndef NDEBUG // unused assert variable in release + int result = zmq_msg_close( &_msg ); + assert(0 == result); +#else + zmq_msg_close( &_msg ); +#endif // NDEBUG +} + +frame::frame(frame&& other) + : _sent( other._sent ) +{ + zmq_msg_init( &_msg ); + zmq_msg_move( &_msg, &other._msg ); + other._sent = false; +} + +frame& frame::operator=(frame&& other) +{ + zmq_msg_init( &_msg ); + zmq_msg_move( &_msg, &other._msg ); + std::swap( _sent, other._sent ); + + return *this; +} + +frame frame::copy() const +{ + frame other( size() ); + other._sent = _sent; + + if( 0 != zmq_msg_copy( &other._msg, const_cast(&_msg) ) ) + { + throw zmq_internal_exception(); + } + + return other; +} + +} // namespace zmqpp diff --git a/dep/zmqpp/zmqpp/frame.hpp b/dep/zmqpp/zmqpp/frame.hpp new file mode 100644 index 00000000000..c9e4b9b7d82 --- /dev/null +++ b/dep/zmqpp/zmqpp/frame.hpp @@ -0,0 +1,58 @@ +/** + * \file + * + * \date 8 Jan 2014 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_MESSAGE_FRAME_HPP_ +#define ZMQPP_MESSAGE_FRAME_HPP_ + +#include + +#include "compatibility.hpp" + +namespace zmqpp { + +/*! + * \brief an internal frame wrapper for a single zmq message + * + * This frame wrapper consists of a zmq message and meta data it is used + * by the zmqpp message class to keep track of parts in the internal + * queue. It is unlikely you need to use this class. + */ +class frame +{ +public: + frame(); + frame(size_t const size); + frame(void const* part, size_t const size); + frame(void* part, size_t const size, zmq_free_fn *ffn, void *hint); + + ~frame(); + + bool is_sent() const { return _sent; } + void const* data() const { return zmq_msg_data( const_cast(&_msg) ); } + size_t size() const { return zmq_msg_size( const_cast(&_msg) ); } + + void mark_sent() { _sent = true; } + zmq_msg_t& msg() { return _msg; } + + // Move operators + frame(frame&& other); + frame& operator=(frame&& other); + + frame copy() const; + +private: + bool _sent; + zmq_msg_t _msg; + + // Disable implicit copy support, code must request a copy to clone + frame(frame const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; + frame& operator=(frame const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; +}; + +} // namespace zmqpp + +#endif /* ZMQPP_MESSAGE_FRAME_HPP_ */ diff --git a/dep/zmqpp/zmqpp/inet.hpp b/dep/zmqpp/zmqpp/inet.hpp new file mode 100644 index 00000000000..5245aa4143c --- /dev/null +++ b/dep/zmqpp/zmqpp/inet.hpp @@ -0,0 +1,171 @@ +/** + * \file + * + * \date 10 Aug 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_INET_HPP_ +#define ZMQPP_INET_HPP_ + +/** \todo cross-platform version of including headers. */ +// We get htons and htonl from here +#ifdef _WIN32 +#include +#else +#include +#endif + +#include "compatibility.hpp" + +namespace zmqpp +{ + +/*! + * \brief Possible byte order types. + * + * An enumeration of all the known order types, all two of them. + * There is also an entry for unknown which is just used as a default. + */ +ZMQPP_COMPARABLE_ENUM order { + big_endian, /*!< byte order is big endian */ + little_endian /*!< byte order is little endian */ +}; + +/*! + * Common code for the 64bit versions of htons/htons and ntohs/ntohl + * + * As htons and ntohs (or htonl and ntohs) always just do the same thing, ie + * swap bytes if the host order differs from network order or otherwise don't + * do anything, it seemed silly to type the code twice. + * + * \note This code assumes network order is always big endian. Which it is. + * \note The host endian is only checked once and afterwards assumed to remain + * the same. + * + * \param value_to_check unsigned 64 bit integer to swap + * \return swapped (or not) unsigned 64 bit integer + */ +inline uint64_t swap_if_needed(uint64_t const value_to_check) +{ + static order host_order = (htonl(42) == 42) ? order::big_endian : order::little_endian; + + if (order::big_endian == host_order) + { + return value_to_check; + } + + union { + uint64_t integer; + uint8_t bytes[8]; + } value { value_to_check }; + + std::swap(value.bytes[0], value.bytes[7]); + std::swap(value.bytes[1], value.bytes[6]); + std::swap(value.bytes[2], value.bytes[5]); + std::swap(value.bytes[3], value.bytes[4]); + + return value.integer; +} + +/*! + * 64 bit version of the htons/htonl + * + * I've used the name htonll to try and keep with the htonl naming scheme. + * + * \param hostlonglong unsigned 64 bit host order integer + * \return unsigned 64 bit network order integer + */ +inline uint64_t htonll(uint64_t const hostlonglong) +{ + return zmqpp::swap_if_needed(hostlonglong); +} + +/*! + * 64 bit version of the ntohs/ntohl + * + * I've used the name htonll to try and keep with the htonl naming scheme. + * + * \param networklonglong unsigned 64 bit network order integer + * \return unsigned 64 bit host order integer + */ +inline uint64_t ntohll(uint64_t const networklonglong) +{ + return zmqpp::swap_if_needed(networklonglong); +} + +/*! + * floating point version of the htons/htonl + * + * \param value host order floating point + * \returns network order floating point + */ +inline float htonf(float value) +{ + assert(sizeof(float) == sizeof(uint32_t)); + + uint32_t temp; + memcpy(&temp, &value, sizeof(uint32_t)); + temp = htonl( temp ); + memcpy(&value, &temp, sizeof(uint32_t)); + + return value; +} + +/*! + * floating point version of the ntohs/ntohl + * + * \param value network order float + * \returns host order float + */ +inline float ntohf(float value) +{ + assert(sizeof(float) == sizeof(uint32_t)); + + uint32_t temp; + memcpy(&temp, &value, sizeof(uint32_t)); + temp = ntohl( temp ); + memcpy(&value, &temp, sizeof(uint32_t)); + + return value; +} + +/*! + * double precision floating point version of the htons/htonl + * + * \param value host order double precision floating point + * \returns network order double precision floating point + */ +inline double htond(double value) +{ + assert(sizeof(double) == sizeof(uint64_t)); + + uint64_t temp; + memcpy(&temp, &value, sizeof(uint64_t)); + temp = zmqpp::htonll(temp); + memcpy(&value, &temp, sizeof(uint64_t)); + + return value; +} + +/*! + * double precision floating point version of the ntohs/ntohl + * + * \param value network order double precision floating point + * \returns host order double precision floating point + */ +inline double ntohd(double value) +{ + assert(sizeof(double) == sizeof(uint64_t)); + + uint64_t temp; + memcpy(&temp, &value, sizeof(uint64_t)); + temp = zmqpp::ntohll(temp); + memcpy(&value, &temp, sizeof(uint64_t)); + + return value; +} + +} + +#endif /* INET_HPP_ */ diff --git a/dep/zmqpp/zmqpp/message.cpp b/dep/zmqpp/zmqpp/message.cpp new file mode 100644 index 00000000000..58587307364 --- /dev/null +++ b/dep/zmqpp/zmqpp/message.cpp @@ -0,0 +1,454 @@ +/* + * Created on: 9 Aug 2011 + * Author: Ben Gray (@benjamg) + */ + +#include +#include + +#include "exception.hpp" +#include "inet.hpp" +#include "message.hpp" + +namespace zmqpp +{ + +/*! + * \brief internal construct + * \internal handles bubbling callback from zmq c style to the c++ functor provided + */ +struct callback_releaser +{ + message::release_function func; +}; + +message::message() + : _parts() + , _read_cursor(0) +{ +} + +message::~message() +{ + _parts.clear(); +} + +size_t message::parts() const +{ + return _parts.size(); +} + +/* + * The two const_casts in size and raw_data are a little bit hacky + * but neither of these methods called this way actually modify data + * so accurately represent the intent of these calls. + */ + +size_t message::size(size_t const part /* = 0 */) const +{ + if(part >= _parts.size()) + { + throw exception("attempting to request a message part outside the valid range"); + } + + return _parts[part].size(); +} + +void const* message::raw_data(size_t const part /* = 0 */) const +{ + if(part >= _parts.size()) + { + throw exception("attempting to request a message part outside the valid range"); + } + + return _parts[part].data(); +} + +zmq_msg_t& message::raw_msg(size_t const part /* = 0 */) +{ + if(part >= _parts.size()) + { + throw exception("attempting to request a message part outside the valid range"); + } + + return _parts[part].msg(); +} + +zmq_msg_t& message::raw_new_msg() +{ + _parts.push_back( frame() ); + + return _parts.back().msg(); +} + +zmq_msg_t& message::raw_new_msg(size_t const reserve_data_size) +{ + _parts.push_back( frame(reserve_data_size) ); + + return _parts.back().msg(); +} + +std::string message::get(size_t const part /* = 0 */) const +{ + return std::string(static_cast(raw_data(part)), size(part)); +} + + +// Move operators will take ownership of message parts without copying +void message::move(void* part, size_t const size, release_function const& release) +{ + callback_releaser* hint = new callback_releaser(); + hint->func = release; + + _parts.push_back( frame( part, size, &message::release_callback, hint ) ); +} + +// Stream reader style +void message::reset_read_cursor() +{ + _read_cursor = 0; +} + +void message::get(int8_t& integer, size_t const part) const +{ + assert(sizeof(int8_t) == size(part)); + + int8_t const* byte = static_cast(raw_data(part)); + integer = *byte; +} + +void message::get(int16_t& integer, size_t const part) const +{ + assert(sizeof(int16_t) == size(part)); + + uint16_t const* network_order = static_cast(raw_data(part)); + integer = static_cast(ntohs(*network_order)); +} + +void message::get(int32_t& integer, size_t const part) const +{ + assert(sizeof(int32_t) == size(part)); + + uint32_t const* network_order = static_cast(raw_data(part)); + integer = static_cast(htonl(*network_order)); +} + +void message::get(int64_t& integer, size_t const part) const +{ + assert(sizeof(int64_t) == size(part)); + + uint64_t const* network_order = static_cast(raw_data(part)); + integer = static_cast(zmqpp::htonll(*network_order)); +} + +void message::get(uint8_t& unsigned_integer, size_t const part) const +{ + assert(sizeof(uint8_t) == size(part)); + + uint8_t const* byte = static_cast(raw_data(part)); + unsigned_integer = *byte; +} + +void message::get(uint16_t& unsigned_integer, size_t const part) const +{ + assert(sizeof(uint16_t) == size(part)); + + uint16_t const* network_order = static_cast(raw_data(part)); + unsigned_integer = ntohs(*network_order); +} + +void message::get(uint32_t& unsigned_integer, size_t const part) const +{ + assert(sizeof(uint32_t) == size(part)); + + uint32_t const* network_order = static_cast(raw_data(part)); + unsigned_integer = ntohl(*network_order); +} + +void message::get(uint64_t& unsigned_integer, size_t const part) const +{ + assert(sizeof(uint64_t) == size(part)); + + uint64_t const* network_order = static_cast(raw_data(part)); + unsigned_integer = zmqpp::ntohll(*network_order); +} + +void message::get(float& floating_point, size_t const part) const +{ + assert(sizeof(float) == size(part)); + + float const* network_order = static_cast(raw_data(part)); + floating_point = zmqpp::ntohf(*network_order); +} + +void message::get(double& double_precision, size_t const part) const +{ + assert(sizeof(double) == size(part)); + + double const* network_order = static_cast(raw_data(part)); + double_precision = zmqpp::ntohd(*network_order); +} + +void message::get(bool& boolean, size_t const part) const +{ + assert(sizeof(uint8_t) == size(part)); + + uint8_t const* byte = static_cast(raw_data(part)); + boolean = (*byte != 0); +} + +void message::get(std::string& string, size_t const part) const +{ + string.assign( get(part) ); +} + + +// Stream writer style - these all use copy styles +message& message::operator<<(int8_t const integer) +{ + add(reinterpret_cast(&integer), sizeof(int8_t)); + return *this; +} + +message& message::operator<<(int16_t const integer) +{ + uint16_t network_order = htons(static_cast(integer)); + add(reinterpret_cast(&network_order), sizeof(uint16_t)); + + return *this; +} + +message& message::operator<<(int32_t const integer) +{ + uint32_t network_order = htonl(static_cast(integer)); + add(reinterpret_cast(&network_order), sizeof(uint32_t)); + + return *this; +} + +message& message::operator<<(int64_t const integer) +{ + uint64_t network_order = zmqpp::htonll(static_cast(integer)); + add(reinterpret_cast(&network_order), sizeof(uint64_t)); + + return *this; +} + + +message& message::operator<<(uint8_t const unsigned_integer) +{ + add(reinterpret_cast(&unsigned_integer), sizeof(uint8_t)); + return *this; +} + +message& message::operator<<(uint16_t const unsigned_integer) +{ + uint16_t network_order = htons(unsigned_integer); + add(reinterpret_cast(&network_order), sizeof(uint16_t)); + + return *this; +} + +message& message::operator<<(uint32_t const unsigned_integer) +{ + uint32_t network_order = htonl(unsigned_integer); + add(reinterpret_cast(&network_order), sizeof(uint32_t)); + + return *this; +} + +message& message::operator<<(uint64_t const unsigned_integer) +{ + uint64_t network_order = zmqpp::htonll(unsigned_integer); + add(reinterpret_cast(&network_order), sizeof(uint64_t)); + + return *this; +} + +message& message::operator<<(float const floating_point) +{ + assert(sizeof(float) == 4); + + float network_order = zmqpp::htonf(floating_point); + add(&network_order, sizeof(float)); + + return *this; +} + +message& message::operator<<(double const double_precision) +{ + assert(sizeof(double) == 8); + + double network_order = zmqpp::htond(double_precision); + add(&network_order, sizeof(double)); + + return *this; +} + +message& message::operator<<(bool const boolean) +{ + uint8_t byte = (boolean) ? 1 : 0; + add(reinterpret_cast(&byte), sizeof(uint8_t)); + + return *this; +} + +message& message::operator<<(char const* c_string) +{ + add(reinterpret_cast(c_string), strlen(c_string)); + return *this; +} + +message& message::operator<<(std::string const& string) +{ + add(reinterpret_cast(string.data()), string.size()); + return *this; +} + +void message::push_front(void const* part, size_t const size) +{ + _parts.emplace( _parts.begin(), part, size ); +} + +void message::push_front(int8_t const integer) +{ + push_front(&integer, sizeof(int8_t)); +} + +void message::push_front(int16_t const integer) +{ + uint16_t network_order = htons(static_cast(integer)); + push_front(&network_order, sizeof(uint16_t)); +} + +void message::push_front(int32_t const integer) +{ + uint32_t network_order = htonl(static_cast(integer)); + push_front(&network_order, sizeof(uint32_t)); +} + +void message::push_front(int64_t const integer) +{ + uint64_t network_order = zmqpp::htonll(static_cast(integer)); + push_front(&network_order, sizeof(uint64_t)); +} + + +void message::push_front(uint8_t const unsigned_integer) +{ + push_front(&unsigned_integer, sizeof(uint8_t)); +} + +void message::push_front(uint16_t const unsigned_integer) +{ + uint16_t network_order = htons(unsigned_integer); + push_front(&network_order, sizeof(uint16_t)); +} + +void message::push_front(uint32_t const unsigned_integer) +{ + uint32_t network_order = htonl(unsigned_integer); + push_front(&network_order, sizeof(uint32_t)); +} + +void message::push_front(uint64_t const unsigned_integer) +{ + uint64_t network_order = zmqpp::htonll(unsigned_integer); + push_front(&network_order, sizeof(uint64_t)); +} + +void message::push_front(float const floating_point) +{ + assert(sizeof(float) == 4); + + float network_order = zmqpp::htonf(floating_point); + push_front(&network_order, sizeof(float)); +} + +void message::push_front(double const double_precision) +{ + assert(sizeof(double) == 8); + + double network_order = zmqpp::htond(double_precision); + push_front(&network_order, sizeof(double)); +} + +void message::push_front(bool const boolean) +{ + uint8_t byte = (boolean) ? 1 : 0; + push_front(&byte, sizeof(uint8_t)); +} + +void message::push_front(char const* c_string) +{ + push_front(c_string, strlen(c_string)); +} + +void message::push_front(std::string const& string) +{ + push_front(string.data(), string.size()); +} + +void message::pop_front() +{ + _parts.erase( _parts.begin() ); +} + +void message::pop_back() +{ + _parts.pop_back(); +} + +message::message(message&& source) NOEXCEPT + : _parts() + , _read_cursor(0) +{ + std::swap(_parts, source._parts); +} + +message& message::operator=(message&& source) NOEXCEPT +{ + std::swap(_parts, source._parts); + return *this; +} + +message message::copy() const +{ + message msg; + msg.copy(*this); + return msg; +} + +void message::copy(message const& source) +{ + _parts.resize( source._parts.size() ); + for(size_t i = 0; i < source._parts.size(); ++i) + { + _parts[i] = source._parts[i].copy(); + } + + // we don't need a copy of the releasers as we did data copies of the internal data, + //_releasers = source._releasers; + //_strings = source._strings +} + +// Used for internal tracking +void message::sent(size_t const part) +{ + // sanity check + assert(!_parts[part].is_sent()); + _parts[part].mark_sent(); +} + +// Note that these releasers are not thread safe, the only safety is provided by +// the socket class taking ownership so no updates can happen while zmq does it's thing +// If used in a custom class this has to be dealt with. +void message::release_callback(void* data, void* hint) +{ + callback_releaser* releaser = static_cast(hint); + releaser->func(data); + + delete releaser; +} + +} diff --git a/dep/zmqpp/zmqpp/message.hpp b/dep/zmqpp/zmqpp/message.hpp new file mode 100644 index 00000000000..c232e032ee0 --- /dev/null +++ b/dep/zmqpp/zmqpp/message.hpp @@ -0,0 +1,253 @@ +/** + * \file + * + * \date 9 Aug 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_MESSAGE_HPP_ +#define ZMQPP_MESSAGE_HPP_ + +#include +#include +#include +#include +#include + +#include + +#include "compatibility.hpp" +#include "frame.hpp" + +namespace zmqpp +{ + +/*! + * \brief a zmq message with optional multipart support + * + * A zmq message is made up of one or more parts which are sent together to + * the target endpoints. zmq guarantees either the whole message or none + * of the message will be delivered. + */ +class message +{ +public: + /*! + * \brief callback to release user allocated data. + * + * The release function will be called on any void* moved part. + * It must be thread safe to the extent that the callback may occur on + * one of the context threads. + * + * The function called will be passed a single variable which is the + * pointer to the memory allocated. + */ + typedef std::function release_function; + + message(); + ~message(); + + template + message(T const &part, Args &&...args) + : message() + { + add(part, std::forward(args)...); + } + + size_t parts() const; + size_t size(size_t const part) const; + std::string get(size_t const part) const; + + void get(int8_t& integer, size_t const part) const; + void get(int16_t& integer, size_t const part) const; + void get(int32_t& integer, size_t const part) const; + void get(int64_t& integer, size_t const part) const; + + void get(uint8_t& unsigned_integer, size_t const part) const; + void get(uint16_t& unsigned_integer, size_t const part) const; + void get(uint32_t& unsigned_integer, size_t const part) const; + void get(uint64_t& unsigned_integer, size_t const part) const; + + void get(float& floating_point, size_t const part) const; + void get(double& double_precision, size_t const part) const; + void get(bool& boolean, size_t const part) const; + + void get(std::string& string, size_t const part) const; + + // Warn: If a pointer type is requested the message (well zmq) still 'owns' + // the data and will release it when the message object is freed. + template + Type get(size_t const part) + { + Type value; + get(value, part); + return value; + } + + template + void extract(T &nextpart, Args &...args) + { + assert(part < parts()); + get(nextpart,part); + extract(args...); + } + + template + void extract(T &nextpart) + { + assert(part < parts()); + get(nextpart,part); + } + + // Raw get data operations, useful with data structures more than anything else + // Warn: The message (well zmq) still 'owns' the data and will release it + // when the message object is freed. + template + void get(Type*& value, size_t const part) const + { + value = static_cast(raw_data(part)); + } + + // Warn: The message (well zmq) still 'owns' the data and will release it + // when the message object is freed. + template + void get(Type** value, size_t const part) const + { + *value = static_cast(raw_data(part)); + } + + // Move operators will take ownership of message parts without copying + void move(void* part, size_t const size, release_function const& release); + + // Raw move data operation, useful with data structures more than anything else + template + void move(Object *part) + { + move(part, sizeof(Object), &deleter_callback); + } + + // Copy operators will take copies of any data + template + void add(Type *part, size_t const size) + { + _parts.push_back( frame( part, size ) ); + } + + + template + void add(Type const& part, Args &&...args) + { + *this << part; + add(std::forward(args)...); + } + + template + void add(Type const part) + { + *this << part; + } + + // Stream reader style + void reset_read_cursor(); + + template + message& operator>>(Type& value) + { + get(value, _read_cursor++); + return *this; + } + + // Stream writer style - these all use copy styles + message& operator<<(int8_t const integer); + message& operator<<(int16_t const integer); + message& operator<<(int32_t const integer); + message& operator<<(int64_t const integer); + + message& operator<<(uint8_t const unsigned_integer); + message& operator<<(uint16_t const unsigned_integer); + message& operator<<(uint32_t const unsigned_integer); + message& operator<<(uint64_t const unsigned_integer); + + message& operator<<(float const floating_point); + message& operator<<(double const double_precision); + message& operator<<(bool const boolean); + + message& operator<<(char const* c_string); + message& operator<<(std::string const& string); + + // Queue manipulation + void push_front(void const* part, size_t const size); + + // TODO: unify conversion of types with the stream operators + void push_front(int8_t const integer); + void push_front(int16_t const integer); + void push_front(int32_t const integer); + void push_front(int64_t const integer); + + void push_front(uint8_t const unsigned_integer); + void push_front(uint16_t const unsigned_integer); + void push_front(uint32_t const unsigned_integer); + void push_front(uint64_t const unsigned_integer); + + void push_front(float const floating_point); + void push_front(double const double_precision); + void push_front(bool const boolean); + + void push_front(char const* c_string); + void push_front(std::string const& string); + + void pop_front(); + + void push_back(void const* part, size_t const size) + { + add( part, size ); + } + + template + void push_back(Type const part) + { + *this << part; + } + + void pop_back(); + + void remove(size_t const part); + + // Move supporting + message(message&& source) NOEXCEPT; + message& operator=(message&& source) NOEXCEPT; + + // Copy support + message copy() const; + void copy(message const& source); + + // Used for internal tracking + void sent(size_t const part); + + // Access to raw zmq details + void const* raw_data(size_t const part = 0) const; + zmq_msg_t& raw_msg(size_t const part = 0); + zmq_msg_t& raw_new_msg(); + zmq_msg_t& raw_new_msg(size_t const reserve_data_size); + +private: + typedef std::vector parts_type; + parts_type _parts; + size_t _read_cursor; + + // Disable implicit copy support, code must request a copy to clone + message(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; + message& operator=(message const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; + + static void release_callback(void* data, void* hint); + + template + static void deleter_callback(void* data) + { + delete static_cast(data); + } +}; + +} + +#endif /* ZMQPP_MESSAGE_HPP_ */ diff --git a/dep/zmqpp/zmqpp/poller.cpp b/dep/zmqpp/zmqpp/poller.cpp new file mode 100644 index 00000000000..a6340c9bd61 --- /dev/null +++ b/dep/zmqpp/zmqpp/poller.cpp @@ -0,0 +1,182 @@ +/* + * Created on: 16 Aug 2011 + * Author: Ben Gray (@benjamg) + */ + +#include "exception.hpp" +#include "socket.hpp" +#include "poller.hpp" + +#include + +namespace zmqpp +{ + +const long poller::wait_forever = -1; +const short poller::poll_none = 0; +const short poller::poll_in = ZMQ_POLLIN; +const short poller::poll_out = ZMQ_POLLOUT; +const short poller::poll_error = ZMQ_POLLERR; + +poller::poller() + : _items() + , _index() + , _fdindex() +{ + +} + +poller::~poller() +{ + _items.clear(); + _index.clear(); + _fdindex.clear(); +} + +void poller::add(socket& socket, short const event /* = POLL_IN */) +{ + zmq_pollitem_t item { socket, 0, event, 0 }; + + size_t index = _items.size(); + _items.push_back(item); + _index[socket] = index; +} + +void poller::add(int const descriptor, short const event /* = POLL_IN */) +{ + zmq_pollitem_t item { nullptr, descriptor, event, 0 }; + + size_t index = _items.size(); + _items.push_back(item); + _fdindex[descriptor] = index; +} + +bool poller::has(socket_t const& socket) +{ + return _index.find(socket) != _index.end(); +} + +bool poller::has(int const descriptor) +{ + return _fdindex.find(descriptor) != _fdindex.end(); +} + +void poller::reindex(size_t const index) +{ + if ( nullptr != _items[index].socket ) + { + auto found = _index.find( _items[index].socket ); + if (_index.end() == found) { throw exception("unable to reindex socket in poller"); } + found->second = index; + } + else + { + auto found = _fdindex.find( _items[index].fd ); + if (_fdindex.end() == found) { throw exception("unable to reindex file descriptor in poller"); } + found->second = index; + } +} + +void poller::remove(socket_t const& socket) +{ + auto found = _index.find(socket); + if (_index.end() == found) { return; } + + if ( _items.size() - 1 == found->second ) + { + _items.pop_back(); + _index.erase(found); + return; + } + + std::swap(_items[found->second], _items.back()); + _items.pop_back(); + + auto index = found->second; + _index.erase(found); + + reindex( index ); +} + +void poller::remove(int const descriptor) +{ + auto found = _fdindex.find(descriptor); + if (_fdindex.end() == found) { return; } + + if ( _items.size() - 1 == found->second ) + { + _items.pop_back(); + _fdindex.erase(found); + return; + } + + std::swap(_items[found->second], _items.back()); + _items.pop_back(); + + auto index = found->second; + _fdindex.erase(found); + + reindex( index ); +} + +void poller::check_for(socket const& socket, short const event) +{ + auto found = _index.find(socket); + if (_index.end() == found) + { + throw exception("this socket is not represented within this poller"); + } + + _items[found->second].events = event; +} + +void poller::check_for(int const descriptor, short const event) +{ + auto found = _fdindex.find(descriptor); + if (_fdindex.end() == found) + { + throw exception("this socket is not represented within this poller"); + } + + _items[found->second].events = event; +} + +bool poller::poll(long timeout /* = WAIT_FOREVER */) +{ + int result = zmq_poll(_items.data(), _items.size(), timeout); + if (result < 0) + { + if(EINTR == zmq_errno()) + { + return false; + } + + throw zmq_internal_exception(); + } + + return (result > 0); +} + +short poller::events(socket const& socket) const +{ + auto found = _index.find(socket); + if (_index.end() == found) + { + throw exception("this socket is not represented within this poller"); + } + + return _items[found->second].revents; +} + +short poller::events(int const descriptor) const +{ + auto found = _fdindex.find(descriptor); + if (_fdindex.end() == found) + { + throw exception("this file descriptor is not represented within this poller"); + } + + return _items[found->second].revents; +} + +} diff --git a/dep/zmqpp/zmqpp/poller.hpp b/dep/zmqpp/zmqpp/poller.hpp new file mode 100644 index 00000000000..a19063a091d --- /dev/null +++ b/dep/zmqpp/zmqpp/poller.hpp @@ -0,0 +1,186 @@ +/** + * \file + * + * \date 9 Aug 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_POLLER_HPP_ +#define ZMQPP_POLLER_HPP_ + +#include +#include + +#include "compatibility.hpp" + +namespace zmqpp +{ + +class socket; +typedef socket socket_t; + +/*! + * Polling wrapper. + * + * Allows access to polling for any number of sockets or file descriptors. + */ +class poller +{ +public: + static const long wait_forever; /*!< Block forever flag, default setting. */ + + static const short poll_none; /*!< No polling flags set. */ + static const short poll_in; /*!< Monitor inbound flag. */ + static const short poll_out; /*!< Monitor output flag. */ + static const short poll_error; /*!< Monitor error flag.\n Only for file descriptors. */ + + /*! + * Construct an empty polling model. + */ + poller(); + + /*! + * Cleanup poller. + * + * Any sockets will need to be closed separately. + */ + ~poller(); + + /*! + * Add a socket to the polling model and set which events to monitor. + * + * \param socket the socket to monitor. + * \param event the event flags to monitor on the socket. + */ + void add(socket_t& socket, short const event = poll_in); + + /*! + * Add a file descriptor to the polling model and set which events to monitor. + * + * \param descriptor the file descriptor to monitor. + * \param event the event flags to monitor. + */ + void add(int const descriptor, short const event = poll_in | poll_error); + + /*! + * Check if we are monitoring a given socket with this poller. + * + * \param socket the socket to check. + * \return true if it is there. + */ + bool has(socket_t const& socket); + + /*! + * Check if we are monitoring a given file descriptor with this poller. + * + * \param descriptor the file descriptor to check. + * \return true if it is there. + */ + bool has(int const descriptor); + + /*! + * Stop monitoring a socket. + * + * \param socket the socket to stop monitoring. + */ + void remove(socket_t const& socket); + + /*! + * Stop monitoring a file descriptor. + * + * \param descriptor the file descriptor to stop monitoring. + */ + void remove(int const descriptor); + + /*! + * Update the monitored event flags for a given socket. + * + * \param socket the socket to update event flags. + * \param event the event flags to monitor on the socket. + */ + void check_for(socket_t const& socket, short const event); + + /*! + * Update the monitored event flags for a given file descriptor. + * + * \param descriptor the file descriptor to update event flags. + * \param event the event flags to monitor on the socket. + */ + void check_for(int const descriptor, short const event); + + /*! + * Poll for monitored events. + * + * By default this method will block forever or until at least one of the monitored + * sockets or file descriptors has events. + * + * If a timeout is set and was reached then this function returns false. + * + * \param timeout milliseconds to timeout. + * \return true if there is an event.. + */ + bool poll(long timeout = wait_forever); + + /*! + * Get the event flags triggered for a socket. + * + * \param socket the socket to get triggered event flags for. + * \return the event flags. + */ + short events(socket_t const& socket) const; + + /*! + * Get the event flags triggered for a file descriptor. + * + * \param descriptor the file descriptor to get triggered event flags for. + * \return the event flags. + */ + short events(int const descriptor) const; + + /*! + * Check either a file descriptor or socket for input events. + * + * Templated helper method that calls through to event and checks for a given flag + * + * \param watchable either a file descriptor or socket known to the poller. + * \return true if there is input. + */ + template + bool has_input(Watched const& watchable) const { return events(watchable) & poll_in; } + + /*! + * Check either a file descriptor or socket for output events. + * + * Templated helper method that calls through to event and checks for a given flag + * + * \param watchable either a file descriptor or socket known to the poller. + * \return true if there is output. + */ + template + bool has_output(Watched const& watchable) const { return events(watchable) & poll_out; } + + /*! + * Check a file descriptor. + * + * Templated helper method that calls through to event and checks for a given flag + * + * Technically this template works for sockets as well but the error flag is never set for + * sockets so I have no idea why someone would call it. + * + * \param watchable a file descriptor know to the poller. + * \return true if there is an error. + */ + template + bool has_error(Watched const& watchable) const { return events(watchable) & poll_error; } + +private: + std::vector _items; + std::unordered_map _index; + std::unordered_map _fdindex; + + void reindex(size_t const index); +}; + +} + +#endif /* ZMQPP_POLLER_HPP_ */ diff --git a/dep/zmqpp/zmqpp/socket.cpp b/dep/zmqpp/zmqpp/socket.cpp new file mode 100644 index 00000000000..0c6a795966c --- /dev/null +++ b/dep/zmqpp/zmqpp/socket.cpp @@ -0,0 +1,758 @@ +/* + * Created on: 9 Aug 2011 + * Author: Ben Gray (@benjamg) + */ + +#include +#include +#include +#include + +#include "context.hpp" +#include "exception.hpp" +#include "message.hpp" +#include "socket.hpp" + +namespace zmqpp +{ + +const int socket::normal = 0; +#if (ZMQ_VERSION_MAJOR == 2) +const int socket::dont_wait = ZMQ_NOBLOCK; +#else +const int socket::dont_wait = ZMQ_DONTWAIT; +#endif +const int socket::send_more = ZMQ_SNDMORE; +#ifdef ZMQ_EXPERIMENTAL_LABELS +const int socket::send_label = ZMQ_SNDLABEL; +#endif + +const int max_socket_option_buffer_size = 256; +const int max_stream_buffer_size = 4096; + +socket::socket(const context& context, socket_type const type) + : _socket(nullptr) + , _type(type) + , _recv_buffer() +{ + _socket = zmq_socket(context, static_cast(type)); + if(nullptr == _socket) + { + throw zmq_internal_exception(); + } + + zmq_msg_init(&_recv_buffer); +} + +socket::~socket() +{ + zmq_msg_close(&_recv_buffer); + + if (nullptr != _socket) + { + +#ifndef NDEBUG // unused assert variable in release + int result = zmq_close(_socket); + assert(0 == result); +#else + zmq_close(_socket); +#endif // NDEBUG + + _socket = nullptr; + } +} + +void socket::bind(endpoint_t const& endpoint) +{ + int result = zmq_bind(_socket, endpoint.c_str()); + + if (0 != result) + { + throw zmq_internal_exception(); + } +} + +void socket::unbind(endpoint_t const& endpoint) +{ + int result = zmq_unbind(_socket, endpoint.c_str()); + + if (0 != result) + { + throw zmq_internal_exception(); + } +} + +void socket::connect(endpoint_t const& endpoint) +{ + int result = zmq_connect(_socket, endpoint.c_str()); + + if (0 != result) + { + throw zmq_internal_exception(); + } +} + +void socket::disconnect(endpoint_t const& endpoint) +{ + int result = zmq_disconnect(_socket, endpoint.c_str()); + + if (0 != result) + { + throw zmq_internal_exception(); + } +} + +void socket::close() +{ + int result = zmq_close(_socket); + + if (0 != result) + { + throw zmq_internal_exception(); + } + + _socket = nullptr; +} + +bool socket::send(message& message, bool const dont_block /* = false */) +{ + size_t parts = message.parts(); + if (parts == 0) + { + throw std::invalid_argument("sending requires messages have at least one part"); + } + + bool dont_wait = dont_block; + for(size_t i = 0; i < parts; ++i) + { + int flag = socket::normal; + if(dont_wait) { flag |= socket::dont_wait; } + if(i < (parts - 1)) { flag |= socket::send_more; } + +#if (ZMQ_VERSION_MAJOR == 2) + int result = zmq_send( _socket, &message.raw_msg(i), flag ); +#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) + int result = zmq_sendmsg( _socket, &message.raw_msg(i), flag ); +#else + int result = zmq_msg_send( &message.raw_msg(i), _socket, flag ); +#endif + + if (result < 0) + { + // the zmq framework should not block if the first part is accepted + // so we should only ever get this error on the first part + if((0 == i) && (EAGAIN == zmq_errno())) + { + return false; + } + + if(EINTR == zmq_errno()) + { + if (0 == message.parts()) + { + return false; + } + + // If we have an interrupt but it's not on the first part then we + // know we can safely send out the rest of the message as we can + // enforce that it won't wait on a blocking action + dont_wait = true; + continue; + } + + // sanity checking + assert(EAGAIN != zmq_errno()); + + throw zmq_internal_exception(); + } + + message.sent(i); + } + + // Leave message reference in a stable state + zmqpp::message local; + std::swap(local, message); + return true; +} + +bool socket::receive(message& message, bool const dont_block /* = false */) +{ + if (message.parts() > 0) + { + // swap and discard old message + zmqpp::message local; + std::swap(local, message); + } + + int flags = (dont_block) ? socket::dont_wait : socket::normal; + bool more = true; + + while(more) + { +#if (ZMQ_VERSION_MAJOR == 2) + int result = zmq_recv( _socket, &_recv_buffer, flags ); +#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) + int result = zmq_recvmsg( _socket, &_recv_buffer, flags ); +#else + int result = zmq_msg_recv( &_recv_buffer, _socket, flags ); +#endif + + if(result < 0) + { + if ((0 == message.parts()) && (EAGAIN == zmq_errno())) + { + return false; + } + + if(EINTR == zmq_errno()) + { + if (0 == message.parts()) + { + return false; + } + + // If we have an interrupt but it's not on the first part then we + // know we can safely pull out the rest of the message as it will + // not be blocking + continue; + } + + assert(EAGAIN != zmq_errno()); + + throw zmq_internal_exception(); + } + + zmq_msg_t& dest = message.raw_new_msg(); + zmq_msg_move(&dest, &_recv_buffer); + + get(socket_option::receive_more, more); + } + + return true; +} + + +bool socket::send(std::string const& string, int const flags /* = NORMAL */) +{ + return send_raw(string.data(), string.size(), flags); +} + +bool socket::receive(std::string& string, int const flags /* = NORMAL */) +{ +#if (ZMQ_VERSION_MAJOR == 2) + int result = zmq_recv( _socket, &_recv_buffer, flags ); +#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) + int result = zmq_recvmsg( _socket, &_recv_buffer, flags ); +#else + int result = zmq_msg_recv( &_recv_buffer, _socket, flags ); +#endif + + if(result >= 0) + { + string.reserve(zmq_msg_size(&_recv_buffer)); + string.assign(static_cast(zmq_msg_data(&_recv_buffer)), zmq_msg_size(&_recv_buffer)); + + return true; + } + + if (EAGAIN == zmq_errno() || EINTR == zmq_errno()) + { + return false; + } + + throw zmq_internal_exception(); +} + + +bool socket::send_raw(char const* buffer, int const length, int const flags /* = NORMAL */) +{ +#if (ZMQ_VERSION_MAJOR == 2) + zmq_msg_t msg; + int result = zmq_msg_init_size(&msg, length); + if (result != 0) + { + zmq_internal_exception(); + } + + memcpy(zmq_msg_data(&msg), buffer, length); + result = zmq_send(_socket, &msg, flags); +#else + int result = zmq_send(_socket, buffer, length, flags); +#endif + if(result >= 0) + { + return true; + } + +#if (ZMQ_VERSION_MAJOR == 2) + // only actually need to close this on error + zmq_msg_close(&msg); +#endif + + if (EAGAIN == zmq_errno() || EINTR == zmq_errno()) + { + return false; + } + + throw zmq_internal_exception(); +} + +bool socket::receive_raw(char* buffer, int& length, int const flags /* = NORMAL */) +{ +#if (ZMQ_VERSION_MAJOR == 2) + int result = zmq_recv( _socket, &_recv_buffer, flags ); +#elif (ZMQ_VERSION_MAJOR < 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR < 2)) + int result = zmq_recvmsg( _socket, &_recv_buffer, flags ); +#else + int result = zmq_msg_recv( &_recv_buffer, _socket, flags ); +#endif + + if(result >= 0) + { + length = zmq_msg_size(&_recv_buffer); + memcpy(buffer, zmq_msg_data(&_recv_buffer), length); + + return true; + } + + if (EAGAIN == zmq_errno() || EINTR == zmq_errno()) + { + return false; + } + + throw zmq_internal_exception(); +} + + +// Helper +void socket::subscribe(std::string const& topic) +{ + set(socket_option::subscribe, topic); +} + +void socket::unsubscribe(std::string const& topic) +{ + set(socket_option::unsubscribe, topic); +} + +bool socket::has_more_parts() const +{ + return get(socket_option::receive_more); +} + + +// Set socket options for different types of option +void socket::set(socket_option const option, int const value) +{ + switch(option) + { + // unsigned 64bit Integers +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::high_water_mark: + case socket_option::send_buffer_size: + case socket_option::receive_buffer_size: +#endif + case socket_option::affinity: + if (value < 0) { throw exception("attempting to set an unsigned 64 bit integer option with a negative integer"); } + set(option, static_cast(value)); + break; + + // 64bit Integers +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::rate: + case socket_option::recovery_interval: + case socket_option::recovery_interval_seconds: + case socket_option::swap_size: +#else + case socket_option::max_messsage_size: +#endif + set(option, static_cast(value)); + break; + + // Boolean +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) + case socket_option::ipv4_only: +#endif +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::multicast_loopback: +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) +#if (ZMQ_VERSION_MINOR == 2) + case socket_option::delay_attach_on_connect: +#else + case socket_option::immediate: +#endif + case socket_option::router_mandatory: + case socket_option::xpub_verbose: +#endif + if (value == 0) { set(option, false); } + else if (value == 1) { set(option, true); } + else { throw exception("attempting to set a boolean option with a non 0 or 1 integer"); } + break; + + // Default or Boolean +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) + case socket_option::tcp_keepalive: + if (value < -1 || value > 1) { throw exception("attempting to set a default or boolean option with a non -1, 0 or 1 integer"); } + if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) + { + throw zmq_internal_exception(); + } + break; +#endif + + // Integers that require +ve numbers +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::reconnect_interval_max: +#else + case socket_option::reconnect_interval_max: + case socket_option::send_buffer_size: + case socket_option::recovery_interval: + case socket_option::receive_buffer_size: + case socket_option::send_high_water_mark: + case socket_option::receive_high_water_mark: + case socket_option::multicast_hops: + case socket_option::rate: +#endif + case socket_option::backlog: + if (value < 0) { throw exception("attempting to set a positive only integer option with a negative integer"); } + // Integers + case socket_option::reconnect_interval: + case socket_option::linger: + case socket_option::receive_timeout: + case socket_option::send_timeout: +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) + case socket_option::tcp_keepalive_idle: + case socket_option::tcp_keepalive_count: + case socket_option::tcp_keepalive_interval: +#endif + if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) + { + throw zmq_internal_exception(); + } + break; + default: + throw exception("attempting to set a non signed integer option with a signed integer value"); + } +} + +void socket::set(socket_option const option, bool const value) +{ + switch(option) + { +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::multicast_loopback: +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) + case socket_option::ipv4_only: +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) +#if (ZMQ_VERSION_MINOR == 2) + case socket_option::delay_attach_on_connect: +#else + case socket_option::immediate: +#endif + case socket_option::router_mandatory: + case socket_option::xpub_verbose: +#endif + { + int ivalue = value ? 1 : 0; + if (0 != zmq_setsockopt(_socket, static_cast(option), &ivalue, sizeof(ivalue))) + { + throw zmq_internal_exception(); + } + break; + } + default: + throw exception("attempting to set a non boolean option with a boolean value"); + } +} + +void socket::set(socket_option const option, uint64_t const value) +{ + switch(option) + { +#if (ZMQ_VERSION_MAJOR == 2) + // unsigned 64bit Integers + case socket_option::high_water_mark: + case socket_option::send_buffer_size: + case socket_option::receive_buffer_size: +#endif + case socket_option::affinity: + if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) + { + throw zmq_internal_exception(); + } + break; + default: + throw exception("attempting to set a non unsigned 64 bit integer option with a unsigned 64 bit integer value"); + } +} + +void socket::set(socket_option const option, int64_t const value) +{ + switch(option) + { +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::rate: + case socket_option::recovery_interval: + case socket_option::recovery_interval_seconds: + case socket_option::swap_size: +#else + case socket_option::max_messsage_size: +#endif + // zmq only allowed +ve int64_t options + if (value < 0) { throw exception("attempting to set a positive only 64 bit integer option with a negative 64bit integer"); } + if (0 != zmq_setsockopt(_socket, static_cast(option), &value, sizeof(value))) + { + throw zmq_internal_exception(); + } + break; + default: + throw exception("attempting to set a non 64 bit integer option with a 64 bit integer value"); + } +} + +void socket::set(socket_option const option, char const* value, size_t const length) +{ + switch(option) + { + case socket_option::identity: + case socket_option::subscribe: + case socket_option::unsubscribe: +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) + case socket_option::tcp_accept_filter: +#endif + if (0 != zmq_setsockopt(_socket, static_cast(option), value, length)) + { + throw zmq_internal_exception(); + } + break; + default: + throw exception("attempting to set a non string option with a string value"); + } +} + +// Get socket options, multiple versions for easy of use +void socket::get(socket_option const option, int& value) const +{ + size_t value_size = sizeof(int); + + switch(option) + { +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::receive_more: + case socket_option::multicast_loopback: + value = static_cast(get(option)); + break; +#endif + case socket_option::type: + case socket_option::linger: + case socket_option::backlog: + case socket_option::reconnect_interval: + case socket_option::reconnect_interval_max: + case socket_option::receive_timeout: + case socket_option::send_timeout: + case socket_option::file_descriptor: + case socket_option::events: +#if (ZMQ_VERSION_MAJOR > 2) + case socket_option::receive_more: + case socket_option::send_buffer_size: + case socket_option::receive_buffer_size: + case socket_option::rate: + case socket_option::recovery_interval: + case socket_option::send_high_water_mark: + case socket_option::receive_high_water_mark: + case socket_option::multicast_hops: +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) + case socket_option::ipv4_only: +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) +#if (ZMQ_VERSION_MINOR == 2) + case socket_option::delay_attach_on_connect: +#else + case socket_option::immediate: +#endif + case socket_option::tcp_keepalive: + case socket_option::tcp_keepalive_idle: + case socket_option::tcp_keepalive_count: + case socket_option::tcp_keepalive_interval: +#endif +#ifdef ZMQ_EXPERIMENTAL_LABELS + case socket_option::receive_label: +#endif + if (0 != zmq_getsockopt(_socket, static_cast(option), &value, &value_size)) + { + throw zmq_internal_exception(); + } + + // sanity check + assert(value_size <= sizeof(int)); + break; + default: + throw exception("attempting to get a non integer option with an integer value"); + } +} + +void socket::get(socket_option const option, bool& value) const +{ +#if (ZMQ_VERSION_MAJOR == 2) + int64_t int_value = 0; + size_t value_size = sizeof(int64_t); +#else + int int_value = 0; + size_t value_size = sizeof(int); +#endif + + switch(option) + { + case socket_option::receive_more: +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::multicast_loopback: +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) + case socket_option::ipv4_only: +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) +#if (ZMQ_VERSION_MINOR == 2) + case socket_option::delay_attach_on_connect: +#else + case socket_option::immediate: +#endif +#endif +#ifdef ZMQ_EXPERIMENTAL_LABELS + case socket_option::receive_label: +#endif + if (0 != zmq_getsockopt(_socket, static_cast(option), &int_value, &value_size)) + { + throw zmq_internal_exception(); + } + + value = (int_value == 1) ? true : false; + break; + default: + throw exception("attempting to get a non boolean option with a boolean value"); + } +} + +void socket::get(socket_option const option, uint64_t& value) const +{ + size_t value_size = sizeof(uint64_t); + + switch(option) + { +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::high_water_mark: + case socket_option::send_buffer_size: + case socket_option::receive_buffer_size: +#endif + case socket_option::affinity: + if(0 != zmq_getsockopt(_socket, static_cast(option), &value, &value_size)) + { + throw zmq_internal_exception(); + } + break; + default: + throw exception("attempting to get a non unsigned 64 bit integer option with an unsigned 64 bit integer value"); + } +} + +void socket::get(socket_option const option, int64_t& value) const +{ + size_t value_size = sizeof(int64_t); + + switch(option) + { +#if (ZMQ_VERSION_MAJOR == 2) + case socket_option::rate: + case socket_option::recovery_interval: + case socket_option::recovery_interval_seconds: + case socket_option::swap_size: + case socket_option::receive_more: + case socket_option::multicast_loopback: +#else + case socket_option::max_messsage_size: +#endif + if(0 != zmq_getsockopt(_socket, static_cast(option), &value, &value_size)) + { + throw zmq_internal_exception(); + } + break; + default: + throw exception("attempting to get a non 64 bit integer option with an 64 bit integer value"); + } +} + +void socket::get(socket_option const option, std::string& value) const +{ + static std::array buffer; + size_t size = max_socket_option_buffer_size; + + switch(option) + { + case socket_option::identity: +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) + case socket_option::last_endpoint: +#endif + if(0 != zmq_getsockopt(_socket, static_cast(option), buffer.data(), &size)) + { + throw zmq_internal_exception(); + } + + value.assign(buffer.data(), size); + break; + default: + throw exception("attempting to get a non string option with a string value"); + } +} + +socket::socket(socket&& source) NOEXCEPT + : _socket(source._socket) + , _type(source._type) + , _recv_buffer() +{ + // we steal the zmq_msg_t from the valid socket, we only init our own because it's cheap + // and zmq_msg_move does a valid check + zmq_msg_init(&_recv_buffer); + zmq_msg_move(&_recv_buffer, &source._recv_buffer); + + // Clean up source a little, we will handle the deinit, it doesn't need to + source._socket = nullptr; +} + +socket& socket::operator=(socket&& source) NOEXCEPT +{ + std::swap(_socket, source._socket); + + _type = source._type; // just clone? + + // we steal the zmq_msg_t from the valid socket, we only init our own because it's cheap + // and zmq_msg_move does a valid check + zmq_msg_init(&_recv_buffer); + zmq_msg_move(&_recv_buffer, &source._recv_buffer); + + return *this; +} + + +socket::operator bool() const +{ + return nullptr != _socket; +} + + +socket::operator void*() const +{ + return _socket; +} + +void socket::track_message(message const& /* message */, uint32_t const parts, bool& should_delete) +{ + if (parts == 0) + { + should_delete = true; + } +} + +} diff --git a/dep/zmqpp/zmqpp/socket.hpp b/dep/zmqpp/zmqpp/socket.hpp new file mode 100644 index 00000000000..279bf801f77 --- /dev/null +++ b/dep/zmqpp/zmqpp/socket.hpp @@ -0,0 +1,500 @@ +/** + * \file + * + * \date 9 Aug 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_SOCKET_HPP_ +#define ZMQPP_SOCKET_HPP_ + +#include +#include +#include + +#include + +#include "compatibility.hpp" + +#include "socket_types.hpp" +#include "socket_options.hpp" + +namespace zmqpp +{ + +class context; +class message; + +typedef std::string endpoint_t; +typedef context context_t; +typedef message message_t; + +/*! + * The socket class represents the zmq sockets. + * + * A socket can be bound and/or connected to as many endpoints as required + * with the sole exception of a ::pair socket. + * + * The routing is handled by zmq based on the type set. + * + * The bound side of an inproc connection must occur first and inproc can only + * connect to other inproc sockets of the same context. + * + * This class is c++0x move supporting and cannot be copied. + */ +class socket +{ +public: + static const int normal; /*!< /brief default send type, no flags set */ +#if (ZMQ_VERSION_MAJOR == 2) + static const int dont_wait; /*!< /brief don't block if sending is not currently possible */ +#else + static const int dont_wait; /*!< /brief don't block if sending is not currently possible */ +#endif + static const int send_more; /*!< /brief more parts will follow this one */ +#ifdef ZMQ_EXPERIMENTAL_LABELS + static const int send_label; /*!< /brief this message part is an internal zmq label */ +#endif + + /*! + * Create a socket for a given type. + * + * \param context the zmq context under which the socket will live + * \param type a valid ::socket_type for the socket + */ + socket(context_t const& context, socket_type const type); + + /*! + * This will close any socket still open before returning + */ + ~socket(); + + /*! + * Get the type of the socket, this works on zmqpp types and not the zmq internal types. + * Use the socket::get method if you wish to intergoate the zmq internal ones. + * + * \return the type of the socket + */ + socket_type type() const { return _type; } + + /*! + * Asynchronously binds to an endpoint. + * + * \param endpoint the zmq endpoint to bind to + */ + void bind(endpoint_t const& endpoint); + + /*! + * Unbinds from a previously bound endpoint. + * + * \param endpoint the zmq endpoint to bind to + */ + void unbind(endpoint_t const& endpoint); + + /*! + * Asynchronously connects to an endpoint. + * If the endpoint is not inproc then zmq will happily keep trying + * to connect until there is something there. + * + * Inproc sockets must have a valid target already bound before connection + * will work. + * + * \param endpoint the zmq endpoint to connect to + */ + void connect(endpoint_t const& endpoint); + + /*! + * Asynchronously connects to multiple endpoints. + * If the endpoint is not inproc then zmq will happily keep trying + * to connect until there is something there. + * + * Inproc sockets must have a valid target already bound before connection + * will work. + * + * This is a helper function that wraps the single item connect in a loop + * + * \param connections_begin the starting iterator for zmq endpoints. + * \param connections_end the final iterator for zmq endpoints. + */ + template + void connect(InputIterator const& connections_begin, InputIterator const& connections_end) + { + for(InputIterator it = connections_begin; it != connections_end; ++it) + { + connect(*it); + } + } + + + /*! + * Disconnects a previously connected endpoint. + * + * \param endpoint the zmq endpoint to disconnect from + */ + void disconnect(endpoint_t const& endpoint); + + /*! + * Disconnects from multiple previously connected endpoints. + * + * This is a helper function that wraps the single item disconnect in a loop + * + * \param disconnections_begin the starting iterator for zmq endpoints. + * \param disconnections_end the final iterator for zmq endpoints. + */ + template + void disconnect(InputIterator const& disconnections_begin, InputIterator const& disconnections_end) + { + for(InputIterator it = disconnections_begin; it != disconnections_end; ++it) + { + disconnect(*it); + } + } + + /*! + * Closes the internal zmq socket and marks this instance + * as invalid. + */ + void close(); + + /*! + * Sends the message over the connection, this may be a multipart message. + * + * If dont_block is true and we are unable to add a new message then this + * function will return false. + * + * \param message message to send + * \param dont_block boolean to dictate if we wait while sending. + * \return true if message sent, false if it would have blocked + */ + bool send(message_t& message, bool const dont_block = false); + + /*! + * Gets a message from the connection, this may be a multipart message. + * + * If dont_block is true and we are unable to get a message then this + * function will return false. + * + * \param message reference to fill with received data + * \param dont_block boolean to dictate if we wait for data. + * \return true if message sent, false if it would have blocked + */ + bool receive(message_t& message, bool const dont_block = false); + + /*! + * Sends the byte data held by the string as the next message part. + * + * If the socket::DONT_WAIT flag and we are unable to add a new message to + * socket then this function will return false. + * + * \param string message part to send + * \param flags message send flags + * \return true if message part sent, false if it would have blocked + */ + bool send(std::string const& string, int const flags = normal); + + /*! + * If there is a message ready then get the next part as a string + * + * If the socket::DONT_WAIT flag and there is no message ready to receive + * then this function will return false. + * + * \param string message part to receive into + * \param flags message receive flags + * \return true if message part received, false if it would have blocked + */ + bool receive(std::string& string, int const flags = normal); + + /*! + * Sends the byte data pointed to by buffer as the next part of the message. + * + * If the socket::DONT_WAIT flag and we are unable to add a new message to + * socket then this function will return false. + * + * \param buffer byte buffer pointer to start writing from + * \param length max length of the buffer + * \param flags message send flags + * \return true if message part sent, false if it would have blocked + */ + bool send_raw(char const* buffer, int const length, int const flags = normal); + + /*! + * \warning If the buffer is not large enough for the message part then the + * data will be truncated. The rest of the part is lost forever. + * + * If there is a message ready then get the next part of it as a raw + * byte buffer. + * + * If the socket::DONT_WAIT flag and there is no message ready to receive + * then this function will return false. + * + * \param buffer byte buffer pointer to start writing to + * \param length max length of the buffer + * \param flags message receive flags + * \return true if message part received, false if it would have blocked + */ + bool receive_raw(char* buffer, int& length, int const flags = normal); + + /*! + * + * Subscribe to a topic + * + * Helper function that is equivalent of calling + * \code + * set(zmqpp::socket_option::subscribe, topic); + * \endcode + * + * This method is only useful for subscribe type sockets. + * + * \param topic the topic to subscribe to. + */ + void subscribe(std::string const& topic); + + /*! + * Subscribe to a topic + * + * Helper function that is equivalent of a loop calling + * \code + * set(zmqpp::socket_option::subscribe, topic); + * \endcode + * + * This method is only useful for subscribe type sockets. + * + * Generally this will be used with stl collections using begin() and + * end() functions to get the iterators. + * For this reason the end loop runs until the end iterator, not inclusive + * of it. + * + * \param topics_begin the starting iterator for topics. + * \param topics_end the final iterator for topics. + */ + template + void subscribe(InputIterator const& topics_begin, InputIterator const& topics_end) + { + for(InputIterator it = topics_begin; it != topics_end; ++it) + { + subscribe(*it); + } + } + + /*! + * Unsubscribe from a topic + * + * Helper function that is equivalent of calling + * \code + * set(zmqpp::socket_option::unsubscribe, topic); + * \endcode + * + * This method is only useful for subscribe type sockets. + * + * \param topic the topic to unsubscribe from. + */ + void unsubscribe(std::string const& topic); + + /*! + * Unsubscribe from a topic + * + * Helper function that is equivalent of a loop calling + * \code + * set(zmqpp::socket_option::unsubscribe, topic); + * \endcode + * + * This method is only useful for subscribe type sockets. + * + * Generally this will be used with stl collections using begin() and + * end() functions to get the iterators. + * For this reason the end loop runs until the end iterator, not inclusive + * of it. + * + * \param topics_begin the starting iterator for topics. + * \param topics_end the final iterator for topics. + */ + template + void unsubscribe(InputIterator const& topics_begin, InputIterator const& topics_end) + { + for(InputIterator it = topics_begin; it != topics_end; ++it) + { + unsubscribe(*it); + } + } + + /*! + * If the last receive part call to the socket resulted + * in a label or a non-terminating part of a multipart + * message this will return true. + * + * \return true if there are more parts + */ + bool has_more_parts() const; + + /*! + * Set the value of an option in the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value to set the option to + */ + void set(socket_option const option, int const value); + + /*! + * Set the value of an option in the underlaying zmq socket. + * + * \since 2.0.0 (built against 0mq version 3.1.x or later) + * + * \param option a valid ::socket_option + * \param value to set the option to + */ + void set(socket_option const option, bool const value); + + /*! + * Set the value of an option in the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value to set the option to + */ + void set(socket_option const option, uint64_t const value); + + /*! + * Set the value of an option in the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value to set the option to + */ + void set(socket_option const option, int64_t const value); + + /*! + * Set the value of an option in the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param pointer to raw byte value to set the option to + * \param length the size of the raw byte value + */ + void set(socket_option const option, char const* value, size_t const length); + + /*! + * Set the value of an option in the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param pointer to null terminated cstring value to set the option to + */ + inline void set(socket_option const option, char const* value) { set(option, value, strlen(value)); } + + /*! + * Set the value of an option in the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value to set the option to + */ + inline void set(socket_option const option, std::string const value) { set(option, value.c_str(), value.length()); } + + /*! + * Get a socket option from the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value referenced int to return value in + */ + void get(socket_option const option, int& value) const; + + /*! + * Get a socket option from the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value referenced bool to return value in + */ + void get(socket_option const option, bool& value) const; + + /*! + * Get a socket option from the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value referenced uint64_t to return value in + */ + void get(socket_option const option, uint64_t& value) const; + + /*! + * Get a socket option from the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value referenced uint64_t to return value in + */ + void get(socket_option const option, int64_t& value) const; + + /*! + * Get a socket option from the underlaying zmq socket. + * + * \param option a valid ::socket_option + * \param value referenced std::string to return value in + */ + void get(socket_option const option, std::string& value) const; + + /*! + * For those that don't want to get into a referenced value this templated method + * will return the value instead. + * + * \param option a valid ::socket_option + * \return socket option value + */ + template + Type get(socket_option const option) const + { + Type value = Type(); + get(option, value); + return value; + } + + /*! + * Move constructor + * + * Moves the internals of source to this object, there is no guarantee + * that source will be left in a valid state. + * + * This constructor is noexcept and so will not throw exceptions + * + * \param source target socket to steal internals from + */ + socket(socket&& source) NOEXCEPT; + + /*! + * Move operator + * + * Moves the internals of source to this object, there is no guarantee + * that source will be left in a valid state. + * + * This function is noexcept and so will not throw exceptions + * + * \param source target socket to steal internals from + * \return socket reference to this + */ + socket& operator=(socket&& source) NOEXCEPT; + + /*! + * Check the socket is still valid + * + * This tests the internal state of the socket. + * If creation failed for some reason or if the move functions were used + * to move the socket internals to another instance this will return false. + * + * \return true if the socket is valid + */ + operator bool() const; + + /*! + * Access to the raw 0mq context + * + * \return void pointer to the underlying 0mq socket + */ + operator void*() const; + +private: + void* _socket; + socket_type _type; + zmq_msg_t _recv_buffer; + + // No copy + socket(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; + socket& operator=(socket const&) NOEXCEPT ZMQPP_EXPLICITLY_DELETED; + + void track_message(message_t const&, uint32_t const, bool&); +}; + +} + +#endif /* ZMQPP_SOCKET_HPP_ */ diff --git a/dep/zmqpp/zmqpp/socket_options.hpp b/dep/zmqpp/zmqpp/socket_options.hpp new file mode 100644 index 00000000000..c5c8586cbc7 --- /dev/null +++ b/dep/zmqpp/zmqpp/socket_options.hpp @@ -0,0 +1,80 @@ +/** + * \file + * + * \date 23 Sep 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_SOCKET_OPTIONS_HPP_ +#define ZMQPP_SOCKET_OPTIONS_HPP_ + +namespace zmqpp +{ + +/** \todo Expand the information on the options to make it actually useful. */ +/*! + * \brief possible Socket options in zmq + */ + +enum class socket_option { + affinity = ZMQ_AFFINITY, /*!< I/O thread affinity */ + identity = ZMQ_IDENTITY, /*!< Socket identity */ + subscribe = ZMQ_SUBSCRIBE, /*!< Add topic subscription - set only */ + unsubscribe = ZMQ_UNSUBSCRIBE, /*!< Remove topic subscription - set only */ + rate = ZMQ_RATE, /*!< Multicast data rate */ + send_buffer_size = ZMQ_SNDBUF, /*!< Kernel transmission buffer size */ + receive_buffer_size = ZMQ_RCVBUF, /*!< Kernel receive buffer size */ + receive_more = ZMQ_RCVMORE, /*!< Can receive more parts - get only */ + file_descriptor = ZMQ_FD, /*!< Socket file descriptor - get only */ + events = ZMQ_EVENTS, /*!< Socket event flags - get only */ + type = ZMQ_TYPE, /*!< Socket type - get only */ + linger = ZMQ_LINGER, /*!< Socket linger timeout */ + backlog = ZMQ_BACKLOG, /*!< Maximum length of outstanding connections - get only */ +#if (ZMQ_VERSION_MAJOR == 2) + // Note that this is inverse of the zmq names for version 2.x + recovery_interval_seconds = ZMQ_RECOVERY_IVL, /*!< Multicast recovery interval in seconds */ + recovery_interval = ZMQ_RECOVERY_IVL_MSEC, /*!< Multicast recovery interval in milliseconds */ +#else + recovery_interval = ZMQ_RECOVERY_IVL, /*!< Multicast recovery interval in milliseconds */ +#endif + reconnect_interval = ZMQ_RECONNECT_IVL, /*!< Reconnection interval */ + reconnect_interval_max = ZMQ_RECONNECT_IVL_MAX, /*!< Maximum reconnection interval */ + receive_timeout = ZMQ_RCVTIMEO, /*!< Maximum inbound block timeout */ + send_timeout = ZMQ_SNDTIMEO, /*!< Maximum outbound block timeout */ +#if (ZMQ_VERSION_MAJOR == 2) + high_water_mark = ZMQ_HWM, /*!< High-water mark for all messages */ + swap_size = ZMQ_SWAP, /*!< Maximum socket swap size in bytes */ + multicast_loopback = ZMQ_MCAST_LOOP, /*!< Allow multicast packet loopback */ +#else + max_messsage_size = ZMQ_MAXMSGSIZE, /*!< Maximum inbound message size */ + send_high_water_mark = ZMQ_SNDHWM, /*!< High-water mark for outbound messages */ + receive_high_water_mark = ZMQ_RCVHWM, /*!< High-water mark for inbound messages */ + multicast_hops = ZMQ_MULTICAST_HOPS, /*!< Maximum number of multicast hops */ +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 1)) + ipv4_only = ZMQ_IPV4ONLY, +#endif +#if (ZMQ_VERSION_MAJOR > 3) || ((ZMQ_VERSION_MAJOR == 3) && (ZMQ_VERSION_MINOR >= 2)) +#if (ZMQ_VERSION_MINOR == 2) + delay_attach_on_connect = ZMQ_DELAY_ATTACH_ON_CONNECT, /*!< Delay buffer attachment until connect complete */ +#else + // ZMQ_DELAY_ATTACH_ON_CONNECT is renamed in ZeroMQ starting 3.3.x + immediate = ZMQ_IMMEDIATE, /*!< Block message sending until connect complete */ +#endif + last_endpoint = ZMQ_LAST_ENDPOINT, /*!< Last bound endpoint - get only */ + router_mandatory = ZMQ_ROUTER_MANDATORY, /*!< Require routable messages - set only */ + xpub_verbose = ZMQ_XPUB_VERBOSE, /*!< Pass on existing subscriptions - set only */ + tcp_keepalive = ZMQ_TCP_KEEPALIVE, /*!< Enable TCP keepalives */ + tcp_keepalive_idle = ZMQ_TCP_KEEPALIVE_IDLE, /*!< TCP keepalive idle count (generally retry count) */ + tcp_keepalive_count = ZMQ_TCP_KEEPALIVE_CNT, /*!< TCP keepalive retry count */ + tcp_keepalive_interval = ZMQ_TCP_KEEPALIVE_INTVL, /*!< TCP keepalive interval */ + tcp_accept_filter = ZMQ_TCP_ACCEPT_FILTER, /*!< Filter inbound connections - set only */ +#endif +#ifdef ZMQ_EXPERIMENTAL_LABELS + receive_label = ZMQ_RCVLABEL, /*!< Received label part - get only */ +#endif +}; + +} + +#endif /* ZMQPP_SOCKET_OPTIONS_HPP_ */ diff --git a/dep/zmqpp/zmqpp/socket_types.hpp b/dep/zmqpp/zmqpp/socket_types.hpp new file mode 100644 index 00000000000..e59e71ca0e1 --- /dev/null +++ b/dep/zmqpp/zmqpp/socket_types.hpp @@ -0,0 +1,148 @@ +/** + * \file + * + * \date 23 Sep 2011 + * \author Ben Gray (\@benjamg) + */ + +#ifndef ZMQPP_SOCKET_TYPES_HPP_ +#define ZMQPP_SOCKET_TYPES_HPP_ + +namespace zmqpp +{ + +/*! + * \brief Socket types allowed by zmq + * + * The socket type choose at creation must be one of these types. + * + * Each is designed for a different use and has different limitations. + */ +enum class socket_type { + /*! + * One to one - two way connection.\n + * Connect to ::pair.\n + * A \c pair socket has to be connected only one other pair socket and allows + * two way communication between them. + */ + pair = ZMQ_PAIR, + + /*! + * One to many - fan out.\n + * Connect to ::subscribe or ::xsubscribe.\n + * Socket is send only.\n + * Socket will drop messages and not block.\n + * \c publish sockets allow sending of the same message to many subscribers + * each subscriber can limit what is sent through the socket_option::subscribe + * settings. + */ + publish = ZMQ_PUB, + + /*! + * \note It seems doxygen can't work out which data is for the socket type and + * which is for the socket option so both get listed for both. + * + * One to many - fair-queued.\n + * Connect to ::publish or ::xpublish.\n + * Socket is receive only.\n + * The \c subscribe socket can connection to any number of publishers and will + * fairly pull messages from each. The socket_option::subscribe settings can + * be use to limit which messages are received and by default none are. + */ + subscribe = ZMQ_SUB, + + /*! + * One to many - fair-queued.\n + * Connect to ::push.\n + * Socket is receive only.\n + * The \c pull socket fairly pulls messages from all pushers it is connected + * to. + */ + pull = ZMQ_PULL, + + /*! + * One to many - load-balanced.\n + * Connect to ::pull.\n + * Socket is send only.\n + * Socket will block if unable to send.\n + * The \c push socket fairly distributes messages between any connected + * puller sockets. + */ + push = ZMQ_PUSH, + + /*! + * One to many - fair-queued outgoing, last peer incoming.\n + * Connect to ::reply or ::xreply.\n + * Socket flips between send and receive only.\n + * Socket will block if unable to send.\n + * The \c request socket will fairly balance requests sent out to a + * replier and then can only be used to receive until that replier + * sends a reply. + */ + request = ZMQ_REQ, + + /*! + * One to many - load-balanced incoming, last peer outgoing.\n + * Connect to ::request or ::xrequest.\n + * Socket flips between send and receive only.\n + * Socket will drop messages and not block.\n + * The \c reply socket can only receive until it pulls a message from a + * requester at which point it can only send until the reply is sent. + */ + reply = ZMQ_REP, + + /*! + * One to many - fan out.\n + * Connect to ::subscribe or ::xsubscribe.\n + * Socket is send only with the exception of special subscription messages.\n + * Socket will drop messages and not block.\n + * \c xpublish act the same as ::publish sockets however also allow special + * subscription messages to be received from subscribers. + */ + xpublish = ZMQ_XPUB, + + /*! + * One to many - fair-queued.\n + * Connect to ::publish or ::xpublish.\n + * Socket is receive only with the exception of special subscription messages\n + * \c xsubscribe act the same as ::subscribe sockets however also allow special + * subscription messages to be send to connected publishers. + */ + xsubscribe = ZMQ_XSUB, + + /*! + * One to many - fair-queued incoming, load-balanced outgoing.\n + * Connect to ::reply or ::xreply.\n + * Socket will block if unable to send.\n + * An \c xrequest socket balances requests between repliers and pulls replies + * back in a fair manner. Each request is expected to have exactly one reply. + */ + xrequest = ZMQ_XREQ, + + /*! + * One to many - fair-queued incoming, targeted outgoing.\n + * Connect to ::request or ::xrequest.\n + * Socket will drop messages and not block.\n + * An \c xreply socket fairly pulls in requests from requesters and will + * label requests so it can return replies back to the correct target. + */ + xreply = ZMQ_XREP, + + // To match for people who prefer the shorter versions + pub = ZMQ_PUB, /*!< version of ::publish to match zmq name convention */ + sub = ZMQ_SUB, /*!< version of ::subscribe to match zmq name convention */ + req = ZMQ_REQ, /*!< version of ::request to match zmq name convention */ + rep = ZMQ_REP, /*!< version of ::reply to match zmq name convention */ + xpub = ZMQ_XPUB, /*!< version of ::xpublish to match zmq name convention */ + xsub = ZMQ_XSUB, /*!< version of ::xsubscribe to match zmq name convention */ + xreq = ZMQ_XREQ, /*!< version of ::xrequest to match zmq name convention */ + xrep = ZMQ_XREP, /*!< version of ::xreply to match zmq name convention */ + + // For completion + router = ZMQ_ROUTER, /*!< \deprecated Matches zmq 2.x xrep functionality. */ + dealer = ZMQ_DEALER /*!< \deprecated Matches zmq 2.x xreq functionality. */ +}; + +} + +#endif /* ZMQPP_SOCKET_TYPES_HPP_ */ diff --git a/dep/zmqpp/zmqpp/zmqpp.cpp b/dep/zmqpp/zmqpp/zmqpp.cpp new file mode 100644 index 00000000000..216948e73e7 --- /dev/null +++ b/dep/zmqpp/zmqpp/zmqpp.cpp @@ -0,0 +1,30 @@ +/* + * Created on: 18 Aug 2011 + * Author: Ben Gray (@benjamg) + */ + +#include "zmqpp.hpp" + +namespace zmqpp +{ + +std::string version() +{ + return BUILD_VERSION; +} + +void version(uint8_t& major, uint8_t& minor, uint8_t& revision) +{ + major = ZMQPP_VERSION_MAJOR; + minor = ZMQPP_VERSION_MINOR; + revision = ZMQPP_VERSION_REVISION; +} + +void zmq_version(uint8_t& major, uint8_t& minor, uint8_t& patch) +{ + major = ZMQ_VERSION_MAJOR; + minor = ZMQ_VERSION_MINOR; + patch = ZMQ_VERSION_PATCH; +} + +} diff --git a/dep/zmqpp/zmqpp/zmqpp.hpp b/dep/zmqpp/zmqpp/zmqpp.hpp new file mode 100644 index 00000000000..92a47ce38bf --- /dev/null +++ b/dep/zmqpp/zmqpp/zmqpp.hpp @@ -0,0 +1,111 @@ +/** + * \file + * + * \date 9 Aug 2011 + * \author Ben Gray (\@benjamg) + * + * License: http://www.opensource.org/licenses/MIT + * + * Copyright (C) 2011 by Ben Gray + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef ZMQPP_ZMQPP_HPP_ +#define ZMQPP_ZMQPP_HPP_ + +/** + * \def ZMQPP_VERSION_MAJOR + * zmqpp major version number, generated at compile time + */ +#define ZMQPP_VERSION_MAJOR BUILD_VERSION_MAJOR + +/** + * \def ZMQPP_VERSION_MINOR + * zmqpp minor version number, generated at compile time + */ +#define ZMQPP_VERSION_MINOR BUILD_VERSION_MINOR + +/** + * \def ZMQPP_VERSION_REVISION + * zmqpp version revision number, generated at compile time + */ +#define ZMQPP_VERSION_REVISION BUILD_VERSION_REVISION + +#include + +#include "compatibility.hpp" +#include "context.hpp" +#include "exception.hpp" +#include "message.hpp" +#include "poller.hpp" +#include "socket.hpp" + +/*! + * \brief C++ wrapper around zmq + * + * All zmq++ / zmqpp functions, constants and classes live within this namespace, + */ +namespace zmqpp +{ + +/*! + * Returns the current major.minor.revision version number as a string. + * + * \return string version number. + */ +std::string version(); + +/*! + * Retrieve the parts of the zmqpp version number. + * + * Set the three parameters to values representing the zmqpp version number. + * These values are generated at library compile time. + * + * \param major an unsigned 8 bit reference to set to the major version. + * \param minor an unsigned 8 bit reference to set to the minor version. + * \param revision an unsigned 8 bit reference to set the current revision. + */ +void version(uint8_t& major, uint8_t& minor, uint8_t& revision); + +/*! + * Retrieve the parts of the 0mq version this library was built against. + * + * Because sections of the library are optionally compiled in or ignored + * depending on the version of 0mq it was compiled against this method is + * provided to allow sanity checking for usage. + * + * Set the three parameters to values representing the 0mq version number. + * These values are generated at library compile time. + * + * \param major an unsigned 8 bit reference to set to the major version. + * \param minor an unsigned 8 bit reference to set to the minor version. + * \param revision an unsigned 8 bit reference to set the current revision. + */ +void zmq_version(uint8_t& major, uint8_t& minor, uint8_t& patch); + +typedef context context_t; /*!< \brief context type */ +typedef std::string endpoint_t; /*!< \brief endpoint type */ +typedef message message_t; /*!< \brief message type */ +typedef poller poller_t; /*!< \brief poller type */ +typedef socket socket_t; /*!< \brief socket type */ + +} + +#endif /* ZMQPP_ZMQPP_HPP_ */ diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index ea2ad3abac7..e691b9527a5 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -25,6 +25,7 @@ if( SERVERS ) add_subdirectory(game) add_subdirectory(collision) add_subdirectory(authserver) + add_subdirectory(ipc) add_subdirectory(bnetserver) add_subdirectory(scripts) add_subdirectory(worldserver) diff --git a/src/server/bnetserver/CMakeLists.txt b/src/server/bnetserver/CMakeLists.txt index 9d99ac7f0c5..5b854018d47 100644 --- a/src/server/bnetserver/CMakeLists.txt +++ b/src/server/bnetserver/CMakeLists.txt @@ -45,6 +45,7 @@ endif() include_directories( ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/zmqpp ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration ${CMAKE_SOURCE_DIR}/src/server/shared/Database @@ -56,6 +57,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Threading ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Authentication ${CMAKE_CURRENT_SOURCE_DIR}/Realms @@ -64,6 +66,7 @@ include_directories( ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${VALGRIND_INCLUDE_DIR} + ${ZMQ_INCLUDE_DIR} ) add_executable(bnetserver @@ -80,9 +83,12 @@ if( NOT WIN32 ) endif() target_link_libraries(bnetserver + ipc shared + zmqpp ${MYSQL_LIBRARY} ${OPENSSL_LIBRARIES} + ${ZMQ_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ) diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp index ff891304bd3..ce90019c011 100644 --- a/src/server/bnetserver/Main.cpp +++ b/src/server/bnetserver/Main.cpp @@ -35,6 +35,7 @@ #include "RealmList.h" #include "SystemConfig.h" #include "Util.h" +#include "ZmqContext.h" #include #include #include @@ -94,12 +95,21 @@ int main(int argc, char** argv) } } + int32 worldListenPort = sConfigMgr->GetIntDefault("WorldserverListenPort", 1118); + if (worldListenPort < 0 || worldListenPort > 0xFFFF) + { + TC_LOG_ERROR("server.bnetserver", "Specified worldserver listen port (%d) out of allowed range (1-65535)", worldListenPort); + return 1; + } + // Initialize the database connection if (!StartDB()) return 1; + sIpcContext->Initialize(); + // Get the list of realms for the server - sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10)); + sRealmList->Initialize(_ioService, sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 10), worldListenPort); // Start the listening port (acceptor) for auth connections int32 bnport = sConfigMgr->GetIntDefault("BattlenetPort", 1119); @@ -135,6 +145,10 @@ int main(int argc, char** argv) // Start the io service worker loop _ioService.run(); + sIpcContext->Close(); + + sRealmList->Close(); + // Close the Database Pool and library StopDB(); diff --git a/src/server/bnetserver/Packets/BitStream.h b/src/server/bnetserver/Packets/BitStream.h index 952ec5a39e2..54c61ab3bbf 100644 --- a/src/server/bnetserver/Packets/BitStream.h +++ b/src/server/bnetserver/Packets/BitStream.h @@ -212,14 +212,6 @@ namespace Battlenet } } - void SetReadPos(uint32 bits) - { - if (bits > _writePos) - throw BitStreamPositionException(true, bits, 0, _writePos); - - _readPos = bits; - } - bool IsRead() const { return _readPos >= _writePos; } uint8* GetBuffer() { return _buffer.data(); } @@ -227,6 +219,10 @@ namespace Battlenet size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; } + // These methods are meant to only be used when their corresponding actions in the client ignore the value completely + void ReadSkip(uint32 bitCount) { _readPos += bitCount; } + void WriteSkip(uint32 bitCount) { Write(0, bitCount); } + private: uint32 _writePos; uint32 _readPos; diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp index 14c5fb3a665..2659ec6204f 100644 --- a/src/server/bnetserver/Packets/FriendsPackets.cpp +++ b/src/server/bnetserver/Packets/FriendsPackets.cpp @@ -132,7 +132,7 @@ std::string Battlenet::Friends::SocialNetworkCheckConnectedResult::ToString() co void Battlenet::Friends::SocialNetworkCheckConnectedResult::Write() { - _stream.Write(0, 23); // Ignored + _stream.WriteSkip(23); _stream.Write(Result, 16); _stream.Write(SocialNetworkId, 32); } diff --git a/src/server/bnetserver/Packets/PacketManager.cpp b/src/server/bnetserver/Packets/PacketManager.cpp index 019cf48ac30..e18f3dc5ffb 100644 --- a/src/server/bnetserver/Packets/PacketManager.cpp +++ b/src/server/bnetserver/Packets/PacketManager.cpp @@ -115,8 +115,8 @@ void Battlenet::PacketManager::RegisterWoWRealmPackets() REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_SUBSCRIBE_RESPONSE, WOWREALM), WoWRealm::ListSubscribeResponse); REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_UPDATE, WOWREALM), WoWRealm::ListUpdate); REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_LIST_COMPLETE, WOWREALM), WoWRealm::ListComplete); - REGISTER_SERVER_PACKET_NAME(PacketHeader(WoWRealm::SMSG_TOON_READY, WOWREALM), "WoWRealm::ToonReady"); - REGISTER_SERVER_PACKET_NAME(PacketHeader(WoWRealm::SMSG_TOON_LOGGED_OUT, WOWREALM), "WoWRealm::ToonLoggedOut"); + REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_READY, WOWREALM), WoWRealm::ToonReady); + REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_TOON_LOGGED_OUT, WOWREALM), WoWRealm::ToonLoggedOut); REGISTER_SERVER_PACKET(PacketHeader(WoWRealm::SMSG_JOIN_RESPONSE_V2, WOWREALM), WoWRealm::JoinResponseV2); } diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.cpp b/src/server/bnetserver/Packets/WoWRealmPackets.cpp index beeeb14895c..986152cbccb 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.cpp +++ b/src/server/bnetserver/Packets/WoWRealmPackets.cpp @@ -40,6 +40,26 @@ void Battlenet::WoWRealm::ListUnsubscribe::CallHandler(Session* session) session->HandleListUnsubscribe(*this); } +void Battlenet::WoWRealm::JoinRequestV2::Read() +{ + Realm.Battlegroup = _stream.Read(8); + Realm.Index = _stream.Read(32); + Realm.Region = _stream.Read(8); + ClientSeed = _stream.Read(32); +} + +std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index; + return stream.str().c_str(); +} + +void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) +{ + session->HandleJoinRequestV2(*this); +} + Battlenet::WoWRealm::ListSubscribeResponse::~ListSubscribeResponse() { for (ServerPacket* realmData : RealmData) @@ -143,24 +163,32 @@ std::string Battlenet::WoWRealm::ListUpdate::ToString() const return stream.str().c_str(); } -void Battlenet::WoWRealm::JoinRequestV2::Read() +void Battlenet::WoWRealm::ToonReady::Write() { - Realm.Battlegroup = _stream.Read(8); - Realm.Index = _stream.Read(32); - Realm.Region = _stream.Read(8); - ClientSeed = _stream.Read(32); + _stream.Write(Realm.Region, 8); + _stream.WriteFourCC(Game); + uint32 realmAddress = ((Realm.Battlegroup << 16) & 0xFF0000) | uint16(Realm.Index); + _stream.Write(realmAddress, 32); + _stream.WriteString(Name, 7, -2); + _stream.WriteSkip(7); + _stream.Write(Guid, 64); + _stream.WriteFourCC(Game); + _stream.Write(Realm.Region, 8); + _stream.WriteSkip(21); + _stream.Write(realmAddress, 32); + _stream.WriteSkip(9); + _stream.Write(0, 64); // Unknown + _stream.Write(0, 32); // Unknown } -std::string Battlenet::WoWRealm::JoinRequestV2::ToString() const +std::string Battlenet::WoWRealm::ToonReady::ToString() const { std::ostringstream stream; - stream << "Battlenet::WoWRealm::JoinRequestV2 ClientSeed " << ClientSeed << " Region " << uint32(Realm.Region) << " Battlegroup " << uint32(Realm.Battlegroup) << " Index " << Realm.Index; - return stream.str().c_str(); -} + stream << "Battlenet::WoWRealm::ToonReady" << " Game: " << Game + << ", Region: " << uint32(Realm.Region) << ", Battlegroup: " << uint32(Realm.Battlegroup) << ", Index: " << Realm.Index + << ", Guid: " << Guid << ", Name: " << Name; -void Battlenet::WoWRealm::JoinRequestV2::CallHandler(Session* session) -{ - session->HandleJoinRequestV2(*this); + return stream.str().c_str(); } void Battlenet::WoWRealm::JoinResponseV2::Write() diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h index 2b1390a9067..b411c63100a 100644 --- a/src/server/bnetserver/Packets/WoWRealmPackets.h +++ b/src/server/bnetserver/Packets/WoWRealmPackets.h @@ -153,6 +153,33 @@ namespace Battlenet std::string ToString() const override { return "Battlenet::WoWRealm::ListComplete"; } }; + class ToonReady final : public ServerPacket + { + public: + ToonReady() : ServerPacket(PacketHeader(SMSG_TOON_READY, WOWREALM)), Game("WoW"), Guid(0) + { + } + + void Write() override; + std::string ToString() const override; + + std::string Game; + RealmId Realm; + uint64 Guid; + std::string Name; + }; + + class ToonLoggedOut final : public ServerPacket + { + public: + ToonLoggedOut() : ServerPacket(PacketHeader(SMSG_TOON_LOGGED_OUT, WOWREALM)) + { + } + + void Write() override { } + std::string ToString() const override { return "Battlenet::WoWRealm::ToonLoggedOut"; } + }; + class JoinResponseV2 final : public ServerPacket { public: diff --git a/src/server/bnetserver/Realms/RealmList.cpp b/src/server/bnetserver/Realms/RealmList.cpp index 2bf93e12cb3..cc7e1d492a8 100644 --- a/src/server/bnetserver/Realms/RealmList.cpp +++ b/src/server/bnetserver/Realms/RealmList.cpp @@ -16,12 +16,21 @@ * with this program. If not, see . */ -#include #include "Common.h" #include "Database/DatabaseEnv.h" #include "SessionManager.h" #include "Util.h" +#include "Commands.h" #include "RealmList.h" +#include + +Battlenet::RealmId& Battlenet::RealmId::operator=(Battlenet::RealmHandle const& handle) +{ + Region = handle.Region; + Battlegroup = handle.Battlegroup; + Index = handle.Index; + return *this; +} ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const { @@ -58,7 +67,7 @@ ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) cons return endpoint; } -RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr) +RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr), _worldListener(nullptr) { } @@ -66,10 +75,11 @@ RealmList::~RealmList() { delete _updateTimer; delete _resolver; + delete _worldListener; } // Load the realm list from the database -void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval) +void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval, uint16 worldListenPort) { _updateInterval = updateInterval; _updateTimer = new boost::asio::deadline_timer(ioService); @@ -77,6 +87,14 @@ void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInte // Get the content of the realmlist table in the database UpdateRealms(boost::system::error_code()); + + _worldListener = new WorldListener(worldListenPort); + _worldListener->Start(); +} + +void RealmList::Close() +{ + _worldListener->End(); } template diff --git a/src/server/bnetserver/Realms/RealmList.h b/src/server/bnetserver/Realms/RealmList.h index a4d3d77ff56..dc78a00dfdd 100644 --- a/src/server/bnetserver/Realms/RealmList.h +++ b/src/server/bnetserver/Realms/RealmList.h @@ -19,11 +19,12 @@ #ifndef _REALMLIST_H #define _REALMLIST_H +#include "Common.h" +#include "WorldListener.h" #include #include #include #include -#include "Common.h" using namespace boost::asio; @@ -44,6 +45,8 @@ enum RealmFlags namespace Battlenet { + struct RealmHandle; + struct RealmId { RealmId() : Region(0), Battlegroup(0), Index(0), Build(0) { } @@ -59,6 +62,8 @@ namespace Battlenet { return memcmp(this, &r, sizeof(RealmId) - sizeof(Build)) < 0; } + + RealmId& operator=(RealmHandle const& handle); }; } @@ -98,7 +103,8 @@ public: ~RealmList(); - void Initialize(boost::asio::io_service& ioService, uint32 updateInterval); + void Initialize(boost::asio::io_service& ioService, uint32 updateInterval, uint16 worldListenPort); + void Close(); RealmMap const& GetRealms() const { return _realms; } Realm const* GetRealm(Battlenet::RealmId const& id) const; @@ -114,6 +120,7 @@ private: uint32 _updateInterval; boost::asio::deadline_timer* _updateTimer; boost::asio::ip::tcp::resolver* _resolver; + WorldListener* _worldListener; }; #define sRealmList RealmList::instance() diff --git a/src/server/bnetserver/Realms/WorldListener.cpp b/src/server/bnetserver/Realms/WorldListener.cpp new file mode 100644 index 00000000000..30886a67310 --- /dev/null +++ b/src/server/bnetserver/Realms/WorldListener.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Log.h" +#include "SessionManager.h" +#include "WoWRealmPackets.h" +#include "ZmqContext.h" +#include "WorldListener.h" + +WorldListener::HandlerTable const WorldListener::_handlers; + +WorldListener::HandlerTable::HandlerTable() +{ +#define DEFINE_HANDLER(opc, func) _handlers[opc] = { func, #opc } + + DEFINE_HANDLER(BNET_CHANGE_TOON_ONLINE_STATE, &WorldListener::HandleToonOnlineStatusChange); + +#undef DEFINE_HANDLER +} + +WorldListener::WorldListener(uint16 worldListenPort) : _worldListenPort(worldListenPort) +{ + _worldSocket = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull); +} + +WorldListener::~WorldListener() +{ + delete _worldSocket; +} + +void WorldListener::Run() +{ + while (!ProcessExit()) + { + _poller->poll(); + if (_poller->events(*_worldSocket) & zmqpp::poller::poll_in) + { + int32 op1; + do + { + zmqpp::message msg; + _worldSocket->receive(msg); + Dispatch(msg); + _worldSocket->get(zmqpp::socket_option::events, op1); + } while (op1 & zmqpp::poller::poll_in); + } + } +} + +void WorldListener::HandleOpen() +{ + _worldSocket->bind(std::string("tcp://*:") + std::to_string(_worldListenPort)); + _poller->add(*_worldSocket); + TC_LOG_INFO("server.ipc", "Listening on connections from worldservers..."); +} + +void WorldListener::HandleClose() +{ + _worldSocket->close(); + TC_LOG_INFO("server.ipc", "Shutting down connections from worldservers..."); +} + +void WorldListener::Dispatch(zmqpp::message& msg) const +{ + Battlenet::Header ipcHeader; + msg >> ipcHeader; + + if (ipcHeader.Ipc.Channel != IPC_CHANNEL_BNET) + return; + + if (ipcHeader.Ipc.Command < IPC_BNET_MAX_COMMAND) + (this->*_handlers[ipcHeader.Ipc.Command].Handler)(ipcHeader.Realm, msg); +} + +void WorldListener::HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const +{ + Battlenet::ToonHandle toonHandle; + bool online; + msg >> toonHandle; + msg >> online; + + if (Battlenet::Session* session = sSessionMgr.GetSession(toonHandle.AccountId, toonHandle.GameAccountId)) + { + if (online) + { + Battlenet::WoWRealm::ToonReady* toonReady = new Battlenet::WoWRealm::ToonReady(); + toonReady->Realm = realm; + toonReady->Guid = toonHandle.Guid; + toonReady->Name = toonHandle.Name; + session->AsyncWrite(toonReady); + } + else + session->AsyncWrite(new Battlenet::WoWRealm::ToonLoggedOut()); + } +} diff --git a/src/server/bnetserver/Realms/WorldListener.h b/src/server/bnetserver/Realms/WorldListener.h new file mode 100644 index 00000000000..04d5342449c --- /dev/null +++ b/src/server/bnetserver/Realms/WorldListener.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef WorldListener_h__ +#define WorldListener_h__ + +#include "ZMQTask.h" +#include "Commands.h" + +class WorldListener : public ZMQTask +{ +public: + explicit WorldListener(uint16 worldListenPort); + ~WorldListener(); + void Run() override; + +protected: + void HandleOpen() override; + void HandleClose() override; + +private: + void Dispatch(zmqpp::message& msg) const; + + typedef void(WorldListener::*PacketHandler)(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const; + class HandlerTable + { + public: + HandlerTable(); + + struct HandlerInfo + { + PacketHandler Handler; + char const* Name; + }; + + HandlerInfo const& operator[](uint8 opcode) const { return _handlers[opcode]; } + + private: + HandlerInfo _handlers[IPC_BNET_MAX_COMMAND]; + }; + + void HandleToonOnlineStatusChange(Battlenet::RealmHandle const& realm, zmqpp::message& msg) const; + + zmqpp::socket* _worldSocket; + uint16 _worldListenPort; + static HandlerTable const _handlers; +}; + +#endif // WorldListener_h__ diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h index a2c587841a4..c932115a04b 100644 --- a/src/server/bnetserver/Server/Session.h +++ b/src/server/bnetserver/Server/Session.h @@ -93,9 +93,9 @@ namespace Battlenet bool IsSubscribedToRealmListUpdates() const { return _subscribedToRealmListUpdates; } - protected: void AsyncWrite(ServerPacket* packet); + protected: void ReadHandler() override; private: diff --git a/src/server/bnetserver/Server/SessionManager.cpp b/src/server/bnetserver/Server/SessionManager.cpp index 8dcee55ec6c..9e5836dab8d 100644 --- a/src/server/bnetserver/Server/SessionManager.cpp +++ b/src/server/bnetserver/Server/SessionManager.cpp @@ -49,3 +49,22 @@ void Battlenet::SessionManager::RemoveSession(Session* session) _sessions.erase({ session->GetAccountId(), session->GetGameAccountId() }); _sessionsByAccountId[session->GetAccountId()].remove(session); } + +Battlenet::Session* Battlenet::SessionManager::GetSession(uint32 accountId, uint32 gameAccountId) const +{ + auto itr = _sessions.find({ accountId, gameAccountId }); + if (itr != _sessions.end()) + return itr->second; + + return nullptr; +} + +std::list Battlenet::SessionManager::GetSessions(uint32 accountId) const +{ + std::list sessions; + auto itr = _sessionsByAccountId.find(accountId); + if (itr != _sessionsByAccountId.end()) + sessions = itr->second; + + return sessions; +} diff --git a/src/server/bnetserver/Server/SessionManager.h b/src/server/bnetserver/Server/SessionManager.h index bbd78c052d2..08ca5ce2b4e 100644 --- a/src/server/bnetserver/Server/SessionManager.h +++ b/src/server/bnetserver/Server/SessionManager.h @@ -60,6 +60,9 @@ namespace Battlenet void RemoveSession(Session* /*session*/); + Session* GetSession(uint32 accountId, uint32 gameAccountId) const; + std::list GetSessions(uint32 accountId) const; + template void LockedForEach(Iterator iterator) { diff --git a/src/server/bnetserver/bnetserver.conf.dist b/src/server/bnetserver/bnetserver.conf.dist index 84456c117b3..102ddb9906a 100644 --- a/src/server/bnetserver/bnetserver.conf.dist +++ b/src/server/bnetserver/bnetserver.conf.dist @@ -46,6 +46,13 @@ LogsDir = "" MaxPingTime = 30 +# +# WorldserverListenPort +# Description: TCP port to listen on for incoming worldserver IPC. +# Default: 1118 + +WorldserverListenPort = 1118 + # # BattlenetPort # Description: TCP port to reach the auth server for battle.net connections. diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt index 1c5fcbee52e..3aac255be29 100644 --- a/src/server/collision/CMakeLists.txt +++ b/src/server/collision/CMakeLists.txt @@ -47,6 +47,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/shared/DataStores + ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/game/Addons ${CMAKE_SOURCE_DIR}/src/server/game/Conditions ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 79512e57fe3..6550bccc06d 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -107,7 +107,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& else { bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid); - logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmID); + logGmTrade = AccountMgr::HasPermission(bidderAccId, rbac::RBAC_PERM_LOG_GM_TRADE, realmHandle.Index); if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName)) bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 0d1b460500e..27b3ea2c381 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -111,6 +111,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/zlib + ${CMAKE_SOURCE_DIR}/dep/zmqpp ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/collision/Models @@ -129,6 +130,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/Accounts ${CMAKE_CURRENT_SOURCE_DIR}/Achievements @@ -205,6 +207,7 @@ include_directories( ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${VALGRIND_INCLUDE_DIR} + ${ZMQ_INCLUDE_DIR} ) add_library(game STATIC diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index ace13989efb..6dfd25495d2 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -160,7 +160,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac if (target) target_sec = target->GetSecurity(); else if (target_account) - target_sec = AccountMgr::GetSecurity(target_account, realmID); + target_sec = AccountMgr::GetSecurity(target_account, realmHandle.Index); else return true; // caller must report error for (target == NULL && target_account == 0) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 2cae8427161..bef7aada6e9 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -47,6 +47,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "BattlenetServerManager.h" class LoginQueryHolder : public SQLQueryHolder { @@ -689,13 +690,13 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); stmt->setUInt32(0, GetAccountId()); - stmt->setUInt32(1, realmID); + stmt->setUInt32(1, realmHandle.Index); trans->Append(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS); stmt->setUInt32(0, createInfo->CharCount); stmt->setUInt32(1, GetAccountId()); - stmt->setUInt32(2, realmID); + stmt->setUInt32(2, realmHandle.Index); trans->Append(stmt); LoginDatabase.CommitTransaction(trans); @@ -1139,6 +1140,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin); + sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), true); + delete holder; } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 8d11b9bf41d..3f7cf24206d 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -609,7 +609,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std team = Player::TeamForRace(fields[1].GetUInt8()); friendAccountId = fields[2].GetUInt32(); - if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID))) + if (HasPermission(rbac::RBAC_PERM_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmHandle.Index))) { if (friendGuid) { diff --git a/src/server/game/Server/BattlenetServerManager.cpp b/src/server/game/Server/BattlenetServerManager.cpp new file mode 100644 index 00000000000..b267926c6ff --- /dev/null +++ b/src/server/game/Server/BattlenetServerManager.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Config.h" +#include "World.h" +#include "ZmqContext.h" +#include "BattlenetServerManager.h" + +void Battlenet::ServerManager::InitializeConnection() +{ + std::string bnetserverAddress = sConfigMgr->GetStringDefault("BnetServer.Address", "127.0.0.1"); + int32 bnetserverPort = sConfigMgr->GetIntDefault("BnetServer.Port", 1118); + _socket = new ZmqMux("inproc://bnetmgr", "tcp://" + bnetserverAddress + ":" + std::to_string(bnetserverPort)); + _socket->Start(); +} + +void Battlenet::ServerManager::CloseConnection() +{ + _socket->End(); + delete _socket; + _socket = nullptr; +} + +Battlenet::Header Battlenet::ServerManager::CreateHeader(BnetCommands command) +{ + Header header; + header.Ipc.Channel = IPC_CHANNEL_BNET; + header.Ipc.Command = command; + header.Realm = realmHandle; + return header; +} + +void Battlenet::ServerManager::SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online) +{ + // Do nothing for Grunt login + if (!battlenetAccountId) + return; + + Header header = CreateHeader(BNET_CHANGE_TOON_ONLINE_STATE); + ToonHandle toon; + toon.AccountId = battlenetAccountId; + toon.GameAccountId = gameAccountId; + toon.Guid = guid; + toon.Name = name; + + zmqpp::message msg; + msg << header; + msg << toon; + msg << online; + + _socket->Send(&msg); +} diff --git a/src/server/game/Server/BattlenetServerManager.h b/src/server/game/Server/BattlenetServerManager.h new file mode 100644 index 00000000000..fe103a1c981 --- /dev/null +++ b/src/server/game/Server/BattlenetServerManager.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef BattlenetMgr_h__ +#define BattlenetMgr_h__ + +#include "ZmqMux.h" +#include "Commands.h" + +namespace zmqpp +{ + class socket; +} + +namespace Battlenet +{ + class ServerManager + { + ServerManager() : _socket(nullptr) { } + + public: + void InitializeConnection(); + void CloseConnection(); + + static ServerManager& Instance() + { + static ServerManager instance; + return instance; + } + + void SendChangeToonOnlineState(uint32 battlenetAccountId, uint32 gameAccountId, ObjectGuid guid, std::string const& name, bool online); + + private: + static Header CreateHeader(BnetCommands command); + ZmqMux* _socket; + }; +} + +#define sBattlenetServer Battlenet::ServerManager::Instance() + +#endif // BattlenetMgr_h__ diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 4c183939460..0fd46f0d20b 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -47,6 +47,7 @@ #include "Transport.h" #include "WardenWin.h" #include "WardenMac.h" +#include "BattlenetServerManager.h" namespace { @@ -582,6 +583,9 @@ void WorldSession::LogoutPlayer(bool save) _player->CleanupsBeforeDelete(); TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel()); + + sBattlenetServer.SendChangeToonOnlineState(GetBattlenetAccountId(), GetAccountId(), _player->GetGUID(), _player->GetName(), false); + if (Map* _map = _player->FindMap()) _map->RemovePlayerFromMap(_player, true); @@ -1143,11 +1147,11 @@ void WorldSession::LoadPermissions() AccountMgr::GetName(id, name); uint8 secLevel = GetSecurity(); - _RBACData = new rbac::RBACData(id, name, realmID, secLevel); + _RBACData = new rbac::RBACData(id, name, realmHandle.Index, secLevel); _RBACData->LoadFromDB(); TC_LOG_DEBUG("rbac", "WorldSession::LoadPermissions [AccountId: %u, Name: %s, realmId: %d, secLevel: %u]", - id, name.c_str(), realmID, secLevel); + id, name.c_str(), realmHandle.Index, secLevel); } rbac::RBACData* WorldSession::GetRBACData() @@ -1162,7 +1166,7 @@ bool WorldSession::HasPermission(uint32 permission) bool hasPermission = _RBACData->HasPermission(permission); TC_LOG_DEBUG("rbac", "WorldSession::HasPermission [AccountId: %u, Name: %s, realmId: %d]", - _RBACData->GetId(), _RBACData->GetName().c_str(), realmID); + _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index); return hasPermission; } @@ -1170,7 +1174,7 @@ bool WorldSession::HasPermission(uint32 permission) void WorldSession::InvalidateRBACData() { TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]", - _RBACData->GetId(), _RBACData->GetName().c_str(), realmID); + _RBACData->GetId(), _RBACData->GetName().c_str(), realmHandle.Index); delete _RBACData; _RBACData = NULL; } diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index bff343bdcb1..7933ddfeb4d 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -406,7 +406,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) return; } - if (realmIndex != realmID) + if (realmIndex != realmHandle.Index) { SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm)."); @@ -485,7 +485,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID); stmt->setUInt32(0, id); - stmt->setInt32(1, int32(realmID)); + stmt->setInt32(1, int32(realmHandle.Index)); result = LoginDatabase.Query(stmt); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 6adb93d4742..4b114255dbc 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1375,7 +1375,7 @@ void World::SetInitialWorldSettings() uint32 server_type = IsFFAPvPRealm() ? uint32(REALM_TYPE_PVP) : getIntConfig(CONFIG_GAME_TYPE); uint32 realm_zone = getIntConfig(CONFIG_REALM_ZONE); - LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query + LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmHandle.Index); // One-time query ///- Remove the bones (they should not exist in DB though) and old corpses after a restart PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CORPSES); @@ -1797,7 +1797,7 @@ void World::SetInitialWorldSettings() m_startTime = m_gameTime; LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES(%u, %u, 0, '%s')", - realmID, uint32(m_startTime), _FULLVERSION); // One-time query + realmHandle.Index, uint32(m_startTime), _FULLVERSION); // One-time query m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS); m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS); @@ -2079,7 +2079,7 @@ void World::Update(uint32 diff) stmt->setUInt32(0, tmpDiff); stmt->setUInt16(1, uint16(maxOnlinePlayers)); - stmt->setUInt32(2, realmID); + stmt->setUInt32(2, realmHandle.Index); stmt->setUInt32(3, uint32(m_startTime)); LoginDatabase.Execute(stmt); @@ -2809,13 +2809,13 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM); stmt->setUInt32(0, accountId); - stmt->setUInt32(1, realmID); + stmt->setUInt32(1, realmHandle.Index); LoginDatabase.Execute(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS); stmt->setUInt8(0, charCount); stmt->setUInt32(1, accountId); - stmt->setUInt32(2, realmID); + stmt->setUInt32(2, realmHandle.Index); LoginDatabase.Execute(stmt); } } @@ -2984,7 +2984,7 @@ void World::ResetCurrencyWeekCap() void World::LoadDBAllowedSecurityLevel() { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL); - stmt->setInt32(0, int32(realmID)); + stmt->setInt32(0, int32(realmHandle.Index)); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 49d154d8db6..2c74e3929fe 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -24,6 +24,7 @@ #define __WORLD_H #include "Common.h" +#include "Commands.h" #include "ObjectGuid.h" #include "Timer.h" #include "SharedDefines.h" @@ -879,7 +880,7 @@ class World std::deque> m_realmCharCallbacks; }; -extern uint32 realmID; +extern Battlenet::RealmHandle realmHandle; #define sWorld World::instance() #endif diff --git a/src/server/ipc/CMakeLists.txt b/src/server/ipc/CMakeLists.txt new file mode 100644 index 00000000000..93a5d630dfe --- /dev/null +++ b/src/server/ipc/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2008-2014 TrinityCore +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +file(GLOB_RECURSE sources_ipc *.cpp *.h) + +set(ipc_SRCS + ${sources_ipc} +) + +include_directories( + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/dep/zmqpp + ${CMAKE_SOURCE_DIR}/src/server/shared/ + ${ZMQ_INCLUDE_DIR} +) + +add_library(ipc STATIC ${ipc_SRCS}) diff --git a/src/server/ipc/Commands.cpp b/src/server/ipc/Commands.cpp new file mode 100644 index 00000000000..8e494fc34b9 --- /dev/null +++ b/src/server/ipc/Commands.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Commands.h" +#include + +zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header) +{ + msg >> header.Channel; + msg >> header.Command; + return msg; +} + +zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm) +{ + msg >> realm.Region; + msg >> realm.Battlegroup; + msg >> realm.Index; + return msg; +} + +zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header) +{ + msg >> header.Ipc; + msg >> header.Realm; + return msg; +} + +zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle) +{ + msg >> toonHandle.AccountId; + msg >> toonHandle.GameAccountId; + msg >> toonHandle.Guid; + msg >> toonHandle.Name; + return msg; +} + +zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header) +{ + msg << header.Channel; + msg << header.Command; + return msg; +} + +zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm) +{ + msg << realm.Region; + msg << realm.Battlegroup; + msg << realm.Index; + return msg; +} + +zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header) +{ + msg << header.Ipc; + msg << header.Realm; + return msg; +} + +zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle) +{ + msg << toonHandle.AccountId; + msg << toonHandle.GameAccountId; + msg << toonHandle.Guid; + msg << toonHandle.Name; + return msg; +} diff --git a/src/server/ipc/Commands.h b/src/server/ipc/Commands.h new file mode 100644 index 00000000000..05309a45022 --- /dev/null +++ b/src/server/ipc/Commands.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef _COMMANDS_H +#define _COMMANDS_H + +#include "Define.h" +#include + +enum Channels +{ + IPC_CHANNEL_BNET, + + MAX_IPC_CHANNELS, +}; + +enum BnetCommands +{ + BNET_CHANGE_TOON_ONLINE_STATE, + + IPC_BNET_MAX_COMMAND +}; + +struct IPCHeader +{ + uint8 Channel; + uint8 Command; +}; + +namespace Battlenet +{ + struct RealmHandle + { + uint8 Region; + uint8 Battlegroup; + uint32 Index; + }; + + struct Header + { + IPCHeader Ipc; + RealmHandle Realm; + }; + + struct ToonHandle + { + uint32 AccountId; + uint32 GameAccountId; + uint64 Guid; + std::string Name; + }; +} + +namespace zmqpp +{ + class message; +} + +zmqpp::message& operator>>(zmqpp::message& msg, IPCHeader& header); +zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm); +zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header); +zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle); + +zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header); +zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm); +zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header); +zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle); + +#endif // _COMMANDS_H diff --git a/src/server/ipc/ZMQTask.cpp b/src/server/ipc/ZMQTask.cpp new file mode 100644 index 00000000000..0d25dc2babf --- /dev/null +++ b/src/server/ipc/ZMQTask.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ZMQTask.h" +#include "ZmqContext.h" +#include + +ZMQTask::ZMQTask() +{ + _poller = new zmqpp::poller(); +} + +ZMQTask::~ZMQTask() +{ + delete _poller; + _poller = NULL; + delete _inproc; + delete _thread; +} + +void ZMQTask::Start() +{ + _inproc = sIpcContext->CreateInprocSubscriber(); + _poller->add(*_inproc); + + HandleOpen(); + _thread = new std::thread(&ZMQTask::Run, this); +} + +void ZMQTask::End() +{ + _thread->join(); + _inproc->close(); + HandleClose(); +} + +bool ZMQTask::ProcessExit() +{ + if (_poller->events(*_inproc) == zmqpp::poller::poll_in) + { + int op1; + do + { + zmqpp::message msg; + if (!_inproc->receive(msg, true)) + return false; //No more messages to read from sock. This shouldn't happen. + + // strip 'internalmq.' from message + std::string cmd = msg.get(0).substr(11); + if (cmd == "kill") + return true; + + _inproc->get(zmqpp::socket_option::events, op1); + } while (op1 & zmqpp::poller::poll_in); + } + + return false; +} + +void ZMQTask::Pipeline(zmqpp::socket* from, zmqpp::socket* to) +{ + /* + Push messages from socket to socket. + */ + if (_poller->events(*from) == zmqpp::poller::poll_in) + { + int32 op1, op2; + do + { + zmqpp::message msg; + if (!from->receive(msg, true)) + return; //No more messages to read from socket. This shouldn't happen. + + to->send(msg); + from->get(zmqpp::socket_option::events, op1); + to->get(zmqpp::socket_option::events, op2); + } while(op1 & zmqpp::poller::poll_in && op2 & zmqpp::poller::poll_out); + } +} diff --git a/src/server/ipc/ZMQTask.h b/src/server/ipc/ZMQTask.h new file mode 100644 index 00000000000..24251893aaa --- /dev/null +++ b/src/server/ipc/ZMQTask.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef __ZMQTASK_H +#define __ZMQTASK_H + +#include "Define.h" +#include +#include +#include + +/* + This class serves as a base for all long running tasks + It is set up to terminate its running task upon receiving "kill" command +*/ +class ZMQTask +{ +public: + ZMQTask(); + virtual ~ZMQTask(); + + void Start(); + void End(); + virtual void Run() = 0; + +protected: + virtual void HandleOpen() { } + virtual void HandleClose() { } + void Pipeline(zmqpp::socket* from, zmqpp::socket* to); + bool ProcessExit(); + + zmqpp::poller* _poller; + + zmqpp::socket* _inproc; + std::thread* _thread; +}; + +#endif // __ZMQTASK_H diff --git a/src/server/ipc/ZmqContext.cpp b/src/server/ipc/ZmqContext.cpp new file mode 100644 index 00000000000..305e6b1d843 --- /dev/null +++ b/src/server/ipc/ZmqContext.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ZmqContext.h" + +ZmqContext::ZmqContext() : _inproc(nullptr) +{ +} + +ZmqContext::~ZmqContext() +{ + delete _inproc; +} + +zmqpp::socket* ZmqContext::CreateNewSocket(zmqpp::socket_type type) +{ + std::unique_lock lock(_mutex); + return new zmqpp::socket(_context, type); +} + +void ZmqContext::Initialize() +{ + _inproc = new zmqpp::socket(_context, zmqpp::socket_type::pub); + _inproc->bind("inproc://workers"); +} + +zmqpp::socket* ZmqContext::CreateInprocSubscriber() +{ + zmqpp::socket* sub = CreateNewSocket(zmqpp::socket_type::sub); + sub->connect("inproc://workers"); + sub->subscribe("internalmq."); + return sub; +} + +void ZmqContext::Close() +{ + _inproc->send("internalmq.kill"); +} diff --git a/src/server/ipc/ZmqContext.h b/src/server/ipc/ZmqContext.h new file mode 100644 index 00000000000..a6ad12b1b70 --- /dev/null +++ b/src/server/ipc/ZmqContext.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef __ZMQCONTEX_H +#define __ZMQCONTEX_H + +#include +#include + +/* + * We need to serialize access to zmq context otherwise stuff blows up. + */ +class ZmqContext +{ +public: + ~ZmqContext(); + + static ZmqContext* Instance() + { + static ZmqContext instance; + return &instance; + } + + zmqpp::socket* CreateNewSocket(zmqpp::socket_type); + void Initialize(); + zmqpp::socket* CreateInprocSubscriber(); + void Close(); + +private: + ZmqContext(); + ZmqContext(ZmqContext const&) = delete; + ZmqContext& operator=(ZmqContext const&) = delete; + + zmqpp::context _context; + std::mutex _mutex; + zmqpp::socket* _inproc; +}; + +#define sIpcContext ZmqContext::Instance() + +#endif diff --git a/src/server/ipc/ZmqListener.cpp b/src/server/ipc/ZmqListener.cpp new file mode 100644 index 00000000000..98333305e58 --- /dev/null +++ b/src/server/ipc/ZmqListener.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ZmqListener.h" +#include "ZmqContext.h" + +ZmqListener::ZmqListener(std::string const& from, std::string const& to) +{ + _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::sub); + _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push); + _from->connect(from); + _to->bind(to); +} + +ZmqListener::~ZmqListener() +{ + delete _from; + delete _to; +} + +void ZmqListener::HandleOpen() +{ +} + +void ZmqListener::HandleClose() +{ + _from->close(); + _to->close(); +} + +void ZmqListener::Run() +{ + while (!ProcessExit()) + { + _poller->poll(); + + while (_poller->events(*_from) & zmqpp::poller::poll_in && + _poller->events(*_to) & zmqpp::poller::poll_out) + { + zmqpp::message msg; + _from->receive(msg); + _to->send(msg); + } + } +} + +void ZmqListener::Subscribe(std::string const& keyword) +{ + _from->subscribe(keyword); +} + +void ZmqListener::Unsubscribe(std::string const& keyword) +{ + _from->unsubscribe(keyword); +} diff --git a/src/server/ipc/ZmqListener.h b/src/server/ipc/ZmqListener.h new file mode 100644 index 00000000000..8b79ba67f6d --- /dev/null +++ b/src/server/ipc/ZmqListener.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef __ZMQLISTENER_H +#define __ZMQLISTENER_H + +#include "ZMQTask.h" +#include + +class ZmqListener : public ZMQTask +{ +/* + * Read broadcasts from remote PUB socket, and forward them to + * another socket. + * + * from - client SUB socket + * to - listen PUSH socket + * + */ +public: + ZmqListener(std::string const& from, std::string const& to); + ~ZmqListener(); + void Run() override; + + void Subscribe(std::string const& keyword); + void Unsubscribe(std::string const& keyword); + +protected: + void HandleOpen() override; + void HandleClose() override; + +private: + zmqpp::socket* _from; + zmqpp::socket* _to; +}; + +#endif diff --git a/src/server/ipc/ZmqMux.cpp b/src/server/ipc/ZmqMux.cpp new file mode 100644 index 00000000000..4b5a4f48b05 --- /dev/null +++ b/src/server/ipc/ZmqMux.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ZmqMux.h" +#include "ZmqContext.h" + +ZmqMux::ZmqMux(std::string from_uri, std::string to_uri): + _fromAddress(from_uri) +{ + printf("Opening muxer thread from %s to %s\n", from_uri.c_str(), to_uri.c_str()); + _from = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull); + _to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push); + + _from->bind(from_uri); + _to->connect(to_uri); +} + +ZmqMux::~ZmqMux() +{ + delete _from; + delete _to; +} + +void ZmqMux::HandleOpen() +{ + _poller->add(*_from); + _poller->add(*_to, zmqpp::poller::poll_out); +} + +bool ZmqMux::Send(zmqpp::message* m, bool dont_block) +{ + if (_socket.get() == nullptr) + { + _socket.reset(sIpcContext->CreateNewSocket(zmqpp::socket_type::push)); + _socket->connect(_fromAddress); + } + + return _socket->send(*m, dont_block); +} + +void ZmqMux::Run() +{ + for (;;) + { + if (!_poller->poll()) + break; + + if (ProcessExit()) + break; + + Pipeline(_from, _to); + } +} diff --git a/src/server/ipc/ZmqMux.h b/src/server/ipc/ZmqMux.h new file mode 100644 index 00000000000..4b81f11daaf --- /dev/null +++ b/src/server/ipc/ZmqMux.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef __ZMQMUX_H +#define __ZMQMUX_H + +#include "ZMQTask.h" +#include +#include + +/* + * Multiplexes zmq messages from many threads, + * and then passes them to another socket. + */ +class ZmqMux : public ZMQTask +{ +public: + ZmqMux(std::string from, std::string to); + ~ZmqMux(); + bool Send(zmqpp::message*, bool dont_block = false); + void Run() override; + +protected: + void HandleOpen() override; + +private: + boost::thread_specific_ptr _socket; + zmqpp::socket* _from; + zmqpp::socket* _to; + std::string const _fromAddress; +}; + +#endif diff --git a/src/server/ipc/ZmqWorker.cpp b/src/server/ipc/ZmqWorker.cpp new file mode 100644 index 00000000000..f205ea831b5 --- /dev/null +++ b/src/server/ipc/ZmqWorker.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "ZmqWorker.h" +#include "ZmqContext.h" + +ZmqWorker::ZmqWorker(std::string task_uri, std::string res_uri) : + _taskUri(task_uri), _resultsUri(res_uri) +{ +} + +ZmqWorker::~ZmqWorker() +{ + delete _taskQueue; + delete _results; + delete _inproc; +} + +void ZmqWorker::HandleOpen() +{ + _taskQueue = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull); + _results = sIpcContext->CreateNewSocket(zmqpp::socket_type::push); + + _taskQueue->connect(_taskUri); + _results->connect(_resultsUri); + + _poller->add(*_taskQueue); +} + +void ZmqWorker::HandleClose() +{ + _taskQueue->close(); + _results->close(); +} + +void ZmqWorker::Run() +{ + while (!ProcessExit()) + { + _poller->poll(); + if (_poller->events(*_taskQueue) & zmqpp::poller::poll_in) + PerformWork(); + } +} + +void ZmqWorker::PerformWork() +{ + int32 op1; + do + { + zmqpp::message msg; + _taskQueue->receive(msg); + Dispatch(msg); + _taskQueue->get(zmqpp::socket_option::events, op1); + } while (op1 & zmqpp::poller::poll_in); +} diff --git a/src/server/ipc/ZmqWorker.h b/src/server/ipc/ZmqWorker.h new file mode 100644 index 00000000000..b3e221e9129 --- /dev/null +++ b/src/server/ipc/ZmqWorker.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef __ZMQWORKER_H +#define __ZMQWORKER_H + +#include "ZMQTask.h" +#include + +class ZmqWorker : public ZMQTask +{ +public: + ZmqWorker(std::string task_uri, std::string res_uri); + ~ZmqWorker(); + void Run() override; + +protected: + void HandleOpen() override; + void HandleClose() override; + zmqpp::socket* _results; + +private: + void PerformWork(); + virtual void Dispatch(zmqpp::message const&) = 0; + zmqpp::socket* _taskQueue; + std::string _taskUri; + std::string _resultsUri; +}; + +#endif diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index e92c883eeff..eab6a36d02e 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -64,6 +64,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/collision/Models diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 27ec4835ce6..4c5b68516ca 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -163,7 +163,7 @@ public: ///- Get the accounts with GM Level >0 PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_GM_ACCOUNTS); stmt->setUInt8(0, uint8(SEC_MODERATOR)); - stmt->setInt32(1, int32(realmID)); + stmt->setInt32(1, int32(realmHandle.Index)); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 386be81c198..6fa3c6512b7 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1542,7 +1542,7 @@ public: // Query the prepared statement for login data stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); - stmt->setInt32(0, int32(realmID)); + stmt->setInt32(0, int32(realmHandle.Index)); stmt->setUInt32(1, accId); PreparedQueryResult result = LoginDatabase.Query(stmt); diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp index 95ef5ab6984..ab960026d69 100644 --- a/src/server/scripts/Commands/cs_rbac.cpp +++ b/src/server/scripts/Commands/cs_rbac.cpp @@ -160,7 +160,7 @@ public: if (!rdata) { - data->rbac = new rbac::RBACData(accountId, accountName, realmID, AccountMgr::GetSecurity(accountId, realmID)); + data->rbac = new rbac::RBACData(accountId, accountName, realmHandle.Index, AccountMgr::GetSecurity(accountId, realmHandle.Index)); data->rbac->LoadFromDB(); data->needDelete = true; } diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index 674658f41ff..f2aa046676f 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -98,7 +98,7 @@ public: ObjectGuid targetGuid = sObjectMgr->GetPlayerGUIDByName(target); uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); // Target must exist and have administrative rights - if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmID)) + if (!AccountMgr::HasPermission(accountId, rbac::RBAC_PERM_COMMANDS_BE_ASSIGNED_TICKET, realmHandle.Index)) { handler->SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A); return true; @@ -122,7 +122,7 @@ public: // Assign ticket SQLTransaction trans = SQLTransaction(NULL); - ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmID))); + ticket->SetAssignedTo(targetGuid, AccountMgr::IsAdminAccount(AccountMgr::GetSecurity(accountId, realmHandle.Index))); ticket->SaveToDB(trans); sTicketMgr->UpdateLastChange(); @@ -378,7 +378,7 @@ public: { ObjectGuid guid = ticket->GetAssignedToGUID(); uint32 accountId = sObjectMgr->GetPlayerAccountIdByGUID(guid); - security = AccountMgr::GetSecurity(accountId, realmID); + security = AccountMgr::GetSecurity(accountId, realmHandle.Index); } // Check security diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index 0cdf5f13f79..65972e680ef 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -47,6 +47,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/gsoap ${CMAKE_SOURCE_DIR}/dep/sockets/include ${CMAKE_SOURCE_DIR}/dep/SFMT + ${CMAKE_SOURCE_DIR}/dep/zmqpp ${CMAKE_SOURCE_DIR}/src/server/collision ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/collision/Models @@ -64,6 +65,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities + ${CMAKE_SOURCE_DIR}/src/server/ipc ${CMAKE_SOURCE_DIR}/src/server/game ${CMAKE_SOURCE_DIR}/src/server/game/Accounts ${CMAKE_SOURCE_DIR}/src/server/game/Achievements @@ -141,6 +143,7 @@ include_directories( ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${VALGRIND_INCLUDE_DIR} + ${ZMQ_INCLUDE_DIR} ) add_executable(worldserver @@ -164,18 +167,21 @@ set_target_properties(worldserver PROPERTIES LINK_FLAGS "${worldserver_LINK_FLAG target_link_libraries(worldserver game + ipc shared scripts collision g3dlib gsoap Detour + zmqpp ${JEMALLOC_LIBRARY} ${READLINE_LIBRARY} ${TERMCAP_LIBRARY} ${MYSQL_LIBRARY} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} + ${ZMQ_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ) diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 6c93343b8de..c5127b8f3e2 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -20,13 +20,9 @@ /// @{ /// \file -#include -#include -#include -#include -#include - #include "Common.h" +#include "Commands.h" +#include "ZmqContext.h" #include "DatabaseEnv.h" #include "AsyncAcceptor.h" #include "RASession.h" @@ -47,6 +43,12 @@ #include "SystemConfig.h" #include "WorldSocket.h" #include "WorldSocketMgr.h" +#include "BattlenetServerManager.h" +#include +#include +#include +#include +#include using namespace boost::program_options; @@ -79,7 +81,7 @@ uint32 _maxCoreStuckTimeInMs(0); WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the world database CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database -uint32 realmID; ///< Id of the realm +Battlenet::RealmHandle realmHandle; ///< Id of the realm void SignalHandler(const boost::system::error_code& error, int signalNumber); void FreezeDetectorHandler(const boost::system::error_code& error); @@ -188,7 +190,7 @@ extern int main(int argc, char** argv) } // Set server offline (not connectable) - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmHandle.Index); // Initialize the World sWorld->SetInitialWorldSettings(); @@ -223,7 +225,7 @@ extern int main(int argc, char** argv) sWorldSocketMgr.StartNetwork(_ioService, worldListener, worldPort); // Set server online (allow connecting now) - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmHandle.Index); // Start the freeze check callback cycle in 5 seconds (cycle itself is 1 sec) if (int coreStuckTime = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0)) @@ -234,6 +236,10 @@ extern int main(int argc, char** argv) TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", coreStuckTime); } + sIpcContext->Initialize(); + + sBattlenetServer.InitializeConnection(); + TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION); sScriptMgr->OnStartup(); @@ -245,6 +251,10 @@ extern int main(int argc, char** argv) sScriptMgr->OnShutdown(); + sIpcContext->Close(); + + sBattlenetServer.CloseConnection(); + sWorld->KickAll(); // save and kick all players sWorld->UpdateSessions(1); // real players unload required UpdateSessions call @@ -260,7 +270,7 @@ extern int main(int argc, char** argv) sOutdoorPvPMgr->Die(); // set server offline - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmHandle.Index); // Clean up threads if any if (soapThread != nullptr) @@ -523,13 +533,24 @@ bool StartDB() } ///- Get the realm Id from the configuration file - realmID = sConfigMgr->GetIntDefault("RealmID", 0); - if (!realmID) + realmHandle.Index = sConfigMgr->GetIntDefault("RealmID", 0); + if (!realmHandle.Index) { TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file"); return false; } - TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realmID); + + QueryResult realmIdQuery = LoginDatabase.PQuery("SELECT `Region`,`Battlegroup` FROM `realmlist` WHERE `id`=%u", realmHandle.Index); + if (!realmIdQuery) + { + TC_LOG_ERROR("server.worldserver", "Realm id %u not defined in realmlist table", realmHandle.Index); + return false; + } + + realmHandle.Region = (*realmIdQuery)[0].GetUInt8(); + realmHandle.Battlegroup = (*realmIdQuery)[1].GetUInt8(); + + TC_LOG_INFO("server.worldserver", "Realm running as realm ID %u region %u battlegroup %u", realmHandle.Index, uint32(realmHandle.Region), uint32(realmHandle.Battlegroup)); ///- Clean the database before starting ClearOnlineAccounts(); @@ -556,7 +577,7 @@ void StopDB() void ClearOnlineAccounts() { // Reset online status for all accounts with characters on the current realm - LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID); + LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmHandle.Index); // Reset online status for all characters CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0"); diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 6c3972de421..57d97756d70 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -3324,3 +3324,24 @@ PacketSpoof.BanDuration = 86400 # ################################################################################################### + +################################################################################################### +# IPC SETTINGS +# +# BnetServer.Address +# Description: Determines IP address of battle.net server to connect to. +# Default: 127.0.0.1 +# + +BnetServer.Address = 127.0.0.1 + +# +# BnetServer.Port +# Description: Determines port to use when connecting to battle.net server. +# Default: 1118 +# + +BnetServer.Port = 1118 + +# +################################################################################################### -- cgit v1.2.3 From a147770702179273ddd26983d649fa8a54ed6f85 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Fri, 17 Oct 2014 22:59:53 +0200 Subject: Core/Player: Additional fixes related to https://github.com/TrinityCore/TrinityCore/commit/ee5eaab598e445e3926edf6e12b1b2b4477c2594 Fix whispers to players on loading screen and few other cases. --- src/server/game/Chat/Channels/Channel.cpp | 10 +++++----- src/server/game/Globals/ObjectAccessor.cpp | 18 ++++++++++++++++++ src/server/game/Globals/ObjectAccessor.h | 1 + src/server/game/Handlers/CalendarHandler.cpp | 2 +- src/server/game/Handlers/ChatHandler.cpp | 2 +- src/server/game/Handlers/GroupHandler.cpp | 2 +- src/server/game/Handlers/MiscHandler.cpp | 2 +- src/server/game/World/World.cpp | 4 ++-- 8 files changed, 30 insertions(+), 11 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index cc2d3279daa..40605444ec0 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -296,7 +296,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b return; } - Player* bad = sObjectAccessor->FindPlayerByName(badname); + Player* bad = sObjectAccessor->FindConnectedPlayerByName(badname); ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty; if (!victim || !IsOn(victim)) { @@ -366,7 +366,7 @@ void Channel::UnBan(Player const* player, std::string const& badname) return; } - Player* bad = sObjectAccessor->FindPlayerByName(badname); + Player* bad = sObjectAccessor->FindConnectedPlayerByName(badname); ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty; if (!victim || !IsBanned(victim)) @@ -439,7 +439,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo if (guid == _ownerGUID && std::string(p2n) == player->GetName() && mod) return; - Player* newp = sObjectAccessor->FindPlayerByName(p2n); + Player* newp = sObjectAccessor->FindConnectedPlayerByName(p2n); ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty; if (!victim || !IsOn(victim) || @@ -487,7 +487,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname) return; } - Player* newp = sObjectAccessor->FindPlayerByName(newname); + Player* newp = sObjectAccessor->FindConnectedPlayerByName(newname); ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty; if (!victim || !IsOn(victim) || @@ -641,7 +641,7 @@ void Channel::Invite(Player const* player, std::string const& newname) return; } - Player* newp = sObjectAccessor->FindPlayerByName(newname); + Player* newp = sObjectAccessor->FindConnectedPlayerByName(newname); if (!newp || !newp->isGMVisible()) { WorldPacket data; diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 105ffc0be94..1323e232e80 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -233,6 +233,24 @@ Player* ObjectAccessor::FindPlayerByName(std::string const& name) return NULL; } +Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name) +{ + boost::shared_lock lock(*HashMapHolder::GetLock()); + + std::string nameStr = name; + std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower); + HashMapHolder::MapType const& m = GetPlayers(); + for (HashMapHolder::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter) + { + std::string currentName = iter->second->GetName(); + std::transform(currentName.begin(), currentName.end(), currentName.begin(), ::tolower); + if (nameStr.compare(currentName) == 0) + return iter->second; + } + + return NULL; +} + void ObjectAccessor::SaveAllPlayers() { boost::shared_lock lock(*HashMapHolder::GetLock()); diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index b0e3eb58529..d8beb22690a 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -171,6 +171,7 @@ class ObjectAccessor // this returns Player even if he is not in world, for example teleporting static Player* FindConnectedPlayer(ObjectGuid); + static Player* FindConnectedPlayerByName(std::string const& name); // when using this, you must use the hashmapholder's lock static HashMapHolder::MapType const& GetPlayers() diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 6d0caf9c072..5db9cbab9ce 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -432,7 +432,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent; - if (Player* player = sObjectAccessor->FindPlayerByName(name.c_str())) + if (Player* player = sObjectAccessor->FindConnectedPlayerByName(name.c_str())) { // Invitee is online inviteeGuid = player->GetGUID(); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index c4539680b82..d5495f42480 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -268,7 +268,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) break; } - Player* receiver = sObjectAccessor->FindPlayerByName(to); + Player* receiver = sObjectAccessor->FindConnectedPlayerByName(to); if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 632f28da48f..c366c725c18 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -606,7 +606,7 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData) if (!group->HasFreeSlotSubGroup(groupNr)) return; - Player* movedPlayer = sObjectAccessor->FindPlayerByName(name); + Player* movedPlayer = sObjectAccessor->FindConnectedPlayerByName(name); ObjectGuid guid; if (movedPlayer) { diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index a9e69ff3f8d..f2aa334eb3a 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1280,7 +1280,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) return; } - Player* player = sObjectAccessor->FindPlayerByName(charname); + Player* player = sObjectAccessor->FindConnectedPlayerByName(charname); if (!player) { diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index fae613797e9..33c5042fc8d 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2459,7 +2459,7 @@ bool World::RemoveBanAccount(BanMode mode, std::string const& nameOrIP) /// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban BanReturn World::BanCharacter(std::string const& name, std::string const& duration, std::string const& reason, std::string const& author) { - Player* pBanned = sObjectAccessor->FindPlayerByName(name); + Player* pBanned = sObjectAccessor->FindConnectedPlayerByName(name); uint32 guid = 0; uint32 duration_secs = TimeStringToSecs(duration); @@ -2500,7 +2500,7 @@ BanReturn World::BanCharacter(std::string const& name, std::string const& durati /// Remove a ban from a character bool World::RemoveBanCharacter(std::string const& name) { - Player* pBanned = sObjectAccessor->FindPlayerByName(name); + Player* pBanned = sObjectAccessor->FindConnectedPlayerByName(name); uint32 guid = 0; /// Pick a player to ban if not online -- cgit v1.2.3 From 863eac9c1a94f202aa5d5008d0b595626ba18951 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 18 Oct 2014 00:01:00 +0200 Subject: Fixed nopch build --- src/server/bnetserver/Packets/CachePackets.cpp | 1 + src/server/bnetserver/Packets/CachePackets.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp index cd5aa05fed6..4679448cbc8 100644 --- a/src/server/bnetserver/Packets/CachePackets.cpp +++ b/src/server/bnetserver/Packets/CachePackets.cpp @@ -15,6 +15,7 @@ * with this program. If not, see . */ +#include "Session.h" #include "CachePackets.h" void Battlenet::Cache::GetStreamItemsRequest::Read() diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h index 4d9987a0f0e..a65ab2651c8 100644 --- a/src/server/bnetserver/Packets/CachePackets.h +++ b/src/server/bnetserver/Packets/CachePackets.h @@ -18,6 +18,7 @@ #ifndef CachePackets_h__ #define CachePackets_h__ +#include "ModuleManager.h" #include "PacketsBase.h" namespace Battlenet -- cgit v1.2.3 From 69a17346d477be337c288145ec9da8a019ed040e Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 18 Oct 2014 00:26:41 +0200 Subject: More build fixes, everyone loves pch --- src/server/bnetserver/Packets/CachePackets.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/server') diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp index 4679448cbc8..b4fa6c6499d 100644 --- a/src/server/bnetserver/Packets/CachePackets.cpp +++ b/src/server/bnetserver/Packets/CachePackets.cpp @@ -16,6 +16,7 @@ */ #include "Session.h" +#include "Util.h" #include "CachePackets.h" void Battlenet::Cache::GetStreamItemsRequest::Read() -- cgit v1.2.3 From 89fae5d172f2ae2776b27a2ac3bf8a8d22082ed9 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 18 Oct 2014 00:37:24 +0200 Subject: Core: Fix merge fail --- src/server/game/DungeonFinding/LFGMgr.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/server') diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index b4e15116e70..3946d7b543f 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -1796,12 +1796,6 @@ void LFGMgr::SendLfgUpdateStatus(ObjectGuid guid, LfgUpdateData const& data, boo player->GetSession()->SendLfgUpdateStatus(data, party); } -void LFGMgr::SendLfgUpdateParty(ObjectGuid guid, LfgUpdateData const& data) -{ - if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) - player->GetSession()->SendLfgUpdateParty(data); -} - void LFGMgr::SendLfgJoinResult(ObjectGuid guid, LfgJoinResultData const& data) { if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) -- cgit v1.2.3 From 4940f8c37ea96584cb2de640d0ac894f0bef3fe6 Mon Sep 17 00:00:00 2001 From: ShinDarth Date: Sat, 18 Oct 2014 11:27:36 +0200 Subject: Core/LootMgr: restore build --- src/server/game/Loot/LootMgr.cpp | 7 ++++++- src/server/game/Loot/LootMgr.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/server') diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index e0bf80b98b9..35b62bd24c3 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -272,6 +272,11 @@ void LootStore::ReportUnusedIds(LootIdSet const& lootIdSet) const TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d isn't %s and not referenced from loot, and thus useless.", GetName(), *itr, GetEntryName()); } +void LootStore::ReportNonExistingId(uint32 lootId) const +{ + TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist", GetName(), lootId); +} + void LootStore::ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const { TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist but it is used by %s %d", GetName(), lootId, ownerType, ownerId); @@ -1565,7 +1570,7 @@ void LoadLootTemplates_Disenchant() uint32 lootid = disenchant->Id; if (lootIdSet.find(lootid) == lootIdSet.end()) - LootTemplates_Disenchant.ReportNonExistingId(lootid, "Item", itr->second.ItemId); + LootTemplates_Disenchant.ReportNonExistingId(lootid); else lootIdSetUsed.insert(lootid); } diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 7d8309f43a6..52632393ca1 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -216,6 +216,7 @@ class LootStore uint32 LoadAndCollectLootIds(LootIdSet& ids_set); void CheckLootRefs(LootIdSet* ref_set = NULL) const; // check existence reference and remove it from ref_set void ReportUnusedIds(LootIdSet const& ids_set) const; + void ReportNonExistingId(uint32 lootId) const; void ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const; bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); } -- cgit v1.2.3 From 0de1603944fe96253e02a1564881c80fe6519ebb Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sat, 18 Oct 2014 15:13:29 +0200 Subject: Core/ObjectAccessor: don't use singleton when calling static methods --- .../game/Battlefield/Zones/BattlefieldWG.cpp | 28 +++++++++++----------- src/server/game/Battlegrounds/ArenaTeamMgr.cpp | 2 +- src/server/game/Chat/Channels/Channel.cpp | 10 ++++---- src/server/game/Chat/Chat.cpp | 6 ++--- src/server/game/Guilds/Guild.cpp | 2 +- src/server/game/Handlers/ArenaTeamHandler.cpp | 2 +- src/server/game/Handlers/CalendarHandler.cpp | 2 +- src/server/game/Handlers/ChatHandler.cpp | 2 +- src/server/game/Handlers/GroupHandler.cpp | 6 ++--- src/server/game/Handlers/MiscHandler.cpp | 4 ++-- src/server/game/World/World.cpp | 4 ++-- src/server/scripts/Commands/cs_ban.cpp | 2 +- src/server/scripts/Commands/cs_character.cpp | 2 +- src/server/scripts/Commands/cs_gm.cpp | 2 +- src/server/scripts/Commands/cs_message.cpp | 2 +- src/server/scripts/Commands/cs_misc.cpp | 8 +++---- src/server/scripts/Commands/cs_reset.cpp | 2 +- src/server/scripts/Commands/cs_ticket.cpp | 2 +- 18 files changed, 44 insertions(+), 44 deletions(-) (limited to 'src/server') diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 4c5994f6b3a..326adb66c72 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -253,7 +253,7 @@ void BattlefieldWG::OnBattleStart() for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) { // Kick player in orb room, TODO: offline player ? - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) { float x, y, z; player->GetPosition(x, y, z); @@ -356,7 +356,7 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer) for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr) { - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) { player->CastSpell(player, SPELL_ESSENCE_OF_WINTERGRASP, true); player->CastSpell(player, SPELL_VICTORY_REWARD, true); @@ -369,13 +369,13 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer) } for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->CastSpell(player, SPELL_DEFEAT_REWARD, true); for (uint8 team = 0; team < 2; ++team) { for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) RemoveAurasFromPlayer(player); m_PlayersInWar[team].clear(); @@ -394,7 +394,7 @@ void BattlefieldWG::OnBattleEnd(bool endByTimer) { for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) { - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) { player->RemoveAurasDueToSpell(m_DefenderTeam == TEAM_ALLIANCE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player->GetGUID()); player->AddAura(m_DefenderTeam == TEAM_HORDE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player); @@ -620,7 +620,7 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim) if (victim->GetTypeId() == TYPEID_PLAYER) { for (GuidSet::const_iterator itr = m_PlayersInWar[killerTeam].begin(); itr != m_PlayersInWar[killerTeam].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) if (player->GetDistance2d(killer) < 40) PromotePlayer(player); return; @@ -635,7 +635,7 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim) { again = true; for (GuidSet::const_iterator iter = m_PlayersInWar[killerTeam].begin(); iter != m_PlayersInWar[killerTeam].end(); ++iter) - if (Player* player = sObjectAccessor->FindPlayer(*iter)) + if (Player* player = ObjectAccessor::FindPlayer(*iter)) if (player->GetDistance2d(killer) < 40.0f) PromotePlayer(player); } @@ -847,7 +847,7 @@ void BattlefieldWG::SendInitWorldStatesToAll() { for (uint8 team = 0; team < 2; team++) for (GuidSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) SendInitWorldStatesTo(player); } @@ -858,7 +858,7 @@ void BattlefieldWG::BrokenWallOrTower(TeamId /*team*/) { for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr) { - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) IncrementQuest(player, WGQuest[player->GetTeamId()][2], true); } }*/ @@ -876,12 +876,12 @@ void BattlefieldWG::UpdatedDestroyedTowerCount(TeamId team) // Remove buff stack on attackers for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->RemoveAuraFromStack(SPELL_TOWER_CONTROL); // Add buff stack to defenders for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) { player->CastSpell(player, SPELL_TOWER_CONTROL, true); DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WG_TOWER_DESTROY, player); @@ -986,7 +986,7 @@ void BattlefieldWG::UpdateTenacity() if (team != TEAM_NEUTRAL) { for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) if (player->getLevel() >= m_MinLevel) player->RemoveAurasDueToSpell(SPELL_TENACITY); @@ -1014,7 +1014,7 @@ void BattlefieldWG::UpdateTenacity() buff_honor = 0; for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->SetAuraStack(SPELL_TENACITY, player, newStack); for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) @@ -1024,7 +1024,7 @@ void BattlefieldWG::UpdateTenacity() if (buff_honor != 0) { for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - if (Player* player = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = ObjectAccessor::FindPlayer(*itr)) player->CastSpell(player, buff_honor, true); for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) if (Creature* creature = GetCreature(*itr)) diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index 3bfd27c69b5..c3f29e2141b 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -158,7 +158,7 @@ void ArenaTeamMgr::DistributeArenaPoints() for (std::map::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr) { // Add points to player if online - if (Player* player = HashMapHolder::Find(ObjectGuid(HIGHGUID_PLAYER, playerItr->first))) + if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, playerItr->first))) player->ModifyArenaPoints(playerItr->second, trans); else // Update database { diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 40605444ec0..6d984ab2e66 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -296,7 +296,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b return; } - Player* bad = sObjectAccessor->FindConnectedPlayerByName(badname); + Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname); ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty; if (!victim || !IsOn(victim)) { @@ -366,7 +366,7 @@ void Channel::UnBan(Player const* player, std::string const& badname) return; } - Player* bad = sObjectAccessor->FindConnectedPlayerByName(badname); + Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname); ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty; if (!victim || !IsBanned(victim)) @@ -439,7 +439,7 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo if (guid == _ownerGUID && std::string(p2n) == player->GetName() && mod) return; - Player* newp = sObjectAccessor->FindConnectedPlayerByName(p2n); + Player* newp = ObjectAccessor::FindConnectedPlayerByName(p2n); ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty; if (!victim || !IsOn(victim) || @@ -487,7 +487,7 @@ void Channel::SetOwner(Player const* player, std::string const& newname) return; } - Player* newp = sObjectAccessor->FindConnectedPlayerByName(newname); + Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname); ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty; if (!victim || !IsOn(victim) || @@ -641,7 +641,7 @@ void Channel::Invite(Player const* player, std::string const& newname) return; } - Player* newp = sObjectAccessor->FindConnectedPlayerByName(newname); + Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname); if (!newp || !newp->isGMVisible()) { WorldPacket data; diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 30405128ab8..6f614994489 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -1072,7 +1072,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text) if (!normalizePlayerName(name)) return ObjectGuid::Empty; - if (Player* player = sObjectAccessor->FindPlayerByName(name)) + if (Player* player = ObjectAccessor::FindPlayerByName(name)) return player->GetGUID(); if (ObjectGuid guid = sObjectMgr->GetPlayerGUIDByName(name)) @@ -1130,7 +1130,7 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, ObjectGuid* p return false; } - Player* pl = sObjectAccessor->FindPlayerByName(name); + Player* pl = ObjectAccessor::FindPlayerByName(name); // if allowed player pointer if (player) @@ -1294,7 +1294,7 @@ bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player*& player return false; } - player = sObjectAccessor->FindPlayerByName(name); + player = ObjectAccessor::FindPlayerByName(name); if (offline) guid = sObjectMgr->GetPlayerGUIDByName(name.c_str()); } diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index c655be6291f..5180c9f497b 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -1513,7 +1513,7 @@ void Guild::HandleBuyBankTab(WorldSession* session, uint8 tabId) void Guild::HandleInviteMember(WorldSession* session, std::string const& name) { - Player* pInvitee = sObjectAccessor->FindPlayerByName(name); + Player* pInvitee = ObjectAccessor::FindPlayerByName(name); if (!pInvitee) { SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_PLAYER_NOT_FOUND_S, name); diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index b77a3fd41cc..fab095a2ad6 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -99,7 +99,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData) if (!normalizePlayerName(invitedName)) return; - player = sObjectAccessor->FindPlayerByName(invitedName); + player = ObjectAccessor::FindPlayerByName(invitedName); } if (!player) diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 5db9cbab9ce..916bebc144a 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -432,7 +432,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent; - if (Player* player = sObjectAccessor->FindConnectedPlayerByName(name.c_str())) + if (Player* player = ObjectAccessor::FindConnectedPlayerByName(name)) { // Invitee is online inviteeGuid = player->GetGUID(); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index d5495f42480..288bb827729 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -268,7 +268,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) break; } - Player* receiver = sObjectAccessor->FindConnectedPlayerByName(to); + Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to); if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index c366c725c18..f42919486a5 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -74,7 +74,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) return; } - Player* player = sObjectAccessor->FindPlayerByName(membername); + Player* player = ObjectAccessor::FindPlayerByName(membername); // no player if (!player) @@ -606,7 +606,7 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData) if (!group->HasFreeSlotSubGroup(groupNr)) return; - Player* movedPlayer = sObjectAccessor->FindConnectedPlayerByName(name); + Player* movedPlayer = ObjectAccessor::FindConnectedPlayerByName(name); ObjectGuid guid; if (movedPlayer) { @@ -913,7 +913,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) ObjectGuid Guid; recvData >> Guid; - Player* player = HashMapHolder::Find(Guid); + Player* player = ObjectAccessor::FindConnectedPlayer(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index f2aa334eb3a..c36523602f8 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -257,7 +257,7 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recvData) boost::shared_lock lock(*HashMapHolder::GetLock()); - HashMapHolder::MapType const& m = sObjectAccessor->GetPlayers(); + HashMapHolder::MapType const& m = ObjectAccessor::GetPlayers(); for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { Player* target = itr->second; @@ -1280,7 +1280,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recvData) return; } - Player* player = sObjectAccessor->FindConnectedPlayerByName(charname); + Player* player = ObjectAccessor::FindConnectedPlayerByName(charname); if (!player) { diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 33c5042fc8d..bb922fce6b1 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2459,7 +2459,7 @@ bool World::RemoveBanAccount(BanMode mode, std::string const& nameOrIP) /// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban BanReturn World::BanCharacter(std::string const& name, std::string const& duration, std::string const& reason, std::string const& author) { - Player* pBanned = sObjectAccessor->FindConnectedPlayerByName(name); + Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name); uint32 guid = 0; uint32 duration_secs = TimeStringToSecs(duration); @@ -2500,7 +2500,7 @@ BanReturn World::BanCharacter(std::string const& name, std::string const& durati /// Remove a ban from a character bool World::RemoveBanCharacter(std::string const& name) { - Player* pBanned = sObjectAccessor->FindConnectedPlayerByName(name); + Player* pBanned = ObjectAccessor::FindConnectedPlayerByName(name); uint32 guid = 0; /// Pick a player to ban if not online diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp index 2ffd5e3b605..0ad812e66ed 100644 --- a/src/server/scripts/Commands/cs_ban.cpp +++ b/src/server/scripts/Commands/cs_ban.cpp @@ -299,7 +299,7 @@ public: if (!*args) return false; - Player* target = sObjectAccessor->FindPlayerByName(args); + Player* target = ObjectAccessor::FindPlayerByName(args); uint32 targetGuid = 0; std::string name(args); diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp index c6769493020..2a38f95b01a 100644 --- a/src/server/scripts/Commands/cs_character.cpp +++ b/src/server/scripts/Commands/cs_character.cpp @@ -776,7 +776,7 @@ public: ObjectGuid characterGuid; uint32 accountId; - Player* player = sObjectAccessor->FindPlayerByName(characterName); + Player* player = ObjectAccessor::FindPlayerByName(characterName); if (player) { characterGuid = player->GetGUID(); diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 29f8c904f97..ee2bb897437 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -124,7 +124,7 @@ public: bool footer = false; boost::shared_lock lock(*HashMapHolder::GetLock()); - HashMapHolder::MapType const& m = sObjectAccessor->GetPlayers(); + HashMapHolder::MapType const& m = ObjectAccessor::GetPlayers(); for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { AccountTypes itrSec = itr->second->GetSession()->GetSecurity(); diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp index f2067e6c70b..715487eff99 100644 --- a/src/server/scripts/Commands/cs_message.cpp +++ b/src/server/scripts/Commands/cs_message.cpp @@ -211,7 +211,7 @@ public: std::string name = strtok(NULL, " "); if (normalizePlayerName(name)) { - if (Player* player = sObjectAccessor->FindPlayerByName(name)) + if (Player* player = ObjectAccessor::FindPlayerByName(name)) { handler->GetSession()->GetPlayer()->RemoveFromWhisperWhiteList(player->GetGUID()); handler->PSendSysMessage(LANG_COMMAND_WHISPEROFFPLAYER, name.c_str()); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index a7716d3230b..ccfb32a2e09 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -2193,7 +2193,7 @@ public: if (args && args[0] != '\0') { - target = sObjectAccessor->FindPlayerByName(args); + target = ObjectAccessor::FindPlayerByName(args); if (!target) { handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -2287,7 +2287,7 @@ public: // find the player std::string name = arg1; normalizePlayerName(name); - player = sObjectAccessor->FindPlayerByName(name); + player = ObjectAccessor::FindPlayerByName(name); // Check if we have duration set if (arg2 && isNumeric(arg2)) { @@ -2351,7 +2351,7 @@ public: { name = targetName; normalizePlayerName(name); - player = sObjectAccessor->FindPlayerByName(name); + player = ObjectAccessor::FindPlayerByName(name); } else // If no name was entered - use target { @@ -2427,7 +2427,7 @@ public: int32 remaintime = fields[1].GetInt32(); // Save the frozen player to update remaining time in case of future .listfreeze uses // before the frozen state expires - if (Player* frozen = sObjectAccessor->FindPlayerByName(player)) + if (Player* frozen = ObjectAccessor::FindPlayerByName(player)) frozen->SaveToDB(); // Notify the freeze duration if (remaintime == -1) // Permanent duration diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp index 484d41a47d9..d0262704c82 100644 --- a/src/server/scripts/Commands/cs_reset.cpp +++ b/src/server/scripts/Commands/cs_reset.cpp @@ -298,7 +298,7 @@ public: CharacterDatabase.Execute(stmt); boost::shared_lock lock(*HashMapHolder::GetLock()); - HashMapHolder::MapType const& plist = sObjectAccessor->GetPlayers(); + HashMapHolder::MapType const& plist = ObjectAccessor::GetPlayers(); for (HashMapHolder::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) itr->second->SetAtLoginFlag(atLogin); diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp index 23858ce67e6..facc760a193 100644 --- a/src/server/scripts/Commands/cs_ticket.cpp +++ b/src/server/scripts/Commands/cs_ticket.cpp @@ -427,7 +427,7 @@ public: // Detect target's GUID ObjectGuid guid; - if (Player* player = sObjectAccessor->FindPlayerByName(name)) + if (Player* player = ObjectAccessor::FindPlayerByName(name)) guid = player->GetGUID(); else guid = sObjectMgr->GetPlayerGUIDByName(name); -- cgit v1.2.3