Fixed some implicit type convs and improved packet api.

This commit is contained in:
WolverinDEV 2019-10-19 13:55:45 +02:00
parent df79c2acab
commit 85b321409d
5 changed files with 71 additions and 46 deletions

View File

@ -126,14 +126,14 @@ DEFINE_VARIABLE_TRANSFORM(std::string, VARTYPE_TEXT, in, in.value());
DEFINE_VARIABLE_TRANSFORM(char*, VARTYPE_TEXT, std::string((const char*) in), (char*) in.value().c_str()); DEFINE_VARIABLE_TRANSFORM(char*, VARTYPE_TEXT, std::string((const char*) in), (char*) in.value().c_str());
DEFINE_VARIABLE_TRANSFORM(const char*, VARTYPE_TEXT, std::string((const char*) in), in.value().c_str()); DEFINE_VARIABLE_TRANSFORM(const char*, VARTYPE_TEXT, std::string((const char*) in), in.value().c_str());
DEFINE_VARIABLE_TRANSFORM(int8_t, VARTYPE_INT, std::to_string(in), std::stoi(in.value())); DEFINE_VARIABLE_TRANSFORM(int8_t, VARTYPE_INT, std::to_string(in), (int8_t) std::stoi(in.value()));
DEFINE_VARIABLE_TRANSFORM(uint8_t, VARTYPE_INT, std::to_string(in), (uint8_t) std::stoul(in.value())); DEFINE_VARIABLE_TRANSFORM(uint8_t, VARTYPE_INT, std::to_string(in), (uint8_t) std::stoul(in.value()));
DEFINE_VARIABLE_TRANSFORM(int16_t, VARTYPE_INT, std::to_string(in), std::stoi(in.value())); DEFINE_VARIABLE_TRANSFORM(int16_t, VARTYPE_INT, std::to_string(in), (int16_t) std::stoi(in.value()));
DEFINE_VARIABLE_TRANSFORM(uint16_t, VARTYPE_INT, std::to_string(in), (uint16_t) std::stoul(in.value())); DEFINE_VARIABLE_TRANSFORM(uint16_t, VARTYPE_INT, std::to_string(in), (uint16_t) std::stoul(in.value()));
DEFINE_VARIABLE_TRANSFORM(int32_t, VARTYPE_INT, std::to_string(in), std::stoi(in.value())); DEFINE_VARIABLE_TRANSFORM(int32_t, VARTYPE_INT, std::to_string(in), std::stoi(in.value()));
DEFINE_VARIABLE_TRANSFORM(uint32_t, VARTYPE_INT, std::to_string(in), std::stoul(in.value())); DEFINE_VARIABLE_TRANSFORM(uint32_t, VARTYPE_INT, std::to_string(in), (uint32_t) std::stoul(in.value()));
DEFINE_VARIABLE_TRANSFORM(int64_t, VARTYPE_LONG, std::to_string(in), std::stoll(in.value())); DEFINE_VARIABLE_TRANSFORM(int64_t, VARTYPE_LONG, std::to_string(in), std::stoll(in.value()));
DEFINE_VARIABLE_TRANSFORM(uint64_t, VARTYPE_LONG, std::to_string(in), std::stoull(in.value())); DEFINE_VARIABLE_TRANSFORM(uint64_t, VARTYPE_LONG, std::to_string(in), std::stoull(in.value()));

View File

@ -39,7 +39,9 @@ namespace str_obf {
return !str[h] ? 5381 : (string_hash(str, h + 1) * 33) ^ str[h]; return !str[h] ? 5381 : (string_hash(str, h + 1) * 33) ^ str[h];
} }
#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned #ifdef WIN32
#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
#endif
constexpr std::uint32_t rng32_next(std::uint64_t& state, const std::uint32_t& inc) noexcept { constexpr std::uint32_t rng32_next(std::uint64_t& state, const std::uint32_t& inc) noexcept {
std::uint64_t oldstate = state; std::uint64_t oldstate = state;
// Advance internal state // Advance internal state
@ -49,7 +51,9 @@ namespace str_obf {
std::uint32_t rot = oldstate >> 59u; std::uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
} }
#pragma warning(default: 4146) // unary minus operator applied to unsigned type, result still unsigned #ifdef WIN32
#pragma warning(default: 4146) // unary minus operator applied to unsigned type, result still unsigned
#endif
/* we use a buffer dividable by 8 so the compiler could do crazy shit, when loading (moving) the characters */ /* we use a buffer dividable by 8 so the compiler could do crazy shit, when loading (moving) the characters */
constexpr size_t recommand_message_buffer(size_t message_size) noexcept { constexpr size_t recommand_message_buffer(size_t message_size) noexcept {

View File

@ -12,30 +12,30 @@ using namespace std;
bool CompressionHandler::compress(protocol::BasicPacket* packet, std::string &error) { bool CompressionHandler::compress(protocol::BasicPacket* packet, std::string &error) {
//// "Always allocate size + 400 bytes for the destination buffer when compressing." <= http://www.quicklz.com/manual.html //// "Always allocate size + 400 bytes for the destination buffer when compressing." <= http://www.quicklz.com/manual.html
auto length = packet->data().length(); auto packet_payload = packet->data();
auto header_length = packet->header().length() + packet->mac().length(); auto header_length = packet->length() - packet_payload.length();
size_t expected_bytes = min(length * 2, length + 400);
auto buffer = buffer::allocate_buffer(expected_bytes + header_length); size_t max_compressed_payload_size = max(min(packet_payload.length() * 2, packet_payload.length() + 400), 24UL); /* at least 12 bytes (QLZ header) */
auto target_buffer = buffer::allocate_buffer(max_compressed_payload_size + header_length);
qlz_state_compress state_compress{}; qlz_state_compress state_compress{};
size_t actualLength = qlz_compress(packet->data().data_ptr(), (char*) &buffer[header_length], packet->data().length(), &state_compress); size_t actual_length = qlz_compress(packet_payload.data_ptr(), (char*) &target_buffer[header_length], packet_payload.length(), &state_compress);
if(actualLength > buffer.length()) { if(actual_length > max_compressed_payload_size) {
logCritical(0, "Buffer overflow! Compressed data is longer than expected. (Expected: {}, Written: {}, Source length: {}, Allocated block size: {})", logCritical(0, "Buffer overflow! Compressed data is longer than expected. (Expected: {}, Written: {}, Allocated block size: {})",
expected_bytes, max_compressed_payload_size,
actualLength, actual_length,
packet->data().length(), target_buffer.capacity()
buffer.capacity()
); );
error = "overflow"; error = "overflow";
return false; return false;
} }
if(actualLength <= 0){ if(actual_length <= 0){
error = "Cloud not compress packet"; error = "Cloud not compress packet";
return false; return false;
} }
memcpy(buffer.data_ptr(), packet->buffer().data_ptr(), header_length); memcpy(target_buffer.data_ptr(), packet->buffer().data_ptr(), header_length);
packet->buffer(buffer.range(0, actualLength + header_length)); packet->buffer(target_buffer.range(0, actual_length + header_length));
return true; return true;
} }

View File

@ -30,7 +30,7 @@ namespace ts {
std::map<int, PacketTypeInfo> PacketTypeInfo::types; std::map<int, PacketTypeInfo> PacketTypeInfo::types;
PacketTypeInfo PacketTypeInfo::fromid(int id) { PacketTypeInfo PacketTypeInfo::fromid(int id) {
for(auto elm : types) for(const auto& elm : types)
if(elm.first == id) return elm.second; if(elm.first == id) return elm.second;
return PacketTypeInfo::Undefined; return PacketTypeInfo::Undefined;
} }
@ -69,11 +69,6 @@ namespace ts {
memset(this->_buffer.data_ptr(), 0, this->_buffer.length()); memset(this->_buffer.data_ptr(), 0, this->_buffer.length());
} }
BasicPacket::BasicPacket(size_t header_length, const pipes::buffer &buffer) {
this->_header_length = (uint8_t) header_length;
this->_buffer = buffer;
}
BasicPacket::~BasicPacket() {} BasicPacket::~BasicPacket() {}
void BasicPacket::append_data(const std::vector<pipes::buffer> &data) { void BasicPacket::append_data(const std::vector<pipes::buffer> &data) {
@ -123,16 +118,22 @@ namespace ts {
* @param buffer -> [mac][Header [uint16 BE packetId | [uint8](4bit flags | 4bit type)]][Data] * @param buffer -> [mac][Header [uint16 BE packetId | [uint8](4bit flags | 4bit type)]][Data]
* @return * @return
*/ */
std::unique_ptr<ServerPacket> ServerPacket::from_buffer(const pipes::buffer_view &buffer) {
auto result = make_unique<ServerPacket>();
ServerPacket::ServerPacket(const pipes::buffer_view& buffer) : BasicPacket(SERVER_HEADER_SIZE, buffer.own_buffer()) { } result->_buffer = buffer.own_buffer();
result->_header_length = SERVER_HEADER_SIZE;
return result;
}
ServerPacket::ServerPacket(uint8_t flagMask, const pipes::buffer_view& data) : BasicPacket(SERVER_HEADER_SIZE, data.length()) { ServerPacket::ServerPacket(uint8_t flagMask, const pipes::buffer_view& data) : BasicPacket(SERVER_HEADER_SIZE, data.length()) {
this->header()[2] = flagMask; this->header()[2] = flagMask;
memcpy(this->data().data_ptr(), data.data_ptr(), data.length()); memcpy(this->data().data_ptr(), data.data_ptr(), data.length());
} }
ServerPacket::ServerPacket(PacketTypeInfo type, const pipes::buffer_view& data) : BasicPacket(SERVER_HEADER_SIZE, data.length()) { ServerPacket::ServerPacket(const PacketTypeInfo& type, const pipes::buffer_view& data) : BasicPacket(SERVER_HEADER_SIZE, data.length()) {
this->header()[2] |= type.type(); this->header()[2] |= (uint8_t) type.type();
memcpy(this->data().data_ptr(), data.data_ptr(), data.length()); memcpy(this->data().data_ptr(), data.data_ptr(), data.length());
} }
@ -160,7 +161,14 @@ namespace ts {
} }
ClientPacket::ClientPacket(const pipes::buffer_view& buffer) : BasicPacket(CLIENT_HEADER_SIZE, buffer.own_buffer()) { } std::unique_ptr<ClientPacket> ClientPacket::from_buffer(const pipes::buffer_view &buffer) {
auto result = make_unique<ClientPacket>();
result->_buffer = buffer.own_buffer();
result->_header_length = CLIENT_HEADER_SIZE;
return result;
}
ClientPacket::ClientPacket(const PacketTypeInfo &type, const pipes::buffer_view& data) : BasicPacket(CLIENT_HEADER_SIZE, data.length()) { ClientPacket::ClientPacket(const PacketTypeInfo &type, const pipes::buffer_view& data) : BasicPacket(CLIENT_HEADER_SIZE, data.length()) {
this->header()[4] = type.type() & 0xF; this->header()[4] = type.type() & 0xF;
@ -188,7 +196,7 @@ namespace ts {
void ClientPacket::type(const ts::protocol::PacketTypeInfo &type) { void ClientPacket::type(const ts::protocol::PacketTypeInfo &type) {
auto& field = this->header().data_ptr<uint8_t>()[4]; auto& field = this->header().data_ptr<uint8_t>()[4];
field &= ~0xF; field &= (uint8_t) ~0xF;
field |= type.type(); field |= type.type();
} }

View File

@ -109,7 +109,7 @@ namespace ts {
}; };
namespace PacketFlag { namespace PacketFlag {
enum PacketFlag { enum PacketFlag : uint8_t {
None = 0x00, None = 0x00,
Fragmented = 0x10, //If packet type voice then its toggle the CELT Mono Fragmented = 0x10, //If packet type voice then its toggle the CELT Mono
NewProtocol = 0x20, NewProtocol = 0x20,
@ -128,7 +128,6 @@ namespace ts {
class BasicPacket { class BasicPacket {
public: public:
explicit BasicPacket(size_t header_length, size_t data_length); explicit BasicPacket(size_t header_length, size_t data_length);
explicit BasicPacket(size_t header_length, const pipes::buffer& buffer);
virtual ~BasicPacket(); virtual ~BasicPacket();
BasicPacket(const BasicPacket&) = delete; BasicPacket(const BasicPacket&) = delete;
@ -141,7 +140,7 @@ namespace ts {
/* packet flag info */ /* packet flag info */
inline bool has_flag(PacketFlag::PacketFlag flag) const { return this->_flags_type_byte() & flag; } inline bool has_flag(PacketFlag::PacketFlag flag) const { return this->_flags_type_byte() & flag; }
inline uint8_t flag_mask() const { return this->_flags_type_byte(); }; inline uint8_t flag_mask() const { return this->_flags_type_byte(); };
std::string flags() const; [[nodiscard]] std::string flags() const;
/* manipulate flags */ /* manipulate flags */
inline void set_flags(PacketFlag::PacketFlags flags) { inline void set_flags(PacketFlag::PacketFlags flags) {
@ -154,7 +153,7 @@ namespace ts {
if(state) if(state)
this->_flags_type_byte() |= flag; this->_flags_type_byte() |= flag;
else else
this->_flags_type_byte() &= ~flag; this->_flags_type_byte() &= (uint8_t) ~flag;
} }
virtual void applyPacketId(PacketIdManager &); virtual void applyPacketId(PacketIdManager &);
@ -192,13 +191,13 @@ namespace ts {
memcpy(this->_buffer.data_ptr(), _new.data_ptr(), MAC_SIZE); memcpy(this->_buffer.data_ptr(), _new.data_ptr(), MAC_SIZE);
} }
inline bool isEncrypted() const { return this->memory_state.encrypted; } [[nodiscard]] inline bool isEncrypted() const { return this->memory_state.encrypted; }
inline void setEncrypted(bool flag){ this->memory_state.encrypted = flag; } inline void setEncrypted(bool flag){ this->memory_state.encrypted = flag; }
inline bool isCompressed() const { return this->memory_state.compressed; } [[nodiscard]] inline bool isCompressed() const { return this->memory_state.compressed; }
inline void setCompressed(bool flag){ this->memory_state.compressed = flag; } inline void setCompressed(bool flag){ this->memory_state.compressed = flag; }
inline bool isFragmentEntry() const { return this->memory_state.fragment_entry; } [[nodiscard]] inline bool isFragmentEntry() const { return this->memory_state.fragment_entry; }
inline void setFragmentedEntry(bool flag){ this->memory_state.fragment_entry = flag; } inline void setFragmentedEntry(bool flag){ this->memory_state.fragment_entry = flag; }
Command asCommand(); Command asCommand();
@ -225,8 +224,13 @@ namespace ts {
} memory_state; } memory_state;
pipes::buffer buffer() { return this->_buffer; } pipes::buffer buffer() { return this->_buffer; }
void buffer(pipes::buffer buffer) { this->_buffer = std::move(buffer); } void buffer(pipes::buffer buffer) {
assert(buffer.length() >= this->_header_length + MAC_SIZE);
this->_buffer = std::move(buffer);
}
protected: protected:
BasicPacket() = default;
virtual const uint8_t& _flags_type_byte() const = 0; virtual const uint8_t& _flags_type_byte() const = 0;
virtual uint8_t& _flags_type_byte() = 0; virtual uint8_t& _flags_type_byte() = 0;
@ -243,12 +247,14 @@ namespace ts {
* Packet from the client * Packet from the client
*/ */
class ClientPacket : public BasicPacket { class ClientPacket : public BasicPacket {
friend std::unique_ptr<ClientPacket> std::make_unique<ClientPacket>();
public: public:
static constexpr size_t META_MAC_SIZE = 8; static constexpr size_t META_MAC_SIZE = 8;
static constexpr size_t META_HEADER_SIZE = CLIENT_HEADER_SIZE; static constexpr size_t META_HEADER_SIZE = CLIENT_HEADER_SIZE;
static constexpr size_t META_SIZE = META_MAC_SIZE + META_HEADER_SIZE; static constexpr size_t META_SIZE = META_MAC_SIZE + META_HEADER_SIZE;
explicit ClientPacket(const pipes::buffer_view& buffer); [[nodiscard]] static std::unique_ptr<ClientPacket> from_buffer(const pipes::buffer_view& buffer);
ClientPacket(const PacketTypeInfo& type, const pipes::buffer_view& data); ClientPacket(const PacketTypeInfo& type, const pipes::buffer_view& data);
ClientPacket(const PacketTypeInfo& type, uint8_t flag_mask, const pipes::buffer_view& data); ClientPacket(const PacketTypeInfo& type, uint8_t flag_mask, const pipes::buffer_view& data);
~ClientPacket() override; ~ClientPacket() override;
@ -267,6 +273,8 @@ namespace ts {
void type(const PacketTypeInfo&); void type(const PacketTypeInfo&);
private: private:
ClientPacket() = default;
const uint8_t &_flags_type_byte() const override { const uint8_t &_flags_type_byte() const override {
return this->header().data_ptr<uint8_t>()[4]; return this->header().data_ptr<uint8_t>()[4];
} }
@ -282,26 +290,31 @@ namespace ts {
* Packet from the server * Packet from the server
*/ */
class ServerPacket : public BasicPacket { class ServerPacket : public BasicPacket {
friend std::unique_ptr<ServerPacket> std::make_unique<ServerPacket>();
public: public:
static constexpr size_t META_MAC_SIZE = 8; static constexpr size_t META_MAC_SIZE = 8;
static constexpr size_t META_HEADER_SIZE = SERVER_HEADER_SIZE; static constexpr size_t META_HEADER_SIZE = SERVER_HEADER_SIZE;
static constexpr size_t META_SIZE = META_MAC_SIZE + META_HEADER_SIZE; static constexpr size_t META_SIZE = META_MAC_SIZE + META_HEADER_SIZE;
explicit ServerPacket(const pipes::buffer_view& buffer); [[nodiscard]] static std::unique_ptr<ServerPacket> from_buffer(const pipes::buffer_view& buffer);
ServerPacket(uint8_t flagMask, const pipes::buffer_view& data); ServerPacket(uint8_t flagMask, const pipes::buffer_view& data);
ServerPacket(PacketTypeInfo type, const pipes::buffer_view& data); ServerPacket(const PacketTypeInfo& type, const pipes::buffer_view& data);
ServerPacket(PacketTypeInfo type, size_t /* data length */); ServerPacket(PacketTypeInfo type, size_t /* data length */);
~ServerPacket() override; ~ServerPacket() override;
ServerPacket(const ServerPacket&) = delete; ServerPacket(const ServerPacket&) = delete;
ServerPacket(ServerPacket&&) = delete; ServerPacket(ServerPacket&&) = delete;
uint16_t packetId() const override; [[nodiscard]] uint16_t packetId() const override;
uint16_t generationId() const override; [[nodiscard]] uint16_t generationId() const override;
void generationId(uint16_t generation) { this->genId = generation; } void generationId(uint16_t generation) { this->genId = generation; }
PacketTypeInfo type() const override; [[nodiscard]] PacketTypeInfo type() const override;
private: private:
const uint8_t &_flags_type_byte() const override { ServerPacket() = default;
[[nodiscard]] const uint8_t &_flags_type_byte() const override {
return this->header().data_ptr<uint8_t>()[2]; return this->header().data_ptr<uint8_t>()[2];
} }