diff --git a/src/network/generate_protocol.py b/src/network/generate_protocol.py new file mode 100644 index 0000000..3dc8285 --- /dev/null +++ b/src/network/generate_protocol.py @@ -0,0 +1,75 @@ +import hjson + +text = '' + +def add_text(fmt, *args): + global text + text += (fmt + '\n').format(*args) + +def resolve_type(aliases, type): + if type in aliases: + return aliases[type] + return type + +def print_states(states): + add_text(' enum class ProtocolState : int32_t') + add_text(' {{') + for state, value in states.items(): + add_text(' {} = {},', state, value) + add_text(' }};') + +def get_rw_func(primitiveType, aliasedType, read): + prefix = 'Read' if read else 'Write' + if aliasedType == 'varint': + return '{}VarInt<{}>'.format(prefix, primitiveType) + elif aliasedType == 'string': + return '{}String'.format(prefix) + else: + return 'Read<{}>'.format(aliasedType) + +def print_messages(list, aliases, primitives, serverbound): + global text + for message_name, message in list.items(): + add_text(' struct {}Message', message_name) + add_text(' {{') + add_text(' static constexpr int32_t PacketId = {};', message['id']) + add_text(' static constexpr bool ServerBound = {};', 'true' if serverbound else 'false') + add_text(' static constexpr ProtocolState PacketState = ProtocolState::{};', message['state']) + add_text('') + if serverbound: + add_text(' {}Message(PacketReader& reader)', message_name) + add_text(' {{') + for name, type in message['vars'].items(): + add_text(' {} = reader.{}();', name, get_rw_func(resolve_type(primitives, type), resolve_type(aliases, type), True)) + add_text(' }}') + add_text('') + + for name, type in message['vars'].items(): + add_text(' {} {};', resolve_type(primitives, type), name) + + add_text(' }};') + +def print_protocol(): + with open('protocol.hjson') as message_file: + message_scheme = hjson.load(message_file) + + print_states(message_scheme['states']) + + add_text('') + + print_messages( + message_scheme['messages']['serverbound'], + message_scheme['types']['aliases'], + message_scheme['types']['primitives'], + True) + +add_text('#pragma once') +add_text('') +add_text('#include ') +add_text('') +add_text('namespace Feather::Messages') +add_text('{{') +print_protocol() +add_text('}}') + +print(text) \ No newline at end of file diff --git a/src/network/protocol.hjson b/src/network/protocol.hjson new file mode 100644 index 0000000..35b59a2 --- /dev/null +++ b/src/network/protocol.hjson @@ -0,0 +1,46 @@ +{ + types : + { + aliases : + { + ProtocolState : varint + } + + primitives : + { + varint : int32_t + } + } + + states : + { + Handholding : -1 + Play : 0 + Status : 1 + Login : 2 + } + + messages : + { + serverbound : + { + Handshake : + { + id : 0 + state : Handholding + vars : + { + protocolVersion : varint + serverIP : string + port : uint16_t + intention : ProtocolState + } + } + } + + clientbound : + { + + } + } +} \ No newline at end of file