1313
1414import ict .minesunshineone .peek .PeekPlugin ;
1515import ict .minesunshineone .peek .data .PeekData ;
16+ import ict .minesunshineone .peek .util .PlayerStateUtil ;
1617
1718/**
1819 * 核心 Peek 状态管理器
@@ -22,7 +23,7 @@ public class PeekStateHandler {
2223
2324 private final PeekPlugin plugin ;
2425 private final Map <UUID , PeekData > activePeeks = new HashMap <>();
25-
26+
2627 // 委托的处理器
2728 private final BossBarHandler bossBarHandler ;
2829 private final RangeChecker rangeChecker ;
@@ -66,8 +67,7 @@ public void startPeek(Player peeker, Player target) {
6667 peeker .getHealth (),
6768 peeker .getFoodLevel (),
6869 peeker .getSaturation (),
69- peeker .getActivePotionEffects ()
70- );
70+ peeker .getActivePotionEffects ());
7171
7272 activePeeks .put (peeker .getUniqueId (), data );
7373 plugin .getStateManager ().savePlayerState (peeker , data );
@@ -81,7 +81,7 @@ public void startPeek(Player peeker, Player target) {
8181
8282 // 发送消息给观察者
8383 plugin .getMessages ().send (peeker , "peek-start" , "player" , target .getName ());
84-
84+
8585 // 只有非静默模式才通知目标
8686 if (!silentPeek ) {
8787 plugin .getMessages ().send (target , "being-peeked" , "player" , peeker .getName ());
@@ -120,10 +120,10 @@ public void startSelfPeek(Player peeker) {
120120
121121 try {
122122 logDebug ("Starting self peek: %s" , peeker .getName ());
123-
123+
124124 // 保存当前位置作为原始位置
125125 Location originalLocation = peeker .getLocation ().clone ();
126-
126+
127127 // 创建特殊的 PeekData,目标设为自己
128128 PeekData data = new PeekData (
129129 originalLocation ,
@@ -133,16 +133,15 @@ public void startSelfPeek(Player peeker) {
133133 peeker .getHealth (),
134134 peeker .getFoodLevel (),
135135 peeker .getSaturation (),
136- peeker .getActivePotionEffects ()
137- );
136+ peeker .getActivePotionEffects ());
138137
139138 activePeeks .put (peeker .getUniqueId (), data );
140139 plugin .getStateManager ().savePlayerState (peeker , data );
141140 plugin .getStatisticsManager ().recordPeekStart (peeker , peeker ); // 统计中目标也是自己
142141
143142 // 设置为观察者模式但不传送
144143 setSelfPeekGameMode (peeker );
145-
144+
146145 // 发送消息
147146 plugin .getMessages ().send (peeker , "self-peek-start" );
148147
@@ -153,15 +152,16 @@ public void startSelfPeek(Player peeker) {
153152 // 创建 BossBar 并启动自我观察距离检查器
154153 bossBarHandler .createSelfPeekBossBar (peeker , plugin .getMessages ().get ("self-peek-origin" , "原点" ));
155154 startSelfRangeChecker (peeker , originalLocation );
156-
155+
157156 logDebug ("Self peek started successfully for player: %s" , peeker .getName ());
158-
157+
159158 } catch (Exception e ) {
160- plugin .getLogger ().warning (String .format ("启动自我观察时发生错误,玩家: %s,错误: %s" , peeker .getName (), e .getMessage ()));
159+ plugin .getLogger ()
160+ .warning (String .format ("启动自我观察时发生错误,玩家: %s,错误: %s" , peeker .getName (), e .getMessage ()));
161161 if (plugin .getConfig ().getBoolean ("debug" , false )) {
162162 e .printStackTrace ();
163163 }
164-
164+
165165 // 清理可能的残留状态
166166 activePeeks .remove (peeker .getUniqueId ());
167167 // 通知玩家发生错误
@@ -220,11 +220,11 @@ public void endPeek(Player peeker, boolean shouldRestore) {
220220 if (peeker .isOnline ()) {
221221 plugin .getMessages ().send (peeker , "peek-end" );
222222 }
223-
223+
224224 // 检查是否是自我观察模式
225225 boolean isSelfPeek = target != null && target .getUniqueId ().equals (peeker .getUniqueId ());
226226 boolean silentPeek = peeker .isOnline () && plugin .getTargetHandler ().shouldSilentPeek (peeker );
227-
227+
228228 // 非自我观察且非静默模式才通知目标
229229 if (target != null && target .isOnline () && !isSelfPeek && !silentPeek ) {
230230 plugin .getMessages ().send (target , "peek-end-target" , "player" , peeker .getName ());
@@ -249,23 +249,13 @@ private void teleportAndSetGameMode(Player peeker, Player target) {
249249 // 先切换游戏模式
250250 plugin .getServer ().getRegionScheduler ().run (plugin , peeker .getLocation (), task -> {
251251 try {
252- // 如果玩家在睡觉,先让他离开床
253- if (peeker .isSleeping ()) {
254- peeker .wakeup (false );
255- }
256-
257- // 传送之前先设置为蹲下
258- peeker .setSneaking (true );
259-
260- // 如果玩家在附身状态,先退出附身
261- if (peeker .getGameMode () == GameMode .SPECTATOR && peeker .getSpectatorTarget () != null ) {
262- peeker .setSpectatorTarget (null );
263- }
252+ // 清理骑乘状态,准备进入旁观者模式
253+ PlayerStateUtil .prepareForSpectatorMode (peeker , plugin .getLogger ());
264254
265255 // 设置为旁观模式
266256 peeker .setGameMode (GameMode .SPECTATOR );
267257
268- // 等待1 tick后再传送
258+ // 等待2 tick后再传送
269259 plugin .getServer ().getRegionScheduler ().runDelayed (plugin , peeker .getLocation (), delayedTask -> {
270260 peeker .teleportAsync (target .getLocation (), TeleportCause .PLUGIN ).thenAccept (success -> {
271261 if (!success ) {
@@ -282,6 +272,7 @@ private void teleportAndSetGameMode(Player peeker, Player target) {
282272 }, 2L ); // 2 tick 延迟
283273 } catch (Exception e ) {
284274 plugin .getLogger ().warning (String .format ("为玩家 %s 切换游戏模式时发生错误" , peeker .getName ()));
275+ peeker .setSneaking (false ); // 确保异常时也恢复状态
285276 endPeek (peeker );
286277 }
287278 });
@@ -303,69 +294,63 @@ private void setSelfPeekGameMode(Player peeker) {
303294 return ;
304295 }
305296
306- if (peeker .isSleeping ()) {
307- peeker .wakeup (false );
308- }
309-
310- if (peeker .getGameMode () == GameMode .SPECTATOR && peeker .getSpectatorTarget () != null ) {
311- peeker .setSpectatorTarget (null );
312- }
297+ // 清理骑乘状态,准备进入旁观者模式
298+ PlayerStateUtil .prepareForSpectatorMode (peeker , plugin .getLogger ());
313299
314300 peeker .setGameMode (GameMode .SPECTATOR );
315-
301+
316302 logDebug ("Successfully set self peek game mode for player: %s" , peeker .getName ());
317303 } catch (Exception e ) {
318304 plugin .getLogger ().warning (String .format ("为玩家 %s 设置自我观察模式时发生错误: %s" , peeker .getName (), e .getMessage ()));
319305 if (plugin .getConfig ().getBoolean ("debug" , false )) {
320306 e .printStackTrace ();
321307 }
308+ peeker .setSneaking (false ); // 确保异常时也恢复状态
322309 endPeek (peeker );
323310 }
324311 });
325312 }
326313
327314 private void startNormalRangeChecker (Player peeker , Player target ) {
328315 rangeChecker .startRangeChecker (peeker , target ,
329- // 超出范围时
330- () -> {
331- plugin .getMessages ().send (peeker , "range-exceeded" );
332- endPeek (peeker );
333- },
334- // 目标离线时
335- () -> endPeek (peeker ),
336- // 距离更新时
337- (distance ) -> {
338- PeekData data = activePeeks .get (peeker .getUniqueId ());
339- bossBarHandler .updateDistanceBossBar (peeker , distance , data );
340- },
341- // 不同世界时
342- () -> {
343- plugin .getMessages ().send (peeker , "target-in-different-world" );
344- teleportAndSetGameMode (peeker , target );
345- }
346- );
316+ // 超出范围时
317+ () -> {
318+ plugin .getMessages ().send (peeker , "range-exceeded" );
319+ endPeek (peeker );
320+ },
321+ // 目标离线时
322+ () -> endPeek (peeker ),
323+ // 距离更新时
324+ (distance ) -> {
325+ PeekData data = activePeeks .get (peeker .getUniqueId ());
326+ bossBarHandler .updateDistanceBossBar (peeker , distance , data );
327+ },
328+ // 不同世界时
329+ () -> {
330+ plugin .getMessages ().send (peeker , "target-in-different-world" );
331+ teleportAndSetGameMode (peeker , target );
332+ });
347333 }
348334
349335 private void startSelfRangeChecker (Player peeker , Location originalLocation ) {
350336 String selfPeekLabel = plugin .getMessages ().get ("self-peek-origin" , "原点" );
351337 rangeChecker .startSelfRangeChecker (peeker , originalLocation ,
352- // 获取 Peek 数据
353- () -> activePeeks .get (peeker .getUniqueId ()),
354- // 超出自我观察范围时
355- () -> {
356- plugin .getMessages ().send (peeker , "self-peek-range-exceeded" );
357- endPeek (peeker );
358- },
359- // 世界改变时
360- () -> {
361- plugin .getMessages ().send (peeker , "self-peek-world-changed" );
362- endPeek (peeker );
363- },
364- // 距离更新时(用于更新 BossBar)
365- (distance ) -> bossBarHandler .updateDistanceBossBar (peeker , distance , selfPeekLabel ),
366- // 发生错误时
367- () -> endPeek (peeker )
368- );
338+ // 获取 Peek 数据
339+ () -> activePeeks .get (peeker .getUniqueId ()),
340+ // 超出自我观察范围时
341+ () -> {
342+ plugin .getMessages ().send (peeker , "self-peek-range-exceeded" );
343+ endPeek (peeker );
344+ },
345+ // 世界改变时
346+ () -> {
347+ plugin .getMessages ().send (peeker , "self-peek-world-changed" );
348+ endPeek (peeker );
349+ },
350+ // 距离更新时(用于更新 BossBar)
351+ (distance ) -> bossBarHandler .updateDistanceBossBar (peeker , distance , selfPeekLabel ),
352+ // 发生错误时
353+ () -> endPeek (peeker ));
369354 }
370355
371356 private void stopRangeCheckerAndBossBar (Player peeker ) {
0 commit comments