add player notifications on proxy server

This commit is contained in:
Martin Michelsen
2023-03-12 00:09:59 -08:00
parent 2291d758ac
commit 711bbf0a21
7 changed files with 54 additions and 29 deletions
+1
View File
@@ -37,6 +37,7 @@ ClientOptions::ClientOptions()
save_files(false),
enable_chat_commands(true),
enable_chat_filter(true),
enable_player_notifications(false),
suppress_remote_login(false),
zero_remote_guild_card(false),
ep3_infinite_meseta(false),
+1
View File
@@ -39,6 +39,7 @@ struct ClientOptions {
bool save_files;
bool enable_chat_commands;
bool enable_chat_filter;
bool enable_player_notifications;
bool suppress_remote_login;
bool zero_remote_guild_card;
bool ep3_infinite_meseta;
+15 -14
View File
@@ -57,20 +57,21 @@ namespace PatchesMenuItemID {
}
namespace ProxyOptionsMenuItemID {
constexpr uint32_t GO_BACK = 0xAAFFFFAA;
constexpr uint32_t CHAT_COMMANDS = 0xAA0000AA;
constexpr uint32_t CHAT_FILTER = 0xAA1111AA;
constexpr uint32_t INFINITE_HP = 0xAA2222AA;
constexpr uint32_t INFINITE_TP = 0xAA3333AA;
constexpr uint32_t SWITCH_ASSIST = 0xAA4444AA;
constexpr uint32_t BLOCK_EVENTS = 0xAA5555AA;
constexpr uint32_t BLOCK_PATCHES = 0xAA6666AA;
constexpr uint32_t SAVE_FILES = 0xAA7777AA;
constexpr uint32_t RED_NAME = 0xAA8888AA;
constexpr uint32_t BLANK_NAME = 0xAA9999AA;
constexpr uint32_t SUPPRESS_LOGIN = 0xAAAAAAAA;
constexpr uint32_t SKIP_CARD = 0xAABBBBAA;
constexpr uint32_t EP3_INFINITE_MESETA = 0xAACCCCAA;
constexpr uint32_t GO_BACK = 0xAAFFFFAA;
constexpr uint32_t CHAT_COMMANDS = 0xAA0000AA;
constexpr uint32_t CHAT_FILTER = 0xAA1111AA;
constexpr uint32_t PLAYER_NOTIFICATIONS = 0xAA2222AA;
constexpr uint32_t INFINITE_HP = 0xAA3333AA;
constexpr uint32_t INFINITE_TP = 0xAA4444AA;
constexpr uint32_t SWITCH_ASSIST = 0xAA5555AA;
constexpr uint32_t BLOCK_EVENTS = 0xAA6666AA;
constexpr uint32_t BLOCK_PATCHES = 0xAA7777AA;
constexpr uint32_t SAVE_FILES = 0xAA8888AA;
constexpr uint32_t RED_NAME = 0xAA9999AA;
constexpr uint32_t BLANK_NAME = 0xAAAAAAAA;
constexpr uint32_t SUPPRESS_LOGIN = 0xAABBBBAA;
constexpr uint32_t SKIP_CARD = 0xAACCCCAA;
constexpr uint32_t EP3_INFINITE_MESETA = 0xAADDDDAA;
}
+12 -2
View File
@@ -116,7 +116,9 @@ static HandlerResult S_invalid(shared_ptr<ServerState>,
static HandlerResult C_05(shared_ptr<ServerState>,
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
session.disconnect_action = ProxyServer::LinkedSession::DisconnectAction::SHORT_TIMEOUT;
session.disconnect_action = session.version == GameVersion::BB
? ProxyServer::LinkedSession::DisconnectAction::MEDIUM_TIMEOUT
: ProxyServer::LinkedSession::DisconnectAction::SHORT_TIMEOUT;
return HandlerResult::Type::FORWARD;
}
@@ -1307,14 +1309,18 @@ static HandlerResult S_65_67_68_EB(shared_ptr<ServerState>,
if (index >= session.lobby_players.size()) {
session.log.warning("Ignoring invalid player index %zu at position %zu", index, x);
} else {
string name = encode_sjis(cmd.entries[x].disp.name);
if (session.license && (cmd.entries[x].lobby_data.guild_card == session.remote_guild_card_number)) {
cmd.entries[x].lobby_data.guild_card = session.license->serial_number;
num_replacements++;
modified = true;
} else if (session.options.enable_player_notifications && command != 0x67) {
send_text_message_printf(session.client_channel, "$C6Join: %zu / %" PRIu32 "\n%s",
index, cmd.entries[x].lobby_data.guild_card.load(), name.c_str());
}
auto& p = session.lobby_players[index];
p.guild_card_number = cmd.entries[x].lobby_data.guild_card;
string name = encode_sjis(cmd.entries[x].disp.name);
p.name = name;
p.section_id = cmd.entries[x].disp.section_id;
p.char_class = cmd.entries[x].disp.char_class;
@@ -1463,6 +1469,10 @@ static HandlerResult S_66_69_E9(shared_ptr<ServerState>,
session.log.warning("Lobby leave command references missing position");
} else {
auto& p = session.lobby_players[index];
if (session.options.enable_player_notifications) {
send_text_message_printf(session.client_channel, "$C4Leave: %zu / %" PRIu32 "\n%s",
index, p.guild_card_number, p.name.c_str());
}
p.guild_card_number = 0;
p.name.clear();
session.log.info("Removed lobby player (%zu)", index);
+18 -12
View File
@@ -35,11 +35,6 @@ using namespace std::placeholders;
static const uint32_t LICENSED_SESSION_TIMEOUT_USECS = 5 * 60 * 1000000; // 5 minutes
static const uint32_t UNLICENSED_SESSION_TIMEOUT_USECS = 10 * 1000000; // 10 seconds
ProxyServer::ProxyServer(
shared_ptr<struct event_base> base,
shared_ptr<ServerState> state)
@@ -635,7 +630,6 @@ void ProxyServer::LinkedSession::dispatch_on_timeout(
void ProxyServer::LinkedSession::on_timeout() {
this->log.info("Session timed out");
this->server->delete_session(this->id);
}
@@ -672,9 +666,6 @@ void ProxyServer::LinkedSession::on_error(Channel& ch, short events) {
session->send_to_game_server("The server has\ndisconnected.");
}
session->disconnect();
if (session->disconnect_action == ProxyServer::LinkedSession::DisconnectAction::CLOSE_IMMEDIATELY) {
session->server->delete_session(session->id);
}
}
}
@@ -758,6 +749,22 @@ void ProxyServer::LinkedSession::send_to_game_server(const char* error_message)
}
}
uint64_t ProxyServer::LinkedSession::timeout_for_disconnect_action(
DisconnectAction action) {
switch (action) {
case DisconnectAction::LONG_TIMEOUT:
return 5 * 60 * 1000 * 1000; // 5 minutes
case DisconnectAction::MEDIUM_TIMEOUT:
return 30 * 1000 * 1000; // 30 seconds
case DisconnectAction::SHORT_TIMEOUT:
return 10 * 1000 * 1000; // 10 seconds
case DisconnectAction::CLOSE_IMMEDIATELY:
return 0;
default:
throw logic_error("disconnect action does not have a timeout");
}
}
void ProxyServer::LinkedSession::disconnect() {
// Disconnect both ends
this->client_channel.disconnect();
@@ -765,9 +772,8 @@ void ProxyServer::LinkedSession::disconnect() {
// Set a timeout to delete the session entirely (in case the client doesn't
// reconnect)
bool use_long_timeout = (this->license.get() && (this->disconnect_action == DisconnectAction::LONG_TIMEOUT));
struct timeval tv = usecs_to_timeval(use_long_timeout
? LICENSED_SESSION_TIMEOUT_USECS : UNLICENSED_SESSION_TIMEOUT_USECS);
struct timeval tv = usecs_to_timeval(this->timeout_for_disconnect_action(
this->disconnect_action));
event_add(this->timeout_event.get(), &tv);
}
+2 -1
View File
@@ -49,6 +49,7 @@ public:
enum class DisconnectAction {
LONG_TIMEOUT = 0,
MEDIUM_TIMEOUT,
SHORT_TIMEOUT,
CLOSE_IMMEDIATELY,
};
@@ -146,6 +147,7 @@ public:
std::shared_ptr<PSOBBMultiKeyDetectorEncryption> detector_crypt);
void connect();
static uint64_t timeout_for_disconnect_action(DisconnectAction action);
static void dispatch_on_timeout(evutil_socket_t fd, short what, void* ctx);
static void on_input(Channel& ch, uint16_t, uint32_t, std::string& msg);
static void on_error(Channel& ch, short events);
@@ -155,7 +157,6 @@ public:
void send_to_game_server(const char* error_message = nullptr);
void disconnect();
bool is_connected() const;
};
+5
View File
@@ -75,6 +75,7 @@ static const unordered_map<uint32_t, const char16_t*> proxy_options_menu_descrip
{ProxyOptionsMenuItemID::GO_BACK, u"Return to the\nproxy menu"},
{ProxyOptionsMenuItemID::CHAT_COMMANDS, u"Enable chat\ncommands"},
{ProxyOptionsMenuItemID::CHAT_FILTER, u"Enable escape\nsequences in\nchat messages\nand info board"},
{ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS, u"Show a message\nwhen other players\njoin or leave"},
{ProxyOptionsMenuItemID::INFINITE_HP, u"Enable automatic HP\nrestoration when\nyou are hit by an\nenemy or trap\n\nCannot revive you\nfrom one-hit kills"},
{ProxyOptionsMenuItemID::INFINITE_TP, u"Enable automatic TP\nrestoration when\nyou cast any\ntechnique"},
{ProxyOptionsMenuItemID::SWITCH_ASSIST, u"Automatically try\nto unlock 2-player\ndoors when you step\non both switches\nsequentially"},
@@ -105,6 +106,7 @@ static vector<MenuItem> proxy_options_menu_for_client(
add_option(ProxyOptionsMenuItemID::CHAT_COMMANDS, c->options.enable_chat_commands, u"Chat commands");
add_option(ProxyOptionsMenuItemID::CHAT_FILTER, c->options.enable_chat_filter, u"Chat filter");
add_option(ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS, c->options.enable_player_notifications, u"Player notifs");
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
add_option(ProxyOptionsMenuItemID::INFINITE_HP, c->options.infinite_hp, u"Infinite HP");
add_option(ProxyOptionsMenuItemID::INFINITE_TP, c->options.infinite_tp, u"Infinite TP");
@@ -1785,6 +1787,9 @@ static void on_10(shared_ptr<ServerState> s, shared_ptr<Client> c,
case ProxyOptionsMenuItemID::CHAT_FILTER:
c->options.enable_chat_filter = !c->options.enable_chat_filter;
goto resend_proxy_options_menu;
case ProxyOptionsMenuItemID::PLAYER_NOTIFICATIONS:
c->options.enable_player_notifications = !c->options.enable_player_notifications;
goto resend_proxy_options_menu;
case ProxyOptionsMenuItemID::INFINITE_HP:
c->options.infinite_hp = !c->options.infinite_hp;
goto resend_proxy_options_menu;