1
/*
2
 *  The Mana World
3
 *  Copyright (C) 2008  The Mana World Development Team
4
 *
5
 *  This file is part of The Mana World.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
22
#ifndef PLAYER_RELATIONS_H
23
#define PLAYER_RELATIONS_H
24
25
#include <list>
26
#include <map>
27
#include <string>
28
#include <vector>
29
30
class Being;
31
class Player;
32
33
struct PlayerRelation
34
{
35
    static const unsigned int EMOTE        = (1 << 0);
36
    static const unsigned int SPEECH_FLOAT = (1 << 1);
37
    static const unsigned int SPEECH_LOG   = (1 << 2);
38
    static const unsigned int WHISPER      = (1 << 3);
39
    static const unsigned int TRADE        = (1 << 4);
40
41
    static const unsigned int RELATIONS_NR = 4;
42
    static const unsigned int RELATION_PERMISSIONS[RELATIONS_NR];
43
44
    static const unsigned int DEFAULT = EMOTE
45
                                      | SPEECH_FLOAT
46
                                      | SPEECH_LOG
47
                                      | WHISPER
48
                                      | TRADE;
49
    enum Relation {
50
        NEUTRAL     = 0,
51
        FRIEND      = 1,
52
        DISREGARDED = 2,
53
        IGNORED     = 3
54
    };
55
56
    PlayerRelation(Relation relation);
57
58
    Relation mRelation; // bitmask for all of the above
59
};
60
61
62
/**
63
 * Ignore strategy: describes how we should handle ignores.
64
 */
65
class PlayerIgnoreStrategy
66
{
67
public:
68
    std::string mDescription;
69
    std::string mShortName;
70
71
    virtual ~PlayerIgnoreStrategy() {}
72
73
    /**
74
     * Handle the ignoring of the indicated action by the indicated player.
75
     */
76
    virtual void ignore(Player *player, unsigned int flags) = 0;
77
};
78
79
class PlayerRelationsListener
80
{
81
public:
82
    PlayerRelationsListener() { }
83
    virtual ~PlayerRelationsListener() { }
84
85
    virtual void updatedPlayer(const std::string &name) = 0;
86
};
87
88
/**
89
 * Player relations class, represents any particular relations and/or
90
 * preferences the user of the local client has wrt other players (identified
91
 * by std::string).
92
 */
93
class PlayerRelationsManager
94
{
95
public:
96
    PlayerRelationsManager();
97
    ~PlayerRelationsManager();
98
99
    /**
100
     * Initialise player relations manager (load config file etc.)
101
     */
102
    void init();
103
104
    /**
105
     * Load configuration from our config file, or substitute defaults.
106
     */
107
    void load();
108
109
    /**
110
     * Save configuration to our config file.
111
     */
112
    void store();
113
114
    /**
115
     * Determines whether the player in question is being ignored, filtered by
116
     * the specified flags.
117
     */
118
    unsigned int checkPermissionSilently(const std::string &player_name,
119
                                         unsigned int flags);
120
121
    /**
122
     * Tests whether the player in question is being ignored for any of the
123
     * actions in the specified flags. If so, trigger appropriate side effects
124
     * if requested by the player.
125
     */
126
    bool hasPermission(Being *being, unsigned int flags);
127
128
    bool hasPermission(const std::string &being, unsigned int flags);
129
130
    /**
131
     * Updates the relationship with this player.
132
     */
133
    void setRelation(const std::string &name,
134
                     PlayerRelation::Relation relation);
135
136
    /**
137
     * Updates the relationship with this player.
138
     */
139
    PlayerRelation::Relation getRelation(const std::string &name);
140
141
    /**
142
     * Deletes the information recorded for a player.
143
     */
144
    void removePlayer(const std::string &name);
145
146
    /**
147
     * Retrieves the default permissions.
148
     */
149
    unsigned int getDefault() const;
150
151
    /**
152
     * Sets the default permissions.
153
     */
154
    void setDefault(unsigned int permissions);
155
156
    /**
157
     * Retrieves all known player ignore strategies.
158
     *
159
     * The player ignore strategies are allocated statically and must not be
160
     * deleted.
161
     */
162
    std::vector<PlayerIgnoreStrategy *> *getPlayerIgnoreStrategies();
163
164
    /**
165
     * Return the current player ignore strategy.
166
     *
167
     * \return A player ignore strategy, or NULL
168
     */
169
    PlayerIgnoreStrategy *getPlayerIgnoreStrategy() const
170
    {
171
        return mIgnoreStrategy;
172
    }
173
174
    /**
175
     * Sets the strategy to call when ignoring players.
176
     */
177
    void setPlayerIgnoreStrategy(PlayerIgnoreStrategy *strategy)
178
    {
179
        mIgnoreStrategy = strategy;
180
    }
181
182
    /**
183
     * For a given ignore strategy short name, find the appropriate index in
184
     * the ignore strategies vector.
185
     *
186
     * \param The short name of the ignore strategy to look up
187
     * \return The appropriate index, or -1
188
     */
189
    int getPlayerIgnoreStrategyIndex(const std::string &shortname);
190
191
    /**
192
     * Retrieves a sorted vector of all players for which we have any relations
193
     * recorded.
194
     */
195
    std::vector<std::string> *getPlayers();
196
197
    /**
198
     * Removes all recorded player info.
199
     */
200
    void clear();
201
202
    /**
203
     * Do we persist our `ignore' setup?
204
     */
205
    bool getPersistIgnores() const { return mPersistIgnores; }
206
207
    /**
208
     * Change the `ignore persist' flag.
209
     *
210
     * @param value Whether to persist ignores
211
     */
212
    void setPersistIgnores(bool value) { mPersistIgnores = value; }
213
214
    void addListener(PlayerRelationsListener *listener)
215
    {
216
        mListeners.push_back(listener);
217
    }
218
219
    void removeListener(PlayerRelationsListener *listener)
220
    {
221
        mListeners.remove(listener);
222
    }
223
224
private:
225
    void signalUpdate(const std::string &name);
226
227
    bool mPersistIgnores; // If NOT set, we delete the ignored data upon reloading
228
    unsigned int mDefaultPermissions;
229
230
    PlayerIgnoreStrategy *mIgnoreStrategy;
231
    std::map<std::string, PlayerRelation *> mRelations;
232
    std::list<PlayerRelationsListener *> mListeners;
233
    std::vector<PlayerIgnoreStrategy *> mIgnoreStrategies;
234
};
235
236
237
extern PlayerRelationsManager player_relations; // singleton representation of player relations
238
239
240
#endif /* !defined(PLAYER_RELATIONS_H) */