Skip to content

Commit f2a2ce8

Browse files
Merge pull request #5 from MrHua269/main
一些重构()
2 parents 64b04a6 + a384121 commit f2a2ce8

7 files changed

Lines changed: 208 additions & 218 deletions

File tree

src/main/java/ict/minesunshineone/peek/handler/PeekStateHandler.java

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@ public void startPeek(Player peeker, Player target) {
5252
}
5353

5454
// 防止并发修改
55+
final PeekData data;
5556
synchronized (activePeeks) {
5657
if (activePeeks.containsKey(peeker.getUniqueId())) {
5758
plugin.getMessages().send(peeker, "already-peeking");
5859
return;
5960
}
6061

6162
logDebug("Starting peek: %s -> %s", peeker.getName(), target.getName());
62-
PeekData data = new PeekData(
63+
data = new PeekData(
6364
peeker.getLocation().clone(),
6465
peeker.getGameMode(),
6566
target.getUniqueId(),
@@ -70,12 +71,13 @@ public void startPeek(Player peeker, Player target) {
7071
peeker.getActivePotionEffects());
7172

7273
activePeeks.put(peeker.getUniqueId(), data);
73-
plugin.getStateManager().savePlayerState(peeker, data);
74-
plugin.getStatisticsManager().recordPeekStart(peeker, target);
75-
76-
teleportAndSetGameMode(peeker, target);
7774
}
7875

76+
plugin.getStateManager().savePlayerState(peeker, data);
77+
plugin.getStatisticsManager().recordPeekStart(peeker, target);
78+
79+
teleportAndSetGameMode(peeker, target);
80+
7981
// 检查是否静默 peek(有 bypass 权限)
8082
boolean silentPeek = plugin.getTargetHandler().shouldSilentPeek(peeker);
8183

@@ -246,69 +248,68 @@ public void endPeek(Player peeker) {
246248
// ==================== 私有方法 ====================
247249

248250
private void teleportAndSetGameMode(Player peeker, Player target) {
251+
final Runnable onFailed = () -> {
252+
plugin.getMessages().send(peeker, "teleport-failed");
253+
endPeek(peeker);
254+
};
255+
249256
// 先切换游戏模式
250-
plugin.getServer().getRegionScheduler().run(plugin, peeker.getLocation(), task -> {
251-
try {
252-
// 清理骑乘状态,准备进入旁观者模式
253-
PlayerStateUtil.prepareForSpectatorMode(peeker, plugin.getLogger());
254-
255-
// 设置为旁观模式
256-
peeker.setGameMode(GameMode.SPECTATOR);
257-
258-
// 等待2 tick后再传送
259-
plugin.getServer().getRegionScheduler().runDelayed(plugin, peeker.getLocation(), delayedTask -> {
260-
peeker.teleportAsync(target.getLocation(), TeleportCause.PLUGIN).thenAccept(success -> {
261-
if (!success) {
262-
plugin.getMessages().send(peeker, "teleport-failed");
263-
endPeek(peeker);
264-
} else {
265-
// 传送成功后,使用玩家的实体调度器确保在正确线程执行
266-
peeker.getScheduler().run(plugin, scheduledTask -> {
267-
bossBarHandler.createDistanceBossBar(peeker, target);
268-
startNormalRangeChecker(peeker, target);
269-
}, null);
270-
}
271-
});
272-
}, 2L); // 2 tick 延迟
273-
} catch (Exception e) {
274-
plugin.getLogger().warning(String.format("为玩家 %s 切换游戏模式时发生错误", peeker.getName()));
275-
peeker.setSneaking(false); // 确保异常时也恢复状态
276-
endPeek(peeker);
257+
final boolean firstRoundScheduled = peeker.getScheduler().execute(plugin, () -> {
258+
// 清理骑乘状态,准备进入旁观者模式
259+
PlayerStateUtil.prepareForSpectatorMode(peeker);
260+
261+
// 设置为旁观模式
262+
peeker.setGameMode(GameMode.SPECTATOR);
263+
264+
// 等待2 tick后再传送
265+
final boolean secondRoundScheduled = peeker.getScheduler().execute(plugin, () -> {
266+
peeker.teleportAsync(target.getLocation(), TeleportCause.PLUGIN).thenAccept(success -> {
267+
if (!success) {
268+
onFailed.run();
269+
} else {
270+
// 传送成功后,使用玩家的实体调度器确保在正确线程执行
271+
bossBarHandler.createDistanceBossBar(peeker, target);
272+
startNormalRangeChecker(peeker, target);
273+
}
274+
});
275+
}, onFailed, 2L); // 2 tick 延迟
276+
277+
if (!secondRoundScheduled) {
278+
onFailed.run();
277279
}
278-
});
280+
}, onFailed, 1L);
281+
282+
if (!firstRoundScheduled) {
283+
onFailed.run();
284+
}
279285
}
280286

281287
private void setSelfPeekGameMode(Player peeker) {
282-
plugin.getServer().getRegionScheduler().run(plugin, peeker.getLocation(), task -> {
283-
try {
284-
if (!peeker.isOnline()) {
285-
plugin.getLogger().warning(String.format("玩家 %s 在设置自我观察模式时已离线", peeker.getName()));
286-
endPeek(peeker, false);
287-
return;
288-
}
288+
peeker.getScheduler().execute(plugin, () -> {
289+
// 这里如果玩家离线了调度器会自动退役
290+
/*if (!peeker.isOnline()) {
291+
plugin.getLogger().warning(String.format("玩家 %s 在设置自我观察模式时已离线", peeker.getName()));
292+
endPeek(peeker, false);
293+
return;
294+
}*/
289295

290-
if (peeker.isDead()) {
291-
plugin.getLogger().warning(String.format("玩家 %s 在设置自我观察模式时已死亡", peeker.getName()));
292-
plugin.getMessages().send(peeker, "cannot-peek-while-dead");
293-
endPeek(peeker, false);
294-
return;
295-
}
296+
if (peeker.isDead()) {
297+
plugin.getSLF4JLogger().warn("玩家 {} 在设置自我观察模式时已死亡", peeker.getName());
298+
plugin.getMessages().send(peeker, "cannot-peek-while-dead");
299+
endPeek(peeker, false);
300+
return;
301+
}
296302

297-
// 清理骑乘状态,准备进入旁观者模式
298-
PlayerStateUtil.prepareForSpectatorMode(peeker, plugin.getLogger());
303+
// 清理骑乘状态,准备进入旁观者模式
304+
PlayerStateUtil.prepareForSpectatorMode(peeker);
299305

300-
peeker.setGameMode(GameMode.SPECTATOR);
306+
peeker.setGameMode(GameMode.SPECTATOR);
301307

302-
logDebug("Successfully set self peek game mode for player: %s", peeker.getName());
303-
} catch (Exception e) {
304-
plugin.getLogger().warning(String.format("为玩家 %s 设置自我观察模式时发生错误: %s", peeker.getName(), e.getMessage()));
305-
if (plugin.getConfig().getBoolean("debug", false)) {
306-
e.printStackTrace();
307-
}
308-
peeker.setSneaking(false); // 确保异常时也恢复状态
309-
endPeek(peeker);
310-
}
311-
});
308+
logDebug("Successfully set self peek game mode for player: %s", peeker.getName());
309+
}, () -> {
310+
plugin.getSLF4JLogger().warn("玩家 {} 在设置自我观察模式时已离线", peeker.getName());
311+
endPeek(peeker, false);
312+
}, 1L);
312313
}
313314

314315
private void startNormalRangeChecker(Player peeker, Player target) {

src/main/java/ict/minesunshineone/peek/handler/PlayerStateRestorer.java

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* 包括传送、游戏模式、生命值、饥饿度、药水效果等
1717
*/
1818
public class PlayerStateRestorer {
19+
private static final Vector ZERO_VECTOR = new Vector(0, 0, 0);
1920

2021
private final PeekPlugin plugin;
2122

@@ -30,25 +31,29 @@ public PlayerStateRestorer(PeekPlugin plugin) {
3031
* @param data PeekData 数据
3132
*/
3233
public void restorePlayerState(Player peeker, PeekData data) {
33-
plugin.getServer().getRegionScheduler().run(plugin, data.getOriginalLocation(), task -> {
34+
final Runnable onFailed = () -> handleTeleportFailure(peeker, data);
35+
36+
final boolean scheduled = peeker.getScheduler().execute(plugin, ()-> {
3437

3538
// 强制清理任何骑乘/附身状态,防止卡在旁观者模式
36-
PlayerStateUtil.forceExitRidingState(peeker, plugin.getLogger());
39+
PlayerStateUtil.forceExitRidingState(peeker);
3740

3841
// 在传送前先清除动量
39-
peeker.setVelocity(new Vector(0, 0, 0));
42+
peeker.setVelocity(ZERO_VECTOR);
4043

4144
peeker.teleportAsync(data.getOriginalLocation(), TeleportCause.PLUGIN).thenAccept(success -> {
4245
if (success) {
4346
// 传送成功后再改变游戏模式
44-
plugin.getServer().getRegionScheduler().run(plugin, data.getOriginalLocation(), modeTask -> {
45-
applyRestoredState(peeker, data);
46-
});
47+
applyRestoredState(peeker, data);
4748
} else {
48-
handleTeleportFailure(peeker, data);
49+
onFailed.run();
4950
}
5051
});
51-
});
52+
}, onFailed, 1L);
53+
54+
if (!scheduled) {
55+
onFailed.run();
56+
}
5257
}
5358

5459
/**
@@ -62,28 +67,31 @@ public void handleTeleportFailure(Player peeker, PeekData data) {
6267
"无法将玩家 %s 传送回原位置,正在尝试传送到重生点",
6368
peeker.getName()));
6469

65-
Location spawnLoc = resolveSpawnLocation(peeker);
70+
final Location spawnLoc = resolveSpawnLocation(peeker);
71+
72+
final Runnable onFailed = () -> {
73+
plugin.getLogger().severe(String.format(
74+
"未找到可用的重生点,强制恢复玩家 %s 的状态",
75+
peeker.getName()));
76+
forceStateRestoreWithoutTeleport(peeker, data);
77+
};
6678

6779
if (spawnLoc != null) {
68-
plugin.getServer().getRegionScheduler().run(plugin, spawnLoc, spawnTask -> {
80+
final boolean scheduled = peeker.getScheduler().execute(plugin, () -> {
6981
peeker.teleportAsync(spawnLoc, TeleportCause.PLUGIN).thenAccept(spawnSuccess -> {
7082
if (spawnSuccess) {
71-
plugin.getServer().getRegionScheduler().run(plugin, spawnLoc, modeTask -> {
72-
applyRestoredState(peeker, data);
73-
});
83+
applyRestoredState(peeker, data);
7484
} else {
75-
plugin.getLogger().severe(String.format(
76-
"无法将玩家 %s 传送到任何安全位置",
77-
peeker.getName()));
78-
forceStateRestoreWithoutTeleport(peeker, data);
85+
onFailed.run();
7986
}
8087
});
81-
});
88+
}, onFailed, 1L);
89+
90+
if (!scheduled) {
91+
onFailed.run();
92+
}
8293
} else {
83-
plugin.getLogger().severe(String.format(
84-
"未找到可用的重生点,强制恢复玩家 %s 的状态",
85-
peeker.getName()));
86-
forceStateRestoreWithoutTeleport(peeker, data);
94+
onFailed.run();
8795
}
8896

8997
plugin.getMessages().send(peeker, "teleport-failed");
@@ -97,17 +105,13 @@ public void handleTeleportFailure(Player peeker, PeekData data) {
97105
*/
98106
public Location resolveSpawnLocation(Player peeker) {
99107
Location respawnLocation = peeker.getRespawnLocation();
108+
100109
if (respawnLocation != null) {
101110
return respawnLocation;
102111
}
103112

104-
if (peeker.getWorld() != null) {
105-
return peeker.getWorld().getSpawnLocation();
106-
}
113+
return peeker.getWorld().getSpawnLocation();
107114

108-
return plugin.getServer().getWorlds().isEmpty()
109-
? null
110-
: plugin.getServer().getWorlds().get(0).getSpawnLocation();
111115
}
112116

113117
/**
@@ -117,9 +121,7 @@ public Location resolveSpawnLocation(Player peeker) {
117121
* @param data PeekData 数据
118122
*/
119123
public void forceStateRestoreWithoutTeleport(Player peeker, PeekData data) {
120-
plugin.getServer().getRegionScheduler().run(plugin, peeker.getLocation(), modeTask -> {
121-
applyRestoredState(peeker, data);
122-
});
124+
applyRestoredState(peeker, data);
123125
}
124126

125127
/**
@@ -133,7 +135,7 @@ public void applyRestoredState(Player peeker, PeekData data) {
133135
peeker.setVelocity(new Vector(0, 0, 0));
134136

135137
// 再次强制清理骑乘/附身状态,确保万无一失
136-
PlayerStateUtil.forceExitRidingState(peeker, plugin.getLogger());
138+
PlayerStateUtil.forceExitRidingState(peeker);
137139

138140
peeker.setGameMode(data.getOriginalGameMode());
139141
double maxHealth = getMaxHealth(peeker);

0 commit comments

Comments
 (0)