Separate the dispatch and game servers (pt. 1)

gacha is still broken, handbook still needs to be done
This commit is contained in:
KingRainbow44
2023-05-15 00:43:16 -04:00
parent 97fbbdca84
commit bcc9ae10cd
28 changed files with 1225 additions and 379 deletions

View File

@@ -1,28 +1,27 @@
package emu.grasscutter.server.http.handlers;
import static emu.grasscutter.utils.Language.translate;
import com.google.gson.JsonObject;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.gacha.GachaBanner;
import emu.grasscutter.game.gacha.GachaSystem;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.http.Router;
import emu.grasscutter.utils.DispatchUtils;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils;
import io.javalin.Javalin;
import io.javalin.http.ContentType;
import io.javalin.http.Context;
import io.javalin.http.staticfiles.Location;
import lombok.Getter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import lombok.Getter;
import static emu.grasscutter.utils.Language.translate;
/** Handles all gacha-related HTTP requests. */
public final class GachaHandler implements Router {
@@ -33,55 +32,52 @@ public final class GachaHandler implements Router {
public static final String gachaMappings = gachaMappingsPath.toString();
private static void gachaRecords(Context ctx) {
String sessionKey = ctx.queryParam("s");
Account account = DatabaseHelper.getAccountBySessionKey(sessionKey);
var sessionKey = ctx.queryParam("s");
var account = DatabaseHelper.getAccountBySessionKey(sessionKey);
if (account == null) {
ctx.status(403).result("Requested account was not found");
return;
}
Player player = Grasscutter.getGameServer().getPlayerByAccountId(account.getId());
if (player == null) {
ctx.status(403).result("No player associated with requested account");
ctx.status(403).result("Requested account was not found.");
return;
}
// Get page and gacha type.
int page = 0, gachaType = 0;
if (ctx.queryParam("p") != null) page = Integer.parseInt(ctx.queryParam("p"));
if (ctx.queryParam("gachaType") != null)
gachaType = Integer.parseInt(ctx.queryParam("gachaType"));
String records = DatabaseHelper.getGachaRecords(player.getUid(), page, gachaType).toString();
long maxPage = DatabaseHelper.getGachaRecordsMaxPage(player.getUid(), page, gachaType);
var pageStr = ctx.queryParam("p");
if (pageStr != null) page = Integer.parseInt(pageStr);
String template =
var gachaTypeStr = ctx.queryParam("gachaType");
if (gachaTypeStr != null) gachaType = Integer.parseInt(gachaTypeStr);
// Make request to dispatch server.
var data = DispatchUtils.fetchGachaRecords(
account.getId(), page, gachaType);
var records = data.get("records").getAsString();
var maxPage = data.get("maxPage").getAsLong();
var locale = account.getLocale();
var template =
new String(
FileUtils.read(FileUtils.getDataPath("gacha/records.html")), StandardCharsets.UTF_8)
.replace("{{REPLACE_RECORDS}}", records)
.replace("{{REPLACE_MAXPAGE}}", String.valueOf(maxPage))
.replace("{{TITLE}}", translate(player, "gacha.records.title"))
.replace("{{DATE}}", translate(player, "gacha.records.date"))
.replace("{{ITEM}}", translate(player, "gacha.records.item"))
.replace("'{{REPLACE_RECORDS}}'", records)
.replace("'{{REPLACE_MAXPAGE}}'", String.valueOf(maxPage))
.replace("{{TITLE}}", translate(locale, "gacha.records.title"))
.replace("{{DATE}}", translate(locale, "gacha.records.date"))
.replace("{{ITEM}}", translate(locale, "gacha.records.item"))
.replace("{{LANGUAGE}}", Utils.getLanguageCode(account.getLocale()));
ctx.contentType(ContentType.TEXT_HTML);
ctx.result(template);
}
private static void gachaDetails(Context ctx) {
Path detailsTemplate = FileUtils.getDataPath("gacha/details.html");
String sessionKey = ctx.queryParam("s");
Account account = DatabaseHelper.getAccountBySessionKey(sessionKey);
var detailsTemplate = FileUtils.getDataPath("gacha/details.html");
var sessionKey = ctx.queryParam("s");
var account = DatabaseHelper.getAccountBySessionKey(sessionKey);
if (account == null) {
ctx.status(403).result("Requested account was not found");
return;
}
Player player = Grasscutter.getGameServer().getPlayerByAccountId(account.getId());
if (player == null) {
ctx.status(403).result("No player associated with requested account");
return;
}
String template;
try {
String template;try {
template = Files.readString(detailsTemplate);
} catch (IOException e) {
Grasscutter.getLogger().warn("Failed to read data/gacha/details.html");
@@ -90,27 +86,35 @@ public final class GachaHandler implements Router {
}
// Add translated title etc. to the page.
var locale = account.getLocale();
template =
template
.replace("{{TITLE}}", translate(player, "gacha.details.title"))
.replace("{{TITLE}}", translate(locale, "gacha.details.title"))
.replace(
"{{AVAILABLE_FIVE_STARS}}", translate(player, "gacha.details.available_five_stars"))
"{{AVAILABLE_FIVE_STARS}}", translate(locale, "gacha.details.available_five_stars"))
.replace(
"{{AVAILABLE_FOUR_STARS}}", translate(player, "gacha.details.available_four_stars"))
"{{AVAILABLE_FOUR_STARS}}", translate(locale, "gacha.details.available_four_stars"))
.replace(
"{{AVAILABLE_THREE_STARS}}",
translate(player, "gacha.details.available_three_stars"))
translate(locale, "gacha.details.available_three_stars"))
.replace("{{LANGUAGE}}", Utils.getLanguageCode(account.getLocale()));
// Get the banner info for the banner we want.
int scheduleId = Integer.parseInt(ctx.queryParam("scheduleId"));
GachaSystem manager = Grasscutter.getGameServer().getGachaSystem();
GachaBanner banner = manager.getGachaBanners().get(scheduleId);
var scheduleIdStr = ctx.queryParam("scheduleId");
if (scheduleIdStr == null) {
ctx.status(400).result("Missing scheduleId parameter");
return;
}
var scheduleId = Integer.parseInt(scheduleIdStr);
var manager = Grasscutter.getGameServer().getGachaSystem();
var banner = manager.getGachaBanners().get(scheduleId);
// Add 5-star items.
Set<String> fiveStarItems = new LinkedHashSet<>();
var fiveStarItems = new LinkedHashSet<String>();
Arrays.stream(banner.getRateUpItems5()).forEach(i -> fiveStarItems.add(Integer.toString(i)));
Arrays.stream(banner.getRateUpItems5())
.forEach(i -> fiveStarItems.add(Integer.toString(i)));
Arrays.stream(banner.getFallbackItems5Pool1())
.forEach(i -> fiveStarItems.add(Integer.toString(i)));
Arrays.stream(banner.getFallbackItems5Pool2())
@@ -119,9 +123,10 @@ public final class GachaHandler implements Router {
template = template.replace("{{FIVE_STARS}}", "[" + String.join(",", fiveStarItems) + "]");
// Add 4-star items.
Set<String> fourStarItems = new LinkedHashSet<>();
var fourStarItems = new LinkedHashSet<String>();
Arrays.stream(banner.getRateUpItems4()).forEach(i -> fourStarItems.add(Integer.toString(i)));
Arrays.stream(banner.getRateUpItems4())
.forEach(i -> fourStarItems.add(Integer.toString(i)));
Arrays.stream(banner.getFallbackItems4Pool1())
.forEach(i -> fourStarItems.add(Integer.toString(i)));
Arrays.stream(banner.getFallbackItems4Pool2())
@@ -130,8 +135,9 @@ public final class GachaHandler implements Router {
template = template.replace("{{FOUR_STARS}}", "[" + String.join(",", fourStarItems) + "]");
// Add 3-star items.
Set<String> threeStarItems = new LinkedHashSet<>();
Arrays.stream(banner.getFallbackItems3()).forEach(i -> threeStarItems.add(Integer.toString(i)));
var threeStarItems = new LinkedHashSet<String>();
Arrays.stream(banner.getFallbackItems3())
.forEach(i -> threeStarItems.add(Integer.toString(i)));
template = template.replace("{{THREE_STARS}}", "[" + String.join(",", threeStarItems) + "]");
// Done.
@@ -139,6 +145,30 @@ public final class GachaHandler implements Router {
ctx.result(template);
}
/**
* Fetches the gacha records for the specified player.
*
* @param player The player to fetch the records for.
* @param response The response to write to.
* @param page The page to fetch.
* @param type The gacha type to fetch.
*/
public static void fetchGachaRecords(
Player player, JsonObject response,
int page, int type
) {
var playerId = player.getUid();
var records = DatabaseHelper.getGachaRecords(
playerId, page, type).toString();
var maxPage = DatabaseHelper.getGachaRecordsMaxPage(
playerId, page, type);
// Finish the response.
response.addProperty("retcode", 0);
response.addProperty("records", records);
response.addProperty("maxPage", maxPage);
}
@Override
public void applyRoutes(Javalin javalin) {
javalin.get("/gacha", GachaHandler::gachaRecords);