diff options
-rw-r--r-- | src/connectionhandler.cpp | 84 | ||||
-rw-r--r-- | src/dalstorage.cpp | 5 | ||||
-rw-r--r-- | src/defines.h | 30 | ||||
-rw-r--r-- | src/main.cpp | 9 |
4 files changed, 125 insertions, 3 deletions
diff --git a/src/connectionhandler.cpp b/src/connectionhandler.cpp index e8c9a592..98d4a748 100644 --- a/src/connectionhandler.cpp +++ b/src/connectionhandler.cpp @@ -21,6 +21,10 @@ */ +#include <iostream> +#include <vector> +#include <sstream> + #include "connectionhandler.h" #include "netsession.h" #include "utils/logger.h" @@ -31,6 +35,54 @@ #define MAX_CLIENTS 1024 +/** + * TEMPORARY + * Split a string into a std::vector delimiting elements by 'split'. This + * function could be used for ASCII message handling (as we do not have + * a working client yet, using ASCII allows tools like Netcat to be used + * to test server functionality). + * + * This function may seem unoptimized, except it is this way to allow for + * thread safety. + */ +std::vector<std::string> stringSplit(const std::string &str, + const std::string &split) +{ + std::vector<std::string> result; // temporary result + unsigned int i; + unsigned int last = 0; + + // iterate through string + for (i = 0; i < str.length(); i++) { + if (str.compare(i, split.length(), split.c_str(), split.length()) == 0) { + result.push_back(str.substr(last, i - last)); + last = i + 1; + } + } + + // add remainder of string + if (last < str.length()) { + result.push_back(str.substr(last, str.length())); + } + + return result; +} + +/** + * Convert a IP4 address into its string representation + */ +std::string ip4ToString(unsigned int ip4addr) +{ + std::stringstream ss; + ss << (ip4addr & 0x000000ff) << "." + << ((ip4addr & 0x0000ff00) >> 8) << "." + << ((ip4addr & 0x00ff0000) >> 16) << "." + << ((ip4addr & 0xff000000) >> 24); + return ss.str(); +} + +//////////////// + ClientData::ClientData(): inp(0) { @@ -106,9 +158,41 @@ void ConnectionHandler::startListen(ListenThreadData *ltd) // client buffer[result] = 0; LOG_INFO("Received " << buffer); + #ifdef SCRIPT_SUPPORT + // this could be good if you wanted to extend the + // server protocol using a scripting language. This + // could be attained by using allowing scripts to + // "hook" certain messages. + //script->message(buffer); #endif + + // if the scripting subsystem didn't hook the message + // it will be handled by the default message handler. + + // convert the client IP address to string representation + std::string ipaddr = ip4ToString(SDLNet_TCP_GetPeerAddress(s)->host); + + // generate packet + Packet *packet = new Packet(buffer, strlen(buffer)); + MessageIn msg(packet); // (MessageIn frees packet) + + // make sure that the packet is big enough + if (strlen(buffer) >= 4) { + unsigned int messageType = (unsigned int)*packet->data; + if (handlers.find(messageType) != handlers.end()) { + // send message to appropriate handler + handlers[messageType]->receiveMessage(*comp, msg); + } else { + // bad message (no registered handler) + LOG_ERROR("Unhandled message received from " + << ipaddr); + } + } else { + LOG_ERROR("Message too short from " << ipaddr); + } + // } } diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp index c1b517ec..51619007 100644 --- a/src/dalstorage.cpp +++ b/src/dalstorage.cpp @@ -370,7 +370,10 @@ DALStorage::createTable(const std::string& tblName, alreadyExists += tblName; alreadyExists += "' already exists"; #elif defined (POSTGRESQL_SUPPORT) - // TODO + std::string alreadyExists("table "); + alreadyExists += tblName; + alreadyExists += " already exists"; + #else // SQLITE_SUPPORT std::string alreadyExists("table "); alreadyExists += tblName; diff --git a/src/defines.h b/src/defines.h index 2f84c806..bc5dc9b4 100644 --- a/src/defines.h +++ b/src/defines.h @@ -54,5 +54,35 @@ typedef enum { GENDER_UNKNOWN } Genders; +/** + * Enumerated type for received server messages + */ +enum { + MSG_LOGIN = 0, + MSG_MOVE, + MSG_ATTACK, + MSG_PICKUP, + MSG_DROP, + MSG_TRADE, + MSG_CHAT +}; + +// NOTE: Maybe it would be better to reuse some enumerated types with both +// server and client? + +/** + * Enumerated type for messages sent to client + */ +enum { + CMSG_SPAWN = 0, // spawn object + CMSG_DESTROY, // destroy object + CMSG_MOVE, // move object + CMSG_ATTACK, // Player attacked/got attacked by object + CMSG_PICKUP, // Player picked up object + CMSG_DROP, // Player dropped object + CMSG_CHAT, // Another player chatted + CMSG_DIALOG // Message dialog +}; + #endif // _TMWSERV_DEFINES_H_ diff --git a/src/main.cpp b/src/main.cpp index 4b6ec0d8..b26be9ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -73,6 +73,7 @@ bool running = true; /**< Determines if server keeps running */ Skill skillTree("base"); /**< Skill tree */ Configuration config; /**< XML config reader */ +AccountHandler *accountHandler = new AccountHandler(); /**< Account message handler */ /** * SDL timer callback, sends a <code>TMW_WORLD_TICK</code> event. @@ -161,6 +162,9 @@ void deinitialize() delete script; #endif + // destro account handler + delete accountHandler; + // Get rid of persistent data storage tmwserv::Storage::destroy(); } @@ -193,8 +197,9 @@ int main(int argc, char *argv[]) // to the constructor of the account handler, upon which is would register // itself for the messages it handles. // - //AccountHandler *accountHandler = new AccountHandler(); - //connectionHandler->registerHandler(C2S_LOGIN, accountHandler); + + // Register message handlers + connectionHandler->registerHandler(MSG_LOGIN, accountHandler); LOG_INFO("The Mana World Server v" << PACKAGE_VERSION) session->startListen(connectionHandler.get(), SERVER_PORT); |