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(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(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(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(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];
}
#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 {
std::uint64_t oldstate = state;
// Advance internal state
@ -49,7 +51,9 @@ namespace str_obf {
std::uint32_t rot = oldstate >> 59u;
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 */
constexpr size_t recommand_message_buffer(size_t message_size) noexcept {
@ -198,4 +202,4 @@ constexpr auto variable_name = ::str_obf::encode(string, str_obf::generate_key<_
(([]{ \
static strobf_define(_, message); \
return strobf_val(_); \
})())
})())

View File

@ -12,30 +12,30 @@ using namespace std;
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
auto length = packet->data().length();
auto header_length = packet->header().length() + packet->mac().length();
size_t expected_bytes = min(length * 2, length + 400);
auto buffer = buffer::allocate_buffer(expected_bytes + header_length);
auto packet_payload = packet->data();
auto header_length = packet->length() - packet_payload.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{};
size_t actualLength = qlz_compress(packet->data().data_ptr(), (char*) &buffer[header_length], packet->data().length(), &state_compress);
if(actualLength > buffer.length()) {
logCritical(0, "Buffer overflow! Compressed data is longer than expected. (Expected: {}, Written: {}, Source length: {}, Allocated block size: {})",
expected_bytes,
actualLength,
packet->data().length(),
buffer.capacity()
size_t actual_length = qlz_compress(packet_payload.data_ptr(), (char*) &target_buffer[header_length], packet_payload.length(), &state_compress);
if(actual_length > max_compressed_payload_size) {
logCritical(0, "Buffer overflow! Compressed data is longer than expected. (Expected: {}, Written: {}, Allocated block size: {})",
max_compressed_payload_size,
actual_length,
target_buffer.capacity()
);
error = "overflow";
return false;
}
if(actualLength <= 0){
if(actual_length <= 0){
error = "Cloud not compress packet";
return false;
}
memcpy(buffer.data_ptr(), packet->buffer().data_ptr(), header_length);
packet->buffer(buffer.range(0, actualLength + header_length));
memcpy(target_buffer.data_ptr(), packet->buffer().data_ptr(), header_length);
packet->buffer(target_buffer.range(0, actual_length + header_length));
return true;
}

View File

@ -30,7 +30,7 @@ namespace ts {
std::map<int, PacketTypeInfo> PacketTypeInfo::types;
PacketTypeInfo PacketTypeInfo::fromid(int id) {
for(auto elm : types)
for(const auto& elm : types)
if(elm.first == id) return elm.second;
return PacketTypeInfo::Undefined;
}
@ -69,11 +69,6 @@ namespace ts {
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() {}
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]
* @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()) {
this->header()[2] = flagMask;
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()) {
this->header()[2] |= type.type();
ServerPacket::ServerPacket(const PacketTypeInfo& type, const pipes::buffer_view& data) : BasicPacket(SERVER_HEADER_SIZE, data.length()) {
this->header()[2] |= (uint8_t) type.type();
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()) {
this->header()[4] = type.type() & 0xF;
@ -188,7 +196,7 @@ namespace ts {
void ClientPacket::type(const ts::protocol::PacketTypeInfo &type) {
auto& field = this->header().data_ptr<uint8_t>()[4];
field &= ~0xF;
field &= (uint8_t) ~0xF;
field |= type.type();
}

View File

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