hungerlib 3.2.dev13__py3-none-any.whl → 3.2.dev14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hungerlib/__init__.py +2 -2
- hungerlib/bridgeclient.py +19 -20
- hungerlib/messagerouter.py +13 -54
- hungerlib/servers/minecraft.py +13 -52
- {hungerlib-3.2.dev13.dist-info → hungerlib-3.2.dev14.dist-info}/METADATA +1 -1
- {hungerlib-3.2.dev13.dist-info → hungerlib-3.2.dev14.dist-info}/RECORD +9 -9
- {hungerlib-3.2.dev13.dist-info → hungerlib-3.2.dev14.dist-info}/WHEEL +0 -0
- {hungerlib-3.2.dev13.dist-info → hungerlib-3.2.dev14.dist-info}/licenses/LICENSE +0 -0
- {hungerlib-3.2.dev13.dist-info → hungerlib-3.2.dev14.dist-info}/top_level.txt +0 -0
hungerlib/__init__.py
CHANGED
|
@@ -13,7 +13,7 @@ from .datamap import set_default_maps, get_default_maps, Syntax, DataMap, datama
|
|
|
13
13
|
from .messagerouter import MessageRouter
|
|
14
14
|
from .panel import Panel
|
|
15
15
|
from .servers import GenericServer, MinecraftServer
|
|
16
|
-
from .bridgeclient import
|
|
16
|
+
from .bridgeclient import BridgeClient
|
|
17
17
|
from .utils import (
|
|
18
18
|
ColorMap,
|
|
19
19
|
ASCII_COLOR_MAP,
|
|
@@ -94,7 +94,7 @@ __all__ = [
|
|
|
94
94
|
'Snapshot',
|
|
95
95
|
'clearTerminal',
|
|
96
96
|
'validateAll',
|
|
97
|
-
'
|
|
97
|
+
'BridgeClient',
|
|
98
98
|
|
|
99
99
|
# namespaces
|
|
100
100
|
'utils',
|
hungerlib/bridgeclient.py
CHANGED
|
@@ -1,42 +1,41 @@
|
|
|
1
1
|
import requests
|
|
2
|
+
import json
|
|
2
3
|
|
|
3
|
-
class
|
|
4
|
-
def __init__(self,
|
|
5
|
-
self.base =
|
|
4
|
+
class BridgeClient:
|
|
5
|
+
def __init__(self, url, token):
|
|
6
|
+
self.base = url.rstrip("/")
|
|
6
7
|
self.headers = {
|
|
7
|
-
"
|
|
8
|
+
"X-Auth-Key": token,
|
|
8
9
|
"Content-Type": "application/json"
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
def _post(self, path
|
|
12
|
+
def _post(self, path, payload):
|
|
12
13
|
r = requests.post(f"{self.base}{path}", headers=self.headers, json=payload)
|
|
13
14
|
if not r.ok:
|
|
14
15
|
raise RuntimeError(f"HungerBridge error {r.status_code}: {r.text}")
|
|
15
16
|
return r.json()
|
|
16
17
|
|
|
17
|
-
def _get(self, path
|
|
18
|
+
def _get(self, path):
|
|
18
19
|
r = requests.get(f"{self.base}{path}", headers=self.headers)
|
|
19
20
|
if not r.ok:
|
|
20
21
|
raise RuntimeError(f"HungerBridge error {r.status_code}: {r.text}")
|
|
21
22
|
return r.json()
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# -----------------------------
|
|
26
|
-
def health(self):
|
|
27
|
-
return self._get("/health")
|
|
28
|
-
|
|
29
|
-
def ping(self):
|
|
30
|
-
return self._get("/ping")
|
|
31
|
-
|
|
32
|
-
def runCommand(self, command: str, silent: bool = False):
|
|
33
|
-
return self._post("/run", {
|
|
24
|
+
def runCommand(self, command, show_console=False, silent=False):
|
|
25
|
+
return self._post("/v1/run", {
|
|
34
26
|
"command": command,
|
|
35
|
-
"silent": silent
|
|
27
|
+
"silent": silent,
|
|
28
|
+
"show_console": show_console
|
|
36
29
|
})
|
|
37
30
|
|
|
38
|
-
def log(self, message
|
|
39
|
-
return self._post("/log", {
|
|
31
|
+
def log(self, message, level="info"):
|
|
32
|
+
return self._post("/v1/log", {
|
|
40
33
|
"level": level,
|
|
41
34
|
"message": message
|
|
42
35
|
})
|
|
36
|
+
|
|
37
|
+
def getStatus(self):
|
|
38
|
+
return self._get("/v1/status")
|
|
39
|
+
|
|
40
|
+
def getVersion(self):
|
|
41
|
+
return self._get("/v1/version")
|
hungerlib/messagerouter.py
CHANGED
|
@@ -10,11 +10,6 @@ class MessageRouter:
|
|
|
10
10
|
server,
|
|
11
11
|
log_path,
|
|
12
12
|
formatter=None,
|
|
13
|
-
console_backspaces=0,
|
|
14
|
-
|
|
15
|
-
info_prefix="<white>[INFO]: ",
|
|
16
|
-
warn_prefix="<yellow>[WARN]: ",
|
|
17
|
-
error_prefix="<red>[ERROR]: "
|
|
18
13
|
):
|
|
19
14
|
self.name = name
|
|
20
15
|
self.server = server
|
|
@@ -23,12 +18,6 @@ class MessageRouter:
|
|
|
23
18
|
self.log_path = Path(log_path)
|
|
24
19
|
self.log_path.mkdir(parents=True, exist_ok=True)
|
|
25
20
|
|
|
26
|
-
self.console_backspaces = "\b" * console_backspaces
|
|
27
|
-
|
|
28
|
-
self.info_prefix = info_prefix
|
|
29
|
-
self.warn_prefix = warn_prefix
|
|
30
|
-
self.error_prefix = error_prefix
|
|
31
|
-
|
|
32
21
|
self.logger = logging.getLogger(name)
|
|
33
22
|
self.logger.setLevel(logging.DEBUG)
|
|
34
23
|
self._init_file_logger()
|
|
@@ -45,44 +34,21 @@ class MessageRouter:
|
|
|
45
34
|
self.logger.addHandler(handler)
|
|
46
35
|
|
|
47
36
|
# routing primitives
|
|
48
|
-
def
|
|
37
|
+
def _log_origin(self, msg):
|
|
49
38
|
print(msg)
|
|
50
39
|
|
|
51
|
-
def
|
|
52
|
-
if
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# Prefer HungerBridge client if present
|
|
56
|
-
bridge = getattr(self.server, "bridge", None)
|
|
57
|
-
if bridge is not None:
|
|
58
|
-
try:
|
|
59
|
-
bridge.log(self.console_backspaces + msg, level="info")
|
|
60
|
-
return
|
|
61
|
-
except Exception as e:
|
|
62
|
-
print("Bridge destination error, falling back to RCON:", e)
|
|
63
|
-
|
|
64
|
-
# Fallback to RCON/logtellraw
|
|
65
|
-
if hasattr(self.server, "_rcon_send"):
|
|
66
|
-
self.server._rcon_send(
|
|
67
|
-
f'logtellraw targetless "{self.console_backspaces}{msg}"'
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
def log(self, msg, level="INFO"):
|
|
71
|
-
# Prefer HungerBridge client for server log
|
|
72
|
-
bridge = getattr(self.server, "bridge", None)
|
|
73
|
-
if bridge is not None:
|
|
74
|
-
try:
|
|
75
|
-
bridge.log(msg, level=level.lower())
|
|
76
|
-
except Exception as e:
|
|
77
|
-
print("Bridge log error, falling back to file log:", e)
|
|
40
|
+
def _log_destination(self, msg):
|
|
41
|
+
if hasattr(self.server, "bridge"):
|
|
42
|
+
self.server.bridge.log(msg)
|
|
78
43
|
|
|
44
|
+
def _log_file(self, msg, level="INFO"):
|
|
79
45
|
{
|
|
80
46
|
"INFO": self.logger.info,
|
|
81
47
|
"WARN": self.logger.warning,
|
|
82
48
|
"ERROR": self.logger.error
|
|
83
49
|
}[level](msg)
|
|
84
50
|
|
|
85
|
-
def
|
|
51
|
+
def _broadcast(self, msg):
|
|
86
52
|
if hasattr(self.server, "sendBroadcast"):
|
|
87
53
|
self.server.sendBroadcast(msg)
|
|
88
54
|
|
|
@@ -100,36 +66,29 @@ class MessageRouter:
|
|
|
100
66
|
if not template:
|
|
101
67
|
return
|
|
102
68
|
|
|
103
|
-
if level == "info":
|
|
104
|
-
template = self.info_prefix + template
|
|
105
|
-
elif level == "warn":
|
|
106
|
-
template = self.warn_prefix + template
|
|
107
|
-
elif level == "error":
|
|
108
|
-
template = self.error_prefix + template
|
|
109
|
-
|
|
110
69
|
if self.formatter:
|
|
111
70
|
msg = self.formatter(template, **fmt)
|
|
112
71
|
else:
|
|
113
72
|
msg = template
|
|
114
73
|
|
|
115
74
|
if origin:
|
|
116
|
-
self.
|
|
75
|
+
self._log_origin(msg)
|
|
117
76
|
|
|
118
77
|
if destination:
|
|
119
|
-
self.
|
|
78
|
+
self._log_destination(msg)
|
|
120
79
|
|
|
121
80
|
if log:
|
|
122
|
-
self.
|
|
81
|
+
self._log_file(msg, level=level.upper())
|
|
123
82
|
|
|
124
83
|
if broadcast:
|
|
125
|
-
self.
|
|
84
|
+
self._broadcast(msg)
|
|
126
85
|
|
|
127
86
|
# level helpers
|
|
128
87
|
def info(self, template, **fmt):
|
|
129
|
-
self.say(
|
|
88
|
+
self.say(template, level="info", **fmt)
|
|
130
89
|
|
|
131
90
|
def warn(self, template, **fmt):
|
|
132
|
-
self.say(
|
|
91
|
+
self.say(template, level="warn", **fmt)
|
|
133
92
|
|
|
134
93
|
def error(self, template, **fmt):
|
|
135
|
-
self.say(
|
|
94
|
+
self.say(template, level="error", **fmt)
|
hungerlib/servers/minecraft.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import time
|
|
2
2
|
import re
|
|
3
|
-
import mcrcon
|
|
4
3
|
|
|
5
4
|
from hungerlib.panel import Panel
|
|
6
5
|
from hungerlib.utils.colormaps import MC_COLOR_MAP, ASCII_COLOR_MAP
|
|
7
6
|
from hungerlib.servers import GenericServer
|
|
8
|
-
from hungerlib.bridgeclient import
|
|
7
|
+
from hungerlib.bridgeclient import BridgeClient
|
|
8
|
+
from hungerlib.datamap import mapit
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class MinecraftServer(GenericServer):
|
|
@@ -16,12 +16,8 @@ class MinecraftServer(GenericServer):
|
|
|
16
16
|
server_id,
|
|
17
17
|
server_domain,
|
|
18
18
|
server_port,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
bridge_url=None,
|
|
22
|
-
bridge_token=None,
|
|
23
|
-
mc_color_map=MC_COLOR_MAP,
|
|
24
|
-
ascii_color_map=ASCII_COLOR_MAP,
|
|
19
|
+
bridge_url,
|
|
20
|
+
bridge_token,
|
|
25
21
|
tpsCommand='tt20 tps',
|
|
26
22
|
):
|
|
27
23
|
mc_map = (
|
|
@@ -46,33 +42,15 @@ class MinecraftServer(GenericServer):
|
|
|
46
42
|
# Minecraft-specific fields
|
|
47
43
|
self.server_domain = server_domain
|
|
48
44
|
self.server_port = server_port
|
|
49
|
-
self.rcon_port = rcon_port
|
|
50
|
-
self.rcon_password = rcon_password
|
|
51
45
|
self.tpsCommand = tpsCommand
|
|
52
46
|
|
|
53
|
-
#
|
|
54
|
-
self.bridge
|
|
55
|
-
if bridge_url and bridge_token:
|
|
56
|
-
self.bridge = HungerBridgeClient(bridge_url, bridge_token)
|
|
47
|
+
# HungerBridge client
|
|
48
|
+
self.bridge = BridgeClient(bridge_url, bridge_token)
|
|
57
49
|
|
|
58
|
-
# rcon handler (fallback path)
|
|
59
|
-
def _rcon_send(self, command):
|
|
60
|
-
if not self.server_domain or not self.rcon_password:
|
|
61
|
-
return None
|
|
62
|
-
try:
|
|
63
|
-
with mcrcon.MCRcon(self.server_domain, self.rcon_password, port=self.rcon_port) as m:
|
|
64
|
-
resp1 = m.command(command)
|
|
65
|
-
time.sleep(0.05)
|
|
66
|
-
resp2 = m.command("") # fetch buffered packets
|
|
67
|
-
return (resp1 or "") + (resp2 or "")
|
|
68
|
-
except Exception as e:
|
|
69
|
-
print("RCON error:", e)
|
|
70
|
-
return None
|
|
71
50
|
|
|
72
51
|
# getter methods
|
|
73
52
|
def getPlayers(self):
|
|
74
|
-
|
|
75
|
-
output = self._rcon_send("list")
|
|
53
|
+
output = self.bridge.runCommand("list")
|
|
76
54
|
if not output:
|
|
77
55
|
return None
|
|
78
56
|
m = re.search(r"There are (\d+)", output)
|
|
@@ -84,7 +62,7 @@ class MinecraftServer(GenericServer):
|
|
|
84
62
|
Example: /tt20 tps
|
|
85
63
|
This parser WILL NOT WORK with other configurations!
|
|
86
64
|
"""
|
|
87
|
-
output = self.
|
|
65
|
+
output = self.sendCommand(self.tpsCommand)
|
|
88
66
|
if not output:
|
|
89
67
|
return None
|
|
90
68
|
clean = re.sub(r"§.", "", output)
|
|
@@ -100,28 +78,11 @@ class MinecraftServer(GenericServer):
|
|
|
100
78
|
return round(value, rounding) if rounding else value
|
|
101
79
|
|
|
102
80
|
# commands
|
|
103
|
-
def sendConsoleCommand(self, command
|
|
104
|
-
|
|
105
|
-
if self.bridge is not None:
|
|
106
|
-
try:
|
|
107
|
-
return self.bridge.runCommand(command)
|
|
108
|
-
except Exception as e:
|
|
109
|
-
print("Bridge command error, falling back to panel:", e)
|
|
110
|
-
|
|
111
|
-
# Fallback to panel (which may use RCON or other transport)
|
|
112
|
-
return self.panel.commands.send(self.server_id, command)
|
|
81
|
+
def sendConsoleCommand(self, command, show_console=False, silent=False):
|
|
82
|
+
return self.bridge.runCommand(command, show_console, silent)
|
|
113
83
|
|
|
114
|
-
def sendBroadcast(self, message
|
|
115
|
-
translated =
|
|
84
|
+
def sendBroadcast(self, message):
|
|
85
|
+
translated = mapit(message, MC_COLOR_MAP)
|
|
116
86
|
safe = translated.replace('"', '\\"')
|
|
117
87
|
cmd = f'tellraw @a {{"text":"{safe}"}}'
|
|
118
|
-
|
|
119
|
-
# Prefer HungerBridge
|
|
120
|
-
if self.bridge is not None:
|
|
121
|
-
try:
|
|
122
|
-
return self.bridge.runCommand(cmd)
|
|
123
|
-
except Exception as e:
|
|
124
|
-
print("Bridge broadcast error, falling back to panel:", e)
|
|
125
|
-
|
|
126
|
-
# Fallback
|
|
127
|
-
return self.sendConsoleCommand(cmd)
|
|
88
|
+
return self.bridge.runCommand(cmd)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
hungerlib/__init__.py,sha256=
|
|
2
|
-
hungerlib/bridgeclient.py,sha256
|
|
1
|
+
hungerlib/__init__.py,sha256=wESqR_U2a-Y86CUOQvqXkLKYSoffzlaXRhLkQtWNnac,2206
|
|
2
|
+
hungerlib/bridgeclient.py,sha256=LQThA82geuuMVI38x7cmi4YrLI0Z7FULWm21cUO-_DM,1210
|
|
3
3
|
hungerlib/configloader.py,sha256=TdEFqk2zG5nT-vJqdjA36DrbRinY66n0rgI8Z-EZmAk,2548
|
|
4
4
|
hungerlib/datamap.py,sha256=Tvcjc-n-tNO9SNQeh0k3dWzbxrRnnNVUmPnq0gap_8w,2807
|
|
5
|
-
hungerlib/messagerouter.py,sha256=
|
|
5
|
+
hungerlib/messagerouter.py,sha256=zwtGvezCTVPFUoWaeKr5XYkEf4y4MlC-SWEWmUx6V_A,2384
|
|
6
6
|
hungerlib/panel.py,sha256=LljDy3FZoabWotdrNhN89xHd2VcvbiQDshtZgMa0g08,2013
|
|
7
7
|
hungerlib/api/__init__.py,sha256=xuPbWBXVTkr9Jtcmvk8PPiVvi8HDxrIOmb_gOcDZy-M,336
|
|
8
8
|
hungerlib/api/backups.py,sha256=eJEaCot9QpyvaqB3qne6e94CYmjJahj9Tf9r8ogUQr0,642
|
|
@@ -13,13 +13,13 @@ hungerlib/api/schedule.py,sha256=7MmfmSxTs4fgtJBfUQbc2nvvhPLrs2jQ50I73HHvS5s,797
|
|
|
13
13
|
hungerlib/api/startup.py,sha256=YX6y7ZXG6DRNLvUjQFk4Cx7J5Ny4ym6OIWyyQsV5bwE,381
|
|
14
14
|
hungerlib/servers/__init__.py,sha256=ApApJ18N_V6vTxDRVekj98Vdf80JhefYQkTH-5Ow9co,132
|
|
15
15
|
hungerlib/servers/generic.py,sha256=vbAt85YKABwExNNAw8g9eAp-laeKQmgGJ0Qs1L6tNjk,8649
|
|
16
|
-
hungerlib/servers/minecraft.py,sha256=
|
|
16
|
+
hungerlib/servers/minecraft.py,sha256=cSJ6Hym9ONvERgNLvbuB8u40dPk-TZQvI2qwNnBuQBE,2638
|
|
17
17
|
hungerlib/utils/__init__.py,sha256=xyUldIwkVopZrp0Yp5g18vqGDUp3OOT4KknntLU4oes,504
|
|
18
18
|
hungerlib/utils/colormaps.py,sha256=88eIDSI1hZYbtXmd7XujgmR1nhOXAkyB8ospQTqSHns,1240
|
|
19
19
|
hungerlib/utils/time.py,sha256=lhLHMkL5NEP9f7j5k24k5brr1ZvAL22t07eV2rxTZ50,2354
|
|
20
20
|
hungerlib/utils/utils.py,sha256=rGVXiK-ZaN1riNL_1QHKJZdOAX53vGlSDUzEP1Aqle4,1404
|
|
21
|
-
hungerlib-3.2.
|
|
22
|
-
hungerlib-3.2.
|
|
23
|
-
hungerlib-3.2.
|
|
24
|
-
hungerlib-3.2.
|
|
25
|
-
hungerlib-3.2.
|
|
21
|
+
hungerlib-3.2.dev14.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
22
|
+
hungerlib-3.2.dev14.dist-info/METADATA,sha256=ls-7FYUhpQm1XkkLI4JtF1ARajQEpvjOSyEUVm1SlMo,1536
|
|
23
|
+
hungerlib-3.2.dev14.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
24
|
+
hungerlib-3.2.dev14.dist-info/top_level.txt,sha256=uHBMIM8b2Gt6daNkDF4uw-M2Hm2IpIVw1jOK9wC0fNQ,10
|
|
25
|
+
hungerlib-3.2.dev14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|