SQCSimulator2023/SQCSim-common/netprotocol.h

244 lines
7.7 KiB
C
Raw Normal View History

2023-09-25 08:23:52 -04:00
#ifndef NETPROTOCOL_H__
#define NETPROTOCOL_H__
2023-09-30 14:54:39 -04:00
2023-09-25 16:30:03 -04:00
#include <string>
2023-10-27 09:28:34 -04:00
#include "define.h"
2023-09-25 08:23:52 -04:00
#include "vector3.h"
2023-10-27 09:28:34 -04:00
/* Protocole Particulier de Partie a Plusieurs Personnes (PPPPP) */
2023-09-25 08:23:52 -04:00
namespace netprot {
2023-10-27 09:28:34 -04:00
enum class PACKET_TYPE: uint8_t {
2023-09-25 08:23:52 -04:00
ERR, INPUT, OUTPUT, SYNC,
2023-09-25 16:30:03 -04:00
TEAMINF, SELFINF, PLAYINF, LOGINF,
2023-09-25 08:23:52 -04:00
CHUNKMOD, PLAYERMOD, PICKUPMOD,
2023-12-05 06:25:48 -05:00
GAMEINFO, ENDINFO , BULLET,
CHAT, ERRLOG, LAST_PACK
2023-09-25 08:23:52 -04:00
};
2023-11-01 12:18:27 -04:00
/* Structures */
2023-10-27 09:28:34 -04:00
struct Buffer { // Pour pouvoir rendre l'utilisation des buffers plus clean.
2023-11-01 16:40:33 -04:00
char* ptr = new char[BUFFER_LENGTH] { 1 }, * tmp = nullptr;
2023-10-27 09:51:40 -04:00
uint32_t len = BUFFER_LENGTH;
2023-10-27 09:28:34 -04:00
~Buffer() { delete[] ptr; }
void rstLen() { len = BUFFER_LENGTH; }
};
2023-09-25 08:23:52 -04:00
2023-10-27 09:28:34 -04:00
struct Packet { // Pour pouvoir recevoir les paquets du recv() sans avoir à les aiguiller dans la même thread.
void* ptr = nullptr; // Notez que le pointeur doit être supprimé séparément lorsqu'il n'est plus utile.
2023-10-28 11:18:01 -04:00
PACKET_TYPE type = PACKET_TYPE::ERR;
2023-10-24 10:43:30 -04:00
};
2023-11-01 12:18:27 -04:00
/* Constantes */
2023-11-01 10:13:10 -04:00
inline const char Footer[sizeof(uint32_t)] = { '\0', '\r', '\0', '\n' }; // constante de footer qui est ajoutée à chaque paquet envoyé.
2023-11-01 09:19:26 -04:00
2023-11-01 12:18:27 -04:00
/* Sous-structures */
2023-09-29 12:04:08 -04:00
struct Keys {
2023-12-06 15:52:00 -05:00
bool forward = false,
backward = false,
left = false,
right = false,
jump = false,
shoot = false,
block = false;
2023-09-29 12:04:08 -04:00
};
struct States {
2023-12-06 15:52:00 -05:00
bool jumping = false,
shooting = false,
hit = false,
powerup = false,
dead = false,
still = false,
jumpshot = false,
running = false;
2023-09-29 12:04:08 -04:00
};
2023-11-01 12:18:27 -04:00
/* Structures de paquets */
2023-09-25 16:30:03 -04:00
struct Input { // cli -> srv UDP ~frame
2023-09-25 08:23:52 -04:00
Timestamp timestamp;
2023-09-29 12:04:08 -04:00
uint64_t sid = 0;
Keys keys; // 0bFBLRJS__ bit-packing de bool.
2023-09-25 08:23:52 -04:00
Vector3f direction;
2023-09-25 16:30:03 -04:00
};
2023-09-25 08:23:52 -04:00
2023-09-25 16:30:03 -04:00
struct Output { // srv -> cli UDP ~frame
2023-09-25 08:23:52 -04:00
Timestamp timestamp;
uint64_t id = 0;
Vector3f position,
2023-09-29 12:04:08 -04:00
direction;
States states; // 0bJSH_____ bit-packing de bool.
2023-09-25 16:30:03 -04:00
};
2023-09-25 08:23:52 -04:00
2023-11-01 10:13:10 -04:00
struct Sync { // srv -> cli TCP ~second - un premier sync démarre la partie.
2023-09-25 08:23:52 -04:00
Timestamp timestamp;
2023-09-25 08:53:23 -04:00
uint64_t sid = 0;
uint32_t timer = 0;
2023-09-25 08:23:52 -04:00
uint16_t ammo = 0;
2023-12-06 14:31:05 -05:00
float hp = 0;
2023-09-25 08:23:52 -04:00
Vector3f position;
2023-10-28 12:03:22 -04:00
Sync() {}
Sync(Sync* sync) : timestamp(sync->timestamp), sid(sync->sid), timer(sync->timer), ammo(sync->ammo), hp(sync->hp), position(sync->position) {}
2023-09-25 16:30:03 -04:00
};
2023-09-25 08:23:52 -04:00
2023-09-25 16:30:03 -04:00
struct TeamInfo { // cli <-> srv TCP once
2023-09-25 08:23:52 -04:00
char name[32];
uint64_t id = 0;
2023-10-28 12:03:22 -04:00
TeamInfo() {}
2023-10-28 12:13:45 -04:00
TeamInfo(TeamInfo* tem) : id(tem->id) { strcpy(tem->name, name); }
2023-09-25 16:30:03 -04:00
};
2023-09-25 08:23:52 -04:00
2023-09-25 16:30:03 -04:00
struct LoginInfo { // cli <-> srv TCP once
2023-09-25 08:23:52 -04:00
char name[32];
uint64_t sid = 0,
tid = 0;
2023-10-28 12:03:22 -04:00
LoginInfo() {}
2023-10-28 12:13:45 -04:00
LoginInfo(LoginInfo* ply): sid(ply->sid), tid(ply->tid) { strcpy(ply->name, name); }
2023-09-25 16:30:03 -04:00
};
2023-09-25 08:23:52 -04:00
2023-09-25 16:30:03 -04:00
struct PlayerInfo { // cli <-> srv TCP once
2023-09-25 08:23:52 -04:00
char name[32];
uint64_t id = 0,
tid = 0;
2023-10-28 12:03:22 -04:00
PlayerInfo() {}
2023-11-13 16:02:13 -05:00
PlayerInfo(PlayerInfo* log) : id(log->id), tid(log->tid) {
strcpy(log->name, name);
};
PlayerInfo(int id, int tid, std::string strname) : id(id), tid(tid) { memcpy((void*)strname.c_str(), name, strname.length());
}
2023-09-25 16:30:03 -04:00
};
struct GameInfo { // cli <-> srv TCP event (before game start)/ once
2023-09-25 08:23:52 -04:00
uint64_t seed;
2023-09-25 08:53:23 -04:00
uint32_t countdown;
2023-10-28 12:03:22 -04:00
uint8_t gameType; // TODD: enum.
GameInfo() {}
GameInfo(GameInfo* gam) : seed(gam->seed), countdown(gam->countdown), gameType(gam->gameType) {}
2023-09-25 16:30:03 -04:00
};
2023-09-25 08:23:52 -04:00
2023-09-25 16:30:03 -04:00
struct Chat { // cli <-> srv TCP event
2023-09-25 08:23:52 -04:00
uint64_t src_id = 0,
dest_id = 0,
dest_team_id = 0;
2023-12-06 14:31:05 -05:00
char* mess = new char[140]; // Good 'nough for twitr, good 'nough for me.
2023-10-28 12:03:22 -04:00
Chat() {}
2023-12-06 14:31:05 -05:00
Chat(Chat* cha) : src_id(cha->src_id), dest_id(cha->dest_id), dest_team_id(cha->dest_team_id) {
strcpy(mess, 140, cha->mess); }
2023-12-06 15:37:08 -05:00
~Chat() {/* delete[] mess; */}
2023-09-25 16:30:03 -04:00
};
2023-09-25 08:23:52 -04:00
struct ChunkMod {
Vector3f pos;
2023-12-02 11:05:00 -05:00
BlockType b_type, old_b_type;
};
2023-12-05 06:25:48 -05:00
struct BulletAdd {
Timestamp tstamp;
Vector3f pos, dir;
uint64_t id;
};
2023-09-25 16:30:03 -04:00
struct ErrorLog { // srv -> cli TCP event
2023-09-25 08:53:23 -04:00
char mess[140];
bool is_fatal;
2023-10-28 12:03:22 -04:00
ErrorLog() {};
2023-10-28 12:13:45 -04:00
ErrorLog(ErrorLog* err) : is_fatal(err->is_fatal) { strcpy(err->mess, mess); }
2023-09-25 16:30:03 -04:00
};
2023-11-01 12:18:27 -04:00
/* Fonctions */
2023-09-25 16:30:03 -04:00
void Serialize(Input* in, char* buf[], uint32_t* buflen); // cli
void Serialize(Output* out, char* buf[], uint32_t* buflen); // srv
void Serialize(Sync* sync, char* buf[], uint32_t* buflen); // srv
void Serialize(TeamInfo* tinfo, char* buf[], uint32_t* buflen); // cli/srv
void Serialize(LoginInfo* linfo, char* buf[], uint32_t* buflen); // cli/srv
void Serialize(PlayerInfo* pinfo, char* buf[], uint32_t* buflen); // srv
void Serialize(GameInfo* ginfo, char* buf[], uint32_t* buflen); // cli/srv
void Serialize(Chat* chat, char* buf[], uint32_t* buflen); // cli/srv
void Serialize(ChunkMod* chmod, char* buf[], uint32_t* buflen); // srv
2023-12-05 06:25:48 -05:00
void Serialize(BulletAdd* bull, char* buf[], uint32_t* buflen); // srv
2023-09-25 16:30:03 -04:00
void Serialize(ErrorLog* errlog, char* buf[], uint32_t* buflen); // srv
bool Deserialize(Input* in, char* buf, uint32_t* buflen); // srv
bool Deserialize(Output* out, char* buf, uint32_t* buflen); // cli
bool Deserialize(Sync* sync, char* buf, uint32_t* buflen); // cli
bool Deserialize(TeamInfo* tinfo, char* buf, uint32_t* buflen); // cli/srv
bool Deserialize(LoginInfo* linfo, char* buf, uint32_t* buflen); // cli/srv
bool Deserialize(PlayerInfo* pinfo, char* buf, uint32_t* buflen); // cli
bool Deserialize(GameInfo* ginfo, char* buf, uint32_t* buflen); // cli
bool Deserialize(Chat* chat, char* buf, uint32_t* buflen); // srv/cli
bool Deserialize(ChunkMod* chmod, char* buf, uint32_t* buflen); // cli
2023-12-05 06:25:48 -05:00
bool Deserialize(BulletAdd* bull, char* buf, uint32_t* buflen); // cli
bool Deserialize(ErrorLog* errlog, char* buf, uint32_t* buflen); // srv
2023-09-25 16:30:03 -04:00
2023-10-27 09:28:34 -04:00
PACKET_TYPE getType(char* buf, uint32_t buflen);
2023-10-23 16:20:52 -04:00
Packet getPack(char* buf, uint32_t *buflen);
2023-10-27 09:28:34 -04:00
Packet getPack(Buffer* buf);
bool emptyPack(Packet pck);
2023-10-24 10:43:30 -04:00
2023-10-28 12:03:22 -04:00
Packet makePack(void* ptr, PACKET_TYPE type); // Pour pouvoir faire une liste de stock a supprimer sans avoir a en faire une pour chaque type.
2023-11-01 12:18:27 -04:00
template <class T> T copyPack(Packet* pck);
2023-10-27 12:02:29 -04:00
2023-10-23 16:20:52 -04:00
template <class T> void sendPack(SOCKET sock, T* pack, char** buf, uint32_t* buflen);
2023-10-24 09:17:21 -04:00
template <class T> void sendPackTo(SOCKET sock, T* pack, char** buf, uint32_t* buflen, sockaddr_in* sockad);
2023-10-23 16:20:52 -04:00
2023-10-27 09:28:34 -04:00
template <class T> void sendPack(SOCKET sock, T* pack, Buffer* buf);
template <class T> void sendPackTo(SOCKET sock, T* pack, Buffer* buf, sockaddr_in* sockad);
2023-10-28 11:18:01 -04:00
2023-11-06 13:56:12 -05:00
std::vector<char*> recvPacks(SOCKET sock, Buffer* buf, Buffer* oufbuf = nullptr);
std::vector<char*> recvPacksFrom(SOCKET sock, Buffer* buf, sockaddr_in from, Buffer* oufbuf = nullptr);
2023-10-27 09:28:34 -04:00
2023-11-01 12:18:27 -04:00
/* Templates */
template <class T>
T copyPack(Packet* pck) { return T((T*)pck->ptr); }
2023-10-23 16:20:52 -04:00
template <class T>
void sendPack(SOCKET sock, T* pack, char** buf, uint32_t* buflen) {
netprot::Serialize(pack, buf, buflen);
2023-11-01 09:19:26 -04:00
memcpy(*buf + *buflen, Footer, sizeof(uint32_t));
*buflen += sizeof(Footer);
2023-10-23 16:20:52 -04:00
send(sock, *buf, *buflen, 0);
*buflen = BUFFER_LENGTH;
}
2023-10-23 17:49:40 -04:00
2023-10-24 09:17:21 -04:00
template <class T>
void sendPackTo(SOCKET sock, T* pack, char** buf, uint32_t* buflen, sockaddr_in* sockad) {
2023-11-01 09:19:26 -04:00
const sockaddr_in addr = *sockad;
2023-10-24 09:17:21 -04:00
netprot::Serialize(pack, buf, buflen);
2023-11-01 09:19:26 -04:00
memcpy(*buf + *buflen, Footer, sizeof(uint32_t));
*buflen += sizeof(Footer);
2023-10-24 09:17:21 -04:00
sendto(sock, *buf, *buflen, 0, (sockaddr*)&addr, sizeof(addr));
*buflen = BUFFER_LENGTH;
}
2023-10-27 09:28:34 -04:00
template <class T>
void sendPack(SOCKET sock, T* pack, Buffer* buf) {
2023-10-27 09:51:40 -04:00
netprot::Serialize(pack, &buf->ptr, &buf->len);
2023-11-01 09:19:26 -04:00
memcpy(&buf->ptr[buf->len], Footer, sizeof(uint32_t));
buf->len += sizeof(Footer);
2023-10-27 09:28:34 -04:00
send(sock, buf->ptr, buf->len, 0);
buf->rstLen();
}
2023-10-23 16:20:52 -04:00
2023-10-27 09:28:34 -04:00
template <class T>
void sendPackTo(SOCKET sock, T* pack, Buffer* buf, sockaddr_in* sockad) {
2023-11-01 09:19:26 -04:00
const sockaddr_in addr = *sockad;
2023-10-27 09:51:40 -04:00
netprot::Serialize(pack, &buf->ptr, &buf->len);
2023-11-01 09:19:26 -04:00
memcpy(&buf->ptr[buf->len], Footer, sizeof(uint32_t));
buf->len += sizeof(Footer);
2023-10-27 09:28:34 -04:00
sendto(sock, buf->ptr, buf->len, 0, (sockaddr*)&addr, sizeof(addr));
buf->rstLen();
}
2023-10-28 11:18:01 -04:00
2023-10-27 09:28:34 -04:00
};
2023-09-25 08:23:52 -04:00
#endif