高频出售缓冲机制: 1分钟内单种商品≥10次时暂缓推送60秒
Auto Release / build (push) Successful in 2m39s

This commit is contained in:
2026-07-20 13:18:58 +08:00
parent 182545de59
commit f19efa89a8
3 changed files with 90 additions and 8 deletions
+4 -4
View File
@@ -13,7 +13,7 @@ public class BondManager {
// ===== 交易监听器 =====
public interface TransactionListener {
void onTransaction(String playerName, String type, int amount);
void onTransaction(String playerName, String type, int amount, String targetPlayer);
}
private final List<TransactionListener> transactionListeners = new ArrayList<>();
@@ -21,10 +21,10 @@ public class BondManager {
transactionListeners.add(listener);
}
private void fireTransactionEvent(String playerName, String type, int amount) {
private void fireTransactionEvent(String playerName, String type, int amount, String targetPlayer) {
for (TransactionListener listener : transactionListeners) {
try {
listener.onTransaction(playerName, type, amount);
listener.onTransaction(playerName, type, amount, targetPlayer);
} catch (Exception e) {
e.printStackTrace();
}
@@ -382,7 +382,7 @@ public class BondManager {
ps.executeUpdate();
ps.close();
// 触发交易监听器
fireTransactionEvent(player, type, amount);
fireTransactionEvent(player, type, amount, targetPlayer);
} catch (SQLException e) {
e.printStackTrace();
}
+85 -3
View File
@@ -872,13 +872,75 @@ public class WebManager {
// ★ 注册交易监听器(需在BondManager初始化后调用)
public void registerTransactionListener(BondManager bondMgr) {
if (bondMgr == null) return;
bondMgr.addTransactionListener((playerName, type, amount) -> {
plugin.getLogger().info("[Web交易即时] 检测到交易: " + playerName + " " + type + " " + amount + ",立即推送");
requestImmediateTransactionSync();
bondMgr.addTransactionListener((playerName, type, amount, targetPlayer) -> {
// 高频出售商品缓冲逻辑:shop_sell类型商品在1分钟内≥10次时暂缓推送
if ("shop_sell".equals(type) && targetPlayer != null && !targetPlayer.isEmpty()) {
handleHighFreqSell(playerName, targetPlayer, amount);
} else {
plugin.getLogger().info("[Web交易即时] 检测到交易: " + playerName + " " + type + " " + amount + ",立即推送");
requestImmediateTransactionSync();
}
});
plugin.getLogger().info("[Web通信] 交易即时推送监听器已注册");
}
/**
* 高频出售缓冲处理:追踪每种商品的出售频率
* 1分钟内单种商品售卖≥10次时进入缓冲模式,暂缓推送到PHP,60秒后批量推送
*/
private void handleHighFreqSell(String playerName, String itemId, int amount) {
long now = System.currentTimeMillis();
SellItemBuffer buf = sellBuffers.computeIfAbsent(itemId, k -> new SellItemBuffer(itemId));
// 如果窗口已过期(>60秒),重置计数器
if (now - buf.windowStart > 60000) {
buf.count = 0;
buf.windowStart = now;
}
buf.count++;
// 已经在缓冲模式中,不做任何推送
if (buf.buffering && now < buf.bufferEnd) {
plugin.getLogger().info("[Web交易即时] 高频商品缓冲中(" + itemId + "),第" + buf.count + "笔,不推送");
return;
}
// 达到阈值,进入缓冲模式
if (buf.count >= HIGH_FREQ_SELL_THRESHOLD && !buf.buffering) {
buf.buffering = true;
buf.bufferEnd = now + HIGH_FREQ_BUFFER_MS;
inHighFreqBufferMode = true;
bufferModeEndTime = Math.max(bufferModeEndTime, buf.bufferEnd);
plugin.getLogger().info("[Web交易即时] ★ 高频商品触发缓冲: " + itemId + " 1分钟内" + buf.count + "次,暂缓推送60秒");
// 调度60秒后的批量推送
new BukkitRunnable() {
@Override
public void run() {
plugin.getLogger().info("[Web交易即时] 高频缓冲到期(" + itemId + "),批量推送交易");
buf.buffering = false;
buf.count = 0;
buf.windowStart = System.currentTimeMillis();
// 检查是否所有缓冲都结束了
boolean anyBuffering = false;
for (SellItemBuffer b : sellBuffers.values()) {
if (b.buffering) { anyBuffering = true; break; }
}
if (!anyBuffering) inHighFreqBufferMode = false;
requestImmediateTransactionSync();
}
}.runTaskLater(plugin, 20L * 60); // 60秒
return;
}
// 普通交易(未达阈值),立即推送
plugin.getLogger().info("[Web交易即时] 检测到出售: " + playerName + " " + itemId + " " + amount + ",立即推送");
requestImmediateTransactionSync();
}
public void start() {
if (!enabled) {
plugin.getLogger().info("[Web通信] 未启用,在插件设置.txt中设置 web通信-启用=true");
@@ -1318,6 +1380,26 @@ public class WebManager {
private static final long MIN_IMMEDIATE_TX_SYNC_MS = 3000; // 最小间隔3秒,防止频繁推送
private volatile boolean pendingImmediateTxSync = false;
// ★ 高频出售商品缓冲机制:1分钟内单种商品售卖≥10次时暂缓推送
private final ConcurrentHashMap<String, SellItemBuffer> sellBuffers = new ConcurrentHashMap<>();
private static final int HIGH_FREQ_SELL_THRESHOLD = 10; // 10次触发缓冲
private static final long HIGH_FREQ_BUFFER_MS = 60000; // 缓冲60秒
private volatile boolean inHighFreqBufferMode = false; // 全局缓冲模式标志
private volatile long bufferModeEndTime = 0; // 缓冲模式结束时间
private static class SellItemBuffer {
final String itemId;
volatile int count = 0;
volatile long windowStart = 0;
volatile boolean buffering = false;
volatile long bufferEnd = 0;
SellItemBuffer(String itemId) {
this.itemId = itemId;
this.windowStart = System.currentTimeMillis();
}
}
private void requestImmediateTransactionSync() {
long now = System.currentTimeMillis();
if (now - lastImmediateTxSyncTime < MIN_IMMEDIATE_TX_SYNC_MS) {
+1 -1
View File
@@ -1,5 +1,5 @@
name: Sdf1_login
version: 2.8
version: 2.81
main: Sdf1_login.Main
api-version: '1.21'
commands: