diff --git a/src/client/component/demo_recording.cpp b/src/client/component/demo_recording.cpp index 66c1e6d..38d340f 100644 --- a/src/client/component/demo_recording.cpp +++ b/src/client/component/demo_recording.cpp @@ -47,7 +47,7 @@ namespace // demo class void shutdown_watcher(); void process_network_data(auto old_connstate, auto new_connstate, std::span network_data); - void process_predicted_data(); + void process_predicted_data(auto old_connstate, auto new_connstate); private: [[nodiscard]] bool is_auto_recording() const; @@ -419,38 +419,18 @@ namespace // demo class } } - void demo_recording_t::process_predicted_data() + void demo_recording_t::process_predicted_data(auto old_connstate, auto new_connstate) { + if (old_connstate < game::CA_ACTIVE || new_connstate < game::CA_ACTIVE) + { + return; + } + process_helo_pilot_turret_fire(); if (is_recording()) { - // only one predicted data packet is needed per (1000 / sv_fps) msec - // the best way to limit the amount of predicted data is to attempt to predict the next playerState_t::commandTime - // because during demo playback the playerState_t::commandTime determines which predicted data is used - - const auto& cl = *game::mp::cl; - const auto cmd_number = static_cast(cl.cmdNumber); - const auto pred_svr_time_delta = cl.cmds[cmd_number % std::size(cl.cmds)].serverTime - - cl.cmds[(cmd_number - 1) % std::size(cl.cmds)].serverTime; - - const auto pred_svr_time = cl.cgamePredictedDataServerTime; - const auto svr_time_delta = std::clamp(cl.snap.serverTime - cl.oldSnapServerTime, 50, 100); - - const auto cur_cmd_time = cl.snap.ps.commandTime; - const auto next_cmd_time = cur_cmd_time + svr_time_delta; - const auto threshold = (3 * pred_svr_time_delta) / 2; - - if (pred_svr_time + threshold >= next_cmd_time && next_cmd_time + threshold >= pred_svr_time) - { - times_.predicted_data_time = cl.serverTime; - write_predicted_data(user_file_); - } - else if (cl.serverTime >= times_.predicted_data_time + svr_time_delta - 5) - { - times_.predicted_data_time = cl.serverTime; - write_predicted_data(user_file_); - } + write_predicted_data(user_file_); } if (is_auto_recording()) @@ -494,21 +474,11 @@ namespace // hooks return; } + demo.process_predicted_data(old_connstate, new_connstate); demo.process_network_data(old_connstate, new_connstate, std::span(reinterpret_cast(msg.data), msg.cursize)); } - void capture_predicted_data(game::msg_t& msg, std::int32_t value, std::uint32_t bits) - { - if (!demo_playback::playing()) - { - demo.process_predicted_data(); - } - - // call MSG_WriteBits that this hook replaces - game::MSG_WriteBits(&msg, value, bits); - } - void request_non_delta_data(game::msg_t& msg, std::int32_t value, std::uint32_t bits) { if (!demo_playback::playing() && demo.non_delta_data_requested()) @@ -715,9 +685,6 @@ namespace demo_recording // capture incoming packets CL_ParseServerMessage_hook.create(game::CL_ParseServerMessage, capture_data); - // capture client predicted data (in CL_WritePacket) - utils::hook::call(0x1402C21B9, capture_predicted_data); - // request the server for no delta data (in CL_WritePacket) utils::hook::call(0x1402C2026, request_non_delta_data); diff --git a/src/client/component/demo_utils.cpp b/src/client/component/demo_utils.cpp index dc3fe63..ef92fb2 100644 --- a/src/client/component/demo_utils.cpp +++ b/src/client/component/demo_utils.cpp @@ -467,35 +467,35 @@ namespace demo_utils write_network_data_(output, network_data); } - void write_predicted_player_data_(auto& output, const game::ClientArchiveData& cad, - const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id) + void write_predicted_player_data_(auto& output, const game::mp::playerState_t& ps, + std::uint8_t cad_index, predicted_data_id id) { write_id_and_size(output, 50, demo_data_id::predicted_data); output.write(reinterpret_cast(&id), 1); output.write(reinterpret_cast(&cad_index), 1); - output.write(reinterpret_cast(&cad.serverTime), 4); - output.write(reinterpret_cast(&cad.origin[0]), 12); - output.write(reinterpret_cast(&cad.velocity[0]), 12); - output.write(reinterpret_cast(&cad.bobCycle), 4); - output.write(reinterpret_cast(&cad.movementDir), 4); - output.write(reinterpret_cast(&viewangles[0]), 12); + output.write(reinterpret_cast(&ps.commandTime), 4); + output.write(reinterpret_cast(&ps.origin[0]), 12); + output.write(reinterpret_cast(&ps.velocity[0]), 12); + output.write(reinterpret_cast(&ps.bobCycle), 4); + output.write(reinterpret_cast(&ps.movementDir), 4); + output.write(reinterpret_cast(&ps.viewangles[0]), 12); } - void write_predicted_player_data(buffer_t& output, const game::ClientArchiveData& cad, - const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id) + void write_predicted_player_data(buffer_t& output, const game::mp::playerState_t& ps, + std::uint8_t cad_index, predicted_data_id id) { - write_predicted_player_data_(output, cad, viewangles, cad_index, id); + write_predicted_player_data_(output, ps, cad_index, id); } - void write_predicted_player_data(std::ofstream& output, const game::ClientArchiveData& cad, - const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id) + void write_predicted_player_data(std::ofstream& output, const game::mp::playerState_t& ps, + std::uint8_t cad_index, predicted_data_id id) { - write_predicted_player_data_(output, cad, viewangles, cad_index, id); + write_predicted_player_data_(output, ps, cad_index, id); } - void write_predicted_vehicle_data_(auto& output, const game::ClientArchiveData& cad, - const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id) + void write_predicted_vehicle_data_(auto& output, const game::mp::playerState_t& ps, + std::uint8_t cad_index, predicted_data_id id) { const auto size = (id != predicted_data_id::vehicle_gryphon) ? 58 : 82; @@ -503,10 +503,10 @@ namespace demo_utils output.write(reinterpret_cast(&id), 1); output.write(reinterpret_cast(&cad_index), 1); - const auto& vehicle = cad.playerVehStateClientArchive; - output.write(reinterpret_cast(&cad.serverTime), 4); - output.write(reinterpret_cast(&cad.origin[0]), 12); - output.write(reinterpret_cast(&viewangles[0]), 12); + const auto& vehicle = ps.vehicleState; + output.write(reinterpret_cast(&ps.commandTime), 4); + output.write(reinterpret_cast(&ps.origin[0]), 12); + output.write(reinterpret_cast(&ps.viewangles[0]), 12); output.write(reinterpret_cast(&vehicle.flags), 4); output.write(reinterpret_cast(&vehicle.origin[0]), 12); output.write(reinterpret_cast(&vehicle.angles[0]), 12); @@ -520,16 +520,16 @@ namespace demo_utils assert(!vehicle.splineId); } - void write_predicted_vehicle_data(buffer_t& output, const game::ClientArchiveData& cad, - const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id) + void write_predicted_vehicle_data(buffer_t& output, const game::mp::playerState_t& ps, + std::uint8_t cad_index, predicted_data_id id) { - write_predicted_vehicle_data_(output, cad, viewangles, cad_index, id); + write_predicted_vehicle_data_(output, ps, cad_index, id); } - void write_predicted_vehicle_data(std::ofstream& output, const game::ClientArchiveData& cad, - const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id) + void write_predicted_vehicle_data(std::ofstream& output, const game::mp::playerState_t& ps, + std::uint8_t cad_index, predicted_data_id id) { - write_predicted_vehicle_data_(output, cad, viewangles, cad_index, id); + write_predicted_vehicle_data_(output, ps, cad_index, id); } void write_helo_pilot_turret_fire_(auto& output, std::uint8_t fire_count) @@ -675,23 +675,23 @@ namespace demo_utils void write_predicted_data_(auto& output) { - const auto& ps = game::mp::cg->ps; - const auto& viewangles = game::mp::cg->refdefViewAngles; - const auto cad_index = static_cast(game::mp::cl->clientArchiveIndex - 1); - const auto cad_array = std::span(game::mp::cl->clientArchive); + auto& cl = *game::mp::cl; + auto& ps = cl.snap.ps; + const auto& cg = *game::mp::cg; - if (const auto& cad = cad_array[cad_index]; cad.serverTime) + ps.viewangles[0] = cg.refdefViewAngles[0]; + ps.viewangles[1] = cg.refdefViewAngles[1]; + ps.viewangles[2] = cg.refdefViewAngles[2]; + + const auto vehicle_in_use = (ps.vehicleState.entity && ps.vehicleState.entity != 2047); + if (!vehicle_in_use) { - const auto vehicle_in_use = (ps.vehicleState.entity && ps.vehicleState.entity != 2047); - if (!vehicle_in_use) - { - write_predicted_player_data(output, cad, viewangles, cad_index, predicted_data_id::player); - } - else - { - const auto data_type = get_predicted_vehicle_type(ps); - write_predicted_vehicle_data(output, cad, viewangles, cad_index, data_type); - } + write_predicted_player_data(output, ps, static_cast(cl.clientArchiveIndex), predicted_data_id::player); + } + else + { + const auto data_type = get_predicted_vehicle_type(ps); + write_predicted_vehicle_data(output, ps, static_cast(cl.clientArchiveIndex), data_type); } } @@ -842,77 +842,12 @@ namespace demo_utils namespace serialization_server { - void sv_write_predicted_player_data_(auto& output, const game::mp::playerState_t& ps, - std::uint8_t cad_index, predicted_data_id id) - { - write_id_and_size(output, 50, demo_data_id::predicted_data); - output.write(reinterpret_cast(&id), 1); - output.write(reinterpret_cast(&cad_index), 1); - - output.write(reinterpret_cast(&ps.commandTime), 4); - output.write(reinterpret_cast(&ps.origin[0]), 12); - output.write(reinterpret_cast(&ps.velocity[0]), 12); - output.write(reinterpret_cast(&ps.bobCycle), 4); - output.write(reinterpret_cast(&ps.movementDir), 4); - output.write(reinterpret_cast(&ps.viewangles[0]), 12); - } - - void sv_write_predicted_player_data(buffer_t& output, const game::mp::playerState_t& ps, - std::uint8_t cad_index, predicted_data_id id) - { - sv_write_predicted_player_data_(output, ps, cad_index, id); - } - - void sv_write_predicted_player_data(std::ofstream& output, const game::mp::playerState_t& ps, - std::uint8_t cad_index, predicted_data_id id) - { - sv_write_predicted_player_data_(output, ps, cad_index, id); - } - - void sv_write_predicted_vehicle_data_(auto& output, const game::mp::playerState_t& ps, - std::uint8_t cad_index, predicted_data_id id) - { - const auto size = (id != predicted_data_id::vehicle_gryphon) ? 58 : 82; - - write_id_and_size(output, size, demo_data_id::predicted_data); - output.write(reinterpret_cast(&id), 1); - output.write(reinterpret_cast(&cad_index), 1); - - const auto& vehicle = ps.vehicleState; - output.write(reinterpret_cast(&ps.commandTime), 4); - output.write(reinterpret_cast(&ps.origin[0]), 12); - output.write(reinterpret_cast(&ps.viewangles[0]), 12); - output.write(reinterpret_cast(&vehicle.flags), 4); - output.write(reinterpret_cast(&vehicle.origin[0]), 12); - output.write(reinterpret_cast(&vehicle.angles[0]), 12); - - if (id == predicted_data_id::vehicle_gryphon) - { - output.write(reinterpret_cast(&vehicle.velocity[0]), 12); - output.write(reinterpret_cast(&vehicle.angVelocity[0]), 12); - } - - assert(!vehicle.splineId); - } - - void sv_write_predicted_vehicle_data(buffer_t& output, const game::mp::playerState_t& ps, - std::uint8_t cad_index, predicted_data_id id) - { - sv_write_predicted_vehicle_data_(output, ps, cad_index, id); - } - - void sv_write_predicted_vehicle_data(std::ofstream& output, const game::mp::playerState_t& ps, - std::uint8_t cad_index, predicted_data_id id) - { - sv_write_predicted_vehicle_data_(output, ps, cad_index, id); - } - void sv_write_predicted_data_(auto& output, const game::mp::playerState_t& ps, std::size_t send_msg_count) { const auto vehicle_in_use = (ps.vehicleState.entity && ps.vehicleState.entity != 2047); if (!vehicle_in_use) { - sv_write_predicted_player_data(output, ps, static_cast(send_msg_count), predicted_data_id::player); + write_predicted_player_data(output, ps, static_cast(send_msg_count), predicted_data_id::player); } else { @@ -926,7 +861,7 @@ namespace demo_utils } } - sv_write_predicted_vehicle_data(output, ps, static_cast(send_msg_count), data_type); + write_predicted_vehicle_data(output, ps, static_cast(send_msg_count), data_type); } } diff --git a/src/client/component/demo_utils.hpp b/src/client/component/demo_utils.hpp index 94217b1..5bf15b6 100644 --- a/src/client/component/demo_utils.hpp +++ b/src/client/component/demo_utils.hpp @@ -143,15 +143,15 @@ namespace demo_utils void write_network_data(buffer_t& output, std::span network_data); void write_network_data(std::ofstream& output, std::span network_data); - //void write_predicted_player_data(buffer_t& output, const game::ClientArchiveData& cad, - //const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id); - //void write_predicted_player_data(std::ofstream& output, const game::ClientArchiveData& cad, - //const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id); + //void write_predicted_player_data(buffer_t& output, const game::mp::playerState_t& ps, + //std::uint8_t cad_index, predicted_data_id id); + //void write_predicted_player_data(std::ofstream& output, const game::mp::playerState_t& ps, + //std::uint8_t cad_index, predicted_data_id id); - //void write_predicted_vehicle_data(buffer_t& output, const game::ClientArchiveData& cad, - //const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id); - //void write_predicted_vehicle_data(std::ofstream& output, const game::ClientArchiveData& cad, - //const game::vec3_t& viewangles, std::uint8_t cad_index, predicted_data_id id); + //void write_predicted_vehicle_data(buffer_t& output, const game::mp::playerState_t& ps, + //std::uint8_t cad_index, predicted_data_id id); + //void write_predicted_vehicle_data(std::ofstream& output, const game::mp::playerState_t& ps, + //std::uint8_t cad_index, predicted_data_id id); void write_helo_pilot_turret_fire(buffer_t& output, std::uint8_t fire_count); void write_helo_pilot_turret_fire(std::ofstream& output, std::uint8_t fire_count);