Began segmenting the server's code

I've created a separate branch for this because it's gonna be a bitch to
get compiled, and then I'll still have to ensure that the client & server
are work together correctly.

This build does not compile.
This commit is contained in:
Kayne Ruse
2014-04-26 02:05:22 +10:00
parent d55dfb90e4
commit 9c673928e6
8 changed files with 238 additions and 166 deletions
+1 -1
View File
@@ -21,4 +21,4 @@
*/
#include "client_entry.hpp"
unsigned int ClientEntry::uidCounter;
int ClientEntry::uidCounter = 0;
+1 -1
View File
@@ -26,7 +26,7 @@
struct ClientEntry {
IPaddress address;
static unsigned int uidCounter;
static int uidCounter;
};
#endif
@@ -21,167 +21,19 @@
*/
#include "server_application.hpp"
#include "utility.hpp"
#include <stdexcept>
#include <iostream>
#include <string>
//-------------------------
//Define the public members
//-------------------------
void ServerApplication::Init(int argc, char** argv) {
//NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed.
std::cout << "Beginning startup" << std::endl;
//initial setup
ClientEntry::uidCounter = 0;
PlayerEntry::uidCounter = 0;
config.Load("rsc\\config.cfg");
//Init SDL
if (SDL_Init(0)) {
throw(std::runtime_error("Failed to initialize SDL"));
}
std::cout << "Initialized SDL" << std::endl;
//Init SDL_net
if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net"));
}
network.Open(config.Int("server.port"), PACKET_BUFFER_SIZE);
std::cout << "Initialized SDL_net" << std::endl;
//Init SQL
int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr);
if (ret != SQLITE_OK || !database) {
throw(std::runtime_error(std::string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) ));
}
std::cout << "Initialized SQL" << std::endl;
//setup the database
if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) {
throw(std::runtime_error("Failed to initialize SQL's setup script"));
}
std::cout << "Initialized SQL's setup script" << std::endl;
//lua
luaState = luaL_newstate();
if (!luaState) {
throw(std::runtime_error("Failed to initialize lua"));
}
luaL_openlibs(luaState);
std::cout << "Initialized lua" << std::endl;
//run the startup script
if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) {
throw(std::runtime_error(std::string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) ));
}
std::cout << "Initialized lua's setup script" << std::endl;
//setup the map object
regionPager.GetAllocator()->SetLuaState(luaState);
regionPager.GetFormat()->SetLuaState(luaState);
//TODO: config parameter
regionPager.GetFormat()->SetSaveDir("save/mapname/");
std::cout << "Initialized the map system" << std::endl;
std::cout << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl;
std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl;
//finalize the startup
std::cout << "Startup completed successfully" << std::endl;
//debugging
//
}
void ServerApplication::Proc() {
SerialPacket packet;
while(running) {
//suck in the waiting packets & process them
while(network.Receive()) {
//get the packet
deserialize(&packet, network.GetInData());
//cache the source address
packet.meta.srcAddress = network.GetInPacket()->address;
//we need to go deeper
HandlePacket(packet);
}
//give the computer a break
SDL_Delay(10);
}
}
void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl;
//empty the members
regionPager.UnloadAll();
//APIs
lua_close(luaState);
sqlite3_close_v2(database);
network.Close();
SDLNet_Quit();
SDL_Quit();
std::cout << "Shutdown finished" << std::endl;
}
//-------------------------
//Define the uber switch
//-------------------------
void ServerApplication::HandlePacket(SerialPacket packet) {
switch(packet.meta.type) {
case SerialPacket::Type::BROADCAST_REQUEST:
HandleBroadcastRequest(packet);
break;
case SerialPacket::Type::JOIN_REQUEST:
HandleJoinRequest(packet);
break;
case SerialPacket::Type::DISCONNECT:
HandleDisconnect(packet);
break;
case SerialPacket::Type::SYNCHRONIZE:
HandleSynchronize(packet);
break;
case SerialPacket::Type::SHUTDOWN:
HandleShutdown(packet);
break;
case SerialPacket::Type::PLAYER_NEW:
HandlePlayerNew(packet);
break;
case SerialPacket::Type::PLAYER_DELETE:
HandlePlayerDelete(packet);
break;
case SerialPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet);
break;
case SerialPacket::Type::REGION_REQUEST:
HandleRegionRequest(packet);
break;
//handle errors
default:
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
break;
}
}
//-------------------------
//Handle various network input
//-------------------------
void ServerApplication::HandleBroadcastRequest(SerialPacket packet) {
//send back the server's metadata
packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE;
//pack the data
packet.meta.type = SerialPacket::Type::BROADCAST_RESPONSE;
packet.serverInfo.networkVersion = NETWORK_VERSION;
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
packet.serverInfo.playerCount = playerMap.size();
packet.serverInfo.regionWidth = REGION_WIDTH;
packet.serverInfo.regionHeight = REGION_HEIGHT;
packet.serverInfo.regionDepth = REGION_DEPTH;
//send the data
char buffer[PACKET_BUFFER_SIZE];
@@ -195,13 +47,16 @@ void ServerApplication::HandleJoinRequest(SerialPacket packet) {
newClient.address = packet.meta.srcAddress;
clientMap[ClientEntry::uidCounter] = newClient;
//send the client their index
char buffer[PACKET_BUFFER_SIZE];
//create the new player
//TODO: make the player
//send the client their info
packet.meta.type = SerialPacket::Type::JOIN_RESPONSE;
packet.clientInfo.index = ClientEntry::uidCounter;
serialize(&packet, buffer);
//bounce this packet
char buffer[PACKET_BUFFER_SIZE];
serialize(&packet, buffer);
network.Send(&newClient.address, buffer, PACKET_BUFFER_SIZE);
//finished this routine
@@ -224,7 +79,7 @@ void ServerApplication::HandleDisconnect(SerialPacket packet) {
//TODO: can this use DeletePlayer() instead?
//delete server and client side players
erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
erase_if(playerMap, [&](std::pair<int, PlayerEntry> it) -> bool {
//find the internal players to delete
if (it.second.clientIndex == packet.clientInfo.index) {
//send the delete player command to all clients
@@ -323,7 +178,7 @@ void ServerApplication::HandlePlayerDelete(SerialPacket packet) {
delPacket.meta.type = SerialPacket::Type::PLAYER_DELETE;
//delete the specified playerEntry
erase_if(playerMap, [&](std::pair<unsigned int, PlayerEntry> it) -> bool {
erase_if(playerMap, [&](std::pair<int, PlayerEntry> it) -> bool {
//find the specified PlayerEntry
if (it.first == packet.playerInfo.playerIndex) {
//send to all
+1 -1
View File
@@ -21,4 +21,4 @@
*/
#include "player_entry.hpp"
unsigned int PlayerEntry::uidCounter;
int PlayerEntry::uidCounter = 0;
+2 -1
View File
@@ -31,6 +31,7 @@
struct PlayerEntry {
//metadata
int clientIndex;
std::string player;
std::string handle;
std::string avatar;
@@ -56,7 +57,7 @@ struct PlayerEntry {
float luck;
//uid
static unsigned int uidCounter;
static int uidCounter;
};
#endif
+46
View File
@@ -0,0 +1,46 @@
/* Copyright: (c) Kayne Ruse 2013, 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "server_application.hpp"
//-------------------------
//player management
//-------------------------
void ServerApplication::LoadPlayer() {
//
}
void ServerApplication::UnloadPlayer() {
//
}
void ServerApplication::CreatePlayer() {
//
}
void ServerApplication::DeletePlayer() {
//
}
void ServerApplication::SavePlayer() {
//
}
+11 -7
View File
@@ -23,7 +23,6 @@
#define SERVERAPPLICATION_HPP_
//server specific stuff
#include "server_utility.hpp"
#include "client_entry.hpp"
#include "player_entry.hpp"
@@ -63,28 +62,33 @@ public:
private:
void HandlePacket(SerialPacket);
//high cohesion utility functions
//handle incoming traffic
void HandleBroadcastRequest(SerialPacket);
void HandleJoinRequest(SerialPacket);
void HandleDisconnect(SerialPacket);
void HandleSynchronize(SerialPacket);
void HandleDisconnect(SerialPacket);
void HandleShutdown(SerialPacket);
void HandlePlayerNew(SerialPacket);
void HandlePlayerDelete(SerialPacket);
void HandlePlayerUpdate(SerialPacket);
void HandleRegionRequest(SerialPacket);
//TODO: a function that only sends to players in a certain proximity
void PumpPacket(SerialPacket);
//player management
void LoadPlayer();
void UnloadPlayer();
void CreatePlayer();
void DeletePlayer();
void SavePlayer();
//APIs
UDPNetworkUtility network;
sqlite3* database = nullptr;
lua_State* luaState = nullptr;
//server tables
std::map<unsigned int, ClientEntry> clientMap;
std::map<unsigned int, PlayerEntry> playerMap;
std::map<int, ClientEntry> clientMap;
std::map<int, PlayerEntry> playerMap;
//maps
//TODO: I need to handle multiple map objects
+166
View File
@@ -0,0 +1,166 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "server_application.hpp"
#include "server_utility.hpp"
#include <stdexcept>
#include <iostream>
#include <string>
//-------------------------
//Define the public members
//-------------------------
void ServerApplication::Init(int argc, char** argv) {
//NOTE: I might need to rearrange the init process so that lua & SQL can interact with the map system as needed.
std::cout << "Beginning startup" << std::endl;
//initial setup
config.Load("rsc\\config.cfg");
//Init SDL
if (SDL_Init(0)) {
throw(std::runtime_error("Failed to initialize SDL"));
}
std::cout << "Initialized SDL" << std::endl;
//Init SDL_net
if (SDLNet_Init()) {
throw(std::runtime_error("Failed to initialize SDL_net"));
}
network.Open(config.Int("server.port"), PACKET_BUFFER_SIZE);
std::cout << "Initialized SDL_net" << std::endl;
//Init SQL
int ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr);
if (ret != SQLITE_OK || !database) {
throw(std::runtime_error(std::string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) ));
}
std::cout << "Initialized SQL" << std::endl;
//setup the database
if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) {
throw(std::runtime_error("Failed to initialize SQL's setup script"));
}
std::cout << "Initialized SQL's setup script" << std::endl;
//lua
luaState = luaL_newstate();
if (!luaState) {
throw(std::runtime_error("Failed to initialize lua"));
}
luaL_openlibs(luaState);
std::cout << "Initialized lua" << std::endl;
//run the startup script
if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) {
throw(std::runtime_error(std::string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) ));
}
std::cout << "Initialized lua's setup script" << std::endl;
//setup the map object
regionPager.GetAllocator()->SetLuaState(luaState);
regionPager.GetFormat()->SetLuaState(luaState);
//TODO: config parameter
regionPager.GetFormat()->SetSaveDir("save/mapname/");
std::cout << "Initialized the map system" << std::endl;
std::cout << "\tsizeof(SerialPacket): " << sizeof(SerialPacket) << std::endl;
std::cout << "\tPACKET_BUFFER_SIZE: " << PACKET_BUFFER_SIZE << std::endl;
//finalize the startup
std::cout << "Startup completed successfully" << std::endl;
//debugging
//
}
void ServerApplication::Proc() {
SerialPacket packet;
while(running) {
//suck in the waiting packets & process them
while(network.Receive()) {
//get the packet
deserialize(&packet, network.GetInData());
//cache the source address
packet.meta.srcAddress = network.GetInPacket()->address;
//we need to go deeper
HandlePacket(packet);
}
//give the computer a break
SDL_Delay(10);
}
}
void ServerApplication::Quit() {
std::cout << "Shutting down" << std::endl;
//save the server state
//TODO: save the existing players
//empty the members
regionPager.UnloadAll();
//APIs
lua_close(luaState);
sqlite3_close_v2(database);
network.Close();
SDLNet_Quit();
SDL_Quit();
std::cout << "Shutdown finished" << std::endl;
}
//-------------------------
//Define the uber switch
//-------------------------
void ServerApplication::HandlePacket(SerialPacket packet) {
switch(packet.meta.type) {
case SerialPacket::Type::BROADCAST_REQUEST:
HandleBroadcastRequest(packet);
break;
case SerialPacket::Type::JOIN_REQUEST:
HandleJoinRequest(packet);
break;
case SerialPacket::Type::SYNCHRONIZE:
HandleSynchronize(packet);
break;
case SerialPacket::Type::DISCONNECT:
HandleDisconnect(packet);
break;
case SerialPacket::Type::SHUTDOWN:
HandleShutdown(packet);
break;
case SerialPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet);
break;
case SerialPacket::Type::REGION_REQUEST:
HandleRegionRequest(packet);
break;
//handle errors
default:
throw(std::runtime_error("Unknown SerialPacket::Type encountered"));
break;
}
}