00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "net/ea/charserverhandler.h"
00023
00024 #include "net/ea/network.h"
00025 #include "net/ea/protocol.h"
00026
00027 #include "net/messagein.h"
00028 #include "net/messageout.h"
00029
00030 #include "game.h"
00031 #include "log.h"
00032 #include "logindata.h"
00033 #include "main.h"
00034
00035 #include "gui/charcreatedialog.h"
00036 #include "gui/ok_dialog.h"
00037
00038 #include "utils/gettext.h"
00039 #include "utils/stringutils.h"
00040
00041 Net::CharHandler *charHandler;
00042
00043 namespace EAthena {
00044
00045 CharServerHandler::CharServerHandler():
00046 mCharCreateDialog(0)
00047 {
00048 static const Uint16 _messages[] = {
00049 SMSG_CHAR_LOGIN,
00050 SMSG_CHAR_LOGIN_ERROR,
00051 SMSG_CHAR_CREATE_SUCCEEDED,
00052 SMSG_CHAR_CREATE_FAILED,
00053 SMSG_CHAR_DELETE_SUCCEEDED,
00054 SMSG_CHAR_DELETE_FAILED,
00055 SMSG_CHAR_MAP_INFO,
00056 0
00057 };
00058 handledMessages = _messages;
00059 charHandler = this;
00060 }
00061
00062 void CharServerHandler::handleMessage(MessageIn &msg)
00063 {
00064 int slot, flags;
00065 LocalPlayer *tempPlayer;
00066
00067 logger->log("CharServerHandler: Packet ID: %x, Length: %d",
00068 msg.getId(), msg.getLength());
00069 switch (msg.getId())
00070 {
00071 case 0x006b:
00072 msg.skip(2);
00073 flags = msg.readInt32();
00074 logger->log("Server flags are: %x", flags);
00075 msg.skip(16);
00076
00077
00078 n_character = (msg.getLength() - 24) / 106;
00079
00080 for (int i = 0; i < n_character; i++)
00081 {
00082 tempPlayer = readPlayerData(msg, slot);
00083 mCharInfo->select(slot);
00084 mCharInfo->setEntry(tempPlayer);
00085 logger->log("CharServer: Player: %s (%d)",
00086 tempPlayer->getName().c_str(), slot);
00087 }
00088
00089 state = STATE_CHAR_SELECT;
00090 break;
00091
00092 case SMSG_CHAR_LOGIN_ERROR:
00093 switch (msg.readInt8()) {
00094 case 0:
00095 errorMessage = _("Access denied");
00096 break;
00097 case 1:
00098 errorMessage = _("Cannot use this ID");
00099 break;
00100 default:
00101 errorMessage = _("Unknown failure to select character");
00102 break;
00103 }
00104 mCharInfo->unlock();
00105 break;
00106
00107 case SMSG_CHAR_CREATE_SUCCEEDED:
00108 tempPlayer = readPlayerData(msg, slot);
00109 mCharInfo->unlock();
00110 mCharInfo->select(slot);
00111 mCharInfo->setEntry(tempPlayer);
00112 n_character++;
00113
00114
00115 if (mCharCreateDialog)
00116 {
00117 mCharCreateDialog->scheduleDelete();
00118 mCharCreateDialog = 0;
00119 }
00120 break;
00121
00122 case SMSG_CHAR_CREATE_FAILED:
00123 new OkDialog(_("Error"), _("Failed to create character. Most likely"
00124 " the name is already taken."));
00125
00126 if (mCharCreateDialog)
00127 mCharCreateDialog->unlock();
00128 break;
00129
00130 case SMSG_CHAR_DELETE_SUCCEEDED:
00131 delete mCharInfo->getEntry();
00132 mCharInfo->setEntry(0);
00133 mCharInfo->unlock();
00134 n_character--;
00135 new OkDialog(_("Info"), _("Player deleted"));
00136 break;
00137
00138 case SMSG_CHAR_DELETE_FAILED:
00139 mCharInfo->unlock();
00140 new OkDialog(_("Error"), _("Failed to delete character."));
00141 break;
00142
00143 case SMSG_CHAR_MAP_INFO:
00144 player_node = mCharInfo->getEntry();
00145 slot = mCharInfo->getPos();
00146 msg.skip(4);
00147 map_path = msg.readString(16);
00148 mLoginData->hostname = ipToString(msg.readInt32());
00149 mLoginData->port = msg.readInt16();
00150 mCharInfo->unlock();
00151 mCharInfo->select(0);
00152
00153 do
00154 {
00155 LocalPlayer *tmp = mCharInfo->getEntry();
00156 if (tmp != player_node)
00157 {
00158 delete tmp;
00159 mCharInfo->setEntry(0);
00160 }
00161 mCharInfo->next();
00162 } while (mCharInfo->getPos());
00163
00164 mCharInfo->select(slot);
00165 state = STATE_CONNECTING;
00166 break;
00167 }
00168 }
00169
00170 LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
00171 {
00172 LocalPlayer *tempPlayer = new LocalPlayer(mLoginData->account_ID, 0, NULL);
00173 tempPlayer->setGender(mLoginData->sex);
00174
00175 tempPlayer->mCharId = msg.readInt32();
00176 tempPlayer->setXp(msg.readInt32());
00177 tempPlayer->setMoney(msg.readInt32());
00178 tempPlayer->mJobXp = msg.readInt32();
00179 tempPlayer->mJobLevel = msg.readInt32();
00180 tempPlayer->setSprite(Being::SHOE_SPRITE, msg.readInt16());
00181 tempPlayer->setSprite(Being::GLOVES_SPRITE, msg.readInt16());
00182 tempPlayer->setSprite(Being::CAPE_SPRITE, msg.readInt16());
00183 tempPlayer->setSprite(Being::MISC1_SPRITE, msg.readInt16());
00184 msg.readInt32();
00185 msg.readInt32();
00186 msg.readInt32();
00187 msg.skip(2);
00188 tempPlayer->setHp(msg.readInt16());
00189 tempPlayer->setMaxHp(msg.readInt16());
00190 tempPlayer->mMp = msg.readInt16();
00191 tempPlayer->mMaxMp = msg.readInt16();
00192 msg.readInt16();
00193 msg.readInt16();
00194 int hairStyle = msg.readInt16();
00195 Uint16 weapon = msg.readInt16();
00196 tempPlayer->setSprite(Being::WEAPON_SPRITE, weapon);
00197 tempPlayer->setLevel(msg.readInt16());
00198 msg.readInt16();
00199 tempPlayer->setSprite(Being::BOTTOMCLOTHES_SPRITE, msg.readInt16());
00200 tempPlayer->setSprite(Being::SHIELD_SPRITE, msg.readInt16());
00201 tempPlayer->setSprite(Being::HAT_SPRITE, msg.readInt16());
00202 tempPlayer->setSprite(Being::TOPCLOTHES_SPRITE, msg.readInt16());
00203 int hairColor = msg.readInt16();
00204 tempPlayer->setHairStyle(hairStyle, hairColor);
00205 tempPlayer->setSprite(Being::MISC2_SPRITE, msg.readInt16());
00206 tempPlayer->setName(msg.readString(24));
00207 for (int i = 0; i < 6; i++) {
00208 tempPlayer->mAttr[i] = msg.readInt8();
00209 }
00210 slot = msg.readInt8();
00211 msg.readInt8();
00212
00213 return tempPlayer;
00214 }
00215
00216 void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
00217 {
00218 mCharCreateDialog = window;
00219
00220 if (!mCharCreateDialog)
00221 return;
00222
00223 std::vector<std::string> attributes;
00224 attributes.push_back(_("Strength:"));
00225 attributes.push_back(_("Agility:"));
00226 attributes.push_back(_("Vitality:"));
00227 attributes.push_back(_("Intelligence:"));
00228 attributes.push_back(_("Dexterity:"));
00229 attributes.push_back(_("Luck:"));
00230
00231 mCharCreateDialog->setAttributes(attributes, 30, 1, 9);
00232 mCharCreateDialog->setFixedGender(true, mLoginData->sex);
00233 }
00234
00235 void CharServerHandler::connect(LoginData *loginData)
00236 {
00237 mLoginData = loginData;
00238
00239 MessageOut outMsg(CMSG_CHAR_SERVER_CONNECT);
00240 outMsg.writeInt32(loginData->account_ID);
00241 outMsg.writeInt32(loginData->session_ID1);
00242 outMsg.writeInt32(loginData->session_ID2);
00243
00244
00245 outMsg.writeInt16(CLIENT_PROTOCOL_VERSION);
00246 outMsg.writeInt8((loginData->sex == GENDER_MALE) ? 1 : 0);
00247
00248
00249 mNetwork->skip(4);
00250 }
00251
00252 void CharServerHandler::chooseCharacter(int slot, LocalPlayer* character)
00253 {
00254 MessageOut outMsg(CMSG_CHAR_SELECT);
00255 outMsg.writeInt8(slot);
00256 }
00257
00258 void CharServerHandler::newCharacter(const std::string &name, int slot,
00259 bool gender, int hairstyle, int hairColor, std::vector<int> stats)
00260 {
00261 MessageOut outMsg(CMSG_CHAR_CREATE);
00262 outMsg.writeString(name, 24);
00263 for (int i = 0; i < 6; i++)
00264 {
00265 outMsg.writeInt8(stats[i]);
00266 }
00267 outMsg.writeInt8(slot);
00268 outMsg.writeInt16(hairColor);
00269 outMsg.writeInt16(hairstyle);
00270 }
00271
00272 void CharServerHandler::deleteCharacter(int slot, LocalPlayer* character)
00273 {
00274 MessageOut outMsg(CMSG_CHAR_DELETE);
00275 outMsg.writeInt32(character->mCharId);
00276 outMsg.writeString("a@a.com", 40);
00277 }
00278
00279 }