-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add multi_hitsounds #158
base: master
Are you sure you want to change the base?
Add multi_hitsounds #158
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -170,6 +170,8 @@ bool GameConfig::visit_vars(T&& visitor, bool is_save) | |
result &= visitor(dash_faction_key, "Big HUD", big_hud); | ||
result &= visitor(dash_faction_key, "Reticle Scale", reticle_scale); | ||
result &= visitor(dash_faction_key, "Mesh Static Lighting", mesh_static_lighting); | ||
result &= visitor(dash_faction_key, "multi_hitsounds", multi_hitsounds); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keep registry key naming convention |
||
result &= visitor(dash_faction_key, "multi_hitsounds_legacy_mode", multi_hitsounds_legacy_mode); | ||
return result; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#include <array> | ||
#include <xlog/xlog.h> | ||
#include "../main/main.h" | ||
#include "../rf/multi.h" | ||
#include "../rf/sound/sound.h" | ||
#include "../rf/player/player.h" | ||
#include "../misc/player.h" | ||
#include "../multi/multi.h" | ||
#include "../purefaction/pf.h" | ||
#include "custom_packets.h" | ||
|
||
namespace custom_packets { | ||
// Do not drop hitsound packets to save bandwidth, since hitsound packets are | ||
// significantly smaller than sound packets. | ||
void send_hitsound_packet(rf::Player* player){ | ||
if (!rf::is_server) { | ||
return; | ||
} | ||
|
||
rf_packet_header packet{}; | ||
packet.type = static_cast<uint8_t>(custom_packet_type::hitsound); | ||
packet.size = 0; | ||
|
||
rf::multi_io_send(player, &packet, sizeof(packet)); | ||
} | ||
|
||
void process_hitsound_packet(void* data, int len, const rf::NetAddr& addr, rf::Player* player) { | ||
if (rf::is_server) { | ||
return; | ||
} | ||
|
||
rf_packet_header packet; | ||
if (len < sizeof(packet)) { | ||
xlog::trace("Cannot process a hitsound packet; invalid length"); | ||
return; | ||
} | ||
|
||
float invalid = std::numeric_limits<float>::quiet_NaN(); | ||
rf::Vector3 position{invalid, invalid, invalid}; | ||
rf::snd_play_3d(29, position, 1.0f, rf::zero_vector, 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently sound id is configurable on the server. I'd like it to stay this way. |
||
} | ||
|
||
void send_configure_hitsounds_packet(rf::Player* player) { | ||
if (rf::is_server) { | ||
return; | ||
} | ||
|
||
configure_hitsounds_packet packet{}; | ||
packet.hdr.type = static_cast<uint8_t>(custom_packet_type::configure_hitsounds); | ||
packet.hdr.size = sizeof(packet) - sizeof(packet.hdr); | ||
|
||
if (g_game_config.multi_hitsounds_legacy_mode) { | ||
packet.level = 0; | ||
} | ||
else if (g_game_config.multi_hitsounds) { | ||
packet.level = 2; | ||
} | ||
else { | ||
packet.level = 1; | ||
} | ||
|
||
rf::multi_io_send_reliable(player, &packet, sizeof(packet), 0); | ||
} | ||
|
||
void process_configure_hitsounds_packet(void* data, int len, const rf::NetAddr& addr, rf::Player* player) { | ||
if (!rf::is_server) { | ||
return; | ||
} | ||
|
||
configure_hitsounds_packet packet; | ||
if (len < sizeof(packet)) { | ||
xlog::trace("Cannot process a configure_hitsounds packet; invalid length"); | ||
return; | ||
} | ||
|
||
std::memcpy(&packet, data, sizeof(packet)); | ||
|
||
if (packet.level > 2) { | ||
xlog::trace("Cannot process a configure_hitsounds packet; invalid level"); | ||
return; | ||
} | ||
|
||
PlayerAdditionalData& pdata = get_player_additional_data(player); | ||
pdata.multi_hitsounds = packet.level; | ||
|
||
constexpr int NETPLAYER_STATE_IN_GAME = 2; | ||
if (player->net_data->state == NETPLAYER_STATE_IN_GAME) { | ||
static const std::array<std::string, 3> messages { | ||
"\xA6 Hitsounds are set to legacy mode", | ||
"\xA6 Hitsounds are disabled", | ||
"\xA6 Hitsounds are enabled", | ||
}; | ||
send_chat_line_packet(messages[pdata.multi_hitsounds].c_str(), player); | ||
} | ||
} | ||
|
||
bool process_packet(void* data, int len, const rf::NetAddr& addr, rf::Player* player) { | ||
rf_packet_header header; | ||
if (len < static_cast<int>(sizeof(header))) { | ||
xlog::trace("Cannot process a custom packet; invalid length"); | ||
return false; | ||
} | ||
|
||
std::memcpy(&header, data, sizeof(header)); | ||
|
||
switch (static_cast<custom_packet_type>(header.type)) { | ||
case custom_packet_type::configure_hitsounds: { | ||
process_configure_hitsounds_packet(data, len, addr, player); | ||
return true; | ||
} | ||
case custom_packet_type::hitsound: { | ||
process_hitsound_packet(data, len, addr, player); | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#pragma once | ||
|
||
#include "../purefaction/pf_packets.h" | ||
|
||
namespace rf { | ||
struct NetAddr; | ||
struct Player; | ||
} | ||
|
||
namespace custom_packets { | ||
enum class custom_packet_type : uint8_t { | ||
configure_hitsounds = 200, | ||
hitsound = 201, | ||
}; | ||
|
||
struct configure_hitsounds_packet { | ||
rf_packet_header hdr; | ||
uint8_t level; | ||
}; | ||
|
||
void send_hitsound_packet(rf::Player* player); | ||
void process_hitsound_packet(void* data, int len, const rf::NetAddr& addr, rf::Player* player); | ||
void send_configure_hitsounds_packet(rf::Player* player); | ||
void process_configure_hitsounds_packet(void* data, int len, const rf::NetAddr& addr, rf::Player* player); | ||
bool process_packet(void* data, int len, const rf::NetAddr& addr, rf::Player* player); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ | |
#include "multi.h" | ||
#include "server.h" | ||
#include "server_internal.h" | ||
#include "custom_packets.h" | ||
#include "../main/main.h" | ||
#include "../rf/multi.h" | ||
#include "../rf/misc.h" | ||
|
@@ -740,6 +741,7 @@ CodeInjection process_join_accept_send_game_info_req_injection{ | |
rf::NetAddr* server_addr = regs.edi; | ||
xlog::trace("Sending game_info_req to %x:%d", server_addr->ip_addr, server_addr->port); | ||
rf::send_game_info_req_packet(*server_addr); | ||
custom_packets::send_configure_hitsounds_packet(rf::local_player); | ||
}, | ||
}; | ||
|
||
|
@@ -1025,13 +1027,6 @@ void __fastcall multi_io_stats_add_new(void *this_, int edx, int size, bool is_s | |
|
||
FunHook<void __fastcall(void*, int, int, bool, int)> multi_io_stats_add_hook{0x0047CAC0, multi_io_stats_add_new}; | ||
|
||
static void process_custom_packet(void* data, int len, const rf::NetAddr& addr, rf::Player* player) | ||
{ | ||
#if MASK_AS_PF | ||
pf_process_packet(data, len, addr, player); | ||
#endif | ||
} | ||
|
||
CodeInjection multi_io_process_packets_injection{ | ||
0x0047918D, | ||
[](auto& regs) { | ||
|
@@ -1043,7 +1038,13 @@ CodeInjection multi_io_process_packets_injection{ | |
int len = regs.edi; | ||
auto& addr = *addr_as_ref<rf::NetAddr*>(stack_frame + 0xC); | ||
auto player = addr_as_ref<rf::Player*>(stack_frame + 0x10); | ||
process_custom_packet(data + offset, len, addr, player); | ||
#ifdef HAS_PF | ||
if (!pf_process_packet(data, len, addr, player)) { | ||
custom_packets::process_packet(data + offset, len, addr, player); | ||
} | ||
#else | ||
custom_packets::process_packet(data + offset, len, addr, player); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it would be better if this could be not repeated - maybe use something like |
||
#endif | ||
regs.eip = 0x00479194; | ||
} | ||
}, | ||
|
@@ -1082,8 +1083,45 @@ CallHook<int()> game_info_num_players_hook{ | |
}, | ||
}; | ||
|
||
ConsoleCommand2 multi_hitsounds_cmd{ | ||
"multi_hitsounds", | ||
[] (std::optional<std::string> arg) { | ||
if (!rf::is_server) { | ||
if (g_game_config.multi_hitsounds_legacy_mode) { | ||
rf::console::printf("You need to disable multi_hitsounds_legacy_mode"); | ||
return; | ||
} | ||
if (arg.value_or("") != "?") { | ||
g_game_config.multi_hitsounds = !g_game_config.multi_hitsounds; | ||
g_game_config.save(); | ||
custom_packets::send_configure_hitsounds_packet(rf::local_player); | ||
} | ||
rf::console::printf("multi_hitsounds is %s", g_game_config.multi_hitsounds ? "enabled" : "disabled"); | ||
} | ||
}, | ||
"Toggle hitsounds; applies to compatible servers", | ||
}; | ||
|
||
ConsoleCommand2 multi_hitsounds_legacy_mode_cmd{ | ||
"multi_hitsounds_legacy_mode", | ||
[] (std::optional<std::string> arg) { | ||
if (!rf::is_server) { | ||
if (arg.value_or("") != "?") { | ||
g_game_config.multi_hitsounds_legacy_mode = !g_game_config.multi_hitsounds_legacy_mode; | ||
g_game_config.save(); | ||
custom_packets::send_configure_hitsounds_packet(rf::local_player); | ||
} | ||
rf::console::printf("multi_hitsounds_legacy_mode is %s", g_game_config.multi_hitsounds_legacy_mode ? "enabled" : "disabled"); | ||
} | ||
}, | ||
"Toggle legacy mode for hitsounds; applies to compatible servers", | ||
}; | ||
|
||
void network_init() | ||
{ | ||
multi_hitsounds_cmd.register_cmd(); | ||
multi_hitsounds_legacy_mode_cmd.register_cmd(); | ||
|
||
// Improve simultaneous ping | ||
rf::simultaneous_ping = 32; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
#include "server.h" | ||
#include "server_internal.h" | ||
#include "multi.h" | ||
#include "custom_packets.h" | ||
#include "../os/console.h" | ||
#include "../misc/player.h" | ||
#include "../main/main.h" | ||
|
@@ -383,7 +384,13 @@ FunHook<float(rf::Entity*, float, int, int, int)> entity_damage_hook{ | |
auto* damaged_player_stats = static_cast<PlayerStatsNew*>(damaged_player->stats); | ||
damaged_player_stats->add_damage_received(real_damage); | ||
|
||
if (g_additional_server_config.hit_sounds.enabled) { | ||
auto& pdata = get_player_additional_data(killer_player); | ||
if (pdata.multi_hitsounds) { | ||
if (pdata.multi_hitsounds == 2) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. enum > magic constant |
||
custom_packets::send_hitsound_packet(killer_player); | ||
} | ||
} | ||
else if (g_additional_server_config.hit_sounds.enabled) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want more configuration for the server owners so they can force hitsounds disabled, no matter what the client configured. |
||
send_hit_sound_packet(killer_player); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add some description in README about those modes because i'm not sure how this feature works currently