doTransactionPollCheck添加高频补单触发器(15秒间隔)

- WebManager: doTransactionPollCheck每~5秒触发poller_online.php(限流15秒)
- 解决补单延迟(原PollC~30-60秒才触发)

关闭 #1059
This commit is contained in:
2026-07-15 18:01:06 +08:00
parent 501aa40677
commit e791548e87
4 changed files with 44 additions and 4 deletions
+1 -3
View File
@@ -8,7 +8,5 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_26" default="true" project-jdk-name="26" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="26" project-jdk-type="JavaSDK" />
</project>
Generated
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>
@@ -561,6 +561,7 @@ public class AreaCLIManager {
case "item_frame": oldState = land.denyItemFrame; land.denyItemFrame = !land.denyItemFrame; break;
case "redstone": oldState = land.denyRedstoneInteraction; land.denyRedstoneInteraction = !land.denyRedstoneInteraction; break;
case "door": oldState = land.denyDoorInteraction; land.denyDoorInteraction = !land.denyDoorInteraction; break;
case "sign_edit": oldState = land.denySignEdit; land.denySignEdit = !land.denySignEdit; break;
case "audio": oldState = land.denyNoteblockJukebox; land.denyNoteblockJukebox = !land.denyNoteblockJukebox; break;
case "lead": oldState = land.denyLead; land.denyLead = !land.denyLead; break;
case "crop_harvest": oldState = land.denyCropHarvest; land.denyCropHarvest = !land.denyCropHarvest; break;
@@ -677,6 +678,7 @@ public class AreaCLIManager {
perms.add(new PermItem("item_frame", "禁止展示框", !land.denyItemFrame));
perms.add(new PermItem("redstone", "红石电路(中继器/比较器)", !land.denyRedstoneInteraction));
perms.add(new PermItem("door", "禁止门禁(门/按钮/压力板)", !land.denyDoorInteraction));
perms.add(new PermItem("sign_edit", land.denySignEdit ? "禁止编辑告示牌" : "允许编辑告示牌", !land.denySignEdit));
perms.add(new PermItem("audio", "音频(音符盒/唱片机)", !land.denyNoteblockJukebox));
perms.add(new PermItem("lead", "拴绳使用", !land.denyLead));
perms.add(new PermItem("crop_harvest", land.denyCropHarvest ? "禁用农作物收获" : "启用农作物收获", !land.denyCropHarvest));
@@ -715,6 +717,7 @@ public class AreaCLIManager {
case "item_frame": return "禁止展示框";
case "redstone": return "红石电路";
case "door": return "禁止门禁";
case "sign_edit": return "告示牌编辑";
case "audio": return "音频";
case "lead": return "拴绳使用";
case "crop_harvest": return "农作物收获";
@@ -1128,6 +1131,7 @@ public class AreaCLIManager {
{"item_frame", "禁止展示框", "denyItemFrame"},
{"redstone", "红石电路(中继器/比较器)", "denyRedstoneInteraction"},
{"door", "禁止门禁(门/按钮/压力板)", "denyDoorInteraction"},
{"sign_edit", "禁止编辑告示牌", "denySignEdit"},
{"audio", "音频(音符盒/唱片机)", "denyNoteblockJukebox"},
{"lead", "拴绳使用", "denyLead"},
{"crop_harvest", "农作物收获", "denyCropHarvest"},
@@ -1165,6 +1169,10 @@ public class AreaCLIManager {
if (field.equals("denyMobAttack")) {
name = landDefault ? "禁止攻击生物" : "允许攻击生物";
}
// ★ denySignEdit显示名称
if (field.equals("denySignEdit")) {
name = landDefault ? "禁止编辑告示牌" : "允许编辑告示牌";
}
// 如果有per-player覆盖,使用覆盖值;否则使用领地默认
if (playerPerms.containsKey(field)) {
@@ -1208,6 +1216,7 @@ public class AreaCLIManager {
case "denyItemFrame": return land.denyItemFrame;
case "denyRedstoneInteraction": return land.denyRedstoneInteraction;
case "denyDoorInteraction": return land.denyDoorInteraction;
case "denySignEdit": return land.denySignEdit;
case "denyNoteblockJukebox": return land.denyNoteblockJukebox;
case "denyLead": return land.denyLead;
case "denyCropHarvest": return land.denyCropHarvest;
+33
View File
@@ -1495,6 +1495,22 @@ public class WebManager {
* 检查PHP端是否有待处理交易(由合并定时器B调用)
*/
private void doTransactionPollCheck() {
// ★ 2026-07-15 高频补单触发:合并B定时器每~5秒跑一次,顺带触发 poller 快速检测已支付订单
// poller 内部有 flock 锁 + 幂等去重,多次调用安全
if (System.currentTimeMillis() - lastPollerTriggerTime > 15000) { // 限流15秒一次
lastPollerTriggerTime = System.currentTimeMillis();
try {
String pollerUrl = webBaseUrl + "/api/poller_online.php?secret="
+ java.net.URLEncoder.encode(secretKey, "UTF-8");
String pollerResp = doGet(pollerUrl);
if (pollerResp != null && pollerResp.contains("\"result\":\"ok\"")) {
plugin.getLogger().info("[快速补单] 补单成功: " + pollerResp.substring(0, Math.min(100, pollerResp.length())));
}
} catch (Exception ignored) {
// 补单失败不影响交易拉取,静默忽略
}
}
try {
String urlStr = webBaseUrl + "/api/sync.php?action=check_pending_transactions&secret="
+ java.net.URLEncoder.encode(secretKey, "UTF-8");
@@ -6089,6 +6105,7 @@ public class WebManager {
private long lastPullBondChangesLog = 0;
private long lastPollRegisterRequestsLog = 0;
private long lastPollWebLoginExceptionLog = 0;
private long lastPollerTriggerTime = 0; // 补单触发限流(15秒间隔)
private static final long LOG_INTERVAL = 60000; // 1分钟内不重复打印相同日志
/**
@@ -6099,6 +6116,22 @@ public class WebManager {
@Override
public void run() {
try {
// ★ 2026-07-15 补单机制:拉取交易前先触发 poller_online.php 补单
// 平台 HTTP 回调被 Cloudflare WAF 拦截,只能靠本脚本读平台 MySQL 已支付订单补单。
// 先等补单返回(doGet 内置 10s 超时)再拉取 web_transactions,确保充值能到账。
try {
String pollerUrl = webBaseUrl + "/api/poller_online.php?secret="
+ java.net.URLEncoder.encode(secretKey, "UTF-8");
String pollerResp = doGet(pollerUrl);
if (pollerResp != null) {
plugin.getLogger().info("[Web交易] 补单触发完成: " + pollerResp);
} else {
plugin.getLogger().warning("[Web交易] 补单触发无响应(继续拉取)");
}
} catch (Exception pollerEx) {
plugin.getLogger().warning("[Web交易] 补单触发异常(忽略,继续拉取): " + pollerEx.getMessage());
}
String urlStr = webBaseUrl + "/api/sync.php?action=pull_pending_transactions&secret="
+ java.net.URLEncoder.encode(secretKey, "UTF-8");
String json = doGet(urlStr);