summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--src/gui/char_select.cpp8
-rw-r--r--src/gui/connection.cpp4
-rw-r--r--src/gui/gui.cpp2
-rw-r--r--src/gui/login.cpp7
-rw-r--r--src/gui/register.cpp4
-rw-r--r--src/gui/updatewindow.cpp6
-rw-r--r--src/main.cpp189
-rw-r--r--src/main.h30
-rw-r--r--src/net/charserverhandler.cpp22
-rw-r--r--src/net/loginhandler.cpp8
-rw-r--r--src/net/maploginhandler.cpp4
-rw-r--r--src/net/messageout.cpp8
-rw-r--r--src/net/messageout.h5
-rw-r--r--src/net/network.cpp153
-rw-r--r--src/net/network.h59
16 files changed, 323 insertions, 205 deletions
diff --git a/ChangeLog b/ChangeLog
index a9596e29..c4cb401c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-08-20 Bjørn Lindeijer <bjorn@lindeijer.nl>
+
+ * src/gui/connection.cpp, src/gui/login.cpp, src/gui/gui.cpp,
+ src/gui/updatewindow.cpp, src/gui/char_select.cpp,
+ src/gui/register.cpp, src/main.cpp, src/net/loginhandler.cpp,
+ src/net/messageout.cpp, src/net/network.h,
+ src/net/charserverhandler.cpp, src/net/maploginhandler.cpp,
+ src/net/messageout.h, src/net/network.cpp, src/main.h: The Network
+ can now connect to the three servers and affected methods now take the
+ server type as a parameter. The MessageOut gained a convenience
+ constructor (same as was added server side). The game states during
+ login sequence have been renamed and redone in order to ensure no
+ communication is attempted to unconnected servers. This allowed the
+ removal of the outgoing message queue. Connecting to the account
+ server has been moved before the login/register phase (dialogs will
+ still need to be updated). Quite a few things are expected to be
+ broken since I'm rather tired at the moment. I've left many TODO
+ entries in the code.
+
2006-08-19 Bjørn Lindeijer <bjorn@lindeijer.nl>
* src/game.cpp, src/net/network.h, src/net/network.cpp: Removed
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index 775ecc6f..2fa6c68e 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -139,7 +139,7 @@ void CharSelectDialog::action(const std::string &eventId, gcn::Widget *widget)
}
else if (eventId == "cancel")
{
- state = EXIT_STATE;
+ state = STATE_EXIT;
}
else if (eventId == "new")
{
@@ -208,7 +208,7 @@ void CharSelectDialog::attemptCharDelete()
msg.writeShort(PAMSG_CHAR_DELETE);
// TODO: Send the selected slot
msg.writeByte(0);
- network->send(msg);
+ network->send(Network::ACCOUNT, msg);
mCharInfo->lock();
}
@@ -218,7 +218,7 @@ void CharSelectDialog::attemptCharSelect()
MessageOut msg;
msg.writeShort(PAMSG_CHAR_SELECT);
msg.writeByte(mCharInfo->getPos());
- network->send(msg);
+ network->send(Network::ACCOUNT, msg);
mCharInfo->lock();
}
@@ -337,5 +337,5 @@ void CharCreateDialog::attemptCharCreate()
outMsg.writeShort(10); // INT
outMsg.writeShort(10); // DEX
outMsg.writeShort(10); // LUK
- network->send(outMsg);
+ network->send(Network::ACCOUNT, outMsg);
}
diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp
index f7fdaca6..a29008c3 100644
--- a/src/gui/connection.cpp
+++ b/src/gui/connection.cpp
@@ -35,7 +35,9 @@
namespace {
struct ConnectionActionListener : public gcn::ActionListener
{
- void action(const std::string &eventId, gcn::Widget *widget) { state = EXIT_STATE; }
+ void action(const std::string &eventId, gcn::Widget *widget) {
+ state = STATE_EXIT;
+ }
} listener;
}
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 026f24bd..0e200db3 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -234,7 +234,7 @@ Gui::mousePress(int mx, int my, int button)
// Mouse pressed on window container (basically, the map)
// Are we in-game yet?
- if (state != GAME_STATE)
+ if (state != STATE_GAME)
return;
// Check if we are alive and kickin'
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 2f646bd1..cb16dcb4 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -147,18 +147,17 @@ LoginDialog::action(const std::string &eventId, gcn::Widget *widget)
mLoginData->remember = mKeepCheck->isMarked();
mOkButton->setEnabled(false);
- //mCancelButton->setEnabled(false);
mRegisterButton->setEnabled(false);
- state = ACCOUNT_STATE;
+ state = STATE_LOGIN_ATTEMPT;
}
}
else if (eventId == "cancel")
{
- state = EXIT_STATE;
+ state = STATE_EXIT;
}
else if (eventId == "register")
{
- state = REGISTER_STATE;
+ state = STATE_REGISTER;
}
}
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index 49da10b6..52833aea 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -119,7 +119,7 @@ RegisterDialog::action(const std::string &eventId, gcn::Widget *widget)
{
if (eventId == "cancel")
{
- state = EXIT_STATE;
+ state = STATE_EXIT;
}
else if (eventId == "register")
{
@@ -205,7 +205,7 @@ RegisterDialog::action(const std::string &eventId, gcn::Widget *widget)
mLoginData->password = mPasswordField->getText();
mLoginData->email = mEmailField->getText();
- state = REGISTER_ACCOUNT_STATE;
+ state = STATE_REGISTER_ATTEMPT;
}
}
}
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index 8c69d3ef..77a026fe 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -136,7 +136,7 @@ void UpdaterWindow::action(const std::string &eventId, gcn::Widget *widget)
// Skip the updating process
if (mDownloadStatus == UPDATE_COMPLETE)
{
- state = EXIT_STATE;
+ state = STATE_EXIT;
}
else
{
@@ -145,7 +145,7 @@ void UpdaterWindow::action(const std::string &eventId, gcn::Widget *widget)
}
else if (eventId == "play")
{
- state = LOGIN_STATE;
+ state = STATE_LOGIN;
}
}
@@ -198,7 +198,7 @@ int UpdaterWindow::updateProgress(void *ptr,
uw->mCurrentFile + " (" + toString((int)progress * 100) + "%)");
uw->setProgress(progress);
- if (state != UPDATE_STATE || uw->mDownloadStatus == UPDATE_ERROR)
+ if (state != STATE_UPDATE || uw->mDownloadStatus == UPDATE_ERROR)
{
// If the action was canceled return an error code to stop the mThread
return -1;
diff --git a/src/main.cpp b/src/main.cpp
index dc76846e..d62594c9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -99,7 +99,9 @@ Logger *logger; /**< Log object */
namespace {
struct ErrorListener : public gcn::ActionListener
{
- void action(const std::string &eventId, gcn::Widget *widget) { state = LOGIN_STATE; }
+ void action(const std::string &eventId, gcn::Widget *widget) {
+ state = STATE_CHOOSE_SERVER;
+ }
} errorListener;
}
@@ -267,7 +269,7 @@ void init_engine()
}
gui = new Gui(graphics);
- state = UPDATE_STATE; /**< Initial game state */
+ state = STATE_CHOOSE_SERVER; /**< Initial game state */
// Initialize sound engine
try {
@@ -278,7 +280,7 @@ void init_engine()
sound.setMusicVolume((int)config.getValue("musicVolume", 60));
}
catch (const char *err) {
- state = ERROR_STATE;
+ state = STATE_ERROR;
errorMessage = err;
logger->log("Warning: %s", err);
}
@@ -409,9 +411,7 @@ MapLoginHandler mapLoginHandler;
// TODO Find some nice place for these functions
void accountLogin(LoginData *loginData)
{
- logger->log("Trying to connect to account server...");
logger->log("Username is %s", loginData->username.c_str());
- network->connect(loginData->hostname, loginData->port);
network->registerHandler(&loginHandler);
network->registerHandler(&charServerHandler);
loginHandler.setLoginData(loginData);
@@ -419,12 +419,11 @@ void accountLogin(LoginData *loginData)
charServerHandler.setCharInfo(&charInfo);
// Send login infos
- MessageOut msg;
- msg.writeShort(PAMSG_LOGIN);
+ MessageOut msg(PAMSG_LOGIN);
msg.writeLong(0); // client version
msg.writeString(loginData->username);
msg.writeString(loginData->password);
- network->send(msg);
+ network->send(Network::ACCOUNT, msg);
// Clear the password, avoids auto login when returning to login
loginData->password = "";
@@ -440,40 +439,37 @@ void accountLogin(LoginData *loginData)
void accountRegister(LoginData *loginData)
{
- logger->log("Trying to connect to account server...");
logger->log("Username is %s", loginData->username.c_str());
- network->connect(loginData->hostname, loginData->port);
network->registerHandler(&loginHandler);
loginHandler.setLoginData(loginData);
charServerHandler.setLoginData(loginData);
charServerHandler.setCharInfo(&charInfo);
// Send login infos
- MessageOut msg;
- msg.writeShort(PAMSG_REGISTER);
+ MessageOut msg(PAMSG_REGISTER);
msg.writeLong(0); // client version
msg.writeString(loginData->username);
msg.writeString(loginData->password);
msg.writeString(loginData->email);
- network->send(msg);
+ network->send(Network::ACCOUNT, msg);
}
void mapLogin(Network *network, LoginData *loginData)
{
- MessageOut outMsg;
-
- logger->log("Trying to connect to map server...");
+ // TODO: Before the client has been identified using the magic token, the
+ // map path is not known yet.
logger->log("Map: %s", map_path.c_str());
- network->connect(loginData->hostname, loginData->port);
network->registerHandler(&mapLoginHandler);
// Send login infos
- outMsg.writeShort(0x0072);
- outMsg.writeLong(loginData->account_ID);
- outMsg.writeLong(player_node->mCharId);
- outMsg.writeLong(loginData->session_ID1);
- outMsg.writeLong(loginData->session_ID2);
+ // TODO: The token would need to be sent to complete client identification
+ // for the game server
+ //MessageOut outMsg(0x0072);
+ //outMsg.writeLong(loginData->account_ID);
+ //outMsg.writeLong(player_node->mCharId);
+ //outMsg.writeLong(loginData->session_ID1);
+ //outMsg.writeLong(loginData->session_ID2);
}
/** Main */
@@ -515,13 +511,6 @@ int main(int argc, char *argv[])
init_engine();
- if (options.skipUpdate && state != ERROR_STATE) {
- state = LOGIN_STATE;
- }
- else {
- state = UPDATE_STATE;
- }
-
unsigned int oldstate = !state; // We start with a status change.
Window *currentDialog = NULL;
@@ -549,20 +538,21 @@ int main(int argc, char *argv[])
}
network = new Network();
+
SDL_Event event;
- while (state != EXIT_STATE)
+ while (state != STATE_EXIT)
{
// Handle SDL events
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
- state = EXIT_STATE;
+ state = STATE_EXIT;
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
- state = EXIT_STATE;
+ state = STATE_EXIT;
break;
}
@@ -574,7 +564,7 @@ int main(int argc, char *argv[])
if (network->getState() == Network::NET_ERROR)
{
- state = ERROR_STATE;
+ state = STATE_ERROR;
errorMessage = "Got disconnected from server!";
}
@@ -596,48 +586,89 @@ int main(int argc, char *argv[])
gui->draw();
graphics->updateScreen();
+ // TODO: Add connect timeout to go back to choose server
+ if (state == STATE_CONNECT_ACCOUNT &&
+ network->isConnected(Network::ACCOUNT))
+ {
+ if (options.skipUpdate) {
+ state = STATE_LOGIN;
+ } else {
+ state = STATE_UPDATE;
+ }
+ }
+ else if (state == STATE_CONNECT_GAME &&
+ network->isConnected(Network::GAME) &&
+ network->isConnected(Network::CHAT))
+ {
+ // TODO: Somehow send the token
+ state = STATE_GAME;
+ }
+
if (state != oldstate) {
- switch (oldstate)
+ // Load updates after exiting the update state
+ if (oldstate == STATE_UPDATE)
{
- case UPDATE_STATE:
- loadUpdates();
- break;
-
- // Those states don't cause a network disconnect
- case ACCOUNT_STATE:
- case CONNECTING_STATE:
- break;
+ loadUpdates();
+ }
- default:
- network->disconnect();
- network->clearHandlers();
- break;
+ // Disconnect from account server once connected to game server
+ if (oldstate == STATE_CONNECT_GAME && state == STATE_GAME)
+ {
+ network->disconnect(Network::ACCOUNT);
}
oldstate = state;
- if (currentDialog && state != ACCOUNT_STATE &&
- state != CHAR_CONNECT_STATE) {
+ // Get rid of the dialog of the previous state
+ if (currentDialog) {
delete currentDialog;
currentDialog = NULL;
}
switch (state) {
- case LOGIN_STATE:
+ case STATE_CHOOSE_SERVER:
+ logger->log("State: CHOOSE_SERVER");
+ // TODO: Allow changing this using a server choice dialog
+ logger->log("Trying to connect to account server...");
+ network->connect(Network::ACCOUNT,
+ loginData.hostname, loginData.port);
+ state = STATE_CONNECT_ACCOUNT;
+ break;
+
+ case STATE_CONNECT_ACCOUNT:
+ logger->log("State: CONNECT_ACCOUNT");
+ break;
+
+ case STATE_UPDATE:
+ logger->log("State: UPDATE");
+ // TODO: Revive later
+ //currentDialog = new UpdaterWindow();
+ state = STATE_LOGIN;
+ break;
+
+ case STATE_LOGIN:
logger->log("State: LOGIN");
- if (!loginData.password.empty()) {
- state = ACCOUNT_STATE;
- } else {
- currentDialog = new LoginDialog(&loginData);
- }
+ currentDialog = new LoginDialog(&loginData);
+ // TODO: Restore autologin
+ //if (!loginData.password.empty()) {
+ // accountLogin(&loginData);
+ //}
+ break;
+
+ case STATE_LOGIN_ATTEMPT:
+ accountLogin(&loginData);
break;
- case REGISTER_STATE:
+ case STATE_REGISTER:
logger->log("State: REGISTER");
currentDialog = new RegisterDialog(&loginData);
break;
- case CHAR_SELECT_STATE:
+ case STATE_REGISTER_ATTEMPT:
+ accountRegister(&loginData);
+ break;
+
+ case STATE_CHAR_SELECT:
logger->log("State: CHAR_SELECT");
currentDialog = new CharSelectDialog(network, &charInfo);
if (options.chooseDefault) {
@@ -646,50 +677,38 @@ int main(int argc, char *argv[])
}
break;
- case GAME_STATE:
- sound.fadeOutMusic(1000);
-
- currentDialog = NULL;
- login_wallpaper->decRef();
- login_wallpaper = NULL;
-
- logger->log("State: GAME");
- game = new Game(network);
- game->logic();
- delete game;
- state = EXIT_STATE;
- break;
-
- case UPDATE_STATE:
- logger->log("State: UPDATE");
- currentDialog = new UpdaterWindow();
- break;
-
- case ERROR_STATE:
+ case STATE_ERROR:
logger->log("State: ERROR");
currentDialog = new OkDialog("Error", errorMessage);
currentDialog->addActionListener(&errorListener);
currentDialog = NULL; // OkDialog deletes itself
- network->disconnect();
+ network->disconnect(Network::GAME);
+ network->disconnect(Network::CHAT);
network->clearHandlers();
break;
- case CONNECTING_STATE:
- logger->log("State: CONNECTING");
+ case STATE_CONNECT_GAME:
+ logger->log("State: CONNECT_GAME");
mapLogin(network, &loginData);
currentDialog = new ConnectionDialog();
break;
- case ACCOUNT_STATE:
- accountLogin(&loginData);
- break;
+ case STATE_GAME:
+ sound.fadeOutMusic(1000);
- case REGISTER_ACCOUNT_STATE:
- accountRegister(&loginData);
+ currentDialog = NULL;
+ login_wallpaper->decRef();
+ login_wallpaper = NULL;
+
+ logger->log("State: GAME");
+ game = new Game(network);
+ game->logic();
+ delete game;
+ state = STATE_EXIT;
break;
default:
- state = EXIT_STATE;
+ state = STATE_EXIT;
break;
}
}
diff --git a/src/main.h b/src/main.h
index 035b0ec7..47c650af 100644
--- a/src/main.h
+++ b/src/main.h
@@ -39,20 +39,20 @@
enum {
- EXIT_STATE,
- LOGIN_STATE,
- ACCOUNT_STATE,
- REGISTER_STATE,
- REGISTER_ACCOUNT_STATE,
- CHAR_CONNECT_STATE,
- CHAR_SERVER_STATE,
- CHAR_SELECT_STATE,
- CHAR_NEW_STATE,
- CHAR_DEL_STATE,
- GAME_STATE,
- ERROR_STATE,
- UPDATE_STATE,
- CONNECTING_STATE
+ STATE_CHOOSE_SERVER,
+ STATE_CONNECT_ACCOUNT,
+ STATE_UPDATE,
+ STATE_LOGIN,
+ STATE_LOGIN_ATTEMPT,
+ STATE_REGISTER,
+ STATE_REGISTER_ATTEMPT,
+ STATE_CHAR_SELECT,
+ STATE_CHAR_NEW,
+ STATE_CHAR_DELETE,
+ STATE_ERROR,
+ STATE_CONNECT_GAME,
+ STATE_GAME,
+ STATE_EXIT
};
/* length definitions for several char[]s in order
@@ -66,7 +66,7 @@ enum {
LEN_MIN_PASSWORD = 4
};
-extern char n_server, n_character;
+extern char n_character;
extern unsigned char state;
extern std::string errorMessage;
diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp
index b8cc710e..ea9b3196 100644
--- a/src/net/charserverhandler.cpp
+++ b/src/net/charserverhandler.cpp
@@ -165,14 +165,20 @@ CharServerHandler::handleCharSelectResponse(MessageIn &msg)
if (errMsg == 0)
{
- //std::string token = msg.readString(32);
- //std::string gameServer = msg.readString();
- //unsigned short gameServerPort = msg.readShort();
- //std::string chatServer = msg.readString();
- //unsigned short chatServerPort = msg.readShort();
-
- // TODO: Connect to game and chat servers, and login using the given
- // TODO: token.
+ // TODO: Somehow be able to send this token once connected
+ std::string token = msg.readString(32);
+ std::string gameServer = msg.readString();
+ unsigned short gameServerPort = msg.readShort();
+ std::string chatServer = msg.readString();
+ unsigned short chatServerPort = msg.readShort();
+
+ logger->log("Game server: %s:%d", gameServer.c_str(), gameServerPort);
+ logger->log("Chat server: %s:%d", chatServer.c_str(), chatServerPort);
+
+ network->connect(Network::GAME, gameServer, gameServerPort);
+ network->connect(Network::CHAT, chatServer, chatServerPort);
+
+ state = STATE_CONNECT_GAME;
}
}
diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp
index 27d8eed5..4790d7d1 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/loginhandler.cpp
@@ -51,7 +51,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
// Successful login
if (errMsg == ERRMSG_OK)
{
- state = CHAR_SELECT_STATE;
+ state = STATE_CHAR_SELECT;
}
// Login failed
else
@@ -73,7 +73,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
errorMessage = "Unknown error";
break;
}
- state = ERROR_STATE;
+ state = STATE_ERROR;
}
}
break;
@@ -83,7 +83,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
// Successful registration
if (errMsg == ERRMSG_OK)
{
- state = ACCOUNT_STATE;
+ state = STATE_CHAR_SELECT;
}
// Registration failed
else
@@ -105,7 +105,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
errorMessage = "Unknown error";
break;
}
- state = ERROR_STATE;
+ state = STATE_ERROR;
}
}
break;
diff --git a/src/net/maploginhandler.cpp b/src/net/maploginhandler.cpp
index 38ed2203..579e8542 100644
--- a/src/net/maploginhandler.cpp
+++ b/src/net/maploginhandler.cpp
@@ -50,12 +50,12 @@ void MapLoginHandler::handleMessage(MessageIn *msg)
msg->readLong(); // server tick
//logger->log("Protocol: Player start position: (%d, %d), Direction: %d",
// player_node->mX, player_node->mY, direction);
- state = GAME_STATE;
+ state = STATE_GAME;
break;
case 0x0081:
logger->log("Warning: Map server D/C");
- state = ERROR_STATE;
+ state = STATE_ERROR;
break;
}
}
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
index 7f5fadcb..426a1c0d 100644
--- a/src/net/messageout.cpp
+++ b/src/net/messageout.cpp
@@ -36,6 +36,14 @@ MessageOut::MessageOut():
{
}
+MessageOut::MessageOut(short id):
+ mData(0),
+ mDataSize(0),
+ mPos(0)
+{
+ writeShort(id);
+}
+
MessageOut::~MessageOut()
{
if (mData) {
diff --git a/src/net/messageout.h b/src/net/messageout.h
index 22754f60..81369c0e 100644
--- a/src/net/messageout.h
+++ b/src/net/messageout.h
@@ -38,6 +38,11 @@ class MessageOut
MessageOut();
/**
+ * Constructor.
+ */
+ MessageOut(short id);
+
+ /**
* Destructor.
*/
~MessageOut();
diff --git a/src/net/network.cpp b/src/net/network.cpp
index f543bfb1..23d9e291 100644
--- a/src/net/network.cpp
+++ b/src/net/network.cpp
@@ -32,47 +32,55 @@
Network *network;
Network::Network():
- mClient(0), mServer(0),
- mAddress(), mPort(0),
- mState(IDLE)
+ mAccountServer(NULL),
+ mGameServer(NULL),
+ mChatServer(NULL),
+ mState(NET_OK)
{
+ mClient = enet_host_create(NULL, 3, 0, 0);
+
+ if (!mClient)
+ {
+ logger->error(
+ "An error occurred while trying to create an ENet client.");
+ mState = NET_ERROR;
+ }
}
Network::~Network()
{
clearHandlers();
- if (mState != IDLE && mState != NET_ERROR)
- disconnect();
+ disconnect(ACCOUNT);
+ disconnect(GAME);
+ disconnect(CHAT);
}
-bool Network::connect(const std::string &address, short port)
+bool
+Network::connect(Server server, const std::string &address, short port)
{
- if (mState != IDLE && mState != NET_ERROR)
- {
- logger->log("Tried to connect an already connected socket!");
- return false;
- }
+ logger->log("Network::connect(%d, %s, %i)", server, address.c_str(), port);
if (address.empty())
{
- logger->log("Empty address given to Network::connect()!");
+ logger->log("Network::connect() got empty address!");
mState = NET_ERROR;
return false;
}
- logger->log("Network::Connecting to %s:%i", address.c_str(), port);
-
- mAddress = address;
- mPort = port;
+ ENetPeer *peer = NULL;
- mState = CONNECTING;
-
- mClient = enet_host_create(NULL, 1, 0, 0);
+ switch (server) {
+ case ACCOUNT: peer = mAccountServer; break;
+ case GAME: peer = mGameServer; break;
+ case CHAT: peer = mChatServer; break;
+ }
- if (!mClient)
+ if (peer != NULL)
{
- logger->error("An error occurred while trying to create an ENet client.");
+ logger->log("Network::connect() already connected (or connecting) to "
+ "this server!");
+ return false;
}
ENetAddress enetAddress;
@@ -81,32 +89,51 @@ bool Network::connect(const std::string &address, short port)
enetAddress.port = port;
// Initiate the connection, allocating channel 0.
- mServer = enet_host_connect(mClient, &enetAddress, 1);
+ peer = enet_host_connect(mClient, &enetAddress, 1);
- if (mServer == 0)
+ if (peer == NULL)
{
logger->log("Unable to initiate connection to the server.");
mState = NET_ERROR;
return false;
}
+ switch (server) {
+ case ACCOUNT: mAccountServer = peer; break;
+ case GAME: mGameServer = peer; break;
+ case CHAT: mChatServer = peer; break;
+ }
+
return true;
}
-void Network::disconnect()
+void
+Network::disconnect(Server server)
{
- mState = IDLE;
+ ENetPeer *peer = NULL;
- if (mServer)
+ switch (server) {
+ case ACCOUNT: peer = mAccountServer; break;
+ case GAME: peer = mGameServer; break;
+ case CHAT: peer = mChatServer; break;
+ }
+
+ if (peer)
{
- enet_peer_disconnect(mServer, 0);
+ enet_peer_disconnect(peer, 0);
enet_host_flush(mClient);
- enet_peer_reset(mServer);
- mServer = 0;
+ enet_peer_reset(peer);
+
+ switch (server) {
+ case ACCOUNT: mAccountServer = NULL; break;
+ case GAME: mGameServer = NULL; break;
+ case CHAT: mChatServer = NULL; break;
+ }
}
}
-void Network::registerHandler(MessageHandler *handler)
+void
+Network::registerHandler(MessageHandler *handler)
{
const Uint16 *i = handler->handledMessages;
@@ -119,7 +146,8 @@ void Network::registerHandler(MessageHandler *handler)
handler->setNetwork(this);
}
-void Network::unregisterHandler(MessageHandler *handler)
+void
+Network::unregisterHandler(MessageHandler *handler)
{
for (const Uint16 *i = handler->handledMessages; *i; i++)
{
@@ -129,7 +157,8 @@ void Network::unregisterHandler(MessageHandler *handler)
handler->setNetwork(0);
}
-void Network::clearHandlers()
+void
+Network::clearHandlers()
{
MessageHandlerIterator i;
for (i = mMessageHandlers.begin(); i != mMessageHandlers.end(); i++)
@@ -139,6 +168,20 @@ void Network::clearHandlers()
mMessageHandlers.clear();
}
+bool
+Network::isConnected(Server server) const
+{
+ ENetPeer *peer = NULL;
+
+ switch (server) {
+ case ACCOUNT: peer = mAccountServer; break;
+ case GAME: peer = mGameServer; break;
+ case CHAT: peer = mChatServer; break;
+ }
+
+ return peer->state == ENET_PEER_STATE_CONNECTED;
+}
+
void
Network::dispatchMessage(ENetPacket *packet)
{
@@ -162,7 +205,7 @@ Network::dispatchMessage(ENetPacket *packet)
void Network::flush()
{
- if (mState == IDLE || mState == NET_ERROR)
+ if (mState == NET_ERROR)
{
return;
}
@@ -176,7 +219,6 @@ void Network::flush()
{
case ENET_EVENT_TYPE_CONNECT:
logger->log("Connected.");
- mState = CONNECTED;
// Store any relevant server information here.
event.peer->data = 0;
break;
@@ -185,46 +227,53 @@ void Network::flush()
logger->log("Incoming data...");
dispatchMessage(event.packet);
break;
+
case ENET_EVENT_TYPE_DISCONNECT:
- mState = IDLE;
logger->log("Disconnected.");
// Reset the server information.
event.peer->data = 0;
break;
+
case ENET_EVENT_TYPE_NONE:
logger->log("No event during 10 milliseconds.");
break;
+
default:
logger->log("Unhandled enet event.");
break;
}
}
-
- // If connected, manage incoming and outcoming packets
- if (isConnected())
- {
- while (isConnected() && !mOutgoingPackets.empty())
- {
- ENetPacket *packet = mOutgoingPackets.front();
- enet_peer_send(mServer, 0, packet);
- mOutgoingPackets.pop();
- }
- }
}
-void Network::send(const MessageOut &msg)
+void Network::send(Server server, const MessageOut &msg)
{
- if (mState == IDLE || mState == NET_ERROR)
+ if (mState == NET_ERROR)
{
logger->log("Warning: attempt to send a message while network not "
"ready.");
return;
}
- ENetPacket *packet = enet_packet_create(msg.getData(),
- msg.getDataSize(),
- ENET_PACKET_FLAG_RELIABLE);
- mOutgoingPackets.push(packet);
+ ENetPeer *peer = NULL;
+
+ switch (server) {
+ case ACCOUNT: peer = mAccountServer; break;
+ case GAME: peer = mGameServer; break;
+ case CHAT: peer = mChatServer; break;
+ }
+
+ if (peer)
+ {
+ logger->log("Sending message of size %d to server %d...",
+ msg.getDataSize(), server);
+
+ // Directly send away the packet (TODO: check what ENet does in case
+ // this is done before connection is ready)
+ ENetPacket *packet = enet_packet_create(msg.getData(),
+ msg.getDataSize(),
+ ENET_PACKET_FLAG_RELIABLE);
+ enet_peer_send(peer, 0, packet);
+ }
}
char *iptostring(int address)
diff --git a/src/net/network.h b/src/net/network.h
index eb2ce8ab..49583b9d 100644
--- a/src/net/network.h
+++ b/src/net/network.h
@@ -36,8 +36,6 @@ class MessageHandler;
class MessageIn;
class MessageOut;
-class Network;
-
class Network
{
public:
@@ -46,35 +44,53 @@ class Network
Network();
~Network();
- bool connect(const std::string &address, short port);
- void disconnect();
+ typedef enum {
+ ACCOUNT,
+ GAME,
+ CHAT
+ } Server;
+
+ bool
+ connect(Server server, const std::string &address, short port);
+
+ void
+ disconnect(Server server);
+
+ void
+ registerHandler(MessageHandler *handler);
+
+ void
+ unregisterHandler(MessageHandler *handler);
- void registerHandler(MessageHandler *handler);
- void unregisterHandler(MessageHandler *handler);
- void clearHandlers();
+ void
+ clearHandlers();
- int getState() const { return mState; }
- bool isConnected() const { return mState == CONNECTED; }
+ int
+ getState() const { return mState; }
- void dispatchMessage(ENetPacket *packet);
- void flush();
+ bool
+ isConnected(Server server) const;
- void send(const MessageOut &msg);
+ void
+ dispatchMessage(ENetPacket *packet);
+
+ void
+ flush();
+
+ void
+ send(Server server, const MessageOut &msg);
enum State {
- IDLE,
- CONNECTED,
- CONNECTING,
- DATA,
+ NET_OK,
NET_ERROR
};
private:
ENetHost *mClient;
- ENetPeer *mServer;
- std::string mAddress;
- short mPort;
+ ENetPeer *mAccountServer;
+ ENetPeer *mGameServer;
+ ENetPeer *mChatServer;
unsigned int mToSkip;
@@ -83,11 +99,6 @@ class Network
typedef std::map<unsigned short, MessageHandler*> MessageHandlers;
typedef MessageHandlers::iterator MessageHandlerIterator;
MessageHandlers mMessageHandlers;
-
- std::queue<ENetPacket *> mOutgoingPackets;
-
- bool realConnect();
- void receive();
};
/** Convert an address from int format to string */