Skip to content

Commit 4aa704b

Browse files
committed
impl: !here command, which allows a player broadcast his position
1 parent c5a9f0a commit 4aa704b

File tree

1 file changed

+43
-4
lines changed

1 file changed

+43
-4
lines changed

cmdRepost/cmdRepost.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import time
55
import json
66
import re
7+
import math
78

89
__all__ = ['CmdReposter']
910

@@ -44,17 +45,18 @@ def __init__(self, logger, core, config_file):
4445
# available commands
4546
self.cmd_available = {
4647
'tp': self.tp_request,
47-
# TODO: tphere
4848
'tps': self.ask_tps,
4949
'time': self.ask_time,
50-
'restart': self.restart_request,
50+
# 'restart': self.restart_request,
51+
'here': self.broadcast_pos,
5152
}
5253

5354
self.tp_log = {}
5455

5556
# queue
5657
self.repost_remained = []
5758
self.repost_receiver = []
59+
self.player_pos_map = {}
5860

5961
self.timer = QTimer(self)
6062

@@ -84,11 +86,43 @@ def check_repost(self, line):
8486
del self.repost_receiver[0]
8587
self.check_repost(line)
8688

89+
def check_player_nbt(self, line):
90+
match_obj_1 = re.match(r'[^<>]*?\[Server thread/INFO\].*?: (.*)$', line)
91+
text = match_obj_1.group(1) if match_obj_1 else ''
92+
match_obj_2 = re.match(r'^(\w+) has the following entity data: (.*)$', text)
93+
if match_obj_2:
94+
# got player entity data
95+
player = match_obj_2.group(1)
96+
if player not in self.player_pos_map:
97+
return
98+
match_obj_pos = re.match(r'\[(.*?)d, (.*?)d, (.*?)d\]', match_obj_2.group(2))
99+
match_obj_dim = re.match(r'"(minecraft:\w+)"', match_obj_2.group(2))
100+
player_nbt = self.player_pos_map[player]
101+
if match_obj_pos:
102+
player_nbt['pos'] = (
103+
math.floor(float(match_obj_pos.group(1)) + 0.5), # x
104+
math.ceil(float(match_obj_pos.group(2))), # y
105+
math.floor(float(match_obj_pos.group(3)) + 0.5), # z
106+
)
107+
self.logger.debug('CmdReposter parsed player Pos data: {}'.format(player_nbt['pos']))
108+
if match_obj_dim:
109+
player_nbt['dim'] = match_obj_dim.group(1)
110+
self.logger.debug('CmdReposter parsed player Dimension data: {}'.format(player_nbt['dim']))
111+
if player_nbt['pos'] is not None and player_nbt['dim'] is not None:
112+
x, y, z = player_nbt['pos']
113+
dim = player_nbt['dim']
114+
output_string = f'[x:{x}, y:{y}, z:{z}, dim:{dim}]'
115+
cmd = f'execute as {player} run say {output_string}'
116+
self.logger.debug('CmdReposter generated position broadcast: {}'.format(output_string))
117+
self.core.write_server(cmd)
118+
del self.player_pos_map[player]
119+
87120
@QtCore.pyqtSlot(list)
88121
def on_server_output(self, lines):
89122
for line in lines:
90123
self.check_tp(line)
91124
self.check_repost(line)
125+
self.check_player_nbt(line)
92126

93127
@QtCore.pyqtSlot(tuple)
94128
def on_player_input(self, pair):
@@ -166,5 +200,10 @@ def ask_time(self, player, text_list):
166200
else:
167201
self.utils.tell(player, 'Command not acceptable. Please check again.')
168202

169-
def restart_request(self, player, text_list):
170-
pass
203+
def broadcast_pos(self, player, text_list):
204+
self.logger.debug('CmdReposter.broadcast_pos called')
205+
self.player_pos_map[player] = { 'pos': None, 'dim': None }
206+
# Reference (CN): https://zh.minecraft.wiki/w/%E5%91%BD%E4%BB%A4/data
207+
self.core.write_server(f'data get entity {player} Pos')
208+
self.core.write_server(f'data get entity {player} Dimension')
209+
# Wait for `check_player_nbt`

0 commit comments

Comments
 (0)