@@ -414,46 +414,73 @@ def _record_event(self, name: str, event_ts: float):
414414 self ._last_title_ts [name ] = now_real
415415 self ._send_title (name , cps )
416416
417+ def _ws_querytarget_all (self ):
418+ """WS 执行 /querytarget @a,成功返回 Parameters[0],失败返回 None。"""
419+ resp = self .game_ctrl .sendwscmd_with_resp ("/querytarget @a" , 1 )
420+ if (not resp .OutputMessages ) or (not resp .OutputMessages [0 ].Success ):
421+ return None
422+ return resp .OutputMessages [0 ].Parameters [0 ]
423+
424+ @staticmethod
425+ def _parse_querytarget_parameter (parameter ):
426+ """把 Parameters[0] 解析成 list。"""
427+ if isinstance (parameter , str ):
428+ return json .loads (parameter )
429+ return parameter
430+
431+ def _build_uuid_to_name (self ):
432+ """players_uuid(name->uuid) 反转为 uuid->name。"""
433+ players_uuid = getattr (self .game_ctrl , "players_uuid" , None )
434+ if not isinstance (players_uuid , dict ):
435+ return None
436+ return {
437+ v : k
438+ for k , v in players_uuid .items ()
439+ if isinstance (v , str )
440+ }
441+
442+ @staticmethod
443+ def _extract_positions (result_list , uuid_to_name ):
444+ """从 querytarget list 中抽取 (玩家名, (x,y,z)) 列表。"""
445+ if not isinstance (result_list , list ):
446+ return []
447+
448+ ress = []
449+ for it in result_list :
450+ if not isinstance (it , dict ):
451+ continue
452+
453+ uid = it .get ("uniqueId" )
454+ pos = it .get ("position" )
455+ if not isinstance (uid , str ):
456+ continue
457+ if not isinstance (pos , dict ):
458+ continue
459+
460+ pname = uuid_to_name .get (uid ) if uuid_to_name else None
461+ if not isinstance (pname , str ) or not pname :
462+ continue
463+
464+ x = pos .get ("x" )
465+ y = pos .get ("y" )
466+ z = pos .get ("z" )
467+ if not all (isinstance (v , (int , float )) for v in (x , y , z )):
468+ continue
469+
470+ ress .append ((pname , (float (x ), float (y ), float (z ))))
471+
472+ return ress
473+
417474 def _gather_positions (self ):
418475 """获取坐标: /querytarget @a"""
419476 try :
420- resp = self .game_ctrl .sendwscmd_with_resp ("/querytarget @a" , 1 )
421- if (not resp .OutputMessages ) or (not resp .OutputMessages [0 ].Success ):
422- return []
423- parameter = resp .OutputMessages [0 ].Parameters [0 ]
424- result_list = json .loads (parameter ) if isinstance (parameter , str ) else parameter
425- if not isinstance (result_list , list ):
477+ parameter = self ._ws_querytarget_all ()
478+ if parameter is None :
426479 return []
427-
428- players_uuid = getattr (self .game_ctrl , "players_uuid" , None )
429- uuid_to_name = None
430- if isinstance (players_uuid , dict ):
431- uuid_to_name = {v : k for k , v in players_uuid .items () if isinstance (v , str )}
432-
433- ress = []
434- for it in result_list :
435- if not isinstance (it , dict ):
436- continue
437- uid = it .get ("uniqueId" )
438- pos = it .get ("position" )
439- if not isinstance (uid , str ):
440- continue
441- if not isinstance (pos , dict ):
442- continue
443-
444- pname = uuid_to_name .get (uid ) if uuid_to_name else None
445- if not isinstance (pname , str ) or not pname :
446- continue
447-
448- x = pos .get ("x" )
449- y = pos .get ("y" )
450- z = pos .get ("z" )
451- if not all (isinstance (v , (int , float )) for v in (x , y , z )):
452- continue
453-
454- ress .append ((pname , (float (x ), float (y ), float (z ))))
455-
456- return ress
480+
481+ result_list = self ._parse_querytarget_parameter (parameter )
482+ uuid_to_name = self ._build_uuid_to_name ()
483+ return self ._extract_positions (result_list , uuid_to_name )
457484 except Exception :
458485 return []
459486
0 commit comments