From b87372ff1aea3e849d10d2a33072f16bcae4b86d Mon Sep 17 00:00:00 2001 From: Beats <61994374+beats-dh@users.noreply.github.com> Date: Sat, 23 Apr 2022 22:48:36 -0300 Subject: [PATCH] [Enhancement] Decouple all global variables from extern in true singleton (#325) All the global variables * g_* were decoupled to true singletons, reducing the dependencies between the objects and simplifying the amount of calls and instances. They used to be partial singletons mixed with global variables, that way we have one, and only one instance that is accessed via the getInstance methods, that are now the * g_* functions. Changes: g_actions g_chat g_config g_creatureEvents g_database g_databaseTasks g_decay g_dispatcher g_events g_game g_globalEvents g_luaEnvironment g_modules g_monsters g_moveEvents g_npc g_npcs g_RSA g_scheduler g_scripts g_spells g_talkActions g_vocations g_weapons The * g_luaEnvironment has been decoupled using inline, new feature of c++17 --- src/creatures/combat/combat.cpp | 17 +- src/creatures/combat/condition.cpp | 5 +- src/creatures/combat/spells.cpp | 10 +- src/creatures/combat/spells.h | 9 + src/creatures/creature.cpp | 19 +- src/creatures/interactions/chat.cpp | 11 +- src/creatures/interactions/chat.h | 9 + src/creatures/monsters/monster.cpp | 8 +- src/creatures/monsters/monsters.cpp | 14 +- src/creatures/monsters/monsters.h | 9 + .../monsters/spawns/spawn_monster.cpp | 14 +- src/creatures/npcs/npc.cpp | 6 +- src/creatures/npcs/npcs.cpp | 2 - src/creatures/npcs/npcs.h | 9 + src/creatures/npcs/spawns/spawn_npc.cpp | 14 +- src/creatures/players/account/account.cpp | 6 +- src/creatures/players/grouping/party.cpp | 9 +- .../players/imbuements/imbuements.cpp | 1 - src/creatures/players/imbuements/imbuements.h | 15 + src/creatures/players/management/ban.cpp | 6 +- src/creatures/players/player.cpp | 118 ++++---- src/creatures/players/player.h | 2 +- src/creatures/players/vocations/vocation.cpp | 2 +- src/creatures/players/vocations/vocation.h | 26 +- src/database/databasetasks.cpp | 3 +- src/database/databasetasks.h | 14 +- src/game/game.cpp | 272 ++++++++---------- src/game/game.h | 2 +- src/game/scheduling/scheduler.cpp | 2 +- src/game/scheduling/scheduler.h | 14 +- src/game/scheduling/tasks.h | 14 +- src/io/iobestiary.cpp | 9 +- src/io/iologindata.cpp | 3 +- src/io/iomarket.cpp | 6 +- src/items/bed.cpp | 2 +- src/items/containers/container.cpp | 12 +- src/items/containers/container.h | 2 +- src/items/cylinder.cpp | 2 +- src/items/cylinder.h | 2 +- src/items/decay/decay.cpp | 13 +- src/items/decay/decay.h | 16 +- src/items/item.cpp | 21 +- src/items/items.cpp | 3 +- src/items/tile.cpp | 13 +- src/items/tile.h | 2 +- src/items/weapons/weapons.cpp | 9 +- src/items/weapons/weapons.h | 12 +- src/lua/creature/actions.cpp | 8 +- src/lua/creature/actions.h | 9 + src/lua/creature/creatureevent.h | 9 + src/lua/creature/events.h | 14 + src/lua/creature/movement.cpp | 5 +- src/lua/creature/movement.h | 12 +- src/lua/creature/raids.cpp | 12 +- src/lua/creature/talkaction.h | 9 + .../functions/core/game/game_functions.cpp | 22 +- .../functions/core/game/game_functions.hpp | 3 - .../functions/core/game/global_functions.cpp | 14 +- src/lua/functions/core/libs/db_functions.cpp | 7 +- .../network/network_message_functions.hpp | 3 - .../creatures/combat/combat_functions.cpp | 3 - .../creatures/combat/spell_functions.cpp | 20 +- .../creatures/monster/loot_functions.cpp | 1 - .../creatures/monster/monster_functions.cpp | 5 +- .../monster/monster_type_functions.cpp | 12 +- .../creatures/npc/npc_type_functions.cpp | 6 +- .../creatures/player/player_functions.cpp | 22 +- .../creatures/player/vocation_functions.cpp | 15 +- src/lua/functions/events/action_functions.cpp | 3 +- .../events/creature_event_functions.cpp | 3 +- .../events/global_event_functions.cpp | 6 +- .../functions/events/move_event_functions.cpp | 5 +- .../events/talk_action_functions.cpp | 3 +- .../functions/items/imbuement_functions.cpp | 13 +- src/lua/functions/items/item_functions.cpp | 6 +- src/lua/functions/items/weapon_functions.cpp | 6 +- src/lua/functions/map/position_functions.hpp | 3 - src/lua/global/baseevents.cpp | 3 - src/lua/global/globalevent.cpp | 16 +- src/lua/global/globalevent.h | 9 + src/lua/modules/modules.h | 9 + src/lua/scripts/lua_environment.hpp | 2 + src/lua/scripts/luascript.cpp | 1 - src/lua/scripts/scripts.cpp | 71 ----- src/lua/scripts/scripts.h | 5 +- src/otserv.cpp | 63 ++-- src/security/rsa.cpp | 6 +- src/security/rsa.h | 11 +- src/server/network/connection/connection.cpp | 4 +- src/server/network/message/outputmessage.cpp | 3 +- src/server/network/protocol/protocol.cpp | 3 +- src/server/network/protocol/protocolgame.cpp | 64 ++--- src/server/network/protocol/protocolgame.h | 2 +- src/server/network/protocol/protocollogin.cpp | 2 +- .../network/protocol/protocolstatus.cpp | 4 +- src/server/server.cpp | 4 +- src/server/signals.cpp | 34 +-- 97 files changed, 663 insertions(+), 701 deletions(-) diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index d4a05414420..f2ac309c059 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -28,9 +28,6 @@ #include "creatures/monsters/monsters.h" #include "items/weapons/weapons.h" -extern Weapons* g_weapons; -extern Events* g_events; -extern Monsters g_monsters; CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const { @@ -57,7 +54,7 @@ CombatDamage Combat::getCombatDamage(Creature* creature, Creature* target) const ); } else if (formulaType == COMBAT_FORMULA_SKILL) { Item* tool = player->getWeapon(); - const Weapon* weapon = g_weapons->getWeapon(tool); + const Weapon* weapon = g_weapons().getWeapon(tool); if (weapon) { damage.primary.value = normal_random( static_cast(minb), @@ -265,7 +262,7 @@ ReturnValue Combat::canDoCombat(Creature* caster, Tile* tile, bool aggressive) return RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE; } - return g_events->eventCreatureOnAreaCombat(caster, tile, aggressive); + return g_events().eventCreatureOnAreaCombat(caster, tile, aggressive); } bool Combat::isInPvpZone(const Creature* attacker, const Creature* target) @@ -381,7 +378,7 @@ ReturnValue Combat::canDoCombat(Creature* attacker, Creature* target) } } } - return g_events->eventCreatureOnTargetCombat(attacker, target); + return g_events().eventCreatureOnTargetCombat(attacker, target); } void Combat::setPlayerCombatValues(formulaType_t newFormulaType, double newMina, double newMinb, double newMaxa, double newMaxb) @@ -501,7 +498,7 @@ void Combat::CombatHealthFunc(Creature* caster, Creature* target, const CombatPa if (caster && caster->getPlayer()) { Item *item = caster->getPlayer()->getWeapon(); damage = applyImbuementElementalDamage(item, damage); - g_events->eventPlayerOnCombat(caster->getPlayer(), target, item, damage); + g_events().eventPlayerOnCombat(caster->getPlayer(), target, item, damage); if (target && target->getSkull() != SKULL_BLACK && target->getPlayer()) { damage.primary.value /= 2; @@ -578,7 +575,7 @@ void Combat::CombatConditionFunc(Creature* caster, Creature* target, const Comba } else if (caster && caster->getMonster()) { uint16_t playerCharmRaceid = player->parseRacebyCharm(CHARM_CLEANSE, false, 0); if (playerCharmRaceid != 0) { - MonsterType* mType = g_monsters.getMonsterType(caster->getName()); + const MonsterType* mType = g_monsters().getMonsterType(caster->getName()); if (mType && playerCharmRaceid == mType->info.raceid) { IOBestiary g_bestiary; Charm* charm = g_bestiary.getBestiaryCharm(CHARM_CLEANSE); @@ -903,7 +900,7 @@ void Combat::doCombatHealth(Creature* caster, Creature* target, CombatDamage& da if (target && target->getMonster() && damage.primary.type != COMBAT_HEALING) { uint16_t playerCharmRaceid = caster->getPlayer()->parseRacebyCharm(CHARM_LOW, false, 0); if (playerCharmRaceid != 0) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + const MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType && playerCharmRaceid == mType->info.raceid) { IOBestiary g_bestiary; Charm* charm = g_bestiary.getBestiaryCharm(CHARM_LOW); @@ -1106,7 +1103,7 @@ void ValueCallback::getMinMaxValues(Player* player, CombatDamage& damage, bool u case COMBAT_FORMULA_SKILL: { //onGetPlayerMinMaxValues(player, attackSkill, attackValue, attackFactor) Item* tool = player->getWeapon(); - const Weapon* weapon = g_weapons->getWeapon(tool); + const Weapon* weapon = g_weapons().getWeapon(tool); Item* item = nullptr; if (weapon) { diff --git a/src/creatures/combat/condition.cpp b/src/creatures/combat/condition.cpp index 67308329c9b..7daff812b55 100644 --- a/src/creatures/combat/condition.cpp +++ b/src/creatures/combat/condition.cpp @@ -22,7 +22,6 @@ #include "creatures/combat/condition.h" #include "game/game.h" -extern Monsters g_monsters; bool Condition::setParam(ConditionParam_t param, int32_t value) { @@ -1655,7 +1654,7 @@ void ConditionOutfit::serialize(PropWriteStream& propWriteStream) bool ConditionOutfit::startCondition(Creature* creature) { if ((outfit.lookType == 0 && outfit.lookTypeEx == 0) && !monsterName.empty()) { - MonsterType* monsterType = g_monsters.getMonsterType(monsterName); + const MonsterType* monsterType = g_monsters().getMonsterType(monsterName); if (monsterType) { setOutfit(monsterType->info.outfit); } else { @@ -1689,7 +1688,7 @@ void ConditionOutfit::addCondition(Creature* creature, const Condition* addCondi const ConditionOutfit& conditionOutfit = static_cast(*addCondition); if (!conditionOutfit.monsterName.empty() && conditionOutfit.monsterName.compare(monsterName) != 0) { - MonsterType* monsterType = g_monsters.getMonsterType(conditionOutfit.monsterName); + const MonsterType* monsterType = g_monsters().getMonsterType(conditionOutfit.monsterName); if (monsterType) { setOutfit(monsterType->info.outfit); } else { diff --git a/src/creatures/combat/spells.cpp b/src/creatures/combat/spells.cpp index ecdff128d6e..b76f6289e9e 100644 --- a/src/creatures/combat/spells.cpp +++ b/src/creatures/combat/spells.cpp @@ -25,12 +25,6 @@ #include "game/game.h" #include "lua/scripts/lua_environment.hpp" #include "utils/pugicast.h" - -extern Spells* g_spells; -extern Monsters g_monsters; -extern Vocations g_vocations; -extern LuaEnvironment g_luaEnvironment; - Spells::Spells() { scriptInterface.initState(); @@ -333,7 +327,7 @@ Position Spells::getCasterPosition(Creature* creature, Direction dir) } CombatSpell::CombatSpell(Combat* initCombat, bool initNeedTarget, bool initNeedDirection) : - Event(&g_spells->getScriptInterface()), + Event(&g_spells().getScriptInterface()), combat(initCombat), needDirection(initNeedDirection), needTarget(initNeedTarget) @@ -611,7 +605,7 @@ bool Spell::configureSpell(const pugi::xml_node& node) continue; } - int32_t vocationId = g_vocations.getVocationId(attr.as_string()); + int32_t vocationId = g_vocations().getVocationId(attr.as_string()); if (vocationId != -1) { attr = vocationNode.attribute("showInDescription"); vocSpellMap[vocationId] = !attr || attr.as_bool(); diff --git a/src/creatures/combat/spells.h b/src/creatures/combat/spells.h index dc981befe22..7b7798afae0 100644 --- a/src/creatures/combat/spells.h +++ b/src/creatures/combat/spells.h @@ -44,6 +44,13 @@ class Spells final : public BaseEvents Spells(const Spells&) = delete; Spells& operator=(const Spells&) = delete; + static Spells& getInstance() { + // Guaranteed to be destroyed + static Spells instance; + // Instantiated on first use + return instance; + } + Spell* getSpellByName(const std::string& name); RuneSpell* getRuneSpell(uint32_t id); RuneSpell* getRuneSpellByName(const std::string& name); @@ -88,6 +95,8 @@ class Spells final : public BaseEvents LuaScriptInterface scriptInterface { "Spell Interface" }; }; +constexpr auto g_spells = &Spells::getInstance; + using RuneSpellFunction = std::function; class BaseSpell diff --git a/src/creatures/creature.cpp b/src/creatures/creature.cpp index 52185e5bf37..4dc3b9111e5 100644 --- a/src/creatures/creature.cpp +++ b/src/creatures/creature.cpp @@ -29,7 +29,6 @@ double Creature::speedA = 857.36; double Creature::speedB = 261.29; double Creature::speedC = -4795.01; -extern CreatureEvents* g_creatureEvents; Creature::Creature() { @@ -282,13 +281,13 @@ void Creature::addEventWalk(bool firstStep) g_game().checkCreatureWalk(getID()); } - eventWalk = g_scheduler.addEvent(createSchedulerTask(static_cast(ticks), std::bind(&Game::checkCreatureWalk, &g_game(), getID()))); + eventWalk = g_scheduler().addEvent(createSchedulerTask(static_cast(ticks), std::bind(&Game::checkCreatureWalk, &g_game(), getID()))); } void Creature::stopEventWalk() { if (eventWalk != 0) { - g_scheduler.stopEvent(eventWalk); + g_scheduler().stopEvent(eventWalk); eventWalk = 0; } } @@ -606,7 +605,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos if (followCreature && (creature == this || creature == followCreature)) { if (hasFollowPath) { isUpdatingPath = true; - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); } if (newPos.z != oldPos.z || !canSee(followCreature->getPosition())) { @@ -620,7 +619,7 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos } else { if (hasExtraSwing()) { //our target is moving lets see if we can get in hit - g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); } if (newTile->getZone() != oldTile->getZone()) { @@ -769,7 +768,7 @@ bool Creature::dropCorpse(Creature* lastHitCreature, Creature* mostDamageCreatur if (g_configManager().getBoolean(AUTOLOOT)) { int32_t pos = tile->getStackposOfItem(player, corpse); - g_dispatcher.addTask(createTask(std::bind(&Game::playerQuickLoot, &g_game(), mostDamageCreature->getID(), this->getPosition(), corpse->getClientID(), pos - 1, nullptr, false, true))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerQuickLoot, &g_game(), mostDamageCreature->getID(), this->getPosition(), corpse->getClientID(), pos - 1, nullptr, false, true))); } } } @@ -813,7 +812,7 @@ void Creature::changeHealth(int32_t healthChange, bool sendHealthChange/* = true g_game().addCreatureHealth(this); } if (health <= 0) { - g_dispatcher.addTask(createTask(std::bind(&Game::executeDeath, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::executeDeath, &g_game(), getID()))); } } @@ -1285,7 +1284,7 @@ void Creature::removeCondition(ConditionType_t conditionType, ConditionId_t cond if (!force && conditionType == CONDITION_PARALYZE) { int32_t walkDelay = getWalkDelay(); if (walkDelay > 0) { - g_scheduler.addEvent(createSchedulerTask(walkDelay, std::bind(&Game::forceRemoveCondition, &g_game(), getID(), conditionType, conditionId))); + g_scheduler().addEvent(createSchedulerTask(walkDelay, std::bind(&Game::forceRemoveCondition, &g_game(), getID(), conditionType, conditionId))); return; } } @@ -1468,7 +1467,7 @@ void Creature::setNormalCreatureLight() bool Creature::registerCreatureEvent(const std::string& name) { - CreatureEvent* event = g_creatureEvents->getEventByName(name); + CreatureEvent* event = g_creatureEvents().getEventByName(name); if (!event) { return false; } @@ -1490,7 +1489,7 @@ bool Creature::registerCreatureEvent(const std::string& name) bool Creature::unregisterCreatureEvent(const std::string& name) { - CreatureEvent* event = g_creatureEvents->getEventByName(name); + const CreatureEvent* event = g_creatureEvents().getEventByName(name); if (!event) { return false; } diff --git a/src/creatures/interactions/chat.cpp b/src/creatures/interactions/chat.cpp index c16c23cc93e..2af47734162 100644 --- a/src/creatures/interactions/chat.cpp +++ b/src/creatures/interactions/chat.cpp @@ -24,7 +24,6 @@ #include "utils/pugicast.h" #include "game/scheduling/scheduler.h" -extern Chat* g_chat; bool PrivateChatChannel::isInvited(uint32_t guid) const { @@ -99,7 +98,7 @@ bool ChatChannel::addUser(Player& player) if (id == CHANNEL_GUILD) { Guild* guild = player.getGuild(); if (guild && !guild->getMotd().empty()) { - g_scheduler.addEvent(createSchedulerTask(150, std::bind(&Game::sendGuildMotd, &g_game(), player.getID()))); + g_scheduler().addEvent(createSchedulerTask(150, std::bind(&Game::sendGuildMotd, &g_game(), player.getID()))); } } @@ -162,7 +161,7 @@ bool ChatChannel::executeCanJoinEvent(const Player& player) } //canJoin(player) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[CanJoinChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested.", @@ -189,7 +188,7 @@ bool ChatChannel::executeOnJoinEvent(const Player& player) } //onJoin(player) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[OnJoinChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested", @@ -216,7 +215,7 @@ bool ChatChannel::executeOnLeaveEvent(const Player& player) } //onLeave(player) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[OnLeaveChannelEvent::execute - Player {}, on channel {}] " "Call stack overflow. Too many lua script calls being nested.", @@ -243,7 +242,7 @@ bool ChatChannel::executeOnSpeakEvent(const Player& player, SpeakClasses& type, } //onSpeak(player, type, message) - LuaScriptInterface* scriptInterface = g_chat->getScriptInterface(); + LuaScriptInterface* scriptInterface = g_chat().getScriptInterface(); if (!scriptInterface->reserveScriptEnv()) { SPDLOG_ERROR("[OnSpeakChannelEvent::execute - Player {}, type {}] " "Call stack overflow. Too many lua script calls being nested.", diff --git a/src/creatures/interactions/chat.h b/src/creatures/interactions/chat.h index be5d73054b7..c9d60fd93aa 100644 --- a/src/creatures/interactions/chat.h +++ b/src/creatures/interactions/chat.h @@ -127,6 +127,13 @@ class Chat Chat(const Chat&) = delete; Chat& operator=(const Chat&) = delete; + static Chat& getInstance() { + // Guaranteed to be destroyed + static Chat instance; + // Instantiated on first use + return instance; + } + bool load(); ChatChannel* createChannel(const Player& player, uint16_t channelId); @@ -160,4 +167,6 @@ class Chat PrivateChatChannel dummyPrivate; }; +constexpr auto g_chat = &Chat::getInstance; + #endif // SRC_CREATURES_INTERACTIONS_CHAT_H_ diff --git a/src/creatures/monsters/monster.cpp b/src/creatures/monsters/monster.cpp index c9a38068388..62541f27b4a 100644 --- a/src/creatures/monsters/monster.cpp +++ b/src/creatures/monsters/monster.cpp @@ -26,8 +26,6 @@ #include "creatures/combat/spells.h" #include "lua/creature/events.h" -extern Monsters g_monsters; -extern Events* g_events; int32_t Monster::despawnRange; int32_t Monster::despawnRadius; @@ -36,7 +34,7 @@ uint32_t Monster::monsterAutoID = 0x40000000; Monster* Monster::createMonster(const std::string& name) { - MonsterType* mType = g_monsters.getMonsterType(name); + MonsterType* mType = g_monsters().getMonsterType(name); if (!mType) { return nullptr; } @@ -737,7 +735,7 @@ bool Monster::selectTarget(Creature* creature) if (isHostile() || isSummon()) { if (setAttackedCreature(creature) && !isSummon()) { - g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); } } return setFollowCreature(creature); @@ -2042,7 +2040,7 @@ void Monster::updateLookDirection() void Monster::dropLoot(Container* corpse, Creature*) { if (corpse && lootDrop) { - g_events->eventMonsterOnDropLoot(this, corpse); + g_events().eventMonsterOnDropLoot(this, corpse); } } diff --git a/src/creatures/monsters/monsters.cpp b/src/creatures/monsters/monsters.cpp index 4d94107e8a2..aee54a42392 100644 --- a/src/creatures/monsters/monsters.cpp +++ b/src/creatures/monsters/monsters.cpp @@ -28,8 +28,6 @@ #include "utils/pugicast.h" -extern Spells* g_spells; -extern Monsters g_monsters; spellBlock_t::~spellBlock_t() { @@ -165,7 +163,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } } - if (auto spell = g_spells->getSpellByName(name)) { + if (auto spell = g_spells().getSpellByName(name)) { sb.spell = spell; return true; } @@ -184,7 +182,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } std::unique_ptr combatSpellPtr(new CombatSpell(nullptr, needTarget, needDirection)); - if (!combatSpellPtr->loadScript("data/" + g_spells->getScriptBaseName() + "/scripts/" + scriptName)) { + if (!combatSpellPtr->loadScript("data/" + g_spells().getScriptBaseName() + "/scripts/" + scriptName)) { return false; } @@ -369,7 +367,7 @@ bool Monsters::deserializeSpell(const pugi::xml_node& node, spellBlock_t& sb, co } if ((attr = node.attribute("monster"))) { - MonsterType* mType = g_monsters.getMonsterType(attr.as_string()); + const MonsterType* mType = g_monsters().getMonsterType(attr.as_string()); if (mType) { ConditionOutfit* condition = static_cast(Condition::createCondition(CONDITIONID_COMBAT, CONDITION_OUTFIT, duration, 0)); condition->setOutfit(mType->info.outfit); @@ -536,7 +534,7 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std sb.range = std::min((int) spell->range, Map::maxViewportX * 2); sb.minCombatValue = std::min(spell->minCombatValue, spell->maxCombatValue); sb.maxCombatValue = std::max(spell->minCombatValue, spell->maxCombatValue); - sb.spell = g_spells->getSpellByName(spell->name); + sb.spell = g_spells().getSpellByName(spell->name); if (sb.spell) { return true; @@ -546,7 +544,7 @@ bool Monsters::deserializeSpell(MonsterSpell* spell, spellBlock_t& sb, const std if (spell->isScripted) { std::unique_ptr combatSpellPtr(new CombatSpell(nullptr, spell->needTarget, spell->needDirection)); - if (!combatSpellPtr->loadScript("data/" + g_spells->getScriptBaseName() + "/scripts/" + spell->scriptName)) { + if (!combatSpellPtr->loadScript("data/" + g_spells().getScriptBaseName() + "/scripts/" + spell->scriptName)) { SPDLOG_ERROR("[Monsters::deserializeSpell] - Cannot find file: {}", spell->scriptName); return false; @@ -1472,7 +1470,7 @@ MonsterType* Monsters::getMonsterTypeByRaceId(uint16_t thisrace) { if (it == raceid_list.end()) { return nullptr; } - MonsterType* mtype = g_monsters.getMonsterType(it->second); + MonsterType* mtype = g_monsters().getMonsterType(it->second); return (mtype ? mtype : nullptr); } diff --git a/src/creatures/monsters/monsters.h b/src/creatures/monsters/monsters.h index 693b6554781..5842789e8fc 100644 --- a/src/creatures/monsters/monsters.h +++ b/src/creatures/monsters/monsters.h @@ -225,6 +225,13 @@ class Monsters Monsters(const Monsters&) = delete; Monsters& operator=(const Monsters&) = delete; + static Monsters& getInstance() { + // Guaranteed to be destroyed + static Monsters instance; + // Instantiated on first use + return instance; + } + bool loadFromXml(bool reloading = false); bool isLoaded() const { return loaded; @@ -254,4 +261,6 @@ class Monsters bool loaded = false; }; +constexpr auto g_monsters = &Monsters::getInstance; + #endif // SRC_CREATURES_MONSTERS_MONSTERS_H_ diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 00021f81ca9..abad561e4ae 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -27,8 +27,6 @@ #include "utils/pugicast.h" #include "lua/creature/events.h" -extern Monsters g_monsters; -extern Events* g_events; static constexpr int32_t MONSTER_MINSPAWN_INTERVAL = 1000; // 1 second static constexpr int32_t MONSTER_MAXSPAWN_INTERVAL = 86400000; // 1 day @@ -159,7 +157,7 @@ bool SpawnsMonster::isInZone(const Position& centerPos, int32_t radius, const Po void SpawnMonster::startSpawnMonsterCheck() { if (checkSpawnMonsterEvent == 0) { - checkSpawnMonsterEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); + checkSpawnMonsterEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); } } @@ -211,7 +209,7 @@ bool SpawnMonster::spawnMonster(uint32_t spawnMonsterId, MonsterType* monsterTyp spawnedMonsterMap.insert(spawned_pair(spawnMonsterId, monster)); spawnMonsterMap[spawnMonsterId].lastSpawn = OTSYS_TIME(); - g_events->eventMonsterOnSpawn(monster, pos); + g_events().eventMonsterOnSpawn(monster, pos); return true; } @@ -263,7 +261,7 @@ void SpawnMonster::checkSpawnMonster() } if (spawnedMonsterMap.size() < spawnMonsterMap.size()) { - checkSpawnMonsterEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); + checkSpawnMonsterEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnMonster::checkSpawnMonster, this))); } } @@ -273,7 +271,7 @@ void SpawnMonster::scheduleSpawn(uint32_t spawnMonsterId, spawnBlock_t& sb, uint spawnMonster(spawnMonsterId, sb.monsterType, sb.pos, sb.direction); } else { g_game().addMagicEffect(sb.pos, CONST_ME_TELEPORT); - g_scheduler.addEvent(createSchedulerTask(1400, std::bind(&SpawnMonster::scheduleSpawn, this, spawnMonsterId, sb, interval - NONBLOCKABLE_SPAWN_MONSTER_INTERVAL))); + g_scheduler().addEvent(createSchedulerTask(1400, std::bind(&SpawnMonster::scheduleSpawn, this, spawnMonsterId, sb, interval - NONBLOCKABLE_SPAWN_MONSTER_INTERVAL))); } } @@ -295,7 +293,7 @@ void SpawnMonster::cleanup() bool SpawnMonster::addMonster(const std::string& name, const Position& pos, Direction dir, uint32_t scheduleInterval) { - MonsterType* monsterType = g_monsters.getMonsterType(name); + MonsterType* monsterType = g_monsters().getMonsterType(name); if (!monsterType) { SPDLOG_ERROR("Can not find {}", name); return false; @@ -329,7 +327,7 @@ void SpawnMonster::removeMonster(Monster* monster) void SpawnMonster::stopEvent() { if (checkSpawnMonsterEvent != 0) { - g_scheduler.stopEvent(checkSpawnMonsterEvent); + g_scheduler().stopEvent(checkSpawnMonsterEvent); checkSpawnMonsterEvent = 0; } } diff --git a/src/creatures/npcs/npc.cpp b/src/creatures/npcs/npc.cpp index 2847db2c264..77bb1b95ce4 100644 --- a/src/creatures/npcs/npc.cpp +++ b/src/creatures/npcs/npc.cpp @@ -27,8 +27,6 @@ #include "creatures/combat/spells.h" #include "lua/creature/events.h" -extern Npcs g_npcs; -extern Events* g_events; int32_t Npc::despawnRange; int32_t Npc::despawnRadius; @@ -37,7 +35,7 @@ uint32_t Npc::npcAutoID = 0x80000000; Npc* Npc::createNpc(const std::string& name) { - NpcType* npcType = g_npcs.getNpcType(name); + NpcType* npcType = g_npcs().getNpcType(name); if (!npcType) { return nullptr; } @@ -71,7 +69,7 @@ Npc::~Npc() { void Npc::reset() const { - g_npcs.reset(); + g_npcs().reset(); // Close shop window from all npcs and reset the shopPlayerSet for (const auto& [npcId, npc] : g_game().getNpcs()) { npc->closeAllShopWindows(); diff --git a/src/creatures/npcs/npcs.cpp b/src/creatures/npcs/npcs.cpp index abc6feacbdc..a4ba05e0f8e 100644 --- a/src/creatures/npcs/npcs.cpp +++ b/src/creatures/npcs/npcs.cpp @@ -30,8 +30,6 @@ #include "utils/pugicast.h" -extern Spells* g_spells; -extern Npcs g_npcs; bool NpcType::canSpawn(const Position& pos) { diff --git a/src/creatures/npcs/npcs.h b/src/creatures/npcs/npcs.h index 151d3eeaddb..4a052ef78ac 100644 --- a/src/creatures/npcs/npcs.h +++ b/src/creatures/npcs/npcs.h @@ -105,6 +105,13 @@ class Npcs Npcs(const Npcs&) = delete; Npcs& operator=(const Npcs&) = delete; + static Npcs& getInstance() { + // Guaranteed to be destroyed + static Npcs instance; + // Instantiated on first use + return instance; + } + NpcType* getNpcType(const std::string& name, bool create = false); // Reset npcs informations on reload @@ -118,4 +125,6 @@ class Npcs std::map npcs; }; +constexpr auto g_npcs = &Npcs::getInstance; + #endif // SRC_CREATURES_NPCS_NPCS_H_ diff --git a/src/creatures/npcs/spawns/spawn_npc.cpp b/src/creatures/npcs/spawns/spawn_npc.cpp index 4fc9d841020..084f8011f18 100644 --- a/src/creatures/npcs/spawns/spawn_npc.cpp +++ b/src/creatures/npcs/spawns/spawn_npc.cpp @@ -27,8 +27,6 @@ #include "utils/pugicast.h" #include "lua/creature/events.h" -extern Npcs g_npcs; -extern Events* g_events; static constexpr int32_t MINSPAWN_INTERVAL = 1000; // 1 second static constexpr int32_t MAXSPAWN_INTERVAL = 86400000; // 1 day @@ -147,7 +145,7 @@ bool SpawnsNpc::isInZone(const Position& centerPos, int32_t radius, const Positi void SpawnNpc::startSpawnNpcCheck() { if (checkSpawnNpcEvent == 0) { - checkSpawnNpcEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); + checkSpawnNpcEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); } } @@ -199,7 +197,7 @@ bool SpawnNpc::spawnNpc(uint32_t spawnId, NpcType* npcType, const Position& pos, spawnedNpcMap.insert(spawned_pair(spawnId, npc)); spawnNpcMap[spawnId].lastSpawnNpc = OTSYS_TIME(); - g_events->eventNpcOnSpawn(npc, pos); + g_events().eventNpcOnSpawn(npc, pos); return true; } @@ -241,7 +239,7 @@ void SpawnNpc::checkSpawnNpc() } if (spawnedNpcMap.size() < spawnNpcMap.size()) { - checkSpawnNpcEvent = g_scheduler.addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); + checkSpawnNpcEvent = g_scheduler().addEvent(createSchedulerTask(getInterval(), std::bind(&SpawnNpc::checkSpawnNpc, this))); } } @@ -251,7 +249,7 @@ void SpawnNpc::scheduleSpawnNpc(uint32_t spawnId, spawnBlockNpc_t& sb, uint16_t spawnNpc(spawnId, sb.npcType, sb.pos, sb.direction); } else { g_game().addMagicEffect(sb.pos, CONST_ME_TELEPORT); - g_scheduler.addEvent(createSchedulerTask(1400, std::bind(&SpawnNpc::scheduleSpawnNpc, this, spawnId, sb, interval - NONBLOCKABLE_SPAWN_NPC_INTERVAL))); + g_scheduler().addEvent(createSchedulerTask(1400, std::bind(&SpawnNpc::scheduleSpawnNpc, this, spawnId, sb, interval - NONBLOCKABLE_SPAWN_NPC_INTERVAL))); } } @@ -273,7 +271,7 @@ void SpawnNpc::cleanup() bool SpawnNpc::addNpc(const std::string& name, const Position& pos, Direction dir, uint32_t scheduleInterval) { - NpcType* npcType = g_npcs.getNpcType(name); + NpcType* npcType = g_npcs().getNpcType(name); if (!npcType) { SPDLOG_ERROR("Can not find {}", name); return false; @@ -307,7 +305,7 @@ void SpawnNpc::removeNpc(Npc* npc) void SpawnNpc::stopEvent() { if (checkSpawnNpcEvent != 0) { - g_scheduler.stopEvent(checkSpawnNpcEvent); + g_scheduler().stopEvent(checkSpawnNpcEvent); checkSpawnNpcEvent = 0; } } diff --git a/src/creatures/players/account/account.cpp b/src/creatures/players/account/account.cpp index a320c8ad1ba..fa6a8a07b88 100644 --- a/src/creatures/players/account/account.cpp +++ b/src/creatures/players/account/account.cpp @@ -35,7 +35,7 @@ Account::Account() { premium_last_day_ = 0; account_type_ = ACCOUNT_TYPE_NORMAL; db_ = &Database::getInstance(); - db_tasks_ = &g_databaseTasks; + db_tasks_ = &g_databaseTasks(); } Account::Account(uint32_t id) { @@ -46,7 +46,7 @@ Account::Account(uint32_t id) { premium_last_day_ = 0; account_type_ = ACCOUNT_TYPE_NORMAL; db_ = &Database::getInstance(); - db_tasks_ = &g_databaseTasks; + db_tasks_ = &g_databaseTasks(); } Account::Account(const std::string &email) : email_(email) { @@ -56,7 +56,7 @@ Account::Account(const std::string &email) : email_(email) { premium_last_day_ = 0; account_type_ = ACCOUNT_TYPE_NORMAL; db_ = &Database::getInstance(); - db_tasks_ = &g_databaseTasks; + db_tasks_ = &g_databaseTasks(); } diff --git a/src/creatures/players/grouping/party.cpp b/src/creatures/players/grouping/party.cpp index 200c7c0e314..ed58f4a9176 100644 --- a/src/creatures/players/grouping/party.cpp +++ b/src/creatures/players/grouping/party.cpp @@ -23,7 +23,6 @@ #include "game/game.h" #include "lua/creature/events.h" -extern Events* g_events; Party::Party(Player* initLeader) : leader(initLeader) { @@ -32,7 +31,7 @@ Party::Party(Player* initLeader) : leader(initLeader) void Party::disband() { - if (!g_events->eventPartyOnDisband(this)) { + if (!g_events().eventPartyOnDisband(this)) { return; } @@ -86,7 +85,7 @@ bool Party::leaveParty(Player* player) return false; } - if (!g_events->eventPartyOnLeave(this, player)) { + if (!g_events().eventPartyOnLeave(this, player)) { return false; } @@ -183,7 +182,7 @@ bool Party::passPartyLeadership(Player* player) bool Party::joinParty(Player& player) { - if (!g_events->eventPartyOnJoin(this, &player)) { + if (!g_events().eventPartyOnJoin(this, &player)) { return false; } @@ -369,7 +368,7 @@ bool Party::setSharedExperience(Player* player, bool newSharedExpActive) void Party::shareExperience(uint64_t experience, Creature* source/* = nullptr*/) { uint64_t shareExperience = experience; - g_events->eventPartyOnShareExperience(this, shareExperience); + g_events().eventPartyOnShareExperience(this, shareExperience); for (Player* member : memberList) { member->onGainSharedExperience(shareExperience, source); } diff --git a/src/creatures/players/imbuements/imbuements.cpp b/src/creatures/players/imbuements/imbuements.cpp index cd1a2475f88..32afa9a0ca5 100644 --- a/src/creatures/players/imbuements/imbuements.cpp +++ b/src/creatures/players/imbuements/imbuements.cpp @@ -22,7 +22,6 @@ #include "creatures/players/imbuements/imbuements.h" #include "utils/pugicast.h" -extern Events* g_events; Imbuement* Imbuements::getImbuement(uint16_t id) { diff --git a/src/creatures/players/imbuements/imbuements.h b/src/creatures/players/imbuements/imbuements.h index e27410dc1da..a003f8731f4 100644 --- a/src/creatures/players/imbuements/imbuements.h +++ b/src/creatures/players/imbuements/imbuements.h @@ -53,9 +53,22 @@ struct CategoryImbuement { class Imbuements { public: + Imbuements() = default; + bool loadFromXml(bool reloading = false); bool reload(); + // non-copyable + Imbuements(const Imbuements&) = delete; + Imbuements& operator=(const Imbuements&) = delete; + + static Imbuements& getInstance() { + // Guaranteed to be destroyed + static Imbuements instance; + // Instantiated on first use + return instance; + } + Imbuement* getImbuement(uint16_t id); BaseImbuement* getBaseByID(uint16_t id); @@ -75,6 +88,8 @@ class Imbuements { uint32_t runningid = 0; }; +constexpr auto g_imbuements = &Imbuements::getInstance; + class Imbuement { public: diff --git a/src/creatures/players/management/ban.cpp b/src/creatures/players/management/ban.cpp index 7c563752776..4490748b102 100644 --- a/src/creatures/players/management/ban.cpp +++ b/src/creatures/players/management/ban.cpp @@ -75,11 +75,11 @@ bool IOBan::isAccountBanned(uint32_t accountId, BanInfo& banInfo) // Move the ban to history if it has expired query.str(std::string()); query << "INSERT INTO `account_ban_history` (`account_id`, `reason`, `banned_at`, `expired_at`, `banned_by`) VALUES (" << accountId << ',' << db.escapeString(result->getString("reason")) << ',' << result->getNumber("banned_at") << ',' << expiresAt << ',' << result->getNumber("banned_by") << ')'; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); query.str(std::string()); query << "DELETE FROM `account_bans` WHERE `account_id` = " << accountId; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); return false; } @@ -109,7 +109,7 @@ bool IOBan::isIpBanned(uint32_t clientIP, BanInfo& banInfo) if (expiresAt != 0 && time(nullptr) > expiresAt) { query.str(std::string()); query << "DELETE FROM `ip_bans` WHERE `ip` = " << clientIP; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); return false; } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index aee95c049bc..f0a2a1f0c32 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -36,14 +36,6 @@ #include "items/weapons/weapons.h" #include "io/iobestiary.h" -extern Chat* g_chat; -extern Vocations g_vocations; -extern MoveEvents* g_moveEvents; -extern Weapons* g_weapons; -extern CreatureEvents* g_creatureEvents; -extern Events* g_events; -extern Imbuements* g_imbuements; -extern Monsters g_monsters; MuteCountMap Player::muteCountMap; @@ -92,7 +84,7 @@ Player::~Player() bool Player::setVocation(uint16_t vocId) { - Vocation* voc = g_vocations.getVocation(vocId); + Vocation* voc = g_vocations().getVocation(vocId); if (!voc) { return false; } @@ -494,7 +486,7 @@ void Player::updateInventoryImbuement(bool init /* = false */) // Time not decay on protection zone const Tile* playerTile = getTile(); - const CategoryImbuement *categoryImbuement = g_imbuements->getCategoryByID(imbuementInfo.imbuement->getCategory()); + const CategoryImbuement *categoryImbuement = g_imbuements().getCategoryByID(imbuementInfo.imbuement->getCategory()); if (categoryImbuement->agressive && playerTile && playerTile->hasFlag(TILESTATE_PROTECTIONZONE)) { continue; } @@ -539,7 +531,7 @@ void Player::addSkillAdvance(skills_t skill, uint64_t count) return; } - g_events->eventPlayerOnGainSkillTries(this, skill, count); + g_events().eventPlayerOnGainSkillTries(this, skill, count); if (count == 0) { return; } @@ -555,7 +547,7 @@ void Player::addSkillAdvance(skills_t skill, uint64_t count) ss << "You advanced to " << getSkillName(skill) << " level " << skills[skill].level << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); - g_creatureEvents->playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); + g_creatureEvents().playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); sendUpdateSkills = true; currReqTries = nextReqTries; @@ -753,8 +745,8 @@ void Player::addStorageValue(const uint32_t key, const int32_t value, const bool storageMap[key] = value; if (!isLogin) { - auto currentFrameTime = g_dispatcher.getDispatcherCycle(); - g_events->eventOnStorageUpdate(this, key, value, oldValue, currentFrameTime); + auto currentFrameTime = g_dispatcher().getDispatcherCycle(); + g_events().eventOnStorageUpdate(this, key, value, oldValue, currentFrameTime); } } else { storageMap.erase(key); @@ -1155,13 +1147,11 @@ void Player::sendPing() setAttackedCreature(nullptr); } - if (noPongTime >= 60000 && canLogout()) { - if (g_creatureEvents->playerLogout(this)) { - if (client) { - client->logout(true, true); - } else { - g_game().removeCreature(this, true); - } + if (noPongTime >= 60000 && canLogout() && g_creatureEvents().playerLogout(this)) { + if (client) { + client->logout(true, true); + } else { + g_game().removeCreature(this, true); } } } @@ -1255,7 +1245,7 @@ void Player::onApplyImbuement(Imbuement *imbuement, Item *item, uint8_t slot, bo } } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuement->getBaseID()); if (!baseImbuement) { return; @@ -1328,7 +1318,7 @@ void Player::onClearImbuement(Item* item, uint8_t slot) return; } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuementInfo.imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuementInfo.imbuement->getBaseID()); if (!baseImbuement) { return; } @@ -1509,7 +1499,7 @@ void Player::onCreatureAppear(Creature* creature, bool isLogin) Item* item = inventory[slot]; if (item) { item->startDecaying(); - g_moveEvents->onPlayerEquip(this, item, static_cast(slot), false); + g_moveEvents().onPlayerEquip(this, item, static_cast(slot), false); } } @@ -1596,7 +1586,7 @@ void Player::onChangeZone(ZoneType_t zone) g_game().updateCreatureWalkthrough(this); sendIcons(); - g_events->eventPlayerOnChangeZone(this, zone); + g_events().eventPlayerOnChangeZone(this, zone); } void Player::onAttackedCreatureChangeZone(ZoneType_t zone) @@ -1630,7 +1620,7 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout) if (isLogout) { loginPosition = getPosition(); SPDLOG_INFO("{} has logged out", getName()); - g_chat->removeUserFromAllChannels(*this); + g_chat().removeUserFromAllChannels(*this); clearPartyInvitations(); } @@ -1723,7 +1713,7 @@ void Player::onCreatureMove(Creature* creature, const Tile* newTile, const Posit if (hasFollowPath && (creature == followCreature || (creature == this && followCreature))) { isUpdatingPath = false; - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, &g_game(), getID()))); } if (creature != this) { @@ -1885,7 +1875,7 @@ void Player::checkTradeState(const Item* item) void Player::setNextWalkActionTask(SchedulerTask* task) { if (walkTaskEvent != 0) { - g_scheduler.stopEvent(walkTaskEvent); + g_scheduler().stopEvent(walkTaskEvent); walkTaskEvent = 0; } @@ -1896,12 +1886,12 @@ void Player::setNextWalkActionTask(SchedulerTask* task) void Player::setNextWalkTask(SchedulerTask* task) { if (nextStepEvent != 0) { - g_scheduler.stopEvent(nextStepEvent); + g_scheduler().stopEvent(nextStepEvent); nextStepEvent = 0; } if (task) { - nextStepEvent = g_scheduler.addEvent(task); + nextStepEvent = g_scheduler().addEvent(task); resetIdleTime(); } } @@ -1909,7 +1899,7 @@ void Player::setNextWalkTask(SchedulerTask* task) void Player::setNextActionTask(SchedulerTask* task, bool resetIdleTime /*= true */) { if (actionTaskEvent != 0) { - g_scheduler.stopEvent(actionTaskEvent); + g_scheduler().stopEvent(actionTaskEvent); actionTaskEvent = 0; } @@ -1918,7 +1908,7 @@ void Player::setNextActionTask(SchedulerTask* task, bool resetIdleTime /*= true } if (task) { - actionTaskEvent = g_scheduler.addEvent(task); + actionTaskEvent = g_scheduler().addEvent(task); if (resetIdleTime) { this->resetIdleTime(); } @@ -1928,26 +1918,26 @@ void Player::setNextActionTask(SchedulerTask* task, bool resetIdleTime /*= true void Player::setNextActionPushTask(SchedulerTask* task) { if (actionTaskEventPush != 0) { - g_scheduler.stopEvent(actionTaskEventPush); + g_scheduler().stopEvent(actionTaskEventPush); actionTaskEventPush = 0; } if (task) { - actionTaskEventPush = g_scheduler.addEvent(task); + actionTaskEventPush = g_scheduler().addEvent(task); } } void Player::setNextPotionActionTask(SchedulerTask* task) { if (actionPotionTaskEvent != 0) { - g_scheduler.stopEvent(actionPotionTaskEvent); + g_scheduler().stopEvent(actionPotionTaskEvent); actionPotionTaskEvent = 0; } cancelPush(); if (task) { - actionPotionTaskEvent = g_scheduler.addEvent(task); + actionPotionTaskEvent = g_scheduler().addEvent(task); //resetIdleTime(); } } @@ -1965,7 +1955,7 @@ uint32_t Player::getNextPotionActionTime() const void Player::cancelPush() { if (actionTaskEventPush != 0) { - g_scheduler.stopEvent(actionTaskEventPush); + g_scheduler().stopEvent(actionTaskEventPush); actionTaskEventPush = 0; inEventMovePush = false; } @@ -2079,7 +2069,7 @@ void Player::addManaSpent(uint64_t amount) return; } - g_events->eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, amount); + g_events().eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, amount); if (amount == 0) { return; } @@ -2095,7 +2085,7 @@ void Player::addManaSpent(uint64_t amount) ss << "You advanced to magic level " << magLevel << '.'; sendTextMessage(MESSAGE_EVENT_ADVANCE, ss.str()); - g_creatureEvents->playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); + g_creatureEvents().playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); sendUpdateStats = true; currReqMana = nextReqMana; @@ -2136,7 +2126,7 @@ void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = fal return; } - g_events->eventPlayerOnGainExperience(this, source, exp, rawExp); + g_events().eventPlayerOnGainExperience(this, source, exp, rawExp); if (exp == 0) { return; } @@ -2169,7 +2159,7 @@ void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = fal ++level; // Player stats gain for vocations level <= 8 if (vocation->getId() != VOCATION_NONE && level <= 8) { - Vocation* noneVocation = g_vocations.getVocation(VOCATION_NONE); + const Vocation* noneVocation = g_vocations().getVocation(VOCATION_NONE); healthMax += noneVocation->getHPGain(); health += noneVocation->getHPGain(); manaMax += noneVocation->getManaGain(); @@ -2205,7 +2195,7 @@ void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = fal party->updateSharedExperience(); } - g_creatureEvents->playerAdvance(this, SKILL_LEVEL, prevLevel, level); + g_creatureEvents().playerAdvance(this, SKILL_LEVEL, prevLevel, level); std::ostringstream ss; ss << "You advanced from Level " << prevLevel << " to Level " << level << '.'; @@ -2227,7 +2217,7 @@ void Player::removeExperience(uint64_t exp, bool sendText/* = false*/) return; } - g_events->eventPlayerOnLoseExperience(this, exp); + g_events().eventPlayerOnLoseExperience(this, exp); if (exp == 0) { return; } @@ -2265,7 +2255,7 @@ void Player::removeExperience(uint64_t exp, bool sendText/* = false*/) --level; // Player stats loss for vocations level <= 8 if (vocation->getId() != VOCATION_NONE && level <= 8) { - Vocation* noneVocation = g_vocations.getVocation(VOCATION_NONE); + const Vocation* noneVocation = g_vocations().getVocation(VOCATION_NONE); healthMax = std::max(0, healthMax - noneVocation->getHPGain()); manaMax = std::max(0, manaMax - noneVocation->getManaGain()); capacity = std::max(0, capacity - noneVocation->getCapGain()); @@ -2522,7 +2512,7 @@ void Player::death(Creature* lastHitCreature) // Charm bless bestiary if (lastHitCreature && lastHitCreature->getMonster()) { if (charmRuneBless != 0) { - MonsterType* mType = g_monsters.getMonsterType(lastHitCreature->getName()); + const MonsterType* mType = g_monsters().getMonsterType(lastHitCreature->getName()); if (mType && mType->info.raceid == charmRuneBless) { deathLossPercent = (deathLossPercent * 90) / 100; } @@ -2548,7 +2538,7 @@ void Player::death(Creature* lastHitCreature) //Level loss uint64_t expLoss = static_cast(experience * deathLossPercent); - g_events->eventPlayerOnLoseExperience(this, expLoss); + g_events().eventPlayerOnLoseExperience(this, expLoss); sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead."); std::ostringstream lostExp; @@ -2847,7 +2837,7 @@ void Player::addList() void Player::removePlayer(bool displayEffect, bool forced /*= true*/) { - g_creatureEvents->playerLogout(this); + g_creatureEvents().playerLogout(this); if (client) { client->logout(displayEffect, forced); } else { @@ -3185,7 +3175,7 @@ ReturnValue Player::queryAdd(int32_t index, const Thing& thing, uint32_t count, return RETURNVALUE_NOTENOUGHCAPACITY; } - if (!g_moveEvents->onPlayerEquip(const_cast(this), const_cast(item), static_cast(index), true)) { + if (!g_moveEvents().onPlayerEquip(const_cast(this), const_cast(item), static_cast(index), true)) { return RETURNVALUE_CANNOTBEDRESSED; } } @@ -3528,9 +3518,9 @@ void Player::removeThing(Thing* thing, uint32_t count) } } -int32_t Player::getThingIndex(const Thing* thing) const +uint8_t Player::getThingIndex(const Thing* thing) const { - for (int i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { + for (uint8_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; ++i) { if (inventory[i] == thing) { return i; } @@ -3814,7 +3804,7 @@ void Player::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_ { if (link == LINK_OWNER) { //calling movement scripts - g_moveEvents->onPlayerEquip(this, thing->getItem(), static_cast(index), false); + g_moveEvents().onPlayerEquip(this, thing->getItem(), static_cast(index), false); } bool requireListUpdate = true; @@ -3869,7 +3859,7 @@ void Player::postRemoveNotification(Thing* thing, const Cylinder* newParent, int { if (link == LINK_OWNER) { //calling movement scripts - g_moveEvents->onPlayerDeEquip(this, thing->getItem(), static_cast(index)); + g_moveEvents().onPlayerDeEquip(this, thing->getItem(), static_cast(index)); } bool requireListUpdate = true; @@ -3937,7 +3927,7 @@ bool Player::updateSaleShopList(const Item* item) if (!itemId || !item) return true; - g_dispatcher.addTask(createTask(std::bind(&Game::updatePlayerSaleItems, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updatePlayerSaleItems, &g_game(), getID()))); scheduledSaleUpdate = true; return true; } @@ -4009,7 +3999,7 @@ bool Player::setAttackedCreature(Creature* creature) } if (creature) { - g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game(), getID()))); } return true; } @@ -4049,7 +4039,7 @@ void Player::doAttacking(uint32_t) bool result = false; Item* tool = getWeapon(); - const Weapon* weapon = g_weapons->getWeapon(tool); + const Weapon* weapon = g_weapons().getWeapon(tool); uint32_t delay = getAttackSpeed(); bool classicSpeed = g_configManager().getBoolean(CLASSIC_ATTACK_SPEED); @@ -4069,7 +4059,7 @@ void Player::doAttacking(uint32_t) if (!classicSpeed) { setNextActionTask(task, false); } else { - g_scheduler.addEvent(task); + g_scheduler().addEvent(task); } if (result) { @@ -4123,7 +4113,7 @@ void Player::onWalkAborted() void Player::onWalkComplete() { if (walkTask) { - walkTaskEvent = g_scheduler.addEvent(walkTask); + walkTaskEvent = g_scheduler().addEvent(walkTask); walkTask = nullptr; } } @@ -4335,7 +4325,7 @@ void Player::onIdleStatus() void Player::onPlacedCreature() { //scripting event - onLogin - if (!g_creatureEvents->playerLogin(this)) { + if (!g_creatureEvents().playerLogin(this)) { removePlayer(true); } @@ -4848,7 +4838,7 @@ void Player::checkSkullTicks(int64_t ticks) bool Player::isPromoted() const { - uint16_t promotedVocation = g_vocations.getPromotedVocation(vocation->getId()); + uint16_t promotedVocation = g_vocations().getPromotedVocation(vocation->getId()); return promotedVocation == VOCATION_NONE && vocation->getId() != promotedVocation; } @@ -5311,7 +5301,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) oldSkillValue = magLevel; oldPercentToNextLevel = static_cast(manaSpent * 100) / nextReqMana; - g_events->eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, tries); + g_events().eventPlayerOnGainSkillTries(this, SKILL_MAGLEVEL, tries); uint32_t currMagLevel = magLevel; while ((manaSpent + tries) >= nextReqMana) { @@ -5320,7 +5310,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) magLevel++; manaSpent = 0; - g_creatureEvents->playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); + g_creatureEvents().playerAdvance(this, SKILL_MAGLEVEL, magLevel - 1, magLevel); sendUpdate = true; currReqMana = nextReqMana; @@ -5365,7 +5355,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) oldSkillValue = skills[skill].level; oldPercentToNextLevel = static_cast(skills[skill].tries * 100) / nextReqTries; - g_events->eventPlayerOnGainSkillTries(this, skill, tries); + g_events().eventPlayerOnGainSkillTries(this, skill, tries); uint32_t currSkillLevel = skills[skill].level; while ((skills[skill].tries + tries) >= nextReqTries) { @@ -5375,7 +5365,7 @@ bool Player::addOfflineTrainingTries(skills_t skill, uint64_t tries) skills[skill].tries = 0; skills[skill].percent = 0; - g_creatureEvents->playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); + g_creatureEvents().playerAdvance(this, skill, (skills[skill].level - 1), skills[skill].level); sendUpdate = true; currReqTries = nextReqTries; @@ -5481,7 +5471,7 @@ uint16_t Player::getHelpers() const void Player::sendClosePrivate(uint16_t channelId) { if (channelId == CHANNEL_GUILD || channelId == CHANNEL_PARTY) { - g_chat->removeUserFromChannel(*this, channelId); + g_chat().removeUserFromChannel(*this, channelId); } if (client) { diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index d3df75297ad..87e2bd242cd 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -1931,7 +1931,7 @@ class Player final : public Creature, public Cylinder void removeThing(Thing* thing, uint32_t count) override; - int32_t getThingIndex(const Thing* thing) const override; + uint8_t getThingIndex(const Thing* thing) const override; size_t getFirstIndex() const override; size_t getLastIndex() const override; uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override; diff --git a/src/creatures/players/vocations/vocation.cpp b/src/creatures/players/vocations/vocation.cpp index 92a951d1500..29f70733161 100644 --- a/src/creatures/players/vocations/vocation.cpp +++ b/src/creatures/players/vocations/vocation.cpp @@ -171,7 +171,7 @@ Vocation* Vocations::getVocation(uint16_t id) return &it->second; } -int32_t Vocations::getVocationId(const std::string& name) const +uint16_t Vocations::getVocationId(const std::string& name) const { for (const auto& it : vocationsMap) { if (strcasecmp(it.second.name.c_str(), name.c_str()) == 0) { diff --git a/src/creatures/players/vocations/vocation.h b/src/creatures/players/vocations/vocation.h index 420934aec5e..56752d9b323 100644 --- a/src/creatures/players/vocations/vocation.h +++ b/src/creatures/players/vocations/vocation.h @@ -99,9 +99,9 @@ class Vocation return fromVocation; } - bool getMagicShield() const { - return magicShield; - } + bool getMagicShield() const { + return magicShield; + } float meleeDamageMultiplier = 1.0f; float distDamageMultiplier = 1.0f; @@ -132,7 +132,7 @@ class Vocation uint32_t baseSpeed = 220; uint16_t id; - bool magicShield = false; + bool magicShield = false; uint32_t gainSoulTicks = 120000; @@ -146,15 +146,29 @@ class Vocation class Vocations { public: + Vocations() = default; + + Vocations(Vocations const&) = delete; + void operator=(Vocations const&) = delete; + + static Vocations& getInstance() { + // Guaranteed to be destroyed + static Vocations instance; + // Instantiated on first use + return instance; + } + bool loadFromXml(); Vocation* getVocation(uint16_t id); - const std::map& getVocations() const {return vocationsMap;} - int32_t getVocationId(const std::string& name) const; + const std::map& getVocations() const {return vocationsMap;} + uint16_t getVocationId(const std::string& name) const; uint16_t getPromotedVocation(uint16_t vocationId) const; private: std::map vocationsMap; }; +constexpr auto g_vocations = &Vocations::getInstance; + #endif // SRC_CREATURES_PLAYERS_VOCATIONS_VOCATION_H_ diff --git a/src/database/databasetasks.cpp b/src/database/databasetasks.cpp index 764961dfa00..5fe6a1980f2 100644 --- a/src/database/databasetasks.cpp +++ b/src/database/databasetasks.cpp @@ -22,7 +22,6 @@ #include "database/databasetasks.h" #include "game/scheduling/tasks.h" -extern Dispatcher g_dispatcher; DatabaseTasks::DatabaseTasks() { db_ = &Database::getInstance(); @@ -105,7 +104,7 @@ void DatabaseTasks::runTask(const DatabaseTask& task) } if (task.callback) { - g_dispatcher.addTask(createTask(std::bind(task.callback, result, success))); + g_dispatcher().addTask(createTask(std::bind(task.callback, result, success))); } } diff --git a/src/database/databasetasks.h b/src/database/databasetasks.h index 2c62d119af0..3468b57a69e 100644 --- a/src/database/databasetasks.h +++ b/src/database/databasetasks.h @@ -38,6 +38,18 @@ class DatabaseTasks : public ThreadHolder { public: DatabaseTasks(); + + // non-copyable + DatabaseTasks(DatabaseTasks const&) = delete; + void operator=(DatabaseTasks const&) = delete; + + static DatabaseTasks& getInstance() { + // Guaranteed to be destroyed + static DatabaseTasks instance; + // Instantiated on first use + return instance; + } + bool SetDatabaseInterface(Database *database); void start(); void startThread(); @@ -59,6 +71,6 @@ class DatabaseTasks : public ThreadHolder bool flushTasks = false; }; -extern DatabaseTasks g_databaseTasks; +constexpr auto g_databaseTasks = &DatabaseTasks::getInstance; #endif // SRC_DATABASE_DATABASETASKS_H_ diff --git a/src/game/game.cpp b/src/game/game.cpp index 5778e90fec0..f756acff612 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -47,24 +47,6 @@ #include "creatures/npcs/npc.h" #include "creatures/npcs/npcs.h" #include "server/network/webhook/webhook.h" - -extern Actions* g_actions; -extern Chat* g_chat; -extern TalkActions* g_talkActions; -extern Spells* g_spells; -extern Vocations g_vocations; -extern GlobalEvents* g_globalEvents; -extern CreatureEvents* g_creatureEvents; -extern Events* g_events; -extern Monsters g_monsters; -extern Npcs g_npcs; -extern MoveEvents* g_moveEvents; -extern Weapons* g_weapons; -extern Scripts* g_scripts; -extern Modules* g_modules; -extern Imbuements* g_imbuements; -extern LuaEnvironment g_luaEnvironment; - Game::Game() { offlineTrainingWindow.choices.emplace_back("Sword Fighting and Shielding", SKILL_SWORD); @@ -126,7 +108,7 @@ void Game::loadBoostedCreature() } } - MonsterType* monsterType = g_monsters.getMonsterTypeByRaceId(newrace); + const MonsterType* monsterType = g_monsters().getMonsterTypeByRaceId(newrace); query.str(std::string()); query << "UPDATE `boosted_creature` SET "; @@ -164,9 +146,9 @@ void Game::start(ServiceManager* manager) int minutes = tms->tm_min; lightHour = (minutes * LIGHT_DAY_LENGTH) / 60; - g_scheduler.addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); - g_scheduler.addEvent(createSchedulerTask(EVENT_CREATURE_THINK_INTERVAL, std::bind(&Game::checkCreatures, this, 0))); - g_scheduler.addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_CREATURE_THINK_INTERVAL, std::bind(&Game::checkCreatures, this, 0))); + g_scheduler().addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); } GameState_t Game::getGameState() const @@ -229,12 +211,10 @@ bool Game::loadScheduleEventFromXml() } } - if ((attr = schedNode.attribute("script"))) { - if (!(g_scripts->loadEventSchedulerScripts(attr.as_string()))) { - SPDLOG_WARN("Can not load the file '{}' on '/events/scripts/scheduler/'", - attr.as_string()); - return false; - } + if ((attr = schedNode.attribute("script")) && !(g_scripts().loadEventSchedulerScripts(attr.as_string()))) { + SPDLOG_WARN("Can not load the file '{}' on '/events/scripts/scheduler/'", + attr.as_string()); + return false; } for (auto schedENode : schedNode.children()) { @@ -283,7 +263,7 @@ void Game::setGameState(GameState_t newState) loadItemsPrice(); groups.load(); - g_chat->load(); + g_chat().load(); // Load monsters and npcs stored by the "loadFromXML" function map.spawnsMonster.startup(); @@ -306,12 +286,12 @@ void Game::setGameState(GameState_t newState) loadMotdNum(); loadPlayersRecord(); - g_globalEvents->startup(); + g_globalEvents().startup(); break; } case GAME_STATE_SHUTDOWN: { - g_globalEvents->execute(GLOBALEVENT_SHUTDOWN); + g_globalEvents().execute(GLOBALEVENT_SHUTDOWN); //kick all players that are still online auto it = players.begin(); @@ -323,12 +303,12 @@ void Game::setGameState(GameState_t newState) saveMotdNum(); saveGameState(); - g_dispatcher.addTask( + g_dispatcher().addTask( createTask(std::bind(&Game::shutdown, this))); - g_scheduler.stop(); - g_databaseTasks.stop(); - g_dispatcher.stop(); + g_scheduler().stop(); + g_databaseTasks().stop(); + g_dispatcher().stop(); break; } @@ -630,7 +610,7 @@ void Game::saveGameState() Map::save(); - g_databaseTasks.flush(); + g_databaseTasks().flush(); if (gameState == GAME_STATE_MAINTAIN) { setGameState(GAME_STATE_NORMAL); @@ -1248,7 +1228,7 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po //need to walk to the creature first before moving it std::forward_list listDir; if (player->getPathTo(movingCreatureOrigPos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(600, std::bind(&Game::playerMoveCreatureByID, this, @@ -1310,7 +1290,7 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po movingCreature->setLastPosition(movingCreature->getPosition()); } - if (!g_events->eventPlayerOnMoveCreature(player, movingCreature, movingCreaturePos, toPos)) { + if (!g_events().eventPlayerOnMoveCreature(player, movingCreature, movingCreaturePos, toPos)) { return; } @@ -1502,7 +1482,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, //need to walk to the item first before using it std::forward_list listDir; if (player->getPathTo(item->getPosition(), listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -1563,7 +1543,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, std::forward_list listDir; if (player->getPathTo(walkPos, listDir, 0, 0, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -1597,7 +1577,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, return; } - if (!g_events->eventPlayerOnMoveItem(player, item, count, fromPos, toPos, fromCylinder, toCylinder)) { + if (!g_events().eventPlayerOnMoveItem(player, item, count, fromPos, toPos, fromCylinder, toCylinder)) { return; } @@ -1629,7 +1609,7 @@ void Game::playerMoveItem(Player* player, const Position& fromPos, } player->cancelPush(); - g_events->eventPlayerOnItemMoved(player, item, count, fromPos, toPos, fromCylinder, toCylinder); + g_events().eventPlayerOnItemMoved(player, item, count, fromPos, toPos, fromCylinder, toCylinder); } ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, @@ -2811,7 +2791,7 @@ void Game::playerCreatePrivateChannel(uint32_t playerId) return; } - ChatChannel* channel = g_chat->createChannel(*player, CHANNEL_PRIVATE); + ChatChannel* channel = g_chat().createChannel(*player, CHANNEL_PRIVATE); if (!channel || !channel->addUser(*player)) { return; } @@ -2826,7 +2806,7 @@ void Game::playerChannelInvite(uint32_t playerId, const std::string& name) return; } - PrivateChatChannel* channel = g_chat->getPrivateChannel(*player); + PrivateChatChannel* channel = g_chat().getPrivateChannel(*player); if (!channel) { return; } @@ -2850,7 +2830,7 @@ void Game::playerChannelExclude(uint32_t playerId, const std::string& name) return; } - PrivateChatChannel* channel = g_chat->getPrivateChannel(*player); + PrivateChatChannel* channel = g_chat().getPrivateChannel(*player); if (!channel) { return; } @@ -2884,7 +2864,7 @@ void Game::playerOpenChannel(uint32_t playerId, uint16_t channelId) return; } - ChatChannel* channel = g_chat->addUserToChannel(*player, channelId); + const ChatChannel* channel = g_chat().addUserToChannel(*player, channelId); if (!channel) { return; } @@ -2907,7 +2887,7 @@ void Game::playerCloseChannel(uint32_t playerId, uint16_t channelId) return; } - g_chat->removeUserFromChannel(*player, channelId); + g_chat().removeUserFromChannel(*player, channelId); } void Game::playerOpenPrivateChannel(uint32_t playerId, std::string& receiver) @@ -3014,9 +2994,9 @@ void Game::playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t f } Position walkToPos = fromPos; - ReturnValue ret = g_actions->canUse(player, fromPos); + ReturnValue ret = g_actions().canUse(player, fromPos); if (ret == RETURNVALUE_NOERROR) { - ret = g_actions->canUse(player, toPos, item); + ret = g_actions().canUse(player, toPos, item); if (ret == RETURNVALUE_TOOFARAWAY) { walkToPos = toPos; } @@ -3051,7 +3031,7 @@ void Game::playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t f std::forward_list listDir; if (player->getPathTo(walkToPos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerUseItemEx, this, @@ -3099,7 +3079,7 @@ void Game::playerUseItemEx(uint32_t playerId, const Position& fromPos, uint8_t f player->setNextActionTask(nullptr); } - g_actions->useItemEx(player, fromPos, toPos, toStackPos, item, isHotkey); + g_actions().useItemEx(player, fromPos, toPos, toStackPos, item, isHotkey); } void Game::playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPos, @@ -3135,12 +3115,12 @@ void Game::playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPo } } - ReturnValue ret = g_actions->canUse(player, pos); + ReturnValue ret = g_actions().canUse(player, pos); if (ret != RETURNVALUE_NOERROR) { if (ret == RETURNVALUE_TOOFARAWAY) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -3184,7 +3164,7 @@ void Game::playerUseItem(uint32_t playerId, const Position& pos, uint8_t stackPo player->resetIdleTime(); player->setNextActionTask(nullptr); - g_actions->useItem(player, pos, index, item, isHotkey); + g_actions().useItem(player, pos, index, item, isHotkey); } void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uint8_t fromStackPos, uint32_t creatureId, uint16_t spriteId) @@ -3232,9 +3212,9 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uin } Position toPos = creature->getPosition(); Position walkToPos = fromPos; - ReturnValue ret = g_actions->canUse(player, fromPos); + ReturnValue ret = g_actions().canUse(player, fromPos); if (ret == RETURNVALUE_NOERROR) { - ret = g_actions->canUse(player, toPos, item); + ret = g_actions().canUse(player, toPos, item); if (ret == RETURNVALUE_TOOFARAWAY) { walkToPos = toPos; } @@ -3259,7 +3239,7 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uin std::forward_list listDir; if (player->getPathTo(walkToPos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, @@ -3309,7 +3289,7 @@ void Game::playerUseWithCreature(uint32_t playerId, const Position& fromPos, uin player->setNextActionTask(nullptr); } - g_actions->useItemEx(player, fromPos, creature->getPosition(), creature->getParent()->getThingIndex(creature), item, isHotkey, creature); + g_actions().useItemEx(player, fromPos, creature->getPosition(), creature->getParent()->getThingIndex(creature), item, isHotkey, creature); } void Game::playerCloseContainer(uint32_t playerId, uint8_t cid) @@ -3342,7 +3322,7 @@ void Game::playerMoveUpContainer(uint32_t playerId, uint8_t cid) return; } - if (!g_events->eventPlayerOnBrowseField(player, tile->getPosition())) { + if (!g_events().eventPlayerOnBrowseField(player, tile->getPosition())) { return; } @@ -3351,7 +3331,7 @@ void Game::playerMoveUpContainer(uint32_t playerId, uint8_t cid) parentContainer = new Container(tile); parentContainer->incrementReferenceCounter(); browseFields[tile] = parentContainer; - g_scheduler.addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); + g_scheduler().addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); } else { parentContainer = it->second; } @@ -3405,7 +3385,7 @@ void Game::playerRotateItem(uint32_t playerId, const Position& pos, uint8_t stac if (pos.x != 0xFFFF && !Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerRotateItem, this, @@ -3444,7 +3424,7 @@ void Game::playerConfigureShowOffSocket(uint32_t playerId, const Position& pos, if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, false)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerBrowseField, this, playerId, pos)); @@ -3486,7 +3466,7 @@ void Game::playerSetShowOffSocket(uint32_t playerId, Outfit_t& outfit, const Pos if (!Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, false)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerBrowseField, this, playerId, pos)); @@ -3581,7 +3561,7 @@ void Game::playerWrapableItem(uint32_t playerId, const Position& pos, uint8_t st if (pos.x != 0xFFFF && !Position::areInRange<1, 1, 0>(pos, player->getPosition())) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerWrapableItem, this, @@ -3727,7 +3707,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position& pos) if (!Position::areInRange<1, 1>(playerPos, pos)) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerBrowseField, @@ -3744,7 +3724,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position& pos) return; } - if (!g_events->eventPlayerOnBrowseField(player, pos)) { + if (!g_events().eventPlayerOnBrowseField(player, pos)) { return; } @@ -3755,7 +3735,7 @@ void Game::playerBrowseField(uint32_t playerId, const Position& pos) container = new Container(tile); container->incrementReferenceCounter(); browseFields[tile] = container; - g_scheduler.addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); + g_scheduler().addEvent(createSchedulerTask(30000, std::bind(&Game::decreaseBrowseFieldRef, this, tile->getPosition()))); } else { container = it->second; } @@ -3965,7 +3945,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position& pos, uint8_t st if (!Position::areInRange<1, 1>(tradeItemPosition, playerPosition)) { std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(400, std::bind(&Game::playerRequestTrade, this, @@ -4019,7 +3999,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position& pos, uint8_t st return; } - if (!g_events->eventPlayerOnTradeRequest(player, tradePartner, tradeItem)) { + if (!g_events().eventPlayerOnTradeRequest(player, tradePartner, tradeItem)) { return; } @@ -4086,7 +4066,7 @@ void Game::playerAcceptTrade(uint32_t playerId) Item* tradeItem1 = player->tradeItem; Item* tradeItem2 = tradePartner->tradeItem; - if (!g_events->eventPlayerOnTradeAccept(player, tradePartner, tradeItem1, tradeItem2)) { + if (!g_events().eventPlayerOnTradeAccept(player, tradePartner, tradeItem1, tradeItem2)) { internalCloseTrade(player); return; } @@ -4221,7 +4201,7 @@ void Game::playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t Position::getDistanceX(playerPosition, tradeItemPosition), Position::getDistanceY(playerPosition, tradeItemPosition)); if (index == 0) { - g_events->eventPlayerOnLookInTrade(player, tradePartner, tradeItem, lookDistance); + g_events().eventPlayerOnLookInTrade(player, tradePartner, tradeItem, lookDistance); return; } @@ -4241,7 +4221,7 @@ void Game::playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, uint8_t } if (--index == 0) { - g_events->eventPlayerOnLookInTrade(player, tradePartner, item, lookDistance); + g_events().eventPlayerOnLookInTrade(player, tradePartner, item, lookDistance); return; } } @@ -4396,14 +4376,14 @@ void Game::playerLookInShop(uint32_t playerId, uint16_t spriteId, uint8_t count) return; } - int32_t subType; + uint8_t subType; if (it.isFluidContainer() || it.isSplash()) { subType = clientFluidToServer(count); } else { subType = count; } - if (!g_events->eventPlayerOnLookInShop(player, &it, subType)) { + if (!g_events().eventPlayerOnLookInShop(player, &it, subType)) { return; } @@ -4445,7 +4425,7 @@ void Game::playerLookAt(uint32_t playerId, const Position& pos, uint8_t stackPos } // Parse onLook from event player - g_events->eventPlayerOnLook(player, pos, thing, stackPos, lookDistance); + g_events().eventPlayerOnLook(player, pos, thing, stackPos, lookDistance); } void Game::playerLookInBattleList(uint32_t playerId, uint32_t creatureId) @@ -4480,7 +4460,7 @@ void Game::playerLookInBattleList(uint32_t playerId, uint32_t creatureId) lookDistance = -1; } - g_events->eventPlayerOnLookInBattleList(player, creature, lookDistance); + g_events().eventPlayerOnLookInBattleList(player, creature, lookDistance); } void Game::playerQuickLoot(uint32_t playerId, const Position& pos, uint16_t spriteId, uint8_t stackPos, Item* defaultItem, bool lootAllCorpses, bool autoLoot) @@ -4505,7 +4485,7 @@ void Game::playerQuickLoot(uint32_t playerId, const Position& pos, uint16_t spri //need to walk to the corpse first before looting it std::forward_list listDir; if (player->getPathTo(pos, listDir, 0, 1, true, true)) { - g_dispatcher.addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); + g_dispatcher().addTask(createTask(std::bind(&Game::playerAutoWalk, this, player->getID(), listDir))); SchedulerTask* task = createSchedulerTask(0, std::bind( &Game::playerQuickLoot, this, player->getID(), pos, @@ -4603,7 +4583,7 @@ void Game::playerQuickLoot(uint32_t playerId, const Position& pos, uint16_t spri player->lastQuickLootNotification = OTSYS_TIME(); } else { if (corpse->isRewardCorpse()) { - g_actions->useItem(player, pos, 0, corpse, false); + g_actions().useItem(player, pos, 0, corpse, false); } else { if (!lootAllCorpses) { internalQuickLootCorpse(player, corpse); @@ -4839,7 +4819,7 @@ void Game::playerSetAttackedCreature(uint32_t playerId, uint32_t creatureId) } player->setAttackedCreature(attackCreature); - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); } void Game::playerFollowCreature(uint32_t playerId, uint32_t creatureId) @@ -4850,7 +4830,7 @@ void Game::playerFollowCreature(uint32_t playerId, uint32_t creatureId) } player->setAttackedCreature(nullptr); - g_dispatcher.addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); + g_dispatcher().addTask(createTask(std::bind(&Game::updateCreatureWalk, this, player->getID()))); player->setFollowCreature(getCreatureByID(creatureId)); } @@ -4927,7 +4907,7 @@ void Game::playerRequestEditVip(uint32_t playerId, uint32_t guid, const std::str player->editVIP(guid, description, icon, notify); } -void Game::playerApplyImbuement(uint32_t playerId, uint32_t imbuementid, uint8_t slot, bool protectionCharm) +void Game::playerApplyImbuement(uint32_t playerId, uint16_t imbuementid, uint8_t slot, bool protectionCharm) { Player* player = getPlayerByID(playerId); if (!player) { @@ -4938,7 +4918,7 @@ void Game::playerApplyImbuement(uint32_t playerId, uint32_t imbuementid, uint8_t return; } - Imbuement* imbuement = g_imbuements->getImbuement(imbuementid); + Imbuement* imbuement = g_imbuements().getImbuement(imbuementid); if (!imbuement) { return; } @@ -4998,7 +4978,7 @@ void Game::playerTurn(uint32_t playerId, Direction dir) return; } - if (!g_events->eventPlayerOnTurn(player, dir)) { + if (!g_events().eventPlayerOnTurn(player, dir)) { return; } @@ -5089,7 +5069,7 @@ void Game::playerShowQuestLog(uint32_t playerId) return; } - g_events->eventPlayerOnRequestQuestLog(player); + g_events().eventPlayerOnRequestQuestLog(player); } void Game::playerShowQuestLine(uint32_t playerId, uint16_t questId) @@ -5099,7 +5079,7 @@ void Game::playerShowQuestLine(uint32_t playerId, uint16_t questId) return; } - g_events->eventPlayerOnRequestQuestLine(player, questId); + g_events().eventPlayerOnRequestQuestLine(player, questId); } void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type, @@ -5154,7 +5134,7 @@ void Game::playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type, case TALKTYPE_CHANNEL_O: case TALKTYPE_CHANNEL_Y: case TALKTYPE_CHANNEL_R1: - g_chat->talkToChannel(*player, type, text, channelId); + g_chat().talkToChannel(*player, type, text, channelId); break; case TALKTYPE_PRIVATE_PN: @@ -5177,12 +5157,12 @@ bool Game::playerSaySpell(Player* player, SpeakClasses type, const std::string& } std::string words = text; - TalkActionResult_t result = g_talkActions->playerSaySpell(player, type, words); + TalkActionResult_t result = g_talkActions().playerSaySpell(player, type, words); if (result == TALKACTION_BREAK) { return true; } - result = g_spells->playerSaySpell(player, words); + result = g_spells().playerSaySpell(player, words); if (result == TALKACTION_BREAK) { if (!g_configManager().getBoolean(PUSH_WHEN_ATTACKING)) { player->cancelPush(); @@ -5363,7 +5343,7 @@ bool Game::internalCreatureSay(Creature* creature, SpeakClasses type, const std: for (Creature* spectator : spectators) { spectator->onCreatureSay(creature, type, text); if (creature != spectator) { - g_events->eventCreatureOnHear(spectator, creature, text, type); + g_events().eventCreatureOnHear(spectator, creature, text, type); } } return true; @@ -5417,7 +5397,7 @@ void Game::removeCreatureCheck(Creature* creature) void Game::checkCreatures(size_t index) { - g_scheduler.addEvent(createSchedulerTask(EVENT_CHECK_CREATURE_INTERVAL, std::bind(&Game::checkCreatures, this, (index + 1) % EVENT_CREATURECOUNT))); + g_scheduler().addEvent(createSchedulerTask(EVENT_CHECK_CREATURE_INTERVAL, std::bind(&Game::checkCreatures, this, (index + 1) % EVENT_CREATURECOUNT))); auto& checkCreatureList = checkCreatureLists[index]; size_t it = 0, end = checkCreatureList.size(); @@ -5461,7 +5441,7 @@ void Game::changeSpeed(Creature* creature, int32_t varSpeedDelta) void Game::internalCreatureChangeOutfit(Creature* creature, const Outfit_t& outfit) { - if (!g_events->eventCreatureOnChangeOutfit(creature, outfit)) { + if (!g_events().eventCreatureOnChangeOutfit(creature, outfit)) { return; } @@ -5868,7 +5848,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage message.position = targetPos; if (!isEvent) { - g_events->eventCreatureOnDrainHealth(target, attacker, damage.primary.type, damage.primary.value, damage.secondary.type, damage.secondary.value, message.primary.color, message.secondary.color); + g_events().eventCreatureOnDrainHealth(target, attacker, damage.primary.type, damage.primary.value, damage.secondary.type, damage.secondary.value, message.primary.color, message.secondary.color); } if (damage.origin != ORIGIN_NONE && attacker && damage.primary.type != COMBAT_HEALING) { damage.primary.value *= attacker->getBuff(BUFF_DAMAGEDEALT) / 100.; @@ -5892,7 +5872,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage if (!damage.extension && attacker && attacker->getMonster() && targetPlayer) { // Charm rune (target as player) - MonsterType* mType = g_monsters.getMonsterType(attacker->getName()); + MonsterType* mType = g_monsters().getMonsterType(attacker->getName()); if (mType) { IOBestiary g_bestiary; charmRune_t activeCharm = g_bestiary.getCharmFromTarget(targetPlayer, mType); @@ -6071,7 +6051,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage if (target && target->getMonster()) { uint16_t playerCharmRaceidVamp = attackerPlayer->parseRacebyCharm(CHARM_VAMP, false, 0); if (playerCharmRaceidVamp != 0) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + const MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType && playerCharmRaceidVamp == mType->info.raceid) { IOBestiary g_bestiary; Charm* lifec = g_bestiary.getBestiaryCharm(CHARM_VAMP); @@ -6100,7 +6080,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage if (target && target->getMonster()) { uint16_t playerCharmRaceidVoid = attackerPlayer->parseRacebyCharm(CHARM_VOID, false, 0); if (playerCharmRaceidVoid != 0) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + const MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType && playerCharmRaceidVoid == mType->info.raceid) { IOBestiary g_bestiary; Charm* voidc = g_bestiary.getBestiaryCharm(CHARM_VOID); @@ -6123,7 +6103,7 @@ bool Game::combatChangeHealth(Creature* attacker, Creature* target, CombatDamage //Charm rune (attacker as player) if (!damage.extension && target && target->getMonster()) { - MonsterType* mType = g_monsters.getMonsterType(target->getName()); + MonsterType* mType = g_monsters().getMonsterType(target->getName()); if (mType) { IOBestiary g_bestiary; charmRune_t activeCharm = g_bestiary.getCharmFromTarget(attackerPlayer, mType); @@ -6392,7 +6372,7 @@ bool Game::combatChangeMana(Creature* attacker, Creature* target, CombatDamage& if (targetPlayer && attacker && attacker->getMonster()) { //Charm rune (target as player) - MonsterType* mType = g_monsters.getMonsterType(attacker->getName()); + MonsterType* mType = g_monsters().getMonsterType(attacker->getName()); if (mType) { IOBestiary g_bestiary; charmRune_t activeCharm = g_bestiary.getCharmFromTarget(targetPlayer, mType); @@ -6559,7 +6539,7 @@ void Game::addDistanceEffect(const SpectatorHashSet& spectators, const Position& void Game::checkImbuements() { - g_scheduler.addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_IMBUEMENT_INTERVAL, std::bind(&Game::checkImbuements, this))); std::vector toErase; @@ -6581,7 +6561,7 @@ void Game::checkImbuements() void Game::checkLight() { - g_scheduler.addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); + g_scheduler().addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL_MS, std::bind(&Game::checkLight, this))); lightHour += lightHourDelta; @@ -6637,8 +6617,8 @@ void Game::checkLight() } if (currentLightState != lightState) { currentLightState = lightState; - for (auto& it : g_globalEvents->getEventMap(GLOBALEVENT_PERIODCHANGE)) { - it.second.executePeriodChange(lightState, lightInfo); + for (auto& [key, it] : g_globalEvents().getEventMap(GLOBALEVENT_PERIODCHANGE)) { + it.executePeriodChange(lightState, lightInfo); } } } @@ -6672,9 +6652,9 @@ void Game::shutdown() SPDLOG_INFO("Shutting down..."); - g_scheduler.shutdown(); - g_databaseTasks.shutdown(); - g_dispatcher.shutdown(); + g_scheduler().shutdown(); + g_databaseTasks().shutdown(); + g_dispatcher().shutdown(); map.spawnsMonster.clear(); map.spawnsNpc.clear(); raids.clear(); @@ -6889,8 +6869,8 @@ void Game::checkPlayersRecord() uint32_t previousRecord = playersRecord; playersRecord = playersOnline; - for (auto& it : g_globalEvents->getEventMap(GLOBALEVENT_RECORD)) { - it.second.executeRecord(playersRecord, previousRecord); + for (auto& [key, it] : g_globalEvents().getEventMap(GLOBALEVENT_RECORD)) { + it.executeRecord(playersRecord, previousRecord); } updatePlayersRecord(); } @@ -7140,7 +7120,7 @@ void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, C } while (result->next()); player->sendCyclopediaCharacterRecentDeaths(page, static_cast(pages), entries); }; - g_databaseTasks.addTask(std::move(query.str()), callback, true); + g_databaseTasks().addTask(query.str(), callback, true); player->addAsyncOngoingTask(PlayerAsyncTask_RecentDeaths); break; } @@ -7193,7 +7173,7 @@ void Game::playerCyclopediaCharacterInfo(Player* player, uint32_t characterID, C } while (result->next()); player->sendCyclopediaCharacterRecentPvPKills(page, static_cast(pages), entries); }; - g_databaseTasks.addTask(std::move(query.str()), callback, true); + g_databaseTasks().addTask(query.str(), callback, true); player->addAsyncOngoingTask(PlayerAsyncTask_RecentPvPKills); break; } @@ -7239,7 +7219,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego if (vocation != 0xFFFFFFFF) { bool firstVocation = true; - const auto& vocationsMap = g_vocations.getVocations(); + const auto& vocationsMap = g_vocations().getVocations(); for (const auto& it : vocationsMap) { const Vocation& voc = it.second; if (voc.getFromVocation() == vocation) { @@ -7259,7 +7239,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego if (vocation != 0xFFFFFFFF) { bool firstVocation = true; - const auto& vocationsMap = g_vocations.getVocations(); + const auto& vocationsMap = g_vocations().getVocations(); for (const auto& it : vocationsMap) { const Vocation& voc = it.second; if (voc.getFromVocation() == vocation) { @@ -7297,7 +7277,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego characters.reserve(result->countResults()); do { uint8_t characterVocation; - Vocation* voc = g_vocations.getVocation(result->getNumber("vocation")); + const Vocation* voc = g_vocations().getVocation(result->getNumber("vocation")); if (voc) { characterVocation = voc->getClientId(); } else { @@ -7307,7 +7287,7 @@ void Game::playerHighscores(Player* player, HighscoreType_t type, uint8_t catego } while (result->next()); player->sendHighscores(characters, category, vocation, page, static_cast(pages)); }; - g_databaseTasks.addTask(std::move(query.str()), callback, true); + g_databaseTasks().addTask(query.str(), callback, true); player->addAsyncOngoingTask(PlayerAsyncTask_Highscore); } @@ -7327,7 +7307,7 @@ void Game::playerReportRuleViolationReport(uint32_t playerId, const std::string& return; } - g_events->eventPlayerOnReportRuleViolation(player, targetName, reportType, reportReason, comment, translation); + g_events().eventPlayerOnReportRuleViolation(player, targetName, reportType, reportReason, comment, translation); } void Game::playerReportBug(uint32_t playerId, const std::string& message, const Position& position, uint8_t category) @@ -7337,7 +7317,7 @@ void Game::playerReportBug(uint32_t playerId, const std::string& message, const return; } - g_events->eventPlayerOnReportBug(player, message, position, category); + g_events().eventPlayerOnReportBug(player, message, position, category); } void Game::playerDebugAssert(uint32_t playerId, const std::string& assertLine, const std::string& date, const std::string& description, const std::string& comment) @@ -8117,11 +8097,11 @@ void Game::playerBuyStoreOffer(uint32_t playerId, uint32_t offerId, // check if it's an NPC or Monster name. - if (g_monsters.getMonsterType(newName)) { + if (g_monsters().getMonsterType(newName)) { responseMessage = "Your new name cannot be a monster's name."; player -> sendStoreError(STORE_ERROR_PURCHASE, responseMessage); return; - } else if (g_npcs.getNpcType(newName)) { + } else if (g_npcs().getNpcType(newName)) { responseMessage = "Your new name cannot be an NPC's name."; player -> sendStoreError(STORE_ERROR_PURCHASE, responseMessage); return; @@ -8185,7 +8165,7 @@ void Game::playerBuyStoreOffer(uint32_t playerId, uint32_t offerId, return; } else if (offer -> type == PROMOTION) { if (player -> isPremium() && !player -> isPromoted()) { - uint16_t promotedId = g_vocations.getPromotedVocation(player -> getVocation() -> getId()); + uint16_t promotedId = g_vocations().getPromotedVocation(player -> getVocation() -> getId()); if (promotedId == VOCATION_NONE || promotedId == player -> getVocation() -> getId()) { player -> sendStoreError(STORE_ERROR_PURCHASE, "Your character cannot be promoted."); @@ -8613,44 +8593,44 @@ bool Game::reload(ReloadTypes_t reloadType) { switch (reloadType) { case RELOAD_TYPE_MONSTERS: { - g_scripts->loadScripts("monster", false, true); + g_scripts().loadScripts("monster", false, true); return true; } case RELOAD_TYPE_NPCS: { // Reset informations from npc interface g_npc().reset(); // Reload npc scripts - g_scripts->loadScripts("npc", false, true); + g_scripts().loadScripts("npc", false, true); // Reload npclib g_luaEnvironment.loadFile("data/npclib/load.lua"); return true; } - case RELOAD_TYPE_CHAT: return g_chat->load(); + case RELOAD_TYPE_CHAT: return g_chat().load(); case RELOAD_TYPE_CONFIG: return g_configManager().reload(); - case RELOAD_TYPE_EVENTS: return g_events->loadFromXml(); + case RELOAD_TYPE_EVENTS: return g_events().loadFromXml(); case RELOAD_TYPE_ITEMS: return Item::items.reload(); - case RELOAD_TYPE_MODULES: return g_modules->reload(); + case RELOAD_TYPE_MODULES: return g_modules().reload(); case RELOAD_TYPE_MOUNTS: return mounts.reload(); - case RELOAD_TYPE_IMBUEMENTS: return g_imbuements->reload(); + case RELOAD_TYPE_IMBUEMENTS: return g_imbuements().reload(); case RELOAD_TYPE_RAIDS: return raids.reload() && raids.startup(); case RELOAD_TYPE_SCRIPTS: { // commented out stuff is TODO, once we approach further in revscriptsys - g_actions->clear(true); - g_creatureEvents->clear(true); - g_moveEvents->clear(true); - g_talkActions->clear(true); - g_globalEvents->clear(true); - g_weapons->clear(true); - g_weapons->loadDefaults(); - g_spells->clear(true); + g_actions().clear(true); + g_creatureEvents().clear(true); + g_moveEvents().clear(true); + g_talkActions().clear(true); + g_globalEvents().clear(true); + g_weapons().clear(true); + g_weapons().loadDefaults(); + g_spells().clear(true); // Reset informations from npc interface g_npc().reset(); - g_scripts->loadScripts("scripts", false, true); + g_scripts().loadScripts("scripts", false, true); // lean up the monsters interface, ensuring that after reloading the scripts there is no use of any deallocated memory - g_scripts->loadScripts("monster", false, true); + g_scripts().loadScripts("monster", false, true); // Reload npc scripts - g_scripts->loadScripts("npc", false, true); + g_scripts().loadScripts("npc", false, true); // Reload npclib g_luaEnvironment.loadFile("data/npclib/load.lua"); return true; @@ -8661,18 +8641,18 @@ bool Game::reload(ReloadTypes_t reloadType) g_configManager().reload(); raids.reload() && raids.startup(); Item::items.reload(); - g_weapons->clear(true); - g_weapons->loadDefaults(); + g_weapons().clear(true); + g_weapons().loadDefaults(); mounts.reload(); - g_events->loadFromXml(); - g_chat->load(); - g_actions->clear(true); - g_creatureEvents->clear(true); - g_moveEvents->clear(true); - g_talkActions->clear(true); - g_globalEvents->clear(true); - g_spells->clear(true); - g_scripts->loadScripts("scripts", false, true); + g_events().loadFromXml(); + g_chat().load(); + g_actions().clear(true); + g_creatureEvents().clear(true); + g_moveEvents().clear(true); + g_talkActions().clear(true); + g_globalEvents().clear(true); + g_spells().clear(true); + g_scripts().loadScripts("scripts", false, true); } } return true; @@ -8680,7 +8660,7 @@ bool Game::reload(ReloadTypes_t reloadType) bool Game::itemidHasMoveevent(uint32_t itemid) { - return g_moveEvents->isRegistered(itemid); + return g_moveEvents().isRegistered(itemid); } bool Game::hasEffect(uint8_t effectId) { diff --git a/src/game/game.h b/src/game/game.h index 01f470d2f1f..b49a20f7df6 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -340,7 +340,7 @@ class Game void playerRequestAddVip(uint32_t playerId, const std::string& name); void playerRequestRemoveVip(uint32_t playerId, uint32_t guid); void playerRequestEditVip(uint32_t playerId, uint32_t guid, const std::string& description, uint32_t icon, bool notify); - void playerApplyImbuement(uint32_t playerId, uint32_t imbuementid, uint8_t slot, bool protectionCharm); + void playerApplyImbuement(uint32_t playerId, uint16_t imbuementid, uint8_t slot, bool protectionCharm); void playerClearImbuement(uint32_t playerid, uint8_t slot); void playerCloseImbuementWindow(uint32_t playerid); void playerTurn(uint32_t playerId, Direction dir); diff --git a/src/game/scheduling/scheduler.cpp b/src/game/scheduling/scheduler.cpp index 6d1467fb103..7687070dc5e 100644 --- a/src/game/scheduling/scheduler.cpp +++ b/src/game/scheduling/scheduler.cpp @@ -51,7 +51,7 @@ void Scheduler::threadMain() eventLockUnique.unlock(); task->setDontExpire(); - g_dispatcher.addTask(task, true); + g_dispatcher().addTask(task, true); } else { eventLockUnique.unlock(); } diff --git a/src/game/scheduling/scheduler.h b/src/game/scheduling/scheduler.h index 89ec6183c8b..52b7774d4b9 100644 --- a/src/game/scheduling/scheduler.h +++ b/src/game/scheduling/scheduler.h @@ -61,6 +61,18 @@ struct TaskComparator { class Scheduler : public ThreadHolder { public: + Scheduler() = default; + + Scheduler(Scheduler const&) = delete; + void operator=(Scheduler const&) = delete; + + static Scheduler& getInstance() { + // Guaranteed to be destroyed + static Scheduler instance; + // Instantiated on first use + return instance; + } + uint32_t addEvent(SchedulerTask* task); bool stopEvent(uint32_t eventId); @@ -78,6 +90,6 @@ class Scheduler : public ThreadHolder std::unordered_set eventIds; }; -extern Scheduler g_scheduler; +constexpr auto g_scheduler = &Scheduler::getInstance; #endif // SRC_GAME_SCHEDULING_SCHEDULER_H_ diff --git a/src/game/scheduling/tasks.h b/src/game/scheduling/tasks.h index da424e00560..0a62e9d4398 100644 --- a/src/game/scheduling/tasks.h +++ b/src/game/scheduling/tasks.h @@ -67,6 +67,18 @@ Task* createTask(uint32_t expiration, std::function f); class Dispatcher : public ThreadHolder { public: + Dispatcher() = default; + + Dispatcher(Dispatcher const&) = delete; + void operator=(Dispatcher const&) = delete; + + static Dispatcher& getInstance() { + // Guaranteed to be destroyed + static Dispatcher instance; + // Instantiated on first use + return instance; + } + void addTask(Task* task, bool push_front = false); void shutdown(); @@ -85,6 +97,6 @@ class Dispatcher : public ThreadHolder { uint64_t dispatcherCycle = 0; }; -extern Dispatcher g_dispatcher; +constexpr auto g_dispatcher = &Dispatcher::getInstance; #endif // SRC_GAME_SCHEDULING_TASKS_H_ diff --git a/src/io/iobestiary.cpp b/src/io/iobestiary.cpp index 782da99462b..5f3971d8d9e 100644 --- a/src/io/iobestiary.cpp +++ b/src/io/iobestiary.cpp @@ -26,7 +26,6 @@ #include "creatures/monsters/monsters.h" #include "creatures/players/player.h" -extern Monsters g_monsters; bool IOBestiary::parseCharmCombat(Charm* charm, Player* player, Creature* target, int32_t realDamage) { @@ -127,14 +126,14 @@ std::map IOBestiary::findRaceByName(const std::string &ra if (Onlystring) { for (auto it : best_list) { - MonsterType* tmpType = g_monsters.getMonsterType(it.second); + const MonsterType* tmpType = g_monsters().getMonsterType(it.second); if (tmpType && tmpType->info.bestiaryClass == race) { race_list.insert({it.first, it.second}); } } } else { for (auto itn : best_list) { - MonsterType* tmpType = g_monsters.getMonsterType(itn.second); + const MonsterType* tmpType = g_monsters().getMonsterType(itn.second); if (tmpType && tmpType->info.bestiaryRace == raceNumber) { race_list.insert({itn.first, itn.second}); } @@ -203,7 +202,7 @@ uint16_t IOBestiary::getBestiaryRaceUnlocked(Player* player, BestiaryType_t race std::map besty_l = g_game().getBestiaryList(); for (auto it : besty_l) { - MonsterType* mtype = g_monsters.getMonsterType(it.second); + const MonsterType* mtype = g_monsters().getMonsterType(it.second); if (mtype && mtype->info.bestiaryRace == race && player->getBestiaryKillCount(mtype->info.raceid) > 0) { count++; } @@ -427,7 +426,7 @@ std::list IOBestiary::getBestiaryFinished(Player* player) const for (auto nt : besty_l) { uint16_t raceid = nt.first; uint32_t thisKilled = player->getBestiaryKillCount(raceid); - MonsterType* mtype = g_monsters.getMonsterType(nt.second); + const MonsterType* mtype = g_monsters().getMonsterType(nt.second); if (mtype && thisKilled >= mtype->info.bestiaryToUnlock) { finishedMonsters.push_front(raceid); } diff --git a/src/io/iologindata.cpp b/src/io/iologindata.cpp index ef5901207f0..12302efe0cd 100644 --- a/src/io/iologindata.cpp +++ b/src/io/iologindata.cpp @@ -27,7 +27,6 @@ #include -extern Monsters g_monsters; bool IOLoginData::authenticateAccountPassword(const std::string& email, const std::string& password, account::Account *account) { if (account::ERROR_NO != account->LoadAccountDB(email)) { @@ -523,7 +522,7 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) uint16_t raceid_t; while (propBestStream.read(raceid_t)) { - MonsterType* tmp_tt = g_monsters.getMonsterTypeByRaceId(raceid_t); + MonsterType* tmp_tt = g_monsters().getMonsterTypeByRaceId(raceid_t); if (tmp_tt) { player->addBestiaryTrackerList(tmp_tt); } diff --git a/src/io/iomarket.cpp b/src/io/iomarket.cpp index 822beac17d7..d8b3b1782ec 100644 --- a/src/io/iomarket.cpp +++ b/src/io/iomarket.cpp @@ -193,14 +193,14 @@ void IOMarket::checkExpiredOffers() std::ostringstream query; query << "SELECT `id`, `amount`, `price`, `itemtype`, `player_id`, `sale` FROM `market_offers` WHERE `created` <= " << lastExpireDate; - g_databaseTasks.addTask(query.str(), IOMarket::processExpiredOffers, true); + g_databaseTasks().addTask(query.str(), IOMarket::processExpiredOffers, true); int32_t checkExpiredMarketOffersEachMinutes = g_configManager().getNumber(CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES); if (checkExpiredMarketOffersEachMinutes <= 0) { return; } - g_scheduler.addEvent(createSchedulerTask(checkExpiredMarketOffersEachMinutes * 60 * 1000, IOMarket::checkExpiredOffers)); + g_scheduler().addEvent(createSchedulerTask(checkExpiredMarketOffersEachMinutes * 60 * 1000, IOMarket::checkExpiredOffers)); } uint32_t IOMarket::getPlayerOfferCount(uint32_t playerId) @@ -273,7 +273,7 @@ void IOMarket::appendHistory(uint32_t playerId, MarketAction_t type, uint16_t it query << "INSERT INTO `market_history` (`player_id`, `sale`, `itemtype`, `amount`, `price`, `expires_at`, `inserted`, `state`) VALUES (" << playerId << ',' << type << ',' << itemId << ',' << amount << ',' << price << ',' << timestamp << ',' << time(nullptr) << ',' << state << ')'; - g_databaseTasks.addTask(query.str()); + g_databaseTasks().addTask(query.str()); } bool IOMarket::moveOfferToHistory(uint32_t offerId, MarketOfferState_t state) diff --git a/src/items/bed.cpp b/src/items/bed.cpp index 177f36f1a88..020f91b4b6d 100644 --- a/src/items/bed.cpp +++ b/src/items/bed.cpp @@ -162,7 +162,7 @@ bool BedItem::sleep(Player* player) g_game().addMagicEffect(player->getPosition(), CONST_ME_SLEEP); // logout player after he sees himself walk onto the bed and it change id - g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&ProtocolGame::logout, player->client, false, false))); + g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&ProtocolGame::logout, player->client, false, false))); // change self and partner's appearance updateAppearance(player); diff --git a/src/items/containers/container.cpp b/src/items/containers/container.cpp index 6b37b7a4ad8..5ea4cf108b0 100644 --- a/src/items/containers/container.cpp +++ b/src/items/containers/container.cpp @@ -682,9 +682,9 @@ void Container::removeThing(Thing* thing, uint32_t count) } } -int32_t Container::getThingIndex(const Thing* thing) const +uint8_t Container::getThingIndex(const Thing* thing) const { - int32_t index = 0; + uint8_t index = 0; for (Item* item : itemlist) { if (item == thing) { return index; @@ -792,17 +792,17 @@ void Container::internalAddThing(uint32_t, Thing* thing) void Container::startDecaying() { - g_decay.startDecay(this); + g_decay().startDecay(this); for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { - g_decay.startDecay(*it); + g_decay().startDecay(*it); } } void Container::stopDecaying() { - g_decay.stopDecay(this); + g_decay().stopDecay(this); for (ContainerIterator it = iterator(); it.hasNext(); it.advance()) { - g_decay.stopDecay(*it); + g_decay().stopDecay(*it); } } diff --git a/src/items/containers/container.h b/src/items/containers/container.h index 59e573dcd8c..eec9268ef1d 100644 --- a/src/items/containers/container.h +++ b/src/items/containers/container.h @@ -155,7 +155,7 @@ class Container : public Item, public Cylinder void removeThing(Thing* thing, uint32_t count) override final; - int32_t getThingIndex(const Thing* thing) const override final; + uint8_t getThingIndex(const Thing* thing) const override final; size_t getFirstIndex() const override final; size_t getLastIndex() const override final; uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override final; diff --git a/src/items/cylinder.cpp b/src/items/cylinder.cpp index 0081a1e141c..f759a242597 100644 --- a/src/items/cylinder.cpp +++ b/src/items/cylinder.cpp @@ -23,7 +23,7 @@ VirtualCylinder* VirtualCylinder::virtualCylinder = new VirtualCylinder; -int32_t Cylinder::getThingIndex(const Thing*) const +uint8_t Cylinder::getThingIndex(const Thing*) const { return -1; } diff --git a/src/items/cylinder.h b/src/items/cylinder.h index 280a928477f..9fe81236dda 100644 --- a/src/items/cylinder.h +++ b/src/items/cylinder.h @@ -136,7 +136,7 @@ class Cylinder : virtual public Thing * \param thing the object to get the index value from * \returns the index of the object, returns -1 if not found */ - virtual int32_t getThingIndex(const Thing* thing) const; + virtual uint8_t getThingIndex(const Thing* thing) const; /** * Returns the first index diff --git a/src/items/decay/decay.cpp b/src/items/decay/decay.cpp index 70f6126413b..cdee82f1ab1 100644 --- a/src/items/decay/decay.cpp +++ b/src/items/decay/decay.cpp @@ -23,7 +23,6 @@ #include "game/game.h" #include "game/scheduling/scheduler.h" -Decay g_decay; void Decay::startDecay(Item* item) { @@ -41,7 +40,7 @@ void Decay::startDecay(Item* item) return; } - int64_t duration = item->getIntAttr(ITEM_ATTRIBUTE_DURATION); + const int64_t duration = item->getIntAttr(ITEM_ATTRIBUTE_DURATION); if (duration <= 0 && item->hasAttribute(ITEM_ATTRIBUTE_DURATION)) { internalDecayItem(item); return; @@ -52,13 +51,13 @@ void Decay::startDecay(Item* item) stopDecay(item); } - int64_t timestamp = OTSYS_TIME() + static_cast(duration); + int64_t timestamp = OTSYS_TIME() + duration; if (decayMap.empty()) { - eventId = g_scheduler.addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); + eventId = g_scheduler().addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); } else { if (timestamp < decayMap.begin()->first) { - g_scheduler.stopEvent(eventId); - eventId = g_scheduler.addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); + g_scheduler().stopEvent(eventId); + eventId = g_scheduler().addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, duration), std::bind(&Decay::checkDecay, this))); } } @@ -147,7 +146,7 @@ void Decay::checkDecay() } if (it != end) { - eventId = g_scheduler.addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, static_cast(it->first - timestamp)), std::bind(&Decay::checkDecay, this))); + eventId = g_scheduler().addEvent(createSchedulerTask(std::max(SCHEDULER_MINTICKS, static_cast(it->first - timestamp)), std::bind(&Decay::checkDecay, this))); } } diff --git a/src/items/decay/decay.h b/src/items/decay/decay.h index cdcbcd0ebc2..f0d7c88c9ce 100644 --- a/src/items/decay/decay.h +++ b/src/items/decay/decay.h @@ -25,17 +25,29 @@ class Decay { public: + Decay(Decay const&) = delete; + void operator=(Decay const&) = delete; + + static Decay& getInstance() { + // Guaranteed to be destroyed + static Decay instance; + // Instantiated on first use + return instance; + } + void startDecay(Item* item); void stopDecay(Item* item); private: + Decay() = default; + void checkDecay(); void internalDecayItem(Item* item); - uint64_t eventId {0}; + uint32_t eventId {0}; std::map> decayMap; }; -extern Decay g_decay; +constexpr auto g_decay = &Decay::getInstance; #endif // SRC_ITEMS_DECAY_DECAY_H_ diff --git a/src/items/item.cpp b/src/items/item.cpp index 6401907ca98..bdb6cfee6a9 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -37,9 +37,6 @@ #define IMBUEMENT_SLOT 500 -extern Spells* g_spells; -extern Vocations g_vocations; -extern Imbuements* g_imbuements; Items Item::items; @@ -94,7 +91,7 @@ bool Item::getImbuementInfo(uint8_t slot, ImbuementInfo *imbuementInfo) { const ItemAttributes::CustomAttribute* attribute = getCustomAttribute(IMBUEMENT_SLOT + slot); uint32_t info = attribute ? static_cast(attribute->getInt()) : 0; - imbuementInfo->imbuement = g_imbuements->getImbuement(info & 0xFF); + imbuementInfo->imbuement = g_imbuements().getImbuement(info & 0xFF); imbuementInfo->duration = info >> 8; return imbuementInfo->duration && imbuementInfo->imbuement; } @@ -115,13 +112,13 @@ void Item::addImbuement(uint8_t slot, uint16_t imbuementId, int32_t duration) } // Get imbuement by the id - const Imbuement *imbuement = g_imbuements->getImbuement(imbuementId); + const Imbuement *imbuement = g_imbuements().getImbuement(imbuementId); if (!imbuement) { return; } // Get category imbuement for acess category id - const CategoryImbuement* categoryImbuement = g_imbuements->getCategoryByID(imbuement->getCategory()); + const CategoryImbuement* categoryImbuement = g_imbuements().getCategoryByID(imbuement->getCategory()); if (!hasImbuementType(static_cast(categoryImbuement->id), imbuement->getBaseID())) { return; } @@ -140,7 +137,7 @@ bool Item::hasImbuementCategoryId(uint16_t categoryId) { for (uint8_t slotid = 0; slotid < getImbuementSlot(); slotid++) { ImbuementInfo imbuementInfo; if (getImbuementInfo(slotid, &imbuementInfo)) { - const CategoryImbuement* categoryImbuement = g_imbuements->getCategoryByID(imbuementInfo.imbuement->getCategory()); + const CategoryImbuement* categoryImbuement = g_imbuements().getCategoryByID(imbuementInfo.imbuement->getCategory()); if (categoryImbuement->id == categoryId) { return true; } @@ -1479,7 +1476,7 @@ std::string Item::parseImbuementDescription(const Item* item) continue; } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuementInfo.imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuementInfo.imbuement->getBaseID()); if (!baseImbuement) { continue; @@ -1513,7 +1510,7 @@ std::string Item::getDescription(const ItemType& it, int32_t lookDistance, if (it.isRune()) { if (it.runeLevel > 0 || it.runeMagLevel > 0) { - if (RuneSpell* rune = g_spells->getRuneSpell(it.id)) { + if (const RuneSpell* rune = g_spells().getRuneSpell(it.id)) { int32_t tmpSubType = subType; if (item) { tmpSubType = item->getSubType(); @@ -1528,7 +1525,7 @@ std::string Item::getDescription(const ItemType& it, int32_t lookDistance, showVocMap.reserve(vocMap.size() / 2); for (const auto& voc : vocMap) { if (voc.second) { - showVocMap.push_back(g_vocations.getVocation(voc.first)); + showVocMap.push_back(g_vocations().getVocation(voc.first)); } } @@ -2559,12 +2556,12 @@ ItemAttributes::Attribute& ItemAttributes::getAttr(ItemAttrTypes type) void Item::startDecaying() { - g_decay.startDecay(this); + g_decay().startDecay(this); } void Item::stopDecaying() { - g_decay.stopDecay(this); + g_decay().stopDecay(this); } bool Item::hasMarketAttributes() diff --git a/src/items/items.cpp b/src/items/items.cpp index 07332658a58..7f12c28e300 100644 --- a/src/items/items.cpp +++ b/src/items/items.cpp @@ -34,7 +34,6 @@ namespace fs = std::filesystem; namespace fs = boost::filesystem; #endif -extern Weapons* g_weapons; Items::Items(){} @@ -93,7 +92,7 @@ bool Items::reload() return false; } - g_weapons->loadDefaults(); + g_weapons().loadDefaults(); return true; } diff --git a/src/items/tile.cpp b/src/items/tile.cpp index 0d0a2b99e87..b55ce822eb3 100644 --- a/src/items/tile.cpp +++ b/src/items/tile.cpp @@ -34,7 +34,6 @@ #include "map/house/housetile.h" #include "io/iomap.h" -extern MoveEvents* g_moveEvents; StaticTile real_nullptr_tile(0xFFFF, 0xFFFF, 0xFF); Tile& Tile::nullptr_tile = real_nullptr_tile; @@ -1167,9 +1166,9 @@ void Tile::removeCreature(Creature* creature) removeThing(creature, 0); } -int32_t Tile::getThingIndex(const Thing* thing) const +uint8_t Tile::getThingIndex(const Thing* thing) const { - int32_t n = -1; + uint8_t n = -1; if (ground) { if (ground == thing) { return 0; @@ -1427,9 +1426,9 @@ void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t //calling movement scripts if (creature) { - g_moveEvents->onCreatureMove(creature, this, MOVE_EVENT_STEP_IN); + g_moveEvents().onCreatureMove(creature, this, MOVE_EVENT_STEP_IN); } else if (item) { - g_moveEvents->onItemMove(item, this, true); + g_moveEvents().onItemMove(item, this, true); } } @@ -1457,11 +1456,11 @@ void Tile::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32 //calling movement scripts Creature* creature = thing->getCreature(); if (creature) { - g_moveEvents->onCreatureMove(creature, this, MOVE_EVENT_STEP_OUT); + g_moveEvents().onCreatureMove(creature, this, MOVE_EVENT_STEP_OUT); } else { Item* item = thing->getItem(); if (item) { - g_moveEvents->onItemMove(item, this, false); + g_moveEvents().onItemMove(item, this, false); } } } diff --git a/src/items/tile.h b/src/items/tile.h index 63a9b2e0849..e903d262c1d 100644 --- a/src/items/tile.h +++ b/src/items/tile.h @@ -221,7 +221,7 @@ class Tile : public Cylinder void removeCreature(Creature* creature); - int32_t getThingIndex(const Thing* thing) const override final; + uint8_t getThingIndex(const Thing* thing) const override final; size_t getFirstIndex() const override final; size_t getLastIndex() const override final; uint32_t getItemTypeCount(uint16_t itemId, int32_t subType = -1) const override final; diff --git a/src/items/weapons/weapons.cpp b/src/items/weapons/weapons.cpp index e2176237b02..c2b6fe6b9ed 100644 --- a/src/items/weapons/weapons.cpp +++ b/src/items/weapons/weapons.cpp @@ -25,9 +25,6 @@ #include "lua/creature/events.h" #include "items/weapons/weapons.h" -extern Vocations g_vocations; -extern Weapons* g_weapons; -extern Events* g_events; Weapons::Weapons() { @@ -217,10 +214,10 @@ bool Weapon::configureEvent(const pugi::xml_node& node) continue; } - int32_t vocationId = g_vocations.getVocationId(attr.as_string()); + uint16_t vocationId = g_vocations().getVocationId(attr.as_string()); if (vocationId != -1) { vocWeaponMap[vocationId] = true; - int32_t promotedVocation = g_vocations.getPromotedVocation(vocationId); + int32_t promotedVocation = g_vocations().getPromotedVocation(vocationId); if (promotedVocation != VOCATION_NONE) { vocWeaponMap[promotedVocation] = true; } @@ -702,7 +699,7 @@ bool WeaponDistance::useWeapon(Player* player, Item* item, Creature* target) con const ItemType& it = Item::items[id]; if (it.weaponType == WEAPON_AMMO) { Item* mainWeaponItem = player->getWeapon(true); - const Weapon* mainWeapon = g_weapons->getWeapon(mainWeaponItem); + const Weapon* mainWeapon = g_weapons().getWeapon(mainWeaponItem); if (mainWeapon) { damageModifier = mainWeapon->playerWeaponCheck(player, target, mainWeaponItem->getShootRange()); } else { diff --git a/src/items/weapons/weapons.h b/src/items/weapons/weapons.h index c5c2d28a51a..fdfa70735b4 100644 --- a/src/items/weapons/weapons.h +++ b/src/items/weapons/weapons.h @@ -27,7 +27,6 @@ #include "utils/utils_definitions.hpp" #include "creatures/players/vocations/vocation.h" -extern Vocations g_vocations; class Weapon; class WeaponMelee; @@ -46,6 +45,13 @@ class Weapons final : public BaseEvents Weapons(const Weapons&) = delete; Weapons& operator=(const Weapons&) = delete; + static Weapons& getInstance() { + // Guaranteed to be destroyed + static Weapons instance; + // Instantiated on first use + return instance; + } + void loadDefaults(); const Weapon* getWeapon(const Item* item) const; @@ -66,6 +72,8 @@ class Weapons final : public BaseEvents LuaScriptInterface scriptInterface { "Weapon Interface" }; }; +constexpr auto g_weapons = &Weapons::getInstance; + class Weapon : public Event { public: @@ -181,7 +189,7 @@ class Weapon : public Event } void addVocWeaponMap(std::string vocName) { - int32_t vocationId = g_vocations.getVocationId(vocName); + int32_t vocationId = g_vocations().getVocationId(vocName); if (vocationId != -1) { vocWeaponMap[vocationId] = true; } diff --git a/src/lua/creature/actions.cpp b/src/lua/creature/actions.cpp index 907f3d8d019..981a2d9536e 100644 --- a/src/lua/creature/actions.cpp +++ b/src/lua/creature/actions.cpp @@ -27,8 +27,6 @@ #include "creatures/combat/spells.h" #include "items/containers/rewards/rewardchest.h" -extern Spells* g_spells; -extern Actions* g_actions; Actions::Actions() : scriptInterface("Action Interface") { @@ -404,7 +402,7 @@ Action* Actions::getAction(const Item* item) { } //rune items - return g_spells->getRuneSpell(item->getID()); + return g_spells().getRuneSpell(item->getID()); } ReturnValue Actions::internalUseItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey) { @@ -638,10 +636,10 @@ std::string Action::getScriptEventName() const { ReturnValue Action::canExecuteAction(const Player* player, const Position& toPos) { if (!allowFarUse) { - return g_actions->canUse(player, toPos); + return g_actions().canUse(player, toPos); } - return g_actions->canUseFar(player, toPos, checkLineOfSight, checkFloor); + return g_actions().canUseFar(player, toPos, checkLineOfSight, checkFloor); } Thing* Action::getTarget(Player* player, Creature* targetCreature, diff --git a/src/lua/creature/actions.h b/src/lua/creature/actions.h index 58233cba034..5b677721b0a 100644 --- a/src/lua/creature/actions.h +++ b/src/lua/creature/actions.h @@ -141,6 +141,13 @@ class Actions final : public BaseEvents { Actions(const Actions&) = delete; Actions& operator=(const Actions&) = delete; + static Actions& getInstance() { + // Guaranteed to be destroyed + static Actions instance; + // Instantiated on first use + return instance; + } + bool useItem(Player* player, const Position& pos, uint8_t index, Item* item, bool isHotkey); bool useItemEx(Player* player, const Position& fromPos, const Position& toPos, uint8_t toStackPos, Item* item, bool isHotkey, Creature* creature = nullptr); @@ -235,4 +242,6 @@ class Actions final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_actions = &Actions::getInstance; + #endif // SRC_LUA_CREATURE_ACTIONS_H_ diff --git a/src/lua/creature/creatureevent.h b/src/lua/creature/creatureevent.h index 521df2da766..bc66cc1686f 100644 --- a/src/lua/creature/creatureevent.h +++ b/src/lua/creature/creatureevent.h @@ -86,6 +86,13 @@ class CreatureEvents final : public BaseEvents { CreatureEvents(const CreatureEvents&) = delete; CreatureEvents& operator=(const CreatureEvents&) = delete; + static CreatureEvents& getInstance() { + // Guaranteed to be destroyed + static CreatureEvents instance; + // Instantiated on first use + return instance; + } + // global events bool playerLogin(Player* player) const; bool playerLogout(Player* player) const; @@ -110,4 +117,6 @@ class CreatureEvents final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_creatureEvents = &CreatureEvents::getInstance; + #endif // SRC_LUA_CREATURE_CREATUREEVENT_H_ diff --git a/src/lua/creature/events.h b/src/lua/creature/events.h index d4283f71f90..5b908071755 100644 --- a/src/lua/creature/events.h +++ b/src/lua/creature/events.h @@ -77,10 +77,22 @@ class Events { }; public: + Events(); bool loadFromXml(); + // non-copyable + Events(Events const&) = delete; + void operator=(Events const&) = delete; + + static Events& getInstance() { + // Guaranteed to be destroyed + static Events instance; + // Instantiated on first use + return instance; + } + // Creature bool eventCreatureOnChangeOutfit(Creature* creature, const Outfit_t& outfit); ReturnValue eventCreatureOnAreaCombat(Creature* creature, Tile* tile, bool aggressive); @@ -130,4 +142,6 @@ class Events { EventsInfo info; }; +constexpr auto g_events = &Events::getInstance; + #endif // SRC_LUA_CREATURE_EVENTS_H_ diff --git a/src/lua/creature/movement.cpp b/src/lua/creature/movement.cpp index 202c517439c..7ef6bc29b67 100644 --- a/src/lua/creature/movement.cpp +++ b/src/lua/creature/movement.cpp @@ -27,9 +27,6 @@ #include "lua/creature/movement.h" #include "creatures/players/imbuements/imbuements.h" -extern Vocations g_vocations; -extern Events* g_events; -extern Imbuements* g_imbuements; MoveEvents::MoveEvents() : scriptInterface("MoveEvents Interface") { @@ -596,7 +593,7 @@ bool MoveEvent::configureEvent(const pugi::xml_node& node) { continue; } - int32_t vocationId = g_vocations.getVocationId(vocationNameAttribute.as_string()); + int32_t vocationId = g_vocations().getVocationId(vocationNameAttribute.as_string()); if (vocationId != -1) { vocEquipMap[vocationId] = true; if (vocationNode.attribute("showInDescription").as_bool(true)) { diff --git a/src/lua/creature/movement.h b/src/lua/creature/movement.h index 2b3dd5a755c..815c10fd787 100644 --- a/src/lua/creature/movement.h +++ b/src/lua/creature/movement.h @@ -26,7 +26,6 @@ #include "lua/functions/events/move_event_functions.hpp" #include "creatures/players/vocations/vocation.h" -extern Vocations g_vocations; class MoveEvent; using MoveEvent_ptr = std::unique_ptr; @@ -46,6 +45,13 @@ class MoveEvents final : public BaseEvents { MoveEvents(const MoveEvents&) = delete; MoveEvents& operator=(const MoveEvents&) = delete; + static MoveEvents& getInstance() { + // Guaranteed to be destroyed + static MoveEvents instance; + // Instantiated on first use + return instance; + } + uint32_t onCreatureMove(Creature* creature, const Tile* tile, MoveEvent_t eventType); uint32_t onPlayerEquip(Player* player, Item* item, Slots_t slot, bool isCheck); uint32_t onPlayerDeEquip(Player* player, Item* item, Slots_t slot); @@ -85,6 +91,8 @@ class MoveEvents final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_moveEvents = &MoveEvents::getInstance; + using StepFunction = std::function; using MoveFunction = std::function; using EquipFunction = std::function; @@ -136,7 +144,7 @@ class MoveEvent final : public Event { return vocEquipMap; } void addVocEquipMap(std::string vocName) { - int32_t vocationId = g_vocations.getVocationId(vocName); + int32_t vocationId = g_vocations().getVocationId(vocName); if (vocationId != -1) { vocEquipMap[vocationId] = true; } diff --git a/src/lua/creature/raids.cpp b/src/lua/creature/raids.cpp index aad71191b34..0e815095bfe 100644 --- a/src/lua/creature/raids.cpp +++ b/src/lua/creature/raids.cpp @@ -119,7 +119,7 @@ bool Raids::startup() { setLastRaidEnd(OTSYS_TIME()); - checkRaidsEvent = g_scheduler.addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); + checkRaidsEvent = g_scheduler().addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); started = true; return started; @@ -145,11 +145,11 @@ void Raids::checkRaids() { } } - checkRaidsEvent = g_scheduler.addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); + checkRaidsEvent = g_scheduler().addEvent(createSchedulerTask(CHECK_RAIDS_INTERVAL * 1000, std::bind(&Raids::checkRaids, this))); } void Raids::clear() { - g_scheduler.stopEvent(checkRaidsEvent); + g_scheduler().stopEvent(checkRaidsEvent); checkRaidsEvent = 0; for (Raid* raid : raidList) { @@ -234,7 +234,7 @@ void Raid::startRaid() { RaidEvent* raidEvent = getNextRaidEvent(); if (raidEvent) { state = RAIDSTATE_EXECUTING; - nextEventEvent = g_scheduler.addEvent(createSchedulerTask(raidEvent->getDelay(), std::bind(&Raid::executeRaidEvent, this, raidEvent))); + nextEventEvent = g_scheduler().addEvent(createSchedulerTask(raidEvent->getDelay(), std::bind(&Raid::executeRaidEvent, this, raidEvent))); } } @@ -245,7 +245,7 @@ void Raid::executeRaidEvent(RaidEvent* raidEvent) { if (newRaidEvent) { uint32_t ticks = static_cast(std::max(RAID_MINTICKS, newRaidEvent->getDelay() - raidEvent->getDelay())); - nextEventEvent = g_scheduler.addEvent(createSchedulerTask(ticks, std::bind(&Raid::executeRaidEvent, this, newRaidEvent))); + nextEventEvent = g_scheduler().addEvent(createSchedulerTask(ticks, std::bind(&Raid::executeRaidEvent, this, newRaidEvent))); } else { resetRaid(); } @@ -263,7 +263,7 @@ void Raid::resetRaid() { void Raid::stopEvents() { if (nextEventEvent != 0) { - g_scheduler.stopEvent(nextEventEvent); + g_scheduler().stopEvent(nextEventEvent); nextEventEvent = 0; } } diff --git a/src/lua/creature/talkaction.h b/src/lua/creature/talkaction.h index cebb49ab37d..79a62d38b60 100644 --- a/src/lua/creature/talkaction.h +++ b/src/lua/creature/talkaction.h @@ -72,6 +72,13 @@ class TalkActions final : public BaseEvents { TalkActions(const TalkActions&) = delete; TalkActions& operator=(const TalkActions&) = delete; + static TalkActions& getInstance() { + // Guaranteed to be destroyed + static TalkActions instance; + // Instantiated on first use + return instance; + } + TalkActionResult_t playerSaySpell(Player* player, SpeakClasses type, const std::string& words) const; bool registerLuaEvent(TalkAction* event); @@ -88,4 +95,6 @@ class TalkActions final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_talkActions = &TalkActions::getInstance; + #endif // SRC_LUA_CREATURE_TALKACTION_H_ diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 7714ab76ea4..e4dc459a8e3 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -30,19 +30,17 @@ #include "lua/functions/creatures/npc/npc_type_functions.hpp" #include "lua/scripts/scripts.h" -extern Monsters g_monsters; -extern Scripts* g_scripts; // Game int GameFunctions::luaGameCreateMonsterType(lua_State* L) { // Game.createMonsterType(name) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("MonsterTypes can only be registered in the Scripts interface."); lua_pushnil(L); return 1; } - MonsterType* monsterType = g_monsters.getMonsterType(getString(L, 1)); + MonsterType* monsterType = g_monsters().getMonsterType(getString(L, 1)); if (monsterType) { monsterType->info.lootItems.clear(); monsterType->info.attackSpells.clear(); @@ -52,8 +50,8 @@ int GameFunctions::luaGameCreateMonsterType(lua_State* L) { } else if (isString(L, 1)) { monsterType = new MonsterType(); std::string name = getString(L, 1); - g_monsters.addMonsterType(name, monsterType); - monsterType = g_monsters.getMonsterType(getString(L, 1)); + g_monsters().addMonsterType(name, monsterType); + monsterType = g_monsters().getMonsterType(getString(L, 1)); monsterType->name = name; monsterType->nameDescription = "a " + name; pushUserdata(L, monsterType); @@ -66,7 +64,7 @@ int GameFunctions::luaGameCreateMonsterType(lua_State* L) { int GameFunctions::luaGameCreateNpcType(lua_State* L) { // Game.createNpcType(name) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("NpcType can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -189,7 +187,7 @@ int GameFunctions::luaGameGetPlayers(lua_State* L) { int GameFunctions::luaGameLoadMap(lua_State* L) { // Game.loadMap(path) const std::string& path = getString(L, 1); - g_dispatcher.addTask(createTask([path]() {g_game().loadMap(path);})); + g_dispatcher().addTask(createTask([path]() {g_game().loadMap(path); })); return 0; } @@ -213,7 +211,7 @@ int GameFunctions::luaGameGetNpcCount(lua_State* L) { int GameFunctions::luaGameGetMonsterTypes(lua_State* L) { // Game.getMonsterTypes() - auto& type = g_monsters.monsters; + auto& type = g_monsters().monsters; lua_createtable(L, type.size(), 0); for (auto& mType : type) { @@ -538,7 +536,7 @@ int GameFunctions::luaGameGetBestiaryCharm(lua_State* L) { int GameFunctions::luaGameCreateBestiaryCharm(lua_State* L) { // Game.createBestiaryCharm(id) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("Charm bestiary can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -556,7 +554,7 @@ int GameFunctions::luaGameCreateBestiaryCharm(lua_State* L) { int GameFunctions::luaGameCreateItemClassification(lua_State* L) { // Game.createItemClassification(id) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("Item classification can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -612,7 +610,7 @@ int GameFunctions::luaGameReload(lua_State* L) { if (reloadType == RELOAD_TYPE_GLOBAL) { pushBoolean(L, g_luaEnvironment.loadFile("data/global.lua") == 0); pushBoolean(L, g_luaEnvironment.loadFile("data/stages.lua") == 0); - pushBoolean(L, g_scripts->loadScripts("scripts/lib", true, true)); + pushBoolean(L, g_scripts().loadScripts("scripts/lib", true, true)); } else if (reloadType == RELOAD_TYPE_STAGES) { pushBoolean(L, g_luaEnvironment.loadFile("data/stages.lua") == 0); } else { diff --git a/src/lua/functions/core/game/game_functions.hpp b/src/lua/functions/core/game/game_functions.hpp index ebf1a4092bb..3f80c846220 100644 --- a/src/lua/functions/core/game/game_functions.hpp +++ b/src/lua/functions/core/game/game_functions.hpp @@ -24,9 +24,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/luascript.h" - -extern LuaEnvironment g_luaEnvironment; - class GameFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { diff --git a/src/lua/functions/core/game/global_functions.cpp b/src/lua/functions/core/game/global_functions.cpp index 25e82d7cff3..df88305a581 100644 --- a/src/lua/functions/core/game/global_functions.cpp +++ b/src/lua/functions/core/game/global_functions.cpp @@ -30,10 +30,6 @@ #include "server/network/protocol/protocolstatus.h" class Creature; - -extern Chat* g_chat; -extern LuaEnvironment g_luaEnvironment; - int GlobalFunctions::luaDoPlayerAddItem(lua_State* L) { // doPlayerAddItem(cid, itemid, count/subtype, canDropOnMap) // doPlayerAddItem(cid, itemid, count, canDropOnMap, subtype) @@ -657,7 +653,7 @@ int GlobalFunctions::luaAddEvent(lua_State* L) { eventDesc.scriptId = getScriptEnv()->getScriptId(); auto& lastTimerEventId = g_luaEnvironment.lastEventTimerId; - eventDesc.eventId = g_scheduler.addEvent(createSchedulerTask( + eventDesc.eventId = g_scheduler().addEvent(createSchedulerTask( delay, std::bind(&LuaEnvironment::executeTimerEvent, &g_luaEnvironment, lastTimerEventId) )); @@ -687,7 +683,7 @@ int GlobalFunctions::luaStopEvent(lua_State* L) { LuaTimerEventDesc timerEventDesc = std::move(it->second); timerEvents.erase(it); - g_scheduler.stopEvent(timerEventDesc.eventId); + g_scheduler().stopEvent(timerEventDesc.eventId); luaL_unref(globalState, LUA_REGISTRYINDEX, timerEventDesc.function); for (auto parameter : timerEventDesc.parameters) { @@ -750,8 +746,8 @@ int GlobalFunctions::luaGetWaypointPositionByName(lua_State* L) { int GlobalFunctions::luaSendChannelMessage(lua_State* L) { // sendChannelMessage(channelId, type, message) - uint32_t channelId = getNumber(L, 1); - ChatChannel* channel = g_chat->getChannelById(channelId); + uint16_t channelId = getNumber(L, 1); + const ChatChannel* channel = g_chat().getChannelById(channelId); if (!channel) { pushBoolean(L, false); return 1; @@ -767,7 +763,7 @@ int GlobalFunctions::luaSendChannelMessage(lua_State* L) { int GlobalFunctions::luaSendGuildChannelMessage(lua_State* L) { // sendGuildChannelMessage(guildId, type, message) uint32_t guildId = getNumber(L, 1); - ChatChannel* channel = g_chat->getGuildChannelById(guildId); + const ChatChannel* channel = g_chat().getGuildChannelById(guildId); if (!channel) { pushBoolean(L, false); return 1; diff --git a/src/lua/functions/core/libs/db_functions.cpp b/src/lua/functions/core/libs/db_functions.cpp index a1d6deae26b..1cccc81b03a 100644 --- a/src/lua/functions/core/libs/db_functions.cpp +++ b/src/lua/functions/core/libs/db_functions.cpp @@ -23,9 +23,6 @@ #include "database/databasetasks.h" #include "lua/functions/core/libs/db_functions.hpp" #include "lua/scripts/lua_environment.hpp" - -extern LuaEnvironment g_luaEnvironment; - int DBFunctions::luaDatabaseExecute(lua_State* L) { pushBoolean(L, Database::getInstance().executeQuery(getString(L, -1))); return 1; @@ -56,7 +53,7 @@ int DBFunctions::luaDatabaseAsyncExecute(lua_State* L) { luaL_unref(luaState, LUA_REGISTRYINDEX, ref); }; } - g_databaseTasks.addTask(getString(L, -1), callback); + g_databaseTasks().addTask(getString(L, -1), callback); return 0; } @@ -98,7 +95,7 @@ int DBFunctions::luaDatabaseAsyncStoreQuery(lua_State* L) { luaL_unref(luaState, LUA_REGISTRYINDEX, ref); }; } - g_databaseTasks.addTask(getString(L, -1), callback, true); + g_databaseTasks().addTask(getString(L, -1), callback, true); return 0; } diff --git a/src/lua/functions/core/network/network_message_functions.hpp b/src/lua/functions/core/network/network_message_functions.hpp index 1421d12d14a..131d28ae995 100644 --- a/src/lua/functions/core/network/network_message_functions.hpp +++ b/src/lua/functions/core/network/network_message_functions.hpp @@ -24,9 +24,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/luascript.h" - -extern LuaEnvironment g_luaEnvironment; - class NetworkMessageFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { diff --git a/src/lua/functions/creatures/combat/combat_functions.cpp b/src/lua/functions/creatures/combat/combat_functions.cpp index 254d27ac8e2..f14d893b97f 100644 --- a/src/lua/functions/creatures/combat/combat_functions.cpp +++ b/src/lua/functions/creatures/combat/combat_functions.cpp @@ -23,9 +23,6 @@ #include "game/game.h" #include "lua/functions/creatures/combat/combat_functions.hpp" #include "lua/scripts/lua_environment.hpp" - -extern LuaEnvironment g_luaEnvironment; - int CombatFunctions::luaCombatCreate(lua_State* L) { // Combat() pushUserdata(L, g_luaEnvironment.createCombatObject(getScriptEnv()->getScriptInterface())); diff --git a/src/lua/functions/creatures/combat/spell_functions.cpp b/src/lua/functions/creatures/combat/spell_functions.cpp index 43303b20d95..9838db0736b 100644 --- a/src/lua/functions/creatures/combat/spell_functions.cpp +++ b/src/lua/functions/creatures/combat/spell_functions.cpp @@ -23,8 +23,6 @@ #include "creatures/players/vocations/vocation.h" #include "lua/functions/creatures/combat/spell_functions.hpp" -extern Spells* g_spells; -extern Vocations g_vocations; int SpellFunctions::luaSpellCreate(lua_State* L) { // Spell(words, name or id) to get an existing spell @@ -40,7 +38,7 @@ int SpellFunctions::luaSpellCreate(lua_State* L) { if (isNumber(L, 2)) { int32_t id = getNumber(L, 2); - RuneSpell* rune = g_spells->getRuneSpell(id); + RuneSpell* rune = g_spells().getRuneSpell(id); if (rune) { pushUserdata(L, rune); @@ -51,19 +49,19 @@ int SpellFunctions::luaSpellCreate(lua_State* L) { spellType = static_cast(id); } else if (isString(L, 2)) { std::string arg = getString(L, 2); - InstantSpell* instant = g_spells->getInstantSpellByName(arg); + InstantSpell* instant = g_spells().getInstantSpellByName(arg); if (instant) { pushUserdata(L, instant); setMetatable(L, -1, "Spell"); return 1; } - instant = g_spells->getInstantSpell(arg); + instant = g_spells().getInstantSpell(arg); if (instant) { pushUserdata(L, instant); setMetatable(L, -1, "Spell"); return 1; } - RuneSpell* rune = g_spells->getRuneSpellByName(arg); + RuneSpell* rune = g_spells().getRuneSpellByName(arg); if (rune) { pushUserdata(L, rune); setMetatable(L, -1, "Spell"); @@ -141,7 +139,7 @@ int SpellFunctions::luaSpellRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_spells->registerInstantLuaEvent(instant)); + pushBoolean(L, g_spells().registerInstantLuaEvent(instant)); } else if (spell->spellType == SPELL_RUNE) { RuneSpell* rune = dynamic_cast(getUserdata(L, 1)); if (rune->getMagicLevel() != 0 || rune->getLevel() != 0) { @@ -159,7 +157,7 @@ int SpellFunctions::luaSpellRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_spells->registerRuneLuaEvent(rune)); + pushBoolean(L, g_spells().registerRuneLuaEvent(rune)); } return 1; } @@ -578,7 +576,7 @@ int SpellFunctions::luaSpellVocation(lua_State* L) { ++it; std::string s = std::to_string(it); char const *pchar = s.c_str(); - std::string name = g_vocations.getVocation(voc.first)->getVocName(); + std::string name = g_vocations().getVocation(voc.first)->getVocName(); setField(L, pchar, name); } setMetatable(L, -1, "Spell"); @@ -587,7 +585,7 @@ int SpellFunctions::luaSpellVocation(lua_State* L) { for (int i = 0; i < parameters; ++i) { if (getString(L, 2 + i).find(";") != std::string::npos) { std::vector vocList = explodeString(getString(L, 2 + i), ";"); - int32_t vocationId = g_vocations.getVocationId(vocList[0]); + int32_t vocationId = g_vocations().getVocationId(vocList[0]); if (vocList.size() > 0) { if (vocList[1] == "true") { spell->addVocMap(vocationId, true); @@ -596,7 +594,7 @@ int SpellFunctions::luaSpellVocation(lua_State* L) { } } } else { - int32_t vocationId = g_vocations.getVocationId(getString(L, 2 + i)); + int32_t vocationId = g_vocations().getVocationId(getString(L, 2 + i)); spell->addVocMap(vocationId, false); } } diff --git a/src/lua/functions/creatures/monster/loot_functions.cpp b/src/lua/functions/creatures/monster/loot_functions.cpp index 298577a1c58..c484f646978 100644 --- a/src/lua/functions/creatures/monster/loot_functions.cpp +++ b/src/lua/functions/creatures/monster/loot_functions.cpp @@ -22,7 +22,6 @@ #include "creatures/monsters/monsters.h" #include "lua/functions/creatures/monster/loot_functions.hpp" -extern Monsters g_monsters; int LootFunctions::luaCreateLoot(lua_State* L) { // Loot() will create a new loot item diff --git a/src/lua/functions/creatures/monster/monster_functions.cpp b/src/lua/functions/creatures/monster/monster_functions.cpp index c4256c2a7fb..8ea8aa6d7f5 100644 --- a/src/lua/functions/creatures/monster/monster_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_functions.cpp @@ -27,7 +27,6 @@ #include "creatures/monsters/monsters.h" #include "lua/functions/creatures/monster/monster_functions.hpp" -extern Monsters g_monsters; int MonsterFunctions::luaMonsterCreate(lua_State* L) { // Monster(id or userdata) @@ -77,9 +76,9 @@ int MonsterFunctions::luaMonsterSetType(lua_State* L) { if (monster) { MonsterType* monsterType = nullptr; if (isNumber(L, 2)) { - monsterType = g_monsters.getMonsterTypeByRaceId(getNumber(L, 2)); + monsterType = g_monsters().getMonsterTypeByRaceId(getNumber(L, 2)); } else { - monsterType = g_monsters.getMonsterType(getString(L, 2)); + monsterType = g_monsters().getMonsterType(getString(L, 2)); } // Unregister creature events (current MonsterType) for (const std::string& scriptName : monster->mType->info.scripts) { diff --git a/src/lua/functions/creatures/monster/monster_type_functions.cpp b/src/lua/functions/creatures/monster/monster_type_functions.cpp index aaaa555c2dd..4e218ce03b0 100644 --- a/src/lua/functions/creatures/monster/monster_type_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_type_functions.cpp @@ -25,8 +25,6 @@ #include "lua/functions/creatures/monster/monster_type_functions.hpp" #include "lua/scripts/scripts.h" -extern Monsters g_monsters; -extern Scripts* g_scripts; void MonsterTypeFunctions::createMonsterTypeLootLuaTable(lua_State* L, const std::vector& lootList) { lua_createtable(L, lootList.size(), 0); @@ -56,9 +54,9 @@ int MonsterTypeFunctions::luaMonsterTypeCreate(lua_State* L) { // MonsterType(name or raceid) MonsterType* monsterType = nullptr; if (isNumber(L, 2)) { - monsterType = g_monsters.getMonsterTypeByRaceId(getNumber(L, 2)); + monsterType = g_monsters().getMonsterTypeByRaceId(getNumber(L, 2)); } else { - monsterType = g_monsters.getMonsterType(getString(L, 2)); + monsterType = g_monsters().getMonsterType(getString(L, 2)); } if (monsterType) { @@ -774,7 +772,7 @@ int MonsterTypeFunctions::luaMonsterTypeAddAttack(lua_State* L) { MonsterSpell* spell = getUserdata(L, 2); if (spell) { spellBlock_t sb; - if (g_monsters.deserializeSpell(spell, sb, monsterType->name)) { + if (g_monsters().deserializeSpell(spell, sb, monsterType->name)) { monsterType->info.attackSpells.push_back(std::move(sb)); } else { SPDLOG_WARN("Monster: {}, cant load spell: {}", monsterType->name, @@ -826,7 +824,7 @@ int MonsterTypeFunctions::luaMonsterTypeAddDefense(lua_State* L) { MonsterSpell* spell = getUserdata(L, 2); if (spell) { spellBlock_t sb; - if (g_monsters.deserializeSpell(spell, sb, monsterType->name)) { + if (g_monsters().deserializeSpell(spell, sb, monsterType->name)) { monsterType->info.defenseSpells.push_back(std::move(sb)); } else { SPDLOG_WARN("Monster: {}, Cant load spell: {}", monsterType->name, @@ -998,7 +996,7 @@ int MonsterTypeFunctions::luaMonsterTypeEventOnCallback(lua_State* L) { // monsterType:onSay(callback) MonsterType* monsterType = getUserdata(L, 1); if (monsterType) { - if (monsterType->loadCallback(&g_scripts->getScriptInterface())) { + if (monsterType->loadCallback(&g_scripts().getScriptInterface())) { pushBoolean(L, true); return 1; } diff --git a/src/lua/functions/creatures/npc/npc_type_functions.cpp b/src/lua/functions/creatures/npc/npc_type_functions.cpp index af5eed3799e..46ee4a9972f 100644 --- a/src/lua/functions/creatures/npc/npc_type_functions.cpp +++ b/src/lua/functions/creatures/npc/npc_type_functions.cpp @@ -23,8 +23,6 @@ #include "lua/functions/creatures/npc/npc_type_functions.hpp" #include "lua/scripts/scripts.h" -extern Npcs g_npcs; -extern Scripts* g_scripts; void NpcTypeFunctions::createNpcTypeShopLuaTable(lua_State* L, const std::vector& shopVector) { lua_createtable(L, shopVector.size(), 0); @@ -49,7 +47,7 @@ void NpcTypeFunctions::createNpcTypeShopLuaTable(lua_State* L, const std::vector int NpcTypeFunctions::luaNpcTypeCreate(lua_State* L) { // NpcType(name) - NpcType* npcType = g_npcs.getNpcType(getString(L, 1), true); + NpcType* npcType = g_npcs().getNpcType(getString(L, 1), true); pushUserdata(L, npcType); setMetatable(L, -1, "NpcType"); return 1; @@ -290,7 +288,7 @@ int NpcTypeFunctions::luaNpcTypeEventOnCallback(lua_State* L) { // npcType:onCheckItem(callback) NpcType* npcType = getUserdata(L, 1); if (npcType) { - if (npcType->loadCallback(&g_scripts->getScriptInterface())) { + if (npcType->loadCallback(&g_scripts().getScriptInterface())) { pushBoolean(L, true); return 1; } diff --git a/src/lua/functions/creatures/player/player_functions.cpp b/src/lua/functions/creatures/player/player_functions.cpp index ca48ee86228..b5482c13b17 100644 --- a/src/lua/functions/creatures/player/player_functions.cpp +++ b/src/lua/functions/creatures/player/player_functions.cpp @@ -30,10 +30,6 @@ #include "items/item.h" #include "lua/functions/creatures/player/player_functions.hpp" -extern Chat* g_chat; -extern Monsters g_monsters; -extern Spells* g_spells; -extern Vocations g_vocations; int PlayerFunctions::luaPlayerSendInventory(lua_State* L) { // player:sendInventory() @@ -303,7 +299,7 @@ int PlayerFunctions::luaPlayeraddBestiaryKill(lua_State* L) { // player:addBestiaryKill(name[, amount = 1]) Player* player = getUserdata(L, 1); if (player) { - MonsterType* mtype = g_monsters.getMonsterType(getString(L, 2)); + MonsterType* mtype = g_monsters().getMonsterType(getString(L, 2)); if (mtype) { IOBestiary g_bestiary; g_bestiary.addBestiaryKill(player, mtype, getNumber(L, 3, 1)); @@ -324,7 +320,7 @@ int PlayerFunctions::luaPlayergetCharmMonsterType(lua_State* L) { charmRune_t charmid = getNumber(L, 2); uint16_t raceid = player->parseRacebyCharm(charmid, false, 0); if (raceid > 0) { - MonsterType* mtype = g_monsters.getMonsterTypeByRaceId(raceid); + MonsterType* mtype = g_monsters().getMonsterTypeByRaceId(raceid); if (mtype) { pushUserdata(L, mtype); setMetatable(L, -1, "MonsterType"); @@ -1124,9 +1120,9 @@ int PlayerFunctions::luaPlayerSetVocation(lua_State* L) { Vocation* vocation; if (isNumber(L, 2)) { - vocation = g_vocations.getVocation(getNumber(L, 2)); + vocation = g_vocations().getVocation(getNumber(L, 2)); } else if (isString(L, 2)) { - vocation = g_vocations.getVocation(g_vocations.getVocationId(getString(L, 2))); + vocation = g_vocations().getVocation(g_vocations().getVocationId(getString(L, 2))); } else if (isUserdata(L, 2)) { vocation = getUserdata(L, 2); } else { @@ -1917,7 +1913,7 @@ int PlayerFunctions::luaPlayerSendTextMessage(lua_State* L) { TextMessage message(getNumber(L, 2), getString(L, 3)); if (parameters == 4) { uint16_t channelId = getNumber(L, 4); - ChatChannel* channel = g_chat->getChannel(*player, channelId); + ChatChannel* channel = g_chat().getChannel(*player, channelId); if (!channel || !channel->hasUser(*player)) { pushBoolean(L, false); return 1; @@ -2437,7 +2433,7 @@ int PlayerFunctions::luaPlayerCanLearnSpell(lua_State* L) { } const std::string& spellName = getString(L, 2); - InstantSpell* spell = g_spells->getInstantSpellByName(spellName); + const InstantSpell* spell = g_spells().getInstantSpellByName(spellName); if (!spell) { reportErrorFunc("Spell \"" + spellName + "\" not found"); pushBoolean(L, false); @@ -3106,9 +3102,9 @@ int PlayerFunctions::luaPlayerGetInstantSpells(lua_State* L) { } std::vector spells; - for (auto& spell : g_spells->getInstantSpells()) { - if (spell.second.canCast(player)) { - spells.push_back(&spell.second); + for (auto& [key, spell] : g_spells().getInstantSpells()) { + if (spell.canCast(player)) { + spells.push_back(&spell); } } diff --git a/src/lua/functions/creatures/player/vocation_functions.cpp b/src/lua/functions/creatures/player/vocation_functions.cpp index 0f4a77aa4a7..0999bc267e2 100644 --- a/src/lua/functions/creatures/player/vocation_functions.cpp +++ b/src/lua/functions/creatures/player/vocation_functions.cpp @@ -22,18 +22,17 @@ #include "creatures/players/vocations/vocation.h" #include "lua/functions/creatures/player/vocation_functions.hpp" -extern Vocations g_vocations; int VocationFunctions::luaVocationCreate(lua_State* L) { // Vocation(id or name) - uint32_t id; + uint16_t vocationId; if (isNumber(L, 2)) { - id = getNumber(L, 2); + vocationId = getNumber(L, 2); } else { - id = g_vocations.getVocationId(getString(L, 2)); + vocationId = g_vocations().getVocationId(getString(L, 2)); } - Vocation* vocation = g_vocations.getVocation(id); + Vocation* vocation = g_vocations().getVocation(vocationId); if (vocation) { pushUserdata(L, vocation); setMetatable(L, -1, "Vocation"); @@ -269,7 +268,7 @@ int VocationFunctions::luaVocationGetDemotion(lua_State* L) { return 1; } - Vocation* demotedVocation = g_vocations.getVocation(fromId); + Vocation* demotedVocation = g_vocations().getVocation(fromId); if (demotedVocation && demotedVocation != vocation) { pushUserdata(L, demotedVocation); setMetatable(L, -1, "Vocation"); @@ -287,13 +286,13 @@ int VocationFunctions::luaVocationGetPromotion(lua_State* L) { return 1; } - uint16_t promotedId = g_vocations.getPromotedVocation(vocation->getId()); + uint16_t promotedId = g_vocations().getPromotedVocation(vocation->getId()); if (promotedId == VOCATION_NONE) { lua_pushnil(L); return 1; } - Vocation* promotedVocation = g_vocations.getVocation(promotedId); + Vocation* promotedVocation = g_vocations().getVocation(promotedId); if (promotedVocation && promotedVocation != vocation) { pushUserdata(L, promotedVocation); setMetatable(L, -1, "Vocation"); diff --git a/src/lua/functions/events/action_functions.cpp b/src/lua/functions/events/action_functions.cpp index 8c2b539e105..3893ab418a8 100644 --- a/src/lua/functions/events/action_functions.cpp +++ b/src/lua/functions/events/action_functions.cpp @@ -24,7 +24,6 @@ #include "game/game.h" #include "items/item.h" -extern Actions* g_actions; int ActionFunctions::luaCreateAction(lua_State* L) { // Action() @@ -65,7 +64,7 @@ int ActionFunctions::luaActionRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_actions->registerLuaEvent(action)); + pushBoolean(L, g_actions().registerLuaEvent(action)); pushBoolean(L, true); } else { reportErrorFunc(getErrorDesc(LUA_ERROR_ACTION_NOT_FOUND)); diff --git a/src/lua/functions/events/creature_event_functions.cpp b/src/lua/functions/events/creature_event_functions.cpp index fb9037fd4c5..e87e9dbc3b6 100644 --- a/src/lua/functions/events/creature_event_functions.cpp +++ b/src/lua/functions/events/creature_event_functions.cpp @@ -23,7 +23,6 @@ #include "lua/functions/events/creature_event_functions.hpp" #include "utils/tools.h" -extern CreatureEvents* g_creatureEvents; int CreatureEventFunctions::luaCreateCreatureEvent(lua_State* L) { // CreatureEvent(eventName) @@ -90,7 +89,7 @@ int CreatureEventFunctions::luaCreatureEventRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_creatureEvents->registerLuaEvent(creature)); + pushBoolean(L, g_creatureEvents().registerLuaEvent(creature)); } else { lua_pushnil(L); } diff --git a/src/lua/functions/events/global_event_functions.cpp b/src/lua/functions/events/global_event_functions.cpp index 3ed18df982f..ca99536ed89 100644 --- a/src/lua/functions/events/global_event_functions.cpp +++ b/src/lua/functions/events/global_event_functions.cpp @@ -24,12 +24,10 @@ #include "lua/scripts/scripts.h" #include "utils/tools.h" -extern GlobalEvents* g_globalEvents; -extern Scripts* g_scripts; int GlobalEventFunctions::luaCreateGlobalEvent(lua_State* L) { // GlobalEvent(eventName) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("GlobalEvents can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -82,7 +80,7 @@ int GlobalEventFunctions::luaGlobalEventRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_globalEvents->registerLuaEvent(globalevent)); + pushBoolean(L, g_globalEvents().registerLuaEvent(globalevent)); } else { lua_pushnil(L); } diff --git a/src/lua/functions/events/move_event_functions.cpp b/src/lua/functions/events/move_event_functions.cpp index 948edca10e0..fedd938eb11 100644 --- a/src/lua/functions/events/move_event_functions.cpp +++ b/src/lua/functions/events/move_event_functions.cpp @@ -23,7 +23,6 @@ #include "lua/creature/movement.h" #include "lua/functions/events/move_event_functions.hpp" -extern MoveEvents* g_moveEvents; int MoveEventFunctions::luaCreateMoveEvent(lua_State* L) { // MoveEvent() @@ -79,10 +78,10 @@ int MoveEventFunctions::luaMoveEventRegister(lua_State* L) { MoveEvent* moveevent = getUserdata(L, 1); if (moveevent) { if (!moveevent->isScripted()) { - pushBoolean(L, g_moveEvents->registerLuaFunction(moveevent)); + pushBoolean(L, g_moveEvents().registerLuaFunction(moveevent)); return 1; } - pushBoolean(L, g_moveEvents->registerLuaEvent(moveevent)); + pushBoolean(L, g_moveEvents().registerLuaEvent(moveevent)); moveevent->getItemIdRange().clear(); moveevent->getActionIdRange().clear(); moveevent->getUniqueIdRange().clear(); diff --git a/src/lua/functions/events/talk_action_functions.cpp b/src/lua/functions/events/talk_action_functions.cpp index ed8eb04c59a..9f7501529fd 100644 --- a/src/lua/functions/events/talk_action_functions.cpp +++ b/src/lua/functions/events/talk_action_functions.cpp @@ -22,7 +22,6 @@ #include "lua/creature/talkaction.h" #include "lua/functions/events/talk_action_functions.hpp" -extern TalkActions* g_talkActions; int TalkActionFunctions::luaCreateTalkAction(lua_State* L) { // TalkAction(words) @@ -63,7 +62,7 @@ int TalkActionFunctions::luaTalkActionRegister(lua_State* L) { pushBoolean(L, false); return 1; } - pushBoolean(L, g_talkActions->registerLuaEvent(talk)); + pushBoolean(L, g_talkActions().registerLuaEvent(talk)); } else { lua_pushnil(L); } diff --git a/src/lua/functions/items/imbuement_functions.cpp b/src/lua/functions/items/imbuement_functions.cpp index d37e2f75d2f..676ba8e859d 100644 --- a/src/lua/functions/items/imbuement_functions.cpp +++ b/src/lua/functions/items/imbuement_functions.cpp @@ -28,14 +28,11 @@ #include "lua/scripts/scripts.h" #include "utils/tools.h" -extern Imbuements* g_imbuements; -extern Scripts* g_scripts; -extern Weapons* g_weapons; int ImbuementFunctions::luaCreateImbuement(lua_State* L) { // Imbuement(id) - uint32_t imbuementId = getNumber(L, 2); - Imbuement* imbuement = g_imbuements->getImbuement(imbuementId); + uint16_t imbuementId = getNumber(L, 2); + Imbuement* imbuement = g_imbuements().getImbuement(imbuementId); if (imbuement) { pushUserdata(L, imbuement); @@ -97,7 +94,7 @@ int ImbuementFunctions::luaImbuementGetBase(lua_State* L) { return 1; } - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuement->getBaseID()); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuement->getBaseID()); if (!baseImbuement) { lua_pushnil(L); @@ -122,8 +119,8 @@ int ImbuementFunctions::luaImbuementGetCategory(lua_State* L) { lua_pushnil(L); return 1; } - uint32_t categoryId = imbuement->getCategory(); - const CategoryImbuement* categoryImbuement = g_imbuements->getCategoryByID(categoryId); + uint16_t categoryId = imbuement->getCategory(); + const CategoryImbuement* categoryImbuement = g_imbuements().getCategoryByID(categoryId); if (categoryImbuement) { lua_createtable(L, 0, 2); diff --git a/src/lua/functions/items/item_functions.cpp b/src/lua/functions/items/item_functions.cpp index dbef827ff6f..1a1d40e090e 100644 --- a/src/lua/functions/items/item_functions.cpp +++ b/src/lua/functions/items/item_functions.cpp @@ -422,9 +422,9 @@ int ItemFunctions::luaItemSetAttribute(lua_State* L) { case ITEM_ATTRIBUTE_DECAYSTATE: { ItemDecayState_t decayState = getNumber(L, 3); if (decayState == DECAYING_FALSE || decayState == DECAYING_STOPPING) { - g_decay.stopDecay(item); + g_decay().stopDecay(item); } else { - g_decay.startDecay(item); + g_decay().startDecay(item); } pushBoolean(L, true); return 1; @@ -432,7 +432,7 @@ int ItemFunctions::luaItemSetAttribute(lua_State* L) { case ITEM_ATTRIBUTE_DURATION: { item->setDecaying(DECAYING_PENDING); item->setDuration(getNumber(L, 3)); - g_decay.startDecay(item); + g_decay().startDecay(item); pushBoolean(L, true); return 1; } diff --git a/src/lua/functions/items/weapon_functions.cpp b/src/lua/functions/items/weapon_functions.cpp index 009eccc66c2..10c63f3a76e 100644 --- a/src/lua/functions/items/weapon_functions.cpp +++ b/src/lua/functions/items/weapon_functions.cpp @@ -28,12 +28,10 @@ #include "lua/scripts/scripts.h" #include "utils/tools.h" -extern Scripts* g_scripts; -extern Weapons* g_weapons; int WeaponFunctions::luaCreateWeapon(lua_State* L) { // Weapon(type) - if (getScriptEnv()->getScriptInterface() != &g_scripts->getScriptInterface()) { + if (getScriptEnv()->getScriptInterface() != &g_scripts().getScriptInterface()) { reportErrorFunc("Weapons can only be registered in the Scripts interface."); lua_pushnil(L); return 1; @@ -137,7 +135,7 @@ int WeaponFunctions::luaWeaponRegister(lua_State* L) { } weapon->configureWeapon(it); - pushBoolean(L, g_weapons->registerLuaEvent(weapon)); + pushBoolean(L, g_weapons().registerLuaEvent(weapon)); weapon = nullptr; // Releases weapon, removing the luascript reference } else { lua_pushnil(L); diff --git a/src/lua/functions/map/position_functions.hpp b/src/lua/functions/map/position_functions.hpp index b45154c5db5..34e46a1cc15 100644 --- a/src/lua/functions/map/position_functions.hpp +++ b/src/lua/functions/map/position_functions.hpp @@ -24,9 +24,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/luascript.h" - -extern LuaEnvironment g_luaEnvironment; - class PositionFunctions final : LuaScriptInterface { public: static void init(lua_State* L) { diff --git a/src/lua/global/baseevents.cpp b/src/lua/global/baseevents.cpp index 64b40aad34f..1307e67fb9d 100644 --- a/src/lua/global/baseevents.cpp +++ b/src/lua/global/baseevents.cpp @@ -23,9 +23,6 @@ #include "lua/scripts/lua_environment.hpp" #include "utils/pugicast.h" #include "utils/tools.h" - -extern LuaEnvironment g_luaEnvironment; - bool BaseEvents::loadFromXml() { if (loaded) { SPDLOG_ERROR("[BaseEvents::loadFromXml] - It's already loaded."); diff --git a/src/lua/global/globalevent.cpp b/src/lua/global/globalevent.cpp index 2cbb58ee35d..f70335afa12 100644 --- a/src/lua/global/globalevent.cpp +++ b/src/lua/global/globalevent.cpp @@ -45,9 +45,9 @@ void GlobalEvents::clearMap(GlobalEventMap& map, bool fromLua) { } void GlobalEvents::clear(bool fromLua) { - g_scheduler.stopEvent(thinkEventId); + g_scheduler().stopEvent(thinkEventId); thinkEventId = 0; - g_scheduler.stopEvent(timerEventId); + g_scheduler().stopEvent(timerEventId); timerEventId = 0; clearMap(thinkMap, fromLua); @@ -70,7 +70,7 @@ bool GlobalEvents::registerEvent(Event_ptr event, const pugi::xml_node&) { auto result = timerMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (timerEventId == 0) { - timerEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); + timerEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); } return true; } @@ -83,7 +83,7 @@ bool GlobalEvents::registerEvent(Event_ptr event, const pugi::xml_node&) { auto result = thinkMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (thinkEventId == 0) { - thinkEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); + thinkEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); } return true; } @@ -100,7 +100,7 @@ bool GlobalEvents::registerLuaEvent(GlobalEvent* event) { auto result = timerMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (timerEventId == 0) { - timerEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); + timerEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::timer, this))); } return true; } @@ -113,7 +113,7 @@ bool GlobalEvents::registerLuaEvent(GlobalEvent* event) { auto result = thinkMap.emplace(globalEvent->getName(), std::move(*globalEvent)); if (result.second) { if (thinkEventId == 0) { - thinkEventId = g_scheduler.addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); + thinkEventId = g_scheduler().addEvent(createSchedulerTask(SCHEDULER_MINTICKS, std::bind(&GlobalEvents::think, this))); } return true; } @@ -162,7 +162,7 @@ void GlobalEvents::timer() { } if (nextScheduledTime != std::numeric_limits::max()) { - timerEventId = g_scheduler.addEvent(createSchedulerTask(std::max(1000, nextScheduledTime * 1000), + timerEventId = g_scheduler().addEvent(createSchedulerTask(std::max(1000, nextScheduledTime * 1000), std::bind(&GlobalEvents::timer, this))); } } @@ -196,7 +196,7 @@ void GlobalEvents::think() { } if (nextScheduledTime != std::numeric_limits::max()) { - thinkEventId = g_scheduler.addEvent(createSchedulerTask(nextScheduledTime, std::bind(&GlobalEvents::think, this))); + thinkEventId = g_scheduler().addEvent(createSchedulerTask(nextScheduledTime, std::bind(&GlobalEvents::think, this))); } } diff --git a/src/lua/global/globalevent.h b/src/lua/global/globalevent.h index 0bbbcb01d7c..0d0b41c07b9 100644 --- a/src/lua/global/globalevent.h +++ b/src/lua/global/globalevent.h @@ -36,6 +36,13 @@ class GlobalEvents final : public BaseEvents { GlobalEvents(const GlobalEvents&) = delete; GlobalEvents& operator=(const GlobalEvents&) = delete; + static GlobalEvents& getInstance() { + // Guaranteed to be destroyed + static GlobalEvents instance; + // Instantiated on first use + return instance; + } + void startup() const; void timer(); @@ -65,6 +72,8 @@ class GlobalEvents final : public BaseEvents { int32_t thinkEventId = 0, timerEventId = 0; }; +constexpr auto g_globalEvents = &GlobalEvents::getInstance; + class GlobalEvent final : public Event { public: explicit GlobalEvent(LuaScriptInterface* interface); diff --git a/src/lua/modules/modules.h b/src/lua/modules/modules.h index 4a4b85cafbd..10bc785350e 100644 --- a/src/lua/modules/modules.h +++ b/src/lua/modules/modules.h @@ -74,6 +74,13 @@ class Modules final : public BaseEvents { Modules(const Modules&) = delete; Modules& operator=(const Modules&) = delete; + static Modules& getInstance() { + // Guaranteed to be destroyed + static Modules instance; + // Instantiated on first use + return instance; + } + void executeOnRecvbyte(uint32_t playerId, NetworkMessage& msg, uint8_t byte) const; Module* getEventByRecvbyte(uint8_t recvbyte, bool force); @@ -90,4 +97,6 @@ class Modules final : public BaseEvents { LuaScriptInterface scriptInterface; }; +constexpr auto g_modules = &Modules::getInstance; + #endif // SRC_LUA_MODULES_MODULES_H_ diff --git a/src/lua/scripts/lua_environment.hpp b/src/lua/scripts/lua_environment.hpp index 2cc9f47225b..75e636747f5 100644 --- a/src/lua/scripts/lua_environment.hpp +++ b/src/lua/scripts/lua_environment.hpp @@ -82,4 +82,6 @@ class LuaEnvironment: public LuaScriptInterface { friend class CombatSpell; }; +inline LuaEnvironment g_luaEnvironment; + #endif // SRC_LUA_SCRIPTS_LUA_ENVIRONMENT_HPP_ diff --git a/src/lua/scripts/luascript.cpp b/src/lua/scripts/luascript.cpp index f7170242a9c..970c49607d8 100644 --- a/src/lua/scripts/luascript.cpp +++ b/src/lua/scripts/luascript.cpp @@ -27,7 +27,6 @@ ScriptEnvironment::DBResultMap ScriptEnvironment::tempResults; uint32_t ScriptEnvironment::lastResultId = 0; std::multimap ScriptEnvironment::tempItems; -LuaEnvironment g_luaEnvironment; ScriptEnvironment LuaFunctionsLoader::scriptEnv[16]; int32_t LuaFunctionsLoader::scriptEnvIndex = -1; diff --git a/src/lua/scripts/scripts.cpp b/src/lua/scripts/scripts.cpp index 52de60f12a8..305ac0abcad 100644 --- a/src/lua/scripts/scripts.cpp +++ b/src/lua/scripts/scripts.cpp @@ -34,21 +34,6 @@ #include "lua/scripts/lua_environment.hpp" #include "lua/scripts/scripts.h" -Actions* g_actions = nullptr; -CreatureEvents* g_creatureEvents = nullptr; -Chat* g_chat = nullptr; -Events* g_events = nullptr; -GlobalEvents* g_globalEvents = nullptr; -Spells* g_spells = nullptr; -TalkActions* g_talkActions = nullptr; -MoveEvents* g_moveEvents = nullptr; -Weapons* g_weapons = nullptr; -Scripts* g_scripts = nullptr; -Modules* g_modules = nullptr; -Imbuements* g_imbuements = nullptr; - -extern LuaEnvironment g_luaEnvironment; - Scripts::Scripts() : scriptInterface("Scripts Interface") { scriptInterface.initState(); @@ -56,62 +41,6 @@ Scripts::Scripts() : Scripts::~Scripts() { scriptInterface.reInitState(); - - delete g_events; - delete g_weapons; - delete g_spells; - delete g_actions; - delete g_talkActions; - delete g_moveEvents; - delete g_chat; - delete g_creatureEvents; - delete g_globalEvents; - delete g_imbuements; -} - -bool Scripts::loadScriptSystems() { - g_chat = new Chat(); - - // XML loads disabled start - g_weapons = new Weapons(); - if (!g_weapons) { - return false; - } - - g_weapons->loadDefaults(); - - g_spells = new Spells(); - if (!g_spells) { - return false; - } - - g_actions = new Actions(); - if (!g_actions) { - return false; - } - - g_talkActions = new TalkActions(); - if (!g_talkActions) { - return false; - } - - g_moveEvents = new MoveEvents(); - if (!g_moveEvents) { - return false; - } - - g_creatureEvents = new CreatureEvents(); - if (!g_creatureEvents) { - return false; - } - - g_globalEvents = new GlobalEvents(); - if (!g_globalEvents) { - return false; - } - // XML loads disabled end - - return true; } bool Scripts::loadEventSchedulerScripts(const std::string& fileName) { diff --git a/src/lua/scripts/scripts.h b/src/lua/scripts/scripts.h index 070a165d3db..450744c4133 100644 --- a/src/lua/scripts/scripts.h +++ b/src/lua/scripts/scripts.h @@ -33,13 +33,14 @@ class Scripts { Scripts& operator=(const Scripts&) = delete; static Scripts& getInstance() { + // Guaranteed to be destroyed static Scripts instance; + // Instantiated on first use return instance; } bool loadEventSchedulerScripts(const std::string& fileName); bool loadScripts(std::string folderName, bool isLib, bool reload); - bool loadScriptSystems(); LuaScriptInterface& getScriptInterface() { return scriptInterface; } @@ -47,4 +48,6 @@ class Scripts { LuaScriptInterface scriptInterface; }; +constexpr auto g_scripts = &Scripts::getInstance; + #endif // SRC_LUA_SCRIPTS_SCRIPTS_H_ diff --git a/src/otserv.cpp b/src/otserv.cpp index aa36a43ff89..ae45fed37ef 100644 --- a/src/otserv.cpp +++ b/src/otserv.cpp @@ -31,6 +31,7 @@ #include "database/databasetasks.h" #include "game/game.h" #include "game/scheduling/scheduler.h" +#include "game/scheduling/tasks.h" #include "io/iomarket.h" #include "lua/creature/events.h" #include "lua/modules/modules.h" @@ -46,20 +47,6 @@ #include "gitmetadata.h" #endif -DatabaseTasks g_databaseTasks; -Dispatcher g_dispatcher; -Scheduler g_scheduler; - -extern Events* g_events; -extern Imbuements* g_imbuements; -extern LuaEnvironment g_luaEnvironment; -extern Modules* g_modules; -Monsters g_monsters; -Npcs g_npcs; -Vocations g_vocations; -extern Scripts* g_scripts; -RSA2 g_RSA; - std::mutex g_loaderLock; std::condition_variable g_loaderSignal; std::unique_lock g_loaderUniqueLock(g_loaderLock); @@ -96,13 +83,6 @@ void badAllocationHandler() { exit(-1); } -void initGlobalScopes() { - g_scripts = new Scripts(); - g_modules = new Modules(); - g_events = new Events(); - g_imbuements = new Imbuements(); -} - void modulesLoadHelper(bool loaded, std::string moduleName) { SPDLOG_INFO("Loading {}", moduleName); if (!loaded) { @@ -120,7 +100,7 @@ void loadModules() { // set RSA key try { - g_RSA.loadPEM("key.pem"); + g_RSA().loadPEM("key.pem"); } catch(const std::exception& e) { SPDLOG_ERROR(e.what()); startupErrorMessage(); @@ -142,7 +122,7 @@ void loadModules() { startupErrorMessage(); } - g_databaseTasks.start(); + g_databaseTasks().start(); DatabaseManager::updateDatabase(); if (g_configManager().getBoolean(OPTIMIZE_DATABASE) @@ -154,8 +134,6 @@ void loadModules() { "items.otb"); modulesLoadHelper(Item::items.loadFromXml(), "items.xml"); - modulesLoadHelper(Scripts::getInstance().loadScriptSystems(), - "script systems"); // Lua Env modulesLoadHelper((g_luaEnvironment.loadFile("data/global.lua") == 0), @@ -167,9 +145,9 @@ void loadModules() { modulesLoadHelper((g_luaEnvironment.loadFile("data/npclib/load.lua") == 0), "data/npclib/load.lua"); - modulesLoadHelper(g_scripts->loadScripts("scripts/lib", true, false), + modulesLoadHelper(g_scripts().loadScripts("scripts/lib", true, false), "data/scripts/libs"); - modulesLoadHelper(g_vocations.loadFromXml(), + modulesLoadHelper(g_vocations().loadFromXml(), "data/XML/vocations.xml"); modulesLoadHelper(g_game().loadScheduleEventFromXml(), "data/XML/events.xml"); @@ -177,18 +155,18 @@ void loadModules() { "data/XML/outfits.xml"); modulesLoadHelper(Familiars::getInstance().loadFromXml(), "data/XML/familiars.xml"); - modulesLoadHelper(g_imbuements->loadFromXml(), + modulesLoadHelper(g_imbuements().loadFromXml(), "data/XML/imbuements.xml"); - modulesLoadHelper(g_modules->loadFromXml(), + modulesLoadHelper(g_modules().loadFromXml(), "data/modules/modules.xml"); - modulesLoadHelper(g_events->loadFromXml(), + modulesLoadHelper(g_events().loadFromXml(), "data/events/events.xml"); - modulesLoadHelper(g_scripts->loadScripts("scripts", false, false), + modulesLoadHelper(g_scripts().loadScripts("scripts", false, false), "data/scripts"); - modulesLoadHelper(g_scripts->loadScripts("monster", false, false), + modulesLoadHelper(g_scripts().loadScripts("monster", false, false), "data/monster"); - modulesLoadHelper(g_scripts->loadScripts("npc", false, false), - "data/npc"); + modulesLoadHelper(g_scripts().loadScripts("npc", false, false), + "data/npclua"); g_game().loadBoostedCreature(); } @@ -209,10 +187,10 @@ int main(int argc, char* argv[]) { ServiceManager serviceManager; - g_dispatcher.start(); - g_scheduler.start(); + g_dispatcher().start(); + g_scheduler().start(); - g_dispatcher.addTask(createTask(std::bind(mainLoader, argc, argv, + g_dispatcher().addTask(createTask(std::bind(mainLoader, argc, argv, &serviceManager))); g_loaderSignal.wait(g_loaderUniqueLock); @@ -223,14 +201,14 @@ int main(int argc, char* argv[]) { serviceManager.run(); } else { SPDLOG_ERROR("No services running. The server is NOT online!"); - g_databaseTasks.shutdown(); - g_dispatcher.shutdown(); + g_databaseTasks().shutdown(); + g_dispatcher().shutdown(); exit(-1); } - g_scheduler.join(); - g_databaseTasks.join(); - g_dispatcher.join(); + g_scheduler().join(); + g_databaseTasks().join(); + g_dispatcher().join(); return 0; } #endif @@ -292,7 +270,6 @@ void mainLoader(int, char*[], ServiceManager* services) { } // Init and load modules - initGlobalScopes(); loadModules(); #ifdef _WIN32 diff --git a/src/security/rsa.cpp b/src/security/rsa.cpp index 493a36da415..4664de4cde5 100644 --- a/src/security/rsa.cpp +++ b/src/security/rsa.cpp @@ -29,13 +29,13 @@ static CryptoPP::AutoSeededRandomPool prng; -void RSA2::decrypt(char* msg) const +void RSA2::decrypt(uint8_t* msg) const { try { - CryptoPP::Integer m{reinterpret_cast(msg), 128}; + CryptoPP::Integer m{msg, 128}; auto c = pk.CalculateInverse(prng, m); - c.Encode(reinterpret_cast(msg), 128); + c.Encode(msg, 128); } catch (const CryptoPP::Exception &e) { diff --git a/src/security/rsa.h b/src/security/rsa.h index 0d95b4bb45e..c5e351ee824 100644 --- a/src/security/rsa.h +++ b/src/security/rsa.h @@ -33,11 +33,20 @@ class RSA2 RSA2(const RSA2&) = delete; RSA2& operator=(const RSA2&) = delete; + static RSA2& getInstance() { + // Guaranteed to be destroyed + static RSA2 instance; + // Instantiated on first use + return instance; + } + void loadPEM(const std::string& filename); - void decrypt(char* msg) const; + void decrypt(uint8_t* msg) const; private: CryptoPP::RSA::PrivateKey pk; }; +constexpr auto g_RSA = &RSA2::getInstance; + #endif // SRC_SECURITY_RSA_H_ diff --git a/src/server/network/connection/connection.cpp b/src/server/network/connection/connection.cpp index 76711cb1e42..3924ea2e6a5 100644 --- a/src/server/network/connection/connection.cpp +++ b/src/server/network/connection/connection.cpp @@ -69,7 +69,7 @@ void Connection::close(bool force) connectionState = CONNECTION_STATE_DISCONNECTED; if (protocol) { - g_dispatcher.addTask( + g_dispatcher().addTask( createTask(std::bind(&Protocol::release, protocol))); } @@ -103,7 +103,7 @@ Connection::~Connection() void Connection::accept(Protocol_ptr conProtocol) { this->protocol = conProtocol; - g_dispatcher.addTask(createTask(std::bind(&Protocol::onConnect, protocol))); + g_dispatcher().addTask(createTask(std::bind(&Protocol::onConnect, protocol))); connectionState = CONNECTION_STATE_CONNECTING_STAGE2; accept(); diff --git a/src/server/network/message/outputmessage.cpp b/src/server/network/message/outputmessage.cpp index b25c3160aed..d06a409c976 100644 --- a/src/server/network/message/outputmessage.cpp +++ b/src/server/network/message/outputmessage.cpp @@ -24,7 +24,6 @@ #include "utils/lockfree.h" #include "game/scheduling/scheduler.h" -extern Scheduler g_scheduler; const uint16_t OUTPUTMESSAGE_FREE_LIST_CAPACITY = 2048; const std::chrono::milliseconds OUTPUTMESSAGE_AUTOSEND_DELAY {10}; @@ -32,7 +31,7 @@ const std::chrono::milliseconds OUTPUTMESSAGE_AUTOSEND_DELAY {10}; void OutputMessagePool::scheduleSendAll() { auto functor = std::bind(&OutputMessagePool::sendAll, this); - g_scheduler.addEvent(createSchedulerTask(OUTPUTMESSAGE_AUTOSEND_DELAY.count(), functor)); + g_scheduler().addEvent(createSchedulerTask(OUTPUTMESSAGE_AUTOSEND_DELAY.count(), functor)); } void OutputMessagePool::sendAll() diff --git a/src/server/network/protocol/protocol.cpp b/src/server/network/protocol/protocol.cpp index bd15bb598e4..59112f18b5b 100644 --- a/src/server/network/protocol/protocol.cpp +++ b/src/server/network/protocol/protocol.cpp @@ -24,7 +24,6 @@ #include "security/rsa.h" #include "security/xtea.h" -extern RSA2 g_RSA; void Protocol::onSendMessage(const OutputMessage_ptr& msg) { @@ -99,7 +98,7 @@ bool Protocol::RSA_decrypt(NetworkMessage& msg) return false; } - g_RSA.decrypt(reinterpret_cast(msg.getBuffer()) + msg.getBufferPosition()); //does not break strict aliasing + g_RSA().decrypt(msg.getBuffer() + msg.getBufferPosition()); //does not break strict aliasing return msg.getByte() == 0; } diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 914be3456d0..7e08feb2aaf 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -39,25 +39,17 @@ #include "creatures/players/management/waitlist.h" #include "items/weapons/weapons.h" -extern Actions actions; -extern CreatureEvents *g_creatureEvents; -extern Vocations g_vocations; -extern Chat *g_chat; -extern Modules *g_modules; -extern Spells *g_spells; -extern Imbuements *g_imbuements; -extern Monsters g_monsters; template void ProtocolGame::addGameTask(Callable function, Args &&... args) { - g_dispatcher.addTask(createTask(std::bind(function, &g_game(), std::forward(args)...))); + g_dispatcher().addTask(createTask(std::bind(function, &g_game(), std::forward(args)...))); } template void ProtocolGame::addGameTaskTimed(uint32_t delay, Callable function, Args &&... args) { - g_dispatcher.addTask(createTask(delay, std::bind(function, &g_game(), std::forward(args)...))); + g_dispatcher().addTask(createTask(delay, std::bind(function, &g_game(), std::forward(args)...))); } void ProtocolGame::AddItem(NetworkMessage &msg, uint16_t id, uint8_t count) @@ -363,7 +355,7 @@ void ProtocolGame::login(const std::string &name, uint32_t accountId, OperatingS foundPlayer->disconnect(); foundPlayer->isConnecting = true; - eventConnect = g_scheduler.addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::connect, getThis(), foundPlayer->getID(), operatingSystem))); + eventConnect = g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::connect, getThis(), foundPlayer->getID(), operatingSystem))); } else { @@ -394,7 +386,7 @@ void ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem) player = foundPlayer; player->incrementReferenceCounter(); - g_chat->removeUserFromAllChannels(*player); + g_chat().removeUserFromAllChannels(*player); player->clearModalWindows(); player->setOperatingSystem(operatingSystem); player->isConnecting = false; @@ -426,7 +418,7 @@ void ProtocolGame::logout(bool displayEffect, bool forced) } } - if (removePlayer && !g_creatureEvents->playerLogout(player)) { + if (removePlayer && !g_creatureEvents().playerLogout(player)) { return; } @@ -553,7 +545,7 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage &msg) return; } - g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::login, getThis(), characterName, accountId, operatingSystem))); + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::login, getThis(), characterName, accountId, operatingSystem))); } void ProtocolGame::onConnect() @@ -640,18 +632,18 @@ void ProtocolGame::parsePacket(NetworkMessage& msg) if (recvbyte != 0x1D && recvbyte != 0x1E) { // keep the connection alive - g_scheduler.addEvent(createSchedulerTask(500, std::bind(&ProtocolGame::sendPing, getThis()))); - g_scheduler.addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::sendPingBack, getThis()))); + g_scheduler().addEvent(createSchedulerTask(500, std::bind(&ProtocolGame::sendPing, getThis()))); + g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::sendPingBack, getThis()))); return; } } // Modules system if(player && recvbyte != 0xD3){ - g_dispatcher.addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player->getID(), msg, recvbyte))); + g_dispatcher().addTask(createTask(std::bind(&Modules::executeOnRecvbyte, &g_modules(), player->getID(), msg, recvbyte))); } - g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte))); + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte))); } void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyte) @@ -665,7 +657,7 @@ void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyt } switch (recvbyte) { - case 0x14: g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::logout, getThis(), true, false))); break; + case 0x14: g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::logout, getThis(), true, false))); break; case 0x1D: addGameTask(&Game::playerReceivePingBack, player->getID()); break; case 0x1E: addGameTask(&Game::playerReceivePing, player->getID()); break; case 0x2a: addBestiaryTrackerList(msg); break; @@ -743,8 +735,8 @@ void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyt case 0xCC: parseSeekInContainer(msg); break; case 0xCD: parseInspectionObject(msg); break; case 0xD2: addGameTask(&Game::playerRequestOutfit, player->getID()); break; - //g_dispatcher.addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player, msg, recvbyte))); - case 0xD3: g_dispatcher.addTask(createTask(std::bind(&ProtocolGame::parseSetOutfit, getThis(), msg))); break; + //g_dispatcher().addTask(createTask(std::bind(&Modules::executeOnRecvbyte, g_modules, player, msg, recvbyte))); + case 0xD3: g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parseSetOutfit, getThis(), msg))); break; case 0xD4: parseToggleMount(msg); break; case 0xD5: parseApplyImbuement(msg); break; case 0xD6: parseClearImbuement(msg); break; @@ -1137,7 +1129,7 @@ void ProtocolGame::parseSetOutfit(NetworkMessage &msg) } uint16_t startBufferPosition = msg.getBufferPosition(); - Module *outfitModule = g_modules->getEventByRecvbyte(0xD3, false); + Module *outfitModule = g_modules().getEventByRecvbyte(0xD3, false); if (outfitModule) { outfitModule->executeOnRecvbyte(player, msg); @@ -1639,7 +1631,7 @@ void ProtocolGame::sendHighscores(const std::vector &charact msg.addString("(all)"); // All Vocations - hardcoded uint32_t selectedVocation = 0xFFFFFFFF; - const auto &vocationsMap = g_vocations.getVocations(); + const auto &vocationsMap = g_vocations().getVocations(); for (const auto &it : vocationsMap) { const Vocation &vocation = it.second; @@ -1771,7 +1763,7 @@ void ProtocolGame::parseBestiarysendRaces() uint16_t count = 0; for (auto rit : mtype_list) { - MonsterType *mtype = g_monsters.getMonsterType(rit.second); + const MonsterType *mtype = g_monsters().getMonsterType(rit.second); if (!mtype) { return; @@ -1811,7 +1803,7 @@ void ProtocolGame::parseBestiarysendMonsterData(NetworkMessage &msg) auto ait = mtype_list.find(raceId); if (ait != mtype_list.end()) { - MonsterType *mType = g_monsters.getMonsterType(ait->second); + MonsterType *mType = g_monsters().getMonsterType(ait->second); if (mType) { Class = mType->info.bestiaryClass; @@ -1945,7 +1937,7 @@ void ProtocolGame::addBestiaryTrackerList(NetworkMessage &msg) auto it = mtype_list.find(thisrace); if (it != mtype_list.end()) { - MonsterType *mtype = g_monsters.getMonsterType(it->second); + MonsterType *mtype = g_monsters().getMonsterType(it->second); if (mtype) { player->addBestiaryTrackerList(mtype); @@ -2456,7 +2448,7 @@ void ProtocolGame::parseBestiarysendCreatures(NetworkMessage &msg) { if (_it.first == raceid_) { - MonsterType *tmpType = g_monsters.getMonsterType(it_.second); + MonsterType *tmpType = g_monsters().getMonsterType(it_.second); if (!tmpType) { return; @@ -3516,7 +3508,7 @@ void ProtocolGame::sendBasicData() msg.addByte(1); // has reached Main (allow player to open Prey window) } - std::list spellsList = g_spells->getSpellsByVocation(player->getVocationId()); + std::list spellsList = g_spells().getSpellsByVocation(player->getVocationId()); msg.add(spellsList.size()); for (uint16_t sid : spellsList) { @@ -3694,7 +3686,7 @@ void ProtocolGame::sendChannelsDialog() NetworkMessage msg; msg.addByte(0xAB); - const ChannelList &list = g_chat->getChannelList(*player); + const ChannelList &list = g_chat().getChannelList(*player); msg.addByte(list.size()); for (ChatChannel *channel : list) { @@ -4160,7 +4152,7 @@ void ProtocolGame::updateCoinBalance() return; } - g_dispatcher.addTask( + g_dispatcher().addTask( createTask(std::bind([](uint32_t playerId) { Player* threadPlayer = g_game().getPlayerByID(playerId); if (threadPlayer) { @@ -6508,11 +6500,11 @@ void ProtocolGame::AddOutfit(NetworkMessage &msg, const Outfit_t &outfit, bool a } } -void ProtocolGame::addImbuementInfo(NetworkMessage &msg, uint32_t imbuementId) +void ProtocolGame::addImbuementInfo(NetworkMessage &msg, uint16_t imbuementId) const { - Imbuement *imbuement = g_imbuements->getImbuement(imbuementId); - const BaseImbuement *baseImbuement = g_imbuements->getBaseByID(imbuement->getBaseID()); - CategoryImbuement *categoryImbuement = g_imbuements->getCategoryByID(imbuement->getCategory()); + Imbuement *imbuement = g_imbuements().getImbuement(imbuementId); + const BaseImbuement *baseImbuement = g_imbuements().getBaseByID(imbuement->getBaseID()); + const CategoryImbuement *categoryImbuement = g_imbuements().getCategoryByID(imbuement->getCategory()); msg.add(imbuementId); msg.addString(baseImbuement->name + " " + imbuement->getName()); @@ -6570,10 +6562,10 @@ void ProtocolGame::openImbuementWindow(Item *item) msg.addByte(0x01); addImbuementInfo(msg, imbuementInfo.imbuement->getID()); msg.add(imbuementInfo.duration); - msg.add(g_imbuements->getBaseByID(imbuementInfo.imbuement->getBaseID())->removeCost); + msg.add(g_imbuements().getBaseByID(imbuementInfo.imbuement->getBaseID())->removeCost); } - std::vector imbuements = g_imbuements->getImbuements(player, item); + std::vector imbuements = g_imbuements().getImbuements(player, item); std::unordered_map needItems; msg.add(imbuements.size()); diff --git a/src/server/network/protocol/protocolgame.h b/src/server/network/protocol/protocolgame.h index 8fa2e3257ee..b2f117ec61c 100644 --- a/src/server/network/protocol/protocolgame.h +++ b/src/server/network/protocol/protocolgame.h @@ -233,7 +233,7 @@ class ProtocolGame final : public Protocol void parseCoinTransfer(NetworkMessage &msg); // Imbuement info - void addImbuementInfo(NetworkMessage &msg, uint32_t imbuementId); + void addImbuementInfo(NetworkMessage &msg, uint16_t imbuementId) const; //Send functions void sendChannelMessage(const std::string &author, const std::string &text, SpeakClasses type, uint16_t channel); diff --git a/src/server/network/protocol/protocollogin.cpp b/src/server/network/protocol/protocollogin.cpp index 766a74abff4..2532289d8ee 100644 --- a/src/server/network/protocol/protocollogin.cpp +++ b/src/server/network/protocol/protocollogin.cpp @@ -187,5 +187,5 @@ void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) } auto thisPtr = std::static_pointer_cast(shared_from_this()); - g_dispatcher.addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, thisPtr, email, password, version))); + g_dispatcher().addTask(createTask(std::bind(&ProtocolLogin::getCharacterList, thisPtr, email, password, version))); } diff --git a/src/server/network/protocol/protocolstatus.cpp b/src/server/network/protocol/protocolstatus.cpp index 1de279408c4..e8bf050ccda 100644 --- a/src/server/network/protocol/protocolstatus.cpp +++ b/src/server/network/protocol/protocolstatus.cpp @@ -49,7 +49,7 @@ void ProtocolStatus::onRecvFirstMessage(NetworkMessage& msg) //XML info protocol case 0xFF: { if (msg.getString(4) == "info") { - g_dispatcher.addTask(createTask(std::bind( + g_dispatcher().addTask(createTask(std::bind( &ProtocolStatus::sendStatusString, std::static_pointer_cast< ProtocolStatus>(shared_from_this())))); @@ -65,7 +65,7 @@ void ProtocolStatus::onRecvFirstMessage(NetworkMessage& msg) if (requestedInfo & REQUEST_PLAYER_STATUS_INFO) { characterName = msg.getString(); } - g_dispatcher.addTask(createTask(std::bind(&ProtocolStatus::sendInfo, std::static_pointer_cast(shared_from_this()), + g_dispatcher().addTask(createTask(std::bind(&ProtocolStatus::sendInfo, std::static_pointer_cast(shared_from_this()), requestedInfo, characterName))); return; } diff --git a/src/server/server.cpp b/src/server/server.cpp index a4de00f007a..7672bcc1fe0 100644 --- a/src/server/server.cpp +++ b/src/server/server.cpp @@ -124,7 +124,7 @@ void ServicePort::onAccept(Connection_ptr connection, const boost::system::error if (!pendingStart) { close(); pendingStart = true; - g_scheduler.addEvent(createSchedulerTask(15000, + g_scheduler().addEvent(createSchedulerTask(15000, std::bind(&ServicePort::openAcceptor, std::weak_ptr(shared_from_this()), serverPort))); @@ -187,7 +187,7 @@ void ServicePort::open(uint16_t port) SPDLOG_WARN("[ServicePort::open] - Error: {}", e.what()); pendingStart = true; - g_scheduler.addEvent(createSchedulerTask(15000, + g_scheduler().addEvent(createSchedulerTask(15000, std::bind(&ServicePort::openAcceptor, std::weak_ptr(shared_from_this()), port))); } } diff --git a/src/server/signals.cpp b/src/server/signals.cpp index da0cd7d5488..8f98a0bf77e 100644 --- a/src/server/signals.cpp +++ b/src/server/signals.cpp @@ -35,20 +35,6 @@ #include "lua/scripts/lua_environment.hpp" #include "server/signals.h" -extern Scheduler g_scheduler; -extern DatabaseTasks g_databaseTasks; -extern Dispatcher g_dispatcher; - -extern Actions* g_actions; -extern Monsters g_monsters; -extern TalkActions* g_talkActions; -extern Spells* g_spells; -extern CreatureEvents* g_creatureEvents; -extern GlobalEvents* g_globalEvents; -extern Events* g_events; -extern Chat* g_chat; -extern LuaEnvironment g_luaEnvironment; - using ErrorCode = boost::system::error_code; Signals::Signals(boost::asio::io_service& service) : @@ -89,25 +75,25 @@ void Signals::dispatchSignalHandler(int signal) { switch(signal) { case SIGINT: //Shuts the server down - g_dispatcher.addTask(createTask(sigintHandler)); + g_dispatcher().addTask(createTask(sigintHandler)); break; case SIGTERM: //Shuts the server down - g_dispatcher.addTask(createTask(sigtermHandler)); + g_dispatcher().addTask(createTask(sigtermHandler)); break; #ifndef _WIN32 case SIGHUP: //Reload config/data - g_dispatcher.addTask(createTask(sighupHandler)); + g_dispatcher().addTask(createTask(sighupHandler)); break; case SIGUSR1: //Saves game state - g_dispatcher.addTask(createTask(sigusr1Handler)); + g_dispatcher().addTask(createTask(sigusr1Handler)); break; #else case SIGBREAK: //Shuts the server down - g_dispatcher.addTask(createTask(sigbreakHandler)); + g_dispatcher().addTask(createTask(sigbreakHandler)); // hold the thread until other threads end - g_scheduler.join(); - g_databaseTasks.join(); - g_dispatcher.join(); + g_scheduler().join(); + g_databaseTasks().join(); + g_dispatcher().join(); break; #endif default: @@ -154,10 +140,10 @@ void Signals::sighupHandler() g_game().mounts.reload(); SPDLOG_INFO("Reloaded mounts"); - g_events->loadFromXml(); + g_events().loadFromXml(); SPDLOG_INFO("Reloaded events"); - g_chat->load(); + g_chat().load(); SPDLOG_INFO("Reloaded chatchannels"); g_luaEnvironment.loadFile("data/global.lua");