ManaPlus
charserverrecv.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
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 
24 
25 #include "client.h"
26 #include "configuration.h"
27 #include "settings.h"
28 
30 #include "gui/windows/okdialog.h"
31 
33 
34 #include "net/character.h"
35 #include "net/charserverhandler.h"
36 #include "net/messagein.h"
37 #include "net/serverfeatures.h"
38 
39 #include "net/ea/token.h"
40 
41 #include "net/tmwa/gamehandler.h"
42 #include "net/tmwa/loginhandler.h"
43 #include "net/tmwa/network.h"
44 #include "net/tmwa/sprite.h"
45 
46 #include "resources/iteminfo.h"
47 
48 #include "resources/db/itemdb.h"
49 
50 #include "utils/dtor.h"
51 #include "utils/gettext.h"
52 
53 #include "debug.h"
54 
55 namespace TmwAthena
56 {
57 
59 
61 
63  Net::Character *const character)
64 {
65  if (character == nullptr)
66  return;
67 
68  const Token &token =
69  static_cast<LoginHandler*>(loginHandler)->getToken();
70 
71  LocalPlayer *const tempPlayer = new LocalPlayer(
72  msg.readBeingId("account id"), BeingTypeId_zero);
73 
74  PlayerInfoBackend &data = character->data;
75  data.mAttributes[Attributes::PLAYER_EXP] = msg.readInt32("base exp");
76  data.mAttributes[Attributes::MONEY] = msg.readInt32("money");
77  data.mAttributes[Attributes::PLAYER_JOB_EXP] = msg.readInt32("job exp");
78  data.mAttributes[Attributes::PLAYER_JOB_LEVEL] =
79  msg.readInt32("job level");
80 
81  const int shoes = msg.readInt16("shoes");
82  const int gloves = msg.readInt16("gloves");
83  const int cape = msg.readInt16("cape");
84  const int misc1 = msg.readInt16("misc1");
85 
86  msg.readInt32("option");
87  tempPlayer->setKarma(msg.readInt32("karma"));
88  tempPlayer->setManner(msg.readInt32("manner"));
89  msg.readInt16("character points left");
90 
91  data.mAttributes[Attributes::PLAYER_HP] = msg.readInt16("hp");
92  data.mAttributes[Attributes::PLAYER_MAX_HP] = msg.readInt16("max hp");
93  data.mAttributes[Attributes::PLAYER_MP] = msg.readInt16("mp");
94  data.mAttributes[Attributes::PLAYER_MAX_MP] = msg.readInt16("max mp");
95 
96  msg.readInt16("speed");
97  const uint16_t race = msg.readInt16("class");
98  const uint8_t hairStyle = msg.readUInt8("hair style");
99  const uint16_t look = msg.readUInt8("look");
100  tempPlayer->setSubtype(fromInt(race, BeingTypeId), look);
101  const uint16_t weapon = msg.readInt16("weapon");
102  tempPlayer->setSpriteId(SPRITE_BODY,
103  weapon);
104  tempPlayer->setWeaponId(weapon);
105 
106  data.mAttributes[Attributes::PLAYER_BASE_LEVEL] = msg.readInt16("level");
107 
108  msg.readInt16("skill point");
109  const int bottomClothes = msg.readInt16("bottom clothes");
110  const int shield = msg.readInt16("shield");
111 
112  const int hat = msg.readInt16("hat");
113  const int topClothes = msg.readInt16("top clothes");
114 
115  const ItemColor hairColor = fromInt(
116  msg.readUInt8("hair color"), ItemColor);
117  msg.readUInt8("unused");
118  if (hairStyle == 0)
119  {
120  tempPlayer->unSetSprite(SPRITE_HAIR_COLOR);
121  }
122  else
123  {
124  tempPlayer->setSpriteColor(SPRITE_HAIR_COLOR,
125  hairStyle * -1,
126  ItemDB::get(-hairStyle).getDyeColorsString(hairColor));
127  }
128  tempPlayer->setHairColor(hairColor);
129 
130  const int misc2 = msg.readInt16("misc2");
131  tempPlayer->setName(msg.readString(24, "name"));
132 
133  character->dummy = tempPlayer;
134 
135  character->data.mStats[Attributes::PLAYER_STR].base = msg.readUInt8("str");
136  character->data.mStats[Attributes::PLAYER_AGI].base = msg.readUInt8("agi");
137  character->data.mStats[Attributes::PLAYER_VIT].base = msg.readUInt8("vit");
138  character->data.mStats[Attributes::PLAYER_INT].base = msg.readUInt8("int");
139  character->data.mStats[Attributes::PLAYER_DEX].base = msg.readUInt8("dex");
140  character->data.mStats[Attributes::PLAYER_LUK].base = msg.readUInt8("luk");
141 
142  tempPlayer->setSpriteId(SPRITE_HAIR,
143  shoes);
144  tempPlayer->setSpriteId(SPRITE_SHOES,
145  gloves);
146  tempPlayer->setSpriteId(SPRITE_SHIELD,
147  cape);
148  tempPlayer->setSpriteId(SPRITE_HEAD_TOP,
149  misc1);
150  tempPlayer->setSpriteId(SPRITE_WEAPON,
151  bottomClothes);
152  tempPlayer->setSpriteId(SPRITE_FLOOR,
153  shield);
154  tempPlayer->setSpriteId(SPRITE_CLOTHES_COLOR,
155  hat);
156  tempPlayer->setSpriteId(SPRITE_HEAD_BOTTOM,
157  topClothes);
158  tempPlayer->setSpriteId(SPRITE_HEAD_MID,
159  misc2);
160 
161  character->slot = msg.readUInt8("slot");
162  const uint8_t sex = CAST_U8(msg.readUInt8("gender"));
164  tempPlayer->setGender(Being::intToGender(sex));
165  else
166  tempPlayer->setGender(token.sex);
167 }
168 
170 {
171  BLOCK_START("CharServerRecv::processCharLogin")
172 
173  msg.readInt16("len");
174  const int slots = msg.readInt16("slots");
175  if (slots > 0 && slots < 30)
177 
178  msg.skip(18, "unused");
179 
182 
183  // Derive number of characters from message length
184  const int count = (msg.getLength() - 24) / 106;
185 
186  for (int i = 0; i < count; ++i)
187  {
188  Net::Character *const character = new Net::Character;
189  readPlayerData(msg, character);
190  Net::CharServerHandler::mCharacters.push_back(character);
191  if (character->dummy != nullptr)
192  {
193  logger->log("CharServer: Player: %s (%d)",
194  character->dummy->getName().c_str(), character->slot);
195  }
196  }
197 
199  BLOCK_END("CharServerRecv::processCharLogin")
200 }
201 
203 {
204  Network *const network = Network::mInstance;
205  ServerInfo &server = mapServer;
206  BLOCK_START("CharServerRecv::processCharMapInfo")
207  PlayerInfo::setCharId(msg.readInt32("char id?"));
208  GameHandler::setMap(msg.readString(16, "map name"));
209  if (config.getBoolValue("usePersistentIP") || settings.persistentIp)
210  {
211  msg.readInt32("ip address");
212  server.hostname = settings.serverName;
213  }
214  else
215  {
216  server.hostname = ipToString(msg.readInt32("ip address"));
217  }
218  server.port = msg.readInt16("port");
219 
220  // Prevent the selected local player from being deleted
223 
225 
228 
229  if (network != nullptr)
230  network->disconnect();
232  BLOCK_END("CharServerRecv::processCharMapInfo")
233 }
234 
236 {
237  Network *const network = Network::mInstance;
238  ServerInfo &server = mapServer;
239  BLOCK_START("CharServerRecv::processChangeMapServer")
240  if (network == nullptr)
241  {
242  BLOCK_END("CharServerRecv::processChangeMapServer")
243  return;
244  }
245  GameHandler::setMap(msg.readString(16, "map name"));
246  const int x = msg.readInt16("x");
247  const int y = msg.readInt16("y");
248  if (config.getBoolValue("usePersistentIP") || settings.persistentIp)
249  {
250  msg.readInt32("ip address");
251  server.hostname = settings.serverName;
252  }
253  else
254  {
255  server.hostname = ipToString(msg.readInt32("ip address"));
256  }
257  server.port = msg.readInt16("port");
258 
259  network->disconnect();
261  if (localPlayer != nullptr)
262  {
263  localPlayer->setTileCoords(x, y);
264  localPlayer->setMap(nullptr);
265  }
266  BLOCK_END("CharServerRecv::processChangeMapServer")
267 }
268 
270 {
271  BLOCK_START("CharServerRecv::processCharCreate")
272  Net::Character *const character = new Net::Character;
273  readPlayerData(msg, character);
274  Net::CharServerHandler::mCharacters.push_back(character);
275 
277 
278  // Close the character create dialog
281  BLOCK_END("CharServerRecv::processCharCreate")
282 }
283 
285 {
286  BLOCK_START("CharServerRecv::processCharDeleteFailed")
288  msg.readUInt8("error");
290  // TRANSLATORS: error header
291  _("Error"),
292  // TRANSLATORS: error message
293  _("Failed to delete character."),
294  // TRANSLATORS: ok dialog button
295  _("OK"),
297  Modal_true,
299  nullptr,
300  260);
301  BLOCK_END("CharServerRecv::processCharDeleteFailed")
302 }
303 
304 } // namespace TmwAthena
uint16_t characterSlots
Definition: logindata.h:76
unsigned char readUInt8(const char *const str)
Definition: messagein.cpp:103
#define _(s)
Definition: gettext.h:34
const ItemInfo & get(const int id)
Definition: itemdb.cpp:792
#define CAST_U8
Definition: cast.h:26
std::string serverName
Definition: settings.h:112
BeingId readBeingId(const char *const str)
Definition: messagein.cpp:223
void setState(const StateT state)
Definition: client.h:65
LoginData loginData
Definition: client.cpp:184
std::string hostname
Definition: serverinfo.h:44
static Network * mInstance
Definition: network.h:53
void setTileCoords(const int x, const int y)
Definition: being.cpp:5010
#define fromInt(val, name)
Definition: intdefines.h:45
void setMap(Map *const map)
bool persistentIp
Definition: settings.h:150
void processCharLogin(Net::MessageIn &msg)
static void setMap(const std::string &map)
Definition: gamehandler.cpp:45
ServerInfo mapServer
unsigned int getLength() const
Definition: messagein.h:58
#define BLOCK_START(name)
Definition: perfomance.h:78
Configuration config
void processCharCreate(Net::MessageIn &msg)
virtual void setGender(const GenderT gender)
Definition: being.cpp:3581
const BeingTypeId BeingTypeId_zero
Definition: beingtypeid.h:29
ServerInfo charServer
void processCharMapInfo(Net::MessageIn &msg)
#define BLOCK_END(name)
Definition: perfomance.h:79
uint16_t ItemColor
Definition: itemcolor.h:29
bool msg(InputEvent &event)
Definition: chat.cpp:38
Client * client
Definition: client.cpp:117
static CharCreateDialog * mCharCreateDialog
void setCharId(const int charId)
Definition: playerinfo.cpp:379
static GenderT intToGender(const uint8_t sex) A_CONST
Definition: being.h:942
Definition: token.h:29
virtual void clear() const =0
void setSpriteColor(const unsigned int slot, const int id, const std::string &color)
Definition: being.cpp:2890
Logger * logger
Definition: logger.cpp:88
GenderT sex
Definition: token.h:43
Settings settings
Definition: settings.cpp:31
int16_t readInt16(const char *const str)
Definition: messagein.cpp:130
#define CAST_U16
Definition: cast.h:28
Net::ServerFeatures * serverFeatures
Definition: net.cpp:98
bool getBoolValue(const std::string &key) const
void delete_all(Container &c)
Definition: dtor.h:55
uint16_t slot
Definition: character.h:57
Net::LoginHandler * loginHandler
Definition: net.cpp:87
void processChangeMapServer(Net::MessageIn &msg)
uint32_t data
LocalPlayer * localPlayer
void skip(const unsigned int length, const char *const str)
Definition: messagein.cpp:349
uint16_t port
Definition: serverinfo.h:57
void disconnect()
Definition: network.cpp:138
AtrIntMap mAttributes
Definition: playerinfo.h:72
const bool ShowCenter_true
Definition: showcenter.h:29
bool hat(InputEvent &event)
Definition: chat.cpp:61
const char * ipToString(const uint32_t address)
Definition: stringutils.cpp:85
void setSpriteId(const unsigned int slot, const int id)
Definition: being.cpp:2789
void setManner(const int manner)
Definition: being.h:1040
const std::string & getName() const
Definition: being.h:231
virtual void scheduleDelete()
Definition: window.cpp:830
void processCharDeleteFailed(Net::MessageIn &msg)
void setSubtype(const BeingTypeId subtype, const uint16_t look)
Definition: being.cpp:370
void setKarma(const int karma)
Definition: being.h:1034
#define CREATEWIDGET(type,...)
Definition: createwidget.h:28
void readPlayerData(Net::MessageIn &msg, Net::Character *const character)
static void updateCharSelectDialog()
void setName(const std::string &name)
Definition: being.cpp:1135
static Net::Characters mCharacters
static Net::Character * mSelectedCharacter
#define restrict
Definition: localconsts.h:164
std::string readString(int length, const char *const dstr)
Definition: messagein.cpp:367
void setBackend(const PlayerInfoBackend &backend)
Definition: playerinfo.cpp:374
PlayerInfoBackend data
Definition: character.h:56
void setHairColor(const unsigned int slot, const ItemColor color)
Definition: being.cpp:3389
void log(const char *const log_text,...)
Definition: logger.cpp:264
virtual bool haveCreateCharGender() const =0
int32_t readInt32(const char *const str)
Definition: messagein.cpp:174
int BeingTypeId
Definition: beingtypeid.h:29
Net::CharServerHandler * charServerHandler
Definition: net.cpp:82
void setWeaponId(const int id)
Definition: being.cpp:3135
LocalPlayer * dummy
Definition: character.h:55
void unSetSprite(const unsigned int slot)
Definition: being.cpp:2861
static void unlockCharSelectDialog()
void readPlayerData(Net::MessageIn &msg, Net::Character *const character)