Created ConnMan object for server to make it easier to program.
* Updated ServerConnection Authentication call to supply name 'Aurailus' * Packet::deserialize now returns a pointer * Move most of the packet handling code from Server to ConnManmaster
parent
4346f45c1c
commit
0b038364e5
|
@ -89,9 +89,17 @@ add_executable(zeus
|
|||
zeus/client/graphics/scene/MenuScene.h
|
||||
zeus/server/Server.cpp
|
||||
zeus/server/Server.h
|
||||
zeus/server/network/ClientConnection.cpp
|
||||
zeus/server/network/ClientConnection.h
|
||||
zeus/server/network/ServerClient.cpp
|
||||
zeus/server/network/ServerClient.h
|
||||
zeus/generic/network/Packet.cpp
|
||||
zeus/generic/network/Packet.h zeus/server/ServerPlayer.cpp zeus/server/ServerPlayer.h zeus/client/network/ServerConnection.cpp zeus/client/network/ServerConnection.h zeus/client/gameworld/WorldThreadDefs.cpp zeus/client/gameworld/WorldThreadDefs.h)
|
||||
zeus/generic/network/Packet.h
|
||||
zeus/server/ServerPlayer.cpp
|
||||
zeus/server/ServerPlayer.h
|
||||
zeus/client/network/ServerConnection.cpp
|
||||
zeus/client/network/ServerConnection.h
|
||||
zeus/client/gameworld/WorldThreadDefs.cpp
|
||||
zeus/client/gameworld/WorldThreadDefs.h
|
||||
zeus/server/network/ConnMan.cpp
|
||||
zeus/server/network/ConnMan.h)
|
||||
|
||||
target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl)
|
||||
|
|
|
@ -24,7 +24,7 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
else if (start == "server") {
|
||||
Server s(12345);
|
||||
s.start();
|
||||
s.init();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -43,24 +43,25 @@ ServerConfig* ServerConnection::connect() {
|
|||
|
||||
auto packet = Packet::deserialize(recv_buf);
|
||||
|
||||
if (packet.type == Packet::HANDSHAKE) {
|
||||
if (packet->type == Packet::HANDSHAKE) {
|
||||
std::cout << "Handshake received." << std::endl;
|
||||
t = Timer("Authenticate time");
|
||||
handshook = true;
|
||||
|
||||
Packet p;
|
||||
p = Packet(Packet::AUTHTOKEN);
|
||||
p.addString("Hello! I'm a string!!!");
|
||||
p = Packet(Packet::AUTHENTICATE);
|
||||
p.addString("TOKEN");
|
||||
p.addString("Aurailus"); //USERNAME HERE
|
||||
|
||||
sendPacket(p, remote_endpoint);
|
||||
}
|
||||
else if (packet.type == Packet::PLAYRINFO) {
|
||||
else if (packet->type == Packet::PLAYERINFO) {
|
||||
std::cout << "Player info received." << std::endl;
|
||||
connected = true;
|
||||
|
||||
float x = Packet::decodeFloat(&packet.data[0]);
|
||||
float y = Packet::decodeFloat(&packet.data[4]);
|
||||
float z = Packet::decodeFloat(&packet.data[8]);
|
||||
float x = Packet::decodeFloat(&packet->data[0]);
|
||||
float y = Packet::decodeFloat(&packet->data[4]);
|
||||
float z = Packet::decodeFloat(&packet->data[8]);
|
||||
|
||||
return new ServerConfig {
|
||||
.playerPos = glm::vec3(x, y, z)
|
||||
|
@ -90,7 +91,7 @@ void ServerConnection::update() {
|
|||
socket.receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint);
|
||||
|
||||
auto packet = Packet::deserialize(recv_buf);
|
||||
if (packet.length > 0) handlePacket(packet, remote_endpoint);
|
||||
if (packet->length > 0) handlePacket(*packet, remote_endpoint);
|
||||
}
|
||||
|
||||
long sleep_for = 16L*1000000L - t.elapsedNs();
|
||||
|
|
|
@ -9,7 +9,7 @@ Packet::Packet(Packet::PacketType p) {
|
|||
}
|
||||
|
||||
//Convert a vector of PacketBytes (chars) into a PacketData by splitting the head and body information.
|
||||
Packet Packet::deserialize(std::vector<PacketByte> data) {
|
||||
Packet* Packet::deserialize(std::vector<PacketByte> data) {
|
||||
if (data.size() < 4) std::cerr << "Packet does not contain data." << std::endl;
|
||||
|
||||
//Seperate the packet header from the body,
|
||||
|
@ -30,10 +30,10 @@ Packet Packet::deserialize(std::vector<PacketByte> data) {
|
|||
dataBody.push_back(data[i]);
|
||||
}
|
||||
|
||||
auto p = Packet();
|
||||
p.type = (PacketType)num;
|
||||
p.length = dataBody.size();
|
||||
p.data = std::move(dataBody);
|
||||
auto p = new Packet();
|
||||
p->type = (PacketType)num;
|
||||
p->length = dataBody.size();
|
||||
p->data = std::move(dataBody);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
|
||||
~Packet() = default;
|
||||
|
||||
static Packet deserialize(std::vector<PacketByte> data);
|
||||
static Packet* deserialize(std::vector<PacketByte> data);
|
||||
std::vector<Packet::PacketByte> serialize();
|
||||
|
||||
static void encodeInt(std::vector<PacketByte> &target, int num);
|
||||
|
@ -39,11 +39,11 @@ public:
|
|||
static void encodeFloat(std::vector<PacketByte> &target, float num);
|
||||
static float decodeFloat(PacketByte* floatStart);
|
||||
public:
|
||||
const static PacketType UNDEFINED = 0;
|
||||
const static PacketType HANDSHAKE = 1;
|
||||
const static PacketType AUTHTOKEN = 2;
|
||||
const static PacketType PLAYRINFO = 3;
|
||||
const static PacketType REQCHUNKS = 4;
|
||||
const static PacketType UNDEFINED = 0;
|
||||
const static PacketType HANDSHAKE = 1;
|
||||
const static PacketType AUTHENTICATE = 2;
|
||||
const static PacketType PLAYERINFO = 3;
|
||||
const static PacketType REQCHUNKS = 4;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -6,118 +6,28 @@
|
|||
|
||||
Server::Server() = default;
|
||||
|
||||
Server::Server(int port) {
|
||||
Server::Server(unsigned short port) {
|
||||
this->port = port;
|
||||
alive = true;
|
||||
}
|
||||
|
||||
void Server::start() {
|
||||
server_socket = new asio::ip::udp::socket(io_context, udp::endpoint(udp::v4(), (unsigned short)port));
|
||||
void Server::init() {
|
||||
conn.init(port);
|
||||
players = conn.getPlayersMap();
|
||||
|
||||
while (alive) loop();
|
||||
}
|
||||
|
||||
void Server::loop() {
|
||||
Timer t("Loop time");
|
||||
Timer loop("");
|
||||
|
||||
//Collect incoming packets
|
||||
while (server_socket->available() > 0) {
|
||||
size_t pendingSize = server_socket->available();
|
||||
std::vector<Packet::PacketByte> recv_buf((unsigned long)pendingSize);
|
||||
conn.poll();
|
||||
|
||||
auto remote_endpoint = new udp::endpoint();
|
||||
server_socket->receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint);
|
||||
|
||||
auto packet = Packet::deserialize(recv_buf);
|
||||
if (packet.length > 0) handlePacket(packet, remote_endpoint);
|
||||
}
|
||||
|
||||
long sleep_for = 16L*1000000L - t.elapsedNs();
|
||||
long sleep_for = 16L*1000000L - loop.elapsedNs();
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds(sleep_for));
|
||||
}
|
||||
|
||||
std::string Server::createIdentifier(udp::endpoint *endpoint) {
|
||||
return endpoint->address().to_string() + ":" + std::to_string(endpoint->port());
|
||||
}
|
||||
|
||||
void Server::handlePacket(Packet &packet, udp::endpoint* endpoint) {
|
||||
auto identifier = createIdentifier(endpoint);
|
||||
|
||||
if (connections.count(identifier) == 0 || !connections[identifier]->authenticated) {
|
||||
handleAuthPacket(identifier, packet, endpoint);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet.type == Packet::REQCHUNKS) {
|
||||
for (int i = 0; i < packet.length / 12; i++) {
|
||||
int offsetBase = i * 12;
|
||||
int x = Packet::decodeInt(&packet.data[0 + offsetBase]);
|
||||
int y = Packet::decodeInt(&packet.data[0 + offsetBase + 4]);
|
||||
int z = Packet::decodeInt(&packet.data[0 + offsetBase + 8]);
|
||||
printf("%i, %i, %i\n", x, y, z);
|
||||
}
|
||||
std::cout << packet.length << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::handleAuthPacket(std::string& identifier, Packet &packet, udp::endpoint* endpoint) {
|
||||
if (connections.count(identifier) == 0) {
|
||||
if (packet.type == Packet::HANDSHAKE) {
|
||||
addConnection(identifier, endpoint);
|
||||
|
||||
Packet p;
|
||||
p = Packet(Packet::HANDSHAKE);
|
||||
auto data = p.serialize();
|
||||
|
||||
server_socket->send_to(asio::buffer(data, data.size()), *endpoint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (packet.type == Packet::AUTHTOKEN) {
|
||||
int strLen = Packet::decodeInt(&packet.data[0]);
|
||||
|
||||
std::string token(packet.data.begin() + 4, packet.data.begin() + 4 + strLen);
|
||||
|
||||
//TODO: Validate this token somehow
|
||||
std::cout << "Token: " << token << std::endl;
|
||||
|
||||
connections[identifier]->authenticated = true;
|
||||
createPlayer(connections[identifier]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::cout << "Received a non-auth-related packet (" << packet.type <<
|
||||
") from unknown client " << identifier << ". Ignoring." << std::endl;
|
||||
}
|
||||
|
||||
void Server::addConnection(std::string &identifier, udp::endpoint *endpoint) {
|
||||
std::cout << "[INFO] Recieved handshake from new client " << identifier << std::endl;
|
||||
auto conn = new ClientConnection(endpoint);
|
||||
connections.insert(std::pair<std::string, ClientConnection*>(identifier, conn));
|
||||
}
|
||||
|
||||
void Server::createPlayer(ClientConnection *connection) {
|
||||
|
||||
auto player = new ServerPlayer(connection, glm::vec3(0, 64, 0));
|
||||
players.insert(std::pair<std::string, ServerPlayer*>("USERNAME", player));
|
||||
|
||||
Packet p;
|
||||
p = Packet(Packet::PLAYRINFO);
|
||||
|
||||
p.addFloat(player->pos.x);
|
||||
p.addFloat(player->pos.y);
|
||||
p.addFloat(player->pos.z);
|
||||
|
||||
auto data = p.serialize();
|
||||
|
||||
server_socket->send_to(asio::buffer(data, data.size()), *connection->endpoint);
|
||||
}
|
||||
|
||||
void Server::cleanup() {
|
||||
alive = false;
|
||||
|
||||
delete server_socket;
|
||||
}
|
||||
|
||||
Server::~Server() {
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <asio.hpp>
|
||||
|
||||
#include "ServerPlayer.h"
|
||||
#include "network/ClientConnection.h"
|
||||
#include "network/ConnMan.h"
|
||||
#include "network/ServerClient.h"
|
||||
#include "../generic/network/Packet.h"
|
||||
#include "../client/engine/Timer.h"
|
||||
|
||||
|
@ -19,32 +21,19 @@ using asio::ip::udp;
|
|||
class Server {
|
||||
public:
|
||||
Server();
|
||||
explicit Server(int port);
|
||||
explicit Server(unsigned short port);
|
||||
|
||||
void start();
|
||||
|
||||
~Server();
|
||||
private:
|
||||
void init();
|
||||
void loop();
|
||||
void cleanup();
|
||||
|
||||
std::string createIdentifier(udp::endpoint* endpoint);
|
||||
~Server();
|
||||
private:
|
||||
ConnMan conn;
|
||||
std::map<std::string, ServerPlayer*>* players;
|
||||
|
||||
void handlePacket(Packet& packet, udp::endpoint* endpoint);
|
||||
void handleAuthPacket(std::string& identifier, Packet& packet, udp::endpoint* endpoint);
|
||||
|
||||
void addConnection(std::string& identifier, udp::endpoint* endpoint);
|
||||
void createPlayer(ClientConnection* connection);
|
||||
|
||||
//string is IP:Port
|
||||
std::map<std::string, ClientConnection*> connections;
|
||||
//string is username
|
||||
std::map<std::string, ServerPlayer*> players;
|
||||
|
||||
int port;
|
||||
bool alive;
|
||||
asio::io_context io_context;
|
||||
udp::socket* server_socket;
|
||||
unsigned short port;
|
||||
bool alive = true;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ ServerPlayer::ServerPlayer() {
|
|||
this->connection = nullptr;
|
||||
}
|
||||
|
||||
ServerPlayer::ServerPlayer(ClientConnection *connection, glm::vec3 pos) {
|
||||
ServerPlayer::ServerPlayer(ServerClient *connection, glm::vec3 pos) {
|
||||
this->pos = pos;
|
||||
this->connection = connection;
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
|
||||
#include <vec3.hpp>
|
||||
#include "network/ClientConnection.h"
|
||||
#include "network/ServerClient.h"
|
||||
|
||||
class ServerPlayer {
|
||||
public:
|
||||
ServerPlayer();
|
||||
ServerPlayer(ClientConnection* connection, glm::vec3 pos);
|
||||
ServerPlayer(ServerClient* connection, glm::vec3 pos);
|
||||
|
||||
ClientConnection* connection;
|
||||
ServerClient* connection;
|
||||
glm::vec3 pos = glm::vec3(0, 0, 0);
|
||||
|
||||
std::vector<glm::vec3> requestedChunks;
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
//
|
||||
// Created by aurailus on 10/01/19.
|
||||
//
|
||||
|
||||
#include "ClientConnection.h"
|
||||
|
||||
ClientConnection::ClientConnection() = default;
|
||||
|
||||
ClientConnection::ClientConnection(asio::ip::udp::endpoint* endpoint) {
|
||||
this->endpoint = endpoint;
|
||||
this->authenticated = false;
|
||||
}
|
||||
|
||||
ClientConnection::~ClientConnection() {
|
||||
delete this->endpoint;
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// Created by aurailus on 22/01/19.
|
||||
//
|
||||
|
||||
#include "ConnMan.h"
|
||||
|
||||
ConnMan::ConnMan() = default;
|
||||
|
||||
void ConnMan::init(unsigned short port) {
|
||||
server_socket = new asio::ip::udp::socket(io_context, udp::endpoint(udp::v4(), port));
|
||||
}
|
||||
|
||||
void ConnMan::poll() {
|
||||
while (server_socket->available() > 0) {
|
||||
size_t pendingSize = server_socket->available();
|
||||
std::vector<Packet::PacketByte> recv_buf((unsigned long)pendingSize);
|
||||
|
||||
auto remote_endpoint = new udp::endpoint();
|
||||
server_socket->receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint);
|
||||
|
||||
if (recv_buf.size() > 4) {
|
||||
auto packet = Packet::deserialize(recv_buf);
|
||||
handlePacket(packet, remote_endpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConnMan::handlePacket(Packet* packet, udp::endpoint* endpoint) {
|
||||
std::string uuid = createIdentifier(endpoint);
|
||||
|
||||
if (!clients.count(uuid)) {
|
||||
if (packet->type == Packet::HANDSHAKE) {
|
||||
|
||||
auto client = addClient(uuid, endpoint);
|
||||
|
||||
Packet p(Packet::HANDSHAKE);
|
||||
send(&p, client);
|
||||
}
|
||||
}
|
||||
else if (!clients[uuid]->authenticated) {
|
||||
if (packet->type == Packet::AUTHENTICATE) {
|
||||
int strLen = Packet::decodeInt(&packet->data[0]);
|
||||
int offset = 4;
|
||||
|
||||
std::string token(packet->data.begin() + offset, packet->data.begin() + offset + strLen);
|
||||
|
||||
//At some point there needs to be validation here with a centralized server, but for now
|
||||
//we just assume that the information is some sort of token and move on.
|
||||
|
||||
offset = offset + strLen;
|
||||
strLen = Packet::decodeInt(&packet->data[offset]);
|
||||
offset += 4;
|
||||
|
||||
std::string username(packet->data.begin() + offset, packet->data.begin() + offset + strLen);
|
||||
clients[uuid]->authenticated = true;
|
||||
addPlayer(clients[uuid], username);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//TODO: Push to the packet vector
|
||||
// if (packet->type == Packet::REQCHUNKS) {
|
||||
// for (int i = 0; i < packet->length / 12; i++) {
|
||||
// int offsetBase = i * 12;
|
||||
// int x = Packet::decodeInt(&packet->data[0 + offsetBase]);
|
||||
// int y = Packet::decodeInt(&packet->data[0 + offsetBase + 4]);
|
||||
// int z = Packet::decodeInt(&packet->data[0 + offsetBase + 8]);
|
||||
// printf("%i, %i, %i\n", x, y, z);
|
||||
// }
|
||||
// std::cout << packet->length << std::endl;
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ServerClient* ConnMan::addClient(std::string uuid, udp::endpoint* endpoint) {
|
||||
printf("[INFO] Handshake recieved from %s.\n", uuid.c_str());
|
||||
|
||||
auto client = new ServerClient(endpoint, uuid);
|
||||
clients.insert(std::pair<std::string, ServerClient*>(uuid, client));
|
||||
return client;
|
||||
}
|
||||
|
||||
void ConnMan::addPlayer(ServerClient* client, std::string username) {
|
||||
printf("[INFO] User %s has connected with IP %s.\n", username.c_str(), client->uuid.c_str());
|
||||
|
||||
auto player = new ServerPlayer(client, glm::vec3(0, 48, 0));
|
||||
client->player = player;
|
||||
players.insert(std::pair<std::string, ServerPlayer*>(username, player));
|
||||
|
||||
Packet p(Packet::PLAYERINFO);
|
||||
|
||||
p.addFloat(player->pos.x);
|
||||
p.addFloat(player->pos.y);
|
||||
p.addFloat(player->pos.z);
|
||||
|
||||
send(&p, client);
|
||||
}
|
||||
|
||||
//Create a IP + Port combo that can be used as a UUID for an endpoint.
|
||||
std::string ConnMan::createIdentifier(udp::endpoint *endpoint) {
|
||||
return endpoint->address().to_string() + ":" + std::to_string(endpoint->port());
|
||||
}
|
||||
|
||||
void ConnMan::send(Packet *p, ServerClient* client) {
|
||||
send(p, client->endpoint);
|
||||
}
|
||||
|
||||
void ConnMan::send(Packet *p, udp::endpoint* endpoint) {
|
||||
auto data = p->serialize();
|
||||
server_socket->send_to(asio::buffer(data, data.size()), *endpoint);
|
||||
}
|
||||
|
||||
std::map<std::string, ServerPlayer*>* ConnMan::getPlayersMap() {
|
||||
return &players;
|
||||
}
|
||||
|
||||
ConnMan::~ConnMan() {
|
||||
delete server_socket;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// Created by aurailus on 22/01/19.
|
||||
//
|
||||
|
||||
#ifndef ZEUS_CONNMAN_H
|
||||
#define ZEUS_CONNMAN_H
|
||||
|
||||
#include <asio.hpp>
|
||||
#include "ServerClient.h"
|
||||
#include "../ServerPlayer.h"
|
||||
#include "../../generic/network/Packet.h"
|
||||
|
||||
using asio::ip::udp;
|
||||
|
||||
class ConnMan {
|
||||
public:
|
||||
ConnMan();
|
||||
|
||||
void init(unsigned short port);
|
||||
void poll();
|
||||
void send(Packet* p, ServerClient* connection);
|
||||
void send(Packet* p, udp::endpoint* endpoint);
|
||||
|
||||
std::map<std::string, ServerPlayer*>* getPlayersMap();
|
||||
|
||||
~ConnMan();
|
||||
private:
|
||||
void handlePacket(Packet* packet, udp::endpoint* endpoint);
|
||||
std::string createIdentifier(udp::endpoint *endpoint);
|
||||
|
||||
ServerClient* addClient(std::string uuid, udp::endpoint* endpoint);
|
||||
void addPlayer(ServerClient* client, std::string username);
|
||||
|
||||
std::map<std::string, ServerClient*> clients;
|
||||
std::map<std::string, ServerPlayer*> players;
|
||||
|
||||
|
||||
// std::vector<std::pair<udp::endpoint*, Packet>> packets;
|
||||
|
||||
asio::io_context io_context;
|
||||
udp::socket* server_socket;
|
||||
};
|
||||
|
||||
|
||||
#endif //ZEUS_CONNMAN_H
|
Loading…
Reference in New Issue