GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/eathena/guildrecv.cpp Lines: 1 439 0.2 %
Date: 2021-03-17 Branches: 0 396 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2009-2010  The Mana Developers
4
 *  Copyright (C) 2011-2019  The ManaPlus Developers
5
 *  Copyright (C) 2019-2021  Andrei Karas
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "net/eathena/guildrecv.h"
24
25
#include "actormanager.h"
26
#include "configuration.h"
27
#include "notifymanager.h"
28
29
#include "being/localplayer.h"
30
#include "being/playerinfo.h"
31
32
#include "enums/resources/notifytypes.h"
33
34
#include "gui/windows/chatwindow.h"
35
#include "gui/windows/skilldialog.h"
36
#include "gui/windows/socialwindow.h"
37
38
#include "gui/widgets/tabs/chat/guildtab.h"
39
40
#include "net/beinghandler.h"
41
#include "net/messagein.h"
42
43
#include "net/eathena/guildhandler.h"
44
45
#include "utils/delete2.h"
46
#include "utils/checkutils.h"
47
#include "utils/gettext.h"
48
49
#include "debug.h"
50
51
namespace EAthena
52
{
53
54
Guild *taGuild = nullptr;
55
56
namespace GuildRecv
57
{
58
    bool showBasicInfo = false;
59
}  // namespace GuildRecv
60
61
void GuildRecv::processGuildCreateResponse(Net::MessageIn &msg)
62
{
63
    const uint8_t flag = msg.readUInt8("flag");
64
65
    switch (flag)
66
    {
67
        case 0:
68
            // Success
69
            NotifyManager::notify(NotifyTypes::GUILD_CREATED);
70
            break;
71
72
        case 1:
73
            // Already in a guild
74
            NotifyManager::notify(NotifyTypes::GUILD_ALREADY);
75
            break;
76
77
        case 2:
78
            // Unable to make (likely name already in use)
79
            NotifyManager::notify(NotifyTypes::GUILD_ERROR);
80
            break;
81
82
        case 3:
83
            // Emperium check failed
84
            NotifyManager::notify(NotifyTypes::GUILD_EMPERIUM_CHECK_FAILED);
85
            break;
86
87
        default:
88
            // Unknown response
89
            NotifyManager::notify(NotifyTypes::GUILD_ERROR);
90
            break;
91
    }
92
}
93
94
void GuildRecv::processGuildMasterOrMember(Net::MessageIn &msg)
95
{
96
    msg.readInt32("type");  // Type (0x57 for member, 0xd7 for master)
97
}
98
99
void GuildRecv::processGuildBasicInfo(Net::MessageIn &msg)
100
{
101
    const int guildId = msg.readInt32("guild id");
102
    const int level = msg.readInt32("guild level");
103
    const int members = msg.readInt32("connect member");
104
    const int maxMembers = msg.readInt32("max member");
105
    const int avgLevel = msg.readInt32("average level");
106
    const int exp = msg.readInt32("exp");
107
    const int nextExp = msg.readInt32("next exp");
108
    msg.skip(12, "unused");
109
    const int emblem = msg.readInt32("emblem id");
110
    std::string name = msg.readString(24, "guild name");
111
    std::string castle;
112
    std::string master;
113
    if (msg.getVersion() >= 20160622)
114
    {
115
        castle = msg.readString(16, "castles");
116
        msg.readInt32("money, unused");
117
        msg.readBeingId("leader char id");
118
    }
119
    else
120
    {
121
        master = msg.readString(24, "master name");
122
        castle = msg.readString(16, "castles");
123
        msg.readInt32("money, unused");
124
    }
125
126
    if (guildTab != nullptr &&
127
        showBasicInfo)
128
    {
129
        showBasicInfo = false;
130
        // TRANSLATORS: guild info message
131
        guildTab->chatLog(strprintf(_("Guild name: %s"),
132
            name.c_str()),
133
            ChatMsgType::BY_SERVER,
134
            IgnoreRecord_false,
135
            TryRemoveColors_true);
136
        if (!master.empty())
137
        {
138
            // TRANSLATORS: guild info message
139
            guildTab->chatLog(strprintf(_("Guild master: %s"),
140
                master.c_str()),
141
                ChatMsgType::BY_SERVER,
142
                IgnoreRecord_false,
143
                TryRemoveColors_true);
144
        }
145
        // TRANSLATORS: guild info message
146
        guildTab->chatLog(strprintf(_("Guild level: %d"), level),
147
            ChatMsgType::BY_SERVER,
148
            IgnoreRecord_false,
149
            TryRemoveColors_true);
150
        // TRANSLATORS: guild info message
151
        guildTab->chatLog(strprintf(_("Online members: %d"), members),
152
            ChatMsgType::BY_SERVER,
153
            IgnoreRecord_false,
154
            TryRemoveColors_true);
155
        // TRANSLATORS: guild info message
156
        guildTab->chatLog(strprintf(_("Max members: %d"), maxMembers),
157
            ChatMsgType::BY_SERVER,
158
            IgnoreRecord_false,
159
            TryRemoveColors_true);
160
        // TRANSLATORS: guild info message
161
        guildTab->chatLog(strprintf(_("Average level: %d"), avgLevel),
162
            ChatMsgType::BY_SERVER,
163
            IgnoreRecord_false,
164
            TryRemoveColors_true);
165
        // TRANSLATORS: guild info message
166
        guildTab->chatLog(strprintf(_("Guild exp: %d"), exp),
167
            ChatMsgType::BY_SERVER,
168
            IgnoreRecord_false,
169
            TryRemoveColors_true);
170
        // TRANSLATORS: guild info message
171
        guildTab->chatLog(strprintf(_("Guild next exp: %d"), nextExp),
172
            ChatMsgType::BY_SERVER,
173
            IgnoreRecord_false,
174
            TryRemoveColors_true);
175
        // TRANSLATORS: guild info message
176
        guildTab->chatLog(strprintf(_("Guild castle: %s"), castle.c_str()),
177
            ChatMsgType::BY_SERVER,
178
            IgnoreRecord_false,
179
            TryRemoveColors_true);
180
    }
181
182
    Guild *const g = Guild::getGuild(CAST_S16(guildId));
183
    if (g == nullptr)
184
        return;
185
    g->setName(name);
186
    g->setEmblemId(emblem);
187
}
188
189
void GuildRecv::processGuildAlianceInfo(Net::MessageIn &msg)
190
{
191
    const int length = msg.readInt16("len");
192
    if (length < 4)
193
        return;
194
    const int count = (length - 4) / 32;
195
196
    for (int i = 0; i < count; i++)
197
    {
198
        msg.readInt32("opposition");
199
        msg.readInt32("guild id");
200
        msg.readString(24, "guild name");
201
    }
202
}
203
204
void GuildRecv::processGuildMemberList(Net::MessageIn &msg)
205
{
206
    if (actorManager == nullptr)
207
        return;
208
209
    const int length = msg.readInt16("len");
210
    if (length < 4)
211
        return;
212
    int guildSize = 0;
213
    if (msg.getVersion() >= 20161026)
214
    {
215
        guildSize = 34;
216
    }
217
    else
218
    {
219
        guildSize = 104;
220
    }
221
222
    const int count = (length - 4) / guildSize;
223
    if (taGuild == nullptr)
224
    {
225
        logger->log1("!taGuild");
226
        return;
227
    }
228
229
    taGuild->clearMembers();
230
231
    int onlineNum = 0;
232
    int totalNum = 0;
233
    for (int i = 0; i < count; i++)
234
    {
235
        const BeingId id = msg.readBeingId("account id");
236
        const int charId = msg.readInt32("char id");
237
        msg.readInt16("hair");
238
        msg.readInt16("hair color");
239
        const int gender = msg.readInt16("gender");
240
        const int race = msg.readInt16("class");
241
        const int level = msg.readInt16("level");
242
        const int exp = msg.readInt32("exp");
243
        const int online = msg.readInt32("online");
244
        const int pos = msg.readInt32("position");
245
        std::string name;
246
        if (msg.getVersion() < 20161026)
247
        {
248
            msg.skip(50, "unused");
249
            name = msg.readString(24, "name");
250
        }
251
        else
252
        {
253
            msg.readInt32("last login");  // for now unused
254
            name = actorManager->findCharById(charId);
255
            if (name.empty())
256
            {
257
                beingHandler->requestNameByCharId(charId);
258
            }
259
        }
260
261
        GuildMember *const m = taGuild->addMember(id, charId, name);
262
        if (m != nullptr)
263
        {
264
            m->setOnline(online != 0);
265
            m->setID(id);
266
            m->setCharId(charId);
267
            m->setGender(Being::intToGender(CAST_U8(gender)));
268
            m->setLevel(level);
269
            m->setExp(exp);
270
            m->setPos(pos);
271
            m->setRace(race);
272
            Being *const being = actorManager->findBeingByName(
273
                name, ActorType::Player);
274
            if (being != nullptr)
275
            {
276
                being->setGuildName(taGuild->getName());
277
                if (being->getLevel() != level)
278
                {
279
                    being->setLevel(level);
280
                    being->updateName();
281
                }
282
            }
283
            if (online != 0)
284
                onlineNum ++;
285
            totalNum ++;
286
        }
287
    }
288
    taGuild->sort();
289
    actorManager->updatePlayerGuild();
290
    actorManager->updatePlayerColors();
291
    if (socialWindow != nullptr)
292
        socialWindow->updateGuildCounter(onlineNum, totalNum);
293
}
294
295
void GuildRecv::processGuildPosNameList(Net::MessageIn &msg)
296
{
297
    if (taGuild == nullptr)
298
    {
299
        logger->log1("!taGuild");
300
        return;
301
    }
302
303
    const int length = msg.readInt16("len");
304
    if (length < 4)
305
        return;
306
    const int count = (length - 4) / 28;
307
308
    for (int i = 0; i < count; i++)
309
    {
310
        const int id = msg.readInt32("position id");
311
        const std::string name = msg.readString(24, "position name");
312
        taGuild->addPos(id, name);
313
    }
314
}
315
316
void GuildRecv::processGuildPosInfoList(Net::MessageIn &msg)
317
{
318
    const int length = msg.readInt16("len");
319
    if (length < 4)
320
        return;
321
    const int count = (length - 4) / 16;
322
323
    for (int i = 0; i < count; i++)
324
    {
325
        msg.readInt32("id");
326
        msg.readInt32("mode");
327
        msg.readInt32("same id");
328
        msg.readInt32("exp mode");
329
    }
330
}
331
332
void GuildRecv::processGuildPositionChanged(Net::MessageIn &msg)
333
{
334
    UNIMPLEMENTEDPACKET;
335
    msg.readInt16("len");
336
    msg.readInt32("id");
337
    msg.readInt32("mode");
338
    msg.readInt32("same ip");
339
    msg.readInt32("exp mode");
340
    msg.readString(24, "name");
341
}
342
343
void GuildRecv::processGuildMemberPosChange(Net::MessageIn &msg)
344
{
345
    msg.readInt16("len");
346
    const BeingId accountId = msg.readBeingId("account id");
347
    const int charId = msg.readInt32("char id");
348
    const int pos = msg.readInt32("position");
349
    if (taGuild != nullptr)
350
    {
351
        GuildMember *const m = taGuild->getMember(accountId, charId);
352
        if (m != nullptr)
353
            m->setPos(pos);
354
    }
355
}
356
357
void GuildRecv::processGuildEmblemData(Net::MessageIn &msg)
358
{
359
    UNIMPLEMENTEDPACKET;
360
    const int length = msg.readInt16("len");
361
362
    msg.readInt32("guild id");
363
    msg.readInt32("emblem id");
364
    if (length < 12)
365
        return;
366
    msg.skip(length - 12, "emblem data");
367
}
368
369
void GuildRecv::processGuildSkillInfo(Net::MessageIn &msg)
370
{
371
    const int count = (msg.readInt16("len") - 6) / 37;
372
    msg.readInt16("skill points");
373
374
    if (skillDialog != nullptr)
375
        skillDialog->hideSkills(SkillOwner::Guild);
376
    for (int i = 0; i < count; i++)
377
    {
378
        const int skillId = msg.readInt16("skill id");
379
        const SkillType::SkillType inf = static_cast<SkillType::SkillType>(
380
            msg.readInt32("inf"));
381
        const int level = msg.readInt16("skill level");
382
        const int sp = msg.readInt16("sp");
383
        const int range = msg.readInt16("range");
384
        const std::string name = msg.readString(24, "skill name");
385
        const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable);
386
        PlayerInfo::setSkillLevel(skillId, level);
387
        if (skillDialog != nullptr)
388
        {
389
            if (!skillDialog->updateSkill(skillId, range, up, inf, sp))
390
            {
391
                skillDialog->addSkill(SkillOwner::Guild,
392
                    skillId, name, level, range, up, inf, sp);
393
            }
394
        }
395
    }
396
    if (skillDialog != nullptr)
397
        skillDialog->updateModels();
398
}
399
400
void GuildRecv::processGuildNotice(Net::MessageIn &msg)
401
{
402
    if (guildTab != nullptr)
403
    {
404
        const std::string msg1 = msg.readString(60, "msg1");
405
        const std::string msg2 = msg.readString(120, "msg2");
406
        guildTab->chatLog(msg1,
407
            ChatMsgType::BY_SERVER,
408
            IgnoreRecord_false,
409
            TryRemoveColors_true);
410
        guildTab->chatLog(msg2,
411
            ChatMsgType::BY_SERVER,
412
            IgnoreRecord_false,
413
            TryRemoveColors_true);
414
    }
415
    else
416
    {
417
        msg.readString(60, "msg1");
418
        msg.readString(120, "msg2");
419
    }
420
}
421
422
void GuildRecv::processGuildInvite(Net::MessageIn &msg)
423
{
424
    const int guildId = msg.readInt32("guild id");
425
426
    if (socialWindow != nullptr)
427
    {
428
        const std::string guildName = msg.readString(24, "guild name");
429
        socialWindow->showGuildInvite(guildName, guildId, "");
430
    }
431
    else
432
    {
433
        msg.readString(24, "guild name");
434
    }
435
}
436
437
void GuildRecv::processGuildInviteAck(Net::MessageIn &msg)
438
{
439
    const uint8_t flag = msg.readUInt8("flag");
440
    if (guildTab == nullptr)
441
        return;
442
443
    switch (flag)
444
    {
445
        case 0:
446
            NotifyManager::notify(NotifyTypes::GUILD_INVITE_FAILED);
447
            break;
448
449
        case 1:
450
            NotifyManager::notify(NotifyTypes::GUILD_INVITE_REJECTED);
451
            break;
452
453
        case 2:
454
            NotifyManager::notify(NotifyTypes::GUILD_INVITE_JOINED);
455
            break;
456
457
        case 3:
458
            NotifyManager::notify(NotifyTypes::GUILD_INVITE_FULL);
459
            break;
460
461
        default:
462
            NotifyManager::notify(NotifyTypes::GUILD_INVITE_ERROR);
463
            break;
464
    }
465
}
466
467
void GuildRecv::processGuildLeave(Net::MessageIn &msg)
468
{
469
    const std::string nick = msg.readString(24, "nick");
470
    msg.readString(40, "message");
471
472
    if (taGuild != nullptr)
473
        taGuild->removeMember(nick);
474
475
    if (localPlayer == nullptr)
476
        return;
477
478
    if (nick == localPlayer->getName())
479
    {
480
        if (taGuild != nullptr)
481
        {
482
            taGuild->removeFromMembers();
483
            taGuild->clearMembers();
484
            localPlayer->removeGuild(taGuild->getId());
485
        }
486
        NotifyManager::notify(NotifyTypes::GUILD_LEFT);
487
        delete2(guildTab)
488
489
        if ((socialWindow != nullptr) && (taGuild != nullptr))
490
            socialWindow->removeTab(taGuild);
491
        if (actorManager != nullptr)
492
            actorManager->updatePlayerColors();
493
    }
494
    else
495
    {
496
        NotifyManager::notify(NotifyTypes::GUILD_USER_LEFT, nick);
497
        if (actorManager != nullptr)
498
        {
499
            Being *const b = actorManager->findBeingByName(
500
                nick, ActorType::Player);
501
502
            if (b != nullptr)
503
                b->clearGuilds();
504
            if (taGuild != nullptr)
505
                taGuild->removeMember(nick);
506
        }
507
    }
508
}
509
510
void GuildRecv::processGuildLeave2(Net::MessageIn &msg)
511
{
512
    const int charId = msg.readInt32("char id");
513
    msg.readString(40, "message");
514
    std::string nick;
515
516
    if (taGuild != nullptr)
517
    {
518
        const GuildMember *const member = taGuild->getMemberByCharId(charId);
519
        if (member != nullptr)
520
        {
521
            nick = member->getName();
522
            taGuild->removeMember(member);
523
        }
524
    }
525
526
    if (localPlayer == nullptr)
527
        return;
528
529
    if (charId == PlayerInfo::getCharId())
530
    {
531
        if (taGuild != nullptr)
532
        {
533
            taGuild->removeFromMembers();
534
            taGuild->clearMembers();
535
            localPlayer->removeGuild(taGuild->getId());
536
        }
537
        NotifyManager::notify(NotifyTypes::GUILD_LEFT);
538
        delete2(guildTab)
539
540
        if ((socialWindow != nullptr) && (taGuild != nullptr))
541
            socialWindow->removeTab(taGuild);
542
        if (actorManager != nullptr)
543
            actorManager->updatePlayerColors();
544
    }
545
    else
546
    {
547
        NotifyManager::notify(NotifyTypes::GUILD_USER_LEFT, nick);
548
        if (actorManager != nullptr)
549
        {
550
            Being *const b = actorManager->findBeingByName(
551
                nick, ActorType::Player);
552
553
            if (b != nullptr)
554
                b->clearGuilds();
555
            if (taGuild != nullptr)
556
                taGuild->removeMember(nick);
557
        }
558
    }
559
}
560
561
void GuildRecv::processGuildMessage(Net::MessageIn &msg)
562
{
563
    const int msgLength = msg.readInt16("len") - 4;
564
565
    if (msgLength <= 0)
566
        return;
567
    if (guildTab != nullptr)
568
    {
569
        std::string chatMsg = msg.readString(msgLength, "message");
570
        const size_t pos = chatMsg.find(" : ", 0);
571
        if (pos != std::string::npos)
572
        {
573
            const std::string sender_name = chatMsg.substr(0, pos);
574
            chatMsg.erase(0, pos + 3);
575
            trim(chatMsg);
576
            guildTab->chatLog(sender_name, chatMsg);
577
        }
578
        else
579
        {
580
            guildTab->chatLog(chatMsg,
581
                ChatMsgType::BY_SERVER,
582
                IgnoreRecord_false,
583
                TryRemoveColors_true);
584
        }
585
    }
586
    else
587
    {
588
        DEBUGLOGSTR("invisible guild?");
589
        msg.readString(msgLength, "message");
590
    }
591
}
592
593
void GuildRecv::processGuildReqAlliance(Net::MessageIn &msg)
594
{
595
    UNIMPLEMENTEDPACKET;
596
    msg.readInt32("id");
597
    msg.readString(24, "name");
598
}
599
600
void GuildRecv::processGuildReqAllianceAck(Net::MessageIn &msg)
601
{
602
    UNIMPLEMENTEDPACKET;
603
    msg.readInt32("flag");
604
}
605
606
void GuildRecv::processGuildDelAlliance(Net::MessageIn &msg)
607
{
608
    UNIMPLEMENTEDPACKET;
609
    msg.readInt32("guild id");
610
    msg.readInt32("flag");
611
}
612
613
void GuildRecv::processGuildOppositionAck(Net::MessageIn &msg)
614
{
615
    UNIMPLEMENTEDPACKET;
616
    msg.readUInt8("flag");
617
}
618
619
void GuildRecv::processGuildBroken(Net::MessageIn &msg)
620
{
621
    UNIMPLEMENTEDPACKET;
622
    msg.readInt32("flag");
623
}
624
625
void GuildRecv::processGuildExpulsionContinue(const std::string &nick)
626
{
627
    if (taGuild != nullptr)
628
        taGuild->removeMember(nick);
629
630
    if (localPlayer == nullptr)
631
        return;
632
633
    if (nick == localPlayer->getName())
634
    {
635
        if (taGuild != nullptr)
636
        {
637
            taGuild->removeFromMembers();
638
            taGuild->clearMembers();
639
        }
640
        NotifyManager::notify(NotifyTypes::GUILD_KICKED);
641
        delete2(guildTab)
642
643
        if ((socialWindow != nullptr) && (taGuild != nullptr))
644
            socialWindow->removeTab(taGuild);
645
        if (actorManager != nullptr)
646
            actorManager->updatePlayerColors();
647
    }
648
    else
649
    {
650
        NotifyManager::notify(NotifyTypes::GUILD_USER_KICKED, nick);
651
        if (actorManager != nullptr)
652
        {
653
            Being *const b = actorManager->findBeingByName(
654
                nick, ActorType::Player);
655
656
            if (b != nullptr)
657
                b->clearGuilds();
658
            if (taGuild != nullptr)
659
                taGuild->removeMember(nick);
660
        }
661
    }
662
}
663
664
void GuildRecv::processGuildUpdateCoords(Net::MessageIn &msg)
665
{
666
    const BeingId id = msg.readBeingId("account id");
667
    const int x = msg.readInt16("x");
668
    const int y = msg.readInt16("y");
669
    if (taGuild != nullptr)
670
    {
671
        GuildMember *const m = taGuild->getMember(id);
672
        if (m != nullptr)
673
        {
674
            m->setX(x);
675
            m->setY(y);
676
        }
677
    }
678
}
679
680
void GuildRecv::processGuildPositionInfo(Net::MessageIn &msg)
681
{
682
    const int guildId =  msg.readInt32("guild id");
683
    const int emblem =  msg.readInt32("elblem id");
684
    PlayerInfo::setGuildPositionFlags(
685
        static_cast<GuildPositionFlags::Type>(msg.readInt32("mode")));
686
    msg.readUInt8("guild master");
687
    msg.readInt32("unused");
688
    std::string guildName = msg.readString(24, "guild name");
689
690
    Guild *const g = Guild::getGuild(CAST_S16(guildId));
691
    if (g == nullptr)
692
        return;
693
694
    g->setName(guildName);
695
    g->setEmblemId(emblem);
696
    if (taGuild == nullptr)
697
        taGuild = g;
698
    if ((guildTab == nullptr) && (chatWindow != nullptr))
699
    {
700
        guildTab = new GuildTab(chatWindow);
701
        if (config.getBoolValue("showChatHistory"))
702
            guildTab->loadFromLogFile("#Guild");
703
        if (localPlayer != nullptr)
704
            localPlayer->addGuild(taGuild);
705
        guildHandler->memberList();
706
    }
707
708
    if (localPlayer != nullptr)
709
    {
710
        localPlayer->setGuild(g);
711
        localPlayer->setGuildName(g->getName());
712
    }
713
}
714
715
void GuildRecv::processGuildMemberLogin(Net::MessageIn &msg)
716
{
717
    const BeingId accountId = msg.readBeingId("account id");
718
    const int charId = msg.readInt32("char id");
719
    const int online = msg.readInt32("flag");
720
    const GenderT gender = Being::intToGender(CAST_U8(
721
        msg.readInt16("sex")));
722
    msg.readInt16("hair");
723
    msg.readInt16("hair color");
724
    if (taGuild != nullptr)
725
    {
726
        GuildMember *const m = taGuild->getMember(accountId, charId);
727
        if (m != nullptr)
728
        {
729
            m->setOnline(online != 0);
730
            if (online != 0)
731
                m->setGender(gender);
732
            if (guildTab != nullptr)
733
                guildTab->showOnline(m->getName(), fromBool(online, Online));
734
            if (socialWindow != nullptr)
735
                socialWindow->updateGuildCounter(0, 0);
736
        }
737
    }
738
}
739
740
void GuildRecv::processGuildExpulsion(Net::MessageIn &msg)
741
{
742
    const std::string nick = msg.readString(24, "name");
743
    msg.readString(40, "message");
744
745
    GuildRecv::processGuildExpulsionContinue(nick);
746
}
747
748
void GuildRecv::processGuildExpulsion2(Net::MessageIn &msg)
749
{
750
    msg.readString(40, "message");
751
    const int charId = msg.readInt32("char id");
752
753
    std::string nick;
754
755
    if (taGuild != nullptr)
756
    {
757
        const GuildMember *const member = taGuild->getMemberByCharId(charId);
758
        if (member != nullptr)
759
        {
760
            nick = member->getName();
761
            GuildRecv::processGuildExpulsionContinue(nick);
762
        }
763
    }
764
}
765
766
void GuildRecv::processGuildExpulsionList1(Net::MessageIn &msg)
767
{
768
    UNIMPLEMENTEDPACKET;
769
    const int length = msg.readInt16("len");
770
    if (length < 4)
771
        return;
772
773
    const int count = (length - 4) / 88;
774
    for (int i = 0; i < count; i++)
775
    {
776
        msg.readString(24, "char name");
777
        msg.readString(24, "account name");
778
        msg.readString(40, "message");
779
    }
780
}
781
782
void GuildRecv::processGuildExpulsionList2(Net::MessageIn &msg)
783
{
784
    UNIMPLEMENTEDPACKET;
785
    const int length = msg.readInt16("len");
786
    if (length < 4)
787
        return;
788
789
    const int count = (length - 4) / 64;
790
    for (int i = 0; i < count; i++)
791
    {
792
        msg.readString(24, "name");
793
        msg.readString(40, "message");
794
    }
795
}
796
797
void GuildRecv::processGuildExpulsionList3(Net::MessageIn &msg)
798
{
799
    UNIMPLEMENTEDPACKET;
800
    const int length = msg.readInt16("len");
801
    if (length < 4)
802
        return;
803
804
    int count = (length - 4) / 44;
805
    for (int i = 0; i < count; i++)
806
    {
807
        msg.readInt32("char id");
808
        msg.readString(40, "message");
809
    }
810
}
811
812
void GuildRecv::processGuildEmblem(Net::MessageIn &msg)
813
{
814
    UNIMPLEMENTEDPACKET;
815
    msg.readBeingId("being id");
816
    msg.readInt32("guild id");
817
    msg.readInt16("emblem id");
818
}
819
820
void GuildRecv::processOnlineInfo(Net::MessageIn &msg)
821
{
822
    // look like unused packet
823
    UNIMPLEMENTEDPACKET;
824
    msg.readBeingId("being id");
825
    msg.readInt32("char id");
826
    msg.readInt32("online");
827
}
828
829
void GuildRecv::processGuildSetPosition(Net::MessageIn &msg)
830
{
831
    const int positionLen = msg.readInt16("len") - 8;
832
    const BeingId beingId = msg.readBeingId("being id");
833
    std::string position;
834
    if (positionLen > 0)
835
    {
836
        position = msg.readString(positionLen, "position");
837
    }
838
    Being *const dstBeing = actorManager->findBeing(beingId);
839
    if (dstBeing != nullptr)
840
    {
841
        dstBeing->setGuildPos(position);
842
        dstBeing->addToCache();
843
    }
844
}
845
846
2
}  // namespace EAthena