summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/accountclient.cpp4
-rw-r--r--src/accountclient.h23
-rw-r--r--src/accounthandler.cpp13
-rw-r--r--src/chathandler.cpp12
-rw-r--r--src/client.cpp2
-rw-r--r--src/defines.h1
-rw-r--r--src/gameclient.cpp4
-rw-r--r--src/gameclient.h2
-rw-r--r--src/gamehandler.cpp4
-rw-r--r--src/messageout.cpp38
-rw-r--r--src/messageout.h30
-rw-r--r--src/netcomputer.cpp66
-rw-r--r--src/netcomputer.h47
-rw-r--r--src/state.cpp2
14 files changed, 155 insertions, 93 deletions
diff --git a/src/accountclient.cpp b/src/accountclient.cpp
index d93f3b3a..5cdbba29 100644
--- a/src/accountclient.cpp
+++ b/src/accountclient.cpp
@@ -26,8 +26,8 @@
#include "account.h"
#include "accounthandler.h"
-AccountClient::AccountClient(AccountHandler *handler, ENetPeer *peer):
- NetComputer(handler, peer),
+AccountClient::AccountClient(ENetPeer *peer):
+ NetComputer(peer),
mAccountPtr(NULL),
mCharacterPtr(NULL)
{
diff --git a/src/accountclient.h b/src/accountclient.h
index 5c36f020..c3ab8a44 100644
--- a/src/accountclient.h
+++ b/src/accountclient.h
@@ -25,6 +25,7 @@
#define _TMWSERV_ACCOUNTCLIENT_H_
#include "netcomputer.h"
+#include "account.h"
#include <enet/enet.h>
@@ -34,13 +35,13 @@ class AccountHandler;
* A connected computer that can have an account and character associated with
* it.
*/
-class AccountClient: public NetComputer
+class AccountClient : public NetComputer
{
public:
/**
* Constructor.
*/
- AccountClient(AccountHandler *accountHandler, ENetPeer *peer);
+ AccountClient(ENetPeer *peer);
/**
* Destructor.
@@ -50,32 +51,38 @@ class AccountClient: public NetComputer
/**
* Set the account associated with the connection
*/
- void setAccount(AccountPtr acc);
+ void
+ setAccount(AccountPtr acc);
/**
* Unset the account associated with the connection
*/
- void unsetAccount();
+ void
+ unsetAccount();
/**
* Get account associated with the connection.
*/
- AccountPtr getAccount() { return mAccountPtr; }
+ AccountPtr
+ getAccount() const { return mAccountPtr; }
/**
* Set the selected character associated with connection.
*/
- void setCharacter(PlayerPtr ch);
+ void
+ setCharacter(PlayerPtr ch);
/**
* Deselect the character associated with connection.
*/
- void unsetCharacter();
+ void
+ unsetCharacter();
/**
* Get character associated with the connection
*/
- PlayerPtr getCharacter() { return mCharacterPtr; }
+ PlayerPtr
+ getCharacter() const { return mCharacterPtr; }
private:
/** Account associated with connection */
diff --git a/src/accounthandler.cpp b/src/accounthandler.cpp
index 62f26b6b..ec534d9d 100644
--- a/src/accounthandler.cpp
+++ b/src/accounthandler.cpp
@@ -39,12 +39,14 @@
#include "utils/stringfilter.h"
-NetComputer *AccountHandler::computerConnected(ENetPeer *peer)
+NetComputer*
+AccountHandler::computerConnected(ENetPeer *peer)
{
- return new AccountClient(this, peer);
+ return new AccountClient(peer);
}
-void AccountHandler::computerDisconnected(NetComputer *comp)
+void
+AccountHandler::computerDisconnected(NetComputer *comp)
{
delete comp;
}
@@ -54,7 +56,8 @@ void AccountHandler::computerDisconnected(NetComputer *comp)
* correct subroutines. Account handler takes care of determining the
* current step in the account process, be it creation, setup, or login.
*/
-void AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
+void
+AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
{
AccountClient &computer = *static_cast< AccountClient * >(comp);
@@ -253,7 +256,7 @@ void AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
}
// return result
- if (result.getDataSize() > 0)
+ if (result.getLength() > 0)
computer.send(result);
}
diff --git a/src/chathandler.cpp b/src/chathandler.cpp
index e97d23e6..93aaa7d3 100644
--- a/src/chathandler.cpp
+++ b/src/chathandler.cpp
@@ -39,14 +39,14 @@ class ChatClient: public NetComputer
/**
* Constructor.
*/
- ChatClient(ChatHandler *, ENetPeer *);
+ ChatClient(ENetPeer *peer);
std::string characterName;
AccountLevel accountLevel;
};
-ChatClient::ChatClient(ChatHandler *handler, ENetPeer *peer):
- NetComputer(handler, peer),
+ChatClient::ChatClient(ENetPeer *peer):
+ NetComputer(peer),
accountLevel(AL_NORMAL)
{
}
@@ -101,7 +101,7 @@ void ChatHandler::removeOutdatedPending()
NetComputer *ChatHandler::computerConnected(ENetPeer *peer)
{
- return new ChatClient(this, peer);
+ return new ChatClient(peer);
}
void ChatHandler::computerDisconnected(NetComputer *computer)
@@ -363,7 +363,7 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
// The user entered the channel, now give him the announcement string
// and the user list.
result.writeString(chatChannelManager->getChannelAnnouncement(channelId));
- std::vector< std::string > const &userList =
+ std::vector< std::string > const &userList =
chatChannelManager->getUserListInChannel(channelId);
result.writeShort(userList.size());
for (std::vector< std::string >::const_iterator i = userList.begin(), i_end = userList.end();
@@ -419,7 +419,7 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
break;
}
- if (result.getDataSize() > 0)
+ if (result.getLength() > 0)
computer.send(result);
}
diff --git a/src/client.cpp b/src/client.cpp
index d513e146..d68a11ff 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -333,7 +333,7 @@ int main(int argc, char *argv[])
// Send prepared message
if (!exit && connected) {
ENetPacket *packet = enet_packet_create(
- msg.getData(), msg.getDataSize(),
+ msg.getData(), msg.getLength(),
ENET_PACKET_FLAG_RELIABLE);
ENetPeer *peer = peerAccount;
if (msgDestination == 1) peer = peerGame;
diff --git a/src/defines.h b/src/defines.h
index bd50207c..56ef210f 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -55,6 +55,7 @@ typedef enum {
// Network related
const unsigned int MAX_CLIENTS = 1024,
+
// Chat related
/**
* N.B: Private channels can't have an id less
diff --git a/src/gameclient.cpp b/src/gameclient.cpp
index 88deacad..562d85f4 100644
--- a/src/gameclient.cpp
+++ b/src/gameclient.cpp
@@ -28,8 +28,8 @@
#include "state.h"
#include "gamehandler.h"
-GameClient::GameClient(GameHandler *handler, ENetPeer *peer):
- NetComputer(handler, peer),
+GameClient::GameClient(ENetPeer *peer):
+ NetComputer(peer),
mCharacterPtr(NULL)
{
}
diff --git a/src/gameclient.h b/src/gameclient.h
index 756b224d..67994b4e 100644
--- a/src/gameclient.h
+++ b/src/gameclient.h
@@ -41,7 +41,7 @@ class GameClient: public NetComputer
/**
* Constructor.
*/
- GameClient(GameHandler *handler, ENetPeer *peer);
+ GameClient(ENetPeer *peer);
/**
* Destructor.
diff --git a/src/gamehandler.cpp b/src/gamehandler.cpp
index a133e5fa..20c073ce 100644
--- a/src/gamehandler.cpp
+++ b/src/gamehandler.cpp
@@ -105,7 +105,7 @@ void GameHandler::removeOutdatedPending()
NetComputer *GameHandler::computerConnected(ENetPeer *peer)
{
- return new GameClient(this, peer);
+ return new GameClient(peer);
}
void GameHandler::computerDisconnected(NetComputer *computer)
@@ -218,7 +218,7 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
break;
}
- if (result.getDataSize() > 0)
+ if (result.getLength() > 0)
computer.send(result);
}
diff --git a/src/messageout.cpp b/src/messageout.cpp
index d9578577..71e81542 100644
--- a/src/messageout.cpp
+++ b/src/messageout.cpp
@@ -24,36 +24,51 @@
#include "messageout.h"
#include <string>
+#include <stdlib.h>
+#include <iosfwd>
#include <enet/enet.h>
+/** Initial amount of bytes allocated for the messageout data buffer. */
+const unsigned int INITIAL_DATA_CAPACITY = 2;
+
+/** Factor by which the messageout data buffer is increased when too small. */
+const unsigned int CAPACITY_GROW_FACTOR = 2;
+
MessageOut::MessageOut():
- mData(0),
- mDataSize(0),
mPos(0)
{
+ mData = (char*) malloc(INITIAL_DATA_CAPACITY);
+ mDataSize = INITIAL_DATA_CAPACITY;
}
MessageOut::MessageOut(short id):
- mData(0),
- mDataSize(0),
mPos(0)
{
+ mData = (char*) malloc(INITIAL_DATA_CAPACITY);
+ mDataSize = INITIAL_DATA_CAPACITY;
+
writeShort(id);
}
MessageOut::~MessageOut()
{
- if (mData) {
- free(mData);
- }
+ free(mData);
}
void
MessageOut::expand(size_t bytes)
{
- mData = (char*)realloc(mData, bytes);
- mDataSize = bytes;
+ if (bytes > mDataSize)
+ {
+ do
+ {
+ mDataSize *= CAPACITY_GROW_FACTOR;
+ }
+ while (bytes > mDataSize);
+
+ mData = (char*) realloc(mData, mDataSize);
+ }
}
void
@@ -64,7 +79,8 @@ MessageOut::writeByte(char value)
mPos += 1;
}
-void MessageOut::writeShort(short value)
+void
+MessageOut::writeShort(short value)
{
expand(mPos + 2);
uint16_t t = ENET_HOST_TO_NET_16(value);
@@ -101,9 +117,9 @@ MessageOut::writeString(const std::string &string, int length)
// Write the actual string
memcpy(mData + mPos, string.c_str(), stringLength);
- // Pad remaining space with zeros
if (length > stringLength)
{
+ // Pad remaining space with zeros
memset(mData + mPos + stringLength, '\0', length - stringLength);
}
mPos += length;
diff --git a/src/messageout.h b/src/messageout.h
index dac20f71..19997a0b 100644
--- a/src/messageout.h
+++ b/src/messageout.h
@@ -47,15 +47,21 @@ class MessageOut
*/
~MessageOut();
- void writeByte(char value); /**< Writes a byte. */
- void writeShort(short value); /**< Writes a short. */
- void writeLong(long value); /**< Writes a long. */
+ void
+ writeByte(char value); /**< Writes a byte. */
+
+ void
+ writeShort(short value); /**< Writes a short. */
+
+ void
+ writeLong(long value); /**< Writes a long. */
/**
* Writes a string. If a fixed length is not given (-1), it is stored
* as a short at the start of the string.
*/
- void writeString(const std::string &string, int length = -1);
+ void
+ writeString(const std::string &string, int length = -1);
/**
* Returns the content of the message.
@@ -67,21 +73,19 @@ class MessageOut
* Returns the length of the data.
*/
unsigned int
- getDataSize() const { return mDataSize; }
+ getLength() const { return mPos; }
private:
/**
- * Expand the packet data to be able to hold more data.
- *
- * NOTE: For performance enhancements this method could allocate extra
- * memory in advance instead of expanding size every time more data is
- * added.
+ * Ensures the capacity of the data buffer is large enough to hold the
+ * given amount of bytes.
*/
- void expand(size_t size);
+ void
+ expand(size_t size);
char *mData; /**< Data building up. */
- unsigned int mDataSize; /**< Size of data. */
unsigned int mPos; /**< Position in the data. */
+ unsigned int mDataSize; /**< Allocated datasize. */
};
-#endif
+#endif //_TMWSERV_MESSAGEOUT_H_
diff --git a/src/netcomputer.cpp b/src/netcomputer.cpp
index 1c3c50b6..fd9bec5e 100644
--- a/src/netcomputer.cpp
+++ b/src/netcomputer.cpp
@@ -23,39 +23,65 @@
#include "netcomputer.h"
-#include "chatchannelmanager.h"
-#include "connectionhandler.h"
+#include <iosfwd>
+#include <queue>
+#include <iostream>
+
+#include <enet/enet.h>
+
+#include "defines.h"
#include "messageout.h"
-#include "state.h"
+#include "connectionhandler.h"
#include "utils/logger.h"
-NetComputer::NetComputer(ConnectionHandler *handler, ENetPeer *peer):
- mHandler(handler),
+NetComputer::NetComputer(ENetPeer *peer):
mPeer(peer)
{
}
-void NetComputer::disconnect(const std::string &reason)
+bool
+NetComputer::isConnected()
+{
+ return (mPeer->state == ENET_PEER_STATE_CONNECTED);
+}
+
+void
+NetComputer::disconnect(const MessageOut &msg)
{
- // TODO: Send a disconnect message containing the reason, and somehow only
- // TODO: really disconnect the client after waiting for the client to get
- // TODO: the message (or likely got it).
+ if (isConnected())
+ {
+ /* ChannelID 0xFF is the channel used by enet_peer_disconnect.
+ * If a reliable packet is send over this channel ENet guaranties
+ * that the message is recieved before the disconnect request.
+ */
+ send(msg, ENET_PACKET_FLAG_RELIABLE, 0xFF);
- // ENet should generate a disconnect event (notifying the connection
- // handler)
- enet_peer_disconnect(mPeer, 0);
+ /* ENet generates a disconnect event
+ * (notifying the connection handler).
+ */
+ enet_peer_disconnect(mPeer, 0);
+ }
}
-void NetComputer::send(const MessageOut &msg)
+void
+NetComputer::send(const MessageOut &msg, bool reliable,
+ unsigned int channel)
{
- LOG_INFO("Sending packet of length " << msg.getDataSize() << " to "
- << ip4ToString(mPeer->address.host), 2);
+ LOG_INFO("Sending packet of length " << msg.getLength() << " to "
+ << ip4ToString(mPeer->address.host), 2);
- // Create a reliable packet.
- ENetPacket *packet = enet_packet_create(msg.getData(), msg.getDataSize(),
- ENET_PACKET_FLAG_RELIABLE);
+ ENetPacket *packet;
+ packet = enet_packet_create(msg.getData(),
+ msg.getLength(),
+ reliable ? ENET_PACKET_FLAG_RELIABLE : 0);
- // Send the packet to the peer over channel id 0.
- enet_peer_send(mPeer, 0, packet);
+ if (packet)
+ {
+ enet_peer_send(mPeer, channel, packet);
+ }
+ else
+ {
+ LOG_WARN("Failure to create packet!", 0);
+ }
}
diff --git a/src/netcomputer.h b/src/netcomputer.h
index 49dfdc93..842d362b 100644
--- a/src/netcomputer.h
+++ b/src/netcomputer.h
@@ -24,16 +24,8 @@
#ifndef _TMWSERV_NETCOMPUTER_H_
#define _TMWSERV_NETCOMPUTER_H_
-#include <iosfwd>
-#include <queue>
-
#include <enet/enet.h>
-#include "account.h"
-#include "being.h"
-
-// Forward declaration
-class ConnectionHandler;
class MessageOut;
/**
@@ -46,38 +38,51 @@ class NetComputer
/**
* Constructor.
*/
- NetComputer(ConnectionHandler *handler, ENetPeer *peer);
+ NetComputer(ENetPeer *peer);
/**
- * Destructor
+ * Destructor.
*/
virtual ~NetComputer() {}
/**
- * Returns <code>true</code> if this computer is disconnected.
+ * Returns <code>true</code> if this computer is connected.
*/
- //bool
- //isDisconnected();
+ bool
+ isConnected();
/**
- * Disconnects the computer from the server.
+ * Disconnects the computer from the server, after sending a message.
+ *
+ * The caller of this method should prepare the message, because
+ * NetComputer does not know which handler send it
+ * (could have been chat/game/account)
*/
void
- disconnect(const std::string &reason);
+ disconnect(const MessageOut &msg);
/**
* Queues a message for sending to a client.
*
- * TODO: Add support for reliable and maybe also channels now that we
- * TODO: have ENet.
+ * Reliable packets always arrive, if the client stays connected.
+ * Unreliable packets may not arrive, and may not even be send.
+ *
+ * Channels are used to ensure that unrelated reliable packets do not
+ * hold each other up. In essence, each channel represents a different
+ * queque.
+ *
+ * @param msg The message to be send.
+ * @param reliable Defines if a reliable or an unreliable packet
+ * should be send.
+ * @param channel The channel number of which the packet should
+ * be send.
*/
void
- send(const MessageOut &msg);
- //void send(Packet *p, bool reliable = true);
+ send(const MessageOut &msg, bool reliable = true,
+ unsigned int channel = 0);
private:
- ConnectionHandler *mHandler; /**< Connection handler */
ENetPeer *mPeer; /**< Client peer */
};
-#endif
+#endif // _TMWSERV_NETCOMPUTER_H_
diff --git a/src/state.cpp b/src/state.cpp
index 0d3b8636..87e85015 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -96,7 +96,7 @@ State::update()
msg.writeShort(od.second);
}
- if (msg.getDataSize() > 2)
+ if (msg.getLength() > 2)
gameHandler->sendTo(*p, msg);
}