restore deleted item functionality

This commit is contained in:
Martin Michelsen
2023-01-21 21:36:33 -08:00
parent 9d688c2092
commit 4da71e127d
4 changed files with 63 additions and 12 deletions
+14 -5
View File
@@ -148,7 +148,6 @@ static void proxy_command_lobby_info(shared_ptr<ServerState>,
msg += string_printf("%zX", z);
}
}
msg += "\n";
vector<const char*> cheats_tokens;
if (session.options.switch_assist) {
@@ -1052,6 +1051,8 @@ static void proxy_command_item(shared_ptr<ServerState>,
return;
}
bool set_drop = (!args.empty() && (args[0] == u'!'));
string data = parse_data_string(encode_sjis(args));
if (data.size() < 2) {
send_text_message(session.client_channel, u"$C6Item codes must be\n2 bytes or more");
@@ -1071,11 +1072,19 @@ static void proxy_command_item(shared_ptr<ServerState>,
memcpy(&item.data.data2, data.data() + 12, data.size() - 12);
}
send_drop_stacked_item(session.client_channel, item.data, session.area, session.x, session.z);
send_drop_stacked_item(session.server_channel, item.data, session.area, session.x, session.z);
if (set_drop) {
session.next_drop_item = item;
string name = name_for_item(item.data, true);
send_text_message(session.client_channel, u"$C7Item created:\n" + decode_sjis(name));
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 {
send_drop_stacked_item(session.client_channel, item.data, session.area, session.x, session.z);
send_drop_stacked_item(session.server_channel, item.data, session.area, session.x, session.z);
string name = name_for_item(item.data, true);
send_text_message(session.client_channel, u"$C7Item created:\n" + decode_sjis(name));
}
}
+31
View File
@@ -939,6 +939,37 @@ static HandlerResult S_6x(shared_ptr<ServerState>,
session.log.warning("Blocking subcommand 6x49 with invalid count");
return HandlerResult::Type::SUPPRESS;
}
} else if ((data[0] == 0x60) &&
session.next_drop_item.data.data1d[0] &&
(session.version != GameVersion::BB)) {
const auto& cmd = check_size_t<G_EnemyDropItemRequest_DC_6x60>(data,
sizeof(G_EnemyDropItemRequest_DC_6x60),
sizeof(G_EnemyDropItemRequest_PC_V3_BB_6x60));
session.next_drop_item.data.id = session.next_item_id++;
send_drop_item(session.server_channel, session.next_drop_item.data,
true, cmd.area, cmd.x, cmd.z, cmd.request_id);
send_drop_item(session.client_channel, session.next_drop_item.data,
true, cmd.area, cmd.x, cmd.z, cmd.request_id);
session.next_drop_item.clear();
return HandlerResult::Type::SUPPRESS;
// Note: This static_cast is required to make compilers not complain that
// the comparison is always false (which even happens in some environments
// if we use -0x5E... apparently char is unsigned on some systems, or
// std::string's char_type isn't char??)
} else if ((static_cast<uint8_t>(data[0]) == 0xA2) &&
session.next_drop_item.data.data1d[0] &&
(session.version != GameVersion::BB)) {
const auto& cmd = check_size_t<G_BoxItemDropRequest_6xA2>(data);
session.next_drop_item.data.id = session.next_item_id++;
send_drop_item(session.server_channel, session.next_drop_item.data,
false, cmd.area, cmd.x, cmd.z, cmd.request_id);
send_drop_item(session.client_channel, session.next_drop_item.data,
false, cmd.area, cmd.x, cmd.z, cmd.request_id);
session.next_drop_item.clear();
return HandlerResult::Type::SUPPRESS;
} else if ((static_cast<uint8_t>(data[0]) == 0xB5) &&
(session.version == GameVersion::GC) &&
(data.size() > 4)) {
+1
View File
@@ -65,6 +65,7 @@ public:
ClientConfigBB newserv_client_config;
std::deque<bool> should_forward_function_call_return_queue;
G_SwitchStateChanged_6x05 last_switch_enabled_command;
PlayerInventoryItem next_drop_item;
uint32_t next_item_id;
struct LobbyPlayer {
+17 -7
View File
@@ -216,8 +216,10 @@ Proxy commands:\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 <code>\n\
Set the next item to be dropped as if the client had run the $item command.\n\
create-item <data>\n\
Create an item as if the client had run the $item command.\n\
set-next-item <data>\n\
Set the next item to be dropped.\n\
close-idle-sessions\n\
Closes all sessions that don\'t have a client and server connected.\n\
\n\
@@ -635,7 +637,7 @@ session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\
session->options.function_call_return_value = stoul(command_args);
}
} else if (command_name == "set-next-item") {
} else if ((command_name == "create-item") || (command_name == "set-next-item")) {
auto session = this->get_proxy_session(session_name);
if (session->version == GameVersion::BB) {
@@ -665,11 +667,19 @@ session with ID 17205AE4, run the command `on 17205AE4 sc 1D 00 04 00`.\n\
memcpy(&item.data.data2, data.data() + 12, data.size() - 12);
}
send_drop_stacked_item(session->client_channel, item.data, session->area, session->x, session->z);
send_drop_stacked_item(session->server_channel, item.data, session->area, session->x, session->z);
if (command_name == "set-next-item") {
session->next_drop_item = item;
string name = name_for_item(item.data, true);
send_text_message(session->client_channel, u"$C7Item created:\n" + decode_sjis(name));
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 {
send_drop_stacked_item(session->client_channel, item.data, session->area, session->x, session->z);
send_drop_stacked_item(session->server_channel, item.data, session->area, session->x, session->z);
string name = name_for_item(item.data, true);
send_text_message(session->client_channel, u"$C7Item created:\n" + decode_sjis(name));
}
} else if (command_name == "close-idle-sessions") {
size_t count = this->state->proxy_server->delete_disconnected_sessions();