summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt44
-rw-r--r--src/Makefile.am44
-rw-r--r--src/commandhandler.cpp2
-rw-r--r--src/engine.cpp6
-rw-r--r--src/game.cpp42
-rw-r--r--src/gui/charselectdialog.cpp11
-rw-r--r--src/gui/charselectdialog.h2
-rw-r--r--src/gui/login.cpp213
-rw-r--r--src/gui/login.h51
-rw-r--r--src/gui/quitdialog.cpp10
-rw-r--r--src/gui/register.cpp102
-rw-r--r--src/gui/register.h38
-rw-r--r--src/gui/serverdialog.cpp62
-rw-r--r--src/gui/serverdialog.h28
-rw-r--r--src/gui/updatewindow.cpp2
-rw-r--r--src/gui/worldselectdialog.cpp (renamed from src/gui/serverselectdialog.cpp)40
-rw-r--r--src/gui/worldselectdialog.h (renamed from src/gui/serverselectdialog.h)17
-rw-r--r--src/main.cpp607
-rw-r--r--src/main.h63
-rw-r--r--src/net/charhandler.h4
-rw-r--r--src/net/ea/charserverhandler.cpp48
-rw-r--r--src/net/ea/charserverhandler.h8
-rw-r--r--src/net/ea/gamehandler.cpp (renamed from src/net/ea/maphandler.cpp)60
-rw-r--r--src/net/ea/gamehandler.h (renamed from src/net/ea/maphandler.h)20
-rw-r--r--src/net/ea/generalhandler.cpp22
-rw-r--r--src/net/ea/generalhandler.h6
-rw-r--r--src/net/ea/loginhandler.cpp94
-rw-r--r--src/net/ea/loginhandler.h12
-rw-r--r--src/net/ea/logouthandler.cpp65
-rw-r--r--src/net/ea/logouthandler.h47
-rw-r--r--src/net/ea/network.cpp39
-rw-r--r--src/net/ea/network.h10
-rw-r--r--src/net/ea/playerhandler.cpp2
-rw-r--r--src/net/ea/protocol.h6
-rw-r--r--src/net/gamehandler.h (renamed from src/net/maphandler.h)12
-rw-r--r--src/net/generalhandler.h4
-rw-r--r--src/net/logindata.h25
-rw-r--r--src/net/loginhandler.h23
-rw-r--r--src/net/messagehandler.h2
-rw-r--r--src/net/messageout.cpp1
-rw-r--r--src/net/messageout.h2
-rw-r--r--src/net/net.cpp47
-rw-r--r--src/net/net.h13
-rw-r--r--src/net/serverinfo.h31
-rw-r--r--src/net/tmwserv/charhandler.cpp (renamed from src/net/tmwserv/charserverhandler.cpp)155
-rw-r--r--src/net/tmwserv/charhandler.h (renamed from src/net/tmwserv/charserverhandler.h)9
-rw-r--r--src/net/tmwserv/chathandler.cpp46
-rw-r--r--src/net/tmwserv/chathandler.h8
-rw-r--r--src/net/tmwserv/connection.cpp5
-rw-r--r--src/net/tmwserv/connection.h1
-rw-r--r--src/net/tmwserv/gamehandler.cpp132
-rw-r--r--src/net/tmwserv/gamehandler.h (renamed from src/net/tmwserv/maphandler.h)18
-rw-r--r--src/net/tmwserv/generalhandler.cpp60
-rw-r--r--src/net/tmwserv/generalhandler.h7
-rw-r--r--src/net/tmwserv/loginhandler.cpp78
-rw-r--r--src/net/tmwserv/loginhandler.h12
-rw-r--r--src/net/tmwserv/logouthandler.cpp275
-rw-r--r--src/net/tmwserv/logouthandler.h58
-rw-r--r--src/net/tmwserv/maphandler.cpp66
-rw-r--r--src/net/worldinfo.h (renamed from src/net/logouthandler.h)37
60 files changed, 1110 insertions, 1844 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index eeaa7459..f54b6858 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -124,6 +124,8 @@ SET(SRCS
gui/buy.h
gui/buysell.cpp
gui/buysell.h
+ gui/changeemaildialog.cpp
+ gui/changeemaildialog.h
gui/changepassworddialog.cpp
gui/changepassworddialog.h
gui/charselectdialog.cpp
@@ -134,6 +136,8 @@ SET(SRCS
gui/chat.h
gui/confirmdialog.cpp
gui/confirmdialog.h
+ gui/connectiondialog.cpp
+ gui/connectiondialog.h
gui/debugwindow.cpp
gui/debugwindow.h
gui/emotepopup.cpp
@@ -183,6 +187,8 @@ SET(SRCS
gui/playerbox.h
gui/popupmenu.cpp
gui/popupmenu.h
+ gui/quitdialog.cpp
+ gui/quitdialog.h
gui/recorder.cpp
gui/recorder.h
gui/register.cpp
@@ -191,8 +197,8 @@ SET(SRCS
gui/sdlinput.h
gui/sell.cpp
gui/sell.h
- gui/serverselectdialog.cpp
- gui/serverselectdialog.h
+ gui/serverdialog.cpp
+ gui/serverdialog.h
gui/setup.cpp
gui/setup.h
gui/setup_audio.cpp
@@ -240,22 +246,25 @@ SET(SRCS
gui/trade.h
gui/truetypefont.cpp
gui/truetypefont.h
+ gui/unregisterdialog.cpp
+ gui/unregisterdialog.h
gui/updatewindow.cpp
gui/updatewindow.h
gui/viewport.cpp
gui/viewport.h
gui/windowmenu.cpp
gui/windowmenu.h
+ gui/worldselectdialog.cpp
+ gui/worldselectdialog.h
net/adminhandler.h
net/charhandler.h
net/chathandler.h
+ net/gamehandler.h
net/generalhandler.h
net/guildhandler.h
net/inventoryhandler.h
net/logindata.h
net/loginhandler.h
- net/logouthandler.h
- net/maphandler.h
net/messagehandler.cpp
net/messagehandler.h
net/messagein.cpp
@@ -270,6 +279,7 @@ SET(SRCS
net/serverinfo.h
net/specialhandler.h
net/tradehandler.h
+ net/worldinfo.h
resources/action.cpp
resources/action.h
resources/ambientoverlay.cpp
@@ -442,6 +452,8 @@ SET(SRCS_EA
net/ea/chathandler.h
net/ea/equipmenthandler.cpp
net/ea/equipmenthandler.h
+ net/ea/gamehandler.cpp
+ net/ea/gamehandler.h
net/ea/generalhandler.cpp
net/ea/generalhandler.h
net/ea/inventoryhandler.cpp
@@ -450,10 +462,6 @@ SET(SRCS_EA
net/ea/itemhandler.h
net/ea/loginhandler.cpp
net/ea/loginhandler.h
- net/ea/logouthandler.cpp
- net/ea/logouthandler.h
- net/ea/maphandler.cpp
- net/ea/maphandler.h
net/ea/network.cpp
net/ea/network.h
net/ea/npchandler.cpp
@@ -472,20 +480,10 @@ SET(SRCS_EA
SET(SRCS_TMW
gui/buddywindow.cpp
gui/buddywindow.h
- gui/changeemaildialog.cpp
- gui/changeemaildialog.h
- gui/connectiondialog.cpp
- gui/connectiondialog.h
gui/guildlistbox.cpp
gui/guildlistbox.h
gui/guildwindow.cpp
gui/guildwindow.h
- gui/quitdialog.cpp
- gui/quitdialog.h
- gui/serverdialog.cpp
- gui/serverdialog.h
- gui/unregisterdialog.cpp
- gui/unregisterdialog.h
net/tmwserv/accountserver/account.cpp
net/tmwserv/accountserver/account.h
net/tmwserv/accountserver/accountserver.cpp
@@ -512,14 +510,16 @@ SET(SRCS_TMW
net/tmwserv/beinghandler.h
net/tmwserv/buysellhandler.cpp
net/tmwserv/buysellhandler.h
- net/tmwserv/charserverhandler.cpp
- net/tmwserv/charserverhandler.h
+ net/tmwserv/charhandler.cpp
+ net/tmwserv/charhandler.h
net/tmwserv/chathandler.cpp
net/tmwserv/chathandler.h
net/tmwserv/connection.cpp
net/tmwserv/connection.h
net/tmwserv/effecthandler.cpp
net/tmwserv/effecthandler.h
+ net/tmwserv/gamehandler.cpp
+ net/tmwserv/gamehandler.h
net/tmwserv/generalhandler.cpp
net/tmwserv/generalhandler.h
net/tmwserv/guildhandler.cpp
@@ -532,10 +532,6 @@ SET(SRCS_TMW
net/tmwserv/itemhandler.cpp
net/tmwserv/loginhandler.cpp
net/tmwserv/loginhandler.h
- net/tmwserv/logouthandler.cpp
- net/tmwserv/logouthandler.h
- net/tmwserv/maphandler.cpp
- net/tmwserv/maphandler.h
net/tmwserv/network.cpp
net/tmwserv/network.h
net/tmwserv/npchandler.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index ff35cdd5..d1782b46 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -73,6 +73,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/buy.h \
gui/buysell.cpp \
gui/buysell.h \
+ gui/changeemaildialog.cpp \
+ gui/changeemaildialog.h \
gui/changepassworddialog.cpp \
gui/changepassworddialog.h \
gui/charselectdialog.cpp \
@@ -83,6 +85,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/chat.h \
gui/confirmdialog.cpp \
gui/confirmdialog.h \
+ gui/connectiondialog.cpp \
+ gui/connectiondialog.h \
gui/debugwindow.cpp \
gui/debugwindow.h \
gui/emotepopup.cpp \
@@ -132,6 +136,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/playerbox.h \
gui/popupmenu.cpp \
gui/popupmenu.h \
+ gui/quitdialog.cpp \
+ gui/quitdialog.h \
gui/recorder.cpp \
gui/recorder.h \
gui/register.cpp \
@@ -140,8 +146,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/sdlinput.h \
gui/sell.cpp \
gui/sell.h \
- gui/serverselectdialog.cpp \
- gui/serverselectdialog.h \
+ gui/serverdialog.cpp \
+ gui/serverdialog.h \
gui/setup.cpp \
gui/setup.h \
gui/setup_audio.cpp \
@@ -189,22 +195,25 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/trade.h \
gui/truetypefont.cpp \
gui/truetypefont.h \
+ gui/unregisterdialog.cpp \
+ gui/unregisterdialog.h \
gui/updatewindow.cpp \
gui/updatewindow.h \
gui/viewport.cpp \
gui/viewport.h \
gui/windowmenu.cpp \
gui/windowmenu.h \
+ gui/worldselectdialog.cpp \
+ gui/worldselectdialog.h \
net/adminhandler.h \
net/charhandler.h \
net/chathandler.h \
+ net/gamehandler.h \
net/generalhandler.h \
net/guildhandler.h \
net/inventoryhandler.h \
net/logindata.h \
net/loginhandler.h \
- net/logouthandler.h \
- net/maphandler.h \
net/messagehandler.cpp \
net/messagehandler.h \
net/messagein.cpp \
@@ -219,6 +228,7 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
net/serverinfo.h \
net/specialhandler.h \
net/tradehandler.h \
+ net/worldinfo.h \
resources/action.cpp \
resources/action.h \
resources/ambientoverlay.cpp \
@@ -380,20 +390,10 @@ tmw_CXXFLAGS += -DTMWSERV_SUPPORT
tmw_SOURCES += \
gui/buddywindow.cpp \
gui/buddywindow.h \
- gui/changeemaildialog.cpp \
- gui/changeemaildialog.h \
- gui/connectiondialog.cpp \
- gui/connectiondialog.h \
gui/guildlistbox.cpp \
gui/guildlistbox.h \
gui/guildwindow.cpp \
gui/guildwindow.h \
- gui/quitdialog.cpp \
- gui/quitdialog.h \
- gui/serverdialog.cpp \
- gui/serverdialog.h \
- gui/unregisterdialog.cpp \
- gui/unregisterdialog.h \
net/tmwserv/accountserver/account.cpp \
net/tmwserv/accountserver/account.h \
net/tmwserv/accountserver/accountserver.cpp \
@@ -420,14 +420,16 @@ tmw_SOURCES += \
net/tmwserv/beinghandler.h \
net/tmwserv/buysellhandler.cpp \
net/tmwserv/buysellhandler.h \
- net/tmwserv/charserverhandler.cpp \
- net/tmwserv/charserverhandler.h \
+ net/tmwserv/charhandler.cpp \
+ net/tmwserv/charhandler.h \
net/tmwserv/chathandler.cpp \
net/tmwserv/chathandler.h \
net/tmwserv/connection.cpp \
net/tmwserv/connection.h \
net/tmwserv/effecthandler.cpp \
net/tmwserv/effecthandler.h \
+ net/tmwserv/gamehandler.cpp \
+ net/tmwserv/gamehandler.h \
net/tmwserv/generalhandler.cpp \
net/tmwserv/generalhandler.h \
net/tmwserv/guildhandler.cpp \
@@ -440,10 +442,6 @@ tmw_SOURCES += \
net/tmwserv/itemhandler.cpp \
net/tmwserv/loginhandler.cpp \
net/tmwserv/loginhandler.h \
- net/tmwserv/logouthandler.cpp \
- net/tmwserv/logouthandler.h \
- net/tmwserv/maphandler.cpp \
- net/tmwserv/maphandler.h \
net/tmwserv/network.cpp \
net/tmwserv/network.h \
net/tmwserv/npchandler.cpp \
@@ -478,6 +476,8 @@ tmw_SOURCES += \
net/ea/chathandler.h \
net/ea/equipmenthandler.cpp \
net/ea/equipmenthandler.h \
+ net/ea/gamehandler.cpp \
+ net/ea/gamehandler.h \
net/ea/generalhandler.cpp \
net/ea/generalhandler.h \
net/ea/inventoryhandler.cpp \
@@ -486,10 +486,6 @@ tmw_SOURCES += \
net/ea/itemhandler.h \
net/ea/loginhandler.cpp \
net/ea/loginhandler.h \
- net/ea/logouthandler.cpp \
- net/ea/logouthandler.h \
- net/ea/maphandler.cpp \
- net/ea/maphandler.h \
net/ea/network.cpp \
net/ea/network.h \
net/ea/npchandler.cpp \
diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp
index e64da120..6711f962 100644
--- a/src/commandhandler.cpp
+++ b/src/commandhandler.cpp
@@ -33,7 +33,7 @@
#include "net/adminhandler.h"
#include "net/chathandler.h"
-#include "net/maphandler.h"
+#include "net/gamehandler.h"
#include "net/net.h"
#include "net/partyhandler.h"
diff --git a/src/engine.cpp b/src/engine.cpp
index f56f8a49..2cb48ba0 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -34,7 +34,7 @@
#include "gui/okdialog.h"
#include "gui/viewport.h"
-#include "net/maphandler.h"
+#include "net/gamehandler.h"
#include "net/net.h"
#include "resources/mapreader.h"
@@ -44,6 +44,8 @@
#include "utils/gettext.h"
#include "utils/stringutils.h"
+#include <assert.h>
+
Engine::Engine():
mCurrentMap(0)
{
@@ -108,7 +110,7 @@ bool Engine::changeMap(const std::string &mapPath)
delete mCurrentMap;
mCurrentMap = newMap;
- Net::getMapHandler()->mapLoaded(mapPath);
+ Net::getGameHandler()->mapLoaded(mapPath);
return true;
}
diff --git a/src/game.cpp b/src/game.cpp
index de455b30..357092ae 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -71,14 +71,14 @@
#ifdef TMWSERV_SUPPORT
#include "gui/buddywindow.h"
#include "gui/guildwindow.h"
-#include "gui/quitdialog.h"
#endif
#include "gui/npcpostdialog.h"
+#include "gui/quitdialog.h"
#include "gui/specialswindow.h"
#include "gui/storagewindow.h"
+#include "net/gamehandler.h"
#include "net/generalhandler.h"
-#include "net/maphandler.h"
#include "net/net.h"
#include "net/tmwserv/inventoryhandler.h"
@@ -107,11 +107,7 @@ Joystick *joystick = NULL;
extern Window *weightNotice;
extern Window *deathNotice;
-#ifdef TMWSERV_SUPPORT
QuitDialog *quitDialog = NULL;
-#else
-ConfirmDialog *exitConfirm = NULL;
-#endif
OkDialog *disconnectedDialog = NULL;
ChatWindow *chatWindow;
@@ -164,9 +160,6 @@ namespace {
if (event.getId() == "yes" || event.getId() == "ok")
done = true;
-#ifdef EATHENA_SUPPORT
- exitConfirm = NULL;
-#endif
disconnectedDialog = NULL;
}
} exitListener;
@@ -325,13 +318,13 @@ Game::Game():
if (Joystick::getNumberOfJoysticks() > 0)
joystick = new Joystick(0);
-#ifdef EATHENA_SUPPORT
// fade out logon-music here too to give the desired effect of "flowing"
// into the game.
sound.fadeOutMusic(1000);
map_path = map_path.substr(0, map_path.rfind("."));
- engine->changeMap(map_path);
-#endif
+
+ if (!map_path.empty())
+ engine->changeMap(map_path);
setupWindow->setInGame(true);
@@ -344,7 +337,7 @@ Game::Game():
* packet is handled by the older version, but its response
* is ignored by the client
*/
- Net::getMapHandler()->ping(tick_time);
+ Net::getGameHandler()->ping(tick_time);
}
Game::~Game()
@@ -484,7 +477,7 @@ void Game::logic()
// Handle network stuff
Net::getGeneralHandler()->flushNetwork();
- if (!Net::getGeneralHandler()->isNetworkConnected())
+ if (!Net::getGameHandler()->isConnected())
{
if (state != STATE_ERROR)
{
@@ -560,15 +553,9 @@ void Game::handleInput()
{
if (keyboard.isKeyActive(keyboard.KEY_OK))
{
-#ifdef TMWSERV_SUPPORT
// Do not focus chat input when quit dialog is active
if (quitDialog != NULL && quitDialog->isVisible())
continue;
-#else
- if (exitConfirm &&
- keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT))
- done = true;
-#endif
// Close the Browser if opened
else if (helpWindow->isVisible() &&
keyboard.isKeyActive(keyboard.KEY_OK))
@@ -726,7 +713,6 @@ void Game::handleInput()
break;
// Quitting confirmation dialog
case KeyboardConfig::KEY_QUIT:
-#ifdef TMWSERV_SUPPORT
if (!quitDialog)
{
quitDialog = new QuitDialog(&done, &quitDialog);
@@ -736,20 +722,6 @@ void Game::handleInput()
{
quitDialog->action(gcn::ActionEvent(NULL, "cancel"));
}
-#else
- if (!exitConfirm)
- {
- exitConfirm = new ConfirmDialog(_("Quit"),
- _("Are you sure you "
- "want to quit?"));
- exitConfirm->addActionListener(&exitListener);
- exitConfirm->requestMoveToTop();
- }
- else
- {
- exitConfirm->action(gcn::ActionEvent(NULL, _("no")));
- }
-#endif
break;
default:
break;
diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp
index 69a627e1..be1cd3de 100644
--- a/src/gui/charselectdialog.cpp
+++ b/src/gui/charselectdialog.cpp
@@ -98,9 +98,6 @@ CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo,
mCharInfo(charInfo),
mLoginData(loginData),
mCharSelected(false)
-#ifdef EATHENA_SUPPORT
- , mGender(loginData->sex)
-#endif
{
mSelectButton = new Button(_("OK"), "ok", this);
mCancelButton = new Button(_("Cancel"), "cancel", this);
@@ -214,12 +211,8 @@ void CharSelectDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "cancel")
{
-#ifdef TMWSERV_SUPPORT
mCharInfo->clear();
- state = STATE_SWITCH_ACCOUNTSERVER_ATTEMPT;
-#else
- state = STATE_EXIT;
-#endif
+ state = STATE_SWITCH_SERVER_ATTEMPT;
}
#ifdef TMWSERV_SUPPORT
else if (event.getId() == "new")
@@ -250,7 +243,7 @@ void CharSelectDialog::action(const gcn::ActionEvent &event)
{
new CharDeleteConfirm(this);
}
- else if (n_character <= maxSlot)
+ else if (n_character < MAX_CHARACTER_COUNT)
{
// Start new character dialog
CharCreateDialog *charCreateDialog =
diff --git a/src/gui/charselectdialog.h b/src/gui/charselectdialog.h
index 4427017e..5f067404 100644
--- a/src/gui/charselectdialog.h
+++ b/src/gui/charselectdialog.h
@@ -83,11 +83,9 @@ class CharSelectDialog : public Window, public gcn::ActionListener
gcn::Button *mDelCharButton;
gcn::Button *mUnRegisterButton;
gcn::Button *mChangeEmailButton;
-
#else
gcn::Button *mNewDelCharButton;
gcn::Label *mJobLevelLabel;
- Gender mGender;
#endif
/**
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index f6272936..84a6a22c 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -50,73 +50,27 @@ LoginDialog::LoginDialog(LoginData *loginData):
{
gcn::Label *userLabel = new Label(_("Name:"));
gcn::Label *passLabel = new Label(_("Password:"));
-#ifdef EATHENA_SUPPORT
- gcn::Label *serverLabel = new Label(_("Server:"));
- gcn::Label *portLabel = new Label(_("Port:"));
- gcn::Label *dropdownLabel = new Label(_("Recent:"));
- std::vector<std::string> dfltServer;
- dfltServer.push_back("server.themanaworld.org");
- std::vector<std::string> dfltPort;
- dfltPort.push_back("6901");
- mServerList = new DropDownList("MostRecent00", dfltServer, dfltPort,
- MAX_SERVER_LIST_SIZE);
-#endif
mUserField = new TextField(mLoginData->username);
mPassField = new PasswordField(mLoginData->password);
-#ifdef EATHENA_SUPPORT
- mServerField = new TextField(mServerList->getServerAt(0));
- mPortField = new TextField(mServerList->getPortAt(0));
- mServerDropDown = new DropDown(mServerList);
-#endif
mKeepCheck = new CheckBox(_("Remember username"), mLoginData->remember);
mOkButton = new Button(_("OK"), "ok", this);
-#ifdef TMWSERV_SUPPORT
mCancelButton = new Button(_("Cancel"), "cancel", this);
-#else
- mCancelButton = new Button(_("Quit"), "cancel", this);
-#endif
mRegisterButton = new Button(_("Register"), "register", this);
mUserField->setActionEventId("ok");
mPassField->setActionEventId("ok");
-#ifdef EATHENA_SUPPORT
- mServerField->setActionEventId("ok");
- mPortField->setActionEventId("ok");
- mServerDropDown->setActionEventId("changeSelection");
-#endif
mUserField->addKeyListener(this);
mPassField->addKeyListener(this);
-#ifdef EATHENA_SUPPORT
- mServerField->addKeyListener(this);
- mPortField->addKeyListener(this);
- mServerDropDown->addKeyListener(this);
-#endif
mUserField->addActionListener(this);
mPassField->addActionListener(this);
-#ifdef EATHENA_SUPPORT
- mServerField->addActionListener(this);
- mPortField->addActionListener(this);
- mServerDropDown->addActionListener(this);
- mKeepCheck->addActionListener(this);
-#endif
place(0, 0, userLabel);
place(0, 1, passLabel);
-#ifdef EATHENA_SUPPORT
- place(0, 2, serverLabel);
- place(0, 3, portLabel);
- place(0, 4, dropdownLabel);
-#endif
place(1, 0, mUserField, 3).setPadding(1);
place(1, 1, mPassField, 3).setPadding(1);
-#ifdef EATHENA_SUPPORT
- place(1, 2, mServerField, 3).setPadding(1);
- place(1, 3, mPortField, 3).setPadding(1);
- place(1, 4, mServerDropDown, 3).setPadding(1);
-#endif
place(0, 5, mKeepCheck, 4);
place(0, 6, mRegisterButton).setHAlign(LayoutCell::LEFT);
place(2, 6, mCancelButton);
@@ -136,19 +90,12 @@ LoginDialog::LoginDialog(LoginData *loginData):
LoginDialog::~LoginDialog()
{
-#ifdef EATHENA_SUPPORT
- delete mServerList;
-#endif
}
void LoginDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok" && canSubmit())
{
-#ifdef EATHENA_SUPPORT
- mLoginData->hostname = mServerField->getText();
- mLoginData->port = getUShort(mPortField->getText());
-#endif
mLoginData->username = mUserField->getText();
mLoginData->password = mPassField->getText();
mLoginData->remember = mKeepCheck->isSelected();
@@ -156,41 +103,14 @@ void LoginDialog::action(const gcn::ActionEvent &event)
mOkButton->setEnabled(false);
mRegisterButton->setEnabled(false);
-#ifdef EATHENA_SUPPORT
- mServerList->save(mServerField->getText(), mPortField->getText());
- state = STATE_ACCOUNT;
-#else
state = STATE_LOGIN_ATTEMPT;
-#endif
}
-#ifdef EATHENA_SUPPORT
- else if (event.getId() == "changeSelection")
- {
- int selected = mServerDropDown->getSelected();
- mServerField->setText(mServerList->getServerAt(selected));
- mPortField->setText(mServerList->getPortAt(selected));
- }
-#endif
else if (event.getId() == "cancel")
{
-#ifdef TMWSERV_SUPPORT
- state = STATE_SWITCH_ACCOUNTSERVER;
-#else
- state = STATE_EXIT;
-#endif
+ state = STATE_SWITCH_SERVER;
}
else if (event.getId() == "register")
{
-#ifdef EATHENA_SUPPORT
- // Transfer these fields on to the register dialog
- mLoginData->hostname = mServerField->getText();
-
- if (isUShort(mPortField->getText()))
- mLoginData->port = getUShort(mPortField->getText());
- else
- mLoginData->port = 6901;
-#endif
-
mLoginData->username = mUserField->getText();
mLoginData->password = mPassField->getText();
@@ -207,136 +127,5 @@ bool LoginDialog::canSubmit()
{
return !mUserField->getText().empty() &&
!mPassField->getText().empty() &&
-#ifdef EATHENA_SUPPORT
- !mServerField->getText().empty() &&
- isUShort(mPortField->getText()) &&
-#endif
state == STATE_LOGIN;
}
-
-#ifdef EATHENA_SUPPORT
-bool LoginDialog::isUShort(const std::string &str)
-{
- if (str.empty())
- {
- return false;
- }
- unsigned long l = 0;
- for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end();
- strPtr != strEnd; ++strPtr)
- {
- if (*strPtr < '0' || *strPtr > '9')
- return false;
-
- l = l * 10 + (*strPtr - '0'); // *strPtr - '0' will never be negative
-
- if (l > 65535)
- return false;
- }
- return true;
-}
-
-unsigned short LoginDialog::getUShort(const std::string &str)
-{
- unsigned long l = 0;
- for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end();
- strPtr != strEnd; ++strPtr)
- {
- l = l * 10 + (*strPtr - '0');
- }
- return static_cast<unsigned short>(l);
-}
-
-/**
- * LoginDialog::DropDownList
- */
-
-void LoginDialog::DropDownList::saveEntry(const std::string &server,
- const std::string &port, int &saved)
-{
- if (saved < MAX_SERVER_LIST_SIZE && !server.empty())
- {
- config.setValue(mConfigPrefix + "Server" + toString(saved), server);
- config.setValue(mConfigPrefix + "Port" + toString(saved), port);
- ++saved;
- }
-}
-
-LoginDialog::DropDownList::DropDownList(std::string prefix,
- std::vector<std::string> dflt,
- std::vector<std::string> dfltPort,
- int maxEntries) :
- mConfigPrefix(prefix),
- mMaxEntries(maxEntries)
-{
- for (int i = 0; i < maxEntries; ++i)
- {
- std::string server = config.getValue(mConfigPrefix + "Server" +
- toString(i), "");
- if (server.empty()) // Just in case had original config entries
- {
- server = config.getValue(mConfigPrefix + "ServerList" +
- toString(i), "");
- }
- std::string port = config.getValue(mConfigPrefix + "Port" +
- toString(i), dfltPort.front());
-
- if (!server.empty())
- {
- mServers.push_back(server);
- mPorts.push_back(port);
- }
- }
- if (mServers.empty())
- {
- mServers.assign(dflt.begin(), dflt.end());
- mPorts.assign(dfltPort.begin(), dfltPort.end());
- }
-}
-
-void LoginDialog::DropDownList::save(const std::string &server,
- const std::string &port)
-{
- int position = 0;
- saveEntry(server, port, position);
- for (std::vector<std::string>::const_iterator sPtr = mServers.begin(),
- sEnd = mServers.end(),
- pPtr = mPorts.begin(),
- pEnd = mPorts.end();
- sPtr != sEnd && pPtr != pEnd;
- ++sPtr, ++pPtr)
- {
- if (*sPtr != server || *pPtr != port)
- saveEntry(*sPtr, *pPtr, position);
- }
-}
-
-int LoginDialog::DropDownList::getNumberOfElements()
-{
- return mServers.size();
-}
-
-std::string LoginDialog::DropDownList::getElementAt(int i)
-{
- if (i < 0 || i >= getNumberOfElements())
- return "";
-
- return getServerAt(i) + ":" + getPortAt(i);
-}
-
-std::string LoginDialog::DropDownList::getServerAt(int i)
-{
- if (i < 0 || i >= getNumberOfElements())
- return "";
-
- return mServers.at(i);
-}
-
-std::string LoginDialog::DropDownList::getPortAt(int i)
-{
- if (i < 0 || i >= getNumberOfElements())
- return "";
-
- return mPorts.at(i);
-}
-#endif
diff --git a/src/gui/login.h b/src/gui/login.h
index 97e76dfc..74a998ba 100644
--- a/src/gui/login.h
+++ b/src/gui/login.h
@@ -68,65 +68,14 @@ class LoginDialog : public Window, public gcn::ActionListener,
*/
bool canSubmit();
-#ifdef EATHENA_SUPPORT
- /**
- * Function to decide whether string is an unsigned short or not
- *
- * @param str the string to parse
- *
- * @return true is str is an unsigned short, false otherwise
- */
- static bool isUShort(const std::string &str);
-
- /**
- * Converts string to an unsigned short (undefined if invalid)
- *
- * @param str the string to parse
- *
- * @return the value str represents
- */
- static unsigned short getUShort(const std::string &str);
-
-#endif
gcn::TextField *mUserField;
gcn::TextField *mPassField;
-#ifdef EATHENA_SUPPORT
- gcn::TextField *mServerField;
- gcn::TextField *mPortField;
- gcn::DropDown *mServerDropDown;
-#endif
gcn::CheckBox *mKeepCheck;
gcn::Button *mOkButton;
gcn::Button *mCancelButton;
gcn::Button *mRegisterButton;
LoginData *mLoginData;
-
- /**
- * Helper class to keep a list of all the recent entries for the
- * dropdown
- */
- class DropDownList : public gcn::ListModel
- {
- private:
- std::vector<std::string> mServers;
- std::vector<std::string> mPorts;
- std::string mConfigPrefix;
- int mMaxEntries;
- void saveEntry(const std::string &server,
- const std::string &port, int &saved);
- public:
- DropDownList(std::string prefix,
- std::vector<std::string> dfltServer,
- std::vector<std::string> dfltPort,
- int maxEntries);
- void save(const std::string &server, const std::string &port);
- int getNumberOfElements();
- std::string getElementAt(int i);
- std::string getServerAt(int i);
- std::string getPortAt(int i);
- };
- DropDownList *mServerList;
};
#endif
diff --git a/src/gui/quitdialog.cpp b/src/gui/quitdialog.cpp
index 98657001..b2faa618 100644
--- a/src/gui/quitdialog.cpp
+++ b/src/gui/quitdialog.cpp
@@ -55,10 +55,11 @@ QuitDialog::QuitDialog(bool* quitGame, QuitDialog** pointerToMe):
//All states, when we're not logged in to someone.
if (state == STATE_CHOOSE_SERVER ||
- state == STATE_CONNECT_ACCOUNT ||
+ state == STATE_CONNECT_SERVER ||
state == STATE_LOGIN ||
state == STATE_LOGIN_ATTEMPT ||
- state == STATE_UPDATE)
+ state == STATE_UPDATE ||
+ state == STATE_LOAD_DATA)
{
mForceQuit->setSelected(true);
add(mForceQuit);
@@ -107,6 +108,7 @@ void QuitDialog::action(const gcn::ActionEvent &event)
{
*mQuitGame = true;
}
+
state = STATE_EXIT;
}
else if (mSwitchAccountServer->isSelected())
@@ -115,7 +117,8 @@ void QuitDialog::action(const gcn::ActionEvent &event)
{
*mQuitGame = true;
}
- state = STATE_SWITCH_ACCOUNTSERVER_ATTEMPT;
+
+ state = STATE_SWITCH_SERVER_ATTEMPT;
}
else if (mSwitchCharacter->isSelected())
{
@@ -123,7 +126,6 @@ void QuitDialog::action(const gcn::ActionEvent &event)
state = STATE_SWITCH_CHARACTER;
}
-
}
scheduleDelete();
}
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index f1313a5e..ec91c098 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -52,6 +52,8 @@ void WrongDataNoticeListener::action(const gcn::ActionEvent &event)
mTarget->requestFocus();
}
+Gender *RegisterDialog::useGender = NULL;
+
RegisterDialog::RegisterDialog(LoginData *loginData):
Window(_("Register")),
mWrongDataNoticeListener(new WrongDataNoticeListener),
@@ -60,21 +62,15 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
gcn::Label *userLabel = new Label(_("Name:"));
gcn::Label *passwordLabel = new Label(_("Password:"));
gcn::Label *confirmLabel = new Label(_("Confirm:"));
-#ifdef EATHENA_SUPPORT
- gcn::Label *serverLabel = new Label(_("Server:"));
- gcn::Label *portLabel = new Label(_("Port:"));
-#else
+#ifdef TMWSERV_SUPPORT
gcn::Label *emailLabel = new Label(_("Email:"));
#endif
mUserField = new TextField(loginData->username);
mPasswordField = new PasswordField(loginData->password);
mConfirmField = new PasswordField;
-#ifdef EATHENA_SUPPORT
- mServerField = new TextField(loginData->hostname);
- mPortField = new TextField(toString(loginData->port));
mMaleButton = new RadioButton(_("Male"), "sex", true);
mFemaleButton = new RadioButton(_("Female"), "sex", false);
-#else
+#ifdef TMWSERV_SUPPORT
mEmailField = new TextField;
#endif
mRegisterButton = new Button(_("Register"), "register", this);
@@ -85,21 +81,20 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
place(0, 0, userLabel);
place(0, 1, passwordLabel);
place(0, 2, confirmLabel);
-#ifdef EATHENA_SUPPORT
- place(1, 3, mMaleButton);
- place(2, 3, mFemaleButton);
- place(0, 4, serverLabel);
- place(0, 5, portLabel);
-#else
+
+ if (useGender)
+ {
+ place(1, 3, mMaleButton);
+ place(2, 3, mFemaleButton);
+ }
+
+#ifdef TMWSERV_SUPPORT
place(0, 3, emailLabel);
#endif
place(1, 0, mUserField, 3).setPadding(2);
place(1, 1, mPasswordField, 3).setPadding(2);
place(1, 2, mConfirmField, 3).setPadding(2);
-#ifdef EATHENA_SUPPORT
- place(1, 4, mServerField, 3).setPadding(2);
- place(1, 5, mPortField, 3).setPadding(2);
-#else
+#ifdef TMWSERV_SUPPORT
place(1, 3, mEmailField, 3).setPadding(2);
#endif
place = getPlacer(0, 2);
@@ -110,10 +105,6 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
mUserField->addKeyListener(this);
mPasswordField->addKeyListener(this);
mConfirmField->addKeyListener(this);
-#ifdef EATHENA_SUPPORT
- mServerField->addKeyListener(this);
- mPortField->addKeyListener(this);
-#endif
/* TODO:
* This is a quick and dirty way to respond to the ENTER key, regardless of
@@ -128,14 +119,6 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
mPasswordField->addActionListener(this);
mConfirmField->addActionListener(this);
-#ifdef EATHENA_SUPPORT
- mServerField->setActionEventId("register");
- mPortField->setActionEventId("register");
-
- mServerField->addActionListener(this);
- mPortField->addActionListener(this);
-#endif
-
center();
setVisible(true);
mUserField->requestFocus();
@@ -229,21 +212,15 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
mLoginData->username = mUserField->getText();
mLoginData->password = mPasswordField->getText();
-#ifdef EATHENA_SUPPORT
- mLoginData->hostname = mServerField->getText();
- mLoginData->port = getUShort(mPortField->getText());
- mLoginData->sex =
- mFemaleButton->isSelected() ? GENDER_FEMALE : GENDER_MALE;
-#else
+ if (useGender)
+ *useGender = mFemaleButton->isSelected() ? GENDER_FEMALE :
+ GENDER_MALE;
+#ifdef TMWSERV_SUPPORT
mLoginData->email = mEmailField->getText();
#endif
mLoginData->registerLogin = true;
-#ifdef TMWSERV_SUPPORT
state = STATE_REGISTER_ATTEMPT;
-#else
- state = STATE_ACCOUNT;
-#endif
}
}
}
@@ -253,50 +230,15 @@ void RegisterDialog::keyPressed(gcn::KeyEvent &keyEvent)
mRegisterButton->setEnabled(canSubmit());
}
+void RegisterDialog::setGender(Gender *gender)
+{
+ useGender = gender;
+}
+
bool RegisterDialog::canSubmit() const
{
return !mUserField->getText().empty() &&
!mPasswordField->getText().empty() &&
!mConfirmField->getText().empty() &&
-#ifdef EATHENA_SUPPORT
- !mServerField->getText().empty() &&
- isUShort(mPortField->getText()) &&
-#endif
state == STATE_REGISTER;
}
-
-#ifdef EATHENA_SUPPORT
-bool RegisterDialog::isUShort(const std::string &str)
-{
- if (str.empty())
- {
- return false;
- }
- unsigned long l = 0;
- for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end();
- strPtr != strEnd; ++strPtr)
- {
- if (*strPtr < '0' || *strPtr > '9')
- {
- return false;
- }
- l = l * 10 + (*strPtr - '0'); // *strPtr - '0' will never be negative
- if (l > 65535)
- {
- return false;
- }
- }
- return true;
-}
-
-unsigned short RegisterDialog::getUShort(const std::string &str)
-{
- unsigned long l = 0;
- for (std::string::const_iterator strPtr = str.begin(), strEnd = str.end();
- strPtr != strEnd; ++strPtr)
- {
- l = l * 10 + (*strPtr - '0');
- }
- return static_cast<unsigned short>(l);
-}
-#endif
diff --git a/src/gui/register.h b/src/gui/register.h
index 6839c805..729b21c3 100644
--- a/src/gui/register.h
+++ b/src/gui/register.h
@@ -24,6 +24,8 @@
#include "gui/widgets/window.h"
+#include "player.h"
+
#include <guichan/actionlistener.hpp>
#include <guichan/keylistener.hpp>
@@ -78,6 +80,13 @@ class RegisterDialog : public Window, public gcn::ActionListener,
*/
void keyPressed(gcn::KeyEvent &keyEvent);
+ /**
+ * Tell the dialog to show a gender selection. Value stored in the
+ * passed Gender pointer. Default Gender from pointer. Passing NULL
+ * disables the feature.
+ */
+ static void setGender(Gender *gender);
+
private:
/**
* Returns whether submit can be enabled. This is true in the register
@@ -85,46 +94,23 @@ class RegisterDialog : public Window, public gcn::ActionListener,
*/
bool canSubmit() const;
-#ifdef EATHENA_SUPPORT
- /**
- * Function to decide whether string is an unsigned short or not
- *
- * @param str the string to parse
- *
- * @return true if str is an unsigned short, false otherwise
- */
- static bool isUShort(const std::string &str);
-
- /**
- * Converts string to an unsigned short (undefined if invalid)
- *
- * @param str the string to parse
- *
- * @return the value str represents
- */
- static unsigned short getUShort(const std::string &str);
-#endif
-
gcn::TextField *mUserField;
gcn::TextField *mPasswordField;
gcn::TextField *mConfirmField;
-#ifdef EATHENA_SUPPORT
- gcn::TextField *mServerField;
- gcn::TextField *mPortField;
-#else
+#ifdef TMWSERV_SUPPORT
gcn::TextField *mEmailField;
#endif
gcn::Button *mRegisterButton;
gcn::Button *mCancelButton;
-#ifdef EATHENA_SUPPORT
gcn::RadioButton *mMaleButton;
gcn::RadioButton *mFemaleButton;
-#endif
WrongDataNoticeListener *mWrongDataNoticeListener;
LoginData *mLoginData;
+
+ static Gender *useGender;
};
#endif
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp
index bd6b7d4b..91d2dbc7 100644
--- a/src/gui/serverdialog.cpp
+++ b/src/gui/serverdialog.cpp
@@ -29,12 +29,12 @@
#include "gui/widgets/layout.h"
#include "gui/widgets/textfield.h"
-#include "net/logindata.h"
-
#include "configuration.h"
#include "log.h"
#include "main.h"
+#include "net/net.h"
+
#include "utils/gettext.h"
#include "utils/stringutils.h"
@@ -51,48 +51,46 @@ int ServersListModel::getNumberOfElements()
std::string ServersListModel::getElementAt(int elementIndex)
{
- std::string myServer = "";
- myServer = servers.at(elementIndex).serverName;
+ std::string myServer = std::string(servers.at(elementIndex).hostname);
myServer += ":";
myServer += toString(servers.at(elementIndex).port);
return myServer;
}
-void ServersListModel::addFirstElement(Server server)
+void ServersListModel::addFirstElement(ServerInfo server)
{
// Equivalent to push_front
- std::vector<Server>::iterator MyIterator = servers.begin();
+ std::vector<ServerInfo>::iterator MyIterator = servers.begin();
servers.insert(MyIterator, 1, server);
}
-void ServersListModel::addElement(Server server)
+void ServersListModel::addElement(ServerInfo server)
{
servers.push_back(server);
}
-ServerDialog::ServerDialog(LoginData *loginData):
- Window(_("Choose Your Server")), mLoginData(loginData)
+ServerDialog::ServerDialog(ServerInfo *serverInfo):
+ Window(_("Choose Your Server")), mServerInfo(serverInfo)
{
gcn::Label *serverLabel = new Label(_("Server:"));
gcn::Label *portLabel = new Label(_("Port:"));
- mServerNameField = new TextField(mLoginData->hostname);
- mPortField = new TextField(toString(mLoginData->port));
+ mServerNameField = new TextField(mServerInfo->hostname);
+ mPortField = new TextField(toString(mServerInfo->port));
// Add the most used servers from config
mMostUsedServersListModel = new ServersListModel;
- Server currentServer;
+ ServerInfo currentServer;
std::string currentConfig = "";
for (int i=0; i<=MAX_SERVERLIST; i++)
{
- currentServer.serverName = "";
- currentServer.port = 0;
+ currentServer.clear();
currentConfig = "MostUsedServerName" + toString(i);
- currentServer.serverName = config.getValue(currentConfig, "");
+ currentServer.hostname = config.getValue(currentConfig, "");
currentConfig = "MostUsedServerPort" + toString(i);
currentServer.port = (short)atoi(config.getValue(currentConfig, "").c_str());
- if (!currentServer.serverName.empty() || currentServer.port != 0)
+ if (!currentServer.hostname.empty() || currentServer.port != 0)
{
mMostUsedServersListModel->addElement(currentServer);
}
@@ -111,6 +109,8 @@ ServerDialog::ServerDialog(LoginData *loginData):
mPortField->addActionListener(this);
mMostUsedServersDropDown->addActionListener(this);
+ mMostUsedServersDropDown->setSelected(0);
+
place(0, 0, serverLabel);
place(0, 1, portLabel);
place(1, 0, mServerNameField, 3).setPadding(2);
@@ -150,9 +150,9 @@ ServerDialog::action(const gcn::ActionEvent &event)
else if (event.getId() == "changeSelection")
{
// Change the textField Values according to new selection
- Server myServer = mMostUsedServersListModel->getServer
+ ServerInfo myServer = mMostUsedServersListModel->getServer
(mMostUsedServersDropDown->getSelected());
- mServerNameField->setText(myServer.serverName);
+ mServerNameField->setText(myServer.hostname);
mPortField->setText(toString(myServer.port));
}
else if (event.getId() == "connect")
@@ -166,39 +166,39 @@ ServerDialog::action(const gcn::ActionEvent &event)
}
else
{
- mLoginData->hostname = mServerNameField->getText();
- mLoginData->port = (short) atoi(mPortField->getText().c_str());
mOkButton->setEnabled(false);
mCancelButton->setEnabled(false);
// First, look if the entry is a new one.
- Server currentServer;
+ ServerInfo currentServer;
+ ServerInfo tempServer;
+ currentServer.hostname = mServerNameField->getText();
+ currentServer.port = (short) atoi(mPortField->getText().c_str());
bool newEntry = true;
for (int i = 0; i < mMostUsedServersListModel->getNumberOfElements(); i++)
{
- currentServer = mMostUsedServersListModel->getServer(i);
- if (currentServer.serverName == mLoginData->hostname &&
- currentServer.port == mLoginData->port)
+ tempServer = mMostUsedServersListModel->getServer(i);
+ if (tempServer.hostname == mServerInfo->hostname &&
+ tempServer.port == mServerInfo->port)
newEntry = false;
}
- // Then, add it to config if it's really new
- currentServer.serverName = mLoginData->hostname;
- currentServer.port = mLoginData->port;
if (newEntry)
mMostUsedServersListModel->addFirstElement(currentServer);
// Write the entry in config
std::string currentConfig = "";
for (int i = 0; i < mMostUsedServersListModel->getNumberOfElements(); i++)
{
- currentServer = mMostUsedServersListModel->getServer(i);
+ tempServer = mMostUsedServersListModel->getServer(i);
currentConfig = "MostUsedServerName" + toString(i);
- config.setValue(currentConfig, currentServer.serverName);
+ config.setValue(currentConfig, tempServer.hostname);
currentConfig = "MostUsedServerPort" + toString(i);
- config.setValue(currentConfig, toString(currentServer.port));
+ config.setValue(currentConfig, toString(tempServer.port));
}
- state = STATE_CONNECT_ACCOUNT;
+ mServerInfo->hostname = currentServer.hostname;
+ mServerInfo->port = currentServer.port;
+ state = STATE_CONNECT_SERVER;
}
}
else if (event.getId() == "cancel")
diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h
index 93903c08..f1cd26d4 100644
--- a/src/gui/serverdialog.h
+++ b/src/gui/serverdialog.h
@@ -26,7 +26,7 @@
#include "guichanfwd.h"
-#include "net/tmwserv/network.h"
+#include "net/serverinfo.h"
#include <guichan/actionlistener.hpp>
#include <guichan/listmodel.hpp>
@@ -35,20 +35,6 @@
#include <vector>
class DropDown;
-class LoginData;
-
-/**
- * A server structure to keep pairs of servers and ports.
- */
-struct Server
-{
- Server():
- port(0)
- {}
-
- std::string serverName;
- short port;
-};
/**
* Server and Port List Model
@@ -69,21 +55,21 @@ class ServersListModel : public gcn::ListModel
/**
* Used to get the corresponding Server struct
*/
- Server getServer(int elementIndex) const
+ ServerInfo getServer(int elementIndex) const
{ return servers[elementIndex]; }
/**
* Add an Element at the end of the server list
*/
- void addElement(Server server);
+ void addElement(ServerInfo server);
/**
* Add an Element at the beginning of the server list
*/
- void addFirstElement(Server server);
+ void addFirstElement(ServerInfo server);
private:
- std::vector<Server> servers;
+ std::vector<ServerInfo> servers;
};
/**
@@ -99,7 +85,7 @@ class ServerDialog : public Window, public gcn::ActionListener
*
* @see Window::Window
*/
- ServerDialog(LoginData *loginData);
+ ServerDialog(ServerInfo *serverInfo);
/**
* Destructor
@@ -120,7 +106,7 @@ class ServerDialog : public Window, public gcn::ActionListener
DropDown *mMostUsedServersDropDown;
ServersListModel *mMostUsedServersListModel;
- LoginData *mLoginData;
+ ServerInfo *mServerInfo;
};
#endif
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index bb2128b4..b39ee8c2 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -183,7 +183,7 @@ void UpdaterWindow::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "play")
{
- state = STATE_LOADDATA;
+ state = STATE_LOAD_DATA;
}
}
diff --git a/src/gui/serverselectdialog.cpp b/src/gui/worldselectdialog.cpp
index f492ebc7..cdc6bb75 100644
--- a/src/gui/serverselectdialog.cpp
+++ b/src/gui/worldselectdialog.cpp
@@ -19,21 +19,23 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "gui/serverselectdialog.h"
+#include "gui/worldselectdialog.h"
#include "gui/widgets/button.h"
#include "gui/widgets/listbox.h"
#include "gui/widgets/scrollarea.h"
#include "net/logindata.h"
-#include "net/serverinfo.h"
+#include "net/loginhandler.h"
+#include "net/net.h"
+#include "net/worldinfo.h"
#include "main.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
-extern SERVER_INFO **server_info;
+extern WorldInfo **server_info;
/**
* The list model for the server list.
@@ -41,26 +43,31 @@ extern SERVER_INFO **server_info;
class ServerListModel : public gcn::ListModel
{
public:
+ ServerListModel(Worlds worlds):
+ mWorlds(worlds)
+ {
+ }
+
virtual ~ServerListModel() {}
int getNumberOfElements()
{
- return n_server;
+ return mWorlds.size();
}
std::string getElementAt(int i)
{
- const SERVER_INFO *si = server_info[i];
+ const WorldInfo *si = mWorlds[i];
return si->name + " (" + toString(si->online_users) + ")";
}
+ private:
+ Worlds mWorlds;
};
-ServerSelectDialog::ServerSelectDialog(LoginData *loginData, State nextState):
- Window(_("Select Server")),
- mLoginData(loginData),
- mNextState(nextState)
+WorldSelectDialog::WorldSelectDialog(Worlds worlds):
+ Window(_("Select World"))
{
- mServerListModel = new ServerListModel;
+ mServerListModel = new ServerListModel(worlds);
mServerList = new ListBox(mServerListModel);
ScrollArea *mScrollArea = new ScrollArea(mServerList);
mOkButton = new Button(_("OK"), "ok", this);
@@ -88,7 +95,7 @@ ServerSelectDialog::ServerSelectDialog(LoginData *loginData, State nextState):
add(mOkButton);
add(mCancelButton);
- if (n_server == 0)
+ if (worlds.size() == 0)
// Disable Ok button
mOkButton->setEnabled(false);
else
@@ -100,21 +107,18 @@ ServerSelectDialog::ServerSelectDialog(LoginData *loginData, State nextState):
mOkButton->requestFocus();
}
-ServerSelectDialog::~ServerSelectDialog()
+WorldSelectDialog::~WorldSelectDialog()
{
delete mServerListModel;
}
-void ServerSelectDialog::action(const gcn::ActionEvent &event)
+void WorldSelectDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok")
{
mOkButton->setEnabled(false);
- const SERVER_INFO *si = server_info[mServerList->getSelected()];
- mLoginData->hostname = ipToString(si->address);
- mLoginData->port = si->port;
- mLoginData->updateHost = si->updateHost;
- state = mNextState;
+ Net::getLoginHandler()->chooseServer(mServerList->getSelected());
+ state = STATE_UPDATE;
}
else if (event.getId() == "cancel")
state = STATE_LOGIN;
diff --git a/src/gui/serverselectdialog.h b/src/gui/worldselectdialog.h
index fd1484af..be18705c 100644
--- a/src/gui/serverselectdialog.h
+++ b/src/gui/worldselectdialog.h
@@ -19,15 +19,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _CHAR_SEL_SERVER_H
-#define _CHAR_SEL_SERVER_H
+#ifndef WORLD_SELECT_DIALOG_H
+#define WORLD_SELECT_DIALOG_H
#include "gui/widgets/window.h"
-#include "main.h"
+#include "net/worldinfo.h"
#include <guichan/actionlistener.hpp>
#include <guichan/listmodel.hpp>
+#include <vector>
class LoginData;
class ServerListModel;
@@ -37,19 +38,19 @@ class ServerListModel;
*
* \ingroup Interface
*/
-class ServerSelectDialog : public Window, public gcn::ActionListener {
+class WorldSelectDialog : public Window, public gcn::ActionListener {
public:
/**
* Constructor
*
* @see Window::Window
*/
- ServerSelectDialog(LoginData *loginData, State nextState);
+ WorldSelectDialog(Worlds worlds);
/**
* Destructor.
*/
- ~ServerSelectDialog();
+ ~WorldSelectDialog();
/**
* Called when receiving actions from the widgets.
@@ -57,11 +58,9 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
void action(const gcn::ActionEvent &event);
private:
- LoginData *mLoginData;
ServerListModel *mServerListModel;
gcn::ListBox *mServerList;
gcn::Button *mOkButton;
- State mNextState;
};
-#endif
+#endif // WORLD_SELECT_DIALOG_H
diff --git a/src/main.cpp b/src/main.cpp
index 29a1c132..3c83e6eb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -44,39 +44,33 @@
#include "gui/widgets/progressbar.h"
#include "gui/charselectdialog.h"
+#include "gui/connectiondialog.h"
#include "gui/gui.h"
#include "gui/skin.h"
#include "gui/login.h"
#include "gui/okdialog.h"
#include "gui/palette.h"
+#include "gui/quitdialog.h"
#include "gui/register.h"
#include "gui/sdlinput.h"
-#include "gui/serverselectdialog.h"
-#include "gui/setup.h"
-#ifdef TMWSERV_SUPPORT
-#include "gui/connectiondialog.h"
-#include "gui/quitdialog.h"
#include "gui/serverdialog.h"
-#endif
+#include "gui/setup.h"
#include "gui/updatewindow.h"
+#include "gui/worldselectdialog.h"
#include "net/charhandler.h"
+#include "net/gamehandler.h"
#include "net/generalhandler.h"
#include "net/logindata.h"
#include "net/loginhandler.h"
-#include "net/maphandler.h"
#include "net/net.h"
-#include "net/serverinfo.h"
+#include "net/worldinfo.h"
#ifdef TMWSERV_SUPPORT
-#include "net/tmwserv/charserverhandler.h"
+#include "net/tmwserv/charhandler.h"
#include "net/tmwserv/connection.h"
#include "net/tmwserv/generalhandler.h"
#include "net/tmwserv/loginhandler.h"
-#include "net/tmwserv/logouthandler.h"
#include "net/tmwserv/network.h"
-#else
-#include "net/ea/generalhandler.h"
-#include "net/ea/network.h"
#endif
#ifdef TMWSERV_SUPPORT
@@ -147,14 +141,8 @@ namespace
static const int defaultSfxVolume = 100;
static const int defaultMusicVolume = 60;
-std::string token; //used to store magic_token
-
// Account infos
-char n_server, n_character;
-
-// TODO Anyone knows a good location for this? Or a way to make it non-global?
-class SERVER_INFO;
-SERVER_INFO **server_info;
+char n_character;
#ifdef TMWSERV_SUPPORT
extern Net::Connection *gameServerConnection;
@@ -165,7 +153,7 @@ extern Net::Connection *accountServerConnection;
Graphics *graphics;
Game *game = 0;
-State state = STATE_NULL;
+State state = STATE_START;
std::string errorMessage;
Sound sound;
@@ -177,7 +165,7 @@ Logger *logger; /**< Log object */
KeyboardConfig keyboard;
LoginData loginData;
-LockedArray<LocalPlayer*> charInfo(maxSlot + 1);
+LockedArray<LocalPlayer*> charInfo(MAX_CHARACTER_COUNT);
Palette *guiPalette;
@@ -265,7 +253,7 @@ static void setUpdatesDir()
else
{
logger->log("Warning: no protocol was specified for the update host");
- updates << "updates/" << updateHost << "/" << loginData.port;
+ updates << "updates/" << updateHost;
updatesDir = updates.str();
}
@@ -347,7 +335,6 @@ static void initConfiguration(const Options &options)
logger->log("Initializing configuration...");
std::string defaultHost = branding.getValue("defaultServer",
"server.themanaworld.org");
- config.setValue("host", defaultHost);
int defaultPort = (int)branding.getValue("defaultPort", DEFAULT_PORT);
config.setValue("port", defaultPort);
config.setValue("hwaccel", false);
@@ -495,11 +482,6 @@ static void initEngine(const Options &options)
emoteShortcut = new EmoteShortcut;
gui = new Gui(graphics);
-#ifdef TMWSERV_SUPPORT
- state = STATE_CHOOSE_SERVER; /**< Initial game state */
-#else
- state = STATE_LOGIN; /**< Initial game state */
-#endif
// Initialize sound engine
try
@@ -692,11 +674,7 @@ struct ErrorListener : public gcn::ActionListener
{
void action(const gcn::ActionEvent &event)
{
-#ifdef TMWSERV_SUPPORT
state = STATE_CHOOSE_SERVER;
-#else
- state = loginData.registerLogin ? STATE_REGISTER : STATE_LOGIN;
-#endif
}
} errorListener;
@@ -708,7 +686,6 @@ struct AccountListener : public gcn::ActionListener
}
} accountListener;
-#ifdef TMWSERV_SUPPORT
struct LoginListener : public gcn::ActionListener
{
void action(const gcn::ActionEvent &event)
@@ -716,28 +693,15 @@ struct LoginListener : public gcn::ActionListener
state = STATE_LOGIN;
}
} loginListener;
-#endif
} // namespace
// TODO Find some nice place for these functions
-#ifdef TMWSERV_SUPPORT
static void accountLogin(LoginData *loginData)
-#else
-static void accountLogin(Network *network, LoginData *loginData)
-#endif
{
-#ifdef EATHENA_SUPPORT
- logger->log("Trying to connect to account server...");
-#endif
logger->log("Username is %s", loginData->username.c_str());
-#ifdef EATHENA_SUPPORT
- network->connect(loginData->hostname, loginData->port);
-#endif
-#ifdef TMWSERV_SUPPORT
Net::getCharHandler()->setCharInfo(&charInfo);
-#endif
// Send login infos
if (loginData->registerLogin) {
@@ -753,84 +717,11 @@ static void accountLogin(Network *network, LoginData *loginData)
// than the login gui window
if (loginData->remember)
{
- config.setValue("host", loginData->hostname);
config.setValue("username", loginData->username);
}
config.setValue("remember", loginData->remember);
}
-#ifdef EATHENA_SUPPORT
-
-static void positionDialog(Window *dialog, int screenWidth, int screenHeight)
-{
- dialog->setPosition(
- (screenWidth - dialog->getWidth()) / 2,
- (screenHeight - dialog->getHeight()) / 2);
-}
-
-static void charLogin(Network *network, LoginData *loginData)
-{
- logger->log("Trying to connect to char server...");
- network->connect(loginData->hostname, loginData->port);
- Net::getCharHandler()->setCharInfo(&charInfo);
-
- // Send login infos
- Net::getCharHandler()->connect(loginData);
-}
-
-static void mapLogin(Network *network, LoginData *loginData)
-{
- logger->log("Memorizing selected character %s",
- player_node->getName().c_str());
- config.setValue("lastCharacter", player_node->getName());
-
- logger->log("Trying to connect to map server...");
- logger->log("Map: %s", map_path.c_str());
-
- // EAthena::MapHandler *mapHandler = new EAthena::MapHandler;
- network->connect(loginData->hostname, loginData->port);
-
- Net::getMapHandler()->connect(loginData);
-}
-
-#else
-
-static void accountRegister(LoginData *loginData)
-{
- logger->log("Username is %s", loginData->username.c_str());
-
- Net::getCharHandler()->setCharInfo(&charInfo);
- Net::getLoginHandler()->registerAccount(loginData);
-}
-
-static void switchCharacter(std::string *passToken)
-{
- Net::getLogoutHandler()->reset();
- Net::getLogoutHandler()->setScenario(LOGOUT_SWITCH_CHARACTER, passToken);
-}
-
-static void switchAccountServer()
-{
- Net::getLogoutHandler()->reset();
- Net::getLogoutHandler()->setScenario(LOGOUT_SWITCH_LOGIN);
-}
-
-static void logoutThenExit()
-{
- Net::getLogoutHandler()->reset();
- Net::getLogoutHandler()->setScenario(LOGOUT_EXIT);
-}
-
-static void reconnectAccount(const std::string &passToken)
-{
- Net::getCharHandler()->setCharInfo(&charInfo);
-
- Net::AccountServer::reconnectAccount(accountServerConnection, passToken);
-}
-
-#endif
-
-
extern "C" char const *_nl_locale_name_default(void);
static void initInternationalization()
@@ -910,9 +801,7 @@ int main(int argc, char *argv[])
guiPalette = new Palette;
Window *currentDialog = NULL;
-#ifdef TMWSERV_SUPPORT
QuitDialog* quitDialog = NULL;
-#endif
setupWindow = new Setup;
gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
@@ -932,42 +821,36 @@ int main(int argc, char *argv[])
sound.playMusic(branding.getValue("loginMusic", "Magick - Real.ogg"));
- // Initialize login data
- loginData.hostname = options.serverName;
- loginData.port = options.serverPort;
+ // Initialize default server
+ ServerInfo currentServer;
+ currentServer.hostname = options.serverName;
+ currentServer.port = options.serverPort;
loginData.username = options.username;
loginData.password = options.password;
loginData.remember = config.getValue("remember", 0);
loginData.registerLogin = false;
- if (loginData.hostname.empty()) {
- loginData.hostname = branding.getValue("defaultServer",
- "server.themanaworld.org").c_str();
+ if (currentServer.hostname.empty()) {
+ currentServer.hostname = branding.getValue("defaultServer",
+ "server.themanaworld.org").c_str();
}
if (options.serverPort == 0) {
- loginData.port = (short) branding.getValue("defaultPort", DEFAULT_PORT);
+ currentServer.port = (short) branding.getValue("defaultPort",
+ DEFAULT_PORT);
}
if (loginData.username.empty() && loginData.remember) {
loginData.username = config.getValue("username", "");
}
-#ifdef TMWSERV_SUPPORT
- Net::initialize();
- new TmwServ::GeneralHandler; // Currently doesn't need registration
-#else
- Network *network = new Network;
- network->registerHandler(new EAthena::GeneralHandler);
-#endif
-
- Net::getGeneralHandler()->load();
-
int screenWidth = (int) config.getValue("screenwidth", defaultScreenWidth);
int screenHeight = static_cast<int>(config.getValue("screenheight",
defaultScreenHeight));
desktop->setSize(screenWidth, screenHeight);
-
- State oldstate = STATE_EXIT; // We start with a status change
+
+ if (state != STATE_ERROR)
+ state = STATE_CHOOSE_SERVER;
+ State oldstate = STATE_START; // We start with a status change
SDL_Event event;
@@ -989,14 +872,10 @@ int main(int argc, char *argv[])
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
{
-#ifdef TMWSERV_SUPPORT
if (!quitDialog)
quitDialog = new QuitDialog(NULL, &quitDialog);
else
quitDialog->requestMoveToTop();
-#else
- state = STATE_EXIT;
-#endif
}
break;
}
@@ -1004,11 +883,13 @@ int main(int argc, char *argv[])
guiInput->pushInput(event);
}
- Net::getGeneralHandler()->flushNetwork();
+ if (Net::getGeneralHandler())
+ {
+ Net::getGeneralHandler()->flushNetwork();
+ Net::getGeneralHandler()->tick();
+ }
gui->logic();
- Net::getGeneralHandler()->tick();
-
if (progressBar && progressBar->isVisible())
{
progressBar->setProgress(progressBar->getProgress() + 0.005f);
@@ -1019,31 +900,19 @@ int main(int argc, char *argv[])
gui->draw();
graphics->updateScreen();
-#ifdef TMWSERV_SUPPORT
// TODO: Add connect timeouts
- if (state == STATE_CONNECT_ACCOUNT &&
- accountServerConnection->isConnected())
- {
- if (options.skipUpdate) {
- state = STATE_LOADDATA;
- } else {
- state = STATE_UPDATE;
- }
- }
- else if (state == STATE_CONNECT_GAME &&
- gameServerConnection->isConnected() &&
- chatServerConnection->isConnected())
+ if (state == STATE_CONNECT_GAME &&
+ Net::getGameHandler()->isConnected())
{
- accountServerConnection->disconnect();
-// Net::clearHandlers();
+ Net::getLoginHandler()->disconnect();
state = STATE_GAME;
}
- else if (state == STATE_RECONNECT_ACCOUNT &&
- accountServerConnection->isConnected())
+ else if (state == STATE_CONNECT_SERVER &&
+ Net::getLoginHandler()->isConnected())
{
- reconnectAccount(token);
- state = STATE_WAIT;
+ Net::getCharHandler()->setCharInfo(&charInfo);
+ state = STATE_LOGIN;
}
if (state != oldstate)
@@ -1079,9 +948,11 @@ int main(int argc, char *argv[])
// We show the dialog box only if the command-line
// options weren't set.
if (options.serverName.empty() && options.serverPort == 0) {
- currentDialog = new ServerDialog(&loginData);
+ currentDialog = new ServerDialog(&currentServer);
} else {
- state = STATE_CONNECT_ACCOUNT;
+ state = STATE_CONNECT_SERVER;
+
+ Net::connectToServer(currentServer);
// Reset options so that cancelling or connect
// timeout will show the server dialog.
@@ -1090,26 +961,32 @@ int main(int argc, char *argv[])
}
break;
- case STATE_CONNECT_ACCOUNT:
- logger->log("State: CONNECT_ACCOUNT");
- logger->log("Trying to connect to account server...");
- accountServerConnection->connect(loginData.hostname,
- loginData.port);
+ case STATE_CONNECT_SERVER:
+ Net::connectToServer(currentServer);
+
+ logger->log("State: CONNECT_SERVER");
currentDialog = new ConnectionDialog(
- STATE_SWITCH_ACCOUNTSERVER_ATTEMPT);
+ STATE_SWITCH_SERVER_ATTEMPT);
break;
case STATE_UPDATE:
- // Determine which source to use for the update host
- if (!options.updateHost.empty())
- updateHost = options.updateHost;
+ if (options.skipUpdate)
+ {
+ state = STATE_LOAD_DATA;
+ }
else
- updateHost = loginData.updateHost;
+ {
+ // Determine which source to use for the update host
+ if (!options.updateHost.empty())
+ updateHost = options.updateHost;
+ else
+ updateHost = loginData.updateHost;
- setUpdatesDir();
- logger->log("State: UPDATE");
- currentDialog = new UpdaterWindow(updateHost,
- homeDir + "/" + updatesDir);
+ setUpdatesDir();
+ logger->log("State: UPDATE");
+ currentDialog = new UpdaterWindow(updateHost,
+ homeDir + "/" + updatesDir);
+ }
break;
case STATE_LOGIN:
@@ -1129,8 +1006,12 @@ int main(int argc, char *argv[])
}
break;
- case STATE_LOADDATA:
- logger->log("State: LOADDATA");
+ case STATE_LOGIN_ATTEMPT:
+ accountLogin(&loginData);
+ break;
+
+ case STATE_LOAD_DATA:
+ logger->log("State: LOAD DATA");
// Add customdata directory
ResourceManager::getInstance()->searchAndAddArchives(
@@ -1145,15 +1026,43 @@ int main(int argc, char *argv[])
MonsterDB::load();
NPCDB::load();
EmoteDB::load();
+ StatusEffect::load();
Units::loadUnits();
desktop->reloadWallpaper();
- state = STATE_LOGIN;
+ state = STATE_GET_CHARACTERS;
break;
- case STATE_LOGIN_ATTEMPT:
- accountLogin(&loginData);
+ case STATE_WORLD_SELECT:
+ logger->log("State: WORLD SELECT");
+ {
+ Worlds worlds = Net::getLoginHandler()->getWorlds();
+ if (worlds.size() == 0)
+ {
+ state = STATE_UPDATE;
+ }
+ else if (worlds.size() == 1)
+ {
+ Net::getLoginHandler()->chooseServer(0);
+ state = STATE_UPDATE;
+ }
+ else
+ {
+ currentDialog = new WorldSelectDialog(worlds);
+ if (options.chooseDefault)
+ {
+ ((WorldSelectDialog*) currentDialog)->action(
+ gcn::ActionEvent(NULL, "ok"));
+ }
+
+ state = STATE_WORLD_SELECT_ATTEMPT;
+ }
+ }
+ break;
+
+ case STATE_WORLD_SELECT_ATTEMPT:
+ // TODO
break;
case STATE_LOGIN_ERROR:
@@ -1163,21 +1072,24 @@ int main(int argc, char *argv[])
currentDialog = NULL; // OkDialog deletes itself
break;
- case STATE_SWITCH_ACCOUNTSERVER:
- logger->log("State: SWITCH_ACCOUNTSERVER");
+ case STATE_SWITCH_SERVER:
+ logger->log("State: SWITCH_SERVER");
+#ifdef TMWSERV_SUPPORT
gameServerConnection->disconnect();
chatServerConnection->disconnect();
accountServerConnection->disconnect();
+#endif
state = STATE_CHOOSE_SERVER;
break;
- case STATE_SWITCH_ACCOUNTSERVER_ATTEMPT:
- logger->log("State: SWITCH_ACCOUNTSERVER_ATTEMPT");
- switchAccountServer();
+ case STATE_SWITCH_SERVER_ATTEMPT:
+ logger->log("State: SWITCH_SERVER_ATTEMPT");
+
+ // TODO
- state = STATE_SWITCH_ACCOUNTSERVER;
+ state = STATE_SWITCH_SERVER;
break;
case STATE_REGISTER:
@@ -1186,7 +1098,14 @@ int main(int argc, char *argv[])
break;
case STATE_REGISTER_ATTEMPT:
- accountRegister(&loginData);
+ logger->log("Username is %s", loginData.username.c_str());
+
+ Net::getCharHandler()->setCharInfo(&charInfo);
+ Net::getLoginHandler()->registerAccount(&loginData);
+ break;
+
+ case STATE_GET_CHARACTERS:
+ Net::getCharHandler()->getCharacters();
break;
case STATE_CHAR_SELECT:
@@ -1249,7 +1168,9 @@ int main(int argc, char *argv[])
case STATE_UNREGISTER:
logger->log("State: UNREGISTER");
+#ifdef TMWSERV_SUPPORT
accountServerConnection->disconnect();
+#endif
currentDialog = new OkDialog(_("Unregister Successful"),
_("Farewell, come back any time..."));
loginData.clear();
@@ -1271,14 +1192,15 @@ int main(int argc, char *argv[])
currentDialog = new OkDialog(_("Error"), errorMessage);
currentDialog->addActionListener(&errorListener);
currentDialog = NULL; // OkDialog deletes itself
- gameServerConnection->disconnect();
- chatServerConnection->disconnect();
- Net::clearHandlers();
+ Net::getGameHandler()->clear();
+ Net::getGeneralHandler()->clearHandlers();
break;
case STATE_CONNECT_GAME:
logger->log("State: CONNECT_GAME");
- currentDialog = new ConnectionDialog(STATE_SWITCH_ACCOUNTSERVER_ATTEMPT);
+ Net::getGameHandler()->connect();
+ currentDialog = new ConnectionDialog(
+ STATE_SWITCH_SERVER_ATTEMPT);
break;
case STATE_GAME:
@@ -1286,8 +1208,7 @@ int main(int argc, char *argv[])
player_node->getName().c_str());
config.setValue("lastCharacter", player_node->getName());
- Net::GameServer::connect(gameServerConnection, token);
- Net::ChatServer::connect(chatServerConnection, token);
+ Net::getGameHandler()->inGame();
// Allow any alpha opacity
SkinLoader::instance()->setMinimumOpacity(-1.0f);
@@ -1309,36 +1230,24 @@ int main(int argc, char *argv[])
state = STATE_EXIT;
- logoutThenExit();
Net::getGeneralHandler()->unload();
break;
case STATE_SWITCH_CHARACTER:
logger->log("State: SWITCH_CHARACTER");
- switchCharacter(&token);
- break;
-
- case STATE_RECONNECT_ACCOUNT:
- logger->log("State: RECONNECT_ACCOUNT");
-
- // Done with game & chat
- gameServerConnection->disconnect();
- chatServerConnection->disconnect();
- accountServerConnection->connect(
- loginData.hostname,
- loginData.port);
- break;
+ // Done with game
+ Net::getGameHandler()->clear();
- case STATE_WAIT:
+ Net::getCharHandler()->getCharacters();
break;
case STATE_FORCE_QUIT:
logger->log("State: FORCE_QUIT");
+ if (Net::getGeneralHandler())
+ Net::getGeneralHandler()->unload();
state = STATE_EXIT;
- logoutThenExit();
- Net::getGeneralHandler()->unload();
break;
default:
@@ -1347,264 +1256,6 @@ int main(int argc, char *argv[])
}
}
-#else // no TMWSERV_SUPPORT
-
- if (state != oldstate)
- {
- switch (oldstate)
- {
- case STATE_UPDATE:
- loadUpdates();
- break;
-
- // Those states don't cause a network disconnect
- case STATE_LOADDATA:
- case STATE_CHANGEPASSWORD_ATTEMPT:
- case STATE_CHANGEPASSWORD:
- case STATE_ACCOUNTCHANGE_ERROR:
- break;
-
- case STATE_CHAR_SELECT:
- // Don't allow an alpha opacity
- // lower than the default value
- SkinLoader::instance()->setMinimumOpacity(0.8f);
-
- if (state == STATE_CONNECTING)
- network->disconnect();
- break;
-
- case STATE_ACCOUNT:
- case STATE_CHAR_CONNECT:
- case STATE_CONNECTING:
- progressBar->setVisible(false);
- progressLabel->setCaption("");
- break;
-
- default:
- network->disconnect();
- break;
- }
-
- oldstate = state;
-
- if (currentDialog && state != STATE_ACCOUNT &&
- state != STATE_CHAR_CONNECT)
- {
- delete currentDialog;
- currentDialog = NULL;
- }
-
- switch (state)
- {
- case STATE_LOADDATA:
- logger->log("State: LOADDATA");
-
- // Add customdata directory
- ResourceManager::getInstance()->searchAndAddArchives(
- "customdata/",
- "zip",
- false);
-
- // Load XML databases
- ColorDB::load();
- ItemDB::load();
- MonsterDB::load();
- NPCDB::load();
- EmoteDB::load();
- StatusEffect::load();
- Being::load(); // Hairstyles
-
- // Load units
- Units::loadUnits();
-
- desktop->reloadWallpaper();
-
- state = STATE_CHAR_CONNECT;
- break;
-
- case STATE_LOGIN:
- logger->log("State: LOGIN");
-
- // Don't allow an alpha opacity
- // lower than the default value
- SkinLoader::instance()->setMinimumOpacity(0.8f);
-
- if (!loginData.password.empty())
- {
- loginData.registerLogin = false;
- state = STATE_ACCOUNT;
- }
- else
- {
- currentDialog = new LoginDialog(&loginData);
- positionDialog(currentDialog, screenWidth,
- screenHeight);
- }
- break;
-
- case STATE_REGISTER:
- logger->log("State: REGISTER");
- currentDialog = new RegisterDialog(&loginData);
- positionDialog(currentDialog, screenWidth, screenHeight);
- break;
-
- case STATE_CHAR_SERVER:
- logger->log("State: CHAR_SERVER");
-
- if (n_server == 1)
- {
- SERVER_INFO *si = *server_info;
- loginData.hostname = ipToString(si->address);
- loginData.port = si->port;
- loginData.updateHost = si->updateHost;
- state = STATE_UPDATE;
- }
- else
- {
- State nextState = STATE_UPDATE;
- currentDialog = new ServerSelectDialog(&loginData,
- nextState);
- positionDialog(currentDialog, screenWidth,
- screenHeight);
- if (options.chooseDefault)
- {
- ((ServerSelectDialog*) currentDialog)->action(
- gcn::ActionEvent(NULL, "ok"));
- }
- }
- break;
- case STATE_CHAR_SELECT:
- logger->log("State: CHAR_SELECT");
-
- // Don't allow an alpha opacity
- // lower than the default value
- SkinLoader::instance()->setMinimumOpacity(0.8f);
-
- currentDialog = new CharSelectDialog(&charInfo,
- &loginData);
- positionDialog(currentDialog, screenWidth, screenHeight);
-
- if (((CharSelectDialog*) currentDialog)->
- selectByName(options.character))
- options.chooseDefault = true;
- else
- ((CharSelectDialog*) currentDialog)->selectByName(
- config.getValue("lastCharacter", ""));
-
- if (options.chooseDefault)
- ((CharSelectDialog*) currentDialog)->action(
- gcn::ActionEvent(NULL, "ok"));
-
- break;
-
- case STATE_GAME:
- delete progressBar;
- delete progressLabel;
- delete setupButton;
- delete desktop;
- progressBar = NULL;
- progressLabel = NULL;
- currentDialog = NULL;
- setupButton = NULL;
- desktop = NULL;
-
- logger->log("State: GAME");
- // Allow any alpha opacity
- SkinLoader::instance()->setMinimumOpacity(-1.0f);
-
- game->logic();
- delete game;
- game = 0;
- state = STATE_EXIT;
- break;
-
- case STATE_UPDATE:
- if (options.skipUpdate)
- {
- state = STATE_LOADDATA;
- }
- else
- {
- // Determine which source to use for the update host
- if (!options.updateHost.empty())
- updateHost = options.updateHost;
- else
- updateHost = loginData.updateHost;
-
- setUpdatesDir();
- logger->log("State: UPDATE");
-
- currentDialog = new UpdaterWindow(updateHost,
- homeDir + "/" + updatesDir);
- positionDialog(currentDialog, screenWidth,
- screenHeight);
- }
- break;
-
- case STATE_ERROR:
- logger->log("State: ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- positionDialog(currentDialog, screenWidth, screenHeight);
- currentDialog->addActionListener(&errorListener);
- currentDialog = NULL; // OkDialog deletes itself
- network->disconnect();
- break;
-
- case STATE_CONNECTING:
- logger->log("State: CONNECTING");
- progressBar->setVisible(true);
- progressLabel->setCaption(
- _("Connecting to map server..."));
- progressLabel->adjustSize();
- mapLogin(network, &loginData);
- break;
-
- case STATE_CHAR_CONNECT:
- progressBar->setVisible(true);
- progressLabel->setCaption(
- _("Connecting to character server..."));
- progressLabel->adjustSize();
- charLogin(network, &loginData);
- break;
-
- case STATE_ACCOUNT:
- progressBar->setVisible(true);
- progressLabel->setCaption(
- _("Connecting to account server..."));
- progressLabel->adjustSize();
- accountLogin(network, &loginData);
- break;
-
- case STATE_CHANGEPASSWORD_ATTEMPT:
- logger->log("State: CHANGE PASSWORD ATTEMPT");
- Net::getLoginHandler()->changePassword(loginData.username,
- loginData.password,
- loginData.newPassword);
- break;
-
- case STATE_CHANGEPASSWORD:
- logger->log("State: CHANGE PASSWORD");
- currentDialog = new OkDialog(_("Password Change"),
- _("Password changed successfully!"));
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
- loginData.password = loginData.newPassword;
- loginData.newPassword = "";
- break;
-
- case STATE_ACCOUNTCHANGE_ERROR:
- logger->log("State: ACCOUNT CHANGE ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
- break;
-
- default:
- state = STATE_EXIT;
- break;
- }
- }
-#endif
/*
* This loop can really stress the CPU, for no reason since it's
* just constantly redrawing the wallpaper. Added the following
@@ -1615,9 +1266,9 @@ int main(int argc, char *argv[])
}
delete guiPalette;
-#ifdef EATHENA_SUPPORT
+/*#ifdef EATHENA_SUPPORT
delete network;
-#endif
+#endif*/
logger->log("Quitting");
exitEngine();
diff --git a/src/main.h b/src/main.h
index bd1c6184..89ab5edd 100644
--- a/src/main.h
+++ b/src/main.h
@@ -75,48 +75,47 @@
#define PKG_DATADIR ""
#endif
+#define MAX_CHARACTER_COUNT 3
+
/*
* Client different States
*/
enum State {
- STATE_EXIT,
- STATE_LOADDATA,
- STATE_LOGIN,
- STATE_REGISTER,
- STATE_CHAR_SELECT,
- STATE_GAME,
- STATE_ERROR,
- STATE_UPDATE,
- STATE_CHANGEPASSWORD_ATTEMPT,
- STATE_CHANGEPASSWORD,
- STATE_ACCOUNTCHANGE_ERROR,
-#ifdef TMWSERV_SUPPORT
+ STATE_ERROR = -1,
+ STATE_START = 0,
STATE_CHOOSE_SERVER,
- STATE_CONNECT_ACCOUNT,
+ STATE_CONNECT_SERVER,
+ STATE_LOGIN,
STATE_LOGIN_ATTEMPT,
+ STATE_WORLD_SELECT, // 5
+ STATE_WORLD_SELECT_ATTEMPT,
+ STATE_UPDATE,
+ STATE_LOAD_DATA,
+ STATE_GET_CHARACTERS,
+ STATE_CHAR_SELECT, // 10
+ STATE_CONNECT_GAME,
+ STATE_GAME,
+ STATE_CHANGE_MAP, // Switch map-server/gameserver
STATE_LOGIN_ERROR,
+ STATE_ACCOUNTCHANGE_ERROR, // 15
+ STATE_REGISTER,
STATE_REGISTER_ATTEMPT,
- STATE_CHANGEEMAIL_ATTEMPT,
+ STATE_CHANGEPASSWORD_ATTEMPT,
+ STATE_CHANGEPASSWORD,
+ STATE_CHANGEEMAIL_ATTEMPT, // 20
STATE_CHANGEEMAIL,
STATE_UNREGISTER_ATTEMPT,
STATE_UNREGISTER,
+ STATE_SWITCH_SERVER,
+ STATE_SWITCH_SERVER_ATTEMPT, // 25
+ STATE_SWITCH_LOGIN,
+ STATE_SWITCH_LOGIN_ATTEMPT,
STATE_SWITCH_CHARACTER,
- STATE_RECONNECT_ACCOUNT,
- STATE_SWITCH_ACCOUNTSERVER_ATTEMPT,
- STATE_SWITCH_ACCOUNTSERVER,
- STATE_LOGOUT_ATTEMPT,
- STATE_CONNECT_GAME,
+ STATE_SWITCH_CHARACTER_ATTEMPT,
+ STATE_LOGOUT_ATTEMPT, // 30
STATE_WAIT,
- STATE_FORCE_QUIT,
-#else
- STATE_ACCOUNT,
- STATE_CHAR_CONNECT,
- STATE_CHAR_SERVER,
- STATE_CHAR_NEW,
- STATE_CHAR_DEL,
- STATE_CONNECTING,
-#endif
- STATE_NULL
+ STATE_EXIT,
+ STATE_FORCE_QUIT
};
/* length definitions for several char[]s in order
@@ -130,11 +129,7 @@ enum {
LEN_MIN_PASSWORD = 4
};
-// Defines the number of usable player slots
-const short maxSlot = 2;
-
-extern std::string token;
-extern char n_server, n_character;
+extern char n_character;
extern State state;
extern std::string errorMessage;
diff --git a/src/net/charhandler.h b/src/net/charhandler.h
index 56bfbbb4..9ca36a9f 100644
--- a/src/net/charhandler.h
+++ b/src/net/charhandler.h
@@ -38,10 +38,10 @@ class CharHandler
public:
virtual void setCharInfo(LockedArray<LocalPlayer*> *charInfo) = 0;
- virtual void connect(LoginData *loginData) = 0;
-
virtual void setCharCreateDialog(CharCreateDialog *window) = 0;
+ virtual void getCharacters() = 0;
+
virtual void chooseCharacter(int slot, LocalPlayer* character) = 0;
virtual void newCharacter(const std::string &name, int slot,
diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp
index 47d454a8..f854841f 100644
--- a/src/net/ea/charserverhandler.cpp
+++ b/src/net/ea/charserverhandler.cpp
@@ -21,6 +21,7 @@
#include "net/ea/charserverhandler.h"
+#include "net/ea/generalhandler.h"
#include "net/ea/network.h"
#include "net/ea/protocol.h"
@@ -43,6 +44,9 @@
Net::CharHandler *charHandler;
namespace EAthena {
+extern Token netToken;
+extern ServerInfo charServer;
+extern ServerInfo mapServer;
CharServerHandler::CharServerHandler():
mCharCreateDialog(0)
@@ -145,8 +149,8 @@ void CharServerHandler::handleMessage(MessageIn &msg)
slot = mCharInfo->getPos();
msg.skip(4); // CharID, must be the same as player_node->charID
map_path = msg.readString(16);
- mLoginData->hostname = ipToString(msg.readInt32());
- mLoginData->port = msg.readInt16();
+ mapServer.hostname = ipToString(msg.readInt32());
+ mapServer.port = msg.readInt16();
mCharInfo->unlock();
mCharInfo->select(0);
// Clear unselected players infos
@@ -162,7 +166,8 @@ void CharServerHandler::handleMessage(MessageIn &msg)
} while (mCharInfo->getPos());
mCharInfo->select(slot);
- state = STATE_CONNECTING;
+ mNetwork->disconnect();
+ state = STATE_CONNECT_GAME;
break;
}
}
@@ -170,7 +175,7 @@ void CharServerHandler::handleMessage(MessageIn &msg)
LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
{
LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0, NULL);
- tempPlayer->setGender(mLoginData->sex);
+ tempPlayer->setGender(netToken.sex);
tempPlayer->setExp(msg.readInt32());
tempPlayer->setMoney(msg.readInt32());
@@ -229,24 +234,12 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
attributes.push_back(_("Luck:"));
mCharCreateDialog->setAttributes(attributes, 30, 1, 9);
- mCharCreateDialog->setFixedGender(true, mLoginData->sex);
+ mCharCreateDialog->setFixedGender(true, netToken.sex);
}
-void CharServerHandler::connect(LoginData *loginData)
+void CharServerHandler::getCharacters()
{
- mLoginData = loginData;
-
- MessageOut outMsg(CMSG_CHAR_SERVER_CONNECT);
- outMsg.writeInt32(loginData->account_ID);
- outMsg.writeInt32(loginData->session_ID1);
- outMsg.writeInt32(loginData->session_ID2);
- // [Fate] The next word is unused by the old char server, so we squeeze in
- // tmw client version information
- outMsg.writeInt16(CLIENT_PROTOCOL_VERSION);
- outMsg.writeInt8((loginData->sex == GENDER_MALE) ? 1 : 0);
-
- // We get 4 useless bytes before the real answer comes in (what are these?)
- mNetwork->skip(4);
+ connect();
}
void CharServerHandler::chooseCharacter(int slot, LocalPlayer* character)
@@ -276,4 +269,21 @@ void CharServerHandler::deleteCharacter(int slot, LocalPlayer* character)
outMsg.writeString("a@a.com", 40);
}
+void CharServerHandler::connect()
+{
+ mNetwork->disconnect();
+ mNetwork->connect(charServer);
+ MessageOut outMsg(CMSG_CHAR_SERVER_CONNECT);
+ outMsg.writeInt32(netToken.account_ID);
+ outMsg.writeInt32(netToken.session_ID1);
+ outMsg.writeInt32(netToken.session_ID2);
+ // [Fate] The next word is unused by the old char server, so we squeeze in
+ // tmw client version information
+ outMsg.writeInt16(CLIENT_PROTOCOL_VERSION);
+ outMsg.writeInt8((netToken.sex == GENDER_MALE) ? 1 : 0);
+
+ // We get 4 useless bytes before the real answer comes in (what are these?)
+ mNetwork->skip(4);
+}
+
} // namespace EAthena
diff --git a/src/net/ea/charserverhandler.h b/src/net/ea/charserverhandler.h
index 3ebac16e..aa36f873 100644
--- a/src/net/ea/charserverhandler.h
+++ b/src/net/ea/charserverhandler.h
@@ -24,6 +24,9 @@
#include "net/messagehandler.h"
#include "net/charhandler.h"
+#include "net/serverinfo.h"
+
+#include "net/ea/token.h"
class LoginData;
@@ -49,7 +52,7 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler
*/
void setCharCreateDialog(CharCreateDialog *window);
- void connect(LoginData *loginData);
+ void getCharacters();
void chooseCharacter(int slot, LocalPlayer* character);
@@ -58,8 +61,9 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler
void deleteCharacter(int slot, LocalPlayer* character);
+ void connect();
+
protected:
- LoginData *mLoginData;
LockedArray<LocalPlayer*> *mCharInfo;
CharCreateDialog *mCharCreateDialog;
diff --git a/src/net/ea/maphandler.cpp b/src/net/ea/gamehandler.cpp
index c3c9437c..f84688a3 100644
--- a/src/net/ea/maphandler.cpp
+++ b/src/net/ea/gamehandler.cpp
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "net/ea/maphandler.h"
+#include "net/ea/gamehandler.h"
#include "net/ea/network.h"
#include "net/ea/protocol.h"
@@ -37,12 +37,14 @@
#include "utils/gettext.h"
#include "utils/stringutils.h"
-Net::MapHandler *mapHandler;
+Net::GameHandler *gameHandler;
extern Game *game;
namespace EAthena {
+extern Token netToken;
+extern ServerInfo mapServer;
-MapHandler::MapHandler()
+GameHandler::GameHandler()
{
static const Uint16 _messages[] = {
SMSG_MAP_LOGIN_SUCCESS,
@@ -51,10 +53,10 @@ MapHandler::MapHandler()
0
};
handledMessages = _messages;
- mapHandler = this;
+ gameHandler = this;
}
-void MapHandler::handleMessage(MessageIn &msg)
+void GameHandler::handleMessage(MessageIn &msg)
{
unsigned char direction;
@@ -68,9 +70,9 @@ void MapHandler::handleMessage(MessageIn &msg)
msg.skip(2); // unknown
logger->log("Protocol: Player start position: (%d, %d), Direction: %d",
x, y, direction);
- state = STATE_GAME;
+ // Switch now or we'll have problems
+ // state = STATE_GAME;
player_node->setTileCoords(x, y);
- game = new Game;
} break;
case SMSG_SERVER_PING:
@@ -85,43 +87,63 @@ void MapHandler::handleMessage(MessageIn &msg)
}
}
-#include <fstream>
-
-void MapHandler::connect(LoginData *loginData)
+void GameHandler::connect()
{
+ mNetwork->connect(mapServer);
+
// Send login infos
MessageOut outMsg(CMSG_MAP_SERVER_CONNECT);
- outMsg.writeInt32(loginData->account_ID);
+ outMsg.writeInt32(netToken.account_ID);
outMsg.writeInt32(player_node->getId());
- outMsg.writeInt32(loginData->session_ID1);
- outMsg.writeInt32(loginData->session_ID2);
- outMsg.writeInt8((loginData->sex == GENDER_MALE) ? 1 : 0);
+ outMsg.writeInt32(netToken.session_ID1);
+ outMsg.writeInt32(netToken.session_ID2);
+ outMsg.writeInt8((netToken.sex == GENDER_MALE) ? 1 : 0);
// Change the player's ID to the account ID to match what eAthena uses
- player_node->setId(loginData->account_ID);
+ player_node->setId(netToken.account_ID);
// We get 4 useless bytes before the real answer comes in (what are these?)
mNetwork->skip(4);
}
-void MapHandler::mapLoaded(const std::string &mapName)
+bool GameHandler::isConnected()
+{
+ return mNetwork->isConnected();
+}
+
+void GameHandler::disconnect()
+{
+ mNetwork->disconnect();
+}
+
+void GameHandler::inGame()
+{
+ // TODO
+}
+
+void GameHandler::mapLoaded(const std::string &mapName)
{
MessageOut outMsg(CMSG_MAP_LOADED);
}
-void MapHandler::who()
+void GameHandler::who()
{
}
-void MapHandler::quit()
+void GameHandler::quit()
{
MessageOut outMsg(CMSG_CLIENT_QUIT);
}
-void MapHandler::ping(int tick)
+void GameHandler::ping(int tick)
{
MessageOut msg(CMSG_CLIENT_PING);
msg.writeInt32(tick);
}
+void GameHandler::clear()
+{
+ disconnect();
+}
+
} // namespace EAthena
diff --git a/src/net/ea/maphandler.h b/src/net/ea/gamehandler.h
index 205ee18d..6cb640c1 100644
--- a/src/net/ea/maphandler.h
+++ b/src/net/ea/gamehandler.h
@@ -22,20 +22,29 @@
#ifndef NET_EA_MAPHANDLER_H
#define NET_EA_MAPHANDLER_H
-#include "net/maphandler.h"
+#include "net/gamehandler.h"
#include "net/messagehandler.h"
#include "net/net.h"
+#include "net/serverinfo.h"
+
+#include "net/ea/token.h"
namespace EAthena {
-class MapHandler : public MessageHandler, public Net::MapHandler
+class GameHandler : public MessageHandler, public Net::GameHandler
{
public:
- MapHandler();
+ GameHandler();
void handleMessage(MessageIn &msg);
- void connect(LoginData *loginData);
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
+ void inGame();
void mapLoaded(const std::string &mapName);
@@ -44,6 +53,9 @@ class MapHandler : public MessageHandler, public Net::MapHandler
void quit();
void ping(int tick);
+
+ void clear();
+
};
} // namespace EAthena
diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp
index 1d500d62..1dde3b3f 100644
--- a/src/net/ea/generalhandler.cpp
+++ b/src/net/ea/generalhandler.cpp
@@ -22,11 +22,13 @@
#include "net/ea/generalhandler.h"
#include "gui/inventorywindow.h"
+#include "gui/register.h"
#include "gui/skilldialog.h"
#include "gui/statuswindow.h"
#include "net/ea/network.h"
#include "net/ea/protocol.h"
+#include "net/ea/token.h"
#include "net/ea/adminhandler.h"
#include "net/ea/beinghandler.h"
@@ -34,11 +36,10 @@
#include "net/ea/chathandler.h"
#include "net/ea/charserverhandler.h"
#include "net/ea/equipmenthandler.h"
+#include "net/ea/gamehandler.h"
#include "net/ea/inventoryhandler.h"
#include "net/ea/itemhandler.h"
#include "net/ea/loginhandler.h"
-#include "net/ea/logouthandler.h"
-#include "net/ea/maphandler.h"
#include "net/ea/npchandler.h"
#include "net/ea/playerhandler.h"
#include "net/ea/partyhandler.h"
@@ -63,6 +64,9 @@
Net::GeneralHandler *generalHandler;
namespace EAthena {
+Token netToken;
+ServerInfo charServer;
+ServerInfo mapServer;
GeneralHandler::GeneralHandler():
mAdminHandler(new AdminHandler),
@@ -71,11 +75,10 @@ GeneralHandler::GeneralHandler():
mCharHandler(new CharServerHandler),
mChatHandler(new ChatHandler),
mEquipmentHandler(new EquipmentHandler),
+ mGameHandler(new GameHandler),
mInventoryHandler(new InventoryHandler),
mItemHandler(new ItemHandler),
mLoginHandler(new LoginHandler),
- mLogoutHandler(new LogoutHandler),
- mMapHandler(new MapHandler),
mNpcHandler(new NpcHandler),
mPartyHandler(new PartyHandler),
mPlayerHandler(new PlayerHandler),
@@ -146,17 +149,18 @@ void GeneralHandler::handleMessage(MessageIn &msg)
void GeneralHandler::load()
{
+ (new Network)->registerHandler(this);
+
mNetwork->registerHandler(mAdminHandler.get());
mNetwork->registerHandler(mBeingHandler.get());
mNetwork->registerHandler(mBuySellHandler.get());
mNetwork->registerHandler(mChatHandler.get());
mNetwork->registerHandler(mCharHandler.get());
mNetwork->registerHandler(mEquipmentHandler.get());
+ mNetwork->registerHandler(mGameHandler.get());
mNetwork->registerHandler(mInventoryHandler.get());
mNetwork->registerHandler(mItemHandler.get());
mNetwork->registerHandler(mLoginHandler.get());
- mNetwork->registerHandler(mLogoutHandler.get());
- mNetwork->registerHandler(mMapHandler.get());
mNetwork->registerHandler(mNpcHandler.get());
mNetwork->registerHandler(mPlayerHandler.get());
mNetwork->registerHandler(mSpecialHandler.get());
@@ -203,6 +207,7 @@ void GeneralHandler::guiWindowsLoaded()
{
partyTab = new PartyTab;
inventoryWindow->setSplitAllowed(false);
+ RegisterDialog::setGender(&netToken.sex);
skillDialog->loadSkills("ea-skills.xml");
statusWindow->addAttribute(STR, _("Strength"), true);
@@ -226,4 +231,9 @@ void GeneralHandler::guiWindowsUnloaded()
delete partyTab;
}
+void GeneralHandler::clearHandlers()
+{
+ mNetwork->clearHandlers();
+}
+
} // namespace EAthena
diff --git a/src/net/ea/generalhandler.h b/src/net/ea/generalhandler.h
index 98364e5d..099bed0b 100644
--- a/src/net/ea/generalhandler.h
+++ b/src/net/ea/generalhandler.h
@@ -25,6 +25,7 @@
#include "net/generalhandler.h"
#include "net/messagehandler.h"
#include "net/net.h"
+#include "net/serverinfo.h"
namespace EAthena {
@@ -51,6 +52,8 @@ class GeneralHandler : public MessageHandler, public Net::GeneralHandler
void guiWindowsUnloaded();
+ void clearHandlers();
+
protected:
MessageHandlerPtr mAdminHandler;
MessageHandlerPtr mBeingHandler;
@@ -58,11 +61,10 @@ class GeneralHandler : public MessageHandler, public Net::GeneralHandler
MessageHandlerPtr mCharHandler;
MessageHandlerPtr mChatHandler;
MessageHandlerPtr mEquipmentHandler;
+ MessageHandlerPtr mGameHandler;
MessageHandlerPtr mInventoryHandler;
MessageHandlerPtr mItemHandler;
MessageHandlerPtr mLoginHandler;
- MessageHandlerPtr mLogoutHandler;
- MessageHandlerPtr mMapHandler;
MessageHandlerPtr mNpcHandler;
MessageHandlerPtr mPartyHandler;
MessageHandlerPtr mPlayerHandler;
diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp
index 8e7187c0..d2e2adc0 100644
--- a/src/net/ea/loginhandler.cpp
+++ b/src/net/ea/loginhandler.cpp
@@ -21,24 +21,27 @@
#include "net/ea/loginhandler.h"
+#include "net/ea/network.h"
#include "net/ea/protocol.h"
#include "net/logindata.h"
#include "net/messagein.h"
#include "net/messageout.h"
-#include "net/serverinfo.h"
#include "log.h"
#include "main.h"
+#include "utils/dtor.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
-extern SERVER_INFO **server_info;
+Worlds worlds;
Net::LoginHandler *loginHandler;
namespace EAthena {
+extern Token netToken;
+extern ServerInfo charServer;
LoginHandler::LoginHandler()
{
@@ -47,6 +50,7 @@ LoginHandler::LoginHandler()
SMSG_LOGIN_DATA,
SMSG_LOGIN_ERROR,
SMSG_CHAR_PASSWORD_RESPONSE,
+ SMSG_SERVER_VERSION_RESPONSE,
0
};
handledMessages = _messages;
@@ -55,7 +59,7 @@ LoginHandler::LoginHandler()
void LoginHandler::handleMessage(MessageIn &msg)
{
- int code;
+ int code, worldCount;
switch (msg.getId())
{
@@ -104,33 +108,34 @@ void LoginHandler::handleMessage(MessageIn &msg)
// Skip the length word
msg.skip(2);
- n_server = (msg.getLength() - 47) / 32;
- server_info =
- (SERVER_INFO**) malloc(sizeof(SERVER_INFO*) * n_server);
+ delete_all(worlds);
+ worldCount = (msg.getLength() - 47) / 32;
- mLoginData->session_ID1 = msg.readInt32();
- mLoginData->account_ID = msg.readInt32();
- mLoginData->session_ID2 = msg.readInt32();
+ netToken.session_ID1 = msg.readInt32();
+ netToken.account_ID = msg.readInt32();
+ netToken.session_ID2 = msg.readInt32();
msg.skip(30); // unknown
- mLoginData->sex = msg.readInt8() ? GENDER_MALE : GENDER_FEMALE;
+ netToken.sex = msg.readInt8() ? GENDER_MALE : GENDER_FEMALE;
- for (int i = 0; i < n_server; i++)
+ for (int i = 0; i < worldCount; i++)
{
- server_info[i] = new SERVER_INFO;
+ WorldInfo *world = new WorldInfo;
- server_info[i]->address = msg.readInt32();
- server_info[i]->port = msg.readInt16();
- server_info[i]->name = msg.readString(20);
- server_info[i]->online_users = msg.readInt32();
- server_info[i]->updateHost = mUpdateHost;
+ world->address = msg.readInt32();
+ world->port = msg.readInt16();
+ world->name = msg.readString(20);
+ world->online_users = msg.readInt32();
+ world->updateHost = mUpdateHost;
msg.skip(2); // unknown
logger->log("Network: Server: %s (%s:%d)",
- server_info[i]->name.c_str(),
- ipToString(server_info[i]->address),
- server_info[i]->port);
+ world->name.c_str(),
+ ipToString(world->address),
+ world->port);
+
+ worlds.push_back(world);
}
- state = STATE_CHAR_SERVER;
+ state = STATE_WORLD_SELECT;
break;
case SMSG_LOGIN_ERROR:
@@ -171,9 +176,40 @@ void LoginHandler::handleMessage(MessageIn &msg)
}
state = STATE_ERROR;
break;
+ case SMSG_SERVER_VERSION_RESPONSE:
+ {
+ // TODO: verify these!
+ msg.readInt8(); // -1
+ msg.readInt8(); // T
+ msg.readInt8(); // M
+ msg.readInt8(); // W
+ msg.readInt8(); // (space)
+ msg.readInt8(); // e
+ msg.readInt8(); // A
+
+ //state = STATE_LOGIN;
+ }
+ break;
}
}
+void LoginHandler::connect()
+{
+ mNetwork->connect(mServer);
+ MessageOut outMsg(CMSG_SERVER_VERSION_REQUEST);
+}
+
+bool LoginHandler::isConnected()
+{
+ return mNetwork->isConnected();
+}
+
+void LoginHandler::disconnect()
+{
+ if (mNetwork->getServer() == mServer)
+ mNetwork->disconnect();
+}
+
void LoginHandler::loginAccount(LoginData *loginData)
{
mLoginData = loginData;
@@ -194,9 +230,14 @@ void LoginHandler::changePassword(const std::string &username,
outMsg.writeString(newPassword, 24);
}
-void LoginHandler::chooseServer(int server)
+void LoginHandler::chooseServer(unsigned int server)
{
- // TODO
+ if (server >= worlds.size())
+ return;
+
+ charServer.clear();
+ charServer.hostname = ipToString(worlds[server]->address);
+ charServer.port = worlds[server]->port;
}
void LoginHandler::registerAccount(LoginData *loginData)
@@ -204,7 +245,7 @@ void LoginHandler::registerAccount(LoginData *loginData)
mLoginData = loginData;
std::string username = loginData->username;
- username.append((loginData->sex == GENDER_FEMALE) ? "_F" : "_M");
+ username.append((netToken.sex == GENDER_FEMALE) ? "_F" : "_M");
sendLoginRegister(username, loginData->password);
}
@@ -232,4 +273,9 @@ void LoginHandler::sendLoginRegister(const std::string &username,
outMsg.writeInt8(0x03);
}
+Worlds LoginHandler::getWorlds()
+{
+ return worlds;
+}
+
} // namespace EAthena
diff --git a/src/net/ea/loginhandler.h b/src/net/ea/loginhandler.h
index 93f21754..bc1aa816 100644
--- a/src/net/ea/loginhandler.h
+++ b/src/net/ea/loginhandler.h
@@ -25,6 +25,8 @@
#include "net/loginhandler.h"
#include "net/messagehandler.h"
+#include "net/ea/token.h"
+
#include <string>
struct LoginData;
@@ -38,6 +40,12 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler
void handleMessage(MessageIn &msg);
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
void loginAccount(LoginData *loginData);
void changeEmail(const std::string &email);
@@ -46,13 +54,15 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler
const std::string &oldPassword,
const std::string &newPassword);
- void chooseServer(int server);
+ void chooseServer(unsigned int server);
void registerAccount(LoginData *loginData);
void unregisterAccount(const std::string &username,
const std::string &password);
+ Worlds getWorlds();
+
private:
void sendLoginRegister(const std::string &username,
const std::string &password);
diff --git a/src/net/ea/logouthandler.cpp b/src/net/ea/logouthandler.cpp
deleted file mode 100644
index 7de87c6a..00000000
--- a/src/net/ea/logouthandler.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2004 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/ea/logouthandler.h"
-
-#include "net/ea/protocol.h"
-
-#include "net/logindata.h"
-#include "net/messagein.h"
-#include "net/messageout.h"
-#include "net/serverinfo.h"
-
-#include "log.h"
-#include "main.h"
-
-#include "utils/gettext.h"
-#include "utils/stringutils.h"
-
-Net::LogoutHandler *logoutHandler;
-
-namespace EAthena {
-
-LogoutHandler::LogoutHandler()
-{
- static const Uint16 _messages[] = {
- 0
- };
- handledMessages = _messages;
- logoutHandler = this;
-}
-
-void LogoutHandler::handleMessage(MessageIn &msg)
-{
-}
-
-void LogoutHandler::setScenario(unsigned short scenario,
- std::string *passToken)
-{
- // TODO
-}
-
-void LogoutHandler::reset()
-{
- // TODO
-}
-
-} // namespace EAthena
diff --git a/src/net/ea/logouthandler.h b/src/net/ea/logouthandler.h
deleted file mode 100644
index 0d118ab0..00000000
--- a/src/net/ea/logouthandler.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2004 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
- */
-
-#ifndef NET_EA_LOGOUTHANDLER_H
-#define NET_EA_LOGOUTHANDLER_H
-
-#include "net/logouthandler.h"
-#include "net/messagehandler.h"
-
-#include <string>
-
-namespace EAthena {
-
-class LogoutHandler : public MessageHandler, public Net::LogoutHandler
-{
- public:
- LogoutHandler();
-
- void handleMessage(MessageIn &msg);
-
- void setScenario(unsigned short scenario,
- std::string *passToken = NULL);
-
- void reset();
-};
-
-} // namespace EAthena
-
-#endif // NET_EA_LOGOUTHANDLER_H
diff --git a/src/net/ea/network.cpp b/src/net/ea/network.cpp
index c6bc712c..68bdc870 100644
--- a/src/net/ea/network.cpp
+++ b/src/net/ea/network.cpp
@@ -21,12 +21,16 @@
#include "net/ea/network.h"
+#include "net/ea/protocol.h"
+
#include "net/messagehandler.h"
#include "net/messagein.h"
-#include "log.h"
#include "utils/stringutils.h"
+#include "log.h"
+
+#include <assert.h>
#include <sstream>
/** Warning: buffers and other variables are shared,
@@ -95,7 +99,6 @@ Network *Network::mInstance = 0;
Network::Network():
mSocket(0),
- mAddress(), mPort(0),
mInBuffer(new char[BUFFER_SIZE]),
mOutBuffer(new char[BUFFER_SIZE]),
mInSize(0), mOutSize(0),
@@ -125,24 +128,26 @@ Network::~Network()
SDLNet_Quit();
}
-bool Network::connect(const std::string &address, short port)
+bool Network::connect(ServerInfo server)
{
if (mState != IDLE && mState != NET_ERROR)
{
logger->log("Tried to connect an already connected socket!");
+ assert(false);
return false;
}
- if (address.empty())
+ if (server.hostname.empty())
{
setError("Empty address given to Network::connect()!");
return false;
}
- logger->log("Network::Connecting to %s:%i", address.c_str(), port);
+ logger->log("Network::Connecting to %s:%i", server.hostname.c_str(),
+ server.port);
- mAddress = address;
- mPort = port;
+ mServer.hostname = server.hostname;
+ mServer.port = server.port;
// Reset to sane values
mOutSize = 0;
@@ -269,12 +274,16 @@ void Network::skip(int len)
bool Network::messageReady()
{
- int len = -1;
+ int len = -1, msgId;
SDL_mutexP(mMutex);
if (mInSize >= 2)
{
- len = packet_lengths[readWord(0)];
+ msgId = readWord(0);
+ if (msgId == SMSG_SERVER_VERSION_RESPONSE)
+ len = 10;
+ else
+ len = packet_lengths[msgId];
if (len == -1 && mInSize > 4)
len = readWord(2);
@@ -297,7 +306,11 @@ MessageIn Network::getNextMessage()
SDL_mutexP(mMutex);
int msgId = readWord(0);
- int len = packet_lengths[msgId];
+ int len;
+ if (msgId == SMSG_SERVER_VERSION_RESPONSE)
+ len = 10;
+ else
+ len = packet_lengths[msgId];
if (len == -1)
len = readWord(2);
@@ -316,9 +329,11 @@ bool Network::realConnect()
{
IPaddress ipAddress;
- if (SDLNet_ResolveHost(&ipAddress, mAddress.c_str(), mPort) == -1)
+ if (SDLNet_ResolveHost(&ipAddress, mServer.hostname.c_str(),
+ mServer.port) == -1)
{
- std::string errorMessage = "Unable to resolve host \"" + mAddress + "\"";
+ std::string errorMessage = "Unable to resolve host \"" +
+ mServer.hostname + "\"";
setError(errorMessage);
logger->log("SDLNet_ResolveHost: %s", errorMessage.c_str());
return false;
diff --git a/src/net/ea/network.h b/src/net/ea/network.h
index 741a8297..b61f363b 100644
--- a/src/net/ea/network.h
+++ b/src/net/ea/network.h
@@ -22,6 +22,8 @@
#ifndef EA_NETWORK_H
#define EA_NETWORK_H
+#include "net/serverinfo.h"
+
#include <SDL_net.h>
#include <SDL_thread.h>
@@ -47,10 +49,13 @@ class Network
~Network();
- bool connect(const std::string &address, short port);
+ bool connect(ServerInfo server);
void disconnect();
+ ServerInfo getServer()
+ { return mServer; }
+
void registerHandler(MessageHandler *handler);
void unregisterHandler(MessageHandler *handler);
@@ -97,8 +102,7 @@ class Network
TCPsocket mSocket;
- std::string mAddress;
- short mPort;
+ ServerInfo mServer;
char *mInBuffer, *mOutBuffer;
unsigned int mInSize, mOutSize;
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 3e379d82..ae94ab92 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -548,7 +548,7 @@ void PlayerHandler::changeAction(Being::Action action)
void PlayerHandler::respawn()
{
- MessageOut outMsg(CMSG_PLAYER_RESPAWN);
+ MessageOut outMsg(CMSG_PLAYER_RESTART);
outMsg.writeInt8(0);
}
diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h
index 07350841..8f3e40b5 100644
--- a/src/net/ea/protocol.h
+++ b/src/net/ea/protocol.h
@@ -47,6 +47,8 @@ static const int STORAGE_OFFSET = 1;
/*********************************
* Packets from server to client *
*********************************/
+#define SMSG_SERVER_VERSION_RESPONSE 0x7531
+
#define SMSG_SERVER_PING 0x007f /**< Contains server tick */
#define SMSG_CONNECTION_PROBLEM 0x0081
@@ -162,6 +164,8 @@ static const int STORAGE_OFFSET = 1;
/**********************************
* Packets from client to server *
**********************************/
+#define CMSG_SERVER_VERSION_REQUEST 0x7530
+
#define CMSG_CHAR_PASSWORD_CHANGE 0x0061 /**< Custom change password packet */
#define CMSG_CHAR_SERVER_CONNECT 0x0065
#define CMSG_CHAR_SELECT 0x0066
@@ -195,7 +199,7 @@ static const int STORAGE_OFFSET = 1;
#define CMSG_PLAYER_CHANGE_DIR 0x009b
#define CMSG_PLAYER_CHANGE_DEST 0x0085
#define CMSG_PLAYER_CHANGE_ACT 0x0089
-#define CMSG_PLAYER_RESPAWN 0x00b2
+#define CMSG_PLAYER_RESTART 0x00b2
#define CMSG_PLAYER_EMOTE 0x00bf
#define CMSG_PLAYER_ATTACK 0x0089
#define CMSG_WHO_REQUEST 0x00c1
diff --git a/src/net/maphandler.h b/src/net/gamehandler.h
index 6c91f4ef..062b6770 100644
--- a/src/net/maphandler.h
+++ b/src/net/gamehandler.h
@@ -28,10 +28,16 @@
namespace Net {
-class MapHandler
+class GameHandler
{
public:
- virtual void connect(LoginData *loginData) = 0;
+ virtual void connect() = 0;
+
+ virtual bool isConnected() = 0;
+
+ virtual void disconnect() = 0;
+
+ virtual void inGame() = 0;
virtual void mapLoaded(const std::string &mapName) = 0;
@@ -40,6 +46,8 @@ class MapHandler
virtual void quit() = 0;
virtual void ping(int tick) = 0;
+
+ virtual void clear() = 0;
};
} // namespace Net
diff --git a/src/net/generalhandler.h b/src/net/generalhandler.h
index 3865ca92..3b081834 100644
--- a/src/net/generalhandler.h
+++ b/src/net/generalhandler.h
@@ -19,6 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "main.h"
+
#ifndef GENERALHANDLER_H
#define GENERALHANDLER_H
@@ -40,6 +42,8 @@ class GeneralHandler
virtual void guiWindowsLoaded() = 0;
virtual void guiWindowsUnloaded() = 0;
+
+ virtual void clearHandlers() = 0;
};
} // namespace Net
diff --git a/src/net/logindata.h b/src/net/logindata.h
index db7aafff..5e72f8fd 100644
--- a/src/net/logindata.h
+++ b/src/net/logindata.h
@@ -25,28 +25,18 @@
#include <string>
#include "player.h"
+#include "net/serverinfo.h"
struct LoginData
{
std::string username;
std::string password;
std::string newPassword;
- std::string hostname;
std::string updateHost;
-#ifdef TMWSERV_SUPPORT
std::string email;
std::string newEmail;
-#endif
- short port;
-#ifdef EATHENA_SUPPORT
- int account_ID;
- int session_ID1;
- int session_ID2;
- Gender sex;
-#endif
-
- bool remember; /**< Whether to store the username and host. */
+ bool remember; /**< Whether to store the username. */
bool registerLogin; /**< Whether an account is being registered. */
void clear()
@@ -54,20 +44,9 @@ struct LoginData
username.clear();
password.clear();
newPassword.clear();
- hostname.clear();
updateHost.clear();
-#ifdef TMWSERV_SUPPORT
email.clear();
newEmail.clear();
-#endif
- port = 0;
-
-#ifdef EATHENA_SUPPORT
- account_ID = 0;
- session_ID1 = 0;
- session_ID2 = 0;
- sex = GENDER_UNSPECIFIED;
-#endif
}
};
diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h
index fdd57689..26dfb53b 100644
--- a/src/net/loginhandler.h
+++ b/src/net/loginhandler.h
@@ -24,13 +24,29 @@
#include "logindata.h"
+#include "net/serverinfo.h"
+#include "net/worldinfo.h"
+
#include <iosfwd>
+#include <vector>
namespace Net {
class LoginHandler
{
public:
+ virtual void setServer(const ServerInfo &server)
+ { mServer = server; }
+
+ virtual ServerInfo getServer()
+ { return mServer; }
+
+ virtual void connect() = 0;
+
+ virtual bool isConnected() = 0;
+
+ virtual void disconnect() = 0;
+
virtual void loginAccount(LoginData *loginData) = 0;
virtual void changeEmail(const std::string &email) = 0;
@@ -39,12 +55,17 @@ class LoginHandler
const std::string &oldPassword,
const std::string &newPassword) = 0;
- virtual void chooseServer(int server) = 0;
+ virtual void chooseServer(unsigned int server) = 0;
virtual void registerAccount(LoginData *loginData) = 0;
virtual void unregisterAccount(const std::string &username,
const std::string &password) = 0;
+
+ virtual Worlds getWorlds() = 0;
+
+ protected:
+ ServerInfo mServer;
};
} // namespace Net
diff --git a/src/net/messagehandler.h b/src/net/messagehandler.h
index 28d4fea5..c89f3dcd 100644
--- a/src/net/messagehandler.h
+++ b/src/net/messagehandler.h
@@ -22,6 +22,8 @@
#ifndef NET_MESSAGEHANDLER_H
#define NET_MESSAGEHANDLER_H
+#include "net/messagein.h"
+
#include <SDL_types.h>
#include <memory>
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
index 4333ac85..133aac96 100644
--- a/src/net/messageout.cpp
+++ b/src/net/messageout.cpp
@@ -38,6 +38,7 @@ MessageOut::MessageOut(short id):
mDataSize(0),
mPos(0)
{
+ mID = id;
#ifdef EATHENA_SUPPORT
mNetwork = Network::instance();
mData = mNetwork->mOutBuffer + mNetwork->mOutSize;
diff --git a/src/net/messageout.h b/src/net/messageout.h
index 5027ea47..f44aaa95 100644
--- a/src/net/messageout.h
+++ b/src/net/messageout.h
@@ -80,6 +80,8 @@ class MessageOut
*/
unsigned int getDataSize() const;
+ short mID;
+
private:
#ifdef TMWSERV_SUPPORT
/**
diff --git a/src/net/net.cpp b/src/net/net.cpp
index 7df336c6..6a9c072a 100644
--- a/src/net/net.cpp
+++ b/src/net/net.cpp
@@ -21,6 +21,8 @@
#include "net/net.h"
+#include "main.h"
+
#include "net/adminhandler.h"
#include "net/charhandler.h"
#include "net/chathandler.h"
@@ -28,22 +30,26 @@
#include "net/guildhandler.h"
#include "net/inventoryhandler.h"
#include "net/loginhandler.h"
-#include "net/logouthandler.h"
-#include "net/maphandler.h"
+#include "net/gamehandler.h"
#include "net/npchandler.h"
#include "net/partyhandler.h"
#include "net/playerhandler.h"
#include "net/specialhandler.h"
#include "net/tradehandler.h"
+#ifdef TMWSERV_SUPPORT
+#include "net/tmwserv/generalhandler.h"
+#else
+#include "net/ea/generalhandler.h"
+#endif
+
extern Net::AdminHandler *adminHandler;
extern Net::CharHandler *charHandler;
extern Net::ChatHandler *chatHandler;
extern Net::GeneralHandler *generalHandler;
extern Net::InventoryHandler *inventoryHandler;
extern Net::LoginHandler *loginHandler;
-extern Net::LogoutHandler *logoutHandler;
-extern Net::MapHandler *mapHandler;
+extern Net::GameHandler *gameHandler;
extern Net::NpcHandler *npcHandler;
extern Net::PartyHandler *partyHandler;
extern Net::PlayerHandler *playerHandler;
@@ -65,6 +71,11 @@ Net::ChatHandler *Net::getChatHandler()
return chatHandler;
}
+Net::GameHandler *Net::getGameHandler()
+{
+ return gameHandler;
+}
+
Net::GeneralHandler *Net::getGeneralHandler()
{
return generalHandler;
@@ -86,16 +97,6 @@ Net::LoginHandler *Net::getLoginHandler()
return loginHandler;
}
-Net::LogoutHandler *Net::getLogoutHandler()
-{
- return logoutHandler;
-}
-
-Net::MapHandler *Net::getMapHandler()
-{
- return mapHandler;
-}
-
Net::NpcHandler *Net::getNpcHandler()
{
return npcHandler;
@@ -120,3 +121,21 @@ Net::TradeHandler *Net::getTradeHandler()
{
return tradeHandler;
}
+
+void Net::connectToServer(const ServerInfo &server)
+{
+ // TODO: Actually query the server about itself and choose the netcode
+ // based on that
+
+#ifdef TMWSERV_SUPPORT
+ new TmwServ::GeneralHandler;
+#else
+ new EAthena::GeneralHandler;
+#endif
+
+ Net::getGeneralHandler()->load();
+
+ Net::getLoginHandler()->setServer(server);
+
+ Net::getLoginHandler()->connect();
+}
diff --git a/src/net/net.h b/src/net/net.h
index 1d91faa7..5b0c92f4 100644
--- a/src/net/net.h
+++ b/src/net/net.h
@@ -19,6 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "net/serverinfo.h"
+
#ifndef NET_H
#define NET_H
@@ -27,12 +29,11 @@ namespace Net {
class AdminHandler;
class CharHandler;
class ChatHandler;
+class GameHandler;
class GeneralHandler;
class GuildHandler;
class InventoryHandler;
class LoginHandler;
-class LogoutHandler;
-class MapHandler;
class NpcHandler;
class PartyHandler;
class PlayerHandler;
@@ -42,18 +43,22 @@ class TradeHandler;
AdminHandler *getAdminHandler();
CharHandler *getCharHandler();
ChatHandler *getChatHandler();
+GameHandler *getGameHandler();
GeneralHandler *getGeneralHandler();
GuildHandler *getGuildHandler();
InventoryHandler *getInventoryHandler();
LoginHandler *getLoginHandler();
-LogoutHandler *getLogoutHandler();
-MapHandler *getMapHandler();
NpcHandler *getNpcHandler();
PartyHandler *getPartyHandler();
PlayerHandler *getPlayerHandler();
SpecialHandler *getSpecialHandler();
TradeHandler *getTradeHandler();
+/**
+ * Handles server detection and connection
+ */
+void connectToServer(const ServerInfo &server);
+
} // namespace Net
#endif // NET_H
diff --git a/src/net/serverinfo.h b/src/net/serverinfo.h
index c38d13c7..ac2e803d 100644
--- a/src/net/serverinfo.h
+++ b/src/net/serverinfo.h
@@ -1,6 +1,6 @@
/*
* The Mana World
- * Copyright (C) 2004 The Mana World Development Team
+ * Copyright (C) 2009 The Mana World Development Team
*
* This file is part of The Mana World.
*
@@ -19,18 +19,25 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef SERVERINFO_
-#define SERVERINFO_
+#ifndef SERVERINFO_H
+#define SERVERINFO_H
#include <string>
-struct SERVER_INFO
-{
- int address;
- short port;
- std::string name;
- short online_users;
- std::string updateHost;
-};
+typedef struct SERVER_INFO {
+ std::string hostname;
+ unsigned short port;
-#endif
+ void clear()
+ {
+ hostname.clear();
+ port = 0;
+ }
+
+ bool operator==(struct SERVER_INFO other)
+ {
+ return (hostname == other.hostname && port == other.port);
+ }
+} ServerInfo;
+
+#endif // SERVERINFO_H
diff --git a/src/net/tmwserv/charserverhandler.cpp b/src/net/tmwserv/charhandler.cpp
index 93181a93..ec260d84 100644
--- a/src/net/tmwserv/charserverhandler.cpp
+++ b/src/net/tmwserv/charhandler.cpp
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "net/tmwserv/charserverhandler.h"
+#include "net/tmwserv/charhandler.h"
#include "net/tmwserv/connection.h"
#include "net/tmwserv/protocol.h"
@@ -28,7 +28,9 @@
#include "net/tmwserv/accountserver/account.h"
#include "net/logindata.h"
+#include "net/loginhandler.h"
#include "net/messagein.h"
+#include "net/net.h"
#include "game.h"
#include "localplayer.h"
@@ -42,14 +44,34 @@
#include "utils/gettext.h"
+extern Net::Connection *accountServerConnection;
extern Net::Connection *gameServerConnection;
extern Net::Connection *chatServerConnection;
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;
+
namespace TmwServ {
-CharServerHandler::CharServerHandler():
+extern std::string netToken;
+extern ServerInfo gameServer;
+extern ServerInfo chatServer;
+
+CharHandler::CharHandler():
mCharCreateDialog(0)
{
static const Uint16 _messages[] = {
@@ -63,11 +85,8 @@ CharServerHandler::CharServerHandler():
charHandler = this;
}
-void CharServerHandler::handleMessage(MessageIn &msg)
+void CharHandler::handleMessage(MessageIn &msg)
{
- int slot;
- LocalPlayer *tempPlayer;
-
switch (msg.getId())
{
case APMSG_CHAR_CREATE_RESPONSE:
@@ -107,17 +126,26 @@ void CharServerHandler::handleMessage(MessageIn &msg)
break;
case APMSG_CHAR_INFO:
- tempPlayer = readPlayerData(msg, slot);
- mCharInfo->unlock();
- mCharInfo->select(slot);
- mCharInfo->setEntry(tempPlayer);
-
- // Close the character create dialog
- if (mCharCreateDialog)
+ {
+ 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++)
{
- mCharCreateDialog->scheduleDelete();
- mCharCreateDialog = 0;
+ info.attr[i] = msg.readInt8();
}
+
+ chars.push_back(info);
+ }
break;
case APMSG_CHAR_SELECT_RESPONSE:
@@ -126,7 +154,7 @@ void CharServerHandler::handleMessage(MessageIn &msg)
}
}
-void CharServerHandler::handleCharCreateResponse(MessageIn &msg)
+void CharHandler::handleCharCreateResponse(MessageIn &msg)
{
int errMsg = msg.readInt8();
@@ -177,23 +205,27 @@ void CharServerHandler::handleCharCreateResponse(MessageIn &msg)
mCharCreateDialog->unlock();
}
-void CharServerHandler::handleCharSelectResponse(MessageIn &msg)
+void CharHandler::handleCharSelectResponse(MessageIn &msg)
{
int errMsg = msg.readInt8();
if (errMsg == ERRMSG_OK)
{
- token = msg.readString(32);
- std::string gameServer = msg.readString();
- unsigned short gameServerPort = msg.readInt16();
- std::string chatServer = msg.readString();
- unsigned short chatServerPort = msg.readInt16();
+ netToken = msg.readString(32);
- logger->log("Game server: %s:%d", gameServer.c_str(), gameServerPort);
- logger->log("Chat server: %s:%d", chatServer.c_str(), chatServerPort);
+ gameServer.hostname.assign(msg.readString());
+ gameServer.port = msg.readInt16();
- gameServerConnection->connect(gameServer, gameServerPort);
- chatServerConnection->connect(chatServer, chatServerPort);
+ chatServer.hostname.assign(msg.readString());
+ chatServer.port = msg.readInt16();
+
+ logger->log("Game server: %s:%d", gameServer.hostname.c_str(),
+ gameServer.port);
+ logger->log("Chat server: %s:%d", chatServer.hostname.c_str(),
+ chatServer.port);
+
+ gameServerConnection->connect(gameServer.hostname, gameServer.port);
+ chatServerConnection->connect(chatServer.hostname, chatServer.port);
// Keep the selected character and delete the others
player_node = mCharInfo->getEntry();
@@ -224,28 +256,7 @@ void CharServerHandler::handleCharSelectResponse(MessageIn &msg)
}
}
-LocalPlayer* CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
-{
- LocalPlayer *tempPlayer = new LocalPlayer;
- slot = msg.readInt8(); // character slot
- tempPlayer->setName(msg.readString());
- tempPlayer->setGender(msg.readInt8() == GENDER_MALE ? GENDER_MALE : GENDER_FEMALE);
- int hs = msg.readInt8(), hc = msg.readInt8();
- tempPlayer->setSprite(Player::HAIR_SPRITE, hs * -1, ColorDB::get(hc));
- tempPlayer->setLevel(msg.readInt16());
- tempPlayer->setCharacterPoints(msg.readInt16());
- tempPlayer->setCorrectionPoints(msg.readInt16());
- tempPlayer->setMoney(msg.readInt32());
-
- for (int i = 0; i < 7; i++)
- {
- tempPlayer->setAttributeBase(i, msg.readInt8());
- }
-
- return tempPlayer;
-}
-
-void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
+void CharHandler::setCharCreateDialog(CharCreateDialog *window)
{
mCharCreateDialog = window;
@@ -262,12 +273,54 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *window)
mCharCreateDialog->setAttributes(attributes, 60, 1, 20);
}
-void CharServerHandler::chooseCharacter(int slot, LocalPlayer* character)
+void CharHandler::getCharacters()
+{
+ 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(Player::HAIR_SPRITE, 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]);
+ }
+
+ mCharInfo->setEntry(tempPlayer);
+ }
+
+ // Close the character create dialog
+ if (mCharCreateDialog)
+ {
+ mCharCreateDialog->scheduleDelete();
+ mCharCreateDialog = 0;
+ }
+
+ state = STATE_CHAR_SELECT;
+ }
+}
+
+void CharHandler::chooseCharacter(int slot, LocalPlayer* character)
{
Net::AccountServer::Account::selectCharacter(slot);
}
-void CharServerHandler::newCharacter(const std::string &name, int slot, bool gender,
+void CharHandler::newCharacter(const std::string &name, int slot, bool gender,
int hairstyle, int hairColor, std::vector<int> stats)
{
Net::AccountServer::Account::createCharacter(name, hairstyle, hairColor,
@@ -281,7 +334,7 @@ void CharServerHandler::newCharacter(const std::string &name, int slot, bool gen
);
}
-void CharServerHandler::deleteCharacter(int slot, LocalPlayer* character)
+void CharHandler::deleteCharacter(int slot, LocalPlayer* character)
{
Net::AccountServer::Account::deleteCharacter(slot);
}
diff --git a/src/net/tmwserv/charserverhandler.h b/src/net/tmwserv/charhandler.h
index 4d79d60e..2c62c1d0 100644
--- a/src/net/tmwserv/charserverhandler.h
+++ b/src/net/tmwserv/charhandler.h
@@ -32,10 +32,10 @@ namespace TmwServ {
/**
* Deals with incoming messages related to character selection.
*/
-class CharServerHandler : public MessageHandler, public Net::CharHandler
+class CharHandler : public MessageHandler, public Net::CharHandler
{
public:
- CharServerHandler();
+ CharHandler();
void handleMessage(MessageIn &msg);
@@ -51,7 +51,7 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler
*/
void setCharCreateDialog(CharCreateDialog *window);
- void connect(LoginData *loginData) {} // Unused
+ void getCharacters();
void chooseCharacter(int slot, LocalPlayer* character);
@@ -68,9 +68,6 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler
LockedArray<LocalPlayer*> *mCharInfo;
CharCreateDialog *mCharCreateDialog;
-
- LocalPlayer*
- readPlayerData(MessageIn &msg, int &slot);
};
} // namespace TmwServ
diff --git a/src/net/tmwserv/chathandler.cpp b/src/net/tmwserv/chathandler.cpp
index c95f6ac5..229f09be 100644
--- a/src/net/tmwserv/chathandler.cpp
+++ b/src/net/tmwserv/chathandler.cpp
@@ -35,9 +35,10 @@
#include "being.h"
#include "beingmanager.h"
-#include "game.h"
#include "channel.h"
#include "channelmanager.h"
+#include "game.h"
+#include "main.h"
#include "gui/widgets/channeltab.h"
#include "gui/chat.h"
@@ -53,8 +54,13 @@ extern Being *player_node;
Net::ChatHandler *chatHandler;
+extern Net::Connection *chatServerConnection;
+
namespace TmwServ {
+extern std::string netToken;
+extern ServerInfo chatServer;
+
ChatHandler::ChatHandler()
{
static const Uint16 _messages[] = {
@@ -68,6 +74,7 @@ ChatHandler::ChatHandler()
CPMSG_LIST_CHANNELUSERS_RESPONSE,
CPMSG_CHANNEL_EVENT,
CPMSG_WHO_RESPONSE,
+ CPMSG_DISCONNECT_RESPONSE,
0
};
handledMessages = _messages;
@@ -117,6 +124,28 @@ void ChatHandler::handleMessage(MessageIn &msg)
case CPMSG_WHO_RESPONSE:
handleWhoResponse(msg);
break;
+ case CPMSG_DISCONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ // TODO: Handle logout
+ }
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Chatserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Chatserver: Unknown error";
+ break;
+ }
+ state = STATE_ERROR;
+ }
+ }
+ break;
}
}
@@ -323,6 +352,21 @@ void ChatHandler::handleWhoResponse(MessageIn &msg)
}
}
+void ChatHandler::connect()
+{
+ Net::ChatServer::connect(chatServerConnection, netToken);
+}
+
+bool ChatHandler::isConnected()
+{
+ return chatServerConnection->isConnected();
+}
+
+void ChatHandler::disconnect()
+{
+ chatServerConnection->disconnect();
+}
+
void ChatHandler::talk(const std::string &text)
{
MessageOut msg(PGMSG_SAY);
diff --git a/src/net/tmwserv/chathandler.h b/src/net/tmwserv/chathandler.h
index bc30de7c..85bc2054 100644
--- a/src/net/tmwserv/chathandler.h
+++ b/src/net/tmwserv/chathandler.h
@@ -25,6 +25,8 @@
#include "net/chathandler.h"
#include "net/messagehandler.h"
+#include "net/serverinfo.h"
+
namespace TmwServ {
class ChatHandler : public MessageHandler, public Net::ChatHandler
@@ -37,6 +39,12 @@ class ChatHandler : public MessageHandler, public Net::ChatHandler
*/
void handleMessage(MessageIn &msg);
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
void talk(const std::string &text);
void me(const std::string &text);
diff --git a/src/net/tmwserv/connection.cpp b/src/net/tmwserv/connection.cpp
index 6762af89..9346e3cc 100644
--- a/src/net/tmwserv/connection.cpp
+++ b/src/net/tmwserv/connection.cpp
@@ -32,6 +32,7 @@
Net::Connection::Connection(ENetHost *client):
mConnection(0), mClient(client)
{
+ mPort = 0;
Net::connections++;
}
@@ -66,6 +67,8 @@ bool Net::Connection::connect(const std::string &address, short port)
return false;
}
+ mPort = port;
+
return true;
}
@@ -95,8 +98,6 @@ void Net::Connection::send(const MessageOut &msg)
return;
}
- //logger->log("Sending message of size %d...", msg.getDataSize());
-
ENetPacket *packet = enet_packet_create(msg.getData(),
msg.getDataSize(),
ENET_PACKET_FLAG_RELIABLE);
diff --git a/src/net/tmwserv/connection.h b/src/net/tmwserv/connection.h
index 447cf71c..8d1c2924 100644
--- a/src/net/tmwserv/connection.h
+++ b/src/net/tmwserv/connection.h
@@ -71,6 +71,7 @@ namespace Net
friend Connection *Net::getConnection();
Connection(ENetHost *client);
+ short mPort;
ENetPeer *mConnection;
ENetHost *mClient;
State mState;
diff --git a/src/net/tmwserv/gamehandler.cpp b/src/net/tmwserv/gamehandler.cpp
new file mode 100644
index 00000000..ec2f33c4
--- /dev/null
+++ b/src/net/tmwserv/gamehandler.cpp
@@ -0,0 +1,132 @@
+/*
+ * The Mana World
+ * Copyright (C) 2004 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/tmwserv/gamehandler.h"
+
+#include "net/tmwserv/chathandler.h"
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/tmwserv/chatserver/chatserver.h"
+#include "net/tmwserv/gameserver/gameserver.h"
+
+#include "main.h"
+
+Net::GameHandler *gameHandler;
+
+extern TmwServ::ChatHandler *chatHandler;
+
+extern Net::Connection *gameServerConnection;
+
+namespace TmwServ {
+
+extern std::string netToken;
+extern ServerInfo gameServer;
+
+GameHandler::GameHandler()
+{
+ static const Uint16 _messages[] = {
+ GPMSG_DISCONNECT_RESPONSE,
+ 0
+ };
+ handledMessages = _messages;
+ gameHandler = this;
+}
+
+void GameHandler::handleMessage(MessageIn &msg)
+{
+ switch (msg.getId())
+ {
+ case GPMSG_DISCONNECT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ // TODO: Handle logout
+ }
+ // Logout failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Gameserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Gameserver: Unknown error";
+ break;
+ }
+ state = STATE_ERROR;
+ }
+ }
+ break;
+ }
+}
+
+void GameHandler::connect()
+{
+ //
+}
+
+bool GameHandler::isConnected()
+{
+ return gameServerConnection->isConnected() &&
+ chatHandler->isConnected();
+}
+
+void GameHandler::disconnect()
+{
+ gameServerConnection->disconnect();
+ chatHandler->disconnect();
+}
+
+void GameHandler::inGame()
+{
+ Net::GameServer::connect(gameServerConnection, netToken);
+ chatHandler->connect();
+}
+
+void GameHandler::mapLoaded(const std::string &mapName)
+{
+ // TODO
+}
+
+void GameHandler::who()
+{
+ // TODO
+}
+
+void GameHandler::quit()
+{
+ // TODO
+}
+
+void GameHandler::ping(int tick)
+{
+ // TODO
+}
+
+void GameHandler::clear()
+{
+ disconnect();
+}
+
+} // namespace TmwServ
diff --git a/src/net/tmwserv/maphandler.h b/src/net/tmwserv/gamehandler.h
index 099ec7e0..4721d634 100644
--- a/src/net/tmwserv/maphandler.h
+++ b/src/net/tmwserv/gamehandler.h
@@ -22,19 +22,27 @@
#ifndef NET_TMWSERV_MAPHANDLER_H
#define NET_TMWSERV_MAPHANDLER_H
-#include "net/maphandler.h"
+#include "net/gamehandler.h"
#include "net/messagehandler.h"
+#include "net/serverinfo.h"
+
namespace TmwServ {
-class MapHandler : public MessageHandler, public Net::MapHandler
+class GameHandler : public MessageHandler, public Net::GameHandler
{
public:
- MapHandler();
+ GameHandler();
void handleMessage(MessageIn &msg);
- void connect(LoginData *loginData);
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
+ void inGame();
void mapLoaded(const std::string &mapName);
@@ -43,6 +51,8 @@ class MapHandler : public MessageHandler, public Net::MapHandler
void quit();
void ping(int tick);
+
+ void clear();
};
} // namespace TmwServ
diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp
index 011433fe..81bb46be 100644
--- a/src/net/tmwserv/generalhandler.cpp
+++ b/src/net/tmwserv/generalhandler.cpp
@@ -19,28 +19,28 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "net/tmwserv/generalhandler.h"
+
#include "gui/inventorywindow.h"
#include "gui/partywindow.h"
+#include "gui/register.h"
#include "gui/skilldialog.h"
#include "gui/specialswindow.h"
#include "gui/statuswindow.h"
-#include "net/tmwserv/generalhandler.h"
-
#include "net/tmwserv/network.h"
#include "net/tmwserv/connection.h"
#include "net/tmwserv/beinghandler.h"
#include "net/tmwserv/buysellhandler.h"
-#include "net/tmwserv/charserverhandler.h"
+#include "net/tmwserv/charhandler.h"
#include "net/tmwserv/chathandler.h"
#include "net/tmwserv/effecthandler.h"
+#include "net/tmwserv/gamehandler.h"
#include "net/tmwserv/guildhandler.h"
#include "net/tmwserv/inventoryhandler.h"
#include "net/tmwserv/itemhandler.h"
#include "net/tmwserv/loginhandler.h"
-#include "net/tmwserv/logouthandler.h"
-#include "net/tmwserv/maphandler.h"
#include "net/tmwserv/npchandler.h"
#include "net/tmwserv/partyhandler.h"
#include "net/tmwserv/playerhandler.h"
@@ -49,6 +49,8 @@
#include "utils/gettext.h"
+#include "main.h"
+
#include <list>
Net::GeneralHandler *generalHandler;
@@ -59,24 +61,29 @@ Net::Connection *accountServerConnection = 0;
namespace TmwServ {
+std::string netToken = "";
+ServerInfo gameServer;
+ServerInfo chatServer;
+
GeneralHandler::GeneralHandler():
- mBeingHandler(new BeingHandler),
- mBuySellHandler(new BuySellHandler),
- mCharServerHandler(new CharServerHandler),
- mChatHandler(new ChatHandler),
- mEffectHandler(new EffectHandler),
- mGuildHandler(new GuildHandler),
- mInventoryHandler(new InventoryHandler),
- mItemHandler(new ItemHandler),
- mLoginHandler(new LoginHandler),
- mLogoutHandler(new LogoutHandler),
- mMapHandler(new MapHandler),
- mNpcHandler(new NpcHandler),
- mPartyHandler(new PartyHandler),
- mPlayerHandler(new PlayerHandler),
- mTradeHandler(new TradeHandler),
- mSpecialHandler(new SpecialHandler)
+ mBeingHandler(new BeingHandler),
+ mBuySellHandler(new BuySellHandler),
+ mCharHandler(new CharHandler),
+ mChatHandler(new ChatHandler),
+ mEffectHandler(new EffectHandler),
+ mGameHandler(new GameHandler),
+ mGuildHandler(new GuildHandler),
+ mInventoryHandler(new InventoryHandler),
+ mItemHandler(new ItemHandler),
+ mLoginHandler(new LoginHandler),
+ mNpcHandler(new NpcHandler),
+ mPartyHandler(new PartyHandler),
+ mPlayerHandler(new PlayerHandler),
+ mTradeHandler(new TradeHandler),
+ mSpecialHandler(new SpecialHandler)
{
+ Net::initialize();
+
accountServerConnection = Net::getConnection();
gameServerConnection = Net::getConnection();
chatServerConnection = Net::getConnection();
@@ -98,15 +105,14 @@ void GeneralHandler::load()
{
Net::registerHandler(mBeingHandler.get());
Net::registerHandler(mBuySellHandler.get());
- Net::registerHandler(mCharServerHandler.get());
+ Net::registerHandler(mCharHandler.get());
Net::registerHandler(mChatHandler.get());
Net::registerHandler(mEffectHandler.get());
+ Net::registerHandler(mGameHandler.get());
Net::registerHandler(mGuildHandler.get());
Net::registerHandler(mInventoryHandler.get());
Net::registerHandler(mItemHandler.get());
Net::registerHandler(mLoginHandler.get());
- Net::registerHandler(mLogoutHandler.get());
- Net::registerHandler(mMapHandler.get());
Net::registerHandler(mNpcHandler.get());
Net::registerHandler(mPartyHandler.get());
Net::registerHandler(mPlayerHandler.get());
@@ -151,6 +157,7 @@ void GeneralHandler::guiWindowsLoaded()
{
inventoryWindow->setSplitAllowed(true);
partyWindow->clearPartyName();
+ RegisterDialog::setGender(NULL);
skillDialog->loadSkills("tmw-skills.xml");
specialsWindow->loadSpecials("specials.xml");
@@ -169,4 +176,9 @@ void GeneralHandler::guiWindowsUnloaded()
// TODO
}
+void GeneralHandler::clearHandlers()
+{
+ Net::clearHandlers();
+}
+
} // namespace TmwServ
diff --git a/src/net/tmwserv/generalhandler.h b/src/net/tmwserv/generalhandler.h
index 40166ca0..6c1d849f 100644
--- a/src/net/tmwserv/generalhandler.h
+++ b/src/net/tmwserv/generalhandler.h
@@ -47,18 +47,19 @@ class GeneralHandler : public Net::GeneralHandler
void guiWindowsUnloaded();
+ void clearHandlers();
+
protected:
MessageHandlerPtr mBeingHandler;
MessageHandlerPtr mBuySellHandler;
- MessageHandlerPtr mCharServerHandler;
+ MessageHandlerPtr mCharHandler;
MessageHandlerPtr mChatHandler;
MessageHandlerPtr mEffectHandler;
+ MessageHandlerPtr mGameHandler;
MessageHandlerPtr mGuildHandler;
MessageHandlerPtr mInventoryHandler;
MessageHandlerPtr mItemHandler;
MessageHandlerPtr mLoginHandler;
- MessageHandlerPtr mLogoutHandler;
- MessageHandlerPtr mMapHandler;
MessageHandlerPtr mNpcHandler;
MessageHandlerPtr mPartyHandler;
MessageHandlerPtr mPlayerHandler;
diff --git a/src/net/tmwserv/loginhandler.cpp b/src/net/tmwserv/loginhandler.cpp
index f728d831..74b8abad 100644
--- a/src/net/tmwserv/loginhandler.cpp
+++ b/src/net/tmwserv/loginhandler.cpp
@@ -48,6 +48,8 @@ LoginHandler::LoginHandler()
APMSG_RECONNECT_RESPONSE,
APMSG_PASSWORD_CHANGE_RESPONSE,
APMSG_EMAIL_CHANGE_RESPONSE,
+ APMSG_LOGOUT_RESPONSE,
+ APMSG_UNREGISTER_RESPONSE,
0
};
handledMessages = _messages;
@@ -156,7 +158,54 @@ void LoginHandler::handleMessage(MessageIn &msg)
}
}
break;
+ case APMSG_LOGOUT_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful logout
+ if (errMsg == ERRMSG_OK)
+ {
+ // TODO: handle logout
+ }
+ // Logout failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_NO_LOGIN:
+ errorMessage = "Accountserver: Not logged in";
+ break;
+ default:
+ errorMessage = "Accountserver: Unknown error";
+ break;
+ }
+ state = STATE_ERROR;
+ }
+ }
+ break;
+ case APMSG_UNREGISTER_RESPONSE:
+ {
+ int errMsg = msg.readInt8();
+ // Successful unregistration
+ if (errMsg == ERRMSG_OK)
+ {
+ state = STATE_UNREGISTER;
+ }
+ // Unregistration failed
+ else
+ {
+ switch (errMsg) {
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage =
+ "Accountserver: Wrong username or password";
+ break;
+ default:
+ errorMessage = "Accountserver: Unknown error";
+ break;
+ }
+ state = STATE_ACCOUNTCHANGE_ERROR;
+ }
+ }
+ break;
}
}
@@ -167,7 +216,8 @@ void LoginHandler::handleLoginResponse(MessageIn &msg)
if (errMsg == ERRMSG_OK)
{
readUpdateHost(msg);
- state = STATE_CHAR_SELECT;
+ // No worlds atm, but future use :-D
+ state = STATE_WORLD_SELECT;
}
else
{
@@ -199,7 +249,7 @@ void LoginHandler::handleRegisterResponse(MessageIn &msg)
if (errMsg == ERRMSG_OK)
{
readUpdateHost(msg);
- state = STATE_CHAR_SELECT;
+ state = STATE_WORLD_SELECT;
}
else
{
@@ -233,6 +283,23 @@ void LoginHandler::readUpdateHost(MessageIn &msg)
}
}
+void LoginHandler::connect()
+{
+ accountServerConnection->connect(mServer.hostname, mServer.port);
+ /*if (state == STATE_CONNECT_SERVER)
+ state = STATE_LOGIN;*/
+}
+
+bool LoginHandler::isConnected()
+{
+ return accountServerConnection->isConnected();
+}
+
+void LoginHandler::disconnect()
+{
+ accountServerConnection->disconnect();
+}
+
void LoginHandler::loginAccount(LoginData *loginData)
{
mLoginData = loginData;
@@ -255,7 +322,7 @@ void LoginHandler::changePassword(const std::string &username,
newPassword);
}
-void LoginHandler::chooseServer(int server)
+void LoginHandler::chooseServer(unsigned int server)
{
// TODO
}
@@ -275,4 +342,9 @@ void LoginHandler::unregisterAccount(const std::string &username,
Net::AccountServer::Account::unregister(username, password);
}
+Worlds LoginHandler::getWorlds()
+{
+ return Worlds();
+}
+
} // namespace TmwServ
diff --git a/src/net/tmwserv/loginhandler.h b/src/net/tmwserv/loginhandler.h
index f3bc0c6d..50b3d8c7 100644
--- a/src/net/tmwserv/loginhandler.h
+++ b/src/net/tmwserv/loginhandler.h
@@ -25,6 +25,8 @@
#include "net/loginhandler.h"
#include "net/messagehandler.h"
+#include "net/serverinfo.h"
+
class LoginData;
namespace TmwServ {
@@ -36,6 +38,12 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler
void handleMessage(MessageIn &msg);
+ void connect();
+
+ bool isConnected();
+
+ void disconnect();
+
void loginAccount(LoginData *loginData);
void changeEmail(const std::string &email);
@@ -44,13 +52,15 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler
const std::string &oldPassword,
const std::string &newPassword);
- void chooseServer(int server);
+ void chooseServer(unsigned int server);
void registerAccount(LoginData *loginData);
void unregisterAccount(const std::string &username,
const std::string &password);
+ Worlds getWorlds();
+
private:
void handleLoginResponse(MessageIn &msg);
void handleRegisterResponse(MessageIn &msg);
diff --git a/src/net/tmwserv/logouthandler.cpp b/src/net/tmwserv/logouthandler.cpp
deleted file mode 100644
index 9ac6c7d4..00000000
--- a/src/net/tmwserv/logouthandler.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2004 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/tmwserv/logouthandler.h"
-
-#include "net/tmwserv/connection.h"
-#include "net/tmwserv/protocol.h"
-
-#include "net/tmwserv/accountserver/accountserver.h"
-#include "net/tmwserv/chatserver/chatserver.h"
-#include "net/tmwserv/gameserver/gameserver.h"
-
-#include "net/messagein.h"
-
-#include "main.h"
-
-Net::LogoutHandler *logoutHandler;
-
-extern Net::Connection *gameServerConnection;
-extern Net::Connection *chatServerConnection;
-extern Net::Connection *accountServerConnection;
-
-namespace TmwServ {
-
-LogoutHandler::LogoutHandler():
- mPassToken(NULL),
- mScenario(LOGOUT_EXIT),
- mLoggedOutAccount(false),
- mLoggedOutGame(false),
- mLoggedOutChat(false)
-{
- static const Uint16 _messages[] = {
- APMSG_LOGOUT_RESPONSE,
- APMSG_UNREGISTER_RESPONSE,
- GPMSG_DISCONNECT_RESPONSE,
- CPMSG_DISCONNECT_RESPONSE,
- 0
- };
- handledMessages = _messages;
- logoutHandler = this;
-}
-
-void LogoutHandler::handleMessage(MessageIn &msg)
-{
- switch (msg.getId())
- {
- case APMSG_LOGOUT_RESPONSE:
- {
- int errMsg = msg.readInt8();
-
- // Successful logout
- if (errMsg == ERRMSG_OK)
- {
- mLoggedOutAccount = true;
-
- switch (mScenario)
- {
- case LOGOUT_SWITCH_LOGIN:
- if (mLoggedOutGame && mLoggedOutChat)
- state = STATE_SWITCH_ACCOUNTSERVER;
- break;
-
- case LOGOUT_EXIT:
- default:
- if (mLoggedOutGame && mLoggedOutChat)
- state = STATE_FORCE_QUIT;
- break;
- }
- }
- // Logout failed
- else
- {
- switch (errMsg) {
- case ERRMSG_NO_LOGIN:
- errorMessage = "Accountserver: Not logged in";
- break;
- default:
- errorMessage = "Accountserver: Unknown error";
- break;
- }
- state = STATE_ERROR;
- }
- }
- break;
- case APMSG_UNREGISTER_RESPONSE:
- {
- int errMsg = msg.readInt8();
- // Successful unregistration
- if (errMsg == ERRMSG_OK)
- {
- state = STATE_UNREGISTER;
- }
- // Unregistration failed
- else
- {
- switch (errMsg) {
- case ERRMSG_INVALID_ARGUMENT:
- errorMessage =
- "Accountserver: Wrong username or password";
- break;
- default:
- errorMessage = "Accountserver: Unknown error";
- break;
- }
- state = STATE_ACCOUNTCHANGE_ERROR;
- }
- }
- break;
- case GPMSG_DISCONNECT_RESPONSE:
- {
- int errMsg = msg.readInt8();
- // Successful logout
- if (errMsg == ERRMSG_OK)
- {
- mLoggedOutGame = true;
-
- switch (mScenario)
- {
- case LOGOUT_SWITCH_CHARACTER:
- if (mPassToken)
- {
- *mPassToken = msg.readString(32);
- mPassToken = NULL;
- }
- if (mLoggedOutChat) state = STATE_RECONNECT_ACCOUNT;
- break;
-
- case LOGOUT_SWITCH_LOGIN:
- if (mLoggedOutAccount && mLoggedOutChat)
- state = STATE_SWITCH_ACCOUNTSERVER;
- break;
-
- case LOGOUT_EXIT:
- default:
- if (mLoggedOutAccount && mLoggedOutChat)
- state = STATE_FORCE_QUIT;
- break;
- }
- }
- // Logout failed
- else
- {
- switch (errMsg) {
- case ERRMSG_NO_LOGIN:
- errorMessage = "Gameserver: Not logged in";
- break;
- default:
- errorMessage = "Gameserver: Unknown error";
- break;
- }
- state = STATE_ERROR;
- }
- }
- break;
- case CPMSG_DISCONNECT_RESPONSE:
- {
- int errMsg = msg.readInt8();
- // Successful logout
- if (errMsg == ERRMSG_OK)
- {
- mLoggedOutChat = true;
-
- switch (mScenario)
- {
- case LOGOUT_SWITCH_CHARACTER:
- if (mLoggedOutGame) state = STATE_RECONNECT_ACCOUNT;
- break;
-
- case LOGOUT_SWITCH_LOGIN:
- if (mLoggedOutAccount && mLoggedOutGame)
- state = STATE_SWITCH_ACCOUNTSERVER;
- break;
-
- case LOGOUT_EXIT:
- default:
- if (mLoggedOutAccount && mLoggedOutGame)
- {
- state = STATE_FORCE_QUIT;
- }
- break;
- }
- }
- else
- {
- switch (errMsg) {
- case ERRMSG_NO_LOGIN:
- errorMessage = "Chatserver: Not logged in";
- break;
- default:
- errorMessage = "Chatserver: Unknown error";
- break;
- }
- state = STATE_ERROR;
- }
- }
- break;
- }
-}
-
-void LogoutHandler::setScenario(unsigned short scenario,
- std::string *passToken)
-{
- mScenario = scenario;
- mPassToken = passToken;
-
- // Can't logout if we were not logged in ...
- if (mScenario == LOGOUT_EXIT)
- {
- if (accountServerConnection->isConnected())
- Net::AccountServer::logout();
- else
- setAccountLoggedOut();
-
- if (gameServerConnection->isConnected())
- Net::GameServer::logout(false);
- else
- setGameLoggedOut();
-
- if (chatServerConnection->isConnected())
- Net::ChatServer::logout();
- else
- setChatLoggedOut();
- }
- else if (mScenario == LOGOUT_SWITCH_LOGIN)
- {
- if (accountServerConnection->isConnected())
- Net::AccountServer::logout();
- else
- setAccountLoggedOut();
-
- if (gameServerConnection->isConnected())
- Net::GameServer::logout(false);
- else
- setGameLoggedOut();
-
- if (chatServerConnection->isConnected())
- Net::ChatServer::logout();
- else
- setChatLoggedOut();
- }
- else if (mScenario == LOGOUT_SWITCH_CHARACTER)
- {
- Net::GameServer::logout(true);
- Net::ChatServer::logout();
- }
-}
-
-void LogoutHandler::reset()
-{
- mPassToken = NULL;
- mScenario = LOGOUT_EXIT;
- mLoggedOutAccount = false;
- mLoggedOutGame = false;
- mLoggedOutChat = false;
-}
-
-} // namespace TmwServ
diff --git a/src/net/tmwserv/logouthandler.h b/src/net/tmwserv/logouthandler.h
deleted file mode 100644
index 19b6d43a..00000000
--- a/src/net/tmwserv/logouthandler.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2004 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
- */
-
-#ifndef NET_TMWSERV_LOGOUTHANDLER_H
-#define NET_TMWSERV_LOGOUTHANDLER_H
-
-#include "net/logouthandler.h"
-#include "net/messagehandler.h"
-
-#include <string>
-
-namespace TmwServ {
-
-class LogoutHandler : public MessageHandler, public Net::LogoutHandler
-{
- public:
- LogoutHandler();
-
- void handleMessage(MessageIn &msg);
-
- void setScenario(unsigned short scenario,
- std::string *passToken = NULL);
-
- void reset();
-
- void setAccountLoggedOut() { mLoggedOutAccount = true; }
- void setGameLoggedOut() { mLoggedOutGame = true; }
- void setChatLoggedOut() { mLoggedOutChat = true; }
-
- private:
- std::string* mPassToken;
- unsigned short mScenario;
- bool mLoggedOutAccount;
- bool mLoggedOutGame;
- bool mLoggedOutChat;
-};
-
-} // namespace TmwServ
-
-#endif
diff --git a/src/net/tmwserv/maphandler.cpp b/src/net/tmwserv/maphandler.cpp
deleted file mode 100644
index d64ea13b..00000000
--- a/src/net/tmwserv/maphandler.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * The Mana World
- * Copyright (C) 2004 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/tmwserv/maphandler.h"
-
-Net::MapHandler *mapHandler;
-
-namespace TmwServ {
-
-MapHandler::MapHandler()
-{
- static const Uint16 _messages[] = {
- 0
- };
- handledMessages = _messages;
- mapHandler = this;
-}
-
-void MapHandler::handleMessage(MessageIn &msg)
-{
-}
-
-void MapHandler::connect(LoginData *loginData)
-{
- // TODO
-}
-
-void MapHandler::mapLoaded(const std::string &mapName)
-{
- // TODO
-}
-
-void MapHandler::who()
-{
- // TODO
-}
-
-void MapHandler::quit()
-{
- // TODO
-}
-
-void MapHandler::ping(int tick)
-{
- // TODO
-}
-
-} // namespace TmwServ
diff --git a/src/net/logouthandler.h b/src/net/worldinfo.h
index f6c44e5c..045c64c2 100644
--- a/src/net/logouthandler.h
+++ b/src/net/worldinfo.h
@@ -19,31 +19,20 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef LOGOUTHANDLER_H
-#define LOGOUTHANDLER_H
+#ifndef WORLD_INFO_H
+#define WORLD_INFO_H
-#include "logindata.h"
+#include <string>
+#include <vector>
-#include <iosfwd>
+typedef struct {
+ int address;
+ std::string name;
+ short port;
+ short online_users;
+ std::string updateHost;
+} WorldInfo;
-/**
- * The different scenarios for which LogoutHandler can be used
- */
-enum {
- LOGOUT_EXIT,
- LOGOUT_SWITCH_LOGIN,
- LOGOUT_SWITCH_CHARACTER
-};
-
-namespace Net {
-class LogoutHandler
-{
- public:
- virtual void setScenario(unsigned short scenario,
- std::string *passToken = NULL) = 0;
-
- virtual void reset() = 0;
-};
-}
+typedef std::vector<WorldInfo*> Worlds;
-#endif // LOGOUTHANDLER_H
+#endif // WORLD_INFO_H