ManaPlus
vendingrecv.cpp
Go to the documentation of this file.
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 
23 
24 #include "actormanager.h"
25 #include "itemcolormanager.h"
26 #include "notifymanager.h"
27 
29 
30 #include "being/localplayer.h"
31 #include "being/playerinfo.h"
32 
33 #include "const/net/inventory.h"
34 
36 
37 #include "gui/windows/buydialog.h"
38 
40 
43 
44 #include "net/messagein.h"
45 
46 #include "resources/iteminfo.h"
47 
48 #include "resources/db/unitsdb.h"
49 
51 
54 
55 #include "utils/gettext.h"
56 #include "utils/stringutils.h"
57 
58 #include "debug.h"
59 
60 extern int packetVersion;
61 extern int serverVersion;
62 extern int itemIdLen;
63 
64 namespace EAthena
65 {
66 
67 namespace VendingRecv
68 {
69  BuyDialog *mBuyDialog = nullptr;
70 } // namespace VendingRecv
71 
73 {
74  VendingSlotsListener::distributeEvent(msg.readInt16("slots allowed"));
75 }
76 
78 {
79  if (actorManager == nullptr)
80  return;
81  const BeingId id = msg.readBeingId("owner id");
82  Being *const dstBeing = actorManager->findBeing(id);
83  if (dstBeing != nullptr)
84  {
85  dstBeing->setSellBoard(msg.readString(80, "shop name"));
86  }
87  else
88  {
89  msg.readString(80, "shop name");
90  }
91 }
92 
94 {
95  if (actorManager == nullptr)
96  return;
97  const BeingId id = msg.readBeingId("owner id");
98  Being *const dstBeing = actorManager->findBeing(id);
99  if (dstBeing != nullptr)
100  dstBeing->setSellBoard(std::string());
101  if (dstBeing == localPlayer)
102  {
105  }
106 }
107 
109 {
110  if (actorManager == nullptr)
111  return;
112  int packetLen = 22;
113  if (msg.getVersion() >= 20160921)
114  packetLen = 53;
115  else if (msg.getVersion() >= 20150226)
116  packetLen = 47;
117  if (itemIdLen == 4)
118  packetLen += 10;
119  int offset = 8;
120  if (msg.getVersion() >= 20100105)
121  offset += 4;
122 
123  const int count = (msg.readInt16("len") - offset) / packetLen;
124  const BeingId id = msg.readBeingId("id");
125  const Being *const being = actorManager->findBeing(id);
126  if (being == nullptr)
127  return;
128  int cards[maxCards];
131  if (msg.getVersion() >= 20100105)
132  msg.readInt32("vender id");
133  for (int f = 0; f < count; f ++)
134  {
135  const int value = msg.readInt32("price");
136  const int amount = msg.readInt16("amount");
137  const int index = msg.readInt16("inv index");
138  const ItemTypeT type = static_cast<ItemTypeT>(
139  msg.readUInt8("item type"));
140  const int itemId = msg.readItemId("item id");
141  msg.readUInt8("identify");
142  msg.readUInt8("attribute");
143  msg.readUInt8("refine");
144  for (int d = 0; d < maxCards; d ++)
145  cards[d] = msg.readItemId("card");
146  ItemOptionsList *options = nullptr;
147  if (msg.getVersion() >= 20150226)
148  {
149  options = new ItemOptionsList;
150  for (int d = 0; d < 5; d ++)
151  {
152  const uint16_t idx = msg.readInt16("option index");
153  const uint16_t val = msg.readInt16("option value");
154  msg.readUInt8("option param");
155  options->add(idx, val);
156  }
157  }
158  if (msg.getVersion() >= 20160921)
159  {
160  msg.readInt32("equip type?");
161  msg.readInt16("look");
162  }
163 
164  const ItemColor color = ItemColorManager::getColorFromCards(&cards[0]);
165  ShopItem *const item = mBuyDialog->addItem(itemId, type,
166  color, amount, value);
167  if (item != nullptr)
168  {
169  item->setInvIndex(index);
170  item->setOptions(options);
171  }
172  delete options;
173  }
174  mBuyDialog->sort();
175 }
176 
178 {
179  msg.readInt16("inv index");
180  msg.readInt16("amount");
181  const int flag = msg.readUInt8("flag");
182  switch (flag)
183  {
184  case 0:
185  break;
186  case 1:
188  break;
189  case 2:
191  break;
192  case 4:
194  break;
195  case 5:
197  break;
198  case 6: // +++ probably need show exact error messages?
199  case 7:
201  break;
202  default:
205  break;
206  }
207 }
208 
210 {
211  int packetLen = 22;
212  if (msg.getVersion() >= 20150226)
213  packetLen += 25;
214  if (itemIdLen == 4)
215  packetLen += 10;
216 
217  const int count = (msg.readInt16("len") - 8) / packetLen;
218  msg.readInt32("id");
219  for (int f = 0; f < count; f ++)
220  {
221  msg.readInt32("price");
222  msg.readInt16("inv index");
223  msg.readInt16("amount");
224  msg.readUInt8("item type");
225  msg.readItemId("item id");
226  msg.readUInt8("identify");
227  msg.readUInt8("attribute");
228  msg.readUInt8("refine");
229  for (int d = 0; d < maxCards; d ++)
230  msg.readItemId("card");
231  if (msg.getVersion() >= 20150226)
232  {
233  for (int d = 0; d < 5; d ++)
234  {
235  msg.readInt16("option index");
236  msg.readInt16("option value");
237  msg.readUInt8("option param");
238  }
239  }
240  }
243 }
244 
246 {
247  const int index = msg.readInt16("inv index") - INVENTORY_OFFSET;
248  const int amount = msg.readInt16("amount");
249  int money = 0;
250  if (msg.getVersion() >= 20141016)
251  {
252  msg.readInt32("char id");
253  msg.readInt32("time");
254  money = msg.readInt32("zeny");
255  }
256  const Inventory *const inventory = PlayerInfo::getCartInventory();
257  if (inventory == nullptr)
258  return;
259  const Item *const item = inventory->getItem(index);
260  if (item == nullptr)
261  return;
262 
263  const ItemInfo &info = item->getInfo();
264  std::string str;
265  if (money != 0)
266  {
267  // TRANSLATORS: vending sold item message
268  str = strprintf(_("Sold item %s amount %d. You got: %s"),
269  info.getLink().c_str(),
270  amount,
271  UnitsDb::formatCurrency(money).c_str());
272  }
273  else
274  {
275  // TRANSLATORS: vending sold item message
276  str = strprintf(_("Sold item %s amount %d"),
277  info.getLink().c_str(),
278  amount);
279  }
281 }
282 
284 {
286  msg.readUInt8("result");
287 }
288 
289 } // namespace EAthena
ActorManager * actorManager
int BeingId
Definition: beingid.h:30
#define maxCards
Definition: cards.h:25
Being * findBeing(const BeingId id) const
Definition: being.h:96
void setSellBoard(const std::string &text)
Definition: being.cpp:5328
void sort()
Definition: buydialog.cpp:472
ShopItem * addItem(const int id, const ItemTypeT type, const ItemColor color, const int amount, const int price)
Definition: buydialog.cpp:457
void setMoney(const int amount)
Definition: buydialog.cpp:437
Item * getItem(const int index) const
Definition: inventory.cpp:83
static ItemColor getColorFromCards(const int *const cards)
Definition: item.h:50
void setInvIndex(const int index)
Definition: item.h:159
void setOptions(const ItemOptionsList *const options)
Definition: item.cpp:189
const ItemInfo & getInfo() const
Definition: item.h:171
static void distributeEvent(const bool b)
static void distributeEvent(const int slots)
static const int INVENTORY_OFFSET
Definition: inventory.h:27
#define CREATEWIDGETV(var, type,...)
Definition: createwidget.h:25
const std::string DEFAULT_CURRENCY
Definition: currency.h:27
#define _(s)
Definition: gettext.h:35
uint16_t ItemColor
Definition: itemcolor.h:30
ItemType ::T ItemTypeT
Definition: itemtype.h:43
LocalPlayer * localPlayer
#define UNIMPLEMENTEDPACKETFIELD(field)
Definition: logger.h:59
#define UNIMPLEMENTEDPACKET
Definition: logger.h:56
bool msg(InputEvent &event)
Definition: chat.cpp:39
bool info(InputEvent &event)
Definition: commands.cpp:57
void processOpen(Net::MessageIn &msg)
void processOpenStatus(Net::MessageIn &msg)
void processShowBoard(Net::MessageIn &msg)
Definition: vendingrecv.cpp:77
void processItemsList(Net::MessageIn &msg)
void processHideBoard(Net::MessageIn &msg)
Definition: vendingrecv.cpp:93
void processOpenReq(Net::MessageIn &msg)
Definition: vendingrecv.cpp:72
BuyDialog * mBuyDialog
Definition: vendingrecv.cpp:69
void processReport(Net::MessageIn &msg)
void processBuyAck(Net::MessageIn &msg)
void notify(const unsigned int message)
@ BUY_FAILED_NO_MONEY
Definition: notifytypes.h:34
@ BUY_FAILED_TOO_MANY_ITEMS
Definition: notifytypes.h:36
@ BUY_FAILED_OVERWEIGHT
Definition: notifytypes.h:35
void enableVending(const bool b)
Definition: playerinfo.cpp:658
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:102
Inventory * getCartInventory()
Definition: playerinfo.cpp:207
std::string formatCurrency(const int value)
Definition: unitsdb.cpp:324
std::string strprintf(const char *const format,...)
void add(const uint16_t index, const uint16_t value)
int serverVersion
Definition: client.cpp:124
int itemIdLen
Definition: client.cpp:130
int packetVersion
Definition: client.cpp:125