diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/accountclient.cpp | 4 | ||||
-rw-r--r-- | src/accountclient.h | 23 | ||||
-rw-r--r-- | src/accounthandler.cpp | 13 | ||||
-rw-r--r-- | src/chathandler.cpp | 12 | ||||
-rw-r--r-- | src/client.cpp | 2 | ||||
-rw-r--r-- | src/defines.h | 1 | ||||
-rw-r--r-- | src/gameclient.cpp | 4 | ||||
-rw-r--r-- | src/gameclient.h | 2 | ||||
-rw-r--r-- | src/gamehandler.cpp | 4 | ||||
-rw-r--r-- | src/messageout.cpp | 38 | ||||
-rw-r--r-- | src/messageout.h | 30 | ||||
-rw-r--r-- | src/netcomputer.cpp | 66 | ||||
-rw-r--r-- | src/netcomputer.h | 47 | ||||
-rw-r--r-- | src/state.cpp | 2 |
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); } |