summaryrefslogtreecommitdiff
path: root/c++/codec-minecraft/minecraft.h
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2023-10-17 02:30:52 +0200
committerClaudius "keldu" Holeksa <mail@keldu.de>2023-10-17 02:30:52 +0200
commite933ccb59c7f032d2ffc5c5f7046317a06e85e14 (patch)
treedb0992ce4d337d9a0f3761fd111385a38f71af45 /c++/codec-minecraft/minecraft.h
parent37a120868976520c54a9df29d246c68c599bf917 (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.h116
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 {
+
+}
+}