00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "account-server/accounthandler.hpp"
00025
00026 #include "defines.h"
00027 #include "configuration.h"
00028 #include "point.h"
00029 #include "account-server/account.hpp"
00030 #include "account-server/accountclient.hpp"
00031 #include "account-server/characterdata.hpp"
00032 #include "account-server/serverhandler.hpp"
00033 #include "account-server/storage.hpp"
00034 #include "chat-server/chathandler.hpp"
00035 #include "net/connectionhandler.hpp"
00036 #include "net/messagein.hpp"
00037 #include "net/messageout.hpp"
00038 #include "net/netcomputer.hpp"
00039 #include "utils/logger.h"
00040 #include "utils/stringfilter.h"
00041 #include "utils/tokencollector.hpp"
00042 #include "utils/tokendispenser.hpp"
00043
00044 AccountHandler::AccountHandler():
00045 mTokenCollector(this)
00046 {
00047 }
00048
00049 bool
00050 AccountHandler::startListen(enet_uint16 port)
00051 {
00052 LOG_INFO("Account handler started:");
00053 return ConnectionHandler::startListen(port);
00054 }
00055
00056 NetComputer*
00057 AccountHandler::computerConnected(ENetPeer *peer)
00058 {
00059 return new AccountClient(peer);
00060 }
00061
00062 void
00063 AccountHandler::computerDisconnected(NetComputer *comp)
00064 {
00065 AccountClient* computer = static_cast< AccountClient * >(comp);
00066
00067 if (computer->status == CLIENT_QUEUED)
00068
00069 mTokenCollector.deletePendingClient(computer);
00070
00071 delete computer;
00072 }
00073
00079 void
00080 AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
00081 {
00082 AccountClient &computer = *static_cast< AccountClient * >(comp);
00083
00084 Storage &store = Storage::instance("tmw");
00085
00086 #if defined (SQLITE_SUPPORT)
00087
00088
00089 store.setUser(config.getValue("dbuser", ""));
00090 store.setPassword(config.getValue("dbpass", ""));
00091 store.close();
00092 store.open();
00093 #endif
00094
00095 switch (message.getId())
00096 {
00097 case PAMSG_LOGIN:
00098 LOG_DEBUG("Received msg ... PAMSG_LOGIN");
00099 handleLoginMessage(computer, message);
00100 break;
00101
00102 case PAMSG_LOGOUT:
00103 LOG_DEBUG("Received msg ... PAMSG_LOGOUT");
00104 handleLogoutMessage(computer);
00105 break;
00106
00107 case PAMSG_RECONNECT:
00108 LOG_DEBUG("Received msg ... PAMSG_RECONNECT");
00109 handleReconnectMessage(computer, message);
00110 break;
00111
00112 case PAMSG_REGISTER:
00113 LOG_DEBUG("Received msg ... PAMSG_REGISTER");
00114 handleRegisterMessage(computer, message);
00115 break;
00116
00117 case PAMSG_UNREGISTER:
00118 LOG_DEBUG("Received msg ... PAMSG_UNREGISTER");
00119 handleUnregisterMessage(computer, message);
00120 break;
00121
00122 case PAMSG_EMAIL_CHANGE:
00123 LOG_DEBUG("Received msg ... PAMSG_EMAIL_CHANGE");
00124 handleEmailChangeMessage(computer, message);
00125 break;
00126
00127 case PAMSG_EMAIL_GET:
00128 LOG_DEBUG("Received msg ... PAMSG_EMAIL_GET");
00129 handleEmailGetMessage(computer);
00130 break;
00131
00132 case PAMSG_PASSWORD_CHANGE:
00133 LOG_DEBUG("Received msg ... PAMSG_PASSWORD_CHANGE");
00134 handlePasswordChangeMessage(computer, message);
00135 break;
00136
00137 case PAMSG_CHAR_CREATE:
00138 LOG_DEBUG("Received msg ... PAMSG_CHAR_CREATE");
00139 handleCharacterCreateMessage(computer, message);
00140 break;
00141
00142 case PAMSG_CHAR_SELECT:
00143 LOG_DEBUG("Received msg ... PAMSG_CHAR_SELECT");
00144 handleCharacterSelectMessage(computer, message);
00145 break;
00146
00147 case PAMSG_CHAR_DELETE:
00148 LOG_DEBUG("Received msg ... PAMSG_CHAR_DELETE");
00149 handleCharacterDeleteMessage(computer, message);
00150 break;
00151
00152 default:
00153 LOG_WARN("AccountHandler::processMessage, Invalid message type "
00154 << message.getId());
00155 MessageOut result(XXMSG_INVALID);
00156 computer.send(result);
00157 break;
00158 }
00159 }
00160
00161 void
00162 AccountHandler::handleLoginMessage(AccountClient &computer, MessageIn &msg)
00163 {
00164 MessageOut reply(APMSG_LOGIN_RESPONSE);
00165
00166 if (computer.status != CLIENT_LOGIN)
00167 {
00168 reply.writeByte(ERRMSG_FAILURE);
00169 computer.send(reply);
00170 return;
00171 }
00172
00173 unsigned long clientVersion = msg.readLong();
00174
00175 if (clientVersion < config.getValue("clientVersion", 0))
00176 {
00177 reply.writeByte(LOGIN_INVALID_VERSION);
00178 computer.send(reply);
00179 return;
00180 }
00181
00182 std::string username = msg.readString();
00183 std::string password = msg.readString();
00184
00185 if (stringFilter->findDoubleQuotes(username))
00186 {
00187 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00188 computer.send(reply);
00189 return;
00190 }
00191
00192 if (getClientNumber() >= MAX_CLIENTS )
00193 {
00194 reply.writeByte(LOGIN_SERVER_FULL);
00195 computer.send(reply);
00196 return;
00197 }
00198
00199
00200 Storage &store = Storage::instance("tmw");
00201 AccountPtr acc = store.getAccount(username);
00202
00203 if (!acc.get() || acc->getPassword() != password)
00204 {
00205 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00206 computer.send(reply);
00207 return;
00208 }
00209
00210
00211 computer.setAccount(acc);
00212 computer.status = CLIENT_CONNECTED;
00213
00214 reply.writeByte(ERRMSG_OK);
00215 computer.send(reply);
00216
00217
00218 Characters &chars = computer.getAccount()->getCharacters();
00219
00220
00221 for (unsigned int i = 0; i < chars.size(); i++)
00222 {
00223 MessageOut charInfo(APMSG_CHAR_INFO);
00224 charInfo.writeByte(i);
00225 charInfo.writeString(chars[i]->getName());
00226 charInfo.writeByte((unsigned char) chars[i]->getGender());
00227 charInfo.writeByte(chars[i]->getHairStyle());
00228 charInfo.writeByte(chars[i]->getHairColor());
00229 charInfo.writeByte(chars[i]->getLevel());
00230 charInfo.writeLong(chars[i]->getMoney());
00231
00232 for (int j = 0; j < NB_BASE_ATTRIBUTES; ++j)
00233 charInfo.writeShort(chars[i]->getBaseAttribute(j));
00234
00235 computer.send(charInfo);
00236 }
00237 return;
00238 }
00239
00240 void
00241 AccountHandler::handleLogoutMessage(AccountClient &computer)
00242 {
00243 MessageOut reply(APMSG_LOGOUT_RESPONSE);
00244
00245 if (computer.status == CLIENT_LOGIN)
00246 {
00247 reply.writeByte(ERRMSG_NO_LOGIN);
00248 }
00249 else if (computer.status == CLIENT_CONNECTED)
00250 {
00251 computer.unsetAccount();
00252 computer.status = CLIENT_LOGIN;
00253 reply.writeByte(ERRMSG_OK);
00254 }
00255 else if (computer.status == CLIENT_QUEUED)
00256 {
00257
00258 mTokenCollector.deletePendingClient(&computer);
00259
00260 return;
00261 }
00262 computer.send(reply);
00263 }
00264
00265 void AccountHandler::
00266 handleReconnectMessage(AccountClient &computer, MessageIn &msg)
00267 {
00268 if (computer.status != CLIENT_LOGIN)
00269 {
00270 LOG_DEBUG("Account tried to reconnect, but was already logged in "
00271 << "or queued.");
00272 return;
00273 }
00274
00275 std::string magic_token = msg.readString(MAGIC_TOKEN_LENGTH);
00276 computer.status = CLIENT_QUEUED;
00277 mTokenCollector.addPendingClient(magic_token, &computer);
00278 }
00279
00280 void
00281 AccountHandler::handleRegisterMessage(AccountClient &computer, MessageIn &msg)
00282 {
00283 unsigned long clientVersion = msg.readLong();
00284 std::string username = msg.readString();
00285 std::string password = msg.readString();
00286 std::string email = msg.readString();
00287
00288 MessageOut reply(APMSG_REGISTER_RESPONSE);
00289
00290 if (computer.status != CLIENT_LOGIN)
00291 {
00292 reply.writeByte(ERRMSG_FAILURE);
00293 }
00294 else if (clientVersion < config.getValue("clientVersion", 0))
00295 {
00296 reply.writeByte(REGISTER_INVALID_VERSION);
00297 }
00298 else if (stringFilter->findDoubleQuotes(username))
00299 {
00300 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00301 }
00302 else if (stringFilter->findDoubleQuotes(email))
00303 {
00304 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00305 }
00306 else if ((username.length() < MIN_LOGIN_LENGTH) ||
00307 (username.length() > MAX_LOGIN_LENGTH))
00308 {
00309 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00310 }
00311 else if ((password.length() < MIN_PASSWORD_LENGTH) ||
00312 (password.length() > MAX_PASSWORD_LENGTH))
00313 {
00314 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00315 }
00316 else if (!stringFilter->isEmailValid(email))
00317 {
00318 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00319 }
00320
00321 else if (!stringFilter->filterContent(username))
00322 {
00323 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00324 }
00325 else
00326 {
00327 Storage &store = Storage::instance("tmw");
00328 AccountPtr accPtr = store.getAccount(username);
00329
00330
00331 if (accPtr.get())
00332 {
00333 reply.writeByte(REGISTER_EXISTS_USERNAME);
00334 }
00335
00336 else if (store.doesEmailAddressExist(email))
00337 {
00338 reply.writeByte(REGISTER_EXISTS_EMAIL);
00339 }
00340 else
00341 {
00342 AccountPtr acc(new Account(username, password, email));
00343 store.addAccount(acc);
00344 reply.writeByte(ERRMSG_OK);
00345
00346
00347 computer.setAccount(acc);
00348 computer.status = CLIENT_CONNECTED;
00349 }
00350 }
00351
00352 computer.send(reply);
00353 }
00354
00355 void
00356 AccountHandler::handleUnregisterMessage(AccountClient &computer,
00357 MessageIn &msg)
00358 {
00359 LOG_DEBUG("AccountHandler::handleUnregisterMessage");
00360 std::string username = msg.readString();
00361 std::string password = msg.readString();
00362
00363 MessageOut reply(APMSG_UNREGISTER_RESPONSE);
00364
00365 if (computer.status != CLIENT_LOGIN)
00366 {
00367 reply.writeByte(ERRMSG_FAILURE);
00368 computer.send(reply);
00369 return;
00370 }
00371
00372 if (stringFilter->findDoubleQuotes(username))
00373 {
00374 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00375 computer.send(reply);
00376 return;
00377 }
00378
00379
00380 Storage &store = Storage::instance("tmw");
00381 AccountPtr accPtr = store.getAccount(username);
00382
00383 if (!accPtr.get() || accPtr->getPassword() != password)
00384 {
00385 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00386 computer.send(reply);
00387 return;
00388 }
00389
00390
00391 LOG_DEBUG("Unregistered \"" << username
00392 << "\", AccountID: " << accPtr->getID());
00393 store.delAccount(accPtr);
00394 reply.writeByte(ERRMSG_OK);
00395
00396
00397
00398 if (computer.getAccount().get() != NULL &&
00399 computer.getAccount()->getName() == username)
00400 {
00401 computer.unsetAccount();
00402 computer.status = CLIENT_LOGIN;
00403 }
00404 computer.send(reply);
00405 }
00406
00407 void AccountHandler::
00408 handleEmailChangeMessage(AccountClient &computer, MessageIn &msg)
00409 {
00410 MessageOut reply(APMSG_EMAIL_CHANGE_RESPONSE);
00411
00412 if (computer.status != CLIENT_CONNECTED ||
00413 computer.getAccount().get() == NULL)
00414 {
00415 reply.writeByte(ERRMSG_NO_LOGIN);
00416 computer.send(reply);
00417 return;
00418 }
00419
00420 std::string email = msg.readString();
00421
00422 Storage &store = Storage::instance("tmw");
00423
00424 if (!stringFilter->isEmailValid(email))
00425 {
00426 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00427 }
00428 else if (stringFilter->findDoubleQuotes(email))
00429 {
00430 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00431 }
00432 else if (store.doesEmailAddressExist(email))
00433 {
00434 reply.writeByte(EMAILCHG_EXISTS_EMAIL);
00435 }
00436 else
00437 {
00438 computer.getAccount()->setEmail(email);
00439 reply.writeByte(ERRMSG_OK);
00440 }
00441 computer.send(reply);
00442 }
00443
00444 void AccountHandler::
00445 handleEmailGetMessage(AccountClient &computer)
00446 {
00447 MessageOut reply(APMSG_EMAIL_GET_RESPONSE);
00448
00449 if (computer.status != CLIENT_CONNECTED ||
00450 computer.getAccount().get() == NULL)
00451 {
00452 reply.writeByte(ERRMSG_NO_LOGIN);
00453 computer.send(reply);
00454 return;
00455 }
00456
00457 reply.writeByte(ERRMSG_OK);
00458 reply.writeString(computer.getAccount()->getEmail());
00459
00460 computer.send(reply);
00461 }
00462
00463 void
00464 AccountHandler::handlePasswordChangeMessage(AccountClient &computer,
00465 MessageIn &msg)
00466 {
00467 std::string oldPassword = msg.readString();
00468 std::string newPassword = msg.readString();
00469
00470 MessageOut reply(APMSG_PASSWORD_CHANGE_RESPONSE);
00471
00472 if (computer.status != CLIENT_CONNECTED ||
00473 computer.getAccount().get() == NULL)
00474 {
00475 reply.writeByte(ERRMSG_NO_LOGIN);
00476 }
00477 else if (newPassword.length() < MIN_PASSWORD_LENGTH ||
00478 newPassword.length() > MAX_PASSWORD_LENGTH)
00479 {
00480 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00481 }
00482 else if (stringFilter->findDoubleQuotes(newPassword))
00483 {
00484 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00485 }
00486 else if (oldPassword != computer.getAccount()->getPassword())
00487 {
00488 reply.writeByte(ERRMSG_FAILURE);
00489 }
00490 else
00491 {
00492 computer.getAccount()->setPassword(newPassword);
00493 reply.writeByte(ERRMSG_OK);
00494 }
00495
00496 computer.send(reply);
00497 }
00498
00499 void
00500 AccountHandler::handleCharacterCreateMessage(AccountClient &computer,
00501 MessageIn &msg)
00502 {
00503 std::string name = msg.readString();
00504 int hairStyle = msg.readByte();
00505 int hairColor = msg.readByte();
00506 int gender = msg.readByte();
00507
00508 MessageOut reply(APMSG_CHAR_CREATE_RESPONSE);
00509
00510 if (computer.status != CLIENT_CONNECTED ||
00511 computer.getAccount().get() == NULL)
00512 {
00513 reply.writeByte(ERRMSG_NO_LOGIN);
00514 }
00515 else if (!stringFilter->filterContent(name))
00516 {
00517 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00518 }
00519 else if (stringFilter->findDoubleQuotes(name))
00520 {
00521 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00522 }
00523 else if (hairStyle < 0 || hairStyle > MAX_HAIRSTYLE_VALUE)
00524 {
00525 reply.writeByte(CREATE_INVALID_HAIRSTYLE);
00526 }
00527 else if (hairColor < 0 || hairColor > MAX_HAIRCOLOR_VALUE)
00528 {
00529 reply.writeByte(CREATE_INVALID_HAIRCOLOR);
00530 }
00531 else if (gender < 0 || gender > MAX_GENDER_VALUE)
00532 {
00533 reply.writeByte(CREATE_INVALID_GENDER);
00534 }
00535 else if ((name.length() < MIN_CHARACTER_LENGTH) ||
00536 (name.length() > MAX_CHARACTER_LENGTH))
00537 {
00538 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00539 }
00540 else
00541 {
00542 Storage &store = Storage::instance("tmw");
00543 if (store.doesCharacterNameExist(name))
00544 {
00545 reply.writeByte(CREATE_EXISTS_NAME);
00546 computer.send(reply);
00547 return;
00548 }
00549
00550
00551 Characters &chars = computer.getAccount()->getCharacters();
00552 if (chars.size() >= MAX_OF_CHARACTERS)
00553 {
00554 reply.writeByte(CREATE_TOO_MUCH_CHARACTERS);
00555 computer.send(reply);
00556 return;
00557 }
00558
00559
00560
00561
00562 unsigned short attributes[NB_BASE_ATTRIBUTES];
00563 for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i)
00564 attributes[i] = msg.readShort();
00565
00566 unsigned int totalAttributes = 0;
00567 bool validNonZeroAttributes = true;
00568 for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i)
00569 {
00570
00571 totalAttributes += attributes[i];
00572
00573
00574 if (attributes[i] <= 0) validNonZeroAttributes = false;
00575 }
00576
00577 if (totalAttributes > POINTS_TO_DISTRIBUTES_AT_LVL1)
00578 {
00579 reply.writeByte(CREATE_ATTRIBUTES_TOO_HIGH);
00580 }
00581 else if (totalAttributes < POINTS_TO_DISTRIBUTES_AT_LVL1)
00582 {
00583 reply.writeByte(CREATE_ATTRIBUTES_TOO_LOW);
00584 }
00585 else if (!validNonZeroAttributes)
00586 {
00587 reply.writeByte(CREATE_ATTRIBUTES_EQUAL_TO_ZERO);
00588 }
00589 else
00590 {
00591 CharacterPtr newCharacter(new CharacterData(name));
00592 for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i)
00593 newCharacter->setBaseAttribute(i, attributes[i]);
00594 newCharacter->setMoney(0);
00595 newCharacter->setLevel(1);
00596 newCharacter->setGender(gender);
00597 newCharacter->setHairStyle(hairStyle);
00598 newCharacter->setHairColor(hairColor);
00599 newCharacter->setMapId((int) config.getValue("defaultMap", 1));
00600 Point startingPos((int) config.getValue("startX", 512),
00601 (int) config.getValue("startY", 512));
00602 newCharacter->setPosition(startingPos);
00603 computer.getAccount()->addCharacter(newCharacter);
00604
00605 LOG_INFO("Character " << name << " was created for "
00606 << computer.getAccount()->getName() << "'s account.");
00607
00608 store.flush(computer.getAccount());
00609 reply.writeByte(ERRMSG_OK);
00610 computer.send(reply);
00611
00612
00613 MessageOut charInfo(APMSG_CHAR_INFO);
00614 int slot = chars.size() - 1;
00615 charInfo.writeByte(slot);
00616 charInfo.writeString(chars[slot]->getName());
00617 charInfo.writeByte((unsigned char) chars[slot]->getGender());
00618 charInfo.writeByte(chars[slot]->getHairStyle());
00619 charInfo.writeByte(chars[slot]->getHairColor());
00620 charInfo.writeByte(chars[slot]->getLevel());
00621 charInfo.writeShort(chars[slot]->getMoney());
00622 for (int j = 0; j < NB_BASE_ATTRIBUTES; ++j)
00623 charInfo.writeShort(chars[slot]->getBaseAttribute(j));
00624 computer.send(charInfo);
00625 return;
00626 }
00627 }
00628
00629 computer.send(reply);
00630 }
00631
00632 void AccountHandler::
00633 handleCharacterSelectMessage(AccountClient &computer, MessageIn &msg)
00634 {
00635 MessageOut reply(APMSG_CHAR_SELECT_RESPONSE);
00636
00637 if (computer.status != CLIENT_CONNECTED ||
00638 computer.getAccount().get() == NULL)
00639 {
00640 reply.writeByte(ERRMSG_NO_LOGIN);
00641 computer.send(reply);
00642 return;
00643 }
00644
00645 unsigned char charNum = msg.readByte();
00646 Characters &chars = computer.getAccount()->getCharacters();
00647
00648
00649 if (charNum >= chars.size())
00650 {
00651
00652 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00653 computer.send(reply);
00654 return;
00655 }
00656
00657 std::string address;
00658 short port;
00659 if (!serverHandler->getGameServerFromMap(
00660 chars[charNum]->getMapId(), address, port))
00661 {
00662 LOG_ERROR("Character Selection: No game server for the map.");
00663 reply.writeByte(ERRMSG_FAILURE);
00664 computer.send(reply);
00665 return;
00666 }
00667
00668
00669 computer.setCharacter(chars[charNum]);
00670 CharacterPtr selectedChar = computer.getCharacter();
00671 reply.writeByte(ERRMSG_OK);
00672
00673 LOG_DEBUG(selectedChar->getName() << " is trying to enter the servers.");
00674
00675 std::string magic_token(utils::getMagicToken());
00676 reply.writeString(magic_token, MAGIC_TOKEN_LENGTH);
00677 reply.writeString(address);
00678 reply.writeShort(port);
00679
00680
00681 reply.writeString(config.getValue("accountServerAddress", "localhost"));
00682 reply.writeShort(int(config.getValue("accountServerPort",
00683 DEFAULT_SERVER_PORT)) + 2);
00684
00685 serverHandler->registerGameClient(magic_token, selectedChar);
00686 registerChatClient(magic_token, selectedChar->getName(), AL_NORMAL);
00687
00688 computer.send(reply);
00689 }
00690
00691 void AccountHandler::
00692 handleCharacterDeleteMessage(AccountClient &computer, MessageIn &msg)
00693 {
00694 MessageOut reply(APMSG_CHAR_DELETE_RESPONSE);
00695
00696 if (computer.status != CLIENT_CONNECTED ||
00697 computer.getAccount().get() == NULL)
00698 {
00699 reply.writeByte(ERRMSG_NO_LOGIN);
00700 computer.send(reply);
00701 return;
00702 }
00703
00704 unsigned char charNum = msg.readByte();
00705 Characters &chars = computer.getAccount()->getCharacters();
00706
00707
00708 if (charNum >= chars.size())
00709 {
00710
00711 reply.writeByte(ERRMSG_INVALID_ARGUMENT);
00712 computer.send(reply);
00713 return;
00714 }
00715
00716
00717
00718 if (computer.getCharacter().get() != NULL &&
00719 computer.getCharacter()->getName() == chars[charNum].get()->getName())
00720 computer.unsetCharacter();
00721
00722 std::string deletedCharacter = chars[charNum].get()->getName();
00723 computer.getAccount()->delCharacter(deletedCharacter);
00724
00725 Storage &store = Storage::instance("tmw");
00726 store.flush(computer.getAccount());
00727
00728 LOG_INFO(deletedCharacter << ": Character deleted...");
00729
00730 reply.writeByte(ERRMSG_OK);
00731
00732 computer.send(reply);
00733 }
00734
00735 void
00736 AccountHandler::tokenMatched(AccountClient *computer, int accountID)
00737 {
00738 MessageOut reply(APMSG_RECONNECT_RESPONSE);
00739
00740
00741 Storage &store = Storage::instance("tmw");
00742 AccountPtr acc = store.getAccountByID(accountID);
00743
00744
00745 computer->setAccount(acc);
00746 computer->status = CLIENT_CONNECTED;
00747
00748 reply.writeByte(ERRMSG_OK);
00749 computer->send(reply);
00750
00751
00752 Characters &chars = computer->getAccount()->getCharacters();
00753
00754
00755 for (unsigned int i = 0; i < chars.size(); i++)
00756 {
00757 MessageOut charInfo(APMSG_CHAR_INFO);
00758 charInfo.writeByte(i);
00759 charInfo.writeString(chars[i]->getName());
00760 charInfo.writeByte((unsigned char) chars[i]->getGender());
00761 charInfo.writeByte(chars[i]->getHairStyle());
00762 charInfo.writeByte(chars[i]->getHairColor());
00763 charInfo.writeByte(chars[i]->getLevel());
00764 charInfo.writeShort(chars[i]->getMoney());
00765
00766 for (int j = 0; j < NB_BASE_ATTRIBUTES; ++j)
00767 {
00768 charInfo.writeShort(chars[i]->getBaseAttribute(j));
00769 }
00770 computer->send(charInfo);
00771 }
00772 }
00773
00774 void
00775 AccountHandler::deletePendingClient(AccountClient* computer)
00776 {
00777
00778 if (computer->status != CLIENT_QUEUED) return;
00779
00780 MessageOut msg(APMSG_CONNECTION_TIMEDOUT);
00781 computer->disconnect(msg);
00782
00783 }
00784
00785 void
00786 AccountHandler::deletePendingConnect(int accountID)
00787 {
00788
00789
00790
00791 }