make replay commands more usable
This commit is contained in:
+19
-17
@@ -8,14 +8,15 @@
|
||||
#include <phosg/Strings.hh>
|
||||
#include <phosg/Time.hh>
|
||||
|
||||
#include "Loggers.hh"
|
||||
#include "Server.hh"
|
||||
#include "ProxyServer.hh"
|
||||
#include "Lobby.hh"
|
||||
#include "Client.hh"
|
||||
#include "Lobby.hh"
|
||||
#include "Loggers.hh"
|
||||
#include "ProxyServer.hh"
|
||||
#include "ReceiveCommands.hh"
|
||||
#include "SendCommands.hh"
|
||||
#include "Text.hh"
|
||||
#include "Server.hh"
|
||||
#include "StaticGameData.hh"
|
||||
#include "Text.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -409,7 +410,7 @@ static void server_command_saverec(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
l->prev_battle_record.reset();
|
||||
}
|
||||
|
||||
static void server_command_playrec(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
static void server_command_playrec(shared_ptr<ServerState> s, shared_ptr<Lobby> l,
|
||||
shared_ptr<Client> c, const std::u16string& args) {
|
||||
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
|
||||
send_text_message(c, u"$C4This command can\nonly be used on\nEpisode 3");
|
||||
@@ -420,19 +421,20 @@ static void server_command_playrec(shared_ptr<ServerState>, shared_ptr<Lobby> l,
|
||||
return;
|
||||
}
|
||||
|
||||
if (l->is_game() && (l->flags & Lobby::Flag::EPISODE_3_ONLY) && (l->flags & Lobby::Flag::IS_SPECTATOR_TEAM) && l->battle_player) {
|
||||
l->flags |= Lobby::Flag::BATTLE_IN_PROGRESS;
|
||||
if (l->battle_player) {
|
||||
l->battle_player->start();
|
||||
|
||||
} else if (args.empty()) {
|
||||
c->next_game_battle_record.reset();
|
||||
send_text_message(c, u"$C6Replay state\ncleared");
|
||||
|
||||
} else {
|
||||
string filename = "system/ep3/battle-records/" + encode_sjis(args) + ".mzrd";
|
||||
string data = load_file(filename);
|
||||
c->next_game_battle_record.reset(new Episode3::BattleRecord(data));
|
||||
send_text_message(c, u"$C6Replay state set");
|
||||
uint32_t flags = Lobby::Flag::NON_V1_ONLY | Lobby::Flag::EPISODE_3_ONLY | Lobby::Flag::IS_SPECTATOR_TEAM;
|
||||
string filename = encode_sjis(args);
|
||||
if (filename[0] == '!') {
|
||||
flags |= Lobby::Flag::START_BATTLE_PLAYER_IMMEDIATELY;
|
||||
filename = filename.substr(1);
|
||||
}
|
||||
string data = load_file("system/ep3/battle-records/" + filename + ".mzrd");
|
||||
shared_ptr<Episode3::BattleRecord> record(new Episode3::BattleRecord(data));
|
||||
shared_ptr<Episode3::BattleRecordPlayer> battle_player(
|
||||
new Episode3::BattleRecordPlayer(record, s->game_server->get_base()));
|
||||
auto game = create_game_generic(s, c, args.c_str(), u"", 0xFF, 0, flags, battle_player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,6 @@ struct Client {
|
||||
bool can_chat;
|
||||
std::string pending_bb_save_username;
|
||||
uint8_t pending_bb_save_player_index;
|
||||
std::shared_ptr<const Episode3::BattleRecord> next_game_battle_record;
|
||||
|
||||
bool proxy_block_events;
|
||||
bool proxy_block_function_calls;
|
||||
|
||||
@@ -283,22 +283,26 @@ void BattleRecord::set_battle_end_timestamp() {
|
||||
|
||||
BattleRecordPlayer::BattleRecordPlayer(
|
||||
shared_ptr<const BattleRecord> rec,
|
||||
shared_ptr<struct event_base> base,
|
||||
shared_ptr<Lobby> l)
|
||||
shared_ptr<struct event_base> base)
|
||||
: record(rec),
|
||||
event_it(this->record->events.begin()),
|
||||
play_start_timestamp(0),
|
||||
base(base),
|
||||
lobby(l),
|
||||
next_command_ev(event_new(this->base.get(), -1, EV_TIMEOUT, &BattleRecordPlayer::dispatch_schedule_events, this), event_free) { }
|
||||
|
||||
shared_ptr<const BattleRecord> BattleRecordPlayer::get_record() const {
|
||||
return this->record;
|
||||
}
|
||||
|
||||
void BattleRecordPlayer::set_lobby(std::shared_ptr<Lobby> l) {
|
||||
this->lobby = l;
|
||||
}
|
||||
|
||||
void BattleRecordPlayer::start() {
|
||||
this->play_start_timestamp = now();
|
||||
this->schedule_events();
|
||||
if (this->play_start_timestamp == 0) {
|
||||
this->play_start_timestamp = now();
|
||||
this->schedule_events();
|
||||
}
|
||||
}
|
||||
|
||||
void BattleRecordPlayer::dispatch_schedule_events(
|
||||
@@ -348,10 +352,10 @@ void BattleRecordPlayer::schedule_events() {
|
||||
// This should have been handled before the lobby was even created
|
||||
break;
|
||||
case BattleRecord::Event::Type::BATTLE_COMMAND:
|
||||
send_command(l, 0xC9, 0x00, ev.data);
|
||||
send_command(l, (ev.data.size() >= 0x400) ? 0x6C : 0xC9, 0x00, ev.data);
|
||||
break;
|
||||
case BattleRecord::Event::Type::GAME_COMMAND:
|
||||
send_command(l, 0x60, 0x00, ev.data);
|
||||
send_command(l, (ev.data.size() >= 0x400) ? 0x6C : 0x60, 0x00, ev.data);
|
||||
break;
|
||||
case BattleRecord::Event::Type::EP3_GAME_COMMAND:
|
||||
send_command(l, 0xCB, 0x00, ev.data);
|
||||
|
||||
@@ -98,11 +98,12 @@ class BattleRecordPlayer {
|
||||
public:
|
||||
BattleRecordPlayer(
|
||||
std::shared_ptr<const BattleRecord> rec,
|
||||
std::shared_ptr<struct event_base> base,
|
||||
std::shared_ptr<Lobby> l);
|
||||
std::shared_ptr<struct event_base> base);
|
||||
~BattleRecordPlayer() = default;
|
||||
|
||||
std::shared_ptr<const BattleRecord> get_record() const;
|
||||
|
||||
void set_lobby(std::shared_ptr<Lobby> l);
|
||||
void start();
|
||||
|
||||
private:
|
||||
|
||||
+17
-16
@@ -22,26 +22,27 @@
|
||||
|
||||
struct Lobby {
|
||||
enum Flag {
|
||||
GAME = 0x00000001,
|
||||
EPISODE_3_ONLY = 0x00000002,
|
||||
NON_V1_ONLY = 0x00000004, // DC NTE and DCv1 not allowed
|
||||
PERSISTENT = 0x00000008,
|
||||
GAME = 0x00000001,
|
||||
EPISODE_3_ONLY = 0x00000002,
|
||||
NON_V1_ONLY = 0x00000004, // DC NTE and DCv1 not allowed
|
||||
PERSISTENT = 0x00000008,
|
||||
|
||||
// Flags used only for games
|
||||
CHEATS_ENABLED = 0x00000100,
|
||||
QUEST_IN_PROGRESS = 0x00000200,
|
||||
BATTLE_IN_PROGRESS = 0x00000400,
|
||||
JOINABLE_QUEST_IN_PROGRESS = 0x00000800,
|
||||
ITEM_TRACKING_ENABLED = 0x00001000,
|
||||
IS_SPECTATOR_TEAM = 0x00002000, // EPISODE_3_ONLY must also be set
|
||||
SPECTATORS_FORBIDDEN = 0x00004000,
|
||||
BATTLE_MODE = 0x00008000,
|
||||
CHALLENGE_MODE = 0x00010000,
|
||||
SOLO_MODE = 0x00020000,
|
||||
CHEATS_ENABLED = 0x00000100,
|
||||
QUEST_IN_PROGRESS = 0x00000200,
|
||||
BATTLE_IN_PROGRESS = 0x00000400,
|
||||
JOINABLE_QUEST_IN_PROGRESS = 0x00000800,
|
||||
ITEM_TRACKING_ENABLED = 0x00001000,
|
||||
IS_SPECTATOR_TEAM = 0x00002000, // EPISODE_3_ONLY must also be set
|
||||
SPECTATORS_FORBIDDEN = 0x00004000,
|
||||
BATTLE_MODE = 0x00008000,
|
||||
CHALLENGE_MODE = 0x00010000,
|
||||
SOLO_MODE = 0x00020000,
|
||||
START_BATTLE_PLAYER_IMMEDIATELY = 0x00040000,
|
||||
|
||||
// Flags used only for lobbies
|
||||
PUBLIC = 0x01000000,
|
||||
DEFAULT = 0x02000000,
|
||||
PUBLIC = 0x01000000,
|
||||
DEFAULT = 0x02000000,
|
||||
};
|
||||
|
||||
PrefixedLogger log;
|
||||
|
||||
+12
-10
@@ -1931,9 +1931,7 @@ static void on_chat_generic(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
|
||||
char private_flags = 0;
|
||||
u16string processed_text;
|
||||
if ((text[0] != '\t') &&
|
||||
(l->flags & Lobby::Flag::EPISODE_3_ONLY) &&
|
||||
l->ep3_server_base) {
|
||||
if ((text[0] != '\t') && (l->flags & Lobby::Flag::EPISODE_3_ONLY)) {
|
||||
private_flags = text[0];
|
||||
processed_text = remove_language_marker(text.substr(1));
|
||||
} else {
|
||||
@@ -2448,13 +2446,15 @@ static void on_set_blocked_senders_list(shared_ptr<ServerState>, shared_ptr<Clie
|
||||
|
||||
|
||||
|
||||
static shared_ptr<Lobby> create_game_generic(shared_ptr<ServerState> s,
|
||||
shared_ptr<Lobby> create_game_generic(
|
||||
shared_ptr<ServerState> s,
|
||||
shared_ptr<Client> c,
|
||||
const std::u16string& name,
|
||||
const std::u16string& password,
|
||||
uint8_t episode,
|
||||
uint8_t difficulty,
|
||||
uint32_t flags) {
|
||||
uint32_t flags,
|
||||
shared_ptr<Episode3::BattleRecordPlayer> battle_player) {
|
||||
|
||||
// A player's actual level is their displayed level - 1, so the minimums for
|
||||
// Episode 1 (for example) are actually 1, 20, 40, 80.
|
||||
@@ -2504,11 +2504,9 @@ static shared_ptr<Lobby> create_game_generic(shared_ptr<ServerState> s,
|
||||
game->random_seed = c->override_random_seed;
|
||||
game->random->seed(game->random_seed);
|
||||
}
|
||||
if (c->next_game_battle_record) {
|
||||
game->battle_player.reset(new Episode3::BattleRecordPlayer(
|
||||
c->next_game_battle_record, s->game_server->get_base(), game));
|
||||
c->next_game_battle_record.reset();
|
||||
game->flags |= Lobby::Flag::IS_SPECTATOR_TEAM;
|
||||
if (battle_player) {
|
||||
game->battle_player = battle_player;
|
||||
battle_player->set_lobby(game);
|
||||
}
|
||||
game->common_item_creator.reset(new CommonItemCreator(
|
||||
s->common_item_data, game->random));
|
||||
@@ -2694,6 +2692,10 @@ static void on_client_ready(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
if (c->version() == GameVersion::BB) {
|
||||
send_get_player_info(c);
|
||||
}
|
||||
|
||||
if (l->battle_player && (l->flags & Lobby::Flag::START_BATTLE_PLAYER_IMMEDIATELY)) {
|
||||
l->battle_player->start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,16 @@
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<Lobby> create_game_generic(
|
||||
std::shared_ptr<ServerState> s,
|
||||
std::shared_ptr<Client> c,
|
||||
const std::u16string& name,
|
||||
const std::u16string& password,
|
||||
uint8_t episode,
|
||||
uint8_t difficulty,
|
||||
uint32_t flags,
|
||||
std::shared_ptr<Episode3::BattleRecordPlayer> battle_player = nullptr);
|
||||
|
||||
void on_connect(std::shared_ptr<ServerState> s, std::shared_ptr<Client> c);
|
||||
void on_disconnect(std::shared_ptr<ServerState> s,
|
||||
std::shared_ptr<Client> c);
|
||||
|
||||
Reference in New Issue
Block a user