GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/tmwa/guildmanager.cpp Lines: 1 276 0.4 %
Date: 2017-11-29 Branches: 0 386 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2011-2017  The ManaPlus Developers
4
 *
5
 *  This file is part of The ManaPlus Client.
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, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#ifdef TMWA_SUPPORT
22
#include "net/tmwa/guildmanager.h"
23
24
#include "actormanager.h"
25
#include "client.h"
26
#include "configuration.h"
27
#include "guild.h"
28
#include "notifymanager.h"
29
30
#include "being/localplayer.h"
31
32
#include "enums/resources/notifytypes.h"
33
34
#include "gui/windows/chatwindow.h"
35
#include "gui/windows/socialwindow.h"
36
37
#include "gui/widgets/tabs/chat/emulateguildtab.h"
38
39
#include "net/chathandler.h"
40
#include "net/packetlimiter.h"
41
42
#include "utils/delete2.h"
43
#include "utils/timer.h"
44
45
#include "debug.h"
46
47
GuildManager *guildManager = nullptr;
48
49
static const int requestTimeout = 5;
50
51
bool GuildManager::mEnableGuildBot = false;
52
53
GuildManager::GuildManager() :
54
    mGotInfo(false),
55
    mGotName(false),
56
    mSentInfoRequest(false),
57
    mSentNameRequest(false),
58
    mHavePower(false),
59
    mTempList(),
60
    mTab(nullptr),
61
    mRequest(false),
62
    mRequestTime(cur_time + 3),
63
    mGotOnlineInfo(false)
64
{
65
}
66
67
GuildManager::~GuildManager()
68
{
69
    delete2(mTab);
70
}
71
72
void GuildManager::init()
73
{
74
    int val = serverConfig.getValue("enableGuildBot", -1);
75
    if (val == -1)
76
    {
77
        if (Client::isTmw())
78
            val = 1;
79
        else
80
            val = 0;
81
        serverConfig.setValue("enableGuildBot", val);
82
    }
83
    mEnableGuildBot = (val != 0);
84
    if (mEnableGuildBot)
85
    {
86
        if (guildManager == nullptr)
87
            guildManager = new GuildManager;
88
        else
89
            guildManager->reload();
90
    }
91
    else if (guildManager != nullptr)
92
    {
93
        delete2(guildManager);
94
    }
95
}
96
97
void GuildManager::reload()
98
{
99
    mGotInfo = false;
100
    mGotName = false;
101
    mHavePower = false;
102
    mRequest = false;
103
    mSentNameRequest = false;
104
    mSentInfoRequest = false;
105
    mGotOnlineInfo = false;
106
    mRequestTime = 0;
107
    mTempList.clear();
108
109
    if (socialWindow != nullptr)
110
    {
111
        Guild *const guild = Guild::getGuild(1);
112
        if ((guild != nullptr) && (socialWindow != nullptr))
113
            socialWindow->removeTab(guild);
114
    }
115
    delete2(mTab);
116
}
117
118
void GuildManager::send(const std::string &msg)
119
{
120
    chatHandler->privateMessage("guild", msg);
121
}
122
123
void GuildManager::chat(const std::string &msg)
124
{
125
    if ((localPlayer == nullptr) || (mTab == nullptr))
126
        return;
127
128
    chatHandler->privateMessage("guild", msg);
129
    mTab->chatLog(localPlayer->getName(), msg);
130
}
131
132
void GuildManager::getNames(StringVect &names) const
133
{
134
    const Guild *const guild = createGuild();
135
    if (guild != nullptr)
136
        guild->getNames(names);
137
}
138
139
void GuildManager::requestGuildInfo()
140
{
141
    if (mRequest && mRequestTime + 15 < cur_time)
142
        return;
143
144
    if (!mGotName && !mSentNameRequest)
145
    {
146
        if (!PacketLimiter::limitPackets(PacketType::PACKET_WHISPER))
147
            return;
148
        send("!info " + toString(tick_time));
149
        mRequest = true;
150
        mSentNameRequest = true;
151
        mRequestTime = cur_time + requestTimeout;
152
    }
153
    else if (!mGotInfo && !mSentInfoRequest && !mSentNameRequest)
154
    {
155
        if (!PacketLimiter::limitPackets(PacketType::PACKET_WHISPER))
156
            return;
157
        send("!getonlineinfo " + toString(tick_time));
158
        mRequest = true;
159
        mSentInfoRequest = true;
160
        mRequestTime = cur_time + requestTimeout;
161
    }
162
}
163
164
void GuildManager::slowLogic()
165
{
166
    if (!mGotOnlineInfo && mGotName && mRequestTime < cur_time)
167
    {
168
        if (!PacketLimiter::limitPackets(PacketType::PACKET_WHISPER))
169
            return;
170
        send("!getonlineinfo " + toString(tick_time));
171
        mRequest = true;
172
        mSentInfoRequest = true;
173
        mRequestTime = cur_time + requestTimeout;
174
    }
175
}
176
177
void GuildManager::updateList()
178
{
179
    Guild *const guild = Guild::getGuild(1);
180
    if (guild != nullptr)
181
    {
182
        guild->setServerGuild(false);
183
        StringVectCIter it = mTempList.begin();
184
        const StringVectCIter it_end = mTempList.end();
185
        int i = 0;
186
        while (it != it_end)
187
        {
188
            std::string name = *it;
189
            const size_t sz = name.size();
190
            if (sz > 1)
191
            {
192
                const int status = atoi(name.substr(sz - 1).c_str());
193
194
                name = name.substr(0, sz - 1);
195
                GuildMember *const m = guild->addMember(
196
                    fromInt(i, BeingId), 0, name);
197
                if (m != nullptr)
198
                {
199
                    m->setOnline((status & 1) != 0);
200
                    m->setGender(Gender::UNSPECIFIED);
201
                    if ((status & 2) != 0)
202
                        m->setPos(10);
203
                    else
204
                        m->setPos(0);
205
                    if (localPlayer != nullptr &&
206
                        name == localPlayer->getName())
207
                    {
208
                        mHavePower = ((status & 2) != 0);
209
                        m->setOnline(true);
210
                    }
211
                }
212
            }
213
            ++ it;
214
            i ++;
215
        }
216
        guild->sort();
217
        createTab(guild);
218
        if (actorManager != nullptr)
219
        {
220
            actorManager->updatePlayerGuild();
221
            actorManager->updatePlayerColors();
222
        }
223
        if (socialWindow != nullptr)
224
            socialWindow->updateGuildCounter();
225
    }
226
    mTempList.clear();
227
    mSentInfoRequest = false;
228
    mGotInfo = true;
229
}
230
231
void GuildManager::createTab(Guild *const guild)
232
{
233
    if (mTab == nullptr)
234
    {
235
        mTab = new EmulateGuildTab(chatWindow);
236
        if (config.getBoolValue("showChatHistory"))
237
            mTab->loadFromLogFile("#Guild");
238
        if (localPlayer != nullptr)
239
            localPlayer->addGuild(guild);
240
    }
241
}
242
243
Guild *GuildManager::createGuild() const
244
{
245
    Guild *const guild = Guild::getGuild(1);
246
    if (guild == nullptr)
247
        return nullptr;
248
249
    guild->setServerGuild(false);
250
    return guild;
251
}
252
253
bool GuildManager::processGuildMessage(const std::string &msg)
254
{
255
    const bool res = process(msg);
256
257
    if (!mRequest)
258
        requestGuildInfo();
259
260
    return res;
261
}
262
263
bool GuildManager::process(std::string msg)
264
{
265
    if (msg.size() > 4 && msg[0] == '#' && msg[1] == '#')
266
        msg = msg.substr(3);
267
268
    const bool haveNick = (msg.find(": ") != std::string::npos);
269
270
    if (!haveNick && findCutLast(msg, " is now Offline."))
271
    {
272
        Guild *const guild = createGuild();
273
        if (guild == nullptr)
274
            return false;
275
        if (msg.size() < 4)
276
            return false;
277
        if (msg[0] == '#' && msg[1] == '#')
278
            msg = msg.substr(3);
279
280
        GuildMember *const m = guild->addMember(msg);
281
        if (m != nullptr)
282
            m->setOnline(false);
283
        guild->sort();
284
        mRequest = false;
285
        if (mTab != nullptr)
286
            mTab->showOnline(msg, Online_false);
287
        if (socialWindow != nullptr)
288
            socialWindow->updateGuildCounter();
289
        return true;
290
    }
291
    else if (!haveNick && findCutLast(msg, " is now Online."))
292
    {
293
        Guild *const guild = createGuild();
294
        if (guild == nullptr)
295
            return false;
296
        if (msg.size() < 4)
297
            return false;
298
        if (msg[0] == '#' && msg[1] == '#')
299
            msg = msg.substr(3);
300
        GuildMember *const m = guild->addMember(msg);
301
        if (m != nullptr)
302
            m->setOnline(true);
303
        guild->sort();
304
        mRequest = false;
305
        if (mTab != nullptr)
306
            mTab->showOnline(msg, Online_true);
307
        if (socialWindow != nullptr)
308
            socialWindow->updateGuildCounter();
309
        return true;
310
    }
311
    else if (findCutFirst(msg, "Welcome to the "))
312
    {
313
        Guild *const guild = createGuild();
314
        if (guild == nullptr)
315
            return false;
316
//        logger->log("welcome message: %s", msg.c_str());
317
        const size_t pos = msg.find("! (");
318
        if (pos == std::string::npos)
319
            return false;
320
        msg = msg.substr(0, pos);
321
        guild->setName(msg);
322
        if (localPlayer != nullptr)
323
            localPlayer->setGuildName(msg);
324
        mGotName = true;
325
        mSentNameRequest = false;
326
        mRequest = false;
327
        return true;
328
    }
329
    else if (findCutFirst(msg, "Player name: "))
330
    {
331
        Guild *const guild = createGuild();
332
        if (guild == nullptr)
333
            return false;
334
        size_t pos = msg.find("Access Level: ");
335
        if (pos == std::string::npos)
336
            return false;
337
338
        msg = msg.substr(pos);
339
        if (!findCutFirst(msg, "Access Level: "))
340
            return false;
341
342
        pos = msg.find(", Guild:");
343
        if (pos == std::string::npos)
344
            return false;
345
346
        const int level = atoi(msg.substr(0, pos).c_str());
347
        if (level >= 10)
348
            mHavePower = true;
349
        else
350
            mHavePower = false;
351
352
        msg = msg.substr(pos + strlen(", Guild:"));
353
        pos = msg.find(", No. Of Online Players: ");
354
        if (pos == std::string::npos)
355
            return false;
356
357
        msg = msg.substr(0, pos);
358
//        logger->log("guild name: %s", msg.c_str());
359
360
        guild->setName(msg);
361
        if (localPlayer != nullptr)
362
            localPlayer->setGuildName(msg);
363
        mGotName = true;
364
        mSentNameRequest = false;
365
        mRequest = false;
366
        return true;
367
    }
368
    else if (findCutFirst(msg, "OL#"))
369
    {
370
//        logger->log("OL");
371
        mTempList.clear();
372
        splitToStringVector(mTempList, msg, '#');
373
        if (msg.empty() || msg[msg.size() - 1] != '#')
374
            updateList();
375
        mRequest = false;
376
        mGotOnlineInfo = true;
377
        return true;
378
    }
379
    else if (findCutFirst(msg, "oL#"))
380
    {
381
//        logger->log("oL");
382
        splitToStringVector(mTempList, msg, '#');
383
        if (msg.empty() || msg[msg.size() - 1] != '#')
384
            updateList();
385
        mRequest = false;
386
        mGotOnlineInfo = true;
387
        return true;
388
    }
389
    else if (msg == "You are currently not in a guild. For more information "
390
             "or to discuss the possibility of adding you own guild "
391
             "please contact Jero.")
392
    {
393
        mRequest = true;
394
        return true;
395
    }
396
    else if (findCutFirst(msg, "You have been invited to the ")
397
             && findCutLast(msg, " guild chat. If you would like to accept "
398
             "this invitation please reply \"yes\" and if not then \"no\" ."))
399
    {
400
        if (socialWindow != nullptr)
401
            socialWindow->showGuildInvite(msg, 1, "");
402
        return true;
403
    }
404
    else if (!haveNick && (findCutLast(msg, " has been removed "
405
             "from the Guild.") || findCutLast(msg, " has left the Guild.")))
406
    {
407
        Guild *const guild = createGuild();
408
        if (guild == nullptr)
409
            return false;
410
        if (msg.size() < 4)
411
            return false;
412
        if (msg[0] == '#' && msg[1] == '#')
413
            msg = msg.substr(3);
414
415
        if (actorManager != nullptr)
416
        {
417
            Being *const b = actorManager->findBeingByName(
418
                msg, ActorType::Player);
419
420
            if (b != nullptr)
421
            {
422
                b->clearGuilds();
423
                b->setGuildName("");
424
                b->updateColors();
425
            }
426
        }
427
428
        guild->removeMember(msg);
429
        return true;
430
    }
431
    else if (msg == "You have been removed from the Guild" ||
432
             msg == "You have left the Guild")
433
    {
434
        return afterRemove();
435
    }
436
    Guild *const guild = createGuild();
437
    if (guild == nullptr)
438
        return false;
439
    if (mTab == nullptr)
440
    {
441
        createTab(guild);
442
    }
443
    if (mTab != nullptr)
444
    {
445
        const size_t pos = msg.find(": ", 0);
446
        if (pos != std::string::npos)
447
        {
448
            const std::string sender_name = msg.substr(0, pos);
449
            if (guild->getMember(sender_name) == nullptr)
450
            {
451
                mTab->chatLog(msg, ChatMsgType::BY_SERVER);
452
                return true;
453
            }
454
455
            msg.erase(0, pos + 2);
456
            if (msg.size() > 3 && msg[0] == '#' && msg[1] == '#')
457
                msg.erase(0, 3);
458
459
            trim(msg);
460
            mTab->chatLog(sender_name, msg);
461
        }
462
        else
463
        {
464
            mTab->chatLog(msg, ChatMsgType::BY_SERVER);
465
        }
466
        return true;
467
    }
468
    return false;
469
}
470
471
void GuildManager::kick(const std::string &msg)
472
{
473
    send("!remove " + msg);
474
}
475
476
void GuildManager::invite(const std::string &msg)
477
{
478
    send("!invite " + msg);
479
}
480
481
void GuildManager::leave()
482
{
483
    send("!leave");
484
}
485
486
void GuildManager::notice(const std::string &msg)
487
{
488
    if (msg.empty())
489
        send("!removemotd");
490
    else
491
        send("!setmotd " + msg);
492
}
493
494
void GuildManager::clear()
495
{
496
    if (socialWindow != nullptr)
497
    {
498
        Guild *const guild = Guild::getGuild(1);
499
        if (guild != nullptr)
500
            socialWindow->removeTab(guild);
501
    }
502
}
503
504
void GuildManager::inviteResponse(const bool response)
505
{
506
    if (response)
507
        send("yes");
508
    else
509
        send("no");
510
}
511
512
bool GuildManager::afterRemove()
513
{
514
    Guild *const guild = createGuild();
515
    if (guild == nullptr)
516
        return false;
517
    guild->removeFromMembers();
518
    guild->clearMembers();
519
    if (localPlayer != nullptr)
520
    {
521
        localPlayer->setGuildName("");
522
        localPlayer->clearGuilds();
523
    }
524
    NotifyManager::notify(NotifyTypes::GUILD_LEFT);
525
    delete2(mTab);
526
527
    if (socialWindow != nullptr)
528
        socialWindow->removeTab(guild);
529
    if (actorManager != nullptr)
530
    {
531
        actorManager->updatePlayerGuild();
532
        actorManager->updatePlayerColors();
533
    }
534
    reload();
535
    return true;
536
}
537
538
ChatTab *GuildManager::getTab()
539
{
540
    return mTab;
541
4
}
542
543
#endif  // TMWA_SUPPORT