From c8cb3e61f7294f362d7222661c8805d1d4edeca7 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sat, 1 Oct 2022 00:56:17 -0700 Subject: [PATCH] add set-next-item shell command --- src/ServerShell.cc | 34 ++++++++++++++++++++++++++++++++++ src/StaticGameData.cc | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ServerShell.cc b/src/ServerShell.cc index 7e5643ed..23bcaafc 100644 --- a/src/ServerShell.cc +++ b/src/ServerShell.cc @@ -145,6 +145,8 @@ Proxy commands (these will only work when exactly one client is connected):\n\ responds as if the function was called (with the given return value), but\n\ does not send the code to the client. To stop blocking function calls, omit\n\ the return value.\n\ + set-next-item \n\ + Set the next item to be dropped as if the client had run the $item command.\n\ close-idle-sessions\n\ Closes all sessions that don\'t have a client and server connected.\n\ "); @@ -400,6 +402,38 @@ Proxy commands (these will only work when exactly one client is connected):\n\ session->function_call_return_value = stoul(command_args); } + } else if (command_name == "set-next-item") { + auto session = this->get_proxy_session(); + + if (session->version == GameVersion::BB) { + throw runtime_error("proxy session is BB"); + } + if (!session->is_in_game) { + throw runtime_error("proxy session is not in a game"); + } + if (session->lobby_client_id != session->leader_client_id) { + throw runtime_error("proxy session is not game leader"); + } + + string data = parse_data_string(command_args); + if (data.size() < 2) { + throw runtime_error("data too short"); + } + if (data.size() > 16) { + throw runtime_error("data too long"); + } + + session->next_drop_item.clear(); + if (data.size() <= 12) { + memcpy(&session->next_drop_item.data.data1, data.data(), data.size()); + } else { + memcpy(&session->next_drop_item.data.data1, data.data(), 12); + memcpy(&session->next_drop_item.data.data2, data.data() + 12, data.size() - 12); + } + + string name = name_for_item(session->next_drop_item.data, true); + send_text_message(session->client_channel, u"$C7Next drop:\n" + decode_sjis(name)); + } else if (command_name == "close-idle-sessions") { size_t count = this->state->proxy_server->delete_disconnected_sessions(); fprintf(stderr, "%zu sessions closed\n", count); diff --git a/src/StaticGameData.cc b/src/StaticGameData.cc index 30ecc24c..a0cf1c08 100644 --- a/src/StaticGameData.cc +++ b/src/StaticGameData.cc @@ -1610,7 +1610,7 @@ string name_for_item(const ItemData& item, bool include_color_codes) { // center and right PBs from the list, and the left PB is then used as // an index into this modified list to determine the actual left PB. // Here, we don't construct a temporary list and instead just skip the - // center and right PB values with a loop instead. + // center and right PB values with a loop. uint8_t actual_left_pb = 0; for (;;) { if ((actual_left_pb == center_pb) || (actual_left_pb == right_pb)) {