Skip to content

Commit

Permalink
Add initial packets, update schema version to 2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Nickid2018 committed Oct 2, 2024
1 parent 963a3b3 commit 5936d50
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 285 deletions.
2 changes: 1 addition & 1 deletion mc_dissector.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#define MCJE_FILTER "mcje"
#define MCBE_FILTER "mcbe"

#define PROTOCOL_DATA_VERSION "2.0"
#define PROTOCOL_DATA_VERSION "2.1"

#if defined(DEBUG)
#define WS_LOG(format, ...) ws_log("", LOG_LEVEL_CRITICAL, format, ##__VA_ARGS__)
Expand Down
8 changes: 7 additions & 1 deletion protocol/protocol_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <epan/conversation.h>
#include "protocol_data.h"

char *STATE_NAME[] = {"Handshake", "Play", "Server List Ping", "Login", "Transfer", "Configuration", "Invalid"};
char *STATE_NAME[] = {"Handshake", "Play", "Status", "Login", "Transfer", "Configuration", "Invalid"};

int32_t read_var_int(tvbuff_t *tvb, int32_t offset, int32_t *result) {
uint8_t read;
Expand Down Expand Up @@ -59,4 +59,10 @@ wmem_map_t *get_global_data(packet_info *pinfo) {
conversation_t *conv = find_or_create_conversation(pinfo);
mc_protocol_context *ctx = conversation_get_proto_data(conv, proto_mcje);
return ctx->global_data;
}

uint32_t je_state_to_protocol_set_state(je_state state, bool is_client) {
if (state == TRANSFER)
state = LOGIN;
return is_client ? state : 16 + state;
}
4 changes: 3 additions & 1 deletion protocol/protocol_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#define is_invalid(x) ((x) == INVALID_DATA)

typedef enum {
HANDSHAKE, PLAY, PING, LOGIN, TRANSFER, CONFIGURATION, // Normal states
HANDSHAKE, PLAY, STATUS, LOGIN, TRANSFER, CONFIGURATION, // Normal states
INVALID, NOT_COMPATIBLE, PROTOCOL_NOT_FOUND // Special states
} je_state;

Expand Down Expand Up @@ -56,6 +56,8 @@ extern char *STATE_NAME[];

wmem_map_t *get_global_data(packet_info *pinfo);

uint32_t je_state_to_protocol_set_state(je_state state, bool is_client);

int32_t read_var_int(tvbuff_t *tvb, int32_t offset, int32_t *result);

int32_t read_var_int_with_limit(tvbuff_t *tvb, int32_t offset, int32_t max_length, int32_t *result);
Expand Down
37 changes: 28 additions & 9 deletions protocol/schema/functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ DISSECT_PROTOCOL(record_entity_id) {
entity_id_record = wmem_map_new(wmem_file_scope(), g_str_hash, g_str_equal);
wmem_map_insert(get_global_data(pinfo), "#entity_id_record", entity_id_record);
}
gchar *entity_id = wmem_map_lookup(packet_saves, "entity_id");
gchar *str_type = wmem_map_lookup(packet_saves, "entity_type");
char *entity_id = wmem_map_lookup(packet_saves, "entity_id");
char *str_type = wmem_map_lookup(packet_saves, "entity_type");
wmem_map_insert(entity_id_record, entity_id, str_type);
return 0;
}
Expand All @@ -32,7 +32,7 @@ DISSECT_PROTOCOL(record_entity_id_player) {
entity_id_record = wmem_map_new(wmem_file_scope(), g_str_hash, g_str_equal);
wmem_map_insert(get_global_data(pinfo), "#entity_id_record", entity_id_record);
}
gchar *entity_id = wmem_map_lookup(packet_saves, "entity_id");
char *entity_id = wmem_map_lookup(packet_saves, "entity_id");
wmem_map_insert(entity_id_record, entity_id, "player");
return 0;
}
Expand All @@ -45,7 +45,7 @@ DISSECT_PROTOCOL(record_entity_id_experience_orb) {
entity_id_record = wmem_map_new(wmem_file_scope(), g_str_hash, g_str_equal);
wmem_map_insert(get_global_data(pinfo), "#entity_id_record", entity_id_record);
}
gchar *entity_id = wmem_map_lookup(packet_saves, "entity_id");
char *entity_id = wmem_map_lookup(packet_saves, "entity_id");
wmem_map_insert(entity_id_record, entity_id, "experience_orb");
return 0;
}
Expand All @@ -58,7 +58,7 @@ DISSECT_PROTOCOL(record_entity_id_painting) {
entity_id_record = wmem_map_new(wmem_file_scope(), g_str_hash, g_str_equal);
wmem_map_insert(get_global_data(pinfo), "#entity_id_record", entity_id_record);
}
gchar *entity_id = wmem_map_lookup(packet_saves, "entity_id");
char *entity_id = wmem_map_lookup(packet_saves, "entity_id");
wmem_map_insert(entity_id_record, entity_id, "painting");
return 0;
}
Expand All @@ -71,7 +71,7 @@ DISSECT_PROTOCOL(sync_entity_data) {
entity_id_record = wmem_map_new(wmem_file_scope(), g_str_hash, g_str_equal);
wmem_map_insert(get_global_data(pinfo), "#entity_id_record", entity_id_record);
}
gchar *entity_id = wmem_map_lookup(packet_saves, "entity_id");
char *entity_id = wmem_map_lookup(packet_saves, "entity_id");
char *type = wmem_map_lookup(entity_id_record, entity_id);
if (type != NULL) {
proto_item *item = proto_tree_add_string(tree, hf_generated, tvb, 0, 0, type);
Expand All @@ -83,15 +83,34 @@ DISSECT_PROTOCOL(sync_entity_data) {
proto_item_prepend_text(item, "Entity Type ");
return 0;
}
gchar *sync_id = wmem_map_lookup(packet_saves, "sync_id");
gchar *end;
char *sync_id = wmem_map_lookup(packet_saves, "sync_id");
char *end;
int64_t sync = strtol(sync_id, &end, 10);
uint32_t protocol_version = (uint64_t) wmem_map_lookup(get_global_data(pinfo), "protocol_version");
gchar *found_name = get_entity_sync_data_name(protocol_version, type, sync);
char *found_name = get_entity_sync_data_name(protocol_version, type, sync);
if (found_name == NULL)
found_name = "Unknown Sync Data!";
proto_item *item = proto_tree_add_string(tree, hf_generated, tvb, 0, 0, found_name);
proto_item_set_generated(item);
proto_item_prepend_text(item, "Sync Data Type ");
return 0;
}

DISSECT_PROTOCOL(display_protocol_version) {
if (!tree) return 0;
char *protocol_version_str = wmem_map_lookup(packet_saves, "protocol_version");
char *end;
uint32_t protocol_version = strtoll(protocol_version_str, &end, 10);
char **java_versions = get_mapped_java_versions(protocol_version);
proto_item *item;
if (java_versions == NULL || java_versions[0] == NULL) {
item = proto_tree_add_string(tree, hf_generated, tvb, 0, 0, "Unknown Protocol Version");
} else {
char *java_version = g_strjoinv(", ", java_versions);
g_strfreev(java_versions);
item = proto_tree_add_string(tree, hf_generated, tvb, 0, 0, java_version);
}
proto_item_set_generated(item);
proto_item_prepend_text(item, "Game Version ");
return 0;
}
2 changes: 2 additions & 0 deletions protocol/schema/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ DISSECT_PROTOCOL(record_entity_id_painting);

DISSECT_PROTOCOL(sync_entity_data);

DISSECT_PROTOCOL(display_protocol_version);

#endif //MC_DISSECTOR_FUNCTIONS_H
16 changes: 13 additions & 3 deletions protocol/schema/schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extern char *pref_protocol_data_dir;

void destroy_protocol(protocol_dissector_set *dissector_set) {
wmem_destroy_allocator(dissector_set->allocator);
wmem_free(wmem_epan_scope(), dissector_set);
dissector_set->valid = false;
}

// PROTOCOL SUB-DISSECTORS ---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1056,6 +1056,7 @@ COMPOSITE_PROTOCOL_DEFINE(func) {
FUNC_PROTOCOL(record_entity_id_player, dissect_record_entity_id_player)
FUNC_PROTOCOL(record_entity_id_experience_orb, dissect_record_entity_id_experience_orb)
FUNC_PROTOCOL(record_entity_id_painting, dissect_record_entity_id_painting)
FUNC_PROTOCOL(display_protocol_version, dissect_display_protocol_version)

if (this_dissector->dissect_protocol == NULL) {
wmem_free(allocator, this_dissector);
Expand Down Expand Up @@ -1257,6 +1258,11 @@ uint32_t map_name_to_state(char *name) {
if (strcmp(name, "configuration") == 0) return CONFIGURATION;
if (strcmp(name, "configuration_client") == 0) return CONFIGURATION;
if (strcmp(name, "configuration_server") == 0) return 16 + CONFIGURATION;
if (strcmp(name, "handshaking") == 0) return 16 + HANDSHAKE;
if (strcmp(name, "handshaking_server") == 0) return 16 + HANDSHAKE;
if (strcmp(name, "status") == 0) return STATUS;
if (strcmp(name, "status_client") == 0) return STATUS;
if (strcmp(name, "status_server") == 0) return 16 + STATUS;
return ~0u;
}

Expand All @@ -1279,8 +1285,7 @@ char *map_state_to_name(uint32_t state) {
}
}

protocol_dissector_set *create_protocol(uint32_t protocol_version) {
cJSON *protocol_source = get_protocol_source(protocol_version);
protocol_dissector_set *create_protocol_with_json(cJSON *protocol_source, uint32_t protocol_version) {
if (protocol_source == NULL) return NULL;
protocol_dissector_set *set = wmem_alloc(wmem_epan_scope(), sizeof(protocol_dissector_set));
set->protocol_version = protocol_version;
Expand All @@ -1293,11 +1298,16 @@ protocol_dissector_set *create_protocol(uint32_t protocol_version) {
set->state_to_next = wmem_map_new(set->allocator, g_direct_hash, g_direct_equal);
set->state_to_next_side = wmem_map_new(set->allocator, g_direct_hash, g_direct_equal);
set->special_mark = wmem_map_new(set->allocator, g_direct_hash, g_direct_equal);
set->valid = true;
cJSON *now = protocol_source->child;
while (now != NULL) {
uint32_t state = map_name_to_state(now->string);
if (state != ~0u) make_state_protocol(now, set, state);
now = now->next;
}
return set;
}

protocol_dissector_set *create_protocol(uint32_t protocol_version) {
return create_protocol_with_json(get_protocol_source(protocol_version), protocol_version);
}
4 changes: 4 additions & 0 deletions protocol/schema/schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ struct protocol_dissector_set_struct {
wmem_map_t *readable_names;

wmem_allocator_t *allocator;

bool valid;
};

#define DISSECT_ERROR (1 << 31)
Expand All @@ -39,6 +41,8 @@ uint32_t map_name_to_state(char *name);

char *map_state_to_name(uint32_t state);

protocol_dissector_set *create_protocol_with_json(cJSON *protocol_source, uint32_t protocol_version);

protocol_dissector_set *create_protocol(uint32_t protocol_version);

void destroy_protocol(protocol_dissector_set *dissector_set);
Expand Down
51 changes: 46 additions & 5 deletions protocol/storage/storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//

#include "storage.h"
#include "protocol/schema/schema.h"

extern char *pref_protocol_data_dir;

Expand All @@ -27,12 +26,12 @@ void ensure_cached_##name() { \

#define DATA_CACHED_UINT(name) \
wmem_map_t *cached_##name = NULL; \
void *get_cached_##name(guint version) { \
void *get_cached_##name(uint32_t version) { \
if (cached_##name == NULL) \
return NULL; \
return wmem_map_lookup(cached_##name, GUINT_TO_POINTER(version)); \
} \
void set_cached_##name(guint version, void *value) { \
void set_cached_##name(uint32_t version, void *value) { \
if (cached_##name == NULL) \
cached_##name = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal); \
wmem_map_insert(cached_##name, GUINT_TO_POINTER(version), value); \
Expand Down Expand Up @@ -68,12 +67,15 @@ JSON_CACHED(settings, "settings.json")

JSON_CACHED(versions, "java_edition/versions.json")

DATA_CACHED_UINT(protocol)

DATA_CACHED_UINT(entity_sync_data)

DATA_CACHED_STR(registry_data)

wmem_map_t *index_mappings;
wmem_map_t *protocol_mappings;
wmem_map_t *index_mappings = NULL;
wmem_map_t *protocol_mappings = NULL;
protocol_dissector_set *initial_set = NULL;

wmem_map_t *read_csv(char *path) {
wmem_map_t *csv = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
Expand Down Expand Up @@ -156,11 +158,21 @@ gboolean clean_json(gpointer key _U_, gpointer value, gpointer user_data _U_) {
return true;
}

gboolean clean_protocol(gpointer key _U_, gpointer value, gpointer user_data _U_) {
destroy_protocol(value);
return true;
}

void clear_storage() {
CLEAR_CACHED_JSON(settings)
CLEAR_CACHED_JSON(versions)
CLEAR_CACHED_DATA(entity_sync_data, clean_json)
CLEAR_CACHED_DATA(registry_data, clean_json)
CLEAR_CACHED_DATA(protocol, clean_protocol)
if (initial_set != NULL) {
destroy_protocol(initial_set);
initial_set = NULL;
}
}

char **get_mapped_java_versions(uint32_t protocol_version) {
Expand Down Expand Up @@ -337,4 +349,33 @@ bool is_compatible_protocol_data() {
ensure_cached_settings();
cJSON *version = cJSON_GetObjectItem(cached_settings, "version");
return version != NULL && g_strcmp0(version->valuestring, PROTOCOL_DATA_VERSION) == 0;
}

protocol_dissector_set *get_initial_protocol() {
if (initial_set != NULL) return initial_set;
char *file = g_build_filename(pref_protocol_data_dir, "java_edition", "initial.json", NULL);

char *content = NULL;
if (!g_file_get_contents(file, &content, NULL, NULL)) {
ws_log("MC-Dissector", LOG_LEVEL_WARNING, "Cannot read file %s", file);
g_free(file);
return NULL;
}

cJSON *json = cJSON_Parse(content);
g_free(content);
if (json == NULL)
ws_log("MC-Dissector", LOG_LEVEL_WARNING, "Cannot parse file %s: %s", file, cJSON_GetErrorPtr());
g_free(file);

initial_set = create_protocol_with_json(json, ~0u);
return initial_set;
}

protocol_dissector_set *get_protocol_set(uint32_t protocol_version) {
protocol_dissector_set *cached = get_cached_protocol(protocol_version);
if (cached != NULL) return cached;
cached = create_protocol(protocol_version);
set_cached_protocol(protocol_version, cached);
return cached;
}
5 changes: 5 additions & 0 deletions protocol/storage/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "cJSON.h"
#include "mc_dissector.h"
#include "protocol/schema/schema.h"

void clear_storage();

Expand All @@ -30,6 +31,10 @@ cJSON *get_registry(uint32_t protocol_version, char *registry);

char *get_registry_data(uint32_t protocol_version, char *registry, uint32_t index);

protocol_dissector_set *get_initial_protocol();

protocol_dissector_set *get_protocol_set(uint32_t protocol_version);

bool get_settings_flag(char *name);

bool is_compatible_protocol_data();
Expand Down
Loading

0 comments on commit 5936d50

Please sign in to comment.