diff --git a/.idea/modules.xml b/.idea/modules.xml
index 5f692ba..20c249f 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,9 +2,9 @@
-
+
\ No newline at end of file
diff --git a/backend/src/main/java/org/cubewhy/api/BackendApplication.java b/backend/src/main/java/org/cubewhy/api/BackendApplication.java
index bb9c972..2ce5081 100644
--- a/backend/src/main/java/org/cubewhy/api/BackendApplication.java
+++ b/backend/src/main/java/org/cubewhy/api/BackendApplication.java
@@ -17,6 +17,7 @@ public class BackendApplication {
public static final File crashReportFolder = new File(configPath, "crash-reports");
public static final File artifactsFolder = new File(configPath, "artifacts");
public static final File applicationConfigFile = new File(configPath, "application.yml");
+
public static void main(String[] args) {
configPath.mkdirs();
new FileUtils().extractFile("application.yml", applicationConfigFile);
diff --git a/backend/src/main/java/org/cubewhy/api/StartupRunner.java b/backend/src/main/java/org/cubewhy/api/StartupRunner.java
index 8b65ac5..cfd631e 100644
--- a/backend/src/main/java/org/cubewhy/api/StartupRunner.java
+++ b/backend/src/main/java/org/cubewhy/api/StartupRunner.java
@@ -3,12 +3,14 @@
import jakarta.annotation.Resource;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
+import org.cubewhy.api.files.InvokeCount;
import org.cubewhy.api.utils.AddonFileListener;
import org.cubewhy.api.utils.FileUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import javax.net.ssl.*;
+import java.io.File;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@@ -20,6 +22,8 @@ public class StartupRunner implements CommandLineRunner {
FileUtils utils;
FileAlterationMonitor monitor = new FileAlterationMonitor(10000L);
+ public static final InvokeCount counter = new InvokeCount(new File(configPath, "invoke-counter.json"));
+
/**
* Callback used to run the bean.
*
diff --git a/backend/src/main/java/org/cubewhy/api/controller/LauncherController.java b/backend/src/main/java/org/cubewhy/api/controller/LauncherController.java
index 62f0613..fd9b856 100644
--- a/backend/src/main/java/org/cubewhy/api/controller/LauncherController.java
+++ b/backend/src/main/java/org/cubewhy/api/controller/LauncherController.java
@@ -26,6 +26,7 @@
import java.util.UUID;
import static org.cubewhy.api.BackendApplication.*;
+import static org.cubewhy.api.StartupRunner.counter;
@RestController
@RequestMapping("/launcher")
@@ -55,6 +56,9 @@ public void launch(@NotNull HttpServletRequest request, @NotNull HttpServletResp
String json = null;
// return download url
// Find at //-.json
+ // 拼接下载链接
+ counter.addCount("launcher/launch");
+
InputStream stream = fileUtils.getExternalFile(branchesFolder + String.format("/%s/%s-%s.json", info.getBranch(), info.getVersion(), info.getModule()));
if (stream != null) {
json = utils.readAll(stream);
@@ -138,4 +142,6 @@ public void getCrashReport(HttpServletResponse response, @RequestParam(required
response.getWriter().write(RestBean.success(JSONObject.parse(json)).toJson());
}
}
+
+
}
diff --git a/backend/src/main/java/org/cubewhy/api/controller/WebController.java b/backend/src/main/java/org/cubewhy/api/controller/WebController.java
index be2c623..fc1e612 100644
--- a/backend/src/main/java/org/cubewhy/api/controller/WebController.java
+++ b/backend/src/main/java/org/cubewhy/api/controller/WebController.java
@@ -5,6 +5,7 @@
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import jakarta.websocket.server.PathParam;
import org.cubewhy.api.entity.RestBean;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
@@ -17,6 +18,8 @@
import java.io.IOException;
+import static org.cubewhy.api.StartupRunner.counter;
+
@RestController
@RequestMapping("/api/web")
public class WebController {
@@ -51,6 +54,12 @@ public void pay(HttpServletRequest request, @NotNull HttpServletResponse respons
response.sendRedirect(target);
}
+ @GetMapping("invoke")
+ public void invoke(HttpServletResponse response, @PathParam("api") String api) throws IOException {
+ response.setContentType("application/json");
+ response.getWriter().write(RestBean.success(counter.getCount(api)).toJson());
+ }
+
@GetMapping("latest")
public void latestVersion(HttpServletRequest request, HttpServletResponse response) throws Exception {
/*
diff --git a/backend/src/main/java/org/cubewhy/api/entity/GameInfo.java b/backend/src/main/java/org/cubewhy/api/entity/GameInfo.java
index 3c95ecd..1ae5b2f 100644
--- a/backend/src/main/java/org/cubewhy/api/entity/GameInfo.java
+++ b/backend/src/main/java/org/cubewhy/api/entity/GameInfo.java
@@ -9,4 +9,6 @@ public class GameInfo implements BaseData {
String version;
String branch;
String module;
+ String os;
+ String arch;
}
diff --git a/backend/src/main/java/org/cubewhy/api/files/InvokeCount.java b/backend/src/main/java/org/cubewhy/api/files/InvokeCount.java
new file mode 100644
index 0000000..4de0b52
--- /dev/null
+++ b/backend/src/main/java/org/cubewhy/api/files/InvokeCount.java
@@ -0,0 +1,75 @@
+package org.cubewhy.api.files;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+
+@Slf4j
+public class InvokeCount {
+ @Getter
+ private JSONObject config;
+ public final File file;
+
+ public InvokeCount(File file) {
+ this.file = file;
+ this.load();
+ }
+
+ public void addCount(String apiName) {
+ if (!config.containsKey(apiName)) {
+ config.put(apiName, 0);
+ }
+ config.put(apiName, config.getIntValue(apiName) + 1);
+ save();
+ }
+
+ public int getCount(String apiName) {
+ return config.getIntValue(apiName, 0);
+ }
+
+ public InvokeCount save() {
+ try {
+ BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(this.file));
+ bufferedWriter.write(config.toString());
+ bufferedWriter.flush();
+ bufferedWriter.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+
+ public InvokeCount load() {
+ FileReader fileReader;
+ boolean successful = false;
+
+ while (!successful) {
+ try {
+ fileReader = new FileReader(this.file, StandardCharsets.UTF_8);
+ config = JSON.parseObject(fileReader);
+ if (config == null) {
+ config = new JSONObject();
+ }
+ successful = true;
+ fileReader.close();
+ } catch (FileNotFoundException e) {
+
+ try {
+ if (!this.file.getParentFile().exists()) {
+ this.file.getParentFile().mkdirs();
+ }
+ this.file.createNewFile();
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return this;
+ }
+}
diff --git a/backend/src/main/java/org/cubewhy/api/utils/AddonFileListener.java b/backend/src/main/java/org/cubewhy/api/utils/AddonFileListener.java
index 76b9e93..3ab9254 100644
--- a/backend/src/main/java/org/cubewhy/api/utils/AddonFileListener.java
+++ b/backend/src/main/java/org/cubewhy/api/utils/AddonFileListener.java
@@ -41,10 +41,11 @@ public static void addFile(File file) throws IOException {
addons.add(json);
}
- private static String getAddonType(File file) {
+ private static String getAddonType(@NotNull File file) {
return switch (file.getParentFile().getName()) {
case "mods" -> "weave";
case "cn" -> "cn";
+ case "fabric" -> "fabric";
case "javaagents" -> "Agent";
default ->
// Unreachable
@@ -52,7 +53,7 @@ private static String getAddonType(File file) {
};
}
- private void walkDir(File dir) throws IOException {
+ private void walkDir(@NotNull File dir) throws IOException {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {