Move Data, Plugin, Script, Packet access from Strings to Paths (#1839)

* Move Data, Plugin, Script, Packet access from Strings to Paths
- No longer dump default Data files to folder on launch
- Allow Scripts to be loaded from Resources zip
- Lay groundwork for Plugins to be loaded from zip
This commit is contained in:
Luke H-W
2022-10-07 23:01:08 +10:30
committed by GitHub
parent f6ce7e349d
commit dd6e1bb8a3
21 changed files with 242 additions and 244 deletions

View File

@@ -2,7 +2,8 @@ package emu.grasscutter.server.game;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.Set;
import java.nio.file.Path;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerDebugMode;
import emu.grasscutter.game.Account;
@@ -16,6 +17,8 @@ import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import lombok.Setter;
import static emu.grasscutter.config.Configuration.*;
import static emu.grasscutter.utils.Language.translate;
@@ -24,14 +27,14 @@ public class GameSession implements GameSessionManager.KcpChannel {
private final GameServer server;
private GameSessionManager.KcpTunnel tunnel;
private Account account;
private Player player;
@Getter @Setter private Account account;
@Getter private Player player;
private boolean useSecretKey;
private SessionState state;
@Setter private boolean useSecretKey;
@Getter @Setter private SessionState state;
private int clientTime;
private long lastPingTime;
@Getter private int clientTime;
@Getter private long lastPingTime;
private int lastClientSeq = 10;
public GameSession(GameServer server) {
@@ -56,52 +59,20 @@ public class GameSession implements GameSessionManager.KcpChannel {
return useSecretKey;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getAccountId() {
return this.getAccount().getId();
}
public Player getPlayer() {
return player;
}
public synchronized void setPlayer(Player player) {
this.player = player;
this.player.setSession(this);
this.player.setAccount(this.getAccount());
}
public SessionState getState() {
return state;
}
public void setState(SessionState state) {
this.state = state;
}
public boolean isLoggedIn() {
return this.getPlayer() != null;
}
public void setUseSecretKey(boolean useSecretKey) {
this.useSecretKey = useSecretKey;
}
public int getClientTime() {
return this.clientTime;
}
public long getLastPingTime() {
return lastPingTime;
}
public void updateLastPingTime(int clientTime) {
this.clientTime = clientTime;
this.lastPingTime = System.currentTimeMillis();
@@ -112,8 +83,8 @@ public class GameSession implements GameSessionManager.KcpChannel {
}
public void replayPacket(int opcode, String name) {
String filePath = PACKET(name);
File p = new File(filePath);
Path filePath = FileUtils.getPluginPath(name);
File p = filePath.toFile();
if (!p.exists()) return;

View File

@@ -11,42 +11,38 @@ import emu.grasscutter.data.excels.MonsterData;
import emu.grasscutter.data.excels.SceneData;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Language;
import emu.grasscutter.utils.Utils;
import io.javalin.http.ContentType;
import io.javalin.http.Context;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
final class HandbookRequestHandler implements DocumentationHandler {
private List<String> handbookHtmls;
private final String template;
public HandbookRequestHandler() {
final File templateFile = new File(Utils.toFilePath(DATA("documentation/handbook.html")));
if (templateFile.exists()) {
this.template = new String(FileUtils.read(templateFile), StandardCharsets.UTF_8);
this.handbookHtmls = generateHandbookHtmls();
} else {
Grasscutter.getLogger().warn("File does not exist: " + templateFile);
this.template = null;
var templatePath = FileUtils.getDataPath("documentation/handbook.html");
try {
this.handbookHtmls = generateHandbookHtmls(Files.readString(templatePath));
} catch (IOException ignored) {
Grasscutter.getLogger().warn("File does not exist: " + templatePath);
}
}
@Override
public void handle(Context ctx) {
final int langIdx = Language.TextStrings.MAP_LANGUAGES.getOrDefault(DOCUMENT_LANGUAGE, 0); // TODO: This should really be based off the client language somehow
if (template == null) {
if (this.handbookHtmls == null) {
ctx.status(500);
} else {
ctx.contentType(ContentType.TEXT_HTML);
ctx.result(handbookHtmls.get(langIdx));
ctx.result(this.handbookHtmls.get(langIdx));
}
}
private List<String> generateHandbookHtmls() {
private List<String> generateHandbookHtmls(String template) {
final int NUM_LANGUAGES = Language.TextStrings.NUM_LANGUAGES;
final List<String> output = new ArrayList<>(NUM_LANGUAGES);
final List<Language> languages = Language.TextStrings.getLanguages();

View File

@@ -1,29 +1,28 @@
package emu.grasscutter.server.http.documentation;
import static emu.grasscutter.config.Configuration.DATA;
import static emu.grasscutter.utils.Language.translate;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils;
import io.javalin.http.ContentType;
import io.javalin.http.Context;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.nio.file.Files;
final class RootRequestHandler implements DocumentationHandler {
private final String template;
public RootRequestHandler() {
final File templateFile = new File(Utils.toFilePath(DATA("documentation/index.html")));
if (templateFile.exists()) {
template = new String(FileUtils.read(templateFile), StandardCharsets.UTF_8);
} else {
Grasscutter.getLogger().warn("File does not exist: " + templateFile);
template = null;
var templatePath = FileUtils.getDataPath("documentation/index.html");
String t = null;
try {
t = Files.readString(templatePath);
} catch (IOException ignored) {
Grasscutter.getLogger().warn("File does not exist: " + templatePath);
}
this.template = t;
}
@Override

View File

@@ -5,7 +5,6 @@ import emu.grasscutter.data.DataLoader;
import emu.grasscutter.server.http.objects.HttpJsonResponse;
import emu.grasscutter.server.http.Router;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils;
import io.javalin.Javalin;
import io.javalin.http.ContentType;
import io.javalin.http.Context;
@@ -74,7 +73,7 @@ public final class AnnouncementsHandler implements Router {
private static void getPageResources(Context ctx) {
try (InputStream filestream = DataLoader.load(ctx.path())) {
String possibleFilename = Utils.toFilePath(DATA(ctx.path()));
String possibleFilename = ctx.path();
ContentType fromExtension = ContentType.getContentTypeByExtension(possibleFilename.substring(possibleFilename.lastIndexOf(".") + 1));
ctx.contentType(fromExtension != null ? fromExtension : ContentType.APPLICATION_OCTET_STREAM);

View File

@@ -13,31 +13,36 @@ 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.File;
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 static emu.grasscutter.config.Configuration.DATA;
import static emu.grasscutter.utils.Language.translate;
/**
* Handles all gacha-related HTTP requests.
*/
public final class GachaHandler implements Router {
public static final String gachaMappings = DATA(Utils.toFilePath("gacha/mappings.js"));
@Getter private static final Path gachaMappingsPath = FileUtils.getDataUserPath("gacha/mappings.js");
@Deprecated(forRemoval = true)
public static final String gachaMappings = gachaMappingsPath.toString();
@Override public void applyRoutes(Javalin javalin) {
javalin.get("/gacha", GachaHandler::gachaRecords);
javalin.get("/gacha/details", GachaHandler::gachaDetails);
javalin._conf.addSinglePageRoot("/gacha/mappings", gachaMappings, Location.EXTERNAL);
javalin._conf.addSinglePageRoot("/gacha/mappings", gachaMappingsPath.toString(), Location.EXTERNAL); // TODO: This ***must*** be changed to take the Path not a String. This might involve upgrading Javalin.
}
private static void gachaRecords(Context ctx) {
File recordsTemplate = new File(Utils.toFilePath(DATA("gacha/records.html")));
File recordsTemplate = FileUtils.getDataPath("gacha/records.html").toFile();
if (!recordsTemplate.exists()) {
Grasscutter.getLogger().warn("File does not exist: " + recordsTemplate);
ctx.status(500);
@@ -77,13 +82,7 @@ public final class GachaHandler implements Router {
}
private static void gachaDetails(Context ctx) {
File detailsTemplate = new File(Utils.toFilePath(DATA("gacha/details.html")));
if (!detailsTemplate.exists()) {
Grasscutter.getLogger().warn("File does not exist: " + detailsTemplate);
ctx.status(500);
return;
}
Path detailsTemplate = FileUtils.getDataPath("gacha/details.html");
String sessionKey = ctx.queryParam("s");
Account account = DatabaseHelper.getAccountBySessionKey(sessionKey);
if (account == null) {
@@ -96,7 +95,14 @@ public final class GachaHandler implements Router {
return;
}
String template = new String(FileUtils.read(detailsTemplate), StandardCharsets.UTF_8);
String template;
try {
template = Files.readString(detailsTemplate);
} catch (IOException e) {
Grasscutter.getLogger().warn("Failed to read data/gacha/details.html");
ctx.status(500);
return;
}
// Add translated title etc. to the page.
template = template.replace("{{TITLE}}", translate(player, "gacha.details.title"))