implement ep3 jukebox

This commit is contained in:
Martin Michelsen
2022-03-08 12:04:25 -08:00
parent 431484c3d3
commit d30a3220c8
5 changed files with 77 additions and 9 deletions
+18 -1
View File
@@ -362,6 +362,14 @@ static void check_is_game(shared_ptr<Lobby> l, bool is_game) {
}
}
static void check_is_ep3(shared_ptr<Client> c, bool is_ep3) {
if (!!(c->flags & ClientFlag::Episode3Games) != is_ep3) {
throw precondition_failed(is_ep3 ?
u"$C6This command can only\nbe used in Episode 3." :
u"$C6This command cannot\nbe used in Episode 3.");
}
}
static void check_cheats_enabled(shared_ptr<Lobby> l) {
if (!(l->flags & LobbyFlag::CheatsEnabled)) {
throw precondition_failed(u"$C6This command can\nonly be used in\ncheat mode.");
@@ -817,6 +825,14 @@ static void command_warp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
send_warp(c, area);
}
static void command_song(shared_ptr<ServerState>, shared_ptr<Lobby>,
shared_ptr<Client> c, const char16_t* args) {
check_is_ep3(c, true);
uint32_t song = stoul(encode_sjis(args), nullptr, 0);
send_ep3_change_music(c, song);
}
static void command_infinite_hp(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const char16_t*) {
check_is_game(l, true);
@@ -890,10 +906,11 @@ static const unordered_map<u16string, ChatCommandDefinition> chat_commands({
{u"item" , {command_item , u"Usage:\nitem <item-code>"}},
{u"kick" , {command_kick , u"Usage:\nkick <name-or-number>"}},
{u"li" , {command_lobby_info , u"Usage:\nli"}},
{u"password" , {command_password , u"Usage:\nlock [password]\nomit password to\nunlock game"}},
{u"maxlevel" , {command_max_level , u"Usage:\nmax_level <level>"}},
{u"minlevel" , {command_min_level , u"Usage:\nmin_level <level>"}},
{u"password" , {command_password , u"Usage:\nlock [password]\nomit password to\nunlock game"}},
{u"silence" , {command_silence , u"Usage:\nsilence <name-or-number>"}},
{u"song" , {command_song , u"Usage:\nsong <song-number>"}},
{u"type" , {command_lobby_type , u"Usage:\ntype <name>"}},
{u"warp" , {command_warp , u"Usage:\nwarp <area-number>"}},
});
+14 -5
View File
@@ -463,18 +463,27 @@ void process_server_time_request(shared_ptr<ServerState>, shared_ptr<Client> c,
void process_ep3_jukebox(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint16_t command, uint32_t, uint16_t size, const void* data) {
struct Cmd {
uint32_t unknown[3]; // should be FFFFFFFF 00000000
struct InputCmd {
uint32_t transaction_num;
uint32_t value;
uint32_t unknown_token;
};
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
struct OutputCmd {
uint32_t remaining_meseta;
uint32_t unknown;
uint32_t unknown_token;
};
check_size(size, sizeof(InputCmd));
const auto* in_cmd = reinterpret_cast<const InputCmd*>(data);
OutputCmd out_cmd = {1000000, 0x80E8, in_cmd->unknown_token};
auto l = s->find_lobby(c->lobby_id);
if (!l || !(l->flags & LobbyFlag::Episode3)) {
return;
}
send_command(l, command, 0x03, cmd);
send_command(c, command, 0x03, &out_cmd, sizeof(out_cmd));
}
void process_ep3_menu_challenge(shared_ptr<ServerState>, shared_ptr<Client> c,
+11 -2
View File
@@ -869,6 +869,15 @@ static void process_subcommand_forward_check_size_game(shared_ptr<ServerState>,
forward_subcommand(l, c, command, flag, p, count);
}
static void process_subcommand_forward_check_size_ep3_lobby(shared_ptr<ServerState>,
shared_ptr<Lobby> l, shared_ptr<Client> c, uint8_t command, uint8_t flag,
const PSOSubcommand* p, size_t count) {
if (!(l->flags & LobbyFlag::Episode3) || l->is_game() || (p->byte[1] != count)) {
return;
}
forward_subcommand(l, c, command, flag, p, count);
}
static void process_subcommand_invalid(shared_ptr<ServerState>,
shared_ptr<Lobby>, shared_ptr<Client>, uint8_t command, uint8_t flag,
const PSOSubcommand* p, size_t count) {
@@ -951,7 +960,7 @@ subcommand_handler_t subcommand_handlers[0x100] = {
process_subcommand_drop_item,
process_subcommand_unimplemented,
process_subcommand_forward_check_size,
process_subcommand_forward_check_size_game,
process_subcommand_forward_check_size,
process_subcommand_unimplemented,
process_subcommand_hit_by_monster,
// 30
@@ -1106,7 +1115,7 @@ subcommand_handler_t subcommand_handlers[0x100] = {
process_subcommand_unimplemented,
process_subcommand_bank_action,
process_subcommand_unimplemented,
process_subcommand_unimplemented,
process_subcommand_forward_check_size_ep3_lobby,
// C0
process_subcommand_unimplemented,
process_subcommand_unimplemented,
+29 -1
View File
@@ -1847,7 +1847,6 @@ void send_player_stats_change(shared_ptr<Lobby> l, shared_ptr<Client> c,
send_command(l, 0x60, 0x00, subs);
}
// sends a player to the given area.
void send_warp(shared_ptr<Client> c, uint32_t area) {
PSOSubcommand cmds[2];
cmds[0].byte[0] = 0x94;
@@ -1858,6 +1857,35 @@ void send_warp(shared_ptr<Client> c, uint32_t area) {
send_command(c, 0x62, c->lobby_client_id, cmds, 8);
}
void send_ep3_change_music(shared_ptr<Client> c, uint32_t song) {
PSOSubcommand cmds[2];
cmds[0].byte[0] = 0xBF;
cmds[0].byte[1] = 0x02;
cmds[0].byte[2] = c->lobby_client_id;
cmds[0].byte[3] = 0x00;
cmds[1].dword = song;
send_command(c, 0x60, 0x00, cmds, 8);
}
void send_set_player_visibility(shared_ptr<Lobby> l, shared_ptr<Client> c,
bool visible) {
PSOSubcommand cmd;
cmd.byte[0] = visible ? 0x23 : 0x22;
cmd.byte[1] = 0x01;
cmd.byte[2] = c->lobby_client_id;
cmd.byte[3] = 0x00;
send_command(l, 0x60, 0x00, &cmd, 4);
}
void send_revive_player(shared_ptr<Lobby> l, shared_ptr<Client> c) {
PSOSubcommand cmd;
cmd.byte[0] = 0x31;
cmd.byte[1] = 0x01;
cmd.byte[2] = c->lobby_client_id;
cmd.byte[3] = 0x00;
send_command(l, 0x60, 0x00, &cmd, 4);
}
////////////////////////////////////////////////////////////////////////////////
+5
View File
@@ -158,6 +158,11 @@ void send_player_stats_change(std::shared_ptr<Lobby> l, std::shared_ptr<Client>
PlayerStatsChange which, uint32_t amount);
void send_warp(std::shared_ptr<Client> c, uint32_t area);
void send_ep3_change_music(std::shared_ptr<Client> c, uint32_t song);
void send_set_player_visibility(std::shared_ptr<Lobby> l,
std::shared_ptr<Client> c, bool visible);
void send_revive_player(std::shared_ptr<Lobby> l, std::shared_ptr<Client> c);
void send_drop_item(std::shared_ptr<Lobby> l, const ItemData& item,
bool from_enemy, uint8_t area, float x, float y, uint16_t request_id);
void send_drop_stacked_item(std::shared_ptr<Lobby> l, const ItemData& item,