diff --git a/server/src/sock/packet.cpp b/server/src/sock/packet.cpp new file mode 100644 index 0000000..20fce5c --- /dev/null +++ b/server/src/sock/packet.cpp @@ -0,0 +1,67 @@ +#include "packet.hpp" + +int sosc::Packet::Parse(const std::string& data, std::string* extra) { + const unsigned char* raw = + (const unsigned char*)data.c_str(); + auto length = data.length(); + + if(length < 2) + return PCK_MORE; + + if(raw[0] != 0xB0 || raw[1] != 0x0B) + return PCK_ERR; + + if(length < 6) + return PCK_MORE; + + uint32_t expected_length = net::ntohv(data, 2); + if(expected_length > PCK_MAX_LEN || expected_length < 8) + return PCK_ERR; + if(length < expected_length) + return PCK_MORE; + + this->id = data[6]; + std::vector region_lengths; + int region_count = data[7], ptr = 8; + for(int i = 0; i < region_count; ++i) { + if(ptr >= length) + return PCK_ERR; + + switch(raw[ptr]) { + default: + region_lengths.push_back(raw[ptr]); + break; + case 254: + if(ptr + 2 >= length) + return PCK_ERR; + + region_lengths.push_back( + net::ntohv(data, ptr + 1) + ); + break; + case 255: + if(ptr + 4 >= length) + return PCK_ERR; + + region_lengths.push_back( + net::ntohv(data, ptr + 1); + ); + break; + } + } +} + +bool sosc::Packet::Check(int region_count, ...) { + if(region_count > 0xFF) + return false; + + va_list args; + va_start(args, region_count); + for(int i = 0; i < region_count; ++i) { + uint32_t length = va_arg(args, uint32_t); + if(length != PCK_ANY && this->regions[i].length() != length) + return false; + } + + return true; +} diff --git a/server/src/sock/packet.hpp b/server/src/sock/packet.hpp new file mode 100644 index 0000000..4790ebb --- /dev/null +++ b/server/src/sock/packet.hpp @@ -0,0 +1,38 @@ +#ifndef SOSC_PACKET_H +#define SOSC_PACKET_H + +#include +#include +#include +#include "../utils/net.hpp" + +#define PCK_ANY 0 + +#define PCK_OK 0 +#define PCK_MORE 1 +#define PCK_ERR -1 + +#define PCK_MAX_LEN 0xFFFFFFFF + +namespace sosc { +class Packet { +public: + int Parse(const std::string& data, std::string* extra = nullptr); + bool Check(int region_count, ...); + + inline uint8_t GetId() const { + return this->id; + } + + inline std::string operator [] + (const std::vector::size_type index) const + { + return regions[index]; + } +private: + uint8_t id; + std::vector regions; +}; +} + +#endif diff --git a/server/src/sock/scapesock.cpp b/server/src/sock/scapesock.cpp new file mode 100644 index 0000000..7715141 --- /dev/null +++ b/server/src/sock/scapesock.cpp @@ -0,0 +1,2 @@ +#include "scapesock.hpp" + diff --git a/server/src/sock/scapesock.hpp b/server/src/sock/scapesock.hpp new file mode 100644 index 0000000..f4af399 --- /dev/null +++ b/server/src/sock/scapesock.hpp @@ -0,0 +1,23 @@ +#ifndef SOSC_SCAPESOCK_H +#define SOSC_SCAPESOCK_H + +#include "packet.hpp" +#include "tcpsock.hpp" + +namespace sosc { +class ScapeConnection { +public: + +private: + sosc::TcpClient client; +}; + +class ScapeServer { +public: + +private: + sosc::TcpServer server; +}; +} + +#endif