From b6ae71b9705ea879d705b9b9ba9be3bdf4023f16 Mon Sep 17 00:00:00 2001 From: Leandro Date: Sun, 29 May 2016 16:45:06 -0430 Subject: [PATCH 1/2] Fix exhaust for 7x (error al compilar) --- path_7_x/sources/spells.cpp | 728 ++++++++++++++++++------------------ 1 file changed, 365 insertions(+), 363 deletions(-) diff --git a/path_7_x/sources/spells.cpp b/path_7_x/sources/spells.cpp index 779ed06b3..2c9a07ba0 100644 --- a/path_7_x/sources/spells.cpp +++ b/path_7_x/sources/spells.cpp @@ -35,8 +35,8 @@ extern Spells* g_spells; extern Monsters g_monsters; extern ConfigManager g_config; -Spells::Spells(): -m_interface("Spell Interface") +Spells::Spells() : + m_interface("Spell Interface") { m_interface.initState(); spellId = 0; @@ -48,42 +48,42 @@ ReturnValue Spells::onPlayerSay(Player* player, const std::string& words) trimString(reWords); InstantSpell* instantSpell = getInstantSpell(reWords); - if(!instantSpell) + if (!instantSpell) return RET_NOTPOSSIBLE; size_t size = instantSpell->getWords().length(); std::string param = reWords.substr(size, reWords.length() - size), reParam = ""; - if(instantSpell->getHasParam() && !param.empty() && param[0] == ' ') + if (instantSpell->getHasParam() && !param.empty() && param[0] == ' ') { size_t quote = param.find('"', 1); - if(quote != std::string::npos) + if (quote != std::string::npos) { size_t tmp = param.find('"', quote + 1); - if(tmp == std::string::npos) + if (tmp == std::string::npos) tmp = param.length(); reParam = param.substr(quote + 1, tmp - quote - 1); } - else if(param.find(' ', 1) == std::string::npos) + else if (param.find(' ', 1) == std::string::npos) reParam = param.substr(1, param.length()); trimString(reParam); } Position pos = player->getPosition(); - if(!instantSpell->castInstant(player, reParam)) + if (!instantSpell->castInstant(player, reParam)) return RET_NEEDEXCHANGE; MessageClasses type = MSG_SPEAK_SAY; - if(g_config.getBool(ConfigManager::EMOTE_SPELLS)) + if (g_config.getBool(ConfigManager::EMOTE_SPELLS)) type = MSG_SPEAK_MONSTER_SAY; - if(!g_config.getBool(ConfigManager::SPELL_NAME_INSTEAD_WORDS)) + if (!g_config.getBool(ConfigManager::SPELL_NAME_INSTEAD_WORDS)) { - if(g_config.getBool(ConfigManager::UNIFIED_SPELLS)) + if (g_config.getBool(ConfigManager::UNIFIED_SPELLS)) { reWords = instantSpell->getWords(); - if(instantSpell->getHasParam()) + if (instantSpell->getHasParam()) reWords += " \"" + reParam + "\""; } @@ -92,14 +92,14 @@ ReturnValue Spells::onPlayerSay(Player* player, const std::string& words) } std::string ret = instantSpell->getName(); - if(param.length()) + if (param.length()) { trimString(param); size_t tmp = 0, rtmp = param.length(); - if(param[0] == '"') + if (param[0] == '"') tmp = 1; - if(param[rtmp] == '"') + if (param[rtmp] == '"') rtmp -= 1; ret += ": " + param.substr(tmp, rtmp); @@ -111,11 +111,11 @@ ReturnValue Spells::onPlayerSay(Player* player, const std::string& words) void Spells::clear() { - for(RunesMap::iterator rit = runes.begin(); rit != runes.end(); ++rit) + for (RunesMap::iterator rit = runes.begin(); rit != runes.end(); ++rit) delete rit->second; runes.clear(); - for(InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) + for (InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) delete it->second; instants.clear(); @@ -126,13 +126,13 @@ void Spells::clear() Event* Spells::getEvent(const std::string& nodeName) { std::string tmpNodeName = asLowerCaseString(nodeName); - if(tmpNodeName == "rune") + if (tmpNodeName == "rune") return new RuneSpell(&m_interface); - if(tmpNodeName == "instant") + if (tmpNodeName == "instant") return new InstantSpell(&m_interface); - if(tmpNodeName == "conjure") + if (tmpNodeName == "conjure") return new ConjureSpell(&m_interface); return NULL; @@ -140,17 +140,17 @@ Event* Spells::getEvent(const std::string& nodeName) bool Spells::registerEvent(Event* event, xmlNodePtr, bool override) { - if(InstantSpell* instant = dynamic_cast(event)) + if (InstantSpell* instant = dynamic_cast(event)) { InstantsMap::iterator it = instants.find(instant->getWords()); instant->setId(spellId++); - if(it == instants.end()) + if (it == instants.end()) { instants[instant->getWords()] = instant; return true; } - if(override) + if (override) { delete it->second; it->second = instant; @@ -161,17 +161,17 @@ bool Spells::registerEvent(Event* event, xmlNodePtr, bool override) return false; } - if(RuneSpell* rune = dynamic_cast(event)) + if (RuneSpell* rune = dynamic_cast(event)) { RunesMap::iterator it = runes.find(rune->getRuneItemId()); rune->setId(spellId++); - if(it == runes.end()) + if (it == runes.end()) { runes[rune->getRuneItemId()] = rune; return true; } - if(override) + if (override) { delete it->second; it->second = rune; @@ -188,7 +188,7 @@ bool Spells::registerEvent(Event* event, xmlNodePtr, bool override) Spell* Spells::getSpellByName(const std::string& name) { Spell* spell; - if((spell = getRuneSpellByName(name)) || (spell = getInstantSpellByName(name))) + if ((spell = getRuneSpellByName(name)) || (spell = getInstantSpellByName(name))) return spell; return NULL; @@ -197,7 +197,7 @@ Spell* Spells::getSpellByName(const std::string& name) RuneSpell* Spells::getRuneSpell(uint32_t id) { RunesMap::iterator it = runes.find(id); - if(it != runes.end()) + if (it != runes.end()) return it->second; return NULL; @@ -205,9 +205,9 @@ RuneSpell* Spells::getRuneSpell(uint32_t id) RuneSpell* Spells::getRuneSpellByName(const std::string& name) { - for(RunesMap::iterator it = runes.begin(); it != runes.end(); ++it) + for (RunesMap::iterator it = runes.begin(); it != runes.end(); ++it) { - if(boost::algorithm::iequals(it->second->getName(), name)) + if (boost::algorithm::iequals(it->second->getName(), name)) return it->second; } @@ -217,21 +217,21 @@ RuneSpell* Spells::getRuneSpellByName(const std::string& name) InstantSpell* Spells::getInstantSpell(const std::string& words) { InstantSpell* result = NULL; - for(InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) + for (InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) { InstantSpell* instantSpell = it->second; - if(!asLowerCaseString(words).compare(0, instantSpell->getWords().length(), + if (!asLowerCaseString(words).compare(0, instantSpell->getWords().length(), asLowerCaseString(instantSpell->getWords()))) { - if(!result || instantSpell->getWords().length() > result->getWords().length()) + if (!result || instantSpell->getWords().length() > result->getWords().length()) result = instantSpell; } } - if(result && words.length() > result->getWords().length()) + if (result && words.length() > result->getWords().length()) { std::string param = words.substr(result->getWords().length(), words.length()); - if(param[0] != ' ' || (param.length() > 1 && (!result->getHasParam() || param.find(' ', 1) != std::string::npos) && param[1] != '"')) + if (param[0] != ' ' || (param.length() > 1 && (!result->getHasParam() || param.find(' ', 1) != std::string::npos) && param[1] != '"')) return NULL; } @@ -241,9 +241,9 @@ InstantSpell* Spells::getInstantSpell(const std::string& words) uint32_t Spells::getInstantSpellCount(const Player* player) { uint32_t count = 0; - for(InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) + for (InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) { - if(it->second->canCast(player)) + if (it->second->canCast(player)) ++count; } @@ -253,13 +253,13 @@ uint32_t Spells::getInstantSpellCount(const Player* player) InstantSpell* Spells::getInstantSpellByIndex(const Player* player, uint32_t index) { uint32_t count = 0; - for(InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) + for (InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) { InstantSpell* instantSpell = it->second; - if(!instantSpell->canCast(player)) + if (!instantSpell->canCast(player)) continue; - if(count == index) + if (count == index) return instantSpell; ++count; @@ -271,9 +271,9 @@ InstantSpell* Spells::getInstantSpellByIndex(const Player* player, uint32_t inde InstantSpell* Spells::getInstantSpellByName(const std::string& name) { std::string tmpName = asLowerCaseString(name); - for(InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) + for (InstantsMap::iterator it = instants.begin(); it != instants.end(); ++it) { - if(tmpName == asLowerCaseString(it->second->getName())) + if (tmpName == asLowerCaseString(it->second->getName())) return it->second; } @@ -287,14 +287,14 @@ Position Spells::getCasterPosition(Creature* creature, Direction dir) bool BaseSpell::castSpell(Creature* creature) { - if(!creature) + if (!creature) return false; bool success = true; CreatureEventList castEvents = creature->getCreatureEvents(CREATURE_EVENT_CAST); - for(CreatureEventList::iterator it = castEvents.begin(); it != castEvents.end(); ++it) + for (CreatureEventList::iterator it = castEvents.begin(); it != castEvents.end(); ++it) { - if(!(*it)->executeCast(creature) && success) + if (!(*it)->executeCast(creature) && success) success = false; } @@ -303,14 +303,14 @@ bool BaseSpell::castSpell(Creature* creature) bool BaseSpell::castSpell(Creature* creature, Creature* target) { - if(!creature || !target) + if (!creature || !target) return false; bool success = true; CreatureEventList castEvents = creature->getCreatureEvents(CREATURE_EVENT_CAST); - for(CreatureEventList::iterator it = castEvents.begin(); it != castEvents.end(); ++it) + for (CreatureEventList::iterator it = castEvents.begin(); it != castEvents.end(); ++it) { - if(!(*it)->executeCast(creature, target) && success) + if (!(*it)->executeCast(creature, target) && success) success = false; } @@ -320,7 +320,7 @@ bool BaseSpell::castSpell(Creature* creature, Creature* target) CombatSpell::CombatSpell(Combat* _combat, bool _needTarget, bool _needDirection) : Event(&g_spells->getInterface()) { - combat =_combat; + combat = _combat; needTarget = _needTarget; needDirection = _needDirection; } @@ -332,7 +332,7 @@ CombatSpell::~CombatSpell() bool CombatSpell::loadScriptCombat() { - if(m_interface->reserveEnv()) + if (m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); combat = env->getCombatObject(env->getLastCombatId()); @@ -346,14 +346,14 @@ bool CombatSpell::loadScriptCombat() bool CombatSpell::castSpell(Creature* creature) { - if(!BaseSpell::castSpell(creature)) + if (!BaseSpell::castSpell(creature)) return false; - if(isScripted()) + if (isScripted()) { LuaVariant var; var.type = VARIANT_POSITION; - if(needDirection) + if (needDirection) var.pos = Spells::getCasterPosition(creature, creature->getDirection()); else var.pos = creature->getPosition(); @@ -362,7 +362,7 @@ bool CombatSpell::castSpell(Creature* creature) } Position pos; - if(needDirection) + if (needDirection) pos = Spells::getCasterPosition(creature, creature->getDirection()); else pos = creature->getPosition(); @@ -373,18 +373,18 @@ bool CombatSpell::castSpell(Creature* creature) bool CombatSpell::castSpell(Creature* creature, Creature* target) { - if(!BaseSpell::castSpell(creature, target)) + if (!BaseSpell::castSpell(creature, target)) return false; - if(isScripted()) + if (isScripted()) { LuaVariant var; - if(combat->hasArea()) + if (combat->hasArea()) { var.type = VARIANT_POSITION; - if(needTarget) + if (needTarget) var.pos = target->getPosition(); - else if(needDirection) + else if (needDirection) var.pos = Spells::getCasterPosition(creature, creature->getDirection()); else var.pos = creature->getPosition(); @@ -398,9 +398,9 @@ bool CombatSpell::castSpell(Creature* creature, Creature* target) return executeCastSpell(creature, var); } - if(combat->hasArea()) + if (combat->hasArea()) { - if(!needTarget) + if (!needTarget) return castSpell(creature); combat->doCombat(creature, target->getPosition()); @@ -414,10 +414,10 @@ bool CombatSpell::castSpell(Creature* creature, Creature* target) bool CombatSpell::executeCastSpell(Creature* creature, const LuaVariant& var) { //onCastSpell(cid, var) - if(m_interface->reserveEnv()) + if (m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); - if(m_scripted == EVENT_SCRIPT_BUFFER) + if (m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(creature->getPosition()); std::stringstream scriptstream; @@ -427,7 +427,7 @@ bool CombatSpell::executeCastSpell(Creature* creature, const LuaVariant& var) scriptstream << *m_scriptData; bool result = true; - if(m_interface->loadBuffer(scriptstream.str())) + if (m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); @@ -438,11 +438,11 @@ bool CombatSpell::executeCastSpell(Creature* creature, const LuaVariant& var) } else { - #ifdef __DEBUG_LUASCRIPTS__ +#ifdef __DEBUG_LUASCRIPTS__ char desc[60]; sprintf(desc, "onCastSpell - %s", creature->getName().c_str()); env->setEvent(desc); - #endif +#endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(creature->getPosition()); @@ -471,9 +471,9 @@ Spell::Spell() magLevel = 0; mana = 0; manaPercent = 0; - #ifdef _MULTIPLATFORM76 +#ifdef _MULTIPLATFORM76 soul = 0; - #endif +#endif range = -1; exhaustion = 1000; needTarget = false; @@ -486,7 +486,7 @@ Spell::Spell() isAggressive = true; learnable = false; - for(int32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) + for (int32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) skills[i] = 10; } @@ -494,7 +494,7 @@ bool Spell::configureSpell(xmlNodePtr p) { int32_t intValue; std::string strValue; - if(readXMLString(p, "name", strValue)) + if (readXMLString(p, "name", strValue)) { name = strValue; const char* reservedList[] = @@ -505,9 +505,9 @@ bool Spell::configureSpell(xmlNodePtr p) "cursecondition" }; - for(uint32_t i = 0; i < sizeof(reservedList) / sizeof(const char*); ++i) + for (uint32_t i = 0; i < sizeof(reservedList) / sizeof(const char*); ++i) { - if(boost::algorithm::iequals(reservedList[i], name.c_str())) + if (boost::algorithm::iequals(reservedList[i], name.c_str())) { std::clog << "[Error - Spell::configureSpell] Spell is using a reserved name: " << reservedList[i] << std::endl; return false; @@ -520,22 +520,22 @@ bool Spell::configureSpell(xmlNodePtr p) return false; } - if(readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)) + if (readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue)) level = intValue; - if(readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "magiclevel", intValue)) + if (readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "magiclevel", intValue)) magLevel = intValue; - if(readXMLString(p, "skill", strValue) || readXMLString(p, "skills", strValue) || readXMLInteger(p, "skillpoints", intValue)) + if (readXMLString(p, "skill", strValue) || readXMLString(p, "skills", strValue) || readXMLInteger(p, "skillpoints", intValue)) { std::vector strVector = explodeString(strValue, ";"), tmpVector; - for(std::vector::iterator it = strVector.begin(); it != strVector.end(); ++it) + for (std::vector::iterator it = strVector.begin(); it != strVector.end(); ++it) { tmpVector = explodeString(*it, ","); - if(tmpVector.size() > 1) + if (tmpVector.size() > 1) { intValue = atoi(tmpVector[0].c_str()); - if(!intValue) + if (!intValue) skills[getSkillId(tmpVector[0])] = atoi(tmpVector[1].c_str()); else skills[intValue] = atoi(tmpVector[1].c_str()); @@ -543,108 +543,107 @@ bool Spell::configureSpell(xmlNodePtr p) } } - if(readXMLInteger(p, "mana", intValue)) + if (readXMLInteger(p, "mana", intValue)) mana = intValue; - if(readXMLInteger(p, "manapercent", intValue)) + if (readXMLInteger(p, "manapercent", intValue)) manaPercent = intValue; - #ifdef _MULTIPLATFORM76 - if(readXMLInteger(p, "soul", intValue)) +#ifdef _MULTIPLATFORM76 + if (readXMLInteger(p, "soul", intValue)) soul = intValue; - #endif +#endif - if(readXMLInteger(p, "exhaustion", intValue)) + if (readXMLInteger(p, "exhaustion", intValue)) exhaustion = intValue; - if(readXMLString(p, "enabled", strValue)) + if (readXMLString(p, "enabled", strValue)) enabled = booleanString(strValue); - if(readXMLString(p, "prem", strValue) || readXMLString(p, "premium", strValue)) + if (readXMLString(p, "prem", strValue) || readXMLString(p, "premium", strValue)) premium = booleanString(strValue); - if(readXMLString(p, "needtarget", strValue)) + if (readXMLString(p, "needtarget", strValue)) needTarget = booleanString(strValue); - if(readXMLString(p, "needweapon", strValue)) + if (readXMLString(p, "needweapon", strValue)) needWeapon = booleanString(strValue); - if(readXMLString(p, "selftarget", strValue)) + if (readXMLString(p, "selftarget", strValue)) selfTarget = booleanString(strValue); - if(readXMLString(p, "needlearn", strValue)) + if (readXMLString(p, "needlearn", strValue)) learnable = booleanString(strValue); - if(readXMLInteger(p, "range", intValue)) + if (readXMLInteger(p, "range", intValue)) range = intValue; - if(readXMLString(p, "blocktype", strValue)) + if (readXMLString(p, "blocktype", strValue)) { std::string tmpStrValue = asLowerCaseString(strValue); - if(tmpStrValue == "all") + if (tmpStrValue == "all") blockingCreature = blockingSolid = true; - else if(tmpStrValue == "solid") + else if (tmpStrValue == "solid") blockingSolid = true; - else if(tmpStrValue == "creature") + else if (tmpStrValue == "creature") blockingCreature = true; else std::clog << "[Warning - Spell::configureSpell] Blocktype \"" << strValue << "\" does not exist." << std::endl; } - else if(readXMLString(p, "blocking", strValue)) + else if (readXMLString(p, "blocking", strValue)) blockingCreature = blockingSolid = booleanString(strValue); - if(readXMLString(p, "aggressive", strValue)) + if (readXMLString(p, "aggressive", strValue)) isAggressive = booleanString(strValue); - - if(!g_config.getBool(ConfigManager::NO_ATTACKHEALING_SIMULTANEUS)) + + if (!g_config.getBool(ConfigManager::NO_ATTACKHEALING_SIMULTANEUS)) { groupExhaustions[SPELLGROUP_ATTACK] = exhaustion; groupExhaustions[SPELLGROUP_HEALING] = exhaustion; } else { - if(readXMLString(p, "groups", strValue)) + if (readXMLString(p, "groups", strValue)) { std::vector strVector = explodeString(strValue, ";"), tmpVector; - for(std::vector::iterator it = strVector.begin(); it != strVector.end(); ++it) + for (std::vector::iterator it = strVector.begin(); it != strVector.end(); ++it) { tmpVector = explodeString((*it), ","); uint32_t id = atoi(tmpVector[0].c_str()), exhaust = isAggressive ? 2000 : 1000; - if(tmpVector.size() > 1) + if (tmpVector.size() > 1) exhaust = atoi(tmpVector[1].c_str()); - if(!id) + if (!id) { strValue = asLowerCaseString(tmpVector[0]); - if(strValue == "attack" || strValue == "attacking") + if (strValue == "attack" || strValue == "attacking") id = SPELLGROUP_ATTACK; - else if(strValue == "heal" || strValue == "healing") + else if (strValue == "heal" || strValue == "healing") id = SPELLGROUP_HEALING; - else if(strValue == "support" || strValue == "supporting") + else if (strValue == "support" || strValue == "supporting") id = SPELLGROUP_SUPPORT; - else if(strValue == "special" || strValue == "ultimate") + else if (strValue == "special" || strValue == "ultimate") id = SPELLGROUP_SPECIAL; } - if(id && exhaust) + if (id && exhaust) groupExhaustions[(SpellGroup_t)id] = exhaust; } } - if(groupExhaustions.empty()) + if (groupExhaustions.empty()) { - if(isAggressive) + if (isAggressive) groupExhaustions[SPELLGROUP_ATTACK] = 2000; else groupExhaustions[SPELLGROUP_HEALING] = 1000; } } - std::string error; - for(xmlNodePtr vocationNode = p->children; vocationNode; vocationNode = vocationNode->next) + for (xmlNodePtr vocationNode = p->children; vocationNode; vocationNode = vocationNode->next) { - if(!parseVocationNode(vocationNode, vocSpellMap, vocStringVec, error)) + if (!parseVocationNode(vocationNode, vocSpellMap, vocStringVec, error)) std::clog << "[Warning - Spell::configureSpell] Spell: " << name << ", " << error << std::endl; } @@ -653,41 +652,48 @@ bool Spell::configureSpell(xmlNodePtr p) bool Spell::checkSpell(Player* player) const { - if(player->hasFlag(PlayerFlag_CannotUseSpells)) + if (player->hasFlag(PlayerFlag_CannotUseSpells)) return false; - if(player->hasFlag(PlayerFlag_IgnoreSpellCheck)) + if (player->hasFlag(PlayerFlag_IgnoreSpellCheck)) return true; - if(!isEnabled()) + if (!isEnabled()) return false; - - if(isAggressive) + if (isAggressive) { - if(!player->hasFlag(PlayerFlag_IgnoreProtectionZone) && player->getZone() == ZONE_PROTECTION) + if (!player->hasFlag(PlayerFlag_IgnoreProtectionZone) && player->getZone() == ZONE_PROTECTION) { player->sendCancelMessage(RET_ACTIONNOTPERMITTEDINPROTECTIONZONE); return false; } - if(!player->hasFlag(PlayerFlag_HasNoExhaustion)) - { + if (player->checkLoginDelay()) + { + player->sendCancelMessage(RET_YOUMAYNOTATTACKIMMEDIATELYAFTERLOGGINGIN); + g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); + return false; + } + } + + if (!player->hasFlag(PlayerFlag_HasNoExhaustion)) + { bool exhausted = false; - if(!g_config.getBool(ConfigManager::NO_ATTACKHEALING_SIMULTANEUS)) + if (!g_config.getBool(ConfigManager::NO_ATTACKHEALING_SIMULTANEUS)) { - if(player->hasCondition(CONDITION_EXHAUST, EXHAUST_SPELLGROUP_ATTACK) || player->hasCondition(CONDITION_EXHAUST, EXHAUST_SPELLGROUP_HEALING)) + if (player->hasCondition(CONDITION_EXHAUST, EXHAUST_SPELLGROUP_ATTACK) || player->hasCondition(CONDITION_EXHAUST, EXHAUST_SPELLGROUP_HEALING)) exhausted = true; } else { - if(g_config.getBool(ConfigManager::ENABLE_COOLDOWNS)) + if (g_config.getBool(ConfigManager::ENABLE_COOLDOWNS)) { - if(!player->hasCondition(CONDITION_SPELLCOOLDOWN, spellId)) + if (!player->hasCondition(CONDITION_SPELLCOOLDOWN, spellId)) { - for(SpellGroup::const_iterator it = groupExhaustions.begin(); it != groupExhaustions.end(); ++it) + for (SpellGroup::const_iterator it = groupExhaustions.begin(); it != groupExhaustions.end(); ++it) { - if(!player->hasCondition(CONDITION_EXHAUST, (Exhaust_t)((int32_t)it->first + 1))) + if (!player->hasCondition(CONDITION_EXHAUST, (Exhaust_t)((int32_t)it->first + 1))) continue; exhausted = true; @@ -697,45 +703,45 @@ bool Spell::checkSpell(Player* player) const else exhausted = true; } - else if(player->hasCondition(CONDITION_EXHAUST, (isAggressive ? EXHAUST_SPELLGROUP_ATTACK : EXHAUST_SPELLGROUP_HEALING))) + else if (player->hasCondition(CONDITION_EXHAUST, (isAggressive ? EXHAUST_SPELLGROUP_ATTACK : EXHAUST_SPELLGROUP_HEALING))) exhausted = true; } - if(exhausted) + if (exhausted) { player->sendCancelMessage(RET_YOUAREEXHAUSTED); - if(isInstant()) + if (isInstant()) g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); - - + + return false; } - } + } - if(isPremium() && !player->isPremium()) + if (isPremium() && !player->isPremium()) { player->sendCancelMessage(RET_YOUNEEDPREMIUMACCOUNT); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if((int32_t)player->getLevel() < level) + if ((int32_t)player->getLevel() < level) { player->sendCancelMessage(RET_NOTENOUGHLEVEL); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if((int32_t)player->getMagicLevel() < magLevel) + if ((int32_t)player->getMagicLevel() < magLevel) { player->sendCancelMessage(RET_NOTENOUGHMAGICLEVEL); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - for(int16_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) + for (int16_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) { - if((int32_t)player->getSkill((skills_t)i, SKILL_LEVEL) < skills[i]) + if ((int32_t)player->getSkill((skills_t)i, SKILL_LEVEL) < skills[i]) { player->sendCancelMessage(RET_NOTENOUGHSKILL); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -743,32 +749,32 @@ bool Spell::checkSpell(Player* player) const } } - if(player->getMana() < getManaCost(player) && !player->hasFlag(PlayerFlag_HasInfiniteMana)) + if (player->getMana() < getManaCost(player) && !player->hasFlag(PlayerFlag_HasInfiniteMana)) { player->sendCancelMessage(RET_NOTENOUGHMANA); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - #ifdef _MULTIPLATFORM76 - if(player->getSoul() < soul && !player->hasFlag(PlayerFlag_HasInfiniteSoul)) +#ifdef _MULTIPLATFORM76 + if (player->getSoul() < soul && !player->hasFlag(PlayerFlag_HasInfiniteSoul)) { player->sendCancelMessage(RET_NOTENOUGHSOUL); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - #endif +#endif - if(isInstant() && isLearnable() && !player->hasLearnedInstantSpell(getName())) + if (isInstant() && isLearnable() && !player->hasLearnedInstantSpell(getName())) { player->sendCancelMessage(RET_YOUNEEDTOLEARNTHISSPELL); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(!vocSpellMap.empty()) + if (!vocSpellMap.empty()) { - if(vocSpellMap.find(player->getVocationId()) == vocSpellMap.end()) + if (vocSpellMap.find(player->getVocationId()) == vocSpellMap.end()) { player->sendCancelMessage(RET_YOURVOCATIONCANNOTUSETHISSPELL); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -776,47 +782,43 @@ bool Spell::checkSpell(Player* player) const } } - if(needWeapon) + if (needWeapon) { - switch(player->getWeaponType()) + switch (player->getWeaponType()) { - case WEAPON_SWORD: - case WEAPON_CLUB: - case WEAPON_AXE: - case WEAPON_FIST: - break; + case WEAPON_SWORD: + case WEAPON_CLUB: + case WEAPON_AXE: + case WEAPON_FIST: + break; - default: - { - player->sendCancelMessage(RET_YOUNEEDAWEAPONTOUSETHISSPELL); - g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); - return false; - } + default: + { + player->sendCancelMessage(RET_YOUNEEDAWEAPONTOUSETHISSPELL); + g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); + return false; + } } } - Condition* condition = player->getCondition(CONDITION_LOGINPROTECTION, CONDITIONID_DEFAULT); - if(condition) - player->removeCondition(condition); - return true; } bool Spell::checkInstantSpell(Player* player, Creature* creature) { - if(!checkSpell(player)) + if (!checkSpell(player)) return false; const Position& toPos = creature->getPosition(); const Position& playerPos = player->getPosition(); - if(playerPos.z > toPos.z) + if (playerPos.z > toPos.z) { player->sendCancelMessage(RET_FIRSTGOUPSTAIRS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(playerPos.z < toPos.z) + if (playerPos.z < toPos.z) { player->sendCancelMessage(RET_FIRSTGODOWNSTAIRS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -824,35 +826,35 @@ bool Spell::checkInstantSpell(Player* player, Creature* creature) } Tile* tile = g_game.getTile(toPos); - if(!tile) + if (!tile) { tile = new StaticTile(toPos.x, toPos.y, toPos.z); g_game.setTile(tile); } ReturnValue ret; - if((ret = Combat::canDoCombat(player, tile, isAggressive, false)) != RET_NOERROR) + if ((ret = Combat::canDoCombat(player, tile, isAggressive, false)) != RET_NOERROR) { player->sendCancelMessage(ret); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(blockingCreature && creature) + if (blockingCreature && creature) { player->sendCancelMessage(RET_NOTENOUGHROOM); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(blockingSolid && tile->hasProperty(BLOCKSOLID)) + if (blockingSolid && tile->hasProperty(BLOCKSOLID)) { player->sendCancelMessage(RET_NOTENOUGHROOM); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(!creature) + if (!creature) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -860,11 +862,11 @@ bool Spell::checkInstantSpell(Player* player, Creature* creature) } Player* targetPlayer = creature->getPlayer(); - if(!isAggressive || !targetPlayer || Combat::isInPvpZone(player, targetPlayer) + if (!isAggressive || !targetPlayer || Combat::isInPvpZone(player, targetPlayer) || player->getSkullType(targetPlayer) != SKULL_NONE) return true; - if(player->getSecureMode() == SECUREMODE_ON) + if (player->getSecureMode() == SECUREMODE_ON) { player->sendCancelMessage(RET_TURNSECUREMODETOATTACKUNMARKEDPLAYERS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -876,21 +878,21 @@ bool Spell::checkInstantSpell(Player* player, Creature* creature) bool Spell::checkInstantSpell(Player* player, const Position& toPos) { - if(!checkSpell(player)) + if (!checkSpell(player)) return false; - if(toPos.x == 0xFFFF) + if (toPos.x == 0xFFFF) return true; const Position& playerPos = player->getPosition(); - if(playerPos.z > toPos.z) + if (playerPos.z > toPos.z) { player->sendCancelMessage(RET_FIRSTGOUPSTAIRS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(playerPos.z < toPos.z) + if (playerPos.z < toPos.z) { player->sendCancelMessage(RET_FIRSTGODOWNSTAIRS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -898,28 +900,28 @@ bool Spell::checkInstantSpell(Player* player, const Position& toPos) } Tile* tile = g_game.getTile(toPos); - if(!tile) + if (!tile) { tile = new StaticTile(toPos.x, toPos.y, toPos.z); g_game.setTile(tile); } ReturnValue ret; - if((ret = Combat::canDoCombat(player, tile, isAggressive, false)) != RET_NOERROR) + if ((ret = Combat::canDoCombat(player, tile, isAggressive, false)) != RET_NOERROR) { player->sendCancelMessage(ret); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(blockingCreature && tile->getTopVisibleCreature(player)) + if (blockingCreature && tile->getTopVisibleCreature(player)) { player->sendCancelMessage(RET_NOTENOUGHROOM); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(blockingSolid && tile->hasProperty(BLOCKSOLID)) + if (blockingSolid && tile->hasProperty(BLOCKSOLID)) { player->sendCancelMessage(RET_NOTENOUGHROOM); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -931,21 +933,21 @@ bool Spell::checkInstantSpell(Player* player, const Position& toPos) bool Spell::checkRuneSpell(Player* player, const Position& toPos) { - if(!checkSpell(player)) + if (!checkSpell(player)) return false; - if(toPos.x == 0xFFFF) + if (toPos.x == 0xFFFF) return true; const Position& playerPos = player->getPosition(); - if(playerPos.z > toPos.z) + if (playerPos.z > toPos.z) { player->sendCancelMessage(RET_FIRSTGOUPSTAIRS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(playerPos.z < toPos.z) + if (playerPos.z < toPos.z) { player->sendCancelMessage(RET_FIRSTGODOWNSTAIRS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -953,14 +955,14 @@ bool Spell::checkRuneSpell(Player* player, const Position& toPos) } Tile* tile = g_game.getTile(toPos); - if(!tile) + if (!tile) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(range != -1 && !g_game.canThrowObjectTo(playerPos, toPos, true, range, range)) + if (range != -1 && !g_game.canThrowObjectTo(playerPos, toPos, true, range, range)) { player->sendCancelMessage(RET_DESTINATIONOUTOFREACH); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -968,7 +970,7 @@ bool Spell::checkRuneSpell(Player* player, const Position& toPos) } ReturnValue ret; - if((ret = Combat::canDoCombat(player, tile, isAggressive, false)) != RET_NOERROR) + if ((ret = Combat::canDoCombat(player, tile, isAggressive, false)) != RET_NOERROR) { player->sendCancelMessage(ret); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -976,32 +978,32 @@ bool Spell::checkRuneSpell(Player* player, const Position& toPos) } Creature* targetCreature = tile->getTopVisibleCreature(player); - if(blockingCreature && targetCreature) + if (blockingCreature && targetCreature) { player->sendCancelMessage(RET_NOTENOUGHROOM); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(blockingSolid && tile->hasProperty(BLOCKSOLID)) + if (blockingSolid && tile->hasProperty(BLOCKSOLID)) { player->sendCancelMessage(RET_NOTENOUGHROOM); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(needTarget && !targetCreature) + if (needTarget && !targetCreature) { player->sendCancelMessage(RET_CANONLYUSETHISRUNEONCREATURES); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(!targetCreature) + if (!targetCreature) return true; Player* targetPlayer = targetCreature->getPlayer(); - if(isAggressive && needTarget && !Combat::isInPvpZone(player, targetPlayer) && player->getSecureMode() == SECUREMODE_ON && (targetPlayer && targetPlayer != player && targetPlayer->getSkull() == SKULL_NONE)) + if (isAggressive && needTarget && !Combat::isInPvpZone(player, targetPlayer) && player->getSecureMode() == SECUREMODE_ON && (targetPlayer && targetPlayer != player && targetPlayer->getSkull() == SKULL_NONE)) { player->sendCancelMessage(RET_TURNSECUREMODETOATTACKUNMARKEDPLAYERS); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1013,11 +1015,11 @@ bool Spell::checkRuneSpell(Player* player, const Position& toPos) void Spell::postSpell(Player* player) const { - if(!player->hasFlag(PlayerFlag_HasNoExhaustion)) + if (!player->hasFlag(PlayerFlag_HasNoExhaustion)) { - if(!g_config.getBool(ConfigManager::NO_ATTACKHEALING_SIMULTANEUS)) + if (!g_config.getBool(ConfigManager::NO_ATTACKHEALING_SIMULTANEUS)) { - if(exhaustion > 0) + if (exhaustion > 0) { player->addExhaust(exhaustion, EXHAUST_SPELLGROUP_ATTACK); player->addExhaust(exhaustion, EXHAUST_SPELLGROUP_HEALING); @@ -1025,27 +1027,27 @@ void Spell::postSpell(Player* player) const } else { - if(g_config.getBool(ConfigManager::ENABLE_COOLDOWNS)) + if (g_config.getBool(ConfigManager::ENABLE_COOLDOWNS)) { - for(SpellGroup::const_iterator it = groupExhaustions.begin(); it != groupExhaustions.end(); ++it) + for (SpellGroup::const_iterator it = groupExhaustions.begin(); it != groupExhaustions.end(); ++it) player->addExhaust(it->second, (Exhaust_t)(it->first + 1)); - if(exhaustion > 0) + if (exhaustion > 0) player->addCooldown(exhaustion, spellId); } - else if(exhaustion > 0) + else if (exhaustion > 0) player->addExhaust(exhaustion, (isAggressive ? EXHAUST_SPELLGROUP_ATTACK : EXHAUST_SPELLGROUP_HEALING)); } } - if(isAggressive && !player->hasFlag(PlayerFlag_NotGainInFight)) + if (isAggressive && !player->hasFlag(PlayerFlag_NotGainInFight)) player->addInFightTicks(false); - #ifdef _MULTIPLATFORM76 +#ifdef _MULTIPLATFORM76 postSpell(player, (uint32_t)getManaCost(player), (uint32_t)getSoulCost()); - #else +#else postSpell(player, (uint32_t)getManaCost(player)); - #endif +#endif } #ifdef _MULTIPLATFORM76 @@ -1054,23 +1056,23 @@ void Spell::postSpell(Player* player, uint32_t manaCost, uint32_t soulCost) cons void Spell::postSpell(Player* player, uint32_t manaCost) const #endif { - if(manaCost > 0) + if (manaCost > 0) { player->changeMana(-(int32_t)manaCost); - if(!player->hasFlag(PlayerFlag_NotGainMana) && (player->getZone() != ZONE_HARDCORE + if (!player->hasFlag(PlayerFlag_NotGainMana) && (player->getZone() != ZONE_HARDCORE || g_config.getBool(ConfigManager::PVPZONE_ADDMANASPENT))) player->addManaSpent(manaCost); } - #ifdef _MULTIPLATFORM76 - if(soulCost > 0) +#ifdef _MULTIPLATFORM76 + if (soulCost > 0) player->changeSoul(-(int32_t)soulCost); - #endif +#endif } int32_t Spell::getManaCost(const Player* player) const { - if(player && manaPercent) + if (player && manaPercent) return (int32_t)std::floor((double)(player->getMaxMana() * manaPercent) / 100.); return mana; @@ -1079,7 +1081,7 @@ int32_t Spell::getManaCost(const Player* player) const ReturnValue Spell::CreateIllusion(Creature* creature, const Outfit_t& outfit, int32_t time) { ConditionOutfit* outfitCondition = new ConditionOutfit(CONDITIONID_COMBAT, CONDITION_OUTFIT, time, false, 0); - if(!outfitCondition) + if (!outfitCondition) return RET_NOTPOSSIBLE; outfitCondition->addOutfit(outfit); @@ -1090,15 +1092,15 @@ ReturnValue Spell::CreateIllusion(Creature* creature, const Outfit_t& outfit, in ReturnValue Spell::CreateIllusion(Creature* creature, const std::string& name, int32_t time) { uint32_t mId = g_monsters.getIdByName(name); - if(!mId) + if (!mId) return RET_CREATUREDOESNOTEXIST; const MonsterType* mType = g_monsters.getMonsterType(mId); - if(!mType) + if (!mType) return RET_CREATUREDOESNOTEXIST; Player* player = creature->getPlayer(); - if(player && !player->hasFlag(PlayerFlag_CanIllusionAll) && !mType->isIllusionable) + if (player && !player->hasFlag(PlayerFlag_CanIllusionAll) && !mType->isIllusionable) return RET_NOTPOSSIBLE; return CreateIllusion(creature, mType->outfit, time); @@ -1107,7 +1109,7 @@ ReturnValue Spell::CreateIllusion(Creature* creature, const std::string& name, i ReturnValue Spell::CreateIllusion(Creature* creature, uint32_t itemId, int32_t time) { const ItemType& it = Item::items[itemId]; - if(!it.id) + if (!it.id) return RET_NOTPOSSIBLE; Outfit_t outfit; @@ -1127,27 +1129,27 @@ InstantSpell::InstantSpell(LuaInterface* _interface) : TalkAction(_interface) bool InstantSpell::configureEvent(xmlNodePtr p) { - if(!Spell::configureSpell(p)) + if (!Spell::configureSpell(p)) return false; - if(!TalkAction::configureEvent(p)) + if (!TalkAction::configureEvent(p)) return false; std::string strValue; - if(readXMLString(p, "param", strValue) || readXMLString(p, "params", strValue)) + if (readXMLString(p, "param", strValue) || readXMLString(p, "params", strValue)) hasParam = booleanString(strValue); - if(readXMLString(p, "direction", strValue)) + if (readXMLString(p, "direction", strValue)) needDirection = booleanString(strValue); - if(readXMLString(p, "casterTargetOrDirection", strValue)) + if (readXMLString(p, "casterTargetOrDirection", strValue)) casterTargetOrDirection = booleanString(strValue); - if(readXMLString(p, "blockwalls", strValue)) + if (readXMLString(p, "blockwalls", strValue)) checkLineOfSight = booleanString(strValue); int32_t intValue; - if(readXMLInteger(p, "limitRange", intValue)) + if (readXMLInteger(p, "limitRange", intValue)) limitRange = intValue; return true; @@ -1156,19 +1158,19 @@ bool InstantSpell::configureEvent(xmlNodePtr p) bool InstantSpell::loadFunction(const std::string& functionName) { std::string tmpFunctionName = asLowerCaseString(functionName); - if(tmpFunctionName == "summonmonster") + if (tmpFunctionName == "summonmonster") function = SummonMonster; - else if(tmpFunctionName == "searchplayer") + else if (tmpFunctionName == "searchplayer") { isAggressive = false; function = SearchPlayer; } - else if(tmpFunctionName == "levitate") + else if (tmpFunctionName == "levitate") { isAggressive = false; function = Levitate; } - else if(tmpFunctionName == "illusion") + else if (tmpFunctionName == "illusion") { isAggressive = false; function = Illusion; @@ -1186,27 +1188,27 @@ bool InstantSpell::loadFunction(const std::string& functionName) bool InstantSpell::castInstant(Player* player, const std::string& param) { LuaVariant var; - if(selfTarget) + if (selfTarget) { var.type = VARIANT_NUMBER; var.number = player->getID(); - if(!checkInstantSpell(player, player)) + if (!checkInstantSpell(player, player)) return false; } - else if(needTarget || casterTargetOrDirection) + else if (needTarget || casterTargetOrDirection) { Creature* target = NULL; - if(hasParam) + if (hasParam) { Player* targetPlayer = NULL; ReturnValue ret = g_game.getPlayerByNameWildcard(param, targetPlayer); target = targetPlayer; - if(limitRange && target && !Position::areInRange(Position(limitRange, + if (limitRange && target && !Position::areInRange(Position(limitRange, limitRange, 0), target->getPosition(), player->getPosition())) target = NULL; - if((!target || target->getHealth() <= 0) && !casterTargetOrDirection) + if ((!target || target->getHealth() <= 0) && !casterTargetOrDirection) { player->sendCancelMessage(ret); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1216,11 +1218,11 @@ bool InstantSpell::castInstant(Player* player, const std::string& param) else { target = player->getAttackedCreature(); - if(limitRange && target && !Position::areInRange(Position(limitRange, + if (limitRange && target && !Position::areInRange(Position(limitRange, limitRange, 0), target->getPosition(), player->getPosition())) target = NULL; - if((!target || target->getHealth() <= 0) && !casterTargetOrDirection) + if ((!target || target->getHealth() <= 0) && !casterTargetOrDirection) { player->sendCancelMessage(RET_YOUCANONLYUSEITONCREATURES); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1228,10 +1230,10 @@ bool InstantSpell::castInstant(Player* player, const std::string& param) } } - if(target) + if (target) { bool canSee = player->canSeeCreature(target); - if(!canSee || !canThrowSpell(player, target)) + if (!canSee || !canThrowSpell(player, target)) { player->sendCancelMessage(canSee ? RET_CREATUREISNOTREACHABLE : RET_PLAYERWITHTHISNAMEISNOTONLINE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1240,37 +1242,37 @@ bool InstantSpell::castInstant(Player* player, const std::string& param) var.type = VARIANT_NUMBER; var.number = target->getID(); - if(!checkInstantSpell(player, target)) + if (!checkInstantSpell(player, target)) return false; } else { var.type = VARIANT_POSITION; var.pos = Spells::getCasterPosition(player, player->getDirection()); - if(!checkInstantSpell(player, var.pos)) + if (!checkInstantSpell(player, var.pos)) return false; } } - else if(hasParam) + else if (hasParam) { var.type = VARIANT_STRING; var.text = param; - if(!checkSpell(player)) + if (!checkSpell(player)) return false; } else { var.type = VARIANT_POSITION; - if(needDirection) + if (needDirection) var.pos = Spells::getCasterPosition(player, player->getDirection()); else var.pos = player->getPosition(); - if(!checkInstantSpell(player, var.pos)) + if (!checkInstantSpell(player, var.pos)) return false; } - if(!internalCastSpell(player, var)) + if (!internalCastSpell(player, var)) return false; Spell::postSpell(player); @@ -1287,16 +1289,16 @@ bool InstantSpell::canThrowSpell(const Creature* creature, const Creature* targe bool InstantSpell::castSpell(Creature* creature) { - if(!BaseSpell::castSpell(creature)) + if (!BaseSpell::castSpell(creature)) return false; LuaVariant var; - if(casterTargetOrDirection) + if (casterTargetOrDirection) { Creature* target = creature->getAttackedCreature(); - if(target && target->getHealth() > 0) + if (target && target->getHealth() > 0) { - if(!creature->canSeeCreature(target) || !canThrowSpell(creature, target)) + if (!creature->canSeeCreature(target) || !canThrowSpell(creature, target)) return false; var.type = VARIANT_NUMBER; @@ -1307,7 +1309,7 @@ bool InstantSpell::castSpell(Creature* creature) return false; } - if(needDirection) + if (needDirection) { var.type = VARIANT_POSITION; var.pos = Spells::getCasterPosition(creature, creature->getDirection()); @@ -1323,10 +1325,10 @@ bool InstantSpell::castSpell(Creature* creature) bool InstantSpell::castSpell(Creature* creature, Creature* target) { - if(!BaseSpell::castSpell(creature, target)) + if (!BaseSpell::castSpell(creature, target)) return false; - if(!needTarget) + if (!needTarget) return castSpell(creature); LuaVariant var; @@ -1337,7 +1339,7 @@ bool InstantSpell::castSpell(Creature* creature, Creature* target) bool InstantSpell::internalCastSpell(Creature* creature, const LuaVariant& var) { - if(isScripted()) + if (isScripted()) return executeCastSpell(creature, var); return function ? function(this, creature, var.text) : false; @@ -1346,10 +1348,10 @@ bool InstantSpell::internalCastSpell(Creature* creature, const LuaVariant& var) bool InstantSpell::executeCastSpell(Creature* creature, const LuaVariant& var) { //onCastSpell(cid, var) - if(m_interface->reserveEnv()) + if (m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); - if(m_scripted == EVENT_SCRIPT_BUFFER) + if (m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(creature->getPosition()); std::stringstream scriptstream; @@ -1359,7 +1361,7 @@ bool InstantSpell::executeCastSpell(Creature* creature, const LuaVariant& var) scriptstream << *m_scriptData; bool result = true; - if(m_interface->loadBuffer(scriptstream.str())) + if (m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); @@ -1370,11 +1372,11 @@ bool InstantSpell::executeCastSpell(Creature* creature, const LuaVariant& var) } else { - #ifdef __DEBUG_LUASCRIPTS__ +#ifdef __DEBUG_LUASCRIPTS__ char desc[60]; sprintf(desc, "onCastSpell - %s", creature->getName().c_str()); env->setEvent(desc); - #endif +#endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(creature->getPosition()); @@ -1399,19 +1401,19 @@ bool InstantSpell::executeCastSpell(Creature* creature, const LuaVariant& var) bool InstantSpell::SearchPlayer(const InstantSpell*, Creature* creature, const std::string& param) { Player* player = creature->getPlayer(); - if(!player || player->isRemoved()) + if (!player || player->isRemoved()) return false; Player* targetPlayer = NULL; ReturnValue ret = g_game.getPlayerByNameWildcard(param, targetPlayer); - if(ret != RET_NOERROR || !targetPlayer || targetPlayer->isRemoved()) + if (ret != RET_NOERROR || !targetPlayer || targetPlayer->isRemoved()) { player->sendCancelMessage(ret); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(targetPlayer->hasCustomFlag(PlayerCustomFlag_NotSearchable) && !player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges)) + if (targetPlayer->hasCustomFlag(PlayerCustomFlag_NotSearchable) && !player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges)) { player->sendCancelMessage(RET_PLAYERWITHTHISNAMEISNOTONLINE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1429,11 +1431,11 @@ bool InstantSpell::SearchPlayer(const InstantSpell*, Creature* creature, const s bool InstantSpell::SummonMonster(const InstantSpell* spell, Creature* creature, const std::string& param) { Player* player = creature->getPlayer(); - if(!player) + if (!player) return false; MonsterType* mType = g_monsters.getMonsterType(param); - if(!mType) + if (!mType) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1441,23 +1443,23 @@ bool InstantSpell::SummonMonster(const InstantSpell* spell, Creature* creature, } int32_t manaCost = (int32_t)(mType->manaCost * g_config.getDouble(ConfigManager::RATE_MONSTER_MANA)); - if(!player->hasFlag(PlayerFlag_CanSummonAll)) + if (!player->hasFlag(PlayerFlag_CanSummonAll)) { - if(!mType->isSummonable) + if (!mType->isSummonable) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(player->getMana() < manaCost) + if (player->getMana() < manaCost) { player->sendCancelMessage(RET_NOTENOUGHMANA); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if((int32_t)player->getSummonCount() >= g_config.getNumber(ConfigManager::MAX_PLAYER_SUMMONS)) + if ((int32_t)player->getSummonCount() >= g_config.getNumber(ConfigManager::MAX_PLAYER_SUMMONS)) { player->sendCancel("You cannot summon more creatures."); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1466,13 +1468,13 @@ bool InstantSpell::SummonMonster(const InstantSpell* spell, Creature* creature, } ReturnValue ret = g_game.placeSummon(creature, param); - if(ret == RET_NOERROR) + if (ret == RET_NOERROR) { - #ifdef _MULTIPLATFORM76 +#ifdef _MULTIPLATFORM76 spell->postSpell(player, (uint32_t)manaCost, (uint32_t)spell->getSoulCost()); - #else +#else spell->postSpell(player, (uint32_t)manaCost); - #endif +#endif g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE); return true; } @@ -1485,7 +1487,7 @@ bool InstantSpell::SummonMonster(const InstantSpell* spell, Creature* creature, bool InstantSpell::Levitate(const InstantSpell*, Creature* creature, const std::string& param) { Player* player = creature->getPlayer(); - if(!player) + if (!player) return false; uint16_t floor = 7; @@ -1494,18 +1496,18 @@ bool InstantSpell::Levitate(const InstantSpell*, Creature* creature, const std:: Position destination = Spells::getCasterPosition(creature, creature->getDirection()); std::string tmpParam = asLowerCaseString(param); - if(tmpParam == "up") + if (tmpParam == "up") floor = 8; - else if(tmpParam != "down") + else if (tmpParam != "down") ret = RET_NOTPOSSIBLE; - if(ret == RET_NOERROR) + if (ret == RET_NOERROR) { ret = RET_NOTPOSSIBLE; - if(position.z != floor) + if (position.z != floor) { Tile* tmpTile = NULL; - if(floor != 7) + if (floor != 7) { tmpTile = g_game.getTile(position.x, position.y, position.z - 1); destination.z--; @@ -1516,11 +1518,11 @@ bool InstantSpell::Levitate(const InstantSpell*, Creature* creature, const std:: destination.z++; } - if(!tmpTile || (!tmpTile->ground && !tmpTile->hasProperty(IMMOVABLEBLOCKSOLID))) + if (!tmpTile || (!tmpTile->ground && !tmpTile->hasProperty(IMMOVABLEBLOCKSOLID))) { Tile* tile = player->getTile(); tmpTile = g_game.getTile(destination); - if(tile && tmpTile && tmpTile->ground && !tmpTile->hasProperty(IMMOVABLEBLOCKSOLID) && + if (tile && tmpTile && tmpTile->ground && !tmpTile->hasProperty(IMMOVABLEBLOCKSOLID) && tile->hasFlag(TILESTATE_HOUSE) == tmpTile->hasFlag(TILESTATE_HOUSE) && tile->hasFlag(TILESTATE_PROTECTIONZONE) == tmpTile->hasFlag(TILESTATE_PROTECTIONZONE)) ret = g_game.internalMoveCreature(NULL, player, tile, tmpTile, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE); @@ -1528,7 +1530,7 @@ bool InstantSpell::Levitate(const InstantSpell*, Creature* creature, const std:: } } - if(ret == RET_NOERROR) + if (ret == RET_NOERROR) { g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_TELEPORT, player->isGhost()); return true; @@ -1542,11 +1544,11 @@ bool InstantSpell::Levitate(const InstantSpell*, Creature* creature, const std:: bool InstantSpell::Illusion(const InstantSpell*, Creature* creature, const std::string& param) { Player* player = creature->getPlayer(); - if(!player) + if (!player) return false; ReturnValue ret = CreateIllusion(creature, param, 60000); - if(ret == RET_NOERROR) + if (ret == RET_NOERROR) { g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_RED); return true; @@ -1559,17 +1561,17 @@ bool InstantSpell::Illusion(const InstantSpell*, Creature* creature, const std:: bool InstantSpell::canCast(const Player* player) const { - if(player->hasFlag(PlayerFlag_CannotUseSpells)) + if (player->hasFlag(PlayerFlag_CannotUseSpells)) return false; - if(player->hasFlag(PlayerFlag_IgnoreSpellCheck) || (!isLearnable() && (vocSpellMap.empty() + if (player->hasFlag(PlayerFlag_IgnoreSpellCheck) || (!isLearnable() && (vocSpellMap.empty() || vocSpellMap.find(player->getVocationId()) != vocSpellMap.end()))) return true; return player->hasLearnedInstantSpell(getName()); } -ConjureSpell::ConjureSpell(LuaInterface* _interface): +ConjureSpell::ConjureSpell(LuaInterface* _interface) : InstantSpell(_interface) { isAggressive = false; @@ -1580,24 +1582,24 @@ ConjureSpell::ConjureSpell(LuaInterface* _interface): bool ConjureSpell::configureEvent(xmlNodePtr p) { - if(!InstantSpell::configureEvent(p)) + if (!InstantSpell::configureEvent(p)) return false; int32_t intValue; - if(readXMLInteger(p, "conjureId", intValue)) + if (readXMLInteger(p, "conjureId", intValue)) conjureId = intValue; - if(readXMLInteger(p, "conjureCount", intValue)) + if (readXMLInteger(p, "conjureCount", intValue)) conjureCount = intValue; - else if(conjureId != 0) + else if (conjureId != 0) { //load the default charge from items.xml const ItemType& it = Item::items[conjureId]; - if(it.charges != 0) + if (it.charges != 0) conjureCount = it.charges; } - if(readXMLInteger(p, "reagentId", intValue)) + if (readXMLInteger(p, "reagentId", intValue)) conjureReagentId = intValue; return true; @@ -1606,7 +1608,7 @@ bool ConjureSpell::configureEvent(xmlNodePtr p) bool ConjureSpell::loadFunction(const std::string& functionName) { std::string tmpFunctionName = asLowerCaseString(functionName); - if(tmpFunctionName == "conjureitem" || tmpFunctionName == "conjurerune") + if (tmpFunctionName == "conjureitem" || tmpFunctionName == "conjurerune") function = ConjureItem; else { @@ -1621,62 +1623,62 @@ bool ConjureSpell::loadFunction(const std::string& functionName) ReturnValue ConjureSpell::internalConjureItem(Player* player, uint32_t conjureId, uint32_t conjureCount, bool transform/* = false*/, uint32_t reagentId/* = 0*/) { - if(!transform) + if (!transform) { Item* newItem = Item::CreateItem(conjureId, conjureCount); - if(!newItem) + if (!newItem) return RET_NOTPOSSIBLE; ReturnValue ret = g_game.internalPlayerAddItem(player, player, newItem, true); - if(ret != RET_NOERROR) + if (ret != RET_NOERROR) delete newItem; g_game.startDecay(newItem); return ret; } - if(!reagentId) + if (!reagentId) return RET_NOTPOSSIBLE; std::list containers; Item *item = NULL, *fromItem = NULL; - for(int32_t i = SLOT_FIRST; i < SLOT_LAST; ++i) + for (int32_t i = SLOT_FIRST; i < SLOT_LAST; ++i) { - if(!(item = player->getInventoryItem((slots_t)i))) + if (!(item = player->getInventoryItem((slots_t)i))) continue; - if(!fromItem && item->getID() == reagentId) + if (!fromItem && item->getID() == reagentId) fromItem = item; - else if(Container* container = item->getContainer()) + else if (Container* container = item->getContainer()) containers.push_back(container); } - if(!fromItem) + if (!fromItem) { - for(std::list::iterator cit = containers.begin(); cit != containers.end(); ++cit) + for (std::list::iterator cit = containers.begin(); cit != containers.end(); ++cit) { - for(ItemList::const_reverse_iterator it = (*cit)->getReversedItems(); it != (*cit)->getReversedEnd(); ++it) + for (ItemList::const_reverse_iterator it = (*cit)->getReversedItems(); it != (*cit)->getReversedEnd(); ++it) { - if((*it)->getID() == reagentId) + if ((*it)->getID() == reagentId) { fromItem = (*it); break; } - if(Container* tmp = (*it)->getContainer()) + if (Container* tmp = (*it)->getContainer()) containers.push_back(tmp); } } } - if(!fromItem) + if (!fromItem) return RET_YOUNEEDAMAGICITEMTOCASTSPELL; - if((fromItem->isStackable() || fromItem->hasCharges()) && fromItem->getSubType() > 1) + if ((fromItem->isStackable() || fromItem->hasCharges()) && fromItem->getSubType() > 1) { item = Item::CreateItem(conjureId, conjureCount); ReturnValue ret = g_game.internalPlayerAddItem(NULL, player, item, false); - if(ret != RET_NOERROR) + if (ret != RET_NOERROR) return ret; g_game.transformItem(fromItem, reagentId, (int32_t)(fromItem->getItemCount() - 1)); @@ -1691,10 +1693,10 @@ ReturnValue ConjureSpell::internalConjureItem(Player* player, uint32_t conjureId bool ConjureSpell::ConjureItem(const ConjureSpell* spell, Creature* creature, const std::string&) { Player* player = creature->getPlayer(); - if(!player) + if (!player) return false; - if(!player->hasFlag(PlayerFlag_IgnoreSpellCheck) && player->getZone() == ZONE_HARDCORE) + if (!player->hasFlag(PlayerFlag_IgnoreSpellCheck) && player->getZone() == ZONE_HARDCORE) { player->sendCancelMessage(RET_CANNOTCONJUREITEMHERE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1702,16 +1704,16 @@ bool ConjureSpell::ConjureItem(const ConjureSpell* spell, Creature* creature, co } ReturnValue result = RET_NOTPOSSIBLE; - if(spell->getReagentId() != 0) + if (spell->getReagentId() != 0) { - if((result = internalConjureItem(player, spell->getConjureId(), spell->getConjureCount(), true, spell->getReagentId())) == RET_NOERROR) + if ((result = internalConjureItem(player, spell->getConjureId(), spell->getConjureCount(), true, spell->getReagentId())) == RET_NOERROR) { spell->postSpell(player); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_RED); return true; } } - else if((result = internalConjureItem(player, spell->getConjureId(), spell->getConjureCount())) == RET_NOERROR) + else if ((result = internalConjureItem(player, spell->getConjureId(), spell->getConjureCount())) == RET_NOERROR) { spell->postSpell(player); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_RED); @@ -1725,10 +1727,10 @@ bool ConjureSpell::ConjureItem(const ConjureSpell* spell, Creature* creature, co bool ConjureSpell::castInstant(Player* player, const std::string& param) { - if(!checkSpell(player)) + if (!checkSpell(player)) return false; - if(!isScripted()) + if (!isScripted()) return function ? function(this, player, param) : false; LuaVariant var; @@ -1737,8 +1739,8 @@ bool ConjureSpell::castInstant(Player* player, const std::string& param) return executeCastSpell(player, var); } -RuneSpell::RuneSpell(LuaInterface* _interface): -Action(_interface) +RuneSpell::RuneSpell(LuaInterface* _interface) : + Action(_interface) { runeId = 0; function = NULL; @@ -1747,14 +1749,14 @@ Action(_interface) bool RuneSpell::configureEvent(xmlNodePtr p) { - if(!Spell::configureSpell(p)) + if (!Spell::configureSpell(p)) return false; - if(!Action::configureEvent(p)) + if (!Action::configureEvent(p)) return false; int32_t intValue; - if(readXMLInteger(p, "id", intValue)) + if (readXMLInteger(p, "id", intValue)) runeId = intValue; else { @@ -1763,14 +1765,14 @@ bool RuneSpell::configureEvent(xmlNodePtr p) } std::string strValue; - if(readXMLString(p, "charges", strValue)) + if (readXMLString(p, "charges", strValue)) hasCharges = booleanString(strValue); ItemType& it = Item::items.getItemType(runeId); - if(level && level != it.runeLevel) + if (level && level != it.runeLevel) it.runeLevel = level; - if(magLevel && magLevel != it.runeMagLevel) + if (magLevel && magLevel != it.runeMagLevel) it.runeMagLevel = magLevel; it.vocationString = parseVocationString(vocStringVec); @@ -1780,14 +1782,14 @@ bool RuneSpell::configureEvent(xmlNodePtr p) bool RuneSpell::loadFunction(const std::string& functionName) { std::string tmpFunctionName = asLowerCaseString(functionName); - if(tmpFunctionName == "chameleon") + if (tmpFunctionName == "chameleon") function = Illusion; - else if(tmpFunctionName == "convince") + else if (tmpFunctionName == "convince") function = Convince; - #ifdef _MULTIPLATFORM76 - else if(tmpFunctionName == "soulfire") +#ifdef _MULTIPLATFORM76 + else if (tmpFunctionName == "soulfire") function = Soulfire; - #endif +#endif else { std::clog << "[Warning - RuneSpell::loadFunction] Function \"" << functionName << "\" does not exist." << std::endl; @@ -1801,11 +1803,11 @@ bool RuneSpell::loadFunction(const std::string& functionName) bool RuneSpell::Illusion(const RuneSpell*, Creature* creature, Item*, const Position&, const Position& posTo) { Player* player = creature->getPlayer(); - if(!player) + if (!player) return false; Thing* thing = g_game.internalGetThing(player, posTo, 0, 0, STACKPOS_MOVE); - if(!thing) + if (!thing) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1813,7 +1815,7 @@ bool RuneSpell::Illusion(const RuneSpell*, Creature* creature, Item*, const Posi } Item* illusionItem = thing->getItem(); - if(!illusionItem || !illusionItem->isMovable()) + if (!illusionItem || !illusionItem->isMovable()) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1821,7 +1823,7 @@ bool RuneSpell::Illusion(const RuneSpell*, Creature* creature, Item*, const Posi } ReturnValue ret = CreateIllusion(creature, illusionItem->getID(), 60000); - if(ret == RET_NOERROR) + if (ret == RET_NOERROR) { g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_RED); return true; @@ -1835,12 +1837,12 @@ bool RuneSpell::Illusion(const RuneSpell*, Creature* creature, Item*, const Posi bool RuneSpell::Convince(const RuneSpell* spell, Creature* creature, Item*, const Position&, const Position& posTo) { Player* player = creature->getPlayer(); - if(!player) + if (!player) return false; - if(!player->hasFlag(PlayerFlag_CanConvinceAll)) + if (!player->hasFlag(PlayerFlag_CanConvinceAll)) { - if((int32_t)player->getSummonCount() >= g_config.getNumber(ConfigManager::MAX_PLAYER_SUMMONS)) + if ((int32_t)player->getSummonCount() >= g_config.getNumber(ConfigManager::MAX_PLAYER_SUMMONS)) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1849,7 +1851,7 @@ bool RuneSpell::Convince(const RuneSpell* spell, Creature* creature, Item*, cons } Thing* thing = g_game.internalGetThing(player, posTo, 0, 0, STACKPOS_LOOK); - if(!thing) + if (!thing) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1857,14 +1859,14 @@ bool RuneSpell::Convince(const RuneSpell* spell, Creature* creature, Item*, cons } Creature* convinceCreature = thing->getCreature(); - if(!convinceCreature) + if (!convinceCreature) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(!player->hasFlag(PlayerFlag_CanConvinceAll) && convinceCreature->getPlayerMaster()) + if (!player->hasFlag(PlayerFlag_CanConvinceAll) && convinceCreature->getPlayerMaster()) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1872,28 +1874,28 @@ bool RuneSpell::Convince(const RuneSpell* spell, Creature* creature, Item*, cons } int32_t manaCost = 0; - if(Monster* monster = convinceCreature->getMonster()) + if (Monster* monster = convinceCreature->getMonster()) manaCost = (int32_t)(monster->getManaCost() * g_config.getDouble(ConfigManager::RATE_MONSTER_MANA)); - if(!player->hasFlag(PlayerFlag_HasInfiniteMana) && player->getMana() < manaCost) + if (!player->hasFlag(PlayerFlag_HasInfiniteMana) && player->getMana() < manaCost) { player->sendCancelMessage(RET_NOTENOUGHMANA); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - if(!convinceCreature->convinceCreature(creature)) + if (!convinceCreature->convinceCreature(creature)) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); return false; } - #ifdef _MULTIPLATFORM76 +#ifdef _MULTIPLATFORM76 spell->postSpell(player, (uint32_t)manaCost, (uint32_t)spell->getSoulCost()); - #else +#else spell->postSpell(player, (uint32_t)manaCost); - #endif +#endif g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_RED); return true; } @@ -1902,11 +1904,11 @@ bool RuneSpell::Convince(const RuneSpell* spell, Creature* creature, Item*, cons bool RuneSpell::Soulfire(const RuneSpell* spell, Creature* creature, Item*, const Position&, const Position& posTo) { Player* player = creature->getPlayer(); - if(!player) + if (!player) return false; Thing* thing = g_game.internalGetThing(player, posTo, 0, 0, STACKPOS_LOOK); - if(!thing) + if (!thing) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1914,7 +1916,7 @@ bool RuneSpell::Soulfire(const RuneSpell* spell, Creature* creature, Item*, cons } Creature* target = thing->getCreature(); - if(!target) + if (!target) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1926,7 +1928,7 @@ bool RuneSpell::Soulfire(const RuneSpell* spell, Creature* creature, Item*, cons soulfireCondition->setParam(CONDITIONPARAM_OWNER, player->getID()); soulfireCondition->addDamage((int32_t)std::ceil((player->getLevel() + player->getMagicLevel()) / 9.), 9000, -10); - if(!target->addCondition(soulfireCondition)) + if (!target->addCondition(soulfireCondition)) { player->sendCancelMessage(RET_NOTPOSSIBLE); g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); @@ -1941,19 +1943,19 @@ bool RuneSpell::Soulfire(const RuneSpell* spell, Creature* creature, Item*, cons ReturnValue RuneSpell::canExecuteAction(const Player* player, const Position& toPos) { - if(player->hasFlag(PlayerFlag_CannotUseSpells)) + if (player->hasFlag(PlayerFlag_CannotUseSpells)) return RET_CANNOTUSETHISOBJECT; ReturnValue ret = Action::canExecuteAction(player, toPos); - if(ret != RET_NOERROR) + if (ret != RET_NOERROR) return ret; - if(toPos.x == 0xFFFF) + if (toPos.x == 0xFFFF) { - if(needTarget) + if (needTarget) return RET_CANONLYUSETHISRUNEONCREATURES; - if(!selfTarget) + if (!selfTarget) return RET_NOTENOUGHROOM; } @@ -1963,14 +1965,14 @@ ReturnValue RuneSpell::canExecuteAction(const Player* player, const Position& to bool RuneSpell::executeUse(Player* player, Item* item, const PositionEx& posFrom, const PositionEx& posTo, bool, uint32_t creatureId) { - if(!checkRuneSpell(player, posTo)) + if (!checkRuneSpell(player, posTo)) return false; bool result = false; - if(isScripted()) + if (isScripted()) { LuaVariant var; - if(creatureId && needTarget) + if (creatureId && needTarget) { var.type = VARIANT_NUMBER; var.number = creatureId; @@ -1983,13 +1985,13 @@ bool RuneSpell::executeUse(Player* player, Item* item, const PositionEx& posFrom result = internalCastSpell(player, var); } - else if(function) + else if (function) result = function(this, player, item, posFrom, posTo); - if(result) + if (result) { Spell::postSpell(player); - if(hasCharges && item && g_config.getBool(ConfigManager::REMOVE_RUNE_CHARGES)) + if (hasCharges && item && g_config.getBool(ConfigManager::REMOVE_RUNE_CHARGES)) g_game.transformItem(item, item->getID(), std::max((int32_t)0, ((int32_t)item->getCharges()) - 1)); } @@ -1998,7 +2000,7 @@ bool RuneSpell::executeUse(Player* player, Item* item, const PositionEx& posFrom bool RuneSpell::castSpell(Creature* creature) { - if(!BaseSpell::castSpell(creature)) + if (!BaseSpell::castSpell(creature)) return false; LuaVariant var; @@ -2009,7 +2011,7 @@ bool RuneSpell::castSpell(Creature* creature) bool RuneSpell::castSpell(Creature* creature, Creature* target) { - if(!BaseSpell::castSpell(creature, target)) + if (!BaseSpell::castSpell(creature, target)) return false; LuaVariant var; @@ -2026,10 +2028,10 @@ bool RuneSpell::internalCastSpell(Creature* creature, const LuaVariant& var) bool RuneSpell::executeCastSpell(Creature* creature, const LuaVariant& var) { //onCastSpell(cid, var) - if(m_interface->reserveEnv()) + if (m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); - if(m_scripted == EVENT_SCRIPT_BUFFER) + if (m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(creature->getPosition()); std::stringstream scriptstream; @@ -2039,7 +2041,7 @@ bool RuneSpell::executeCastSpell(Creature* creature, const LuaVariant& var) scriptstream << *m_scriptData; bool result = true; - if(m_interface->loadBuffer(scriptstream.str())) + if (m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); @@ -2050,11 +2052,11 @@ bool RuneSpell::executeCastSpell(Creature* creature, const LuaVariant& var) } else { - #ifdef __DEBUG_LUASCRIPTS__ +#ifdef __DEBUG_LUASCRIPTS__ char desc[60]; sprintf(desc, "onCastSpell - %s", creature->getName().c_str()); env->setEvent(desc); - #endif +#endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(creature->getPosition()); From 1b6f6c4dbb3889290bb0c38882d21e5cb4b41054 Mon Sep 17 00:00:00 2001 From: Leandro Date: Sun, 29 May 2016 16:52:55 -0430 Subject: [PATCH 2/2] Added CastSystem and AntiDupeSystem // Cast System require the account with name 10 Contiene algunas modificaciones para un optimo funcionamiento con respecto al cast en 8.6 y probado al 100% y funcionando sin problemas. --- CHANGELOG | 1 + path_7_x/mods/mod_cast.xml | 251 ++++++++ path_7_x/sources/Makefile.am | 2 +- path_7_x/sources/databasemanager.cpp | 37 ++ path_7_x/sources/game.cpp | 1 + path_7_x/sources/iologindata.cpp | 42 +- path_7_x/sources/iomapserialize.cpp | 14 +- path_7_x/sources/item.cpp | 33 + path_7_x/sources/item.h | 1 + path_7_x/sources/items.cpp | 2 +- path_7_x/sources/luascript.cpp | 160 +++++ path_7_x/sources/luascript.h | 4 + path_7_x/sources/msvc/TheOTXServer.vcxproj | 2 + .../sources/msvc/TheOTXServer.vcxproj.filters | 6 + path_7_x/sources/otserv.cpp | 98 +++ path_7_x/sources/player.cpp | 15 +- path_7_x/sources/player.h | 12 +- path_7_x/sources/protocolgame.cpp | 186 ++++-- path_7_x/sources/protocolgame.h | 10 +- path_7_x/sources/protocollogin.cpp | 161 +++-- path_7_x/sources/spectators.cpp | 323 ++++++++++ path_7_x/sources/spectators.h | 607 ++++++++++++++++++ 22 files changed, 1837 insertions(+), 131 deletions(-) create mode 100644 path_7_x/mods/mod_cast.xml create mode 100644 path_7_x/sources/spectators.cpp create mode 100644 path_7_x/sources/spectators.h diff --git a/CHANGELOG b/CHANGELOG index 6e8488605..6d23dd422 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -68,6 +68,7 @@ - Death container for 7.x - Fix dont lose CONDITION_INFIGHT on PROTECTION_ZONE only 7x - Fix Exhaust on protocol 7x + - Added CastSystem and AntiDupeSystem for 7x ] [ OTX Server 2.X.S - 2 :: Version "Crying Damson" diff --git a/path_7_x/mods/mod_cast.xml b/path_7_x/mods/mod_cast.xml new file mode 100644 index 000000000..8fb78033e --- /dev/null +++ b/path_7_x/mods/mod_cast.xml @@ -0,0 +1,251 @@ + + + + + 0) then + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are currently watched by " .. count .. " people.") + local str = "" + for _, name in ipairs(data.names) do + str = str .. (str:len() > 0 and ", " or "") .. name + end + + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, str .. ".") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "None is watching your stream right now.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are not streaming right now.") + end + elseif(isInArray({'kick', 'remove'}, t[1])) then + if(data.broadcast) then + if(t[2]) then + if(t[2] ~= "all") then + local found = false + for _, name in ipairs(data.names) do + if(t[2]:lower() == name:lower()) then + found = true + break + end + end + + if(found) then + table.insert(data.kick, t[2]) + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " has been kicked.") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " not found.") + end + else + data.kick = data.names + doPlayerSetSpectators(cid, data) + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You need to type a name.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are not streaming right now.") + end + elseif(isInArray({'ban', 'block'}, t[1])) then + if(data.broadcast) then + if(t[2]) then + local found = false + for _, name in ipairs(data.names) do + if(t[2]:lower() == name:lower()) then + found = true + break + end + end + + if(found) then + table.insert(data.bans, t[2]) + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " has been banned.") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " not found.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You need to type a name.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are not streaming right now.") + end + elseif(isInArray({'unban', 'unblock'}, t[1])) then + if(data.broadcast) then + if(t[2]) then + local found, i = 0, 1 + for _, name in ipairs(data.bans) do + if(t[2]:lower() == name:lower()) then + found = i + break + end + + i = i + 1 + end + + if(found > 0) then + table.remove(data.bans, found) + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " has been unbanned.") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " not found.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You need to type a name.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are not streaming right now.") + end + elseif(isInArray({'bans', 'banlist'}, t[1])) then + if(table.maxn(data.bans)) then + local str = "" + for _, name in ipairs(data.bans) do + str = str .. (str:len() > 0 and ", " or "") .. name + end + + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Currently banned spectators: " .. str .. ".") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your ban list is empty.") + end + elseif(isInArray({'mute', 'squelch'}, t[1])) then + if(data.broadcast) then + if(t[2]) then + local found = false + for _, name in ipairs(data.names) do + if(t[2]:lower() == name:lower()) then + found = true + break + end + end + + if(found) then + table.insert(data.mutes, t[2]) + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " has been muted.") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " not found.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You need to type a name.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are not streaming right now.") + end + elseif(isInArray({'unmute', 'unsquelch'}, t[1])) then + if(data.broadcast) then + if(t[2]) then + local found, i = 0, 1 + for _, name in ipairs(data.mutes) do + if(t[2]:lower() == name:lower()) then + found = i + break + end + + i = i + 1 + end + + if(found > 0) then + table.remove(data.mutes, found) + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " has been unmuted.") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Spectator " .. t[2] .. " not found.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You need to type a name.") + end + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are not streaming right now.") + end + elseif(isInArray({'mutes', 'mutelist'}, t[1])) then + if(table.maxn(data.mutes)) then + local str = "" + for _, name in ipairs(data.mutes) do + str = str .. (str:len() > 0 and ", " or "") .. name + end + + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Currently muted spectators: " .. str .. ".") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your mute list is empty.") + end + elseif(isInArray({'auth', 'protect', 'protection', 'protected'}, t[1])) then + if(isInArray({'off', 'no', 'disable'}, t[2])) then + data.auth = false + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your chat is now unprotected, all spectators can chat without authentication.") + elseif(isInArray({'on', 'yes', 'enable'}, t[2])) then + data.auth = true + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your chat is now protected, all spectators have to authenticate before they can talk.") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your chat is currently " .. (data.auth and "protected" or "unprotected") .. " from guests.") + end + elseif(isInArray({'password', 'guard'}, t[1])) then + if(t[2]) then + if(isInArray({'off', 'no', 'disable'}, t[2])) then + if(data.password:len() ~= 0) then + db.executeQuery("UPDATE `players` SET `broadcasting` = `broadcasting` - 2 WHERE `id` = " .. getPlayerGUID(cid)) + end + + data.password = "" + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have removed password for your stream.") + else + if(data.password:len() ~= 0) then + db.executeQuery("UPDATE `players` SET `broadcasting` = `broadcasting` + 2 WHERE `id` = " .. getPlayerGUID(cid)) + end + + data.password = string.trim(t[2]) + doPlayerSetSpectators(cid, data) + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have set new password for your stream.") + end + elseif(data.password ~= "") then + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your stream is currently protected with password: " .. data.password .. ".") + else + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your stream is currently not protected.") + end + elseif(isInArray({'status', 'info'}, t[1])) then + doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Your stream is currently " .. (data.broadcast and "enabled" or "disabled") .. ".") + else + doShowTextDialog(cid, 1950, "Available commands:\n\n/live on - enables the stream\n/live off - disables the stream\n/live password {password} - sets a password on the stream\n/live password off - disables the password protection\n/live auth on - enables requirement of authentication on chat\n/live auth off - disables requirement of authentication on chat\n/live kick {name} - kick a spectator from your stream\n/live ban {name} - locks spectator IP from joining your stream\n/live unban {name} - removes banishment lock\n/live bans - shows banished spectators list\n/live mute {name} - mutes selected spectator from chat\n/live unmute {name} - removes mute\n/live mutes - shows muted spectators list\n/live show - displays the amount and nicknames of current spectators\n/live status - displays stream status") + end + + return true + end + ]]> + diff --git a/path_7_x/sources/Makefile.am b/path_7_x/sources/Makefile.am index f8c90375d..b89e4207f 100644 --- a/path_7_x/sources/Makefile.am +++ b/path_7_x/sources/Makefile.am @@ -44,7 +44,7 @@ theotxserver_SOURCES = account.h actions.cpp actions.h baseevents.cpp baseevent protocol.cpp protocol.h protocolgame.cpp protocolgame.h \ protocollogin.cpp protocollogin.h raids.cpp raids.h \ resources.h scheduler.cpp scheduler.h scriptmanager.cpp \ - scriptmanager.h server.cpp server.h spawn.cpp spawn.h \ + scriptmanager.h server.cpp server.h spawn.cpp spawn.h spectators.cpp spectators.h \ spells.cpp spells.h status.cpp status.h talkaction.cpp talkaction.h teleport.cpp \ teleport.h templates.h textlogger.cpp textlogger.h thing.cpp thing.h \ tile.cpp tile.h tools.cpp tools.h town.h trashholder.cpp trashholder.h \ diff --git a/path_7_x/sources/databasemanager.cpp b/path_7_x/sources/databasemanager.cpp index 9c9fa1eab..05664a697 100644 --- a/path_7_x/sources/databasemanager.cpp +++ b/path_7_x/sources/databasemanager.cpp @@ -241,6 +241,43 @@ uint32_t DatabaseManager::updateDatabase() return 2; } + case 2: + { + std::clog << "> Updating database to version 3... (Cast & AntiDupe System)" << std::endl; + switch (db->getDatabaseEngine()) + { + case DATABASE_ENGINE_MYSQL: + { + db->query("ALTER TABLE player_items ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE player_depotitems ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE tile_items ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE tile_store ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE house_data ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE `players` ADD `broadcasting` tinyint(4) DEFAULT '0'"); + db->query("ALTER TABLE `players` ADD `viewers` INT(1) DEFAULT '0'"); + break; + } + + case DATABASE_ENGINE_SQLITE: + { + db->query("ALTER TABLE player_items ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE player_depotitems ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE tile_items ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE tile_store ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE house_data ADD serial VARCHAR(255) NOT NULL DEFAULT '';"); + db->query("ALTER TABLE `players` ADD `broadcasting` tinyint(4) NOT NULL DEFAULT 0;"); + db->query("ALTER TABLE `players` ADD `viewers` BOOLEAN(1) NOT NULL DEFAULT 0;"); + break; + } + + default: + break; + } + + registerDatabaseConfig("db_version", 3); + return 3; + } + default: break; } diff --git a/path_7_x/sources/game.cpp b/path_7_x/sources/game.cpp index 7633719f0..d67a58f54 100644 --- a/path_7_x/sources/game.cpp +++ b/path_7_x/sources/game.cpp @@ -2424,6 +2424,7 @@ bool Game::playerCloseChannel(uint32_t playerId, uint16_t channelId) return false; g_chat.removeUserFromChannel(player, channelId); + player->client->chat(channelId); return true; } diff --git a/path_7_x/sources/iologindata.cpp b/path_7_x/sources/iologindata.cpp index cbe3691bc..ecf83758f 100644 --- a/path_7_x/sources/iologindata.cpp +++ b/path_7_x/sources/iologindata.cpp @@ -701,7 +701,7 @@ bool IOLoginData::loadPlayer(Player* player, const std::string& name, bool preLo //load inventory items query.str(""); - query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_items` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; + query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes`, `serial` FROM `player_items` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; if((result = db->storeQuery(query.str()))) { loadItems(itemMap, result); @@ -728,7 +728,7 @@ bool IOLoginData::loadPlayer(Player* player, const std::string& name, bool preLo //load depot items query.str(""); - query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes` FROM `player_depotitems` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; + query << "SELECT `pid`, `sid`, `itemtype`, `count`, `attributes`, `serial` FROM `player_depotitems` WHERE `player_id` = " << player->getGUID() << " ORDER BY `sid` DESC"; if((result = db->storeQuery(query.str()))) { loadItems(itemMap, result); @@ -837,10 +837,16 @@ void IOLoginData::loadItems(ItemMap& itemMap, DBResult* result) if(!item->unserializeAttr(propStream)) std::clog << "[Warning - IOLoginData::loadItems] Unserialize error for item with id " << item->getID() << std::endl; + std::string serial = result->getDataString("serial"); + if (serial != "") + { + std::string key = "serial"; + item->setAttribute(key.c_str(), serial); + } + itemMap[result->getDataInt("sid")] = std::make_pair(item, result->getDataInt("pid")); } - } - while(result->next()); + } while (result->next()); } bool IOLoginData::savePlayer(Player* player, bool preSave/* = true*/, bool shallow/* = false*/) @@ -1003,7 +1009,7 @@ bool IOLoginData::savePlayer(Player* player, bool preSave/* = true*/, bool shall itemList.push_back(itemBlock(slotId, item)); } - stmt.setQuery("INSERT INTO `player_items` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES "); + stmt.setQuery("INSERT INTO `player_items` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`, `serial`) VALUES "); if(!saveItems(player, itemList, stmt)) return false; @@ -1032,7 +1038,7 @@ bool IOLoginData::savePlayer(Player* player, bool preSave/* = true*/, bool shall if(itemList.size()) { - stmt.setQuery("INSERT INTO `player_depotitems` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES "); + stmt.setQuery("INSERT INTO `player_depotitems` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`, `serial`) VALUES "); if(!saveItems(player, itemList, stmt)) return false; @@ -1135,12 +1141,22 @@ bool IOLoginData::saveItems(const Player* player, const ItemBlockList& itemList, PropWriteStream propWriteStream; item->serializeAttr(propWriteStream); + std::string key = "serial"; + boost::any value = item->getAttribute(key.c_str()); + if (value.empty()) + { + item->generateSerial(); + value = item->getAttribute(key.c_str()); + } + + item->eraseAttribute(key.c_str()); + uint32_t attributesSize = 0; const char* attributes = propWriteStream.getStream(attributesSize); std::stringstream buffer; buffer << player->getGUID() << "," << it->first << "," << runningId << "," << item->getID() << "," - << (int32_t)item->getSubType() << "," << db->escapeBlob(attributes, attributesSize); + << (int32_t)item->getSubType() << "," << db->escapeBlob(attributes, attributesSize) << "," << db->escapeString(boost::any_cast(value).c_str()); if(!stmt.addRow(buffer)) return false; @@ -1163,12 +1179,22 @@ bool IOLoginData::saveItems(const Player* player, const ItemBlockList& itemList, PropWriteStream propWriteStream; item->serializeAttr(propWriteStream); + std::string key = "serial"; + boost::any value = item->getAttribute(key.c_str()); + if (value.empty()) + { + item->generateSerial(); + value = item->getAttribute(key.c_str()); + } + + item->eraseAttribute(key.c_str()); + uint32_t attributesSize = 0; const char* attributes = propWriteStream.getStream(attributesSize); std::stringstream buffer; buffer << player->getGUID() << "," << stack.second << "," << runningId << "," << item->getID() << "," - << (int32_t)item->getSubType() << "," << db->escapeBlob(attributes, attributesSize); + << (int32_t)item->getSubType() << "," << db->escapeBlob(attributes, attributesSize) << "," << db->escapeString(boost::any_cast(value).c_str()); if(!stmt.addRow(buffer)) return false; } diff --git a/path_7_x/sources/iomapserialize.cpp b/path_7_x/sources/iomapserialize.cpp index b8916ebdb..1cb36f1c0 100644 --- a/path_7_x/sources/iomapserialize.cpp +++ b/path_7_x/sources/iomapserialize.cpp @@ -821,7 +821,7 @@ bool IOMapSerialize::saveItems(Database* db, uint32_t& tileId, uint32_t houseId, bool stored = false; DBInsert stmt(db); - stmt.setQuery("INSERT INTO `tile_items` (`tile_id`, `world_id`, `sid`, `pid`, `itemtype`, `count`, `attributes`) VALUES "); + stmt.setQuery("INSERT INTO `tile_items` (`tile_id`, `world_id`, `sid`, `pid`, `itemtype`, `count`, `attributes`, `serial`) VALUES "); DBQuery query; for(int32_t i = 0; i < thingCount; ++i) @@ -845,11 +845,21 @@ bool IOMapSerialize::saveItems(Database* db, uint32_t& tileId, uint32_t houseId, PropWriteStream propWriteStream; item->serializeAttr(propWriteStream); + std::string key = "serial"; + boost::any value = item->getAttribute(key.c_str()); + if (value.empty()) + { + item->generateSerial(); + value = item->getAttribute(key.c_str()); + } + + item->eraseAttribute(key.c_str()); + uint32_t attributesSize = 0; const char* attributes = propWriteStream.getStream(attributesSize); query << tileId << ", " << g_config.getNumber(ConfigManager::WORLD_ID) << ", " << ++runningId << ", " << parentId << ", " - << item->getID() << ", " << (int32_t)item->getSubType() << ", " << db->escapeBlob(attributes, attributesSize); + << item->getID() << ", " << (int32_t)item->getSubType() << ", " << db->escapeBlob(attributes, attributesSize) << ", " << db->escapeString(boost::any_cast(value).c_str()); if(!stmt.addRow(query.str())) return false; diff --git a/path_7_x/sources/item.cpp b/path_7_x/sources/item.cpp index 84b30a4b0..099bf8df6 100644 --- a/path_7_x/sources/item.cpp +++ b/path_7_x/sources/item.cpp @@ -1713,3 +1713,36 @@ void Item::__startDecaying() { g_game.startDecay(this); } + +void Item::generateSerial() +{ + std::string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + std::string serial = ""; + for (int32_t i = 1; i < 6; i++) + { + int32_t l = rand() % (letters.length() - 1) + 1; + serial += letters.substr(l, 1); + } + serial += "-"; + for (int32_t i = 1; i < 6; i++) + { + int32_t l = rand() % (letters.length() - 1) + 1; + serial += letters.substr(l, 1); + } + serial += "-"; + for (int32_t i = 1; i < 6; i++) + { + int32_t l = rand() % (letters.length() - 1) + 1; + serial += letters.substr(l, 1); + } + serial += "-"; + for (int32_t i = 1; i < 6; i++) + { + int32_t l = rand() % (letters.length() - 1) + 1; + serial += letters.substr(l, 1); + } + + std::string key = "serial"; + this->setAttribute(key.c_str(), serial); + serial = ""; +} diff --git a/path_7_x/sources/item.h b/path_7_x/sources/item.h index 540717e02..a52583488 100644 --- a/path_7_x/sources/item.h +++ b/path_7_x/sources/item.h @@ -187,6 +187,7 @@ class Item : virtual public Thing, public ItemAttributes static std::string getDescription(const ItemType& it, int32_t lookDistance, const Item* item = NULL, int32_t subType = -1, bool addArticle = true); static std::string getNameDescription(const ItemType& it, const Item* item = NULL, int32_t subType = -1, bool addArticle = true); static std::string getWeightDescription(double weight, bool stackable, uint32_t count = 1); + void generateSerial(); virtual std::string getDescription(int32_t lookDistance) const {return getDescription(items[id], lookDistance, this);} std::string getNameDescription() const {return getNameDescription(items[id], this);} diff --git a/path_7_x/sources/items.cpp b/path_7_x/sources/items.cpp index 0a5579a8d..1189cea88 100644 --- a/path_7_x/sources/items.cpp +++ b/path_7_x/sources/items.cpp @@ -1446,7 +1446,7 @@ void Items::parseItemNode(xmlNodePtr itemNode, uint32_t id) if(readXMLInteger(itemAttributesNode, "value", intValue)) it.getAbilities()->reflect[REFLECT_PERCENT][COMBAT_FIREDAMAGE] += intValue; } - else if(tmpStrValue == "reflectpercentpoison" || tmpStrValue == "reflectpercentearth") + else if (tmpStrValue == "reflectpercentpoison" || tmpStrValue == "reflectpercentearth") { if(readXMLInteger(itemAttributesNode, "value", intValue)) it.getAbilities()->reflect[REFLECT_PERCENT][COMBAT_EARTHDAMAGE] += intValue; diff --git a/path_7_x/sources/luascript.cpp b/path_7_x/sources/luascript.cpp index 134e983b9..3c3b99237 100644 --- a/path_7_x/sources/luascript.cpp +++ b/path_7_x/sources/luascript.cpp @@ -1653,6 +1653,12 @@ void LuaInterface::registerFunctions() //doCreatureSetStorage(uid, key, value) lua_register(m_luaState, "doCreatureSetStorage", LuaInterface::luaDoCreatureSetStorage); + //getPlayerSpectators(cid) + lua_register(m_luaState, "getPlayerSpectators", LuaInterface::luaGetPlayerSpectators); + + //doPlayerSetSpectators(cid, data) + lua_register(m_luaState, "doPlayerSetSpectators", LuaInterface::luaDoPlayerSetSpectators); + //getStorageList() lua_register(m_luaState, "getStorageList", LuaInterface::luaGetStorageList); @@ -2398,6 +2404,12 @@ void LuaInterface::registerFunctions() //doAddAccountBanishment(...) lua_register(m_luaState, "doAddAccountBanishment", LuaInterface::luaDoAddAccountBanishment); + //doAddAccountWarnings(...) + lua_register(m_luaState, "doAddAccountWarnings", LuaInterface::luaDoAddAccountWarnings); + + //getAccountWarnings(accountId) + lua_register(m_luaState, "getAccountWarnings", LuaInterface::luaGetAccountWarnings); + //doAddNotation(...) lua_register(m_luaState, "doAddNotation", LuaInterface::luaDoAddNotation); @@ -5163,6 +5175,131 @@ int32_t LuaInterface::luaDoCreatureSetStorage(lua_State* L) return 1; } +int32_t LuaInterface::luaGetPlayerSpectators(lua_State* L) +{ + ScriptEnviroment* env = getEnv(); + if (Player* player = env->getPlayerByUID(popNumber(L))) + { + lua_newtable(L); + setFieldBool(L, "broadcast", player->client->isBroadcasting()); + setField(L, "password", player->client->getPassword()); + setFieldBool(L, "auth", player->client->isAuth()); + + createTable(L, "names"); + StringVec t = player->client->list(); + + StringVec::const_iterator it = t.begin(); + for (uint32_t i = 1; it != t.end(); ++it, ++i) + { + lua_pushnumber(L, i); + lua_pushstring(L, (*it).c_str()); + pushTable(L); + } + + pushTable(L); + createTable(L, "mutes"); + t = player->client->muteList(); + + it = t.begin(); + for (uint32_t i = 1; it != t.end(); ++it, ++i) + { + lua_pushnumber(L, i); + lua_pushstring(L, (*it).c_str()); + pushTable(L); + } + + pushTable(L); + createTable(L, "bans"); + std::map _t = player->client->banList(); + + std::map::const_iterator _it = _t.begin(); + for (uint32_t i = 1; _it != _t.end(); ++_it, ++i) + { + lua_pushnumber(L, i); + lua_pushstring(L, _it->first.c_str()); + pushTable(L); + } + + pushTable(L); + createTable(L, "kick"); + pushTable(L); + } + else + { + errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND)); + lua_pushboolean(L, false); + } + + return 1; +} + +int32_t LuaInterface::luaDoPlayerSetSpectators(lua_State* L) +{ + std::string password = getFieldString(L, "password"); + bool broadcast = getFieldBool(L, "broadcast"), + auth = getFieldBool(L, "auth"); + + StringVec m, b, k; + lua_pushstring(L, "mutes"); + lua_gettable(L, -2); + + lua_pushnil(L); + while (lua_next(L, -2)) + { + m.push_back(asLowerCaseString(lua_tostring(L, -1))); + lua_pop(L, 1); + } + + lua_pop(L, 1); + lua_pushstring(L, "bans"); + lua_gettable(L, -2); + + lua_pushnil(L); + while (lua_next(L, -2)) + { + b.push_back(asLowerCaseString(lua_tostring(L, -1))); + lua_pop(L, 1); + } + + lua_pop(L, 1); + lua_pushstring(L, "kick"); + lua_gettable(L, -2); + + lua_pushnil(L); + while (lua_next(L, -2)) + { + k.push_back(asLowerCaseString(lua_tostring(L, -1))); + lua_pop(L, 1); + } + + lua_pop(L, 2); + ScriptEnviroment* env = getEnv(); + if (Player* player = env->getPlayerByUID(popNumber(L))) + { + if (player->client->getPassword() != password && !password.empty()) + player->client->clear(false); + + player->client->setPassword(password); + if (!broadcast && player->client->isBroadcasting()) + player->client->clear(false); + + player->client->kick(k); + player->client->mute(m); + player->client->ban(b); + + player->client->setBroadcast(broadcast); + player->client->setAuth(auth); + lua_pushboolean(L, true); + } + else + { + errorEx(getError(LUA_ERROR_PLAYER_NOT_FOUND)); + lua_pushboolean(L, false); + } + + return 1; +} + int32_t LuaInterface::luaGetTileInfo(lua_State* L) { //getTileInfo(pos) @@ -10452,6 +10589,21 @@ int32_t LuaInterface::luaDoAddAccountBanishment(lua_State* L) return 1; } +int32_t LuaInterface::luaDoAddAccountWarnings(lua_State* L) +{ + //doAddAccountWarnings(accountId[, warnings]) + uint32_t warnings = 1; + int32_t params = lua_gettop(L); + if (params > 1) + warnings = popNumber(L); + + Account account = IOLoginData::getInstance()->loadAccount(popNumber(L), true); + account.warnings += warnings; + IOLoginData::getInstance()->saveAccount(account); + lua_pushboolean(L, true); + return 1; +} + int32_t LuaInterface::luaDoAddNotation(lua_State* L) { //doAddNotation(accountId[, playerId[, reason[, comment[, admin[, statement]]]]]]) @@ -10556,6 +10708,14 @@ int32_t LuaInterface::luaDoRemoveNotations(lua_State* L) return 1; } +int32_t LuaInterface::luaGetAccountWarnings(lua_State* L) +{ + //getAccountWarnings(accountId) + Account account = IOLoginData::getInstance()->loadAccount(popNumber(L)); + lua_pushnumber(L, account.warnings); + return 1; +} + int32_t LuaInterface::luaGetNotationsCount(lua_State* L) { //getNotationsCount(accountId[, playerId]) diff --git a/path_7_x/sources/luascript.h b/path_7_x/sources/luascript.h index b674bfedd..6b33d56a9 100644 --- a/path_7_x/sources/luascript.h +++ b/path_7_x/sources/luascript.h @@ -448,6 +448,8 @@ class LuaInterface static int32_t luaDoRemoveIpBanishment(lua_State* L); static int32_t luaDoRemovePlayerBanishment(lua_State* L); static int32_t luaDoRemoveAccountBanishment(lua_State* L); + static int32_t luaDoAddAccountWarnings(lua_State* L); + static int32_t luaGetAccountWarnings(lua_State* L); static int32_t luaDoRemoveNotations(lua_State* L); static int32_t luaDoRemoveStatements(lua_State* L); static int32_t luaGetNotationsCount(lua_State* L); @@ -570,6 +572,8 @@ class LuaInterface static int32_t luaGetCreatureStorageList(lua_State* L); static int32_t luaGetCreatureStorage(lua_State* L); static int32_t luaDoCreatureSetStorage(lua_State* L); + static int32_t luaGetPlayerSpectators(lua_State* L); + static int32_t luaDoPlayerSetSpectators(lua_State* L); static int32_t luaDoPlayerAddBlessing(lua_State* L); static int32_t luaGetPlayerBlessing(lua_State* L); static int32_t luaDoPlayerSetPVPBlessing(lua_State* L); diff --git a/path_7_x/sources/msvc/TheOTXServer.vcxproj b/path_7_x/sources/msvc/TheOTXServer.vcxproj index 01958ee64..92574b58e 100644 --- a/path_7_x/sources/msvc/TheOTXServer.vcxproj +++ b/path_7_x/sources/msvc/TheOTXServer.vcxproj @@ -103,6 +103,7 @@ + @@ -195,6 +196,7 @@ + diff --git a/path_7_x/sources/msvc/TheOTXServer.vcxproj.filters b/path_7_x/sources/msvc/TheOTXServer.vcxproj.filters index ecccdedcf..4fc517dab 100644 --- a/path_7_x/sources/msvc/TheOTXServer.vcxproj.filters +++ b/path_7_x/sources/msvc/TheOTXServer.vcxproj.filters @@ -264,6 +264,9 @@ Header Files + + Header Files + @@ -488,6 +491,9 @@ Source Files + + Source Files + diff --git a/path_7_x/sources/otserv.cpp b/path_7_x/sources/otserv.cpp index b5a8839a7..51361a774 100644 --- a/path_7_x/sources/otserv.cpp +++ b/path_7_x/sources/otserv.cpp @@ -660,6 +660,104 @@ ServiceManager* services) else startupErrorMessage("Couldn't estabilish connection to SQL database!"); + std::clog << ">> Checking for duplicated items" << std::endl; +#if defined(WINDOWS) && !defined(_CONSOLE) + SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Checking for duplicated items"); +#endif + DBQuery query; + query << "SELECT unitedItems.serial, COUNT(1) AS duplicatesCount FROM (SELECT serial FROM `player_items` UNION ALL SELECT serial FROM `player_depotitems` UNION ALL SELECT serial FROM `tile_items`) unitedItems GROUP BY unitedItems.serial HAVING COUNT(1) > 1;"; + std::string logText = ""; + + DBResult* result; + bool duplicated = false; + + if (result = db->storeQuery(query.str())) + { + do + { + std::string serial = result->getDataString("serial"); + if (serial != "" && serial.length() > 1) + { + DBResult* result_; + DBQuery query_playeritems; + query_playeritems << "SELECT `player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`, `serial` FROM `player_items` WHERE `serial` = " << db->escapeString(serial) << ";"; + if (result_ = db->storeQuery(query_playeritems.str())) + { + duplicated = true; + do + { + std::string name; + IOLoginData::getInstance()->getNameByGuid((uint32_t)result_->getDataInt("player_id"), name, false); + std::clog << ">> Deleted item from 'player_items' with SERIAL: [" << serial.c_str() << "] PLAYER: [" << result_->getDataInt("player_id") << "] PLAYER NAME: [" << name.c_str() << "] ITEM: [" << result_->getDataInt("itemtype") << "] COUNT: [" << result_->getDataInt("count") << "]" << std::endl; + std::stringstream logText; + logText << "Deleted item from 'player_items' with SERIAL: [" << serial << "] PLAYER: [" << result_->getDataInt("player_id") << "] PLAYER NAME: [" << name << "] ITEM: [" << result_->getDataInt("itemtype") << "] COUNT: [" << result_->getDataInt("count") << "]"; + Logger::getInstance()->eFile("anti_dupe.log", logText.str(), true); + } while (result_->next()); + result_->free(); + } + + query_playeritems.clear(); + DBQuery query_playerdepotitems; + query_playerdepotitems << "SELECT `player_id`, `sid`, `pid`, `itemtype`, `count`, `attributes`, `serial` FROM `player_depotitems` WHERE `serial` = " << db->escapeString(serial) << ";"; + if (result_ = db->storeQuery(query_playerdepotitems.str())) + { + duplicated = true; + do + { + std::string name; + IOLoginData::getInstance()->getNameByGuid((uint32_t)result_->getDataInt("player_id"), name, false); + std::clog << ">> Deleted item from 'player_depotitems' with SERIAL: [" << serial.c_str() << "] PLAYER: [" << result_->getDataInt("player_id") << "] PLAYER NAME: [" << name.c_str() << "] ITEM: [" << result_->getDataInt("itemtype") << "] COUNT: [" << result_->getDataInt("count") << "]" << std::endl; + std::stringstream logText; + logText << "Deleted item from 'player_depotitems' with SERIAL: [" << serial << "] PLAYER: [" << result_->getDataInt("player_id") << "] PLAYER NAME: [" << name << "] ITEM: [" << result_->getDataInt("itemtype") << "] COUNT: [" << result_->getDataInt("count") << "]"; + Logger::getInstance()->eFile("anti_dupe.log", logText.str(), true); + } while (result_->next()); + result_->free(); + } + + query_playerdepotitems.clear(); + DBQuery query_tileitems; + query_tileitems << "SELECT `tile_id`, `world_id`, `sid`, `pid`, `itemtype`, `count`, `attributes`, `serial` FROM `tile_items` WHERE `serial` = " << db->escapeString(serial) << ";"; + if (result_ = db->storeQuery(query_tileitems.str())) + { + duplicated = true; + do + { + std::clog << ">> Deleted item from 'tile_items' with SERIAL: [" << serial.c_str() << "] TILE ID: [" << result_->getDataInt("tile_id") << "] WORLD ID: [" << result_->getDataInt("world_id") << "] ITEM: [" << result_->getDataInt("itemtype") << "] COUNT: [" << result_->getDataInt("count") << "]" << std::endl; + std::stringstream logText; + logText << "Deleted item from 'tile_items' with SERIAL: [" << serial << "] TILE ID: [" << result_->getDataInt("tile_id") << "] WORLD ID: [" << result_->getDataInt("world_id") << "] ITEM: [" << result_->getDataInt("itemtype") << "] COUNT: [" << result_->getDataInt("count") << "]"; + Logger::getInstance()->eFile("anti_dupe.log", logText.str(), true); + } while (result_->next()); + result_->free(); + } + + query_tileitems.clear(); + DBQuery query_deletepi; + query_deletepi << "DELETE FROM `player_items` WHERE `serial` = " << db->escapeString(serial) << ";"; + if (!db->query(query_deletepi.str())) + std::clog << ">> Cannot delete duplicated items from 'player_items'!" << std::endl; + + query_deletepi.clear(); + DBQuery query_deletedi; + query_deletedi << "DELETE FROM `player_depotitems` WHERE `serial` = " << db->escapeString(serial) << ";"; + if (!db->query(query_deletedi.str())) + std::clog << ">> Cannot delete duplicated items from 'player_depotitems'!" << std::endl; + + query_deletedi.clear(); + DBQuery query_deleteti; + query_deleteti << "DELETE FROM `tile_items` WHERE `serial` = " << db->escapeString(serial) << ";"; + if (!db->query(query_deleteti.str())) + std::clog << ">> Cannot delete duplicated items from 'tile_items'!" << std::endl; + + query_deleteti.clear(); + } + } while (result->next()); + result->free(); + if (duplicated) + std::clog << ">> Duplicated items successfully removed." << std::endl; + } + else + std::clog << ">> There wasn't duplicated items in the server." << std::endl; + std::clog << ">> Loading groups" << std::endl; #if defined(WINDOWS) && !defined(_CONSOLE) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Loading groups"); diff --git a/path_7_x/sources/player.cpp b/path_7_x/sources/player.cpp index 90bddd34d..0fc8fa0b7 100644 --- a/path_7_x/sources/player.cpp +++ b/path_7_x/sources/player.cpp @@ -56,9 +56,9 @@ uint32_t Player::playerCount = 0; MuteCountMap Player::muteCountMap; Player::Player(const std::string& _name, ProtocolGame* p): - Creature(), transferContainer(ITEM_LOCKER), name(_name), nameDescription(_name), client(p) + Creature(), transferContainer(ITEM_LOCKER), name(_name), nameDescription(_name), client(new Spectators(p)) { - if(client) + if (client->getOwner()) p->setPlayer(this); pvpBlessing = pzLocked = isConnecting = addAttackSkillPoint = requestedOutfit = outfitAttributes = sentChat = false; @@ -105,6 +105,7 @@ Player::Player(const std::string& _name, ProtocolGame* p): setParty(NULL); transferContainer.setParent(NULL); + delete client; for(int32_t i = 0; i < 11; ++i) { inventory[i] = NULL; @@ -1275,6 +1276,15 @@ void Player::sendRemoveContainerItem(const Container* container, uint8_t slot, c } } +void Player::sendContainers(ProtocolGame* target) +{ + if (!target) + return; + + for (ContainerVector::const_iterator cl = containerVec.begin(); cl != containerVec.end(); ++cl) + target->sendContainer(cl->first, cl->second, dynamic_cast(cl->second->getParent()) != NULL); +} + void Player::onUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem, const ItemType& oldType, const Item* newItem, const ItemType& newType) { @@ -1524,6 +1534,7 @@ void Player::onCreatureDisappear(const Creature* creature, bool isLogout) if(creature != this) return; + client->clear(true); if(isLogout) loginPosition = getPosition(); diff --git a/path_7_x/sources/player.h b/path_7_x/sources/player.h index 6828d9a0c..e8c11e954 100644 --- a/path_7_x/sources/player.h +++ b/path_7_x/sources/player.h @@ -30,7 +30,7 @@ #include "vocation.h" #include "group.h" -#include "protocolgame.h" +#include "spectators.h" #include "ioguild.h" #include "party.h" #include "npc.h" @@ -41,6 +41,7 @@ class Npc; class Party; class SchedulerTask; class BedItem; +class ProtocolGame; enum skillsid_t { @@ -245,7 +246,7 @@ class Player : public Creature, public Cylinder uint32_t getClientVersion() const {return clientVersion;} void setClientVersion(uint32_t version) {clientVersion = version;} - bool hasClient() const {return (client != NULL);} + bool hasClient() const { return (client->getOwner() != NULL); } bool isVirtual() const {return (getID() == 0);} uint32_t getIP() const; bool canOpenCorpse(uint32_t ownerId); @@ -515,6 +516,8 @@ class Player : public Creature, public Cylinder {if(client) client->sendChannelMessage(author, text, type, channel);} void sendCreatureAppear(const Creature* creature) {if(client) client->sendAddCreature(creature, creature->getPosition(), creature->getTile()->__getIndexOfThing(creature));} + void sendCreatureAppear(const Creature* creature, ProtocolGame* target) + {if (target) target->sendAddCreature(creature, creature->getPosition(), creature->getTile()->getClientIndexOfThing(this, creature)); } void sendCreatureDisappear(const Creature* creature, uint32_t stackpos) {if(client) client->sendRemoveCreature(creature, creature->getPosition(), stackpos);} void sendCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos, @@ -546,6 +549,7 @@ class Player : public Creature, public Cylinder void sendRemoveContainerItem(const Container* container, uint8_t slot, const Item* item); void sendContainer(uint32_t cid, const Container* container, bool hasParent) {if(client) client->sendContainer(cid, container, hasParent);} + void sendContainers(ProtocolGame* target); //inventory void sendAddInventoryItem(slots_t slot, const Item* item) @@ -883,7 +887,7 @@ class Player : public Creature, public Cylinder std::pair backpack; Vocation* vocation; - ProtocolGame* client; + Spectators* client; SchedulerTask* walkTask; Party* party; Group* group; @@ -908,5 +912,7 @@ class Player : public Creature, public Cylinder friend class Actions; friend class IOLoginData; friend class ProtocolGame; + friend class ProtocolLogin; + friend class Spectators; }; #endif diff --git a/path_7_x/sources/protocolgame.cpp b/path_7_x/sources/protocolgame.cpp index ae9711a05..830405383 100644 --- a/path_7_x/sources/protocolgame.cpp +++ b/path_7_x/sources/protocolgame.cpp @@ -75,12 +75,18 @@ void ProtocolGame::setPlayer(Player* p) void ProtocolGame::releaseProtocol() { - if(player && player->client == this) - player->client = NULL; - + if (player) + { + if (!m_spectator) + { + if (player->client->getOwner() == this) + player->client->setOwner(NULL); + } + else if (player->client->isBroadcasting()) + player->client->removeSpectator(this); + } Protocol::releaseProtocol(); } - void ProtocolGame::deleteProtocolTask() { if(player) @@ -92,6 +98,44 @@ void ProtocolGame::deleteProtocolTask() Protocol::deleteProtocolTask(); } +void ProtocolGame::spectate(const std::string& name, const std::string& password) +{ + PlayerVector players = g_game.getPlayersByName(name); + Player* _player = NULL; + if (!players.empty()) + _player = players[random_range(0, (players.size() - 1))]; + + if (!_player || _player->isRemoved() || !_player->client->isBroadcasting() || !_player->client->getOwner()) + { + disconnectClient(0x14, "Stream unavailable."); + return; + } + + if (_player->client->banned(getIP())) + { + disconnectClient(0x14, "You are banned from this stream."); + return; + } + + if (!_player->client->check(password)) + { + disconnectClient(0x14, "This stream is protected! Invalid password."); + return; + } + + m_spectator = true; + player = _player; + player->addRef(); + player->client->addSpectator(this); + + player->sendCreatureAppear(player, this); + player->sendContainers(this); + if (PrivateChatChannel* channel = g_chat.getPrivateChannel(player)) + chat(channel->getId()); + + m_acceptPackets = true; +} + bool ProtocolGame::login(const std::string& name, uint32_t id, const std::string&, OperatingSystem_t operatingSystem, uint16_t version, bool gamemaster) { @@ -347,6 +391,7 @@ bool ProtocolGame::logout(bool displayEffect, bool forceLogout) g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF); } + player->client->clear(true); disconnect(); if(player->isRemoved()) return true; @@ -354,6 +399,32 @@ bool ProtocolGame::logout(bool displayEffect, bool forceLogout) return g_game.removeCreature(player); } +void ProtocolGame::chat(uint16_t channelId) +{ + PrivateChatChannel* tmp = g_chat.getPrivateChannel(player); + if (!tmp) + return; + + NetworkMessage_ptr msg = getOutputBuffer(); + if (!msg) + return; + + TRACK_MESSAGE(msg); + if (channelId) + { + msg->put(0xB2); + msg->put(tmp->getId()); + msg->putString(tmp->getName()); + } + else + { + msg->put(0xAB); + msg->put(1); + msg->put(tmp->getId()); + msg->putString("Live Channel"); + } +} + bool ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem, uint16_t version) { unRef(); @@ -368,10 +439,10 @@ bool ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem, player = _player; player->addRef(); - player->client = this; + player->client->setOwner(this); player->isConnecting = false; - player->sendCreatureAppear(player); + player->sendCreatureAppear(player, this); player->setOperatingSystem(operatingSystem); player->setClientVersion(version); @@ -457,16 +528,9 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg) } } - if(!name) + if (!name) { - if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER)) - { - disconnectClient(0x14, "Invalid account name."); - return; - } - - name = 1; - password = "1"; + name = 10; } if(g_game.getGameState() < GAMESTATE_NORMAL) @@ -494,7 +558,7 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg) } uint32_t id = 1; - if(!IOLoginData::getInstance()->getAccountId(name, id)) + if (name != 10 && (!IOLoginData::getInstance()->getAccountId(name, id))) { ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false); disconnectClient(0x14, "Invalid account name."); @@ -502,7 +566,7 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg) } std::string hash, salt; - if(!IOLoginData::getInstance()->getPassword(id, hash, salt, character) || !encryptTest(salt + password, hash)) + if (name != 10 && (!IOLoginData::getInstance()->getPassword(id, hash, salt, character) || !encryptTest(salt + password, hash))) { ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false); disconnectClient(0x14, "Invalid password."); @@ -532,31 +596,52 @@ void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg) } ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, true); - Dispatcher::getInstance().addTask(createTask(boost::bind( - &ProtocolGame::login, this, character, id, password, operatingSystem, version, gamemaster))); + if (name == 10) + Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::spectate, this, character, password))); + else + Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::login, this, character, id, password, operatingSystem, version, gamemaster))); } void ProtocolGame::parsePacket(NetworkMessage &msg) { - if(!player || !m_acceptPackets || g_game.getGameState() == GAMESTATE_SHUTDOWN || !msg.size()) + if (!player || !m_acceptPackets || g_game.getGameState() == GAMESTATE_SHUTDOWN || !msg.size()) return; uint32_t now = time(NULL); - if(m_packetTime != now) + if (m_packetTime != now) { m_packetTime = now; m_packetCount = 0; } ++m_packetCount; - if(m_packetCount > (uint32_t)g_config.getNumber(ConfigManager::PACKETS_PER_SECOND)) + if (m_packetCount > (uint32_t)g_config.getNumber(ConfigManager::PACKETS_PER_SECOND)) return; uint8_t recvbyte = msg.get(); - if((player->getHealth() == 0 || player->isRemoved()) && recvbyte != 0x14) //a dead player cannot performs actions + if ((player->getHealth() == 0 || player->isRemoved()) && recvbyte != 0x14) //a dead player cannot performs actions return; - if(player->isAccountManager()) + if (m_spectator) + { + switch (recvbyte) + { + case 0x14: parseLogout(msg); break; + case 0x96: parseSay(msg); break; + case 0x1E: parseReceivePing(msg); break; + case 0x97: parseGetChannels(msg); break; + case 0x98: parseOpenChannel(msg); break; + case 0xC9: parseUpdateTile(msg); break; + case 0xCA: parseUpdateContainer(msg); break; + case 0xE8: parseDebugAssert(msg); break; + case 0xA1: parseCancelTarget(msg); break; + + default: + parseCancelWalk(msg); + break; + } + } + else if (player->isAccountManager()) { switch(recvbyte) { @@ -833,7 +918,10 @@ bool ProtocolGame::canSee(uint16_t x, uint16_t y, uint16_t z) const //********************** Parse methods *******************************// void ProtocolGame::parseLogout(NetworkMessage&) { - Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::logout, this, true, false))); + if (m_spectator) + Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::disconnect, this))); + else + Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::logout, this, true, false))); } void ProtocolGame::parseCancelWalk(NetworkMessage&) @@ -865,13 +953,19 @@ void ProtocolGame::parseChannelExclude(NetworkMessage& msg) void ProtocolGame::parseGetChannels(NetworkMessage&) { - addGameTask(&Game::playerRequestChannels, player->getID()); + if (m_spectator) + Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::chat, this, 0))); + else + addGameTask(&Game::playerRequestChannels, player->getID()); } void ProtocolGame::parseOpenChannel(NetworkMessage& msg) { uint16_t channelId = msg.get(); - addGameTask(&Game::playerOpenChannel, player->getID(), channelId); + if (m_spectator) + Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::chat, this, channelId))); + else + addGameTask(&Game::playerOpenChannel, player->getID(), channelId); } void ProtocolGame::parseCloseChannel(NetworkMessage& msg) @@ -1112,27 +1206,33 @@ void ProtocolGame::parseSay(NetworkMessage& msg) uint16_t channelId = 0; MessageClasses type = (MessageClasses)msg.get(); - switch(type) + switch (type) { - case MSG_PRIVATE: - case MSG_GAMEMASTER_PRIVATE: - case MSG_RVR_ANSWER: - receiver = msg.getString(); - break; + case MSG_PRIVATE: + case MSG_GAMEMASTER_PRIVATE: + case MSG_RVR_ANSWER: + receiver = msg.getString(); + break; - case MSG_CHANNEL: - case MSG_CHANNEL_HIGHLIGHT: - case MSG_GAMEMASTER_CHANNEL: - case MSG_GAMEMASTER_ANONYMOUS: - channelId = msg.get(); - break; + case MSG_CHANNEL: + case MSG_CHANNEL_HIGHLIGHT: + case MSG_GAMEMASTER_CHANNEL: + case MSG_GAMEMASTER_ANONYMOUS: + channelId = msg.get(); + break; - default: - break; + default: + break; + } + + if (m_spectator) + { + Dispatcher::getInstance().addTask(createTask(boost::bind(&Spectators::handle, player->client, this, msg.getString(), channelId))); + return; } const std::string text = msg.getString(); - if(text.length() > 255) //client limit + if (text.length() > 255) //client limit { std::stringstream s; s << "Attempt to send message with size " << text.length() << " - client is limited to 255 characters."; @@ -1868,6 +1968,8 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position& pos AddCreatureLight(msg, creature); player->sendIcons(); + if (m_spectator) + return; for(VIPSet::iterator it = player->VIPList.begin(); it != player->VIPList.end(); ++it) { std::string vipName; diff --git a/path_7_x/sources/protocolgame.h b/path_7_x/sources/protocolgame.h index 6722c5c97..f74862e7c 100644 --- a/path_7_x/sources/protocolgame.h +++ b/path_7_x/sources/protocolgame.h @@ -32,6 +32,7 @@ class Container; class Tile; class Connection; class Depot; +class Spectators; typedef std::list > ChannelsList; typedef boost::shared_ptr NetworkMessage_ptr; @@ -49,7 +50,7 @@ class ProtocolGame : public Protocol #endif player = NULL; m_eventConnect = m_packetCount = m_packetTime = 0; - m_debugAssertSent = m_acceptPackets = false; + m_debugAssertSent = m_acceptPackets = m_spectator = false; } virtual ~ProtocolGame() { @@ -62,11 +63,15 @@ class ProtocolGame : public Protocol enum {isSingleSocket = true}; static const char* protocolName() {return "game protocol";} + void spectate(const std::string& name, const std::string& password); + bool login(const std::string& name, uint32_t id, const std::string& password, OperatingSystem_t operatingSystem, uint16_t version, bool gamemaster); bool logout(bool displayEffect, bool forceLogout); + void chat(uint16_t channelId); void setPlayer(Player* p); + Player* getPlayer() const { return player; } private: void disconnectClient(uint8_t error, const char* message); @@ -294,9 +299,10 @@ class ProtocolGame : public Protocol void addGameTaskInternal(uint32_t delay, const FunctionType&); friend class Player; + friend class Spectators; Player* player; uint32_t m_eventConnect, m_maxSizeCount, m_packetCount, m_packetTime; - bool m_debugAssertSent, m_acceptPackets; + bool m_debugAssertSent, m_acceptPackets, m_spectator; }; #endif diff --git a/path_7_x/sources/protocollogin.cpp b/path_7_x/sources/protocollogin.cpp index 024111cd7..167fa4bf8 100644 --- a/path_7_x/sources/protocollogin.cpp +++ b/path_7_x/sources/protocollogin.cpp @@ -100,16 +100,9 @@ void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) uint32_t name = msg.get(); std::string password = msg.getString(); - if(!name) + if (!name) { - if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER)) - { - disconnectClient(0x0A, "Invalid account name."); - return; - } - - name = 1; - password = "1"; + name = 10; } if(!g_config.getBool(ConfigManager::MANUAL_ADVANCED_CONFIG)) @@ -212,7 +205,7 @@ void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) // remove premium days #ifndef __LOGIN_SERVER__ IOLoginData::getInstance()->removePremium(account); - if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !account.charList.size()) + if (account.name != "10" && !g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !account.charList.size()) { disconnectClient(0x0A, std::string("This account does not contain any character yet.\nCreate a new character on the " + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str()); @@ -227,7 +220,7 @@ void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) } IOLoginData::getInstance()->removePremium(account); - if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !charList.size()) + if (account.name != "10" && !g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && !charList.size()) { disconnectClient(0x0A, std::string("This account does not contain any character on this client yet.\nCreate a new character on the " + g_config.getString(ConfigManager::SERVER_NAME) + " website at " + g_config.getString(ConfigManager::URL) + ".").c_str()); @@ -256,81 +249,109 @@ void ProtocolLogin::onRecvFirstMessage(NetworkMessage& msg) //Add char list output->put(0x64); - if(g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && account.number != 1) + if (account.name == "10" && account.name != "0") { - output->put(account.charList.size() + 1); - output->putString("Account Manager"); + PlayerVector players; + for (AutoList::iterator it = Player::autoList.begin(); it != Player::autoList.end(); ++it) + { + if (!it->second->isRemoved() && it->second->client->isBroadcasting()) + players.push_back(it->second); + } + + std::sort(players.begin(), players.end(), Player::sort); + output->put(players.size()); + for (PlayerVector::iterator it = players.begin(); it != players.end(); ++it) + { + std::stringstream s; + s << (*it)->getLevel(); + if (!(*it)->client->check(password)) + s << "*"; - output->putString(g_config.getString(ConfigManager::SERVER_NAME)); - output->put(serverIp); + output->putString((*it)->getName()); + output->putString(s.str()); + output->put(serverIp); - output->put(g_config.getNumber(ConfigManager::GAME_PORT)); + output->put(g_config.getNumber(ConfigManager::GAME_PORT)); + } } else - output->put((uint8_t)account.charList.size()); - - #ifndef __LOGIN_SERVER__ - for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it) { - output->putString((*it)); - if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) - && !g_config.getBool(ConfigManager::CHARLIST_INFO)) + if (g_config.getBool(ConfigManager::ACCOUNT_MANAGER) && account.number != 1) { - if(g_game.getPlayerByName((*it))) - output->putString("Online"); - else - output->putString("Offline"); + output->put(account.charList.size() + 1); + output->putString("Account Manager"); + + output->putString(g_config.getString(ConfigManager::SERVER_NAME)); + output->put(serverIp); + + output->put(g_config.getNumber(ConfigManager::GAME_PORT)); } - else if(g_config.getBool(ConfigManager::CHARLIST_INFO)) + else + output->put((uint8_t)account.charList.size()); + +#ifndef __LOGIN_SERVER__ + for (Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it) { - std::stringstream str; - Player *player = g_game.getPlayerByName((*it)); - bool v = false; - if(g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST)) + output->putString((*it)); + if (g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) + && !g_config.getBool(ConfigManager::CHARLIST_INFO)) { - if(player) - str << "On"; + if (g_game.getPlayerByName((*it))) + output->putString("Online"); else - str << "Off"; - - str << "/"; + output->putString("Offline"); } - - if(!player) + else if (g_config.getBool(ConfigManager::CHARLIST_INFO)) { - v = true; - player = g_game.getPlayerByNameEx((*it)); + std::stringstream str; + Player *player = g_game.getPlayerByName((*it)); + bool v = false; + if (g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST)) + { + if (player) + str << "On"; + else + str << "Off"; + + str << "/"; + } + + if (!player) + { + v = true; + player = g_game.getPlayerByNameEx((*it)); + } + + str << player->getLevel(); + str << "/"; + str << player->getVocation()->getName(); + output->putString(str.str()); + if (v) + delete player; + } + else + output->putString(g_config.getString(ConfigManager::SERVER_NAME)); + + output->put(serverIp); + output->put(g_config.getNumber(ConfigManager::GAME_PORT)); } +#else + for (Characters::iterator it = charList.begin(); it != charList.end(); ++it) + { + output->putString(it->second.name); + if (!g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) || it->second.status < 0) + output->putString(it->second.server->getName()); + else if (it->second.status) + output->putString("Online"); + else + output->putString("Offline"); - str << player->getLevel(); - str << "/"; - str << player->getVocation()->getName(); - output->putString(str.str()); - if(v) - delete player; + output->put(it->second.server->getAddress()); + IntegerVec games = it->second.server->getPorts(); + output->put(games[random_range(0, games.size() - 1)]); + } +#endif } - else - output->putString(g_config.getString(ConfigManager::SERVER_NAME)); - - output->put(serverIp); - output->put(g_config.getNumber(ConfigManager::GAME_PORT)); - } - #else - for(Characters::iterator it = charList.begin(); it != charList.end(); ++it) - { - output->putString(it->second.name); - if(!g_config.getBool(ConfigManager::ON_OR_OFF_CHARLIST) || it->second.status < 0) - output->putString(it->second.server->getName()); - else if(it->second.status) - output->putString("Online"); - else - output->putString("Offline"); - - output->put(it->second.server->getAddress()); - IntegerVec games = it->second.server->getPorts(); - output->put(games[random_range(0, games.size() - 1)]); - } - #endif //Add premium days if(g_config.getBool(ConfigManager::FREE_PREMIUM)) diff --git a/path_7_x/sources/spectators.cpp b/path_7_x/sources/spectators.cpp new file mode 100644 index 000000000..c1a76dcf3 --- /dev/null +++ b/path_7_x/sources/spectators.cpp @@ -0,0 +1,323 @@ +//////////////////////////////////////////////////////////////////////// +// OpenTibia - an opensource roleplaying game +//////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +//////////////////////////////////////////////////////////////////////// +#include "otpch.h" +#include "spectators.h" + +#include "player.h" +#include "chat.h" + +#include "database.h" +#include "tools.h" + +extern Chat g_chat; + +bool Spectators::check(const std::string& _password) +{ + if(password.empty()) + return true; + + std::string t = _password; + return trimString(t) == password; +} + +void Spectators::handle(ProtocolGame* client, const std::string& text, uint16_t channelId) +{ + if(!owner) + return; + + SpectatorList::iterator sit = spectators.find(client); + if(sit == spectators.end()) + return; + + PrivateChatChannel* channel = g_chat.getPrivateChannel(owner->getPlayer()); + if(text[0] == '/') + { + StringVec t = explodeString(text.substr(1, text.length()), " ", true, 1); + toLowerCaseString(t[0]); + if(t[0] == "show") + { + std::stringstream s; + s << spectators.size() << " spectators. "; + for(SpectatorList::const_iterator it = spectators.begin(); it != spectators.end(); ++it) + { + if(it != spectators.begin()) + s << " ,"; + + s << it->second.first; + } + + s << "."; + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, s.str(), NULL, 0); + } + else if(t[0] == "name") + { + if(t.size() > 1) + { + if(t[1].length() > 2) + { + if(t[1].length() < 26) + { + t[1] += " [G]"; + bool found = false; + for(SpectatorList::iterator iit = spectators.begin(); iit != spectators.end(); ++iit) + { + if(asLowerCaseString(iit->second.first) != asLowerCaseString(t[1])) + continue; + + found = true; + break; + } + + if(!found) + { + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Your name has been set to " + t[1] + ".", NULL, 0); + if(!auth && channel) + sendChannelMessage("", sit->second.first + " is now known as " + t[1] + ".", MSG_GAMEMASTER_CHANNEL, channel->getId()); + + StringVec::iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first)); + if(mit != mutes.end()) + (*mit) = asLowerCaseString(t[1]); + + sit->second.first = t[1]; + sit->second.second = false; + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is already taken.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is too long.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Specified name is too short.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0); + } + else if(t[0] == "auth") + { + if(t.size() > 1) + { + StringVec _t = explodeString(t[1], " ", true, 1); + if(_t.size() > 1) + { + Database* db = Database::getInstance(); + DBQuery query; + + query << "SELECT `id`, `salt`, `password` FROM `accounts` WHERE `name` " << db->getStringComparer() << db->escapeString(_t[0]) << " LIMIT 1"; + if(DBResult* result = db->storeQuery(query.str())) + { + std::string password = result->getDataString("salt") + _t[1], + hash = result->getDataString("password"); + uint32_t id = result->getDataInt("id"); + + result->free(); + if(encryptTest(password, hash)) + { + query.str(""); + query << "SELECT `name` FROM `players` WHERE `account_id` = " << id << " ORDER BY `level` DESC LIMIT 1"; + if((result = db->storeQuery(query.str()))) + { + std::string nickname = result->getDataString("name"); + result->free(); + + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "You have authenticated as " + nickname + ".", NULL, 0); + if(channel) + sendChannelMessage("", sit->second.first + " authenticated as " + nickname + ".", MSG_GAMEMASTER_CHANNEL, channel->getId()); + + StringVec::iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first)); + if(mit != mutes.end()) + (*mit) = asLowerCaseString(nickname); + + sit->second.first = nickname; + sit->second.second = true; + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Your account has no characters yet.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Invalid password.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Invalid account name.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Not enough param(s) given.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Command not found.", NULL, 0); + + return; + } + + if(!auth || sit->second.second) + { + StringVec::const_iterator mit = std::find(mutes.begin(), mutes.end(), asLowerCaseString(sit->second.first)); + if(mit == mutes.end()) + { + if(channel && channel->getId() == channelId) + channel->talk(sit->second.first, MSG_CHANNEL_HIGHLIGHT, text); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "You are muted.", NULL, 0); + } + else + client->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "This chat is protected, you have to authenticate first.", NULL, 0); +} + +void Spectators::chat(uint16_t channelId) +{ + if(!owner) + return; + + PrivateChatChannel* tmp = g_chat.getPrivateChannel(owner->getPlayer()); + if(!tmp || tmp->getId() != channelId) + return; + + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + { + it->first->sendClosePrivate(channelId); + it->first->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Chat has been disabled.", NULL, 0); + } +} + +void Spectators::kick(StringVec list) +{ + for(StringVec::const_iterator it = list.begin(); it != list.end(); ++it) + { + for(SpectatorList::iterator sit = spectators.begin(); sit != spectators.end(); ++sit) + { + if(asLowerCaseString(sit->second.first) == *it) + sit->first->disconnect(); + } + } +} + +void Spectators::ban(StringVec _bans) +{ + StringVec::const_iterator it; + for(DataList::iterator bit = bans.begin(); bit != bans.end(); ) + { + it = std::find(_bans.begin(), _bans.end(), bit->first); + if(it == _bans.end()) + bans.erase(bit++); + else + ++bit; + } + + for(it = _bans.begin(); it != _bans.end(); ++it) + { + for(SpectatorList::const_iterator sit = spectators.begin(); sit != spectators.end(); ++sit) + { + if(asLowerCaseString(sit->second.first) != *it) + continue; + + bans[*it] = sit->first->getIP(); + sit->first->disconnect(); + } + } +} + +void Spectators::addSpectator(ProtocolGame* client) +{ + if(++id == 65536) + id = 1; + + std::stringstream s; + s << "Spectator [" << id << "]"; + + spectators[client] = std::make_pair(s.str(), false); + sendTextMessage(MSG_EVENT_ORANGE, s.str() + " joins your stream."); +} + +void Spectators::removeSpectator(ProtocolGame* client) +{ + SpectatorList::iterator it = spectators.find(client); + if(it == spectators.end()) + return; + + StringVec::iterator mit = std::find(mutes.begin(), mutes.end(), it->second.first); + if(mit != mutes.end()) + mutes.erase(mit); + + sendTextMessage(MSG_EVENT_ORANGE, it->second.first + " leaves your stream."); + spectators.erase(it); +} + +void Spectators::sendChannelMessage(std::string author, std::string text, MessageClasses type, uint16_t channel) +{ + if(!owner) + return; + + owner->sendChannelMessage(author, text, type, channel); + PrivateChatChannel* tmp = g_chat.getPrivateChannel(owner->getPlayer()); + if(!tmp || tmp->getId() != channel) + return; + + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendChannelMessage(author, text, type, channel); +} + +void Spectators::sendCreatureChannelSay(const Creature* creature, MessageClasses type, const std::string& text, uint16_t channelId, uint32_t statementId) +{ + if(!owner) + return; + + owner->sendCreatureChannelSay(creature, type, text, channelId, statementId); + PrivateChatChannel* tmp = g_chat.getPrivateChannel(owner->getPlayer()); + if(!tmp || tmp->getId() != channelId) + return; + + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureChannelSay(creature, type, text, channelId, statementId); +} + +void Spectators::sendClosePrivate(uint16_t channelId) +{ + if(!owner) + return; + + owner->sendClosePrivate(channelId); + PrivateChatChannel* tmp = g_chat.getPrivateChannel(owner->getPlayer()); + if(!tmp || tmp->getId() != channelId) + return; + + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + { + it->first->sendClosePrivate(channelId); + it->first->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Chat has been disabled.", NULL, 0); + } +} + +void Spectators::sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName) +{ + if(!owner) + return; + + owner->sendCreatePrivateChannel(channelId, channelName); + PrivateChatChannel* tmp = g_chat.getPrivateChannel(owner->getPlayer()); + if(!tmp || tmp->getId() != channelId) + return; + + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + { + it->first->sendCreatePrivateChannel(channelId, channelName); + it->first->sendCreatureSay(owner->getPlayer(), MSG_PRIVATE, "Chat has been enabled.", NULL, 0); + } +} diff --git a/path_7_x/sources/spectators.h b/path_7_x/sources/spectators.h new file mode 100644 index 000000000..985e13d88 --- /dev/null +++ b/path_7_x/sources/spectators.h @@ -0,0 +1,607 @@ +//////////////////////////////////////////////////////////////////////// +// OpenTibia - an opensource roleplaying game +//////////////////////////////////////////////////////////////////////// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +//////////////////////////////////////////////////////////////////////// + +#ifndef __SPECTATORS__ +#define __SPECTATORS__ + +#include "otsystem.h" +#include "enums.h" + +#include "protocolgame.h" + +class Creature; +class Player; +class House; +class Container; +class Tile; +class Quest; + +typedef std::map > SpectatorList; +typedef std::map DataList; + +class Spectators +{ + public: + Spectators(ProtocolGame* client): owner(client) + { + id = 0; + broadcast = false; + auth = false; + } + virtual ~Spectators() {} + + void clear(bool full) + { + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->disconnect(); + + spectators.clear(); + mutes.clear(); + + id = 0; + if(!full) + return; + + bans.clear(); + password = ""; + broadcast = auth = false; + } + + bool check(const std::string& _password); + void handle(ProtocolGame* client, const std::string& text, uint16_t channelId); + void chat(uint16_t channelId); + + StringVec list() + { + StringVec t; + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + t.push_back(it->second.first); + + return t; + } + + void kick(StringVec list); + StringVec muteList() {return mutes;} + void mute(StringVec _mutes) {mutes = _mutes;} + DataList banList() {return bans;} + void ban(StringVec _bans); + + bool banned(uint32_t ip) const + { + for(DataList::const_iterator it = bans.begin(); it != bans.end(); ++it) + { + if(it->second == ip) + return true; + } + + return false; + } + + ProtocolGame* getOwner() const {return owner;} + void setOwner(ProtocolGame* client) {owner = client;} + + std::string getPassword() const {return password;} + void setPassword(const std::string& value) {password = value;} + + bool isBroadcasting() const {return broadcast;} + void setBroadcast(bool value) {broadcast = value;} + + bool isAuth() const {return auth;} + void setAuth(bool value) {auth = value;} + + void addSpectator(ProtocolGame* client); + void removeSpectator(ProtocolGame* client); + + // inherited + uint32_t getIP() const + { + if(!owner) + return 0; + + return owner->getIP(); + } + + bool logout(bool displayEffect, bool forceLogout) + { + if(!owner) + return true; + + return owner->logout(displayEffect, forceLogout); + } + + void disconnect() + { + if(owner) + owner->disconnect(); + } + + private: + friend class Player; + + SpectatorList spectators; + StringVec mutes; + DataList bans; + + ProtocolGame* owner; + uint32_t id; + std::string password; + bool broadcast, auth; + + // inherited + bool canSee(const Position& pos) const + { + if(!owner) + return false; + + return owner->canSee(pos); + } + + void sendChannelMessage(std::string author, std::string text, MessageClasses type, uint16_t channel); + void sendClosePrivate(uint16_t channelId); + void sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName); + void sendChannelsDialog(const ChannelsList& channels) + { + if(!owner) + return; + + owner->sendChannelsDialog(channels); + } + void sendChannel(uint16_t channelId, const std::string& channelName) + { + if(!owner) + return; + + owner->sendChannel(channelId, channelName); + } + void sendOpenPrivateChannel(const std::string& receiver) + { + if(!owner) + return; + + owner->sendOpenPrivateChannel(receiver); + } + void sendIcons(int32_t icons) + { + if(!owner) + return; + + owner->sendIcons(icons); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendIcons(icons); + } + void sendDistanceShoot(const Position& from, const Position& to, uint8_t type) + { + if(!owner) + return; + + owner->sendDistanceShoot(from, to, type); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendDistanceShoot(from, to, type); + } + void sendMagicEffect(const Position& pos, uint8_t type) + { + if(!owner) + return; + + owner->sendMagicEffect(pos, type); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendMagicEffect(pos, type); + } + void sendAnimatedText(const Position& pos, uint8_t color, const std::string& text) + { + if(!owner) + return; + + owner->sendAnimatedText(pos, color, text); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendAnimatedText(pos, color, text); + } + void sendCreatureHealth(const Creature* creature) + { + if(!owner) + return; + + owner->sendCreatureHealth(creature); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureHealth(creature); + } + void sendSkills() + { + if(!owner) + return; + + owner->sendSkills(); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendSkills(); + } + void sendPing() + { + if(!owner) + return; + + owner->sendPing(); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendPing(); + } + void sendCreatureTurn(const Creature* creature, int16_t stackpos) + { + if(!owner) + return; + + owner->sendCreatureTurn(creature, stackpos); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureTurn(creature, stackpos); + } + void sendCreatureSay(const Creature* creature, MessageClasses type, const std::string& text, Position* pos, uint32_t statementId) + { + if(!owner) + return; + + owner->sendCreatureSay(creature, type, text, pos, statementId); + if(type == MSG_PRIVATE || type == MSG_GAMEMASTER_PRIVATE) // care for privacy! + return; + + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureSay(creature, type, text, pos, statementId); + } + void sendCreatureChannelSay(const Creature* creature, MessageClasses type, const std::string& text, uint16_t channelId, uint32_t statementId); // extended + + void sendCancel(const std::string& message) + { + if(!owner) + return; + + owner->sendCancel(message); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCancel(message); + } + void sendCancelWalk() + { + if(!owner) + return; + + owner->sendCancelWalk(); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCancelWalk(); + } + void sendChangeSpeed(const Creature* creature, uint32_t speed) + { + if(!owner) + return; + + owner->sendChangeSpeed(creature, speed); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendChangeSpeed(creature, speed); + } + void sendCancelTarget() + { + if(!owner) + return; + + owner->sendCancelTarget(); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCancelTarget(); + } + void sendCreatureOutfit(const Creature* creature, const Outfit_t& outfit) + { + if(!owner) + return; + + owner->sendCreatureOutfit(creature, outfit); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureOutfit(creature, outfit); + } + void sendStats() + { + if(!owner) + return; + + owner->sendStats(); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendStats(); + } + void sendTextMessage(MessageClasses mclass, const std::string& message) + { + if(!owner) + return; + + owner->sendTextMessage(mclass, message); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendTextMessage(mclass, message); + } + void sendExtendedOpcode(uint8_t opcode, const std::string& buffer) + { + if(!owner) + return; + + owner->sendExtendedOpcode(opcode, buffer); + } + + void sendRuleViolationsChannel(uint16_t channelId) + { + if(!owner) + return; + + owner->sendRuleViolationsChannel(channelId); + } + void sendRemoveReport(const std::string& name) + { + if(!owner) + return; + + owner->sendRemoveReport(name); + } + void sendLockRuleViolation() + { + if(!owner) + return; + + owner->sendLockRuleViolation(); + } + void sendRuleViolationCancel(const std::string& name) + { + if(!owner) + return; + + owner->sendRuleViolationCancel(name); + } + + void sendCreatureSkull(const Creature* creature) + { + if(!owner) + return; + + owner->sendCreatureSkull(creature); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureSkull(creature); + } + void sendCreatureShield(const Creature* creature) + { + if(!owner) + return; + + owner->sendCreatureShield(creature); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureShield(creature); + } + + void sendTradeItemRequest(const Player* player, const Item* item, bool ack) + { + if(!owner) + return; + + owner->sendTradeItemRequest(player, item, ack); + } + void sendCloseTrade() + { + if(!owner) + return; + + owner->sendCloseTrade(); + } + + void sendTextWindow(uint32_t windowTextId, Item* item, uint16_t maxLen, bool canWrite) + { + if(!owner) + return; + + owner->sendTextWindow(windowTextId, item, maxLen, canWrite); + } + void sendHouseWindow(uint32_t windowTextId, House* house, uint32_t listId, const std::string& text) + { + if(!owner) + return; + + owner->sendHouseWindow(windowTextId, house, listId, text); + } + + void sendOutfitWindow() + { + if(!owner) + return; + + owner->sendOutfitWindow(); + } + + void sendVIPLogIn(uint32_t guid) + { + if(owner) + owner->sendVIPLogIn(guid); + } + void sendVIPLogOut(uint32_t guid) + { + if(owner) + owner->sendVIPLogOut(guid); + } + void sendVIP(uint32_t guid, const std::string& name, bool isOnline) + { + if(owner) + owner->sendVIP(guid, name, isOnline); + } + + void sendCreatureLight(const Creature* creature) + { + if(!owner) + return; + + owner->sendCreatureLight(creature); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureLight(creature); + } + void sendWorldLight(const LightInfo& lightInfo) + { + if(!owner) + return; + + owner->sendWorldLight(lightInfo); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendWorldLight(lightInfo); + } + + void sendCreatureSquare(const Creature* creature, uint8_t color) + { + if(!owner) + return; + + owner->sendCreatureSquare(creature, color); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCreatureSquare(creature, color); + } + + void sendAddTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item) + { + if(!owner) + return; + + owner->sendAddTileItem(tile, pos, stackpos, item); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendAddTileItem(tile, pos, stackpos, item); + } + void sendUpdateTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item) + { + if(!owner) + return; + + owner->sendUpdateTileItem(tile, pos, stackpos, item); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendUpdateTileItem(tile, pos, stackpos, item); + } + void sendRemoveTileItem(const Tile* tile, const Position& pos, uint32_t stackpos) + { + if(!owner) + return; + + owner->sendRemoveTileItem(tile, pos, stackpos); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendRemoveTileItem(tile, pos, stackpos); + } + void sendUpdateTile(const Tile* tile, const Position& pos) + { + if(!owner) + return; + + owner->sendUpdateTile(tile, pos); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendUpdateTile(tile, pos); + } + + void sendAddCreature(const Creature* creature, const Position& pos, uint32_t stackpos) + { + if(!owner) + return; + + owner->sendAddCreature(creature, pos, stackpos); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendAddCreature(creature, pos, stackpos); + } + void sendRemoveCreature(const Creature* creature, const Position& pos, uint32_t stackpos) + { + if(!owner) + return; + + owner->sendRemoveCreature(creature, pos, stackpos); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendRemoveCreature(creature, pos, stackpos); + } + void sendMoveCreature(const Creature* creature, const Tile* newTile, const Position& newPos, uint32_t newStackPos, + const Tile* oldTile, const Position& oldPos, uint32_t oldStackpos, bool teleport) + { + if(!owner) + return; + + owner->sendMoveCreature(creature, newTile, newPos, newStackPos, oldTile, oldPos, oldStackpos, teleport); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendMoveCreature(creature, newTile, newPos, newStackPos, oldTile, oldPos, oldStackpos, teleport); + } + + void sendAddContainerItem(uint8_t cid, const Item* item) + { + if(!owner) + return; + + owner->sendAddContainerItem(cid, item); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendAddContainerItem(cid, item); + } + void sendUpdateContainerItem(uint8_t cid, uint8_t slot, const Item* item) + { + if(!owner) + return; + + owner->sendUpdateContainerItem(cid, slot, item); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendUpdateContainerItem(cid, slot, item); + } + void sendRemoveContainerItem(uint8_t cid, uint8_t slot) + { + if(!owner) + return; + + owner->sendRemoveContainerItem(cid, slot); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendRemoveContainerItem(cid, slot); + } + + void sendContainer(uint32_t cid, const Container* container, bool hasParent) + { + if(!owner) + return; + + owner->sendContainer(cid, container, hasParent); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendContainer(cid, container, hasParent); + } + void sendCloseContainer(uint32_t cid) + { + if(!owner) + return; + + owner->sendCloseContainer(cid); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendCloseContainer(cid); + } + + void sendAddInventoryItem(slots_t slot, const Item* item) + { + if(!owner) + return; + + owner->sendAddInventoryItem(slot, item); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendAddInventoryItem(slot, item); + } + void sendUpdateInventoryItem(slots_t slot, const Item* item) + { + if(!owner) + return; + + owner->sendUpdateInventoryItem(slot, item); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendUpdateInventoryItem(slot, item); + } + void sendRemoveInventoryItem(slots_t slot) + { + if(!owner) + return; + + owner->sendRemoveInventoryItem(slot); + for(SpectatorList::iterator it = spectators.begin(); it != spectators.end(); ++it) + it->first->sendRemoveInventoryItem(slot); + } +}; +#endif +