1 /*
2  *  The ManaPlus Client
3  *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
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/ea/partyrecv.h"
24 
25 #include "actormanager.h"
26 #include "configuration.h"
27 #include "notifymanager.h"
28 #include "party.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 "net/messagein.h"
38 
39 #include "gui/widgets/tabs/chat/partytab.h"
40 
41 #include "utils/delete2.h"
42 
43 #include "debug.h"
44 
45 namespace Ea
46 {
47 
48 Party *taParty = nullptr;
49 
50 namespace PartyRecv
51 {
52     PartyShareT mShareExp = PartyShare::UNKNOWN;
53     PartyShareT mShareItems = PartyShare::UNKNOWN;
54 }  // namespace PartyRecv
55 
processPartyCreate(Net::MessageIn & msg)56 void PartyRecv::processPartyCreate(Net::MessageIn &msg)
57 {
58     if (msg.readUInt8("flag") != 0U)
59         NotifyManager::notify(NotifyTypes::PARTY_CREATE_FAILED);
60     else
61         NotifyManager::notify(NotifyTypes::PARTY_CREATED);
62 }
63 
processPartyExpSettingsContinue(Net::MessageIn & msg,const PartyShareT exp)64 void PartyRecv::processPartyExpSettingsContinue(Net::MessageIn &msg,
65                                                 const PartyShareT exp)
66 {
67     switch (exp)
68     {
69         case PartyShare::YES:
70             if (mShareExp == PartyShare::YES)
71                 break;
72             mShareExp = PartyShare::YES;
73             NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_ON);
74             break;
75         case PartyShare::NO:
76             if (mShareExp == PartyShare::NO)
77                 break;
78             mShareExp = PartyShare::NO;
79             NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_OFF);
80             break;
81         case PartyShare::NOT_POSSIBLE:
82             if (mShareExp == PartyShare::NOT_POSSIBLE)
83                 break;
84             mShareExp = PartyShare::NOT_POSSIBLE;
85             NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_ERROR);
86             break;
87         default:
88         case PartyShare::UNKNOWN:
89             UNIMPLEMENTEDPACKETFIELD(CAST_S32(exp));
90             break;
91     }
92 }
93 
processPartyItemSettingsContinue(Net::MessageIn & msg,const PartyShareT item)94 void PartyRecv::processPartyItemSettingsContinue(Net::MessageIn &msg,
95                                                  const PartyShareT item)
96 {
97     switch (item)
98     {
99         case PartyShare::YES:
100             if (mShareItems == PartyShare::YES)
101                 break;
102             mShareItems = PartyShare::YES;
103             NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ON);
104             break;
105         case PartyShare::NO:
106             if (mShareItems == PartyShare::NO)
107                 break;
108             mShareItems = PartyShare::NO;
109             NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_OFF);
110             break;
111         case PartyShare::NOT_POSSIBLE:
112             if (mShareItems == PartyShare::NOT_POSSIBLE)
113                 break;
114             mShareItems = PartyShare::NOT_POSSIBLE;
115             NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ERROR);
116             break;
117         default:
118         case PartyShare::UNKNOWN:
119             UNIMPLEMENTEDPACKETFIELD(CAST_S32(item));
120             break;
121     }
122 }
123 
processPartyLeave(Net::MessageIn & msg)124 void PartyRecv::processPartyLeave(Net::MessageIn &msg)
125 {
126     const BeingId id = msg.readBeingId("account id");
127     const std::string nick = msg.readString(24, "nick");
128     const int reason = msg.readUInt8("flag");
129     if (localPlayer == nullptr)
130         return;
131 
132     if (id == localPlayer->getId())
133     {
134         switch (reason)
135         {
136             case 0:
137             default:
138                 NotifyManager::notify(NotifyTypes::PARTY_LEFT);
139                 break;
140 
141             case 1:
142                 NotifyManager::notify(NotifyTypes::PARTY_KICKED);
143                 break;
144 
145             case 2:
146                 NotifyManager::notify(NotifyTypes::PARTY_LEFT_DENY);
147                 break;
148 
149             case 3:
150                 NotifyManager::notify(NotifyTypes::PARTY_KICK_DENY);
151                 break;
152         }
153 
154         if (reason >= 2)
155             return;
156 
157         if (Ea::taParty != nullptr)
158         {
159             Ea::taParty->removeFromMembers();
160             Ea::taParty->clearMembers();
161         }
162 
163         delete2(partyTab)
164 
165         if ((socialWindow != nullptr) && (Ea::taParty != nullptr))
166             socialWindow->removeTab(Ea::taParty);
167         localPlayer->setPartyName("");
168     }
169     else
170     {
171         switch (reason)
172         {
173             case 0:
174             default:
175                 NotifyManager::notify(NotifyTypes::PARTY_USER_LEFT, nick);
176                 break;
177 
178             case 1:
179                 NotifyManager::notify(NotifyTypes::PARTY_USER_KICKED, nick);
180                 break;
181 
182             case 2:
183                 NotifyManager::notify(NotifyTypes::PARTY_USER_LEFT_DENY, nick);
184                 break;
185 
186             case 3:
187                 NotifyManager::notify(NotifyTypes::PARTY_USER_KICK_DENY, nick);
188                 break;
189         }
190 
191         if (reason >= 2)
192             return;
193 
194         if (actorManager != nullptr)
195         {
196             Being *const b = actorManager->findBeing(id);
197             if ((b != nullptr) && b->getType() == ActorType::Player)
198             {
199                 b->setParty(nullptr);
200                 b->setPartyName("");
201             }
202         }
203         if (Ea::taParty != nullptr)
204             Ea::taParty->removeMember(id);
205     }
206 }
207 
processPartyUpdateCoords(Net::MessageIn & msg)208 void PartyRecv::processPartyUpdateCoords(Net::MessageIn &msg)
209 {
210     const BeingId id = msg.readBeingId("account id");
211     PartyMember *m = nullptr;
212     if (Ea::taParty != nullptr)
213         m = Ea::taParty->getMember(id);
214     if (m != nullptr)
215     {
216         m->setX(msg.readInt16("x"));
217         m->setY(msg.readInt16("y"));
218     }
219     else
220     {
221         msg.readInt16("x");
222         msg.readInt16("y");
223     }
224 }
225 
createTab()226 void PartyRecv::createTab()
227 {
228     partyTab = new PartyTab(chatWindow);
229     if (config.getBoolValue("showChatHistory"))
230         partyTab->loadFromLogFile("#Party");
231 }
232 
233 }  // namespace Ea
234