summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/charhandler.cpp38
-rw-r--r--src/net/charhandler.h60
-rw-r--r--src/net/ea/charserverhandler.cpp137
-rw-r--r--src/net/ea/charserverhandler.h26
-rw-r--r--src/net/ea/playerhandler.cpp4
-rw-r--r--src/net/ea/playerhandler.h12
-rw-r--r--src/net/manaserv/beinghandler.cpp2
-rw-r--r--src/net/manaserv/charhandler.cpp305
-rw-r--r--src/net/manaserv/charhandler.h57
-rw-r--r--src/net/manaserv/inventoryhandler.cpp6
-rw-r--r--src/net/manaserv/inventoryhandler.h5
-rw-r--r--src/net/manaserv/itemhandler.cpp15
-rw-r--r--src/net/manaserv/loginhandler.cpp2
-rw-r--r--src/net/manaserv/playerhandler.cpp4
-rw-r--r--src/net/manaserv/playerhandler.h12
-rw-r--r--src/net/playerhandler.h4
16 files changed, 364 insertions, 325 deletions
diff --git a/src/net/charhandler.cpp b/src/net/charhandler.cpp
new file mode 100644
index 00000000..8cf756ba
--- /dev/null
+++ b/src/net/charhandler.cpp
@@ -0,0 +1,38 @@
+/*
+ * The Mana World
+ * Copyright (C) 2010 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "net/charhandler.h"
+
+#include "gui/charselectdialog.h"
+
+using namespace Net;
+
+void CharHandler::updateCharSelectDialog()
+{
+ if (mCharSelectDialog)
+ mCharSelectDialog->setCharacters(mCharacters);
+}
+
+void CharHandler::unlockCharSelectDialog()
+{
+ if (mCharSelectDialog)
+ mCharSelectDialog->unlock();
+}
diff --git a/src/net/charhandler.h b/src/net/charhandler.h
index a55e8d86..dfe0882f 100644
--- a/src/net/charhandler.h
+++ b/src/net/charhandler.h
@@ -23,7 +23,6 @@
#define CHARHANDLER_H
#include "localplayer.h"
-#include "lockedarray.h"
#include "logindata.h"
#include <iosfwd>
@@ -35,34 +34,73 @@ class LocalPlayer;
namespace Net {
+/**
+ * A structure to hold information about a character.
+ */
+struct Character
+{
+ Character() :
+ slot(0),
+ dummy(new LocalPlayer)
+ {
+ }
+
+ ~Character()
+ {
+ delete dummy;
+ }
+
+ int slot; /**< The index in the list of characters */
+ LocalPlayer *dummy; /**< A dummy representing this character */
+};
+
+typedef std::list<Character*> Characters;
+
class CharHandler
{
public:
- virtual void setCharInfo(LockedArray<LocalPlayer*> *charInfo) = 0;
-
virtual void setCharSelectDialog(CharSelectDialog *window) = 0;
virtual void setCharCreateDialog(CharCreateDialog *window) = 0;
- virtual void getCharacters() = 0;
+ virtual void requestCharacters() = 0;
- virtual void chooseCharacter(int slot, LocalPlayer *character) = 0;
+ virtual void chooseCharacter(Net::Character *character) = 0;
virtual void newCharacter(const std::string &name, int slot,
- bool gender, int hairstyle, int hairColor,
- std::vector<int> stats) = 0;
+ bool gender, int hairstyle, int hairColor,
+ const std::vector<int> &stats) = 0;
- virtual void deleteCharacter(int slot, LocalPlayer* character) = 0;
+ virtual void deleteCharacter(Net::Character *character) = 0;
virtual void switchCharacter() = 0;
- virtual unsigned int baseSprite() const = 0;
+ virtual int baseSprite() const = 0;
- virtual unsigned int hairSprite() const = 0;
+ virtual int hairSprite() const = 0;
- virtual unsigned int maxSprite() const = 0;
+ virtual int maxSprite() const = 0;
virtual ~CharHandler() {}
+
+ protected:
+ CharHandler():
+ mSelectedCharacter(0),
+ mCharSelectDialog(0),
+ mCharCreateDialog(0)
+ {}
+
+ void updateCharSelectDialog();
+ void unlockCharSelectDialog();
+
+ /** The list of available characters. */
+ Net::Characters mCharacters;
+
+ /** The selected character. */
+ Net::Character *mSelectedCharacter;
+
+ CharSelectDialog *mCharSelectDialog;
+ CharCreateDialog *mCharCreateDialog;
};
} // namespace Net
diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp
index 106d0c8e..a49a55ac 100644
--- a/src/net/ea/charserverhandler.cpp
+++ b/src/net/ea/charserverhandler.cpp
@@ -39,6 +39,7 @@
#include "resources/colordb.h"
+#include "utils/dtor.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
@@ -49,9 +50,7 @@ namespace EAthena {
extern ServerInfo charServer;
extern ServerInfo mapServer;
-CharServerHandler::CharServerHandler():
- mCharSelectDialog(0),
- mCharCreateDialog(0)
+CharServerHandler::CharServerHandler()
{
static const Uint16 _messages[] = {
SMSG_CHAR_LOGIN,
@@ -69,30 +68,32 @@ CharServerHandler::CharServerHandler():
void CharServerHandler::handleMessage(Net::MessageIn &msg)
{
- int count, slot;
- LocalPlayer *tempPlayer;
-
logger->log("CharServerHandler: Packet ID: %x, Length: %d",
- msg.getId(), msg.getLength());
+ msg.getId(), msg.getLength());
+
switch (msg.getId())
{
- case SMSG_CHAR_LOGIN:
- msg.skip(2); // Length word
- msg.skip(20); // Unused
+ case SMSG_CHAR_LOGIN:
+ {
+ msg.skip(2); // Length word
+ msg.skip(20); // Unused
- // Derive number of characters from message length
- count = (msg.getLength() - 24) / 106;
+ // Derive number of characters from message length
+ const int count = (msg.getLength() - 24) / 106;
- for (int i = 0; i < count; i++)
- {
- tempPlayer = readPlayerData(msg, slot);
- mCharInfo->select(slot);
- mCharInfo->setEntry(tempPlayer);
- logger->log("CharServer: Player: %s (%d)",
- tempPlayer->getName().c_str(), slot);
- }
+ for (int i = 0; i < count; ++i)
+ {
+ Net::Character *character = new Net::Character;
+ int slot;
+ character->dummy = readPlayerData(msg, &slot);
+ character->slot = slot;
+ mCharacters.push_back(character);
+ logger->log("CharServer: Player: %s (%d)",
+ character->dummy->getName().c_str(), slot);
+ }
- state = STATE_CHAR_SELECT;
+ state = STATE_CHAR_SELECT;
+ }
break;
case SMSG_CHAR_LOGIN_ERROR:
@@ -108,81 +109,75 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg)
errorMessage = _("Unknown failure to select character.");
break;
}
- mCharInfo->unlock();
+ unlockCharSelectDialog();
break;
case SMSG_CHAR_CREATE_SUCCEEDED:
- tempPlayer = readPlayerData(msg, slot);
- mCharInfo->unlock();
- mCharInfo->select(slot);
- mCharInfo->setEntry(tempPlayer);
-
- // Close the character create dialog
- if (mCharCreateDialog)
{
- mCharCreateDialog->success();
- mCharCreateDialog->scheduleDelete();
- mCharCreateDialog = 0;
+ Net::Character *character = new Net::Character;
+ int slot;
+ character->dummy = readPlayerData(msg, &slot);
+ character->slot = slot;
+ mCharacters.push_back(character);
+
+ updateCharSelectDialog();
+
+ // Close the character create dialog
+ if (mCharCreateDialog)
+ {
+ mCharCreateDialog->scheduleDelete();
+ mCharCreateDialog = 0;
+ }
}
break;
case SMSG_CHAR_CREATE_FAILED:
new OkDialog(_("Error"), _("Failed to create character. Most "
"likely the name is already taken."));
-
if (mCharCreateDialog)
mCharCreateDialog->unlock();
break;
case SMSG_CHAR_DELETE_SUCCEEDED:
- tempPlayer = mCharInfo->getEntry();
- mCharInfo->setEntry(0);
- mCharInfo->unlock();
- if (mCharSelectDialog)
- mCharSelectDialog->update(mCharInfo->getPos());
+ delete mSelectedCharacter;
+ mCharacters.remove(mSelectedCharacter);
+ mSelectedCharacter = 0;
+ updateCharSelectDialog();
+ unlockCharSelectDialog();
new OkDialog(_("Info"), _("Character deleted."));
- delete tempPlayer;
break;
case SMSG_CHAR_DELETE_FAILED:
- mCharInfo->unlock();
+ unlockCharSelectDialog();
new OkDialog(_("Error"), _("Failed to delete character."));
break;
case SMSG_CHAR_MAP_INFO:
- player_node = mCharInfo->getEntry();
- slot = mCharInfo->getPos();
msg.skip(4); // CharID, must be the same as player_node->charID
map_path = msg.readString(16);
mapServer.hostname = ipToString(msg.readInt32());
mapServer.port = msg.readInt16();
- mCharInfo->unlock();
- mCharInfo->select(0);
- // Clear unselected players infos
- do
- {
- LocalPlayer *tmp = mCharInfo->getEntry();
- if (tmp != player_node)
- {
- delete tmp;
- mCharInfo->setEntry(0);
- }
- mCharInfo->next();
- } while (mCharInfo->getPos());
- mCharInfo->select(slot);
+ // Prevent the selected local player from being deleted
+ player_node = mSelectedCharacter->dummy;
+ mSelectedCharacter->dummy = 0;
+
+ delete_all(mCharacters);
+ mCharacters.clear();
+ updateCharSelectDialog();
+
mNetwork->disconnect();
state = STATE_CONNECT_GAME;
break;
}
}
-LocalPlayer *CharServerHandler::readPlayerData(Net::MessageIn &msg, int &slot)
+LocalPlayer *CharServerHandler::readPlayerData(Net::MessageIn &msg, int *slot)
{
const Token &token =
static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();
- LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0, NULL);
+ LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0);
tempPlayer->setGender(token.sex);
tempPlayer->setExp(msg.readInt32());
@@ -219,7 +214,7 @@ LocalPlayer *CharServerHandler::readPlayerData(Net::MessageIn &msg, int &slot)
tempPlayer->setName(msg.readString(24));
for (int i = 0; i < 6; i++)
tempPlayer->setAttributeBase(i + STR, msg.readInt8(), false);
- slot = msg.readInt8(); // character slot
+ *slot = msg.readInt8(); // character slot
msg.readInt8(); // unknown
return tempPlayer;
@@ -228,6 +223,7 @@ LocalPlayer *CharServerHandler::readPlayerData(Net::MessageIn &msg, int &slot)
void CharServerHandler::setCharSelectDialog(CharSelectDialog *window)
{
mCharSelectDialog = window;
+ updateCharSelectDialog();
}
void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
@@ -252,19 +248,22 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
mCharCreateDialog->setFixedGender(true, token.sex);
}
-void CharServerHandler::getCharacters()
+void CharServerHandler::requestCharacters()
{
connect();
}
-void CharServerHandler::chooseCharacter(int slot, LocalPlayer *)
+void CharServerHandler::chooseCharacter(Net::Character *character)
{
+ mSelectedCharacter = character;
+
MessageOut outMsg(CMSG_CHAR_SELECT);
- outMsg.writeInt8(slot);
+ outMsg.writeInt8(mSelectedCharacter->slot);
}
void CharServerHandler::newCharacter(const std::string &name, int slot,
- bool gender, int hairstyle, int hairColor, std::vector<int> stats)
+ bool gender, int hairstyle, int hairColor,
+ const std::vector<int> &stats)
{
MessageOut outMsg(CMSG_CHAR_CREATE);
outMsg.writeString(name, 24);
@@ -277,10 +276,12 @@ void CharServerHandler::newCharacter(const std::string &name, int slot,
outMsg.writeInt16(hairstyle);
}
-void CharServerHandler::deleteCharacter(int slot, LocalPlayer *character)
+void CharServerHandler::deleteCharacter(Net::Character *character)
{
+ mSelectedCharacter = character;
+
MessageOut outMsg(CMSG_CHAR_DELETE);
- outMsg.writeInt32(character->getId());
+ outMsg.writeInt32(mSelectedCharacter->dummy->getId());
outMsg.writeString("a@a.com", 40);
}
@@ -291,17 +292,17 @@ void CharServerHandler::switchCharacter()
outMsg.writeInt8(1);
}
-unsigned int CharServerHandler::baseSprite() const
+int CharServerHandler::baseSprite() const
{
return SPRITE_BASE;
}
-unsigned int CharServerHandler::hairSprite() const
+int CharServerHandler::hairSprite() const
{
return SPRITE_HAIR;
}
-unsigned int CharServerHandler::maxSprite() const
+int CharServerHandler::maxSprite() const
{
return SPRITE_VECTOREND;
}
diff --git a/src/net/ea/charserverhandler.h b/src/net/ea/charserverhandler.h
index b159c63b..d96da452 100644
--- a/src/net/ea/charserverhandler.h
+++ b/src/net/ea/charserverhandler.h
@@ -42,9 +42,6 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler
virtual void handleMessage(Net::MessageIn &msg);
- void setCharInfo(LockedArray<LocalPlayer*> *charInfo)
- { mCharInfo = charInfo; }
-
void setCharSelectDialog(CharSelectDialog *window);
/**
@@ -54,31 +51,28 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler
*/
void setCharCreateDialog(CharCreateDialog *window);
- void getCharacters();
+ void requestCharacters();
- void chooseCharacter(int slot, LocalPlayer* character);
+ void chooseCharacter(Net::Character *character);
void newCharacter(const std::string &name, int slot, bool gender,
- int hairstyle, int hairColor, std::vector<int> stats);
+ int hairstyle, int hairColor,
+ const std::vector<int> &stats);
- void deleteCharacter(int slot, LocalPlayer* character);
+ void deleteCharacter(Net::Character *character);
void switchCharacter();
- unsigned int baseSprite() const;
+ int baseSprite() const;
- unsigned int hairSprite() const;
+ int hairSprite() const;
- unsigned int maxSprite() const;
+ int maxSprite() const;
void connect();
- protected:
- LockedArray<LocalPlayer*> *mCharInfo;
- CharSelectDialog *mCharSelectDialog;
- CharCreateDialog *mCharCreateDialog;
-
- LocalPlayer *readPlayerData(Net::MessageIn &msg, int &slot);
+ private:
+ LocalPlayer *readPlayerData(Net::MessageIn &msg, int *slot);
};
} // namespace EAthena
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 34e0daf4..8de15d2b 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -556,7 +556,7 @@ void PlayerHandler::emote(int emoteId)
outMsg.writeInt8(emoteId);
}
-void PlayerHandler::increaseAttribute(size_t attr)
+void PlayerHandler::increaseAttribute(int attr)
{
if (attr >= STR && attr <= LUK)
{
@@ -566,7 +566,7 @@ void PlayerHandler::increaseAttribute(size_t attr)
}
}
-void PlayerHandler::decreaseAttribute(size_t attr)
+void PlayerHandler::decreaseAttribute(int attr)
{
// Supported by eA?
}
diff --git a/src/net/ea/playerhandler.h b/src/net/ea/playerhandler.h
index 9e7e9ac3..bbfbc74c 100644
--- a/src/net/ea/playerhandler.h
+++ b/src/net/ea/playerhandler.h
@@ -37,31 +37,23 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void handleMessage(Net::MessageIn &msg);
void attack(int id);
-
void emote(int emoteId);
- void increaseAttribute(size_t attr);
-
- void decreaseAttribute(size_t attr);
-
+ void increaseAttribute(int attr);
+ void decreaseAttribute(int attr);
void increaseSkill(int skillId);
void pickUp(FloorItem *floorItem);
-
void setDirection(char direction);
-
void setDestination(int x, int y, int direction = -1);
-
void changeAction(Being::Action action);
void respawn();
void ignorePlayer(const std::string &player, bool ignore);
-
void ignoreAll(bool ignore);
bool canUseMagic();
-
bool canCorrectAttributes();
int getJobLocation();
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp
index 5f9d1586..ae5bbc0e 100644
--- a/src/net/manaserv/beinghandler.cpp
+++ b/src/net/manaserv/beinghandler.cpp
@@ -114,7 +114,7 @@ Vector BeingHandler::giveSpeedInPixelsPerTicks(float speedInTilesPerSeconds)
{
speedInTicks.x = speedInTicks.y = 0;
logger->log("Manaserv::BeingHandler: Speed wasn't given back"
- " because game/Map not initialized.");
+ " because game/Map not initialized.");
}
// We don't use z for now.
speedInTicks.z = 0;
diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp
index 122ee10b..7a75e38d 100644
--- a/src/net/manaserv/charhandler.cpp
+++ b/src/net/manaserv/charhandler.cpp
@@ -41,25 +41,10 @@
#include "resources/colordb.h"
+#include "utils/dtor.h"
#include "utils/gettext.h"
extern Net::CharHandler *charHandler;
-
-struct CharInfo {
- unsigned char slot;
- std::string name;
- Gender gender;
- int hs, hc;
- unsigned short level;
- unsigned short charPoints;
- unsigned short corrPoints;
- unsigned int money;
- unsigned char attr[7];
-};
-
-typedef std::vector<CharInfo> CharInfos;
-CharInfos chars;
-
extern ManaServ::GameHandler *gameHandler;
namespace ManaServ {
@@ -71,9 +56,7 @@ extern std::string netToken;
extern ServerInfo gameServer;
extern ServerInfo chatServer;
-CharHandler::CharHandler():
- mCharSelectDialog(0),
- mCharCreateDialog(0)
+CharHandler::CharHandler()
{
static const Uint16 _messages[] = {
APMSG_CHAR_CREATE_RESPONSE,
@@ -91,104 +74,54 @@ void CharHandler::handleMessage(Net::MessageIn &msg)
switch (msg.getId())
{
case APMSG_CHAR_CREATE_RESPONSE:
- handleCharCreateResponse(msg);
+ handleCharacterCreateResponse(msg);
break;
case APMSG_CHAR_DELETE_RESPONSE:
- {
- int errMsg = msg.readInt8();
- // Character deletion successful
- if (errMsg == ERRMSG_OK)
- {
- LocalPlayer *tempPlayer = mCharInfo->getEntry();
- mCharInfo->setEntry(0);
- mCharInfo->unlock();
- if (mCharSelectDialog)
- mCharSelectDialog->update(mCharInfo->getPos());
- new OkDialog(_("Info"), _("Player deleted."));
- delete tempPlayer;
- }
- // Character deletion failed
- else
- {
- std::string errorMessage = "";
- switch (errMsg)
- {
- case ERRMSG_NO_LOGIN:
- errorMessage = _("Not logged in.");
- break;
- case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("Selection out of range.");
- break;
- default:
- errorMessage = _("Unknown error.");
- }
- mCharInfo->unlock();
- new OkDialog(_("Error"), errorMessage);
- }
- }
+ handleCharacterDeleteResponse(msg);
break;
case APMSG_CHAR_INFO:
- {
- CharInfo info;
- info.slot = msg.readInt8(); // character slot
- info.name = msg.readString();
- info.gender = msg.readInt8() == GENDER_MALE ? GENDER_MALE :
- GENDER_FEMALE;
- info.hs = msg.readInt8();
- info.hc = msg.readInt8();
- info.level = msg.readInt16();
- info.charPoints = msg.readInt16();
- info.corrPoints = msg.readInt16();
- info.money = msg.readInt32();
-
- for (int i = 0; i < 7; i++)
- {
- info.attr[i] = msg.readInt8();
- }
-
- chars.push_back(info);
-
- if (mCharSelectDialog)
- {
- mCharInfo->select(info.slot);
-
- LocalPlayer *tempPlayer = new LocalPlayer();
- tempPlayer->setName(info.name);
- tempPlayer->setGender(info.gender);
- tempPlayer->setSprite(SPRITE_HAIR, info.hs * -1,
- ColorDB::get(info.hc));
- tempPlayer->setLevel(info.level);
- tempPlayer->setCharacterPoints(info.charPoints);
- tempPlayer->setCorrectionPoints(info.corrPoints);
- tempPlayer->setMoney(info.money);
-
- for (int i = 0; i < 7; i++)
- {
- tempPlayer->setAttributeBase(i, info.attr[i], false);
- }
-
- mCharInfo->setEntry(tempPlayer);
-
- mCharSelectDialog->update(info.slot);
- }
- }
+ handleCharacterInfo(msg);
break;
case APMSG_CHAR_SELECT_RESPONSE:
- handleCharSelectResponse(msg);
+ handleCharacterSelectResponse(msg);
break;
}
}
-void CharHandler::handleCharCreateResponse(Net::MessageIn &msg)
+void CharHandler::handleCharacterInfo(Net::MessageIn &msg)
{
- int errMsg = msg.readInt8();
+ CachedCharacterInfo info;
+ info.slot = msg.readInt8();
+ info.name = msg.readString();
+ info.gender = msg.readInt8() == GENDER_MALE ? GENDER_MALE :
+ GENDER_FEMALE;
+ info.hairStyle = msg.readInt8();
+ info.hairColor = msg.readInt8();
+ info.level = msg.readInt16();
+ info.characterPoints = msg.readInt16();
+ info.correctionPoints = msg.readInt16();
+ info.money = msg.readInt32();
+
+ for (int i = 0; i < 7; i++)
+ {
+ info.attribute[i] = msg.readInt8();
+ }
+
+ mCachedCharacterInfos.push_back(info);
+
+ updateCharacters();
+}
+
+void CharHandler::handleCharacterCreateResponse(Net::MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
- // Character creation failed
if (errMsg != ERRMSG_OK)
{
+ // Character creation failed
std::string errorMessage = "";
switch (errMsg)
{
@@ -233,17 +166,48 @@ void CharHandler::handleCharCreateResponse(Net::MessageIn &msg)
}
else
{
+ // Close the character create dialog
if (mCharCreateDialog)
{
- mCharCreateDialog->success();
mCharCreateDialog->scheduleDelete();
mCharCreateDialog = 0;
}
}
+}
+void CharHandler::handleCharacterDeleteResponse(Net::MessageIn &msg)
+{
+ int errMsg = msg.readInt8();
+ if (errMsg == ERRMSG_OK)
+ {
+ // Character deletion successful
+ delete mSelectedCharacter;
+ mCharacters.remove(mSelectedCharacter);
+ updateCharSelectDialog();
+ unlockCharSelectDialog();
+ new OkDialog(_("Info"), _("Player deleted."));
+ }
+ else
+ {
+ // Character deletion failed
+ std::string errorMessage = "";
+ switch (errMsg)
+ {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = _("Not logged in.");
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = _("Selection out of range.");
+ break;
+ default:
+ errorMessage = strprintf(_("Unknown error (%d)."), errMsg);
+ }
+ new OkDialog(_("Error"), errorMessage);
+ }
+ mSelectedCharacter = 0;
}
-void CharHandler::handleCharSelectResponse(Net::MessageIn &msg)
+void CharHandler::handleCharacterSelectResponse(Net::MessageIn &msg)
{
int errMsg = msg.readInt8();
@@ -265,31 +229,20 @@ void CharHandler::handleCharSelectResponse(Net::MessageIn &msg)
gameServerConnection->connect(gameServer.hostname, gameServer.port);
chatServerConnection->connect(chatServer.hostname, chatServer.port);
- // Keep the selected character and delete the others
- player_node = mCharInfo->getEntry();
- int slot = mCharInfo->getPos();
- mCharInfo->unlock();
- mCharInfo->select(0);
-
- do {
- LocalPlayer *tmp = mCharInfo->getEntry();
- if (tmp != player_node)
- {
- delete tmp;
- mCharInfo->setEntry(0);
- }
- mCharInfo->next();
- } while (mCharInfo->getPos());
- mCharInfo->select(slot);
-
- mCharInfo->clear(); //player_node will be deleted by ~Game
+ // Prevent the selected local player from being deleted
+ player_node = mSelectedCharacter->dummy;
+ mSelectedCharacter->dummy = 0;
+
+ mCachedCharacterInfos.clear();
+ updateCharacters();
state = STATE_CONNECT_GAME;
}
- else if(errMsg == ERRMSG_FAILURE)
+ else if (errMsg == ERRMSG_FAILURE)
{
errorMessage = _("No gameservers are available.");
- mCharInfo->clear();
+ delete_all(mCharacters);
+ mCharacters.clear();
state = STATE_ERROR;
}
}
@@ -297,13 +250,15 @@ void CharHandler::handleCharSelectResponse(Net::MessageIn &msg)
void CharHandler::setCharSelectDialog(CharSelectDialog *window)
{
mCharSelectDialog = window;
+ updateCharacters();
}
void CharHandler::setCharCreateDialog(CharCreateDialog *window)
{
mCharCreateDialog = window;
- if (!mCharCreateDialog) return;
+ if (!mCharCreateDialog)
+ return;
std::vector<std::string> attributes;
attributes.push_back(_("Strength:"));
@@ -316,59 +271,34 @@ void CharHandler::setCharCreateDialog(CharCreateDialog *window)
mCharCreateDialog->setAttributes(attributes, 60, 1, 20);
}
-void CharHandler::getCharacters()
+void CharHandler::requestCharacters()
{
if (!accountServerConnection->isConnected())
+ {
Net::getLoginHandler()->connect();
+ }
else
{
- mCharInfo->unlock();
- LocalPlayer *tempPlayer;
- for (CharInfos::const_iterator it = chars.begin(); it != chars.end(); it++)
- {
- const CharInfo info = (CharInfo) (*it);
- mCharInfo->select(info.slot);
-
- tempPlayer = new LocalPlayer();
- tempPlayer->setName(info.name);
- tempPlayer->setGender(info.gender);
- tempPlayer->setSprite(SPRITE_HAIR, info.hs * -1,
- ColorDB::get(info.hc));
- tempPlayer->setLevel(info.level);
- tempPlayer->setCharacterPoints(info.charPoints);
- tempPlayer->setCorrectionPoints(info.corrPoints);
- tempPlayer->setMoney(info.money);
-
- for (int i = 0; i < 7; i++)
- {
- tempPlayer->setAttributeBase(i, info.attr[i], false);
- }
-
- mCharInfo->setEntry(tempPlayer);
- }
-
- // Close the character create dialog
- if (mCharCreateDialog)
- {
- mCharCreateDialog->scheduleDelete();
- mCharCreateDialog = 0;
- }
-
+ // The characters are already there, continue to character selection
state = STATE_CHAR_SELECT;
}
}
-void CharHandler::chooseCharacter(int slot, LocalPlayer* character)
+void CharHandler::chooseCharacter(Net::Character *character)
{
- MessageOut msg(PAMSG_CHAR_SELECT);
-
- msg.writeInt8(slot);
+ mSelectedCharacter = character;
+ MessageOut msg(PAMSG_CHAR_SELECT);
+ msg.writeInt8(mSelectedCharacter->slot);
accountServerConnection->send(msg);
}
-void CharHandler::newCharacter(const std::string &name, int slot, bool gender,
- int hairstyle, int hairColor, std::vector<int> stats)
+void CharHandler::newCharacter(const std::string &name,
+ int /* slot */,
+ bool gender,
+ int hairstyle,
+ int hairColor,
+ const std::vector<int> &stats)
{
MessageOut msg(PAMSG_CHAR_CREATE);
@@ -386,12 +316,12 @@ void CharHandler::newCharacter(const std::string &name, int slot, bool gender,
accountServerConnection->send(msg);
}
-void CharHandler::deleteCharacter(int slot, LocalPlayer* character)
+void CharHandler::deleteCharacter(Net::Character *character)
{
- MessageOut msg(PAMSG_CHAR_DELETE);
-
- msg.writeInt8(slot);
+ mSelectedCharacter = character;
+ MessageOut msg(PAMSG_CHAR_DELETE);
+ msg.writeInt8(mSelectedCharacter->slot);
accountServerConnection->send(msg);
}
@@ -400,19 +330,56 @@ void CharHandler::switchCharacter()
gameHandler->quit(true);
}
-unsigned int CharHandler::baseSprite() const
+int CharHandler::baseSprite() const
{
return SPRITE_BASE;
}
-unsigned int CharHandler::hairSprite() const
+int CharHandler::hairSprite() const
{
return SPRITE_HAIR;
}
-unsigned int CharHandler::maxSprite() const
+int CharHandler::maxSprite() const
{
return SPRITE_VECTOREND;
}
+void CharHandler::updateCharacters()
+{
+ // Delete previous characters
+ delete_all(mCharacters);
+ mCharacters.clear();
+
+ if (!mCharSelectDialog)
+ return;
+
+ // Create new characters and initialize them from the cached infos
+ for (unsigned i = 0; i < mCachedCharacterInfos.size(); ++i)
+ {
+ const CachedCharacterInfo &info = mCachedCharacterInfos.at(i);
+
+ Net::Character *character = new Net::Character;
+ character->slot = info.slot;
+ LocalPlayer *player = character->dummy;
+ player->setName(info.name);
+ player->setGender(info.gender);
+ player->setSprite(SPRITE_HAIR, info.hairStyle * -1,
+ ColorDB::get(info.hairColor));
+ player->setLevel(info.level);
+ player->setCharacterPoints(info.characterPoints);
+ player->setCorrectionPoints(info.correctionPoints);
+ player->setMoney(info.money);
+
+ for (int i = 0; i < 7; i++)
+ {
+ player->setAttributeBase(i, info.attribute[i], false);
+ }
+
+ mCharacters.push_back(character);
+ }
+
+ updateCharSelectDialog();
+}
+
} // namespace ManaServ
diff --git a/src/net/manaserv/charhandler.h b/src/net/manaserv/charhandler.h
index 74f68f55..4a1af307 100644
--- a/src/net/manaserv/charhandler.h
+++ b/src/net/manaserv/charhandler.h
@@ -42,11 +42,6 @@ class CharHandler : public MessageHandler, public Net::CharHandler
void handleMessage(Net::MessageIn &msg);
- void setCharInfo(LockedArray<LocalPlayer*> *charInfo)
- {
- mCharInfo = charInfo;
- }
-
void setCharSelectDialog(CharSelectDialog *window);
/**
@@ -56,32 +51,52 @@ class CharHandler : public MessageHandler, public Net::CharHandler
*/
void setCharCreateDialog(CharCreateDialog *window);
- void getCharacters();
+ void requestCharacters();
- void chooseCharacter(int slot, LocalPlayer* character);
+ void chooseCharacter(Net::Character *character);
void newCharacter(const std::string &name, int slot,
- bool gender, int hairstyle, int hairColor,
- std::vector<int> stats);
+ bool gender, int hairstyle, int hairColor,
+ const std::vector<int> &stats);
- void deleteCharacter(int slot, LocalPlayer* character);
+ void deleteCharacter(Net::Character *character);
void switchCharacter();
- unsigned int baseSprite() const;
-
- unsigned int hairSprite() const;
-
- unsigned int maxSprite() const;
+ int baseSprite() const;
- protected:
- void handleCharCreateResponse(Net::MessageIn &msg);
+ int hairSprite() const;
- void handleCharSelectResponse(Net::MessageIn &msg);
+ int maxSprite() const;
- LockedArray<LocalPlayer*> *mCharInfo;
- CharSelectDialog *mCharSelectDialog;
- CharCreateDialog *mCharCreateDialog;
+ private:
+ /**
+ * Character information needs to be cached since we receive it before
+ * we have loaded the dynamic data, so we can't resolve load any
+ * sprites yet.
+ */
+ struct CachedCharacterInfo {
+ int slot;
+ std::string name;
+ Gender gender;
+ int hairStyle;
+ int hairColor;
+ int level;
+ int characterPoints;
+ int correctionPoints;
+ int money;
+ int attribute[7];
+ };
+
+ void handleCharacterInfo(Net::MessageIn &msg);
+ void handleCharacterCreateResponse(Net::MessageIn &msg);
+ void handleCharacterDeleteResponse(Net::MessageIn &msg);
+ void handleCharacterSelectResponse(Net::MessageIn &msg);
+
+ void updateCharacters();
+
+ /** Cached character information */
+ std::vector<CachedCharacterInfo> mCachedCharacterInfos;
};
} // namespace ManaServ
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp
index 0020a4e7..3ce1aa6f 100644
--- a/src/net/manaserv/inventoryhandler.cpp
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -61,7 +61,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
{
case GPMSG_INVENTORY_FULL:
player_node->clearInventory();
- player_node->mEquipment->setBackend(&mEqiups);
+ player_node->mEquipment->setBackend(&mEquips);
// no break!
case GPMSG_INVENTORY:
@@ -77,7 +77,7 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
int id = msg.readInt16();
if (slot < EQUIPMENT_SIZE)
{
- mEqiups.setEquipment(slot, id);
+ mEquips.setEquipment(slot, id);
}
else if (slot >= 32 && slot < 32 + getSize(INVENTORY))
{
@@ -105,7 +105,7 @@ void InventoryHandler::unequipItem(const Item *item)
// Tidy equipment directly to avoid weapon still shown bug, for instance
int equipSlot = item->getInvIndex();
logger->log("Unequipping %d", equipSlot);
- mEqiups.setEquipment(equipSlot, 0);
+ mEquips.setEquipment(equipSlot, 0);
}
void InventoryHandler::useItem(const Item *item)
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
index 362e392a..402af3b5 100644
--- a/src/net/manaserv/inventoryhandler.h
+++ b/src/net/manaserv/inventoryhandler.h
@@ -30,7 +30,8 @@
namespace ManaServ {
-class EquipBackend : public Equipment::Backend {
+class EquipBackend : public Equipment::Backend
+{
public:
EquipBackend()
{ memset(mEquipment, 0, sizeof(mEquipment)); }
@@ -97,7 +98,7 @@ class InventoryHandler : public MessageHandler, Net::InventoryHandler
size_t getSize(StorageType type) const;
private:
- EquipBackend mEqiups;
+ EquipBackend mEquips;
};
} // namespace ManaServ
diff --git a/src/net/manaserv/itemhandler.cpp b/src/net/manaserv/itemhandler.cpp
index 802f9303..c939589e 100644
--- a/src/net/manaserv/itemhandler.cpp
+++ b/src/net/manaserv/itemhandler.cpp
@@ -58,12 +58,9 @@ void ItemHandler::handleMessage(Net::MessageIn &msg)
if (itemId)
{
- Game *game = Game::instance();
- Map *map = 0;
- if (game)
+ if (Game *game = Game::instance())
{
- map = game->getCurrentMap();
- if (map)
+ if (Map *map = game->getCurrentMap())
{
floorItemManager->create(id,
itemId,
@@ -71,9 +68,11 @@ void ItemHandler::handleMessage(Net::MessageIn &msg)
y / map->getTileHeight());
}
else
- logger->log(
- "ItemHandler: An item wasn't created because of"
- "Game/Map not initialized...");
+ {
+ logger->log(
+ "ItemHandler: An item wasn't created "
+ "because of Game/Map not initialized...");
+ }
}
}
else if (FloorItem *item = floorItemManager->findById(id))
diff --git a/src/net/manaserv/loginhandler.cpp b/src/net/manaserv/loginhandler.cpp
index 63195816..9d8bc0e2 100644
--- a/src/net/manaserv/loginhandler.cpp
+++ b/src/net/manaserv/loginhandler.cpp
@@ -64,9 +64,11 @@ void LoginHandler::handleMessage(Net::MessageIn &msg)
case APMSG_LOGIN_RESPONSE:
handleLoginResponse(msg);
break;
+
case APMSG_REGISTER_RESPONSE:
handleRegisterResponse(msg);
break;
+
case APMSG_RECONNECT_RESPONSE:
{
int errMsg = msg.readInt8();
diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp
index bff9512e..56502ec1 100644
--- a/src/net/manaserv/playerhandler.cpp
+++ b/src/net/manaserv/playerhandler.cpp
@@ -306,14 +306,14 @@ void PlayerHandler::emote(int emoteId)
// TODO
}
-void PlayerHandler::increaseAttribute(size_t attr)
+void PlayerHandler::increaseAttribute(int attr)
{
MessageOut msg(PGMSG_RAISE_ATTRIBUTE);
msg.writeInt8(attr);
gameServerConnection->send(msg);
}
-void PlayerHandler::decreaseAttribute(size_t attr)
+void PlayerHandler::decreaseAttribute(int attr)
{
MessageOut msg(PGMSG_LOWER_ATTRIBUTE);
msg.writeInt8(attr);
diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h
index 6edc96bb..65170d63 100644
--- a/src/net/manaserv/playerhandler.h
+++ b/src/net/manaserv/playerhandler.h
@@ -44,31 +44,23 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void handleMessage(Net::MessageIn &msg);
void attack(int id);
-
void emote(int emoteId);
- void increaseAttribute(size_t attr);
-
- void decreaseAttribute(size_t attr);
-
+ void increaseAttribute(int attr);
+ void decreaseAttribute(int attr);
void increaseSkill(int skillId);
void pickUp(FloorItem *floorItem);
-
void setDirection(char direction);
-
void setDestination(int x, int y, int direction = -1);
-
void changeAction(Being::Action action);
void respawn();
void ignorePlayer(const std::string &player, bool ignore);
-
void ignoreAll(bool ignore);
bool canUseMagic();
-
bool canCorrectAttributes();
int getJobLocation();
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
index 0174ede2..c2ecd2d0 100644
--- a/src/net/playerhandler.h
+++ b/src/net/playerhandler.h
@@ -35,9 +35,9 @@ class PlayerHandler
virtual void emote(int emoteId) = 0;
- virtual void increaseAttribute(size_t attr) = 0;
+ virtual void increaseAttribute(int attr) = 0;
- virtual void decreaseAttribute(size_t attr) = 0;
+ virtual void decreaseAttribute(int attr) = 0;
virtual void increaseSkill(int skillId) = 0;