diff --git a/data/GameAnnouncement.json b/data/GameAnnouncement.json
index 96c88f17c..57cd72c8e 100644
--- a/data/GameAnnouncement.json
+++ b/data/GameAnnouncement.json
@@ -1,19 +1,19 @@
{
+ "t": "{{SYSTEM_TIME}}",
"list": [
{
"ann_id": 1,
"title": "Welcome to Grasscutter!",
"subtitle": "Welcome!",
- "banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/17/f4aa42d505822805eebf4a55d72a78d8_2755691727027973637.jpg",
+ "banner": "{{DISPATCH_PUBLIC}}/hk4e/announcement/assets/banner/1.jpg",
"content": "
Hi there!
First of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you!
〓Discord〓
https://discord.gg/T5vZU6UyeG
〓GitHub〓https://github.com/Grasscutters/Grasscutter",
-
"lang": "en-US"
},
{
"ann_id": 2,
"title": "How to use announcements",
"subtitle": "How to use announcements",
- "banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/17/f4aa42d505822805eebf4a55d72a78d8_2755691727027973637.jpg",
+ "banner": "{{DISPATCH_PUBLIC}}/hk4e/announcement/assets/banner/2.jpg",
"content": "
Announcement content uses HTML. The specific content of the announcement is stored in the program directory GameAnnouncement.json
, while GameAnnouncementList.json
stores the announcement list data.
GameAnnouncement
Parameter | Description |
---|
ann_id | Unique ID |
title | Title shown at the top of the content |
subtitle | Short title shown on the left |
banner | Image to display between content and title |
content | Content body in HTML |
lang | Language code for this entry |
GameAnnouncementList
If you want to add an announcement, please add the list data in the announcement type corresponding to GameAnnouncementList
, and finally add the announcement content in GameAnnouncement
.
",
"lang": "en-US"
}
diff --git a/data/GameAnnouncementList.json b/data/GameAnnouncementList.json
index 7464b3b0f..3697703a3 100644
--- a/data/GameAnnouncementList.json
+++ b/data/GameAnnouncementList.json
@@ -1,15 +1,14 @@
{
- "t": "System.currentTimeMillis()",
+ "t": "{{SYSTEM_TIME}}",
"list": [
{
"list": [
{
"ann_id": 1,
-
"title": "Welcome to Grasscutter!",
"subtitle": "Welcome!",
- "banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/22/7d85f19b152d218e73224d7c138a0fd0_5818585260283672899.jpg",
- "tag_icon": "https://uploadstatic-sea.mihoyo.com/announcement/2020/03/05/a2588f1a51faee9fa8dfe9aead649dd6_7237021399135895303.png",
+ "banner": "{{DISPATCH_PUBLIC}}/hk4e/announcement/assets/banner/1.jpg",
+ "tag_icon": "{{DISPATCH_PUBLIC}}/hk4e/announcement/assets/tag_icon.png",
"type": 2,
"type_label": "System",
"lang": "en-US",
@@ -22,8 +21,8 @@
"ann_id": 2,
"title": "How to use announcements",
"subtitle": "How to use announcements",
- "banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/22/7d85f19b152d218e73224d7c138a0fd0_5818585260283672899.jpg",
- "tag_icon": "https://uploadstatic-sea.mihoyo.com/announcement/2020/03/05/a2588f1a51faee9fa8dfe9aead649dd6_7237021399135895303.png",
+ "banner": "{{DISPATCH_PUBLIC}}/hk4e/announcement/assets/banner/2.jpg",
+ "tag_icon": "{{DISPATCH_PUBLIC}}/hk4e/announcement/assets/tag_icon.png",
"type": 2,
"type_label": "System",
"lang": "en-US",
@@ -59,11 +58,5 @@
],
"timezone": -5,
"alert": false,
- "alert_id": 0,
- "pic_list": [],
- "pic_total": 0,
- "pic_type_list": [],
- "pic_alert": false,
- "pic_alert_id": 0,
- "static_sign": ""
+ "alert_id": 0
}
\ No newline at end of file
diff --git a/src/main/java/emu/grasscutter/server/http/handlers/AnnouncementsHandler.java b/src/main/java/emu/grasscutter/server/http/handlers/AnnouncementsHandler.java
index 1b87225e9..c4776a4b4 100644
--- a/src/main/java/emu/grasscutter/server/http/handlers/AnnouncementsHandler.java
+++ b/src/main/java/emu/grasscutter/server/http/handlers/AnnouncementsHandler.java
@@ -6,6 +6,7 @@ import emu.grasscutter.server.http.Router;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.Utils;
import express.Express;
+import express.http.MediaType;
import express.http.Request;
import express.http.Response;
import io.javalin.Javalin;
@@ -13,27 +14,15 @@ import io.javalin.Javalin;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
-import java.nio.file.Paths;
+import java.nio.charset.StandardCharsets;
import java.util.Objects;
-import static emu.grasscutter.Configuration.DATA;
+import static emu.grasscutter.Configuration.*;
/**
* Handles requests related to the announcements page.
*/
public final class AnnouncementsHandler implements Router {
- private static String template, swjs, vue;
-
- public AnnouncementsHandler() {
- var templateFile = new File(Utils.toFilePath(DATA("/hk4e/announcement/index.html")));
- var swjsFile = new File(Utils.toFilePath(DATA("/hk4e/announcement/sw.js")));
- var vueFile = new File(Utils.toFilePath(DATA("/hk4e/announcement/vue.min.js")));
-
- template = templateFile.exists() ? new String(FileUtils.read(template)) : null;
- swjs = swjsFile.exists() ? new String(FileUtils.read(swjs)) : null;
- vue = vueFile.exists() ? new String(FileUtils.read(vueFile)) : null;
- }
-
@Override public void applyRoutes(Express express, Javalin handle) {
// hk4e-api-os.hoyoverse.com
express.all("/common/hk4e_global/announcement/api/getAlertPic", new HttpJsonResponse("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"total\":0,\"list\":[]}}"));
@@ -47,58 +36,57 @@ public final class AnnouncementsHandler implements Router {
express.all("/hk4e_global/mdk/shopwindow/shopwindow/listPriceTier", new HttpJsonResponse("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"suggest_currency\":\"USD\",\"tiers\":[]}}"));
express.get("/hk4e/announcement/*", AnnouncementsHandler::getPageResources);
- express.get("/sw.js", AnnouncementsHandler::getPageResources);
- express.get("/dora/lib/vue/2.6.11/vue.min.js", AnnouncementsHandler::getPageResources);
}
private static void getAnnouncement(Request request, Response response) {
+ String data = "";
if (Objects.equals(request.baseUrl(), "/common/hk4e_global/announcement/api/getAnnContent")) {
- String data = readToString(Paths.get(DATA("GameAnnouncement.json")).toFile());
- response.send("{\"retcode\":0,\"message\":\"OK\",\"data\":" + data + "}");
+ data = readToString(new File(Utils.toFilePath(DATA("GameAnnouncement.json"))));
} else if (Objects.equals(request.baseUrl(), "/common/hk4e_global/announcement/api/getAnnList")) {
- String data = readToString(Paths.get(DATA("GameAnnouncementList.json")).toFile())
- .replace("System.currentTimeMillis()", String.valueOf(System.currentTimeMillis()));
- response.send("{\"retcode\":0,\"message\":\"OK\",\"data\": " + data + "}");
+ data = readToString(new File(Utils.toFilePath(DATA("GameAnnouncementList.json"))));
+ } else {
+ response.send("{\"retcode\":404,\"message\":\"Unknown request path\"}");
}
+
+ if (data.isEmpty()) {
+ response.send("{\"retcode\":500,\"message\":\"Unable to fetch requsted content\"}");
+ return;
+ }
+
+ String dispatchDomain = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
+ + lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
+ + lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort);
+
+ data = data
+ .replace("{{DISPATCH_PUBLIC}}", dispatchDomain)
+ .replace("{{SYSTEM_TIME}}", String.valueOf(System.currentTimeMillis()));
+ response.send("{\"retcode\":0,\"message\":\"OK\",\"data\": " + data + "}");
}
private static void getPageResources(Request request, Response response) {
- var path = request.path();
- switch(path) {
- case "/sw.js" -> response.send(swjs);
- case "/hk4e/announcement/index.html" -> response.send(template);
- case "/dora/lib/vue/2.6.11/vue.min.js" -> response.send(vue);
-
- default -> {
- File renderFile = new File(Utils.toFilePath(DATA(path)));
- if(!renderFile.exists()) {
- Grasscutter.getLogger().info("File not exist: " + path);
- return;
- }
-
- String ext = path.substring(path.lastIndexOf(".") + 1);
- if ("css".equals(ext)) {
- response.type("text/css");
- response.send(FileUtils.read(renderFile));
- } else {
- response.send(FileUtils.read(renderFile));
- }
- }
+ String filename = Utils.toFilePath(DATA(request.path()));
+ File file = new File(filename);
+ if (file.exists() && file.isFile()) {
+ MediaType fromExtension = MediaType.getByExtension(filename.substring(filename.lastIndexOf(".") + 1));
+ response.type((fromExtension != null) ? fromExtension.getMIME() : "application/octet-stream");
+ response.send(FileUtils.read(file));
+ } else {
+ Grasscutter.getLogger().warn("File does not exist: " + file);
+ response.status(404);
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private static String readToString(File file) {
- long length = file.length();
- byte[] content = new byte[(int) length];
+ byte[] content = new byte[(int) file.length()];
try {
FileInputStream in = new FileInputStream(file);
in.read(content); in.close();
} catch (IOException ignored) {
- Grasscutter.getLogger().warn("File not found: " + file.getAbsolutePath());
+ Grasscutter.getLogger().warn("File does not exist: " + file);
}
- return new String(content);
+ return new String(content, StandardCharsets.UTF_8);
}
}