00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <algorithm>
00023
00024 #include "being.h"
00025 #include "beingmanager.h"
00026 #include "configuration.h"
00027 #include "graphics.h"
00028 #include "player.h"
00029 #include "player_relations.h"
00030
00031 #include "utils/dtor.h"
00032
00033 #define PLAYER_IGNORE_STRATEGY_NOP "nop"
00034 #define PLAYER_IGNORE_STRATEGY_EMOTE0 "emote0"
00035 #define DEFAULT_IGNORE_STRATEGY PLAYER_IGNORE_STRATEGY_EMOTE0
00036
00037 #define NAME "name" // constant for xml serialisation
00038 #define RELATION "relation" // constant for xml serialisation
00039
00040 #define IGNORE_EMOTE_TIME 100
00041
00042
00043 class PlayerConfSerialiser : public ConfigurationListManager<std::pair<std::string, PlayerRelation *>,
00044 std::map<std::string, PlayerRelation *> *>
00045 {
00046 virtual ConfigurationObject *writeConfigItem(std::pair<std::string, PlayerRelation *> value,
00047 ConfigurationObject *cobj)
00048 {
00049 if (!value.second)
00050 return NULL;
00051 cobj->setValue(NAME, value.first);
00052 cobj->setValue(RELATION, toString(value.second->mRelation));
00053
00054 return cobj;
00055 }
00056
00057 virtual std::map<std::string, PlayerRelation *> *
00058 readConfigItem(ConfigurationObject *cobj,
00059 std::map<std::string, PlayerRelation *> *container)
00060 {
00061 std::string name = cobj->getValue(NAME, "");
00062 if (name.empty())
00063 return container;
00064
00065 if (!(*container)[name]) {
00066 int v = (int)cobj->getValue(RELATION, PlayerRelation::NEUTRAL);
00067 (*container)[name] = new PlayerRelation(static_cast<PlayerRelation::Relation>(v));
00068 }
00069
00070
00071 return container;
00072 }
00073 };
00074
00075 static PlayerConfSerialiser player_conf_serialiser;
00076
00077 const unsigned int PlayerRelation::RELATION_PERMISSIONS[RELATIONS_NR] = {
00078 0,
00079 EMOTE | SPEECH_FLOAT | SPEECH_LOG | WHISPER | TRADE,
00080 EMOTE | SPEECH_FLOAT,
00081 0
00082 };
00083
00084 PlayerRelation::PlayerRelation(Relation relation)
00085 {
00086 mRelation = relation;
00087 }
00088
00089 PlayerRelationsManager::PlayerRelationsManager() :
00090 mPersistIgnores(false),
00091 mDefaultPermissions(PlayerRelation::DEFAULT),
00092 mIgnoreStrategy(NULL)
00093 {
00094 }
00095
00096 PlayerRelationsManager::~PlayerRelationsManager()
00097 {
00098 delete_all(mIgnoreStrategies);
00099 }
00100
00101 void PlayerRelationsManager::clear()
00102 {
00103 std::vector<std::string> *names = getPlayers();
00104 for (std::vector<std::string>::const_iterator
00105 it = names->begin(); it != names->end(); it++)
00106 removePlayer(*it);
00107 delete names;
00108 }
00109
00110 #define PERSIST_IGNORE_LIST "persist-player-list"
00111 #define PLAYER_IGNORE_STRATEGY "player-ignore-strategy"
00112 #define DEFAULT_PERMISSIONS "default-player-permissions"
00113
00114 int PlayerRelationsManager::getPlayerIgnoreStrategyIndex(const std::string &name)
00115 {
00116 std::vector<PlayerIgnoreStrategy *> *strategies = getPlayerIgnoreStrategies();
00117 for (unsigned int i = 0; i < strategies->size(); i++)
00118 if ((*strategies)[i]->mShortName == name)
00119 return i;
00120
00121 return -1;
00122 }
00123
00124 void PlayerRelationsManager::load()
00125 {
00126 clear();
00127
00128 mPersistIgnores = config.getValue(PERSIST_IGNORE_LIST, 0);
00129 mDefaultPermissions = (int) config.getValue(DEFAULT_PERMISSIONS, mDefaultPermissions);
00130 std::string ignore_strategy_name = config.getValue(PLAYER_IGNORE_STRATEGY, DEFAULT_IGNORE_STRATEGY);
00131 int ignore_strategy_index = getPlayerIgnoreStrategyIndex(ignore_strategy_name);
00132 if (ignore_strategy_index >= 0)
00133 setPlayerIgnoreStrategy((*getPlayerIgnoreStrategies())[ignore_strategy_index]);
00134
00135 config.getList<std::pair<std::string, PlayerRelation *>,
00136 std::map<std::string, PlayerRelation *> *>
00137 ("player", &(mRelations), &player_conf_serialiser);
00138 }
00139
00140
00141 void PlayerRelationsManager::init()
00142 {
00143 load();
00144
00145 if (!mPersistIgnores)
00146 clear();
00147 }
00148
00149 void PlayerRelationsManager::store()
00150 {
00151 config.setList<std::map<std::string, PlayerRelation *>::const_iterator,
00152 std::pair<std::string, PlayerRelation *>,
00153 std::map<std::string, PlayerRelation *> *>
00154 ("player",
00155 mRelations.begin(), mRelations.end(),
00156 &player_conf_serialiser);
00157
00158 config.setValue(DEFAULT_PERMISSIONS, mDefaultPermissions);
00159 config.setValue(PERSIST_IGNORE_LIST, mPersistIgnores);
00160 config.setValue(PLAYER_IGNORE_STRATEGY,
00161 (mIgnoreStrategy)? mIgnoreStrategy->mShortName : DEFAULT_IGNORE_STRATEGY);
00162
00163 config.write();
00164 }
00165
00166 void PlayerRelationsManager::signalUpdate(const std::string &name)
00167 {
00168 store();
00169
00170 for (std::list<PlayerRelationsListener *>::const_iterator it = mListeners.begin(); it != mListeners.end(); it++)
00171 (*it)->updatedPlayer(name);
00172 }
00173
00174 unsigned int PlayerRelationsManager::checkPermissionSilently(const std::string &player_name, unsigned int flags)
00175 {
00176 PlayerRelation *r = mRelations[player_name];
00177 if (!r)
00178 return mDefaultPermissions & flags;
00179 else {
00180 unsigned int permissions = PlayerRelation::RELATION_PERMISSIONS[r->mRelation];
00181
00182 switch (r->mRelation) {
00183 case PlayerRelation::NEUTRAL:
00184 permissions = mDefaultPermissions;
00185 break;
00186
00187 case PlayerRelation::FRIEND:
00188 permissions |= mDefaultPermissions;
00189 break;
00190
00191 default:
00192 permissions &= mDefaultPermissions;
00193 }
00194
00195 return permissions & flags;
00196 }
00197 }
00198
00199 bool PlayerRelationsManager::hasPermission(Being *being, unsigned int flags)
00200 {
00201 if (being->getType() == Being::PLAYER)
00202 return hasPermission(being->getName(), flags) == flags;
00203 return true;
00204 }
00205
00206 bool PlayerRelationsManager::hasPermission(const std::string &name, unsigned int flags)
00207 {
00208 unsigned int rejections = flags & ~checkPermissionSilently(name, flags);
00209 bool permitted = rejections == 0;
00210
00211 if (!permitted) {
00212
00213 if (mIgnoreStrategy) {
00214 Player *to_ignore = dynamic_cast<Player *>(beingManager->findBeingByName(name, Being::PLAYER));
00215
00216 if (to_ignore)
00217 mIgnoreStrategy->ignore(to_ignore,
00218 rejections);
00219 }
00220 }
00221
00222 return permitted;
00223 }
00224
00225 void PlayerRelationsManager::setRelation(const std::string &player_name,
00226 PlayerRelation::Relation relation)
00227 {
00228 PlayerRelation *r = mRelations[player_name];
00229 if (r == NULL)
00230 mRelations[player_name] = new PlayerRelation(relation);
00231 else
00232 r->mRelation = relation;
00233
00234 signalUpdate(player_name);
00235 }
00236
00237 std::vector<std::string> * PlayerRelationsManager::getPlayers()
00238 {
00239 std::vector<std::string> *retval = new std::vector<std::string>();
00240
00241 for (std::map<std::string, PlayerRelation *>::const_iterator it = mRelations.begin(); it != mRelations.end(); it++)
00242 if (it->second)
00243 retval->push_back(it->first);
00244
00245 sort(retval->begin(), retval->end());
00246
00247 return retval;
00248 }
00249
00250 void PlayerRelationsManager::removePlayer(const std::string &name)
00251 {
00252 if (mRelations[name])
00253 delete mRelations[name];
00254
00255 mRelations.erase(name);
00256
00257 signalUpdate(name);
00258 }
00259
00260
00261 PlayerRelation::Relation PlayerRelationsManager::getRelation(const std::string &name)
00262 {
00263 if (mRelations[name])
00264 return mRelations[name]->mRelation;
00265
00266 return PlayerRelation::NEUTRAL;
00267 }
00268
00270
00271
00272 unsigned int PlayerRelationsManager::getDefault() const
00273 {
00274 return mDefaultPermissions;
00275 }
00276
00277 void PlayerRelationsManager::setDefault(unsigned int permissions)
00278 {
00279 mDefaultPermissions = permissions;
00280
00281 store();
00282 signalUpdate("");
00283 }
00284
00285
00287
00288
00289
00290 class PIS_nothing : public PlayerIgnoreStrategy
00291 {
00292 public:
00293 PIS_nothing()
00294 {
00295 mDescription = "completely ignore";
00296 mShortName = PLAYER_IGNORE_STRATEGY_NOP;
00297 }
00298
00299 virtual void ignore(Player *player, unsigned int flags)
00300 {
00301 }
00302 };
00303
00304 class PIS_dotdotdot : public PlayerIgnoreStrategy
00305 {
00306 public:
00307 PIS_dotdotdot()
00308 {
00309 mDescription = "print '...'";
00310 mShortName = "dotdotdot";
00311 }
00312
00313 virtual void ignore(Player *player, unsigned int flags)
00314 {
00315 player->setSpeech("...", 500);
00316 }
00317 };
00318
00319
00320 class PIS_blinkname : public PlayerIgnoreStrategy
00321 {
00322 public:
00323 PIS_blinkname()
00324 {
00325 mDescription = "blink name";
00326 mShortName = "blinkname";
00327 }
00328
00329 virtual void ignore(Player *player, unsigned int flags)
00330 {
00331 player->flash(200);
00332 }
00333 };
00334
00335 class PIS_emote : public PlayerIgnoreStrategy
00336 {
00337 public:
00338 PIS_emote(int emote_nr, const std::string &description, const std::string &shortname) :
00339 mEmotion(emote_nr)
00340 {
00341 mDescription = description;
00342 mShortName = shortname;
00343 }
00344
00345 virtual void ignore(Player *player, unsigned int flags)
00346 {
00347 player->setEmote(mEmotion, IGNORE_EMOTE_TIME);
00348 }
00349 private:
00350 int mEmotion;
00351 };
00352
00353
00354
00355 std::vector<PlayerIgnoreStrategy *> *
00356 PlayerRelationsManager::getPlayerIgnoreStrategies()
00357 {
00358 if (mIgnoreStrategies.size() == 0)
00359 {
00360
00361 mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE,
00362 "floating '...' bubble",
00363 PLAYER_IGNORE_STRATEGY_EMOTE0));
00364 mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE + 1,
00365 "floating bubble",
00366 "emote1"));
00367 mIgnoreStrategies.push_back(new PIS_nothing());
00368 mIgnoreStrategies.push_back(new PIS_dotdotdot());
00369 mIgnoreStrategies.push_back(new PIS_blinkname());
00370 }
00371 return &mIgnoreStrategies;
00372 }
00373
00374
00375 PlayerRelationsManager player_relations;