Refactor and cleanup of server code
This commit is contained in:
parent
6726982ee6
commit
3ee6551013
@ -5,9 +5,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include "gameserver.hpp"
|
||||||
|
|
||||||
bool console_is_running = false;
|
|
||||||
|
|
||||||
class ServerConsole
|
class ServerConsole
|
||||||
{
|
{
|
||||||
@ -26,13 +24,13 @@ void * console_logic(void *)
|
|||||||
|
|
||||||
std::string input_string;
|
std::string input_string;
|
||||||
|
|
||||||
while(console_is_running)
|
while(game_is_running)
|
||||||
{
|
{
|
||||||
if(std::getline(std::cin, input_string))
|
if(std::getline(std::cin, input_string))
|
||||||
{
|
{
|
||||||
if(input_string == "stop")
|
if(input_string == "stop")
|
||||||
{
|
{
|
||||||
console_is_running = false;
|
game_is_running = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -46,7 +44,7 @@ void * console_logic(void *)
|
|||||||
ServerConsole::ServerConsole(void)
|
ServerConsole::ServerConsole(void)
|
||||||
{
|
{
|
||||||
//Intialized values
|
//Intialized values
|
||||||
console_is_running = true;
|
game_is_running = true;
|
||||||
|
|
||||||
thread = pthread_t();
|
thread = pthread_t();
|
||||||
|
|
||||||
@ -64,7 +62,7 @@ void ServerConsole::stop(void)
|
|||||||
|
|
||||||
bool ServerConsole::is_running(void)
|
bool ServerConsole::is_running(void)
|
||||||
{
|
{
|
||||||
return console_is_running;
|
return game_is_running;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -8,6 +8,9 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "gamemap.hpp"
|
#include "gamemap.hpp"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
bool game_is_running = false;
|
||||||
|
|
||||||
const int SERVER_PORT = 7777;
|
const int SERVER_PORT = 7777;
|
||||||
const int MAX_PLAYERS = 32;
|
const int MAX_PLAYERS = 32;
|
||||||
@ -21,86 +24,155 @@ static std::string usernames[MAX_PLAYERS];
|
|||||||
static ENetHost* server;
|
static ENetHost* server;
|
||||||
|
|
||||||
//===================
|
//===================
|
||||||
// Network Processes
|
// Game Server Logic
|
||||||
//===================
|
//===================
|
||||||
void PlayerMove(ENetEvent* event)
|
namespace gameserver
|
||||||
{
|
{
|
||||||
int peer_id = event->peer -> incomingPeerID;
|
void Intialize()
|
||||||
|
|
||||||
int move_x = 0;
|
|
||||||
int move_y = 1;
|
|
||||||
|
|
||||||
|
|
||||||
std::string data_input((char*)event->packet->data);
|
|
||||||
data_input = data_input.substr(2);
|
|
||||||
|
|
||||||
//Parse input string
|
|
||||||
std::stringstream ss(data_input);
|
|
||||||
std::string tempString;
|
|
||||||
std::getline(ss, tempString, ',');
|
|
||||||
move_x = std::stoi(tempString);
|
|
||||||
std::getline(ss, tempString, '\n');
|
|
||||||
move_y = std::stoi(tempString);
|
|
||||||
|
|
||||||
//Update player position
|
|
||||||
std::string resp = "2|" + gamemap.move_entity(usernames[peer_id], "player", move_x, move_y);
|
|
||||||
const char* data = resp.c_str();
|
|
||||||
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
|
||||||
enet_host_broadcast(server, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataRequest(ENetEvent* event)
|
|
||||||
{
|
|
||||||
//Create world data dump
|
|
||||||
std::string map_dump_resp("2|");
|
|
||||||
map_dump_resp += gamemap.get_tile_dump() + gamemap.get_entity_dump();
|
|
||||||
const char* data = map_dump_resp.c_str();
|
|
||||||
|
|
||||||
//Build and send reliable packet to requester
|
|
||||||
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
|
||||||
enet_peer_send(event->peer, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Authenticate(ENetEvent* event)
|
|
||||||
{
|
|
||||||
//Grab username from packet data
|
|
||||||
std::string username((char*)event->packet->data);
|
|
||||||
username = username.substr(2);
|
|
||||||
|
|
||||||
//Determine if peer already has username
|
|
||||||
int peer_id = event -> peer -> incomingPeerID;
|
|
||||||
const char* data;
|
|
||||||
if(usernames[peer_id] == "")
|
|
||||||
{
|
{
|
||||||
//Update username array
|
printf("Starting DT game server...\n");
|
||||||
usernames[peer_id] = username;
|
|
||||||
|
|
||||||
//Spawn entity
|
for(int i = 0; i < MAX_PLAYERS; i++)
|
||||||
std::string spawn_data = gamemap.spawn_entity(usernames[peer_id], "player", 128, 129);
|
{
|
||||||
|
usernames[i] = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Tell peers about new player
|
void PlayerMove(ENetEvent* event)
|
||||||
data = ("2|" + spawn_data).c_str();
|
{
|
||||||
|
int peer_id = event->peer -> incomingPeerID;
|
||||||
|
|
||||||
|
int move_x = 0;
|
||||||
|
int move_y = 0;
|
||||||
|
|
||||||
|
//Remove id marker from packet data
|
||||||
|
std::string data_input((char*)event->packet->data);
|
||||||
|
data_input = data_input.substr(2);
|
||||||
|
|
||||||
|
//Parse input string
|
||||||
|
std::stringstream ss(data_input);
|
||||||
|
std::string tempString;
|
||||||
|
std::getline(ss, tempString, ',');
|
||||||
|
move_x = std::stoi(tempString);
|
||||||
|
std::getline(ss, tempString, '\n');
|
||||||
|
move_y = std::stoi(tempString);
|
||||||
|
|
||||||
|
//Update player position
|
||||||
|
std::string resp = "2|" + gamemap.move_entity(usernames[peer_id], "player", move_x, move_y);
|
||||||
|
const char* data = resp.c_str();
|
||||||
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
enet_host_broadcast(server, 0, packet);
|
enet_host_broadcast(server, 0, packet);
|
||||||
|
|
||||||
std::cout << usernames[peer_id] << " spawned!" << std::endl;
|
|
||||||
std::cout << peer_id << " | " << username << std::endl;
|
|
||||||
|
|
||||||
std::string okay_response("1|OK");
|
|
||||||
data = (okay_response + username).c_str();
|
|
||||||
|
|
||||||
//Return success
|
|
||||||
packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
|
||||||
enet_peer_send(event -> peer, 0, packet);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
void DataRequest(ENetEvent* event)
|
||||||
{
|
{
|
||||||
std::string resp("1|Already logged in!");
|
//Create world data dump
|
||||||
data = resp.c_str();
|
std::string map_dump_resp("2|");
|
||||||
|
map_dump_resp += gamemap.get_tile_dump() + gamemap.get_entity_dump();
|
||||||
//Return reliable error message
|
const char* data = map_dump_resp.c_str();
|
||||||
|
|
||||||
|
//Build and send reliable packet to requester
|
||||||
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
enet_peer_send(event -> peer, 0, packet);
|
enet_peer_send(event->peer, 0, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Authenticate(ENetEvent* event)
|
||||||
|
{
|
||||||
|
//Grab username from packet data
|
||||||
|
std::string username((char*)event->packet->data);
|
||||||
|
username = username.substr(2);
|
||||||
|
|
||||||
|
//Determine if peer already has username
|
||||||
|
int peer_id = event -> peer -> incomingPeerID;
|
||||||
|
const char* data;
|
||||||
|
if(usernames[peer_id] == "")
|
||||||
|
{
|
||||||
|
//Update username array
|
||||||
|
usernames[peer_id] = username;
|
||||||
|
|
||||||
|
//Spawn entity
|
||||||
|
std::string spawn_data = gamemap.spawn_entity(usernames[peer_id], "player", 128, 129);
|
||||||
|
|
||||||
|
//Tell peers about new player
|
||||||
|
data = ("2|" + spawn_data).c_str();
|
||||||
|
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_host_broadcast(server, 0, packet);
|
||||||
|
|
||||||
|
std::cout << "'" << usernames[peer_id] << "' spawned!" << std::endl;
|
||||||
|
|
||||||
|
std::string okay_response("1|OK");
|
||||||
|
data = (okay_response + username).c_str();
|
||||||
|
|
||||||
|
//Return success
|
||||||
|
packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(event -> peer, 0, packet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string resp("1|Already logged in!");
|
||||||
|
data = resp.c_str();
|
||||||
|
|
||||||
|
//Return reliable error message
|
||||||
|
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_peer_send(event -> peer, 0, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessChatMessage(ENetEvent* event)
|
||||||
|
{
|
||||||
|
int peer_id = event->peer -> incomingPeerID;
|
||||||
|
if(usernames[peer_id] != "")
|
||||||
|
{
|
||||||
|
//Parse input string
|
||||||
|
std::stringstream ss((char*)event->packet->data);
|
||||||
|
std::string chat_message;
|
||||||
|
std::getline(ss, chat_message, '\n');
|
||||||
|
std::string resp = "<" + usernames[peer_id] + "> " + chat_message;
|
||||||
|
const char* data = resp.c_str();
|
||||||
|
|
||||||
|
std::cout << data << std::endl;
|
||||||
|
|
||||||
|
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_host_broadcast(server, 1, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandlePlayerDisconnect(ENetEvent* event)
|
||||||
|
{
|
||||||
|
//Clear username data and remove entity
|
||||||
|
std::string username = usernames[event -> peer -> incomingPeerID];
|
||||||
|
if(username != "")
|
||||||
|
{
|
||||||
|
std::cout << "'" << username << "' disconnected" << std::endl;
|
||||||
|
gamemap.remove_entity(username,"player");
|
||||||
|
usernames[event -> peer -> incomingPeerID] = "";
|
||||||
|
|
||||||
|
std::string resp = "2|delete,player:" + username;
|
||||||
|
const char* data = resp.c_str();
|
||||||
|
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
||||||
|
enet_host_broadcast(server, 0, packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessGeneralInput(ENetEvent* event)
|
||||||
|
{
|
||||||
|
char c [1];
|
||||||
|
c[0] = event->packet->data[0];
|
||||||
|
switch (c[0])
|
||||||
|
{
|
||||||
|
case '1':
|
||||||
|
gameserver::Authenticate(event);
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
gameserver::DataRequest(event);
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
gameserver::PlayerMove(event);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cout << "Invalid packet recieved!" <<std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,17 +9,11 @@
|
|||||||
|
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
#include "gameserver.hpp"
|
#include "gameserver.hpp"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
int main (int argc, char ** argv)
|
int main (int argc, char ** argv)
|
||||||
{
|
{
|
||||||
printf("Starting LD46 game server...\n");
|
//Intialize Enet
|
||||||
|
|
||||||
for(int i = 0; i < MAX_PLAYERS; i++)
|
|
||||||
{
|
|
||||||
usernames[i] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (enet_initialize () != 0)
|
if (enet_initialize () != 0)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "ENet server failed to initialize!\n");
|
fprintf (stderr, "ENet server failed to initialize!\n");
|
||||||
@ -27,35 +21,34 @@ int main (int argc, char ** argv)
|
|||||||
}
|
}
|
||||||
atexit (enet_deinitialize);
|
atexit (enet_deinitialize);
|
||||||
|
|
||||||
|
//Intialize game data
|
||||||
|
gameserver::Intialize();
|
||||||
|
|
||||||
|
//Create console
|
||||||
ServerConsole console;
|
ServerConsole console;
|
||||||
|
|
||||||
//Create ENet objects
|
//Create ENet objects
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
ENetAddress address;
|
ENetAddress address;
|
||||||
|
|
||||||
|
//Build Enet Host
|
||||||
address.host = ENET_HOST_ANY;
|
address.host = ENET_HOST_ANY;
|
||||||
address.port = SERVER_PORT;
|
address.port = SERVER_PORT;
|
||||||
|
|
||||||
|
|
||||||
const int CHANNEL_COUNT = 2;
|
const int CHANNEL_COUNT = 2;
|
||||||
server = enet_host_create (&address, MAX_PLAYERS, CHANNEL_COUNT, 0, 0);
|
server = enet_host_create (&address, MAX_PLAYERS, CHANNEL_COUNT, 0, 0);
|
||||||
|
|
||||||
if (server == NULL)
|
if (server == NULL)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create ENet server host!" << std::endl;
|
std::cout << "Failed to create ENet server host!" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Run main game server loop
|
||||||
std::cout << "Awaiting connections..." << std::endl;
|
std::cout << "Awaiting connections..." << std::endl;
|
||||||
while(console_is_running)
|
while(game_is_running)
|
||||||
{
|
{
|
||||||
ENetEvent event;
|
ENetEvent event;
|
||||||
/* Wait up to 1000 milliseconds for an event. */
|
|
||||||
while (enet_host_service (server, & event, EVENT_RATE) > 0)
|
while (enet_host_service (server, & event, EVENT_RATE) > 0)
|
||||||
{
|
{
|
||||||
printf("Parsing event!\n");
|
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
case ENET_EVENT_TYPE_CONNECT:
|
case ENET_EVENT_TYPE_CONNECT:
|
||||||
@ -64,73 +57,24 @@ int main (int argc, char ** argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_RECEIVE:
|
case ENET_EVENT_TYPE_RECEIVE:
|
||||||
std::cout << "A packet of length " << event.packet -> dataLength << " containing "
|
//Channel #0 processes authentication, world updates,
|
||||||
<< event.packet -> data << " was received from " << event.peer -> data << " on channel"
|
// and player movement
|
||||||
<< event.channelID << std::endl;
|
|
||||||
if (event.channelID == 0)
|
if (event.channelID == 0)
|
||||||
{
|
{
|
||||||
char c [1];
|
gameserver::ProcessGeneralInput(&event);
|
||||||
c[0] = event.packet->data[0];
|
|
||||||
|
|
||||||
/* Determine which function to call based on
|
|
||||||
the value of the first character of packet */
|
|
||||||
std::cout << "Packet Type: " << c << std::endl;
|
|
||||||
switch (c[0])
|
|
||||||
{
|
|
||||||
case '1':
|
|
||||||
Authenticate(&event);
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
DataRequest(&event);
|
|
||||||
break;
|
|
||||||
case '3':
|
|
||||||
PlayerMove(&event);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std::cout << "Invalid packet recieved!" <<std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
enet_packet_destroy (event.packet);
|
|
||||||
}
|
}
|
||||||
|
//Channel #1 proccesses chat messages
|
||||||
else if(event.channelID == 1)
|
else if(event.channelID == 1)
|
||||||
{
|
{
|
||||||
int peer_id = event.peer -> incomingPeerID;
|
gameserver::ProcessChatMessage(&event);
|
||||||
if(usernames[peer_id] != "")
|
|
||||||
{
|
|
||||||
//Parse input string
|
|
||||||
std::stringstream ss((char*)event.packet->data);
|
|
||||||
std::string chat_message;
|
|
||||||
std::getline(ss, chat_message, '\n');
|
|
||||||
std::string resp = "<" + usernames[peer_id] + "> " + chat_message;
|
|
||||||
const char* data = resp.c_str();
|
|
||||||
|
|
||||||
std::cout << data << std::endl;
|
|
||||||
|
|
||||||
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
|
||||||
enet_host_broadcast(server, 1, packet);
|
|
||||||
}
|
|
||||||
enet_packet_destroy (event.packet);
|
|
||||||
}
|
}
|
||||||
|
enet_packet_destroy (event.packet);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENET_EVENT_TYPE_DISCONNECT:
|
case ENET_EVENT_TYPE_DISCONNECT:
|
||||||
std::cout << event.peer -> data << " disconnected." << std::endl;
|
gameserver::HandlePlayerDisconnect(&event);
|
||||||
|
|
||||||
//Clear username data and remove entity
|
|
||||||
std::string username = usernames[event.peer -> incomingPeerID];
|
|
||||||
if(username != "")
|
|
||||||
{
|
|
||||||
std::cout << "Removing '" << username << "'s player data!" << std::endl;
|
|
||||||
gamemap.remove_entity(username,"player");
|
|
||||||
usernames[event.peer -> incomingPeerID] = "";
|
|
||||||
|
|
||||||
std::string resp = "2|delete,player:" + username;
|
|
||||||
const char* data = resp.c_str();
|
|
||||||
ENetPacket* packet = enet_packet_create(data, strlen(data) + 1, ENET_PACKET_FLAG_RELIABLE);
|
|
||||||
enet_host_broadcast(server, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Open peer for new connection
|
//Open peer for new connection
|
||||||
event.peer -> data = NULL;
|
event.peer -> data = NULL;
|
||||||
|
Reference in New Issue
Block a user