diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | src/gui/char_select.cpp | 8 | ||||
-rw-r--r-- | src/gui/connection.cpp | 4 | ||||
-rw-r--r-- | src/gui/gui.cpp | 2 | ||||
-rw-r--r-- | src/gui/login.cpp | 7 | ||||
-rw-r--r-- | src/gui/register.cpp | 4 | ||||
-rw-r--r-- | src/gui/updatewindow.cpp | 6 | ||||
-rw-r--r-- | src/main.cpp | 189 | ||||
-rw-r--r-- | src/main.h | 30 | ||||
-rw-r--r-- | src/net/charserverhandler.cpp | 22 | ||||
-rw-r--r-- | src/net/loginhandler.cpp | 8 | ||||
-rw-r--r-- | src/net/maploginhandler.cpp | 4 | ||||
-rw-r--r-- | src/net/messageout.cpp | 8 | ||||
-rw-r--r-- | src/net/messageout.h | 5 | ||||
-rw-r--r-- | src/net/network.cpp | 153 | ||||
-rw-r--r-- | src/net/network.h | 59 |
16 files changed, 323 insertions, 205 deletions
@@ -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; } } @@ -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 */ |