load correct version of quest in cross-play games

This commit is contained in:
Martin Michelsen
2023-10-08 15:45:36 -07:00
parent 812310054c
commit 226140deb7
+43 -41
View File
@@ -1987,7 +1987,7 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
case MenuID::QUEST: { case MenuID::QUEST: {
auto s = c->require_server_state(); auto s = c->require_server_state();
if (!s->quest_index) { if (!s->quest_index) {
send_lobby_message_box(c, u"$C6Quests are not available."); send_lobby_message_box(c, u"$C6Quests are not\navailable.");
break; break;
} }
auto q = s->quest_index->get(item_id); auto q = s->quest_index->get(item_id);
@@ -1995,11 +1995,6 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
send_lobby_message_box(c, u"$C6Quest does not exist."); send_lobby_message_box(c, u"$C6Quest does not exist.");
break; break;
} }
auto vq = q->version(c->quest_version());
if (!vq) {
send_lobby_message_box(c, u"$C6Quest does not exist\nfor this game version.");
break;
}
// If the client is not in a lobby, send the quest as a download quest. // If the client is not in a lobby, send the quest as a download quest.
// Otherwise, they must be in a game to load a quest. // Otherwise, they must be in a game to load a quest.
@@ -2009,19 +2004,14 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
break; break;
} }
bool is_ep3 = (q->episode == Episode::EP3);
string bin_basename = vq->bin_filename();
shared_ptr<const string> bin_contents = vq->bin_contents();
string dat_basename;
shared_ptr<const string> dat_contents;
if (!is_ep3) {
dat_basename = vq->dat_filename();
dat_contents = vq->dat_contents();
}
if (l) { if (l) {
if (is_ep3 || !dat_contents) { if (q->episode == Episode::EP3) {
throw runtime_error("episode 3 quests cannot be loaded during games"); send_lobby_message_box(c, u"$C6Episode 3 quests\ncannot be loaded\nvia this interface.");
break;
}
if (l->quest) {
send_lobby_message_box(c, u"$C6A quest is already\nin progress.");
break;
} }
if (q->joinable) { if (q->joinable) {
l->flags |= Lobby::Flag::JOINABLE_QUEST_IN_PROGRESS; l->flags |= Lobby::Flag::JOINABLE_QUEST_IN_PROGRESS;
@@ -2031,26 +2021,35 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
l->quest = q; l->quest = q;
l->episode = q->episode; l->episode = q->episode;
for (size_t x = 0; x < l->max_clients; x++) { for (size_t x = 0; x < l->max_clients; x++) {
if (!l->clients[x]) { auto lc = l->clients[x];
if (!lc) {
continue; continue;
} }
send_open_quest_file(l->clients[x], bin_basename + ".bin", auto vq = q->version(lc->quest_version());
bin_basename, bin_contents, QuestFileType::ONLINE); if (!vq) {
send_open_quest_file(l->clients[x], dat_basename + ".dat", send_lobby_message_box(lc, u"$C6Quest does not exist\nfor this game version.");
dat_basename, dat_contents, QuestFileType::ONLINE); lc->should_disconnect = true;
break;
}
string bin_filename = vq->bin_filename();
string dat_filename = vq->dat_filename();
shared_ptr<const string> bin_contents = vq->bin_contents();
shared_ptr<const string> dat_contents = vq->dat_contents();
send_open_quest_file(lc, bin_filename, bin_filename, bin_contents, QuestFileType::ONLINE);
send_open_quest_file(lc, dat_filename, dat_filename, dat_contents, QuestFileType::ONLINE);
// There is no such thing as command AC on PSO V2 - quests just start // There is no such thing as command AC on PSO V1 and V2 - quests just
// immediately when they're done downloading. (This is also the case // start immediately when they're done downloading. (This is also the
// on V3 Trial Edition.) There are also no chunk acknowledgements // case on V3 Trial Edition.) There are also no chunk acknowledgements
// (C->S 13 commands) like there are on GC. So, for PC/Trial clients, // (C->S 13 commands) like there are on GC. So, for pre-V3 clients, we
// we can just not set the loading flag, since we never need to // can just not set the loading flag, since we never need to
// check/clear it later. // check/clear it later.
if ((l->clients[x]->version() != GameVersion::DC) && if ((lc->version() != GameVersion::DC) &&
(l->clients[x]->version() != GameVersion::PC) && (lc->version() != GameVersion::PC) &&
!(l->clients[x]->flags & Client::Flag::IS_GC_TRIAL_EDITION)) { !(lc->flags & Client::Flag::IS_GC_TRIAL_EDITION)) {
l->clients[x]->flags |= Client::Flag::LOADING_QUEST; lc->flags |= Client::Flag::LOADING_QUEST;
l->clients[x]->disconnect_hooks.emplace(QUEST_BARRIER_DISCONNECT_HOOK_NAME, [l]() -> void { lc->disconnect_hooks.emplace(QUEST_BARRIER_DISCONNECT_HOOK_NAME, [l]() -> void {
send_quest_barrier_if_all_clients_ready(l); send_quest_barrier_if_all_clients_ready(l);
}); });
} }
@@ -2058,19 +2057,22 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
} else { } else {
string quest_name = encode_sjis(q->name); string quest_name = encode_sjis(q->name);
auto vq = q->version(c->quest_version());
if (!vq) {
send_lobby_message_box(c, u"$C6Quest does not exist\nfor this game version.");
break;
}
// Episode 3 uses the download quest commands (A6/A7) but does not // Episode 3 uses the download quest commands (A6/A7) but does not
// expect the server to have already encrypted the quest files, unlike // expect the server to have already encrypted the quest files, unlike
// other versions. // other versions.
// TODO: This is not true for Episode 3 Trial Edition. We also would // TODO: This is not true for Episode 3 Trial Edition. We also would
// have to convert the map to MapDefinitionTrial, though. // have to convert the map to a MapDefinitionTrial, though.
if (!is_ep3) { if (vq->version == QuestScriptVersion::GC_EP3) {
send_open_quest_file(c, quest_name, vq->bin_filename(), vq->bin_contents(), QuestFileType::EPISODE_3);
} else {
vq = vq->create_download_quest(); vq = vq->create_download_quest();
} send_open_quest_file(c, quest_name, vq->bin_filename(), vq->bin_contents(), QuestFileType::DOWNLOAD);
send_open_quest_file(c, quest_name, bin_basename, vq->bin_contents(), send_open_quest_file(c, quest_name, vq->dat_filename(), vq->dat_contents(), QuestFileType::DOWNLOAD);
is_ep3 ? QuestFileType::EPISODE_3 : QuestFileType::DOWNLOAD);
if (dat_contents) {
send_open_quest_file(c, quest_name, dat_basename, vq->dat_contents(),
is_ep3 ? QuestFileType::EPISODE_3 : QuestFileType::DOWNLOAD);
} }
} }
break; break;