GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/tmwa/guildmanager.cpp Lines: 1 286 0.3 %
Date: 2021-03-17 Branches: 0 394 0.0 %

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