diff --git a/src/main/java/Sdf1_login/BondManager.java b/src/main/java/Sdf1_login/BondManager.java index b8544ba..36b153b 100644 --- a/src/main/java/Sdf1_login/BondManager.java +++ b/src/main/java/Sdf1_login/BondManager.java @@ -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 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(); } diff --git a/src/main/java/Sdf1_login/WebManager.java b/src/main/java/Sdf1_login/WebManager.java index 4e51efd..be36f9e 100644 --- a/src/main/java/Sdf1_login/WebManager.java +++ b/src/main/java/Sdf1_login/WebManager.java @@ -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 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) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2309b04..530d801 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Sdf1_login -version: 2.8 +version: 2.81 main: Sdf1_login.Main api-version: '1.21' commands: