Skip to content

Commit

Permalink
Fixed simulation events decoding
Browse files Browse the repository at this point in the history
Replaced broken `simulation_event_type_count` patch with `decode_event_from_buffer` implementation and hook
  • Loading branch information
twist84 committed Oct 15, 2024
1 parent 37a60b9 commit 95a36ff
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 15 deletions.
4 changes: 2 additions & 2 deletions game/source/memory/data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ enum
};

#define DATUM_INDEX_TO_ABSOLUTE_INDEX(VALUE) ((VALUE) & 0xFFFF)
#define DATUM_INDEX_TO_IDENTIFIER(VALUE) ((VALUE) >> 16)
#define BUILD_DATUM_INDEX(IDENTIFIER, ABSOLUTE_INDEX) (ABSOLUTE_INDEX | (IDENTIFIER << 16))
#define DATUM_INDEX_TO_IDENTIFIER(VALUE) ((VALUE) >> 16)
#define BUILD_DATUM_INDEX(IDENTIFIER, ABSOLUTE_INDEX) ((IDENTIFIER << 16) | ABSOLUTE_INDEX)
#define DATA_ARRAY_GET_DATA(DATA) ((DATA)->data)

struct s_datum_header
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct c_simulation_event_definition
virtual void write_description_to_string(c_replication_outgoing_event const*, s_simulation_view_telemetry_data const*, real, long, char*) = 0;
virtual long* maximum_required_bits(long* out_bits, c_replication_outgoing_event*, long) = 0; // unsure of the name, pc only?
virtual void event_payload_encode(long, void const*, c_bitstream*) = 0;
virtual bool event_payload_decode(long, void*, c_bitstream*) = 0;
virtual bool event_payload_decode(long, void*, c_bitstream*, bool a4) = 0;
virtual void prepare_event_data_for_gameworld(long, void*) = 0;
virtual bool apply_game_event(long, long const*, long, void const*) = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void c_simulation_hs_script_wake_event_definition::event_payload_encode(long pay
packet->write_string("script-name", definition->script_name, 32);
}

bool c_simulation_hs_script_wake_event_definition::event_payload_decode(long payload_size, void* payload, c_bitstream* packet)
bool c_simulation_hs_script_wake_event_definition::event_payload_decode(long payload_size, void* payload, c_bitstream* packet, bool a4)
{
ASSERT(payload_size == c_simulation_hs_script_wake_event_definition::payload_size());
ASSERT(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct c_simulation_hs_script_wake_event_definition :
virtual void write_description_to_string(c_replication_outgoing_event const* a1, s_simulation_view_telemetry_data const* a2, real a3, long buffer_count, char* buffer) override;
virtual long* maximum_required_bits(long* out_bits, c_replication_outgoing_event*, long) override;
virtual void event_payload_encode(long payload_size, void const* payload, c_bitstream* packet) override;
virtual bool event_payload_decode(long payload_size, void* payload, c_bitstream* packet) override;
virtual bool event_payload_decode(long payload_size, void* payload, c_bitstream* packet, bool a4) override;
virtual void prepare_event_data_for_gameworld(long, void*) override;
virtual bool apply_game_event(long entity_reference_count, long const*, long payload_size, void const* payload) override;

Expand Down
34 changes: 31 additions & 3 deletions game/source/simulation/simulation_gamestate_entities.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "simulation/simulation_gamestate_entities.hpp"

#include "main/main_game.hpp"
#include "memory/bitstream.hpp"
#include "memory/thread_local.hpp"

//.text:00471BC0 ; void __cdecl simulation_gamestate_entities_build_clear_flags(s_simulation_queue_gamestate_clear_data*)
Expand Down Expand Up @@ -69,9 +70,36 @@ void __cdecl simulation_gamestate_entity_set_object_index(long simulation_object
}

//.text:00472020 ; void __cdecl simulation_gamestate_entity_set_simulation_entity_index(long, long)
//.text:00472050 ; void __cdecl simulation_object_glue_index_decode(c_bitstream*, long*)
//.text:00472080 ; void __cdecl simulation_object_glue_index_encode(c_bitstream*, long)
//.text:00472120 ; bool __cdecl simulation_gamestate_index_valid(long)

void __cdecl simulation_object_glue_index_decode(c_bitstream* bitstream, long* gamestate_index_out)
{
//INVOKE(0x00472050, simulation_object_glue_index_decode, bitstream, gamestate_index_out);

ASSERT(bitstream);
ASSERT(gamestate_index_out);

*gamestate_index_out = BUILD_DATUM_INDEX(bitstream->read_integer("gamestgate-index-id", 16), bitstream->read_integer("gamestate-index-absolute", 11));
}

void __cdecl simulation_object_glue_index_encode(c_bitstream* bitstream, long gamestate_index)
{
//INVOKE(0x00472080, simulation_object_glue_index_encode, bitstream, gamestate_index);

ASSERT(bitstream);
ASSERT(gamestate_index);

bitstream->write_integer("gamestgate-index-id", DATUM_INDEX_TO_IDENTIFIER(gamestate_index), 16);
bitstream->write_integer("gamestate-index-absolute", DATUM_INDEX_TO_ABSOLUTE_INDEX(gamestate_index), 11);
}

bool __cdecl simulation_gamestate_index_valid(long gamestate_index)
{
//return INVOKE(0x00472120, simulation_gamestate_index_valid, gamestate_index);

TLS_DATA_GET_VALUE_REFERENCE(simulation_gamestate_entity_data);

return gamestate_index != NONE && datum_try_and_get(*simulation_gamestate_entity_data, gamestate_index) != NULL;
}

long __cdecl simulation_entity_create(e_simulation_entity_type entity_type, long object_index, long simulation_object_glue_index)
{
Expand Down
4 changes: 4 additions & 0 deletions game/source/simulation/simulation_gamestate_entities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct s_simulation_gamestate_entity :
static_assert(sizeof(s_simulation_gamestate_entity) == 0x10);

enum e_simulation_entity_type;
struct c_bitstream;

extern void __cdecl simulation_gamestate_entities_dispose();
extern void __cdecl simulation_gamestate_entities_dispose_from_old_map();
Expand All @@ -22,6 +23,9 @@ extern void __cdecl simulation_gamestate_entities_initialize_for_new_map();
extern void __cdecl simulation_object_glue_delete(long object_index);
extern long __cdecl simulation_object_glue_get_simulation_entity_index(long object_index);
extern void __cdecl simulation_gamestate_entity_set_object_index(long simulation_object_glue_index, long object_index);
extern void __cdecl simulation_object_glue_index_decode(c_bitstream* bitstream, long* gamestate_index_out);
extern void __cdecl simulation_object_glue_index_encode(c_bitstream* bitstream, long gamestate_index);
extern bool __cdecl simulation_gamestate_index_valid(long gamestate_index);
extern long __cdecl simulation_entity_create(e_simulation_entity_type entity_type, long object_index, long simulation_object_glue_index);
extern void __cdecl simulation_entity_delete(long simulation_entity_index, long object_index, long simulation_object_glue_index);
extern void __cdecl simulation_entity_force_update(long simulation_entity_index, long object_index, c_flags<long, qword, 64>& flags);
Expand Down
81 changes: 77 additions & 4 deletions game/source/simulation/simulation_queue_events.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,83 @@
#include "simulation/simulation_queue_events.hpp"

#include "memory/module.hpp"
#include "cseries/cseries_events.hpp"
#include "game_interface/simulation_game_events.hpp"
#include "memory/bitstream.hpp"
#include "memory/module.hpp"
#include "simulation/simulation.hpp"
#include "simulation/simulation_gamestate_entities.hpp"
#include "simulation/simulation_type_collection.hpp"

HOOK_DECLARE(0x004A8780, decode_event_from_buffer);

//#define ENABLE_ADDITION_ENTITY_TYPES

bool __cdecl decode_event_from_buffer(byte* data, long data_size, s_simulation_queue_decoded_event_data* decoded_event_data)
{
//return INVOKE(0x004A8780, decode_event_from_buffer, data, data_size, decoded_event_data);

c_bitstream packet(data, data_size);
packet.begin_reading();

decoded_event_data->event_type = packet.read_enum<e_simulation_event_type, 6>("event-type");
decoded_event_data->reference_count = packet.read_integer("reference-count", 2);

#if defined(ENABLE_ADDITION_ENTITY_TYPES)
if (decoded_event_data->event_type > k_simulation_event_type_count_plus_additional)
#else
if (decoded_event_data->event_type > k_simulation_event_type_count)
#endif
{
generate_event(_event_level_error, "networking:simulation:queue:events: failed to decode event (bad event type %d)",
decoded_event_data->event_type);

return false;
}

if (decoded_event_data->reference_count > k_max_decoded_event_data_reference_count)
{
generate_event(_event_level_error, "networking:simulation:queue:events: crazy reference count during decode %d",
decoded_event_data->reference_count);

return false;
}

for (long reference_index = 0; reference_index < decoded_event_data->reference_count; reference_index++)
{
if (packet.read_bool("gamestate-index-exists"))
simulation_object_glue_index_decode(&packet, &decoded_event_data->references[reference_index]);
else
decoded_event_data->references[reference_index] = NONE;
}

c_simulation_event_definition* event_definition = simulation_get_type_collection()->get_event_definition(decoded_event_data->event_type);
decoded_event_data->payload_size = event_definition->payload_size();

if (decoded_event_data->payload_size > k_max_decoded_event_data_payload_size)
{
generate_event(_event_level_error, "networking:simulation:queue:events: invalid event payload size %d",
decoded_event_data->payload_size);

return false;
}

if (decoded_event_data->payload_size > 0 && !event_definition->event_payload_decode(decoded_event_data->payload_size, decoded_event_data->payload, &packet, false))
{
generate_event(_event_level_warning, "networking:simulation:queue:events: failed to decode event payload type %d",
decoded_event_data->event_type);
}

bool result = !packet.error_occurred();
packet.finish_reading();

return result;
}

t_value_type<byte> const simulation_event_type_count = { .value = k_simulation_event_type_count_plus_additional };
DATA_PATCH_DECLARE(0x004A87E0, simulation_event_type_count, simulation_event_type_count.bytes);
bool __cdecl encode_event_to_buffer(byte* buffer, long buffer_size, long* size_out, e_simulation_event_type event_type, long reference_count, long const* references, void const* payload, long payload_size)
{
return INVOKE(0x004A88B0, encode_event_to_buffer, buffer, buffer_size, size_out, event_type, reference_count, references, payload, payload_size);
}

//.text:004A8780 ; bool __cdecl decode_event_from_buffer(byte*, long, s_simulation_queue_decoded_event_data*)
//.text:004A8A60 ; void __cdecl simulation_queue_event_apply(c_simulation_queue_element const*)
//.text:004A8AE0 ; void __cdecl simulation_queue_event_insert(e_simulation_event_type, long, long const*, long, void*)

16 changes: 13 additions & 3 deletions game/source/simulation/simulation_queue_events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@

#include "cseries/cseries.hpp"

enum
{
k_max_decoded_event_data_reference_count = 2,
k_max_decoded_event_data_payload_size = 1024
};

enum e_simulation_event_type;
struct s_simulation_queue_decoded_event_data
{
long event_type;
e_simulation_event_type event_type;

long reference_count;
long references[2];
long references[k_max_decoded_event_data_reference_count];

byte payload[0x400];
byte payload[k_max_decoded_event_data_payload_size];
long payload_size;
};
static_assert(sizeof(s_simulation_queue_decoded_event_data) == 0x414);

extern bool __cdecl decode_event_from_buffer(byte* data, long data_size, s_simulation_queue_decoded_event_data* decoded_event_data);
extern bool __cdecl encode_event_to_buffer(byte* buffer, long buffer_size, long* size_out, e_simulation_event_type event_type, long reference_count, long const* references, void const* payload, long payload_size);

0 comments on commit 95a36ff

Please sign in to comment.