implement warpme/warpall commands
This commit is contained in:
@@ -316,7 +316,8 @@ Some commands only work on the game server and not on the proxy server. The chat
|
||||
* Cheat mode commands
|
||||
* `$cheat`: Enables or disables cheat mode for the current game. All other cheat mode commands do nothing if cheat mode is disabled. This command does nothing on the proxy server - cheat commands are always available there.
|
||||
* `$infhp` / `$inftp`: Enables or disables infinite HP or TP mode. Applies to only you. In infinite HP mode, one-hit KO attacks will still kill you.
|
||||
* `$warp <area-id>`: Warps yourself to the given area.
|
||||
* `$warpme <area-id>`: Warps yourself to the given area.
|
||||
* `$warpall <area-id>`: Warps everyone in the game to the given area. You must be the leader to use this command, unless you're on the proxy server.
|
||||
* `$next`: Warps yourself to the next area.
|
||||
* `$swa`: Enables or disables switch assist. When enabled, the server will attempt to automatically unlock two-player doors in solo games if you step on both switches sequentially.
|
||||
* `$item <data>` (or `$i <data>`): Create an item. Item codes are 16 hex bytes; at least 2 bytes must be specified, and all unspecified bytes are zeroes. If you are on the proxy server, you must not be using Blue Burst for this command to work. On the game server, this command works for all versions.
|
||||
|
||||
+76
-52
@@ -963,8 +963,8 @@ static void server_command_ban(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Cheat commands
|
||||
|
||||
static void server_command_warp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
shared_ptr<Client> c, const std::u16string& args) {
|
||||
static void server_command_warp(
|
||||
shared_ptr<Lobby> l, shared_ptr<Client> c, const std::u16string& args, bool is_warpall) {
|
||||
check_is_game(l, true);
|
||||
check_cheats_enabled(l);
|
||||
|
||||
@@ -981,21 +981,47 @@ static void server_command_warp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
return;
|
||||
}
|
||||
|
||||
send_warp(c, area);
|
||||
if (is_warpall) {
|
||||
send_warp(l, area, false);
|
||||
} else {
|
||||
send_warp(c, area, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void proxy_command_warp(shared_ptr<ServerState>,
|
||||
ProxyServer::LinkedSession& session, const std::u16string& args) {
|
||||
static void server_command_warpme(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
shared_ptr<Client> c, const std::u16string& args) {
|
||||
server_command_warp(l, c, args, false);
|
||||
}
|
||||
|
||||
static void server_command_warpall(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
shared_ptr<Client> c, const std::u16string& args) {
|
||||
server_command_warp(l, c, args, true);
|
||||
}
|
||||
|
||||
static void proxy_command_warp(
|
||||
ProxyServer::LinkedSession& session, const std::u16string& args, bool is_warpall) {
|
||||
if (!session.is_in_game) {
|
||||
send_text_message(session.client_channel, u"$C6You must be in a\ngame to use this\ncommand");
|
||||
return;
|
||||
}
|
||||
uint32_t area = stoul(encode_sjis(args), nullptr, 0);
|
||||
// TODO: Add limit check here like in the server command implementation
|
||||
send_warp(session.client_channel, session.lobby_client_id, area);
|
||||
send_warp(session.client_channel, session.lobby_client_id, area, !is_warpall);
|
||||
if (is_warpall) {
|
||||
send_warp(session.server_channel, session.lobby_client_id, area, false);
|
||||
}
|
||||
session.area = area;
|
||||
}
|
||||
|
||||
static void proxy_command_warpme(shared_ptr<ServerState>,
|
||||
ProxyServer::LinkedSession& session, const std::u16string& args) {
|
||||
proxy_command_warp(session, args, false);
|
||||
}
|
||||
|
||||
static void proxy_command_warpall(shared_ptr<ServerState>,
|
||||
ProxyServer::LinkedSession& session, const std::u16string& args) {
|
||||
proxy_command_warp(session, args, true);
|
||||
}
|
||||
|
||||
static void server_command_next(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
shared_ptr<Client> c, const std::u16string&) {
|
||||
check_is_game(l, true);
|
||||
@@ -1005,7 +1031,7 @@ static void server_command_next(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
if (limit == 0) {
|
||||
return;
|
||||
}
|
||||
send_warp(c, (c->area + 1) % limit);
|
||||
send_warp(c, (c->area + 1) % limit, true);
|
||||
}
|
||||
|
||||
static void proxy_command_next(shared_ptr<ServerState>,
|
||||
@@ -1016,7 +1042,7 @@ static void proxy_command_next(shared_ptr<ServerState>,
|
||||
}
|
||||
|
||||
session.area++;
|
||||
send_warp(session.client_channel, session.lobby_client_id, session.area);
|
||||
send_warp(session.client_channel, session.lobby_client_id, session.area, true);
|
||||
}
|
||||
|
||||
static void server_command_what(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
@@ -1225,52 +1251,50 @@ typedef void (*proxy_handler_t)(shared_ptr<ServerState>,
|
||||
struct ChatCommandDefinition {
|
||||
server_handler_t server_handler;
|
||||
proxy_handler_t proxy_handler;
|
||||
u16string usage;
|
||||
};
|
||||
|
||||
static const unordered_map<u16string, ChatCommandDefinition> chat_commands({
|
||||
// TODO: implement command_help and actually use the usage strings here
|
||||
{u"$allevent", {server_command_lobby_event_all, nullptr, u"Usage:\nallevent <name/ID>"}},
|
||||
{u"$ann", {server_command_announce, nullptr, u"Usage:\nann <message>"}},
|
||||
{u"$arrow", {server_command_arrow, proxy_command_arrow, u"Usage:\narrow <color>"}},
|
||||
{u"$auction", {server_command_auction, proxy_command_auction, u"Usage:\nauction"}},
|
||||
{u"$ax", {server_command_ax, nullptr, u"Usage:\nax <message>"}},
|
||||
{u"$ban", {server_command_ban, nullptr, u"Usage:\nban <name-or-number>"}},
|
||||
// TODO: implement this on proxy server
|
||||
{u"$bbchar", {server_command_convert_char_to_bb, nullptr, u"Usage:\nbbchar <user> <pass> <1-4>"}},
|
||||
{u"$cheat", {server_command_cheat, nullptr, u"Usage:\ncheat"}},
|
||||
{u"$debug", {server_command_debug, nullptr, u"Usage:\ndebug"}},
|
||||
{u"$edit", {server_command_edit, nullptr, u"Usage:\nedit <stat> <value>"}},
|
||||
{u"$event", {server_command_lobby_event, proxy_command_lobby_event, u"Usage:\nevent <name>"}},
|
||||
{u"$exit", {server_command_exit, proxy_command_exit, u"Usage:\nexit"}},
|
||||
{u"$gc", {server_command_get_self_card, proxy_command_get_player_card, u"Usage:\ngc"}},
|
||||
{u"$infhp", {server_command_infinite_hp, proxy_command_infinite_hp, u"Usage:\ninfhp"}},
|
||||
{u"$inftp", {server_command_infinite_tp, proxy_command_infinite_tp, u"Usage:\ninftp"}},
|
||||
{u"$item", {server_command_item, proxy_command_item, u"Usage:\nitem <item-code>"}},
|
||||
{u"$i", {server_command_item, proxy_command_item, u"Usage:\ni <item-code>"}},
|
||||
{u"$kick", {server_command_kick, nullptr, u"Usage:\nkick <name-or-number>"}},
|
||||
{u"$li", {server_command_lobby_info, proxy_command_lobby_info, u"Usage:\nli"}},
|
||||
{u"$maxlevel", {server_command_max_level, nullptr, u"Usage:\nmax_level <level>"}},
|
||||
{u"$minlevel", {server_command_min_level, nullptr, u"Usage:\nmin_level <level>"}},
|
||||
{u"$next", {server_command_next, proxy_command_next, u"Usage:\nnext"}},
|
||||
{u"$password", {server_command_password, nullptr, u"Usage:\nlock [password]\nomit password to\nunlock game"}},
|
||||
{u"$patch", {server_command_patch, proxy_command_patch, u"Usage:\npatch <name>"}},
|
||||
{u"$persist", {server_command_persist, nullptr, u"Usage:\npersist"}},
|
||||
{u"$playrec", {server_command_playrec, nullptr, u"Usage:\nplayrec <filename>"}},
|
||||
{u"$rand", {server_command_rand, proxy_command_rand, u"Usage:\nrand [hex seed]\nomit seed to revert\nto default"}},
|
||||
{u"$saverec", {server_command_saverec, nullptr, u"Usage:\nsaverec <filename>"}},
|
||||
{u"$sc", {server_command_send_client, proxy_command_send_client, u"Usage:\nsc <data>"}},
|
||||
{u"$secid", {server_command_secid, proxy_command_secid, u"Usage:\nsecid [section ID]\nomit section ID to\nrevert to normal"}},
|
||||
{u"$silence", {server_command_silence, nullptr, u"Usage:\nsilence <name-or-number>"}},
|
||||
// TODO: implement this on proxy server
|
||||
{u"$song", {server_command_song, proxy_command_song, u"Usage:\nsong <song-number>"}},
|
||||
{u"$spec", {server_command_spec, nullptr, u"Usage:\nspec"}},
|
||||
{u"$ss", {nullptr, proxy_command_send_server, u"Usage:\nss <data>"}},
|
||||
{u"$swa", {server_command_switch_assist, proxy_command_switch_assist, u"Usage:\nswa"}},
|
||||
{u"$type", {server_command_lobby_type, nullptr, u"Usage:\ntype <name>"}},
|
||||
{u"$warp", {server_command_warp, proxy_command_warp, u"Usage:\nwarp <area-number>"}},
|
||||
{u"$what", {server_command_what, nullptr, u"Usage:\nwhat"}},
|
||||
{u"$drop", {server_command_drop, nullptr, u"Usage:\nToggles drops"}},
|
||||
{u"$allevent", {server_command_lobby_event_all, nullptr}},
|
||||
{u"$ann", {server_command_announce, nullptr}},
|
||||
{u"$arrow", {server_command_arrow, proxy_command_arrow}},
|
||||
{u"$auction", {server_command_auction, proxy_command_auction}},
|
||||
{u"$ax", {server_command_ax, nullptr}},
|
||||
{u"$ban", {server_command_ban, nullptr}},
|
||||
{u"$bbchar", {server_command_convert_char_to_bb, nullptr}},
|
||||
{u"$cheat", {server_command_cheat, nullptr}},
|
||||
{u"$debug", {server_command_debug, nullptr}},
|
||||
{u"$drop", {server_command_drop, nullptr}},
|
||||
{u"$edit", {server_command_edit, nullptr}},
|
||||
{u"$event", {server_command_lobby_event, proxy_command_lobby_event}},
|
||||
{u"$exit", {server_command_exit, proxy_command_exit}},
|
||||
{u"$gc", {server_command_get_self_card, proxy_command_get_player_card}},
|
||||
{u"$infhp", {server_command_infinite_hp, proxy_command_infinite_hp}},
|
||||
{u"$inftp", {server_command_infinite_tp, proxy_command_infinite_tp}},
|
||||
{u"$item", {server_command_item, proxy_command_item}},
|
||||
{u"$i", {server_command_item, proxy_command_item}},
|
||||
{u"$kick", {server_command_kick, nullptr}},
|
||||
{u"$li", {server_command_lobby_info, proxy_command_lobby_info}},
|
||||
{u"$maxlevel", {server_command_max_level, nullptr}},
|
||||
{u"$minlevel", {server_command_min_level, nullptr}},
|
||||
{u"$next", {server_command_next, proxy_command_next}},
|
||||
{u"$password", {server_command_password, nullptr}},
|
||||
{u"$patch", {server_command_patch, proxy_command_patch}},
|
||||
{u"$persist", {server_command_persist, nullptr}},
|
||||
{u"$playrec", {server_command_playrec, nullptr}},
|
||||
{u"$rand", {server_command_rand, proxy_command_rand}},
|
||||
{u"$saverec", {server_command_saverec, nullptr}},
|
||||
{u"$sc", {server_command_send_client, proxy_command_send_client}},
|
||||
{u"$secid", {server_command_secid, proxy_command_secid}},
|
||||
{u"$silence", {server_command_silence, nullptr}},
|
||||
{u"$song", {server_command_song, proxy_command_song}},
|
||||
{u"$spec", {server_command_spec, nullptr}},
|
||||
{u"$ss", {nullptr, proxy_command_send_server}},
|
||||
{u"$swa", {server_command_switch_assist, proxy_command_switch_assist}},
|
||||
{u"$type", {server_command_lobby_type, nullptr}},
|
||||
{u"$warp", {server_command_warpme, proxy_command_warpme}},
|
||||
{u"$warpme", {server_command_warpme, proxy_command_warpme}},
|
||||
{u"$warpall", {server_command_warpall, proxy_command_warpall}},
|
||||
{u"$what", {server_command_what, nullptr}},
|
||||
});
|
||||
|
||||
struct SplitCommand {
|
||||
|
||||
+12
-4
@@ -1879,16 +1879,24 @@ void send_player_stats_change(Channel& ch, uint16_t client_id, PlayerStatsChange
|
||||
send_command_vt(ch, (subs.size() > 0x400 / sizeof(G_UpdatePlayerStat_6x9A)) ? 0x6C : 0x60, 0x00, subs);
|
||||
}
|
||||
|
||||
void send_warp(Channel& ch, uint8_t client_id, uint32_t area) {
|
||||
void send_warp(Channel& ch, uint8_t client_id, uint32_t area, bool is_private) {
|
||||
G_InterLevelWarp_6x94 cmd = {{0x94, 0x02, 0}, area, {}};
|
||||
ch.send(0x62, client_id, &cmd, sizeof(cmd));
|
||||
ch.send(is_private ? 0x62 : 0x60, client_id, &cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
void send_warp(shared_ptr<Client> c, uint32_t area) {
|
||||
send_warp(c->channel, c->lobby_client_id, area);
|
||||
void send_warp(shared_ptr<Client> c, uint32_t area, bool is_private) {
|
||||
send_warp(c->channel, c->lobby_client_id, area, is_private);
|
||||
c->area = area;
|
||||
}
|
||||
|
||||
void send_warp(shared_ptr<Lobby> l, uint32_t area, bool is_private) {
|
||||
for (const auto& c : l->clients) {
|
||||
if (c) {
|
||||
send_warp(c, area, is_private);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_ep3_change_music(Channel& ch, uint32_t song) {
|
||||
G_ChangeLobbyMusic_GC_Ep3_6xBF cmd = {{0xBF, 0x02, 0}, song};
|
||||
ch.send(0x60, 0x00, cmd);
|
||||
|
||||
+3
-2
@@ -290,8 +290,9 @@ void send_player_stats_change(std::shared_ptr<Lobby> l, std::shared_ptr<Client>
|
||||
PlayerStatsChange stat, uint32_t amount);
|
||||
void send_player_stats_change(
|
||||
Channel& ch, uint16_t client_id, PlayerStatsChange stat, uint32_t amount);
|
||||
void send_warp(Channel& ch, uint8_t client_id, uint32_t area);
|
||||
void send_warp(std::shared_ptr<Client> c, uint32_t area);
|
||||
void send_warp(Channel& ch, uint8_t client_id, uint32_t area, bool is_private);
|
||||
void send_warp(std::shared_ptr<Client> c, uint32_t area, bool is_private);
|
||||
void send_warp(std::shared_ptr<Lobby> l, uint32_t area, bool is_private);
|
||||
|
||||
void send_ep3_change_music(Channel& ch, uint32_t song);
|
||||
void send_set_player_visibility(std::shared_ptr<Lobby> l,
|
||||
|
||||
+12
-3
@@ -208,7 +208,10 @@ Proxy session commands:\n\
|
||||
marker COLOR-ID\n\
|
||||
Change your lobby marker color.\n\
|
||||
warp AREA-ID\n\
|
||||
warpme AREA-ID\n\
|
||||
Send yourself to a specific area.\n\
|
||||
warpall AREA-ID\n\
|
||||
Send everyone to a specific area.\n\
|
||||
set-override-section-id [SECTION-ID]\n\
|
||||
Override the section ID for games you create or join. This affects the\n\
|
||||
active drop chart if you are the leader of the game and the server doesn't\n\
|
||||
@@ -662,12 +665,18 @@ Proxy session commands:\n\
|
||||
auto session = this->get_proxy_session(session_name);
|
||||
session->server_channel.send(0x89, stoul(command_args));
|
||||
|
||||
} else if (command_name == "warp") {
|
||||
} else if ((command_name == "warp") || (command_name == "warpme")) {
|
||||
auto session = this->get_proxy_session(session_name);
|
||||
|
||||
uint8_t area = stoul(command_args);
|
||||
send_warp(session->client_channel, session->lobby_client_id, area);
|
||||
send_warp(session->server_channel, session->lobby_client_id, area);
|
||||
send_warp(session->client_channel, session->lobby_client_id, area, true);
|
||||
|
||||
} else if (command_name == "warpall") {
|
||||
auto session = this->get_proxy_session(session_name);
|
||||
|
||||
uint8_t area = stoul(command_args);
|
||||
send_warp(session->client_channel, session->lobby_client_id, area, false);
|
||||
send_warp(session->server_channel, session->lobby_client_id, area, false);
|
||||
|
||||
} else if ((command_name == "info-board") || (command_name == "info-board-data")) {
|
||||
auto session = this->get_proxy_session(session_name);
|
||||
|
||||
Reference in New Issue
Block a user