diff options
Diffstat (limited to 'src/being/playerrelations.cpp')
-rw-r--r-- | src/being/playerrelations.cpp | 661 |
1 files changed, 0 insertions, 661 deletions
diff --git a/src/being/playerrelations.cpp b/src/being/playerrelations.cpp deleted file mode 100644 index fe774432b..000000000 --- a/src/being/playerrelations.cpp +++ /dev/null @@ -1,661 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * 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 <http://www.gnu.org/licenses/>. - */ - -#include "being/playerrelations.h" - -#include "actormanager.h" -#include "configuration.h" -#include "logger.h" - -#include "being/localplayer.h" -#include "being/playerignorestrategy.h" -#include "being/playerrelation.h" - -#include "utils/dtor.h" -#include "utils/foreach.h" -#include "utils/gettext.h" - -#include "listeners/playerrelationslistener.h" - -#include "debug.h" - -static const unsigned int FIRST_IGNORE_EMOTE = 14; - -typedef std::map<std::string, PlayerRelation *> PlayerRelations; -typedef PlayerRelations::const_iterator PlayerRelationsCIter; -typedef std::list<PlayerRelationsListener *> PlayerRelationListeners; -typedef PlayerRelationListeners::const_iterator PlayerRelationListenersCIter; - -static const char *const PLAYER_IGNORE_STRATEGY_NOP = "nop"; -static const char *const PLAYER_IGNORE_STRATEGY_EMOTE0 = "emote0"; -static const char *const DEFAULT_IGNORE_STRATEGY = - PLAYER_IGNORE_STRATEGY_EMOTE0; - -static const char *const NAME = "name"; -static const char *const RELATION = "relation"; - -static const unsigned int IGNORE_EMOTE_TIME = 100; - -namespace -{ - class SortPlayersFunctor final - { - public: - SortPlayersFunctor() - { } - - A_DEFAULT_COPY(SortPlayersFunctor) - - bool operator() (const std::string &str1, - const std::string &str2) const - { - std::string s1 = str1; - std::string s2 = str2; - toLower(s1); - toLower(s2); - if (s1 == s2) - return str1 < str2; - return s1 < s2; - } - } playersRelSorter; - - // (De)serialisation class - class PlayerConfSerialiser final : - public ConfigurationListManager<std::pair<std::string, - PlayerRelation *>, std::map<std::string, PlayerRelation *> *> - { - public: - PlayerConfSerialiser() - { } - - A_DELETE_COPY(PlayerConfSerialiser) - - ConfigurationObject *writeConfigItem( - const std::pair<std::string, PlayerRelation *> &value, - ConfigurationObject *const cobj) const override final - { - if (cobj == nullptr || - value.second == nullptr) - { - return nullptr; - } - cobj->setValue(NAME, value.first); - cobj->setValue(RELATION, toString( - CAST_S32(value.second->mRelation))); - - return cobj; - } - - std::map<std::string, PlayerRelation *> * - readConfigItem(const ConfigurationObject *const cobj, - std::map<std::string, PlayerRelation *> - *const container) const override final - { - if (cobj == nullptr || - container == nullptr) - { - return container; - } - const std::string name = cobj->getValue(NAME, ""); - if (name.empty()) - return container; - - if ((*container)[name] == nullptr) - { - const int v = cobj->getValueInt(RELATION, - CAST_S32(Relation::NEUTRAL)); - - (*container)[name] = new PlayerRelation( - static_cast<RelationT>(v)); - } - // otherwise ignore the duplicate entry - - return container; - } - }; -} // namespace - -static PlayerConfSerialiser player_conf_serialiser; // stateless singleton - -const unsigned int PlayerRelation::RELATION_PERMISSIONS[RELATIONS_NR] = -{ - /* NEUTRAL */ 0, // we always fall back to the defaults anyway - /* FRIEND */ EMOTE | SPEECH_FLOAT | SPEECH_LOG | WHISPER | TRADE, - /* DISREGARDED*/ EMOTE | SPEECH_FLOAT, - /* IGNORED */ 0, - /* ERASED */ INVISIBLE, - /* BLACKLISTED */ SPEECH_LOG | WHISPER, - /* ENEMY2 */ EMOTE | SPEECH_FLOAT | SPEECH_LOG | WHISPER | TRADE -}; - -PlayerRelationsManager::PlayerRelationsManager() : - mPersistIgnores(false), - mDefaultPermissions(PlayerRelation::DEFAULT), - mIgnoreStrategy(nullptr), - mRelations(), - mListeners(), - mIgnoreStrategies() -{ -} - -PlayerRelationsManager::~PlayerRelationsManager() -{ - delete_all(mIgnoreStrategies); - - FOR_EACH (PlayerRelationsCIter, it, mRelations) - delete it->second; - mRelations.clear(); -} - -void PlayerRelationsManager::clear() -{ - StringVect *const names = getPlayers(); - FOR_EACHP (StringVectCIter, it, names) - removePlayer(*it); - delete names; -} - -static const char *const PERSIST_IGNORE_LIST = "persistent-player-list"; -static const char *const PLAYER_IGNORE_STRATEGY = "player-ignore-strategy"; -static const char *const DEFAULT_PERMISSIONS = "default-player-permissions"; - -int PlayerRelationsManager::getPlayerIgnoreStrategyIndex( - const std::string &name) -{ - const STD_VECTOR<PlayerIgnoreStrategy *> *const strategies - = getPlayerIgnoreStrategies(); - - if (strategies == nullptr) - return -1; - - const size_t sz = strategies->size(); - for (size_t i = 0; i < sz; i++) - { - if ((*strategies)[i]->mShortName == name) - return CAST_S32(i); - } - - return -1; -} - -void PlayerRelationsManager::load() -{ - Configuration *const cfg = &serverConfig; - clear(); - - mPersistIgnores = (cfg->getValue(PERSIST_IGNORE_LIST, 1) != 0); - mDefaultPermissions = CAST_S32(cfg->getValue(DEFAULT_PERMISSIONS, - mDefaultPermissions)); - - const std::string ignore_strategy_name = cfg->getValue( - PLAYER_IGNORE_STRATEGY, DEFAULT_IGNORE_STRATEGY); - const int ignore_strategy_index = getPlayerIgnoreStrategyIndex( - ignore_strategy_name); - - if (ignore_strategy_index >= 0) - { - setPlayerIgnoreStrategy((*getPlayerIgnoreStrategies()) - [ignore_strategy_index]); - } - - cfg->getList<std::pair<std::string, PlayerRelation *>, - std::map<std::string, PlayerRelation *> *> - ("player", &(mRelations), &player_conf_serialiser); -} - - -void PlayerRelationsManager::init() -{ - load(); - - if (!mPersistIgnores) - { - clear(); // Yes, we still keep them around in the config file - // until the next update. - } - - FOR_EACH (PlayerRelationListenersCIter, it, mListeners) - (*it)->updateAll(); -} - -void PlayerRelationsManager::store() const -{ - serverConfig.setList<std::map<std::string, - PlayerRelation *>::const_iterator, - std::pair<std::string, PlayerRelation *>, - std::map<std::string, PlayerRelation *> *> - ("player", mRelations.begin(), mRelations.end(), - &player_conf_serialiser); - - serverConfig.setValue(DEFAULT_PERMISSIONS, mDefaultPermissions); - serverConfig.setValue(PERSIST_IGNORE_LIST, mPersistIgnores); - serverConfig.setValue(PLAYER_IGNORE_STRATEGY, - mIgnoreStrategy != nullptr ? mIgnoreStrategy->mShortName : - DEFAULT_IGNORE_STRATEGY); - - serverConfig.write(); -} - -void PlayerRelationsManager::signalUpdate(const std::string &name) -{ - FOR_EACH (PlayerRelationListenersCIter, it, mListeners) - (*it)->updatedPlayer(name); - - if (actorManager != nullptr) - { - Being *const being = actorManager->findBeingByName( - name, ActorType::Player); - - if (being != nullptr && - being->getType() == ActorType::Player) - { - being->updateColors(); - } - } -} - -unsigned int PlayerRelationsManager::checkPermissionSilently( - const std::string &player_name, const unsigned int flags) const -{ - const std::map<std::string, PlayerRelation *>::const_iterator - it = mRelations.find(player_name); - if (it == mRelations.end()) - { - return mDefaultPermissions & flags; - } - - const PlayerRelation *const r = (*it).second; - unsigned int permissions = PlayerRelation::RELATION_PERMISSIONS[ - CAST_S32(r->mRelation)]; - - switch (r->mRelation) - { - case Relation::NEUTRAL: - permissions = mDefaultPermissions; - break; - - case Relation::FRIEND: - permissions |= mDefaultPermissions; // widen - break; - - case Relation::DISREGARDED: - case Relation::IGNORED: - case Relation::ERASED: - case Relation::BLACKLISTED: - case Relation::ENEMY2: - default: - permissions &= mDefaultPermissions; // narrow - break; - } - - return permissions & flags; -} - -bool PlayerRelationsManager::hasPermission(const Being *const being, - const unsigned int flags) const -{ - if (being == nullptr) - return false; - - if (being->getType() == ActorType::Player) - { - return static_cast<unsigned int>(hasPermission( - being->getName(), flags)) == flags; - } - return true; -} - -bool PlayerRelationsManager::hasPermission(const std::string &name, - const unsigned int flags) const -{ - if (actorManager == nullptr) - return false; - - const unsigned int rejections = flags - & ~checkPermissionSilently(name, flags); - const bool permitted = (rejections == 0); - - if (!permitted) - { - // execute `ignore' strategy, if possible - if (mIgnoreStrategy != nullptr) - { - Being *const b = actorManager->findBeingByName( - name, ActorType::Player); - - if ((b != nullptr) && b->getType() == ActorType::Player) - mIgnoreStrategy->ignore(b, rejections); - } - } - - return permitted; -} - -void PlayerRelationsManager::setRelation(const std::string &player_name, - const RelationT relation) -{ - if (localPlayer == nullptr || - (relation != Relation::NEUTRAL && - localPlayer->getName() == player_name)) - { - return; - } - - PlayerRelation *const r = mRelations[player_name]; - if (r == nullptr) - mRelations[player_name] = new PlayerRelation(relation); - else - r->mRelation = relation; - - signalUpdate(player_name); - store(); -} - -StringVect *PlayerRelationsManager::getPlayers() const -{ - StringVect *const retval = new StringVect; - - FOR_EACH (PlayerRelationsCIter, it, mRelations) - { - if (it->second != nullptr) - retval->push_back(it->first); - } - - std::sort(retval->begin(), retval->end(), playersRelSorter); - - return retval; -} - -StringVect *PlayerRelationsManager::getPlayersByRelation( - const RelationT rel) const -{ - StringVect *const retval = new StringVect; - - FOR_EACH (PlayerRelationsCIter, it, mRelations) - { - if ((it->second != nullptr) && - it->second->mRelation == rel) - { - retval->push_back(it->first); - } - } - - std::sort(retval->begin(), retval->end(), playersRelSorter); - - return retval; -} - -void PlayerRelationsManager::removePlayer(const std::string &name) -{ - delete mRelations[name]; - mRelations.erase(name); - signalUpdate(name); -} - - -RelationT PlayerRelationsManager::getRelation( - const std::string &name) const -{ - const std::map<std::string, PlayerRelation *>::const_iterator - it = mRelations.find(name); - if (it != mRelations.end()) - return (*it).second->mRelation; - - return Relation::NEUTRAL; -} - -//////////////////////////////////////// -// defaults - -unsigned int PlayerRelationsManager::getDefault() const -{ - return mDefaultPermissions; -} - -void PlayerRelationsManager::setDefault(const unsigned int permissions) -{ - mDefaultPermissions = permissions; - - store(); - signalUpdate(""); -} - -void PlayerRelationsManager::ignoreTrade(const std::string &name) const -{ - if (name.empty()) - return; - - const RelationT relation = getRelation(name); - - if (relation == Relation::IGNORED || - relation == Relation::DISREGARDED || - relation == Relation::BLACKLISTED || - relation == Relation::ERASED) - { - return; - } - playerRelations.setRelation(name, Relation::BLACKLISTED); -} - -bool PlayerRelationsManager::checkBadRelation(const std::string &name) const -{ - if (name.empty()) - return true; - - const RelationT relation = getRelation(name); - - if (relation == Relation::IGNORED || - relation == Relation::DISREGARDED || - relation == Relation::BLACKLISTED || - relation == Relation::ERASED || - relation == Relation::ENEMY2) - { - return true; - } - return false; -} - -//////////////////////////////////////// -// ignore strategies - - -class PIS_nothing final : public PlayerIgnoreStrategy -{ - public: - PIS_nothing() : - PlayerIgnoreStrategy() - { - // TRANSLATORS: ignore/unignore action - mDescription = _("Completely ignore"); - mShortName = PLAYER_IGNORE_STRATEGY_NOP; - } - - A_DELETE_COPY(PIS_nothing) - - void ignore(Being *const being A_UNUSED, - const unsigned int flags A_UNUSED) const override final - { - } -}; - -class PIS_dotdotdot final : public PlayerIgnoreStrategy -{ - public: - PIS_dotdotdot() : - PlayerIgnoreStrategy() - { - // TRANSLATORS: ignore/unignore action - mDescription = _("Print '...'"); - mShortName = "dotdotdot"; - } - - A_DELETE_COPY(PIS_dotdotdot) - - void ignore(Being *const being, - const unsigned int flags A_UNUSED) const override final - { - if (being == nullptr) - return; - - logger->log("ignoring: " + being->getName()); - being->setSpeech("..."); - } -}; - - -class PIS_blinkname final : public PlayerIgnoreStrategy -{ - public: - PIS_blinkname() : - PlayerIgnoreStrategy() - { - // TRANSLATORS: ignore/unignore action - mDescription = _("Blink name"); - mShortName = "blinkname"; - } - - A_DELETE_COPY(PIS_blinkname) - - void ignore(Being *const being, - const unsigned int flags A_UNUSED) const override final - { - if (being == nullptr) - return; - - logger->log("ignoring: " + being->getName()); - being->flashName(200); - } -}; - -class PIS_emote final : public PlayerIgnoreStrategy -{ - public: - PIS_emote(const uint8_t emote_nr, - const std::string &description, - const std::string &shortname) : - PlayerIgnoreStrategy(), - mEmotion(emote_nr) - { - mDescription = description; - mShortName = shortname; - } - - A_DELETE_COPY(PIS_emote) - - void ignore(Being *const being, - const unsigned int flags A_UNUSED) const override final - { - if (being == nullptr) - return; - - being->setEmote(mEmotion, IGNORE_EMOTE_TIME); - } - uint8_t mEmotion; -}; - -STD_VECTOR<PlayerIgnoreStrategy *> * -PlayerRelationsManager::getPlayerIgnoreStrategies() -{ - if (mIgnoreStrategies.empty()) - { - // not initialised yet? - mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE, - // TRANSLATORS: ignore strategi - _("Floating '...' bubble"), - PLAYER_IGNORE_STRATEGY_EMOTE0)); - mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE + 1, - // TRANSLATORS: ignore strategi - _("Floating bubble"), - "emote1")); - mIgnoreStrategies.push_back(new PIS_nothing); - mIgnoreStrategies.push_back(new PIS_dotdotdot); - mIgnoreStrategies.push_back(new PIS_blinkname); - } - return &mIgnoreStrategies; -} - -bool PlayerRelationsManager::isGoodName(const std::string &name) const -{ - const size_t size = name.size(); - - if (size < 3) - return true; - - const std::map<std::string, PlayerRelation *>::const_iterator - it = mRelations.find(name); - if (it != mRelations.end()) - return true; - - return checkName(name); -} - -bool PlayerRelationsManager::isGoodName(Being *const being) const -{ - if (being == nullptr) - return false; - if (being->getGoodStatus() != -1) - return being->getGoodStatus() == 1; - - const std::string &name = being->getName(); - const size_t size = name.size(); - - if (size < 3) - return true; - - const std::map<std::string, PlayerRelation *>::const_iterator - it = mRelations.find(name); - if (it != mRelations.end()) - return true; - - const bool status = checkName(name); - being->setGoodStatus(status ? 1 : 0); - return status; -} - -bool PlayerRelationsManager::checkName(const std::string &name) -{ - const size_t size = name.size(); - const std::string check = config.getStringValue("unsecureChars"); - const std::string lastChar = name.substr(size - 1, 1); - - if (name.substr(0, 1) == " " || - lastChar == " " || - lastChar == "." || - name.find(" ") != std::string::npos) - { - return false; - } - else if (check.empty()) - { - return true; - } - else if (name.find_first_of(check) != std::string::npos) - { - return false; - } - else - { - return true; - } -} - -PlayerRelationsManager playerRelations; |