diff --git a/.github/workflows/jvm-ci.yml b/.github/workflows/jvm-ci.yml
index 466e193e60..93fd34bd4b 100644
--- a/.github/workflows/jvm-ci.yml
+++ b/.github/workflows/jvm-ci.yml
@@ -63,7 +63,7 @@ jobs:
type=raw,ci
type=sha
- name: Build and push Docker image
- uses: docker/build-push-action@v6.10.0
+ uses: docker/build-push-action@v6.11.0
with:
context: .
file: ./Dockerfile
@@ -98,7 +98,7 @@ jobs:
type=raw,ci
type=sha
- name: Build and push Docker image
- uses: docker/build-push-action@v6.10.0
+ uses: docker/build-push-action@v6.11.0
with:
context: .
file: ./Dockerfile
diff --git a/.github/workflows/jvm-release.yml b/.github/workflows/jvm-release.yml
index d7c4bb334c..9277ff9357 100644
--- a/.github/workflows/jvm-release.yml
+++ b/.github/workflows/jvm-release.yml
@@ -159,7 +159,7 @@ jobs:
type=raw,latest
type=sha
- name: Build and push Docker image
- uses: docker/build-push-action@v6.10.0
+ uses: docker/build-push-action@v6.11.0
with:
context: .
file: ./Dockerfile
@@ -195,7 +195,7 @@ jobs:
type=raw,latest
type=sha
- name: Build and push Aliyun ACR
- uses: docker/build-push-action@v6.10.0
+ uses: docker/build-push-action@v6.11.0
with:
context: .
file: ./Dockerfile-Release
diff --git a/.gitignore b/.gitignore
index 66171cba55..88a9dc8e3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,3 +51,4 @@ dependency-reduced-pom.xml
PeerBanHelper.jar
*.pkg
install4j/output
+install4j/project.install4j~
diff --git a/pom.xml b/pom.xml
index 4a5e4ba0eb..75f275ae5b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.ghostchu.peerbanhelper
peerbanhelper
- 7.3.1
+ 7.3.2
jar
PeerBanHelper
@@ -258,7 +258,7 @@
org.bspfsystems
yamlconfiguration
- 3.0.1
+ 3.0.2
compile
@@ -398,7 +398,7 @@
org.apache.james
apache-mime4j-dom
- 0.8.11
+ 0.8.12
commons-io
@@ -409,7 +409,7 @@
org.apache.james
apache-mime4j-core
- 0.8.11
+ 0.8.12
commons-io
@@ -420,7 +420,7 @@
org.apache.james
apache-mime4j-storage
- 0.8.11
+ 0.8.12
commons-io
diff --git a/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java b/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java
index 592acb6080..01e2167250 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/PeerBanHelperServer.java
@@ -201,6 +201,10 @@ private void runTestCode() {
return;
}
// run some junky test code here
+// ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory
+// .getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
+// root.setLevel(ch.qos.logback.classic.Level.TRACE);
+
}
diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java b/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java
index e3387de430..cb506f6b28 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/database/DatabaseHelper.java
@@ -75,6 +75,11 @@ private void performUpgrade() throws SQLException {
TableUtils.createTableIfNotExists(database.getDataSource(), AlertEntity.class);
v = 7;
}
+ if (v == 7) {
+ TableUtils.dropTable(getDataSource(), AlertEntity.class, true);
+ TableUtils.createTableIfNotExists(database.getDataSource(), AlertEntity.class);
+ v = 8;
+ }
version.setValue(String.valueOf(v));
metadata.update(version);
}
diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java
index 709e8f1d5a..47909e6cd1 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/database/dao/impl/HistoryDao.java
@@ -44,15 +44,16 @@ public Page getBannedIps(Pageable pageable, String filter) throws
.selectRaw("ip, COUNT(*) AS count")
.groupBy("ip")
.orderByRaw("count DESC");
+ String[] args = new String[0];
if (filter != null) {
- builder.setWhere(builder.where().like("ip", new SelectArg(filter + "%")));
+ builder.setWhere(builder.where().like("ip", new SelectArg()));
+ args = new String[]{filter + "%"};
}
- List mapped;
- try (GenericRawResults banLogs = builder
+ var queryBuilder = builder
.limit(pageable.getSize())
- .offset(pageable.getZeroBasedPage() * pageable.getSize())
- // .where().ge("banAt", twoWeeksAgo)
- .queryRaw()) {
+ .offset(pageable.getZeroBasedPage() * pageable.getSize());
+ List mapped;
+ try (GenericRawResults banLogs = queryRaw(queryBuilder.prepareStatementString(), args)) {
var results = banLogs.getResults();
mapped = results.stream().map(arr -> new PeerBanCount(arr[0], Long.parseLong(arr[1]))).toList();
}
diff --git a/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java b/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java
index 872f1dcab1..ffb43214be 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/database/table/AlertEntity.java
@@ -1,8 +1,8 @@
package com.ghostchu.peerbanhelper.database.table;
import com.ghostchu.peerbanhelper.alert.AlertLevel;
+import com.ghostchu.peerbanhelper.database.TranslationComponentPersistener;
import com.ghostchu.peerbanhelper.text.TranslationComponent;
-import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import lombok.AllArgsConstructor;
@@ -26,8 +26,8 @@ public final class AlertEntity {
private AlertLevel level;
@DatabaseField(canBeNull = false, index = true)
private String identifier;
- @DatabaseField(canBeNull = false, dataType = DataType.SERIALIZABLE)
+ @DatabaseField(canBeNull = false, persisterClass = TranslationComponentPersistener.class)
private TranslationComponent title;
- @DatabaseField(canBeNull = false, dataType = DataType.SERIALIZABLE)
+ @DatabaseField(canBeNull = false, persisterClass = TranslationComponentPersistener.class)
private TranslationComponent content;
}
\ No newline at end of file
diff --git a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java
index 9e62b65a0f..7cf95818f9 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/downloader/impl/qbittorrent/AbstractQbittorrent.java
@@ -162,7 +162,6 @@ public boolean isLoggedIn() {
}
return !info.getQt().isBlank();
} catch (Exception e) {
- log.error("Failed to check login status", e);
return false;
}
}
diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java
index c4b7649696..89e9f43719 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/webapi/PBHPeerController.java
@@ -153,7 +153,7 @@ private void handleInfo(Context ctx) throws SQLException {
private void handleBanHistory(Context ctx) throws SQLException {
- String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toString();
+ String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toNormalizedString();
Pageable pageable = new Pageable(ctx);
var builder = historyDao.queryBuilder()
.orderBy("banAt", false);
@@ -168,7 +168,7 @@ private void handleBanHistory(Context ctx) throws SQLException {
private void handleAccessHistory(Context ctx) throws SQLException {
activeMonitoringModule.flush();
- String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toString();
+ String ip = IPAddressUtil.getIPAddress(ctx.pathParam("ip")).toNormalizedString();
Pageable pageable = new Pageable(ctx);
var builder = peerRecordDao.queryBuilder()
.orderBy("lastTimeSeen", false);
diff --git a/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java b/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java
index e9e9369629..88dbd3c4a7 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/util/json/JsonUtil.java
@@ -1,5 +1,6 @@
package com.ghostchu.peerbanhelper.util.json;
+import com.ghostchu.peerbanhelper.text.TranslationComponent;
import com.google.gson.*;
import org.jetbrains.annotations.NotNull;
@@ -13,6 +14,7 @@ public class JsonUtil {
.setExclusionStrategies(new HiddenAnnotationExclusionStrategy())
.serializeNulls()
.registerTypeAdapter(Timestamp.class, TimestampTypeAdapter.INSTANCE)
+ .registerTypeAdapter(TranslationComponent.class, TranslationComponentTypeAdapter.INSTANCE)
.disableHtmlEscaping()
.create();
diff --git a/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java b/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java
index 5a4521deb1..f109186eaa 100644
--- a/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java
+++ b/src/main/java/com/ghostchu/peerbanhelper/util/json/TranslationComponentTypeAdapter.java
@@ -1,20 +1,72 @@
package com.ghostchu.peerbanhelper.util.json;
import com.ghostchu.peerbanhelper.text.TranslationComponent;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
-import java.lang.reflect.Type;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
-import static com.ghostchu.peerbanhelper.text.TextManager.tlUI;
-
-public class TranslationComponentTypeAdapter implements JsonSerializer {
+public class TranslationComponentTypeAdapter extends TypeAdapter {
public static final TranslationComponentTypeAdapter INSTANCE = new TranslationComponentTypeAdapter();
@Override
- public JsonElement serialize(TranslationComponent ts, Type t, JsonSerializationContext jsc) {
- return new JsonPrimitive(tlUI(ts));
+ public void write(JsonWriter out, TranslationComponent value) throws IOException {
+ out.beginObject();
+ out.name("key").value(value.getKey());
+ out.name("params");
+ out.beginArray(); // 开始 JSON 数组
+ // 遍历 params 数组并写入元素
+ for (Object param : value.getParams()) {
+ if (param instanceof TranslationComponent) {
+ // 如果是 TranslationComponent,递归调用 write 方法
+ TranslationComponentTypeAdapter.INSTANCE.write(out, (TranslationComponent) param);
+ } else {
+ out.value(param.toString());
+ }
+ }
+ out.endArray(); // 结束 JSON 数组
+ out.endObject(); // 结束 JSON 对象
+
+ // 特别注意嵌套里面不允许出现除了 TranslationComponent 以外的 JsonObject,否则必翻车
+ }
+
+ @Override
+ public TranslationComponent read(JsonReader in) throws IOException {
+ String key = null;
+ List