259 lines
5.4 KiB
C++
259 lines
5.4 KiB
C++
#pragma once
|
|
|
|
|
|
#include <iostream>
|
|
#include "Config.h"
|
|
#include <asio/ts/internet.hpp>
|
|
#include <asio.hpp>
|
|
#include <map>
|
|
#include <vector>
|
|
#include <thread>
|
|
|
|
|
|
namespace NetQuake {
|
|
|
|
|
|
|
|
struct NetworkGenericPacket { // generic packet straight from server
|
|
char type[2];
|
|
char length[2];
|
|
std::string remainder;
|
|
};
|
|
|
|
|
|
enum PacketType {
|
|
NQ_CONTROL_PACKET = 0x8000,
|
|
NQ_MESSAGE_BLOCK_CHUNK = 0x0001,
|
|
NQ_MESSAGE_BLOCK_END = 0x0009,
|
|
NQ_ACK = 0x0002,
|
|
NQ_UNRELIABLE = 0x0010,
|
|
NQ_UNKNOWN_PACKET
|
|
};
|
|
|
|
struct SerializedGenericPacket {
|
|
PacketType type;
|
|
int length;
|
|
std::string remainder;
|
|
};
|
|
|
|
SerializedGenericPacket Serialize(NetworkGenericPacket ngp);
|
|
|
|
|
|
enum ClientMessageType {
|
|
CLIENT_MESSAGE_NOOP = 0x00,
|
|
CLIENT_MESSAGE_KEEPALIVE = 0x01,
|
|
CLIENT_MESSAGE_DISCONNECT = 0x02,
|
|
CLIENT_MESSAGE_MOVEMENT = 0x03,
|
|
CLIENT_MESSAGE_CONSOLE = 0x04,
|
|
CLIENT_MESSAGE_UNKNOWN
|
|
};
|
|
|
|
struct ClientMessage {
|
|
ClientMessageType type;
|
|
std::string data;
|
|
};
|
|
|
|
struct ClientMessageBlock {
|
|
std::vector<ClientMessage> messages;
|
|
};
|
|
|
|
struct GenericGamePacket {
|
|
PacketType type;
|
|
int length;
|
|
long packetNumber;
|
|
ClientMessageBlock messageBlock;
|
|
bool valid = false;
|
|
};
|
|
GenericGamePacket toGenericGamePacket(SerializedGenericPacket sgp);
|
|
|
|
enum DemoMessageType {
|
|
DEM_BAD = 0x00,
|
|
DEM_NOP = 0x01,
|
|
DEM_DISCONNECT = 0x02,
|
|
DEM_UPDATESTAT = 0x03,
|
|
DEM_VERSION = 0x04,
|
|
DEM_SETVIEW = 0x05,
|
|
DEM_SOUND = 0x06,
|
|
DEM_TIME = 0x07,
|
|
DEM_PRINT = 0x08,
|
|
DEM_STUFFTEXT = 0x09,
|
|
DEM_SETANGLE = 0x0A,
|
|
DEM_SERVERINFO = 0x0B,
|
|
DEM_LIGHTSTYLE = 0x0C,
|
|
DEM_UPDATENAME = 0x0D,
|
|
DEM_UPDATEFRAGS = 0x0E,
|
|
DEM_CLIENTDATA = 0x0F,
|
|
DEM_STOPSOUND = 0x10,
|
|
DEM_UPDATECOLORS = 0x11,
|
|
DEM_PARTICLE = 0x12,
|
|
DEM_DAMAGE = 0x13,
|
|
DEM_SPAWNSTATIC = 0x14,
|
|
DEM_SPAWNBINARY = 0x15,
|
|
DEM_SPAWNBASELINE = 0x16,
|
|
DEM_TEMP_ENTITY = 0x17,
|
|
DEM_SETPAUSE = 0x18,
|
|
DEM_SIGNONUM = 0x19,
|
|
DEM_CENTERPRINT = 0x1A,
|
|
DEM_KILLEDMONSTER = 0x1B,
|
|
DEM_FOUNDSECRET = 0x1C,
|
|
DEM_SPAWNSTATICSOUND = 0x1D,
|
|
DEM_INTERMISSION = 0x1E,
|
|
DEM_FINALE = 0x1F,
|
|
DEM_CDTRACK = 0x20,
|
|
DEM_SELLSCREEN = 0x21,
|
|
DEM_CUTSCENE = 0x22,
|
|
DEM_UPDATEENTITY = 0x80
|
|
};
|
|
|
|
class GenericServerMessage {
|
|
public:
|
|
DemoMessageType type;
|
|
virtual std::string Serialize() = 0;
|
|
};
|
|
|
|
namespace ServerMessages {
|
|
class Print : public GenericServerMessage { // 0x08
|
|
public:
|
|
std::string text = "";
|
|
Print() { this->type = DEM_PRINT; }
|
|
std::string Serialize();
|
|
};
|
|
class ServerInfo : public GenericServerMessage { // 0x0B
|
|
public:
|
|
long serverVersion = 15;
|
|
long maxClients;
|
|
long multi;
|
|
std::string mapName;
|
|
std::vector<std::string> precacheModels;
|
|
long numModels;
|
|
std::vector<std::string> precacheSounds;
|
|
long numSounds;
|
|
ServerInfo() {
|
|
this->type = DEM_SERVERINFO;
|
|
precacheModels = std::vector<std::string>(256);
|
|
precacheSounds = std::vector<std::string>(256);
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string Serialize();
|
|
};
|
|
|
|
class SignOn : public GenericServerMessage {
|
|
public:
|
|
long signon;
|
|
SignOn() { type = DEM_SIGNONUM; }
|
|
std::string Serialize();
|
|
};
|
|
}
|
|
|
|
class ServerMessageBlock{
|
|
public:
|
|
PacketType type;
|
|
int order;
|
|
std::vector<GenericServerMessage*> serverMessages;
|
|
std::string Serialize();
|
|
};
|
|
|
|
|
|
|
|
enum Control_OpCode {
|
|
CONTROL_CONNECTION_REQUEST = 0x01,
|
|
CONTROL_SERVER_INFO_REQUEST = 0x02,
|
|
CONTROL_PLAYER_INFO_REQUEST = 0x03,
|
|
CONTROL_RULE_INFO_REQUEST = 0x04,
|
|
CONTROL_SERVER_INFO_REPLY = 0x83
|
|
};
|
|
|
|
struct GenericControlPacket {
|
|
Control_OpCode opcode;
|
|
std::string remainder;
|
|
GenericControlPacket(SerializedGenericPacket sgp);
|
|
};
|
|
|
|
enum NetProtocolVersion {
|
|
QTEST1 = 0x01,
|
|
QUNKNOWN = 0x02,
|
|
QGOLD = 0x03
|
|
};
|
|
|
|
struct ServerInfoRequest {
|
|
std::string gameName;
|
|
NetProtocolVersion netVersion;
|
|
ServerInfoRequest(GenericControlPacket gcp);
|
|
};
|
|
|
|
struct Address {
|
|
std::string ip;
|
|
int port;
|
|
};
|
|
|
|
struct ServerInfoReply {
|
|
Address address;
|
|
std::string hostname;
|
|
std::string levelname;
|
|
char currentPlayers;
|
|
char maxPlayers;
|
|
NetProtocolVersion netVersion;
|
|
};
|
|
|
|
std::string Serialize(ServerInfoReply sirp);
|
|
|
|
struct ConnectionRequest {
|
|
std::string gameName;
|
|
NetProtocolVersion netVersion;
|
|
ConnectionRequest(GenericControlPacket gcp);
|
|
};
|
|
|
|
struct ConnectionRequestReply {
|
|
bool reject;
|
|
short port; // LITTLE-ENDIAN (!)(!)(!)(!)(!)
|
|
char unknown[2]; // [ have fun :) ]
|
|
|
|
std::string reason;
|
|
};
|
|
|
|
::std::string Serialize(ConnectionRequestReply crr);
|
|
|
|
class GameEndpoint {
|
|
std::thread internalThread;
|
|
public:
|
|
GameEndpoint();
|
|
GameEndpoint(Config::Config* config, int port, asio::ip::udp::endpoint startRemote);
|
|
|
|
~GameEndpoint();
|
|
};
|
|
|
|
namespace Internal {
|
|
|
|
struct NewEndpointRequestReply {
|
|
bool ready = false;
|
|
bool error = false;
|
|
std::string reason;
|
|
int port;
|
|
asio::ip::udp::endpoint startRemote;
|
|
};
|
|
|
|
class InternalRequestConsole {
|
|
std::vector<NewEndpointRequestReply> newEndpointRequests;
|
|
int lastEndpointRequestTreated = 0;
|
|
public:
|
|
InternalRequestConsole();
|
|
|
|
int newEndpointRequest(asio::ip::udp::endpoint ep);
|
|
NewEndpointRequestReply getEndpointRequest(int id);
|
|
void Update(Config::Config *config, std::vector<GameEndpoint>* gameEndpointsVector);
|
|
~InternalRequestConsole();
|
|
};
|
|
}
|
|
|
|
|
|
std::string AcknowledgePacket(int packet);
|
|
|
|
|
|
void NetQuake_ControlServer(Internal::InternalRequestConsole* internalRequestConsole, Config::Config* config, bool* serverRunning);
|
|
void NetQuake_EndpointServer(Config::Config* config, int port, asio::ip::udp::endpoint startRemote);
|
|
|
|
|
|
} |