1+ package wayzer.reGrief
2+
3+ import arc.struct.IntSet
4+ import arc.util.Interval
5+ import arc.util.Time
6+ import mindustry.core.NetServer
7+ import mindustry.world.blocks.logic.LogicBlock
8+ import mindustryX.events.SendPacketEvent
9+
10+ try {
11+ LogicBlock ::class .java.getDeclaredField(" running" )
12+ } catch (e: Exception ) {
13+ error(" 本脚本依赖MindustryX v143.102 或更新版本" )
14+ }
15+
16+ // 带滑动平均的速率统计
17+ class RateKeeper (val timeWindow : Double = 5.0 ) {
18+ private var lastTime = Time .time
19+ var avgCount = 0.0
20+ fun count (count : Int = 1) {
21+ avgCount + = count / timeWindow
22+ val delta = Time .time - lastTime
23+ if (delta > Time .toSeconds) {
24+ avgCount * = (1 - delta / timeWindow * Time .toSeconds).coerceAtLeast(0.0 )
25+ lastTime = Time .time
26+ }
27+ }
28+ }
29+
30+ val list = mutableListOf<Class <* >>()
31+ val interval = Interval ()
32+ val packetRate = RateKeeper ()
33+ listen<SendPacketEvent > { event ->
34+ if (event.con == null && LogicBlock .running && state.isGame) {
35+ packetRate.count()
36+ list.add(event.packet::class .java)
37+ if (packetRate.avgCount > 2000 ) {
38+ if (state.rules.disableWorldProcessors) return @listen
39+ state.rules.disableWorldProcessors = true
40+ broadcast(" [red]世界处理器发包严重,禁用世界处理器。请联系地图地图作者优化." .with ())
41+ } else if (interval.get(30 * 60f )) {
42+ if (packetRate.avgCount > 1000 ) {
43+ val list = list.groupBy { it }
44+ .map { it.key.simpleName to it.value.size }
45+ .sortedByDescending { it.second }
46+ broadcast(
47+ " [red]世界处理器发包超限, 未来将被禁用,请联系地图地图作者优化。当前值: {avg}/s\n {list|joinLines}" .with (
48+ " avg" to " %.2f" .format(packetRate.avgCount), " list" to list
49+ )
50+ )
51+ }
52+ list.clear()
53+ }
54+ }
55+ }
56+
57+ val healthChanged = RateKeeper (3.0 )
58+ val NetServer .buildHealthChanged: IntSet by reflectDelegate()
59+ listen(EventType .Trigger .update) {
60+ if (! state.isPlaying) return @listen
61+ healthChanged.count(netServer.buildHealthChanged.size)
62+ if (healthChanged.avgCount > 100_000 ) {
63+ if (state.rules.disableWorldProcessors) return @listen
64+ state.rules.disableWorldProcessors = true
65+ broadcast(" [red]世界处理器发包严重,禁用世界处理器。请联系地图地图作者优化." .with ())
66+ broadcast(" BuildHealthChanged ${healthChanged.avgCount.toInt()} /s" .asPlaceHoldString())
67+ }
68+ }
69+ command(" debugLogicPacket" , " 查看逻辑发包速率" ) {
70+ permission = dotId
71+ body {
72+ val list = list.groupBy { it }
73+ .map { it.key to it.value.size }
74+ .sortedByDescending { it.second }
75+ reply(
76+ """
77+ 血量变化: ${healthChanged.avgCount.toInt()} /s
78+ 当前发包速率: ${packetRate.avgCount.toInt()} /s
79+ ${list}
80+ """ .trimIndent().asPlaceHoldString()
81+ )
82+ }
83+ }
0 commit comments