summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2006-08-20 00:56:23 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2006-08-20 00:56:23 +0000
commit01591924a4f33d5a5e4a86db6c256c8ce797a820 (patch)
treea1fe33f8a28a19fddd9f4ccdf7816f85636c4bcb /src/net
parent0841d65d15e4c318ad8f5fe4b7e257d963ef7841 (diff)
downloadMana-01591924a4f33d5a5e4a86db6c256c8ce797a820.tar.gz
Mana-01591924a4f33d5a5e4a86db6c256c8ce797a820.tar.bz2
Mana-01591924a4f33d5a5e4a86db6c256c8ce797a820.tar.xz
Mana-01591924a4f33d5a5e4a86db6c256c8ce797a820.zip
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.
Diffstat (limited to 'src/net')
-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
7 files changed, 169 insertions, 90 deletions
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 */