1/**
2 * The Forgotten Server - a free and open-source MMORPG server emulator
3 * Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifndef FS_PROTOCOLGAME_H_FACA2A2D1A9348B78E8FD7E8003EBB87
21#define FS_PROTOCOLGAME_H_FACA2A2D1A9348B78E8FD7E8003EBB87
22
23#include "chat.h"
24#include "creature.h"
25#include "protocol.h"
26#include "tasks.h"
27#include "walkmatrix.h"
28
29class NetworkMessage;
30class Player;
31class Game;
32class House;
33class Container;
34class Tile;
35class Connection;
36class Quest;
37class ProtocolGame;
38using ProtocolGame_ptr = std::shared_ptr<ProtocolGame>;
39
40extern Game g_game;
41
42struct TextMessage {
43 MessageClasses type = MESSAGE_STATUS_DEFAULT;
44 std::string text;
45 Position position;
46 uint16_t channelId;
47 struct {
48 int32_t value = 0;
49 TextColor_t color;
50 } primary, secondary;
51
52 TextMessage() = default;
53 TextMessage(MessageClasses type, std::string text)
54 : type(type), text(std::move(text)) {}
55};
56
57class InputMessage {
58public:
59 // Define los miembros y métodos de InputMessage aquí
60 // ...
61};
62
63class ProtocolGame final : public Protocol {
64public:
65 // static protocol information
66 enum { server_sends_first = true };
67 enum { protocol_identifier = 0 }; // Not required as we send first
68 enum { use_checksum = true };
69 static const char *protocol_name() { return "gameworld protocol"; }
70
71 explicit ProtocolGame(Connection_ptr connection) : Protocol(connection) {}
72
73 void login(const std::string &name, uint32_t accountId,
74 OperatingSystem_t operatingSystem);
75 void logout(bool displayEffect, bool forced);
76
77 uint16_t getVersion() const { return version; }
78
79private:
80 ProtocolGame_ptr getThis() {
81 return std::static_pointer_cast<ProtocolGame>(shared_from_this());
82 }
83 void connect(uint32_t playerId, OperatingSystem_t operatingSystem);
84 void disconnectClient(const std::string &message) const;
85 void writeToOutputBuffer(const NetworkMessage &msg);
86
87 void release() override;
88
89 void checkCreatureAsKnown(uint32_t id, bool &known, uint32_t &removedKnown);
90
91 bool canSee(int32_t x, int32_t y, int32_t z) const;
92 bool canSee(const Creature *) const;
93 bool canSee(const Position &pos) const;
94
95 // we have all the parse methods
96 void parsePacket(NetworkMessage &msg) override;
97 void onRecvFirstMessage(NetworkMessage &msg) override;
98 void onConnect() override;
99
100 // Parse methods
101 void parseAutoWalk(NetworkMessage &msg);
102 void parseSetOutfit(NetworkMessage &msg);
103 void parseSay(NetworkMessage &msg);
104 void parseLookAt(NetworkMessage &msg);
105 void parseLookInBattleList(NetworkMessage &msg);
106 void parseFightModes(NetworkMessage &msg);
107 void parseAttack(NetworkMessage &msg);
108 void parseFollow(NetworkMessage &msg);
109 void parseEquipObject(NetworkMessage &msg);
110
111 void parseBugReport(NetworkMessage &msg);
112 void parseDebugAssert(NetworkMessage &msg);
113 void parseRuleViolationReport(NetworkMessage &msg);
114
115 void parseThrow(NetworkMessage &msg);
116 void parseUseItemEx(NetworkMessage &msg);
117 void parseUseWithCreature(NetworkMessage &msg);
118 void parseUseItem(NetworkMessage &msg);
119 void parseCloseContainer(NetworkMessage &msg);
120 void parseUpArrowContainer(NetworkMessage &msg);
121 void parseUpdateContainer(NetworkMessage &msg);
122 void parseTextWindow(NetworkMessage &msg);
123 void parseHouseWindow(NetworkMessage &msg);
124 void parseWrapItem(NetworkMessage &msg);
125
126 void parseLookInShop(NetworkMessage &msg);
127 void parsePlayerPurchase(NetworkMessage &msg);
128 void parsePlayerSale(NetworkMessage &msg);
129
130 void parseQuestLine(NetworkMessage &msg);
131
132 void parseInviteToParty(NetworkMessage &msg);
133 void parseJoinParty(NetworkMessage &msg);
134 void parseRevokePartyInvite(NetworkMessage &msg);
135 void parsePassPartyLeadership(NetworkMessage &msg);
136 void parseEnableSharedPartyExperience(NetworkMessage &msg);
137
138 void parseToggleMount(NetworkMessage &msg);
139
140 void parseModalWindowAnswer(NetworkMessage &msg);
141
142 void parseBrowseField(NetworkMessage &msg);
143 void parseSeekInContainer(NetworkMessage &msg);
144
145 // trade methods
146 void parseRequestTrade(NetworkMessage &msg);
147 void parseLookInTrade(NetworkMessage &msg);
148
149 // market methods
150 void parseMarketLeave();
151 void parseMarketBrowse(NetworkMessage &msg);
152 void parseMarketCreateOffer(NetworkMessage &msg);
153 void parseMarketCancelOffer(NetworkMessage &msg);
154 void parseMarketAcceptOffer(NetworkMessage &msg);
155
156 // VIP methods
157 void parseAddVip(NetworkMessage &msg);
158 void parseRemoveVip(NetworkMessage &msg);
159 void parseEditVip(NetworkMessage &msg);
160
161 void parseRotateItem(NetworkMessage &msg);
162
163 // Channel tabs
164 void parseChannelInvite(NetworkMessage &msg);
165 void parseChannelExclude(NetworkMessage &msg);
166 void parseOpenChannel(NetworkMessage &msg);
167 void parseOpenPrivateChannel(NetworkMessage &msg);
168 void parseCloseChannel(NetworkMessage &msg);
169
170 // Send functions
171 void sendChannelMessage(const std::string &author, const std::string &text,
172 SpeakClasses type, uint16_t channel);
173 void sendChannelEvent(uint16_t channelId, const std::string &playerName,
174 ChannelEvent_t channelEvent);
175 void sendClosePrivate(uint16_t channelId);
176 void sendCreatePrivateChannel(uint16_t channelId,
177 const std::string &channelName);
178 void sendChannelsDialog();
179 void sendChannel(uint16_t channelId, const std::string &channelName,
180 const UsersMap *channelUsers,
181 const InvitedMap *invitedUsers);
182 void sendOpenPrivateChannel(const std::string &receiver);
183 void sendToChannel(const Creature *creature, SpeakClasses type,
184 const std::string &text, uint16_t channelId);
185 void sendPrivateMessage(const Player *speaker, SpeakClasses type,
186 const std::string &text);
187 void sendIcons(uint16_t icons);
188 void sendFYIBox(const std::string &message);
189
190 void sendDistanceShoot(const Position &from, const Position &to,
191 uint8_t type);
192 void sendMagicEffect(const Position &pos, uint16_t type);
193 void sendCreatureHealth(const Creature *creature);
194 void sendSkills();
195 void sendPing();
196 void sendPingBack();
197 void sendCreatureTurn(const Creature *creature, uint32_t stackPos);
198 void sendCreatureSay(const Creature *creature, SpeakClasses type,
199 const std::string &text, const Position *pos = nullptr);
200
201 void sendQuestLog();
202 void sendQuestLine(const Quest *quest);
203
204 void sendCancelWalk();
205 void sendChangeSpeed(const Creature *creature, uint32_t speed);
206 void sendCancelTarget();
207 void sendCreatureOutfit(const Creature *creature, const Outfit_t &outfit);
208 void sendCreatureAttackPulse(const Creature *creature, const Outfit_t &outfit,
209 uint32_t duration);
210 void sendStats();
211 void sendBasicData();
212 void sendTextMessage(const TextMessage &message);
213 void sendReLoginWindow(uint8_t unfairFightReduction);
214
215 void sendTutorial(uint8_t tutorialId);
216 void sendAddMarker(const Position &pos, uint8_t markType,
217 const std::string &desc);
218
219 void sendCreatureWalkthrough(const Creature *creature, bool walkthrough);
220 void sendCreatureShield(const Creature *creature);
221 void sendCreatureSkull(const Creature *creature);
222 void sendCreatureType(uint32_t creatureId, uint8_t creatureType);
223 void sendCreatureHelpers(uint32_t creatureId, uint16_t helpers);
224
225 void sendShop(Npc *npc, const ShopInfoList &itemList);
226 void sendCloseShop();
227 void sendSaleItemList(const std::list<ShopInfo> &shop);
228 void sendMarketEnter(uint32_t depotId);
229 void sendMarketLeave();
230 void sendMarketBrowseItem(uint16_t itemId, const MarketOfferList &buyOffers,
231 const MarketOfferList &sellOffers);
232 void sendMarketAcceptOffer(const MarketOfferEx &offer);
233 void sendMarketBrowseOwnOffers(const MarketOfferList &buyOffers,
234 const MarketOfferList &sellOffers);
235 void sendMarketCancelOffer(const MarketOfferEx &offer);
236 void sendMarketBrowseOwnHistory(const HistoryMarketOfferList &buyOffers,
237 const HistoryMarketOfferList &sellOffers);
238 void sendMarketDetail(uint16_t itemId);
239 void sendTradeItemRequest(const std::string &traderName, const Item *item,
240 bool ack);
241 void sendCloseTrade();
242
243 void sendTextWindow(uint32_t windowTextId, Item *item, uint16_t maxlen,
244 bool canWrite);
245 void sendTextWindow(uint32_t windowTextId, uint32_t itemId,
246 const std::string &text);
247 void sendHouseWindow(uint32_t windowTextId, const std::string &text);
248 void sendOutfitWindow();
249
250 void sendUpdatedVIPStatus(uint32_t guid, VipStatus_t newStatus);
251 void sendVIP(uint32_t guid, const std::string &name,
252 const std::string &description, uint32_t icon, bool notify,
253 VipStatus_t status);
254 void sendVIPEntries();
255
256 void sendPendingStateEntered();
257 void sendEnterWorld();
258
259 void sendFightModes();
260
261 void sendCreatureLight(const Creature *creature);
262 void sendWorldLight(LightInfo lightInfo);
263
264 void sendCreatureSquare(const Creature *creature, SquareColor_t color);
265
266 void sendSpellCooldown(uint8_t spellId, uint32_t time);
267 void sendSpellGroupCooldown(SpellGroup_t groupId, uint32_t time);
268
269 // tiles
270 void sendMapDescription(const Position &pos);
271
272 void sendAddTileItem(const Position &pos, uint32_t stackpos,
273 const Item *item);
274 void sendUpdateTileItem(const Position &pos, uint32_t stackpos,
275 const Item *item);
276 void sendRemoveTileThing(const Position &pos, uint32_t stackpos);
277 void sendUpdateTile(const Tile *tile, const Position &pos);
278
279 void sendAddCreature(const Creature *creature, const Position &pos,
280 int32_t stackpos, bool isLogin);
281 void sendMoveCreature(const Creature *creature, const Position &newPos,
282 int32_t newStackPos, const Position &oldPos,
283 int32_t oldStackPos, bool teleport);
284
285 // containers
286 void sendAddContainerItem(uint8_t cid, uint16_t slot, const Item *item);
287 void sendUpdateContainerItem(uint8_t cid, uint16_t slot, const Item *item);
288 void sendRemoveContainerItem(uint8_t cid, uint16_t slot,
289 const Item *lastItem);
290
291 void sendContainer(uint8_t cid, const Container *container, bool hasParent,
292 uint16_t firstIndex);
293 void sendCloseContainer(uint8_t cid);
294
295 // inventory
296 void sendInventoryItem(slots_t slot, const Item *item);
297 void sendItems();
298
299 // messages
300 void sendModalWindow(const ModalWindow &modalWindow);
301
302 // Help functions
303
304 // translate a tile to clientreadable format
305 void GetTileDescription(const Tile *tile, NetworkMessage &msg);
306
307 // translate a floor to clientreadable format
308 void GetFloorDescription(NetworkMessage &msg, int32_t x, int32_t y, int32_t z,
309 int32_t width, int32_t height, int32_t offset,
310 int32_t &skip);
311
312 // translate a map area to clientreadable format
313 void GetMapDescription(int32_t x, int32_t y, int32_t z, int32_t width,
314 int32_t height, NetworkMessage &msg);
315
316 void AddCreature(NetworkMessage &msg, const Creature *creature, bool known,
317 uint32_t remove);
318 void AddPlayerStats(NetworkMessage &msg);
319 void AddOutfit(NetworkMessage &msg, const Outfit_t &outfit,
320 uint16_t lookAttack = 0);
321 void AddPlayerSkills(NetworkMessage &msg);
322 void AddWorldLight(NetworkMessage &msg, LightInfo lightInfo);
323 void AddCreatureLight(NetworkMessage &msg, const Creature *creature);
324
325 // tiles
326 static void RemoveTileThing(NetworkMessage &msg, const Position &pos,
327 uint32_t stackpos);
328
329 void MoveUpCreature(NetworkMessage &msg, const Creature *creature,
330 const Position &newPos, const Position &oldPos);
331 void MoveDownCreature(NetworkMessage &msg, const Creature *creature,
332 const Position &newPos, const Position &oldPos);
333
334 // shop
335 void AddShopItem(NetworkMessage &msg, const ShopInfo &item);
336
337 // otclient
338 void parseExtendedOpcode(NetworkMessage &msg);
339
340 // OTCv8
341 void sendFeatures();
342
343 void sendFloorDescription(const Position &pos, int floor);
344 void parseChangeAwareRange(NetworkMessage &msg);
345 void updateAwareRange(int width, int height);
346 void sendAwareRange();
347
348 void parseNewWalking(NetworkMessage &msg);
349 void checkPredictiveWalking(const Position &pos);
350 void sendPredictiveCancel(const Position &pos, int value);
351 void sendWalkId();
352 void sendNewCancelWalk();
353
354 void parseNewPing(NetworkMessage &msg);
355 void sendNewPing(uint32_t pingId);
356
357 void sendEffect(uint16_t effectId);
358
359 void parseMagicEffect(const std::shared_ptr<InputMessage> &msg);
360
361 friend class Player;
362
363 // Helpers so we don't need to bind every time
364 template <typename Callable, typename... Args>
365 void addGameTask(Callable function, Args &&...args) {
366 g_dispatcher.addTask(
367 createTask(std::bind(function, &g_game, std::forward<Args>(args)...)));
368 }
369
370 template <typename Callable, typename... Args>
371 void addGameTaskTimed(uint32_t delay, Callable function, Args &&...args) {
372 g_dispatcher.addTask(createTask(
373 delay, std::bind(function, &g_game, std::forward<Args>(args)...)));
374 }
375
376 std::unordered_set<uint32_t> knownCreatureSet;
377 Player *player = nullptr;
378
379 uint32_t eventConnect = 0;
380 uint32_t challengeTimestamp = 0;
381 uint16_t version = CLIENT_VERSION_MIN;
382
383 uint8_t challengeRandom = 0;
384
385 bool debugAssertSent = false;
386 bool acceptPackets = false;
387
388 uint16_t otclientV8 = 0;
389 struct AwareRange {
390 int width = 17;
391 int height = 13;
392
393 int left() const { return width / 2; }
394 int right() const { return 1 + width / 2; }
395 int top() const { return height / 2; }
396 int bottom() const { return 1 + height / 2; }
397 int horizontal() const { return width + 1; }
398 int vertical() const { return height + 1; }
399 } awareRange;
400
401 uint32_t walkId = 0;
402 WalkMatrix walkMatrix;
403};
404
405#endif
406