add player notifications on proxy server
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user