Merge branch 'server' (read more)

The only different between this commit and the currently stable branch is the
serialization code and a slight tweak to the server's startup sequence. I tried
to refactor the server, by moving the clientMap and playerMap into their own
wrapper classes, but that failed miserably. I need to stop getting so worked up
all the time, I've wasted way too much time already.
This commit is contained in:
Kayne Ruse
2014-03-11 19:00:32 +11:00
12 changed files with 383 additions and 154 deletions
+21 -8
View File
@@ -65,11 +65,14 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet
packet.playerInfo.motion = {0,0};
//send it
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
char buffer[sizeof(NetworkPacket)];
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket));
//request a sync
packet.meta.type = NetworkPacket::Type::SYNCHRONIZE;
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket));
}
InWorld::~InWorld() {
@@ -88,7 +91,7 @@ void InWorld::Update(double delta) {
//suck in all waiting packets
NetworkPacket packet;
while(network.Receive()) {
memcpy(&packet, network.GetInData(), sizeof(NetworkPacket));
deserialize(&packet, network.GetInData());
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
@@ -287,6 +290,9 @@ void InWorld::HandlePlayerUpdate(NetworkPacket packet) {
void InWorld::SendState() {
NetworkPacket packet;
char buffer[sizeof(NetworkPacket)];
//pack the packet
packet.meta.type = NetworkPacket::Type::PLAYER_UPDATE;
packet.playerInfo.clientIndex = clientIndex;
packet.playerInfo.playerIndex = playerIndex;
@@ -295,21 +301,28 @@ void InWorld::SendState() {
packet.playerInfo.position = localCharacter->GetPosition();
packet.playerInfo.motion = localCharacter->GetMotion();
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket));
}
void InWorld::RequestDisconnect() {
//send a disconnect request
NetworkPacket packet;
char buffer[sizeof(NetworkPacket)];
//send a disconnect request
packet.meta.type = NetworkPacket::Type::DISCONNECT;
packet.clientInfo.index = clientIndex;
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket));
}
void InWorld::RequestShutDown() {
//send a shutdown request
NetworkPacket packet;
char buffer[sizeof(NetworkPacket)];
//send a shutdown request
packet.meta.type = NetworkPacket::Type::SHUTDOWN;
packet.clientInfo.index = clientIndex;
network.Send(Channels::SERVER, &packet, sizeof(NetworkPacket));
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, sizeof(NetworkPacket));
}
+1
View File
@@ -27,6 +27,7 @@
#include "config_utility.hpp"
#include "udp_network_utility.hpp"
#include "network_packet.hpp"
#include "serial.hpp"
#include "image.hpp"
#include "raster_font.hpp"
#include "button.hpp"
+13 -5
View File
@@ -80,7 +80,7 @@ void LobbyMenu::Update(double delta) {
//suck in all waiting packets
NetworkPacket packet;
while(network.Receive()) {
memcpy(&packet, network.GetInData(), sizeof(NetworkPacket));
deserialize(&packet, network.GetInData());
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
@@ -125,10 +125,14 @@ void LobbyMenu::MouseButtonDown(SDL_MouseButtonEvent const& button) {
void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
if (search.MouseButtonUp(button) == Button::State::HOVER) {
//broadcast to the network, or a specific server
//the vars
NetworkPacket packet;
char buffer[sizeof(NetworkPacket)];
//broadcast to the network, or a specific server
packet.meta.type = NetworkPacket::Type::BROADCAST_REQUEST;
network.Send(config["server.host"].c_str(), config.Int("server.port"), reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
serialize(&packet, buffer);
network.Send(config["server.host"].c_str(), config.Int("server.port"), buffer, sizeof(NetworkPacket));
//reset the server list
serverInfo.clear();
@@ -136,10 +140,14 @@ void LobbyMenu::MouseButtonUp(SDL_MouseButtonEvent const& button) {
}
else if (join.MouseButtonUp(button) == Button::State::HOVER && selection != nullptr) {
//join the selected server
//the vars
NetworkPacket packet;
char buffer[sizeof(NetworkPacket)];
//join the selected server
packet.meta.type = NetworkPacket::Type::JOIN_REQUEST;
network.Send(&selection->address, &packet, sizeof(NetworkPacket));
serialize(&packet, buffer);
network.Send(&selection->address, buffer, sizeof(NetworkPacket));
selection = nullptr;
}
+1
View File
@@ -31,6 +31,7 @@
#include "config_utility.hpp"
#include "udp_network_utility.hpp"
#include "network_packet.hpp"
#include "serial.hpp"
#include <vector>
+3
View File
@@ -94,6 +94,9 @@ union NetworkPacket {
Vector2 motion;
}playerInfo;
//map data
//...
//defaults
NetworkPacket() {
meta.type = Type::NONE;
+207
View File
@@ -0,0 +1,207 @@
/* 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 "serial.hpp"
#include <cstring>
//#include <iostream>
//using namespace std;
//-------------------------
//internal serialization functions
//-------------------------
void serializeType(NetworkPacket* packet, char* buffer) {
// cout << "serializeType" << endl;
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
}
void serializeServer(NetworkPacket* packet, char* buffer) {
// cout << "serializeServer" << endl;
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(buffer, packet->serverInfo.name, PACKET_STRING_SIZE);
}
void serializeClient(NetworkPacket* packet, char* buffer) {
// cout << "serializeClient" << endl;
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(buffer, &packet->clientInfo.index, sizeof(int));
}
void serializePlayer(NetworkPacket* packet, char* buffer) {
// cout << "serializePlayer" << endl;
memcpy(buffer, &packet->meta.type, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
//indexes
memcpy(buffer, &packet->playerInfo.clientIndex, sizeof(int));
buffer += sizeof(int);
memcpy(buffer, &packet->playerInfo.playerIndex, sizeof(int));
buffer += sizeof(int);
//text
memcpy(buffer, packet->playerInfo.handle, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
memcpy(buffer, packet->playerInfo.avatar, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
//vectors
memcpy(buffer, &packet->playerInfo.position.x, sizeof(double));
buffer += sizeof(double);
memcpy(buffer, &packet->playerInfo.position.y, sizeof(double));
buffer += sizeof(double);
memcpy(buffer, &packet->playerInfo.motion.x, sizeof(double));
buffer += sizeof(double);
memcpy(buffer, &packet->playerInfo.motion.y, sizeof(double));
}
//-------------------------
//internal deserialization functions
//-------------------------
void deserializeType(NetworkPacket* packet, char* buffer) {
// cout << "deserializeType" << endl;
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
}
void deserializeServer(NetworkPacket* packet, char* buffer) {
// cout << "deserializeServer" << endl;
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(packet->serverInfo.name, buffer, PACKET_STRING_SIZE);
}
void deserializeClient(NetworkPacket* packet, char* buffer) {
// cout << "deserializeClient" << endl;
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
memcpy(&packet->clientInfo.index, buffer, sizeof(int));
}
void deserializePlayer(NetworkPacket* packet, char* buffer) {
// cout << "deserializePlayer" << endl;
memcpy(&packet->meta.type, buffer, sizeof(NetworkPacket::Type));
buffer += sizeof(NetworkPacket::Type);
//indexes
memcpy(&packet->playerInfo.clientIndex, buffer, sizeof(int));
buffer += sizeof(int);
memcpy(&packet->playerInfo.playerIndex, buffer, sizeof(int));
buffer += sizeof(int);
//text
memcpy(packet->playerInfo.handle, buffer, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
memcpy(packet->playerInfo.avatar, buffer, PACKET_STRING_SIZE);
buffer += PACKET_STRING_SIZE;
//vectors
memcpy(&packet->playerInfo.position.x, buffer, sizeof(double));
buffer += sizeof(double);
memcpy(&packet->playerInfo.position.y, buffer, sizeof(double));
buffer += sizeof(double);
memcpy(&packet->playerInfo.motion.x, buffer, sizeof(double));
buffer += sizeof(double);
memcpy(&packet->playerInfo.motion.y, buffer, sizeof(double));
}
//-------------------------
//the interface functions
//-------------------------
void serialize(NetworkPacket* packet, void* buffer) {
switch(packet->meta.type) {
//No extra data
case NetworkPacket::Type::NONE:
case NetworkPacket::Type::PING:
case NetworkPacket::Type::PONG:
case NetworkPacket::Type::BROADCAST_REQUEST:
case NetworkPacket::Type::JOIN_REQUEST:
case NetworkPacket::Type::SYNCHRONIZE:
serializeType(packet, reinterpret_cast<char*>(buffer));
break;
//Server info
case NetworkPacket::Type::BROADCAST_RESPONSE:
serializeServer(packet, reinterpret_cast<char*>(buffer));
break;
//Client info
case NetworkPacket::Type::JOIN_RESPONSE:
case NetworkPacket::Type::DISCONNECT:
case NetworkPacket::Type::SHUTDOWN:
serializeClient(packet, reinterpret_cast<char*>(buffer));
break;
//Player info
case NetworkPacket::Type::PLAYER_NEW:
case NetworkPacket::Type::PLAYER_DELETE:
case NetworkPacket::Type::PLAYER_UPDATE:
serializePlayer(packet, reinterpret_cast<char*>(buffer));
break;
}
// for (int i = 0; i < sizeof(NetworkPacket); i++) {
// cout << ((char*)(buffer))[i];
// }
// cout << endl;
}
void deserialize(NetworkPacket* packet, void* buffer) {
//find the type, so that you can actually deserialize the packet!
deserializeType(packet, reinterpret_cast<char*>(buffer));
switch(packet->meta.type) {
//No extra data
case NetworkPacket::Type::NONE:
case NetworkPacket::Type::PING:
case NetworkPacket::Type::PONG:
case NetworkPacket::Type::BROADCAST_REQUEST:
case NetworkPacket::Type::JOIN_REQUEST:
case NetworkPacket::Type::SYNCHRONIZE:
//
break;
//Server info
case NetworkPacket::Type::BROADCAST_RESPONSE:
deserializeServer(packet, reinterpret_cast<char*>(buffer));
break;
//Client info
case NetworkPacket::Type::JOIN_RESPONSE:
case NetworkPacket::Type::DISCONNECT:
case NetworkPacket::Type::SHUTDOWN:
deserializeClient(packet, reinterpret_cast<char*>(buffer));
break;
//Player info
case NetworkPacket::Type::PLAYER_NEW:
case NetworkPacket::Type::PLAYER_DELETE:
case NetworkPacket::Type::PLAYER_UPDATE:
deserializePlayer(packet, reinterpret_cast<char*>(buffer));
break;
}
// for (int i = 0; i < sizeof(NetworkPacket); i++) {
// cout << ((char*)(buffer))[i];
// }
// cout << endl;
}
@@ -1,4 +1,4 @@
/* Copyright: (c) Kayne Ruse 2013
/* 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
@@ -19,20 +19,12 @@
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef CLIENT_HPP_
#define CLIENT_HPP_
#ifndef SERIAL_HPP_
#define SERIAL_HPP_
#include "SDL/SDL_net.h"
#include "network_packet.hpp"
#include <map>
/* Hold the client info.
*/
struct Client {
IPaddress address;
};
typedef std::map<int, Client> ClientMap;
void serialize(NetworkPacket* const, void*);
void deserialize(NetworkPacket* const, void*);
#endif
View File
+1
View File
@@ -0,0 +1 @@
print("Lua script check OK")
-43
View File
@@ -1,43 +0,0 @@
/* Copyright: (c) Kayne Ruse 2013
*
* 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.
*/
#ifndef PLAYER_HPP_
#define PLAYER_HPP_
#include "vector2.hpp"
#include <string>
#include <map>
/* Hold the player info.
*/
struct Player {
int clientIndex;
std::string handle;
std::string avatar;
Vector2 position;
Vector2 motion;
};
typedef std::map<int, Player> PlayerMap;
#endif
+107 -75
View File
@@ -30,20 +30,28 @@
using namespace std;
//-------------------------
//Define the ServerApplication
//-------------------------
ServerApplication::ServerApplication() {
//
int runSQLScript(sqlite3* db, std::string fname) {
ifstream is(fname);
if (!is.is_open()) {
return -1;
}
string script;
getline(is, script, '\0');
is.close();
//TODO: flesh out this error if needed
if (sqlite3_exec(db, script.c_str(), nullptr, nullptr, nullptr) != SQLITE_OK) {
return -2;
}
return 0;
}
ServerApplication::~ServerApplication() {
//
}
//-------------------------
//Define the public members
//-------------------------
void ServerApplication::Init(int argc, char** argv) {
//TODO: proper command line option parsing
cout << "Beginning startup" << endl;
int ret = 0;
//load config
config.Load("rsc\\config.cfg");
@@ -52,101 +60,108 @@ void ServerApplication::Init(int argc, char** argv) {
if (SDL_Init(0)) {
throw(runtime_error("Failed to initialize SDL"));
}
cout << "initialized SDL" << endl;
cout << "Initialized SDL" << endl;
//Init SDL_net
if (SDLNet_Init()) {
throw(runtime_error("Failed to init SDL_net"));
throw(runtime_error("Failed to initialize SDL_net"));
}
network.Open(config.Int("server.port"), sizeof(NetworkPacket));
cout << "initialized SDL_net" << endl;
cout << "Initialized SDL_net" << endl;
//Init SQL
string dbname = (config["server.dbname"].size()) ? config["server.dbname"] : std::string(argv[0]) + ".db"; //fancy and unnecessary
int ret = sqlite3_open_v2(dbname.c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_FULLMUTEX, nullptr);
ret = sqlite3_open_v2(config["server.dbname"].c_str(), &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, nullptr);
if (ret != SQLITE_OK || !database) {
throw(runtime_error("Failed to open the server database"));
throw(runtime_error(string() + "Failed to initialize SQL: " + sqlite3_errmsg(database) ));
}
cout << "initialized SQL" << endl;
cout << "Database filename: " << dbname << endl;
cout << "Initialized SQL" << endl;
//TODO: move this into a function?
//Run setup scripts
ifstream is("rsc\\scripts\\setup_server.sql");
if (!is.is_open()) {
throw(runtime_error("Failed to run database setup script"));
//setup the database
if (runSQLScript(database, config["dir.scripts"] + "setup_server.sql")) {
throw(runtime_error("Failed to initialize SQL's setup script"));
}
string script;
getline(is, script, '\0');
is.close();
sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr);
cout << "Initialized SQL's setup script" << endl;
//lua
luaState = luaL_newstate();
if (!luaState) {
throw(runtime_error("Failed to initialize lua"));
}
luaL_openlibs(luaState);
cout << "Initialized lua" << endl;
//run the startup script
if (luaL_dofile(luaState, (config["dir.scripts"] + "setup_server.lua").c_str())) {
throw(runtime_error(string() + "Failed to initialize lua's setup script: " + lua_tostring(luaState, -1) ));
}
cout << "Initialized lua's setup script" << endl;
//finalize the startup
cout << "Startup completed successfully" << endl;
}
void ServerApplication::Loop() {
NetworkPacket packet;
while(running) {
//suck in the waiting packets & process them
try {
while(network.Receive()) {
memcpy(&packet, network.GetInData(), sizeof(NetworkPacket));
packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet);
}
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);
}
catch(exception& e) {
cerr << "Network Error: " << e.what() << endl;
}
//give the computer a break
SDL_Delay(10);
}
}
void ServerApplication::Quit() {
//members
network.Close();
cout << "Shutting down" << endl;
//empty the members
//TODO: player manager
//TODO: client manager
//APIs
lua_close(luaState);
sqlite3_close_v2(database);
network.Close();
SDLNet_Quit();
SDL_Quit();
cout << "Shutdown finished" << endl;
}
//-------------------------
//Define the uber switch
//-------------------------
void ServerApplication::HandlePacket(NetworkPacket packet) {
switch(packet.meta.type) {
case NetworkPacket::Type::BROADCAST_REQUEST:
HandleBroadcastRequest(packet);
break;
case NetworkPacket::Type::JOIN_REQUEST:
HandleJoinRequest(packet);
break;
case NetworkPacket::Type::DISCONNECT:
HandleDisconnect(packet);
break;
case NetworkPacket::Type::SYNCHRONIZE:
HandleSynchronize(packet);
break;
case NetworkPacket::Type::SHUTDOWN:
HandleShutdown(packet);
break;
case NetworkPacket::Type::PLAYER_NEW:
HandlePlayerNew(packet);
break;
case NetworkPacket::Type::PLAYER_DELETE:
HandlePlayerDelete(packet);
break;
case NetworkPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet);
break;
//handle errors
default:
throw(runtime_error("Unknown NetworkPacket::Type encountered"));
@@ -154,27 +169,35 @@ void ServerApplication::HandlePacket(NetworkPacket packet) {
}
}
//-------------------------
//Handle various network input
//-------------------------
void ServerApplication::HandleBroadcastRequest(NetworkPacket packet) {
//send back the server's name
//send back the server's metadata
packet.meta.type = NetworkPacket::Type::BROADCAST_RESPONSE;
//TODO: version info
snprintf(packet.serverInfo.name, PACKET_STRING_SIZE, "%s", config["server.name"].c_str());
network.Send(&packet.meta.srcAddress, &packet, sizeof(NetworkPacket));
//TODO: player count
char buffer[sizeof(NetworkPacket)];
serialize(&packet, buffer);
network.Send(&packet.meta.srcAddress, buffer, sizeof(NetworkPacket));
}
void ServerApplication::HandleJoinRequest(NetworkPacket packet) {
//TODO: prevent duplicate logins from the same address?
//create the new client, filling it with the correct info
Client newClient;
newClient.address = packet.meta.srcAddress;
//push the new client
clientMap[clientCounter] = newClient;
//register the new client
ClientEntry c;
c.address = packet.meta.srcAddress;
clientMap[clientCounter] = c;
//send the client their info
char buffer[sizeof(NetworkPacket)];
packet.meta.type = NetworkPacket::Type::JOIN_RESPONSE;
packet.clientInfo.index = clientCounter;
network.Send(&newClient.address, &packet, sizeof(NetworkPacket));
serialize(&packet, buffer);
network.Send(&clientMap[clientCounter].address, buffer, sizeof(NetworkPacket));
//finished this routine
clientCounter++;
@@ -183,32 +206,36 @@ void ServerApplication::HandleJoinRequest(NetworkPacket packet) {
void ServerApplication::HandleDisconnect(NetworkPacket packet) {
//disconnect the specified client
network.Send(&clientMap[packet.clientInfo.index].address, &packet, sizeof(NetworkPacket));
//TODO: authenticate who is disconnecting/kicking
char buffer[sizeof(NetworkPacket)];
serialize(&packet, buffer);
network.Send(&clientMap[packet.clientInfo.index].address, buffer, sizeof(NetworkPacket));
clientMap.erase(packet.clientInfo.index);
//delete players
erase_if(playerMap, [&](pair<int, Player> it) -> bool {
//delete players from all clients
NetworkPacket delPacket;
delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE;
erase_if(playerMap, [&](std::pair<int, PlayerEntry> it) -> bool {
//find the internal players to delete
if (it.second.clientIndex == packet.clientInfo.index) {
NetworkPacket delPacket;
//data to delete one specific player
delPacket.meta.type = NetworkPacket::Type::PLAYER_DELETE;
delPacket.playerInfo.playerIndex = it.first;
//send to all
//send the delete player command to all clients
PumpPacket(delPacket);
return true;
}
return false;
});
//finished this routine
cout << "disconnect, total: " << clientMap.size() << endl;
}
void ServerApplication::HandleSynchronize(NetworkPacket packet) {
//send all the server's data to this client
//TODO: compensate for large distances
NetworkPacket newPacket;
char buffer[sizeof(NetworkPacket)];
//players
newPacket.meta.type = NetworkPacket::Type::PLAYER_UPDATE;
@@ -218,7 +245,8 @@ void ServerApplication::HandleSynchronize(NetworkPacket packet) {
snprintf(newPacket.playerInfo.avatar, PACKET_STRING_SIZE, "%s", it.second.avatar.c_str());
newPacket.playerInfo.position = it.second.position;
newPacket.playerInfo.motion = it.second.motion;
network.Send(&clientMap[packet.clientInfo.index].address, &newPacket, sizeof(NetworkPacket));
serialize(&newPacket, buffer);
network.Send(&clientMap[packet.clientInfo.index].address, buffer, sizeof(NetworkPacket));
}
}
@@ -230,13 +258,15 @@ void ServerApplication::HandleShutdown(NetworkPacket packet) {
packet.meta.type = NetworkPacket::Type::DISCONNECT;
PumpPacket(packet);
//finished this routine
cout << "shutting down" << endl;
}
void ServerApplication::HandlePlayerNew(NetworkPacket packet) {
//create the new player object
Player newPlayer;
PlayerEntry newPlayer;
newPlayer.clientIndex = packet.playerInfo.clientIndex;
newPlayer.mapIndex = 0;
newPlayer.handle = packet.playerInfo.handle;
newPlayer.avatar = packet.playerInfo.avatar;
newPlayer.position = {0,0};
@@ -263,7 +293,7 @@ void ServerApplication::HandlePlayerDelete(NetworkPacket packet) {
}
//delete players
erase_if(playerMap, [&](pair<int, Player> it) -> bool {
erase_if(playerMap, [&](pair<int, PlayerEntry> it) -> bool {
if (it.first == packet.playerInfo.playerIndex) {
NetworkPacket delPacket;
@@ -293,8 +323,10 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) {
}
void ServerApplication::PumpPacket(NetworkPacket packet) {
//send this packet to all clients
//I don't really like this, but it'll do for now
char buffer[sizeof(NetworkPacket)];
serialize(&packet, buffer);
for (auto& it : clientMap) {
network.Send(&it.second.address, &packet, sizeof(NetworkPacket));
network.Send(&it.second.address, buffer, sizeof(NetworkPacket));
}
}
}
+23 -9
View File
@@ -25,28 +25,40 @@
//networking
#include "network_packet.hpp"
#include "udp_network_utility.hpp"
#include "serial.hpp"
//APIs
#include "lua/lua.hpp"
#include "sqlite3/sqlite3.h"
#include "SDL/SDL.h"
//misc
//common
#include "config_utility.hpp"
#include "vector2.hpp"
#include "client.hpp"
#include "player.hpp"
//STL
#include <map>
#include <string>
struct ClientEntry {
IPaddress address;
};
struct PlayerEntry {
int clientIndex;
int mapIndex;
std::string handle;
std::string avatar;
Vector2 position;
Vector2 motion;
};
//The main application class
class ServerApplication {
public:
//standard functions
ServerApplication();
~ServerApplication();
ServerApplication() = default;
~ServerApplication() = default;
void Init(int argc, char** argv);
void Loop();
@@ -73,13 +85,15 @@ private:
//database
sqlite3* database = nullptr;
//lua
lua_State* luaState = nullptr;
//misc
bool running = true;
ConfigUtility config;
//global lists
ClientMap clientMap;
PlayerMap playerMap;
std::map<int, ClientEntry> clientMap;
std::map<int, PlayerEntry> playerMap;
int clientCounter = 0;
int playerCounter = 0;