diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-10-17 02:30:52 +0200 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-10-17 02:30:52 +0200 |
commit | e933ccb59c7f032d2ffc5c5f7046317a06e85e14 (patch) | |
tree | db0992ce4d337d9a0f3761fd111385a38f71af45 /c++/codec-minecraft/minecraft.h | |
parent | 37a120868976520c54a9df29d246c68c599bf917 (diff) |
codec,codec-minecraft: Adding basic foundations needed for the minecraft
protocol
Diffstat (limited to 'c++/codec-minecraft/minecraft.h')
-rw-r--r-- | c++/codec-minecraft/minecraft.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/c++/codec-minecraft/minecraft.h b/c++/codec-minecraft/minecraft.h new file mode 100644 index 0000000..670b019 --- /dev/null +++ b/c++/codec-minecraft/minecraft.h @@ -0,0 +1,116 @@ +#pragma once + +#include <forstio/core/error.h> +#include <forstio/codec/data.h> +#include <forstio/codec/stream_value.h> + +namespace saw { +namespace encode { +struct Minecraft {}; +struct VarIntTransport {}; +} + +template<typename T> +class data<T, encode::Minecraft> { +private: + ring_buffer buffer_; +public: + data() = default; + data(std::size_t size): + buffer_{size} + {} + + buffer& get_buffer(){ + return buffer_; + } +}; + +namespace mc { +namespace impl { +union minecraft_signed_four_conversion { + int32_t s; + uint32_t u; +}; + +union minecraft_signed_eight_conversion { + int64_t s; + uint64_t u; +}; + +template<typename Schema, typename FromEnc> +class minecraft_encode { + static_assert(always_false<Schema, FromEnc>, "This schema type is not being handled by the Minecraft encoding."); +}; + +template<typename FromEnc> +class minecraft_encode<schema::VarInt, FromEnc>{ + static error_or<void> encode(const data<schema::VarInt, FromEnc>& from, buffer& to){ + uint8_t encode_index = 0; + minecraft_signed_four_conversion value; + value.s = from.get(); + + /** + * VarInt max length is 5 bytes + */ + std::array<uint8_t, 5> encode_data; + + do { + uint8_t step = static_cast<uint8_t>(value.u & 0x7F); + value.u = value.u >> 7; + if(value.u != 0){ + step |= 0x80; + } + encode_data[encode_index] = step; + ++encode_index; + }while(value.u != 0); + + auto err = buffer.push(encode_data[0], encode_index); + if (!err.template is_type<err::no_error>()) { + return err; + } + + return no_error(); + } +}; + +template<typename Schema, typename FromEnc> +class minecraft_decode { + static_assert(always_false<Schema, FromEnc>, "This schema type is not being handled by the Minecraft encoding."); +}; + +template<typename FromEnc> +class minecraft_decode<schema::VarInt, FromEnc>{ + static error_or<void> decode(buffer& from, data<schema::VarInt, FromEnc>& to){ + uint8_t num_reads = 0; + + minecraft_signed_four_conversion value; + value.u = 0; + + uint8_t read{}; + do { + auto err = from.pop(read); + if( !err.template is_type<err::no_error>() ){ + return err; + } + value.u |= ((read & 0x7F) << (7*num_reads)); + ++num_reads; + if(num_reads > 5){ + return make_error<err::>(); + } + } while( (read & 0x80) != 0); + + to.set(value.s); + + return no_error(); + } +}; + +} +} + + + +namespace mc { + +} +} |