hungerlib 3.2.dev9__py3-none-any.whl → 3.2.dev11__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 CHANGED
@@ -13,6 +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 health, ping, runCommand, log
16
17
  from .utils import (
17
18
  ColorMap,
18
19
  ASCII_COLOR_MAP,
@@ -93,6 +94,10 @@ __all__ = [
93
94
  'Snapshot',
94
95
  'clearTerminal',
95
96
  'validateAll',
97
+ 'health',
98
+ 'ping',
99
+ 'runCommand',
100
+ 'log',
96
101
 
97
102
  # namespaces
98
103
  'utils',
@@ -0,0 +1,42 @@
1
+ import requests
2
+
3
+ class HungerBridgeClient:
4
+ def __init__(self, base_url: str, token: str):
5
+ self.base = base_url.rstrip("/")
6
+ self.headers = {
7
+ "Authorization": f"Bearer {token}",
8
+ "Content-Type": "application/json"
9
+ }
10
+
11
+ def _post(self, path: str, payload: dict):
12
+ r = requests.post(f"{self.base}{path}", headers=self.headers, json=payload)
13
+ if not r.ok:
14
+ raise RuntimeError(f"HungerBridge error {r.status_code}: {r.text}")
15
+ return r.json()
16
+
17
+ def _get(self, path: str):
18
+ r = requests.get(f"{self.base}{path}", headers=self.headers)
19
+ if not r.ok:
20
+ raise RuntimeError(f"HungerBridge error {r.status_code}: {r.text}")
21
+ return r.json()
22
+
23
+ # -----------------------------
24
+ # Public API
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", {
34
+ "command": command,
35
+ "silent": silent
36
+ })
37
+
38
+ def log(self, message: str, level: str = "info"):
39
+ return self._post("/log", {
40
+ "level": level,
41
+ "message": message
42
+ })
@@ -1,9 +1,6 @@
1
- import inspect
2
1
  import logging
3
2
  from pathlib import Path
4
3
  from datetime import datetime
5
- from hungerlib.utils.colormaps import ASCII_COLOR_MAP, MC_COLOR_MAP
6
- from hungerlib.datamap import DataMap, Syntax, mapit
7
4
 
8
5
 
9
6
  class MessageRouter:
@@ -15,11 +12,6 @@ class MessageRouter:
15
12
  formatter=None,
16
13
  console_backspaces=0,
17
14
 
18
- origin_map=ASCII_COLOR_MAP,
19
- destination_map=ASCII_COLOR_MAP,
20
- broadcast_map=MC_COLOR_MAP,
21
- log_map=None,
22
-
23
15
  info_prefix="<white>[INFO]: ",
24
16
  warn_prefix="<yellow>[WARN]: ",
25
17
  error_prefix="<red>[ERROR]: "
@@ -33,11 +25,6 @@ class MessageRouter:
33
25
 
34
26
  self.console_backspaces = "\b" * console_backspaces
35
27
 
36
- self._origin_map = origin_map
37
- self._destination_map = destination_map
38
- self._broadcast_map = broadcast_map
39
- self._log_map = log_map
40
-
41
28
  self.info_prefix = info_prefix
42
29
  self.warn_prefix = warn_prefix
43
30
  self.error_prefix = error_prefix
@@ -57,47 +44,47 @@ class MessageRouter:
57
44
  handler.setFormatter(formatter)
58
45
  self.logger.addHandler(handler)
59
46
 
60
- # colormap getters/setters
61
- def setOriginMap(self, cmap): self._origin_map = cmap
62
- def getOriginMap(self): return self._origin_map
63
-
64
- def setDestinationMap(self, cmap): self._destination_map = cmap
65
- def getDestinationMap(self): return self._destination_map
66
-
67
- def setBroadcastMap(self, cmap): self._broadcast_map = cmap
68
- def getBroadcastMap(self): return self._broadcast_map
69
-
70
- def setLogMap(self, cmap): self._log_map = cmap
71
- def getLogMap(self): return self._log_map
72
-
73
- # routing primatives
47
+ # routing primitives
74
48
  def origin(self, msg):
75
- colored = mapit(msg, self._origin_map)
76
- print(colored)
49
+ print(msg)
77
50
 
78
51
  def destination(self, msg):
79
- if not self.server or not hasattr(self.server, "_rcon_send"):
52
+ if not self.server:
80
53
  return
81
- colored = mapit(msg, self._destination_map)
82
- self.server._rcon_send(
83
- f'logtellraw targetless "{self.console_backspaces}{colored}"'
84
- )
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
+ )
85
69
 
86
70
  def log(self, msg, level="INFO"):
87
- clean = msg
88
- if self._log_map:
89
- for tag in self._log_map.as_dict().keys():
90
- clean = clean.replace(tag, "")
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)
78
+
91
79
  {
92
80
  "INFO": self.logger.info,
93
81
  "WARN": self.logger.warning,
94
82
  "ERROR": self.logger.error
95
- }[level](clean)
83
+ }[level](msg)
96
84
 
97
85
  def broadcast(self, msg):
98
86
  if hasattr(self.server, "sendBroadcast"):
99
- colored = mapit(msg, self._broadcast_map)
100
- self.server.sendBroadcast(colored)
87
+ self.server.sendBroadcast(msg)
101
88
 
102
89
  # high level router
103
90
  def say(
@@ -1,21 +1,25 @@
1
1
  import time
2
2
  import re
3
3
  import mcrcon
4
+
4
5
  from hungerlib.panel import Panel
5
6
  from hungerlib.utils.colormaps import MC_COLOR_MAP, ASCII_COLOR_MAP
6
7
  from hungerlib.servers import GenericServer
8
+ from hungerlib.bridge import HungerBridgeClient
7
9
 
8
10
 
9
11
  class MinecraftServer(GenericServer):
10
12
  def __init__(
11
13
  self,
12
14
  name,
13
- panel,
15
+ panel: Panel,
14
16
  server_id,
15
17
  server_domain,
16
18
  server_port,
17
19
  rcon_port,
18
20
  rcon_password,
21
+ bridge_url=None,
22
+ bridge_token=None,
19
23
  mc_color_map=MC_COLOR_MAP,
20
24
  ascii_color_map=ASCII_COLOR_MAP,
21
25
  tpsCommand='tt20 tps',
@@ -31,7 +35,6 @@ class MinecraftServer(GenericServer):
31
35
  else ascii_color_map
32
36
  )
33
37
 
34
- # Pass normalized maps to GenericServer
35
38
  super().__init__(
36
39
  name,
37
40
  panel,
@@ -47,9 +50,12 @@ class MinecraftServer(GenericServer):
47
50
  self.rcon_password = rcon_password
48
51
  self.tpsCommand = tpsCommand
49
52
 
53
+ # Optional HungerBridge client
54
+ self.bridge: HungerBridgeClient | None = None
55
+ if bridge_url and bridge_token:
56
+ self.bridge = HungerBridgeClient(bridge_url, bridge_token)
50
57
 
51
-
52
- # rcon handler
58
+ # rcon handler (fallback path)
53
59
  def _rcon_send(self, command):
54
60
  if not self.server_domain or not self.rcon_password:
55
61
  return None
@@ -65,17 +71,19 @@ class MinecraftServer(GenericServer):
65
71
 
66
72
  # getter methods
67
73
  def getPlayers(self):
74
+ # Prefer bridge if we ever add an endpoint; for now still RCON
68
75
  output = self._rcon_send("list")
69
76
  if not output:
70
77
  return None
71
78
  m = re.search(r"There are (\d+)", output)
72
79
  return int(m.group(1)) if m else None
80
+
73
81
  def getTPS(self, type="raw", rounding=10):
74
- '''
82
+ """
75
83
  This has limitations and is not yet complete. It currently ONLY parses TT20's tps command.
76
84
  Example: /tt20 tps
77
85
  This parser WILL NOT WORK with other configurations!
78
- '''
86
+ """
79
87
  output = self._rcon_send(self.tpsCommand)
80
88
  if not output:
81
89
  return None
@@ -91,12 +99,29 @@ class MinecraftServer(GenericServer):
91
99
  value = table.get(type, avg)
92
100
  return round(value, rounding) if rounding else value
93
101
 
94
-
95
102
  # commands
96
- def sendConsoleCommand(self, command):
103
+ def sendConsoleCommand(self, command: str):
104
+ # Prefer HungerBridge
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)
97
112
  return self.panel.commands.send(self.server_id, command)
98
- def sendBroadcast(self, message):
113
+
114
+ def sendBroadcast(self, message: str):
99
115
  translated = self._translate_mc_colors(message)
100
116
  safe = translated.replace('"', '\\"')
101
117
  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
102
127
  return self.sendConsoleCommand(cmd)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hungerlib
3
- Version: 3.2.dev9
3
+ Version: 3.2.dev11
4
4
  Summary: Powerful automation library for Pterodactyl.
5
5
  Author: iFamished
6
6
  License: MIT
@@ -1,7 +1,8 @@
1
- hungerlib/__init__.py,sha256=CTLIet8Tg8Gx3wWUrUNgIsHutv0JS1YzLelp1GLaLTs,2147
1
+ hungerlib/__init__.py,sha256=AtHBFZzOJzVteOLdSe9RA3XPWFvC6H7IyeOHobQnESg,2258
2
+ hungerlib/bridgeclient.py,sha256=-6i5QsloXGt57ayj5-W0WAPbkwxwOyw9noeSabX4EVE,1283
2
3
  hungerlib/configloader.py,sha256=TdEFqk2zG5nT-vJqdjA36DrbRinY66n0rgI8Z-EZmAk,2548
3
4
  hungerlib/datamap.py,sha256=Tvcjc-n-tNO9SNQeh0k3dWzbxrRnnNVUmPnq0gap_8w,2807
4
- hungerlib/messagerouter.py,sha256=1-4KeUT6AgTF0F53n3BtWt0ch0lnHHXYPOWvRtvUVKY,4344
5
+ hungerlib/messagerouter.py,sha256=zd3OvU_ag7ELyU4PHJCeUjnHk8ElN5smMyGd099w8QQ,3827
5
6
  hungerlib/panel.py,sha256=LljDy3FZoabWotdrNhN89xHd2VcvbiQDshtZgMa0g08,2013
6
7
  hungerlib/api/__init__.py,sha256=xuPbWBXVTkr9Jtcmvk8PPiVvi8HDxrIOmb_gOcDZy-M,336
7
8
  hungerlib/api/backups.py,sha256=eJEaCot9QpyvaqB3qne6e94CYmjJahj9Tf9r8ogUQr0,642
@@ -12,13 +13,13 @@ hungerlib/api/schedule.py,sha256=7MmfmSxTs4fgtJBfUQbc2nvvhPLrs2jQ50I73HHvS5s,797
12
13
  hungerlib/api/startup.py,sha256=YX6y7ZXG6DRNLvUjQFk4Cx7J5Ny4ym6OIWyyQsV5bwE,381
13
14
  hungerlib/servers/__init__.py,sha256=ApApJ18N_V6vTxDRVekj98Vdf80JhefYQkTH-5Ow9co,132
14
15
  hungerlib/servers/generic.py,sha256=vbAt85YKABwExNNAw8g9eAp-laeKQmgGJ0Qs1L6tNjk,8649
15
- hungerlib/servers/minecraft.py,sha256=VbzSQqztMB9RZkW9x7R8uWAZgmEbQuT5NnEIPCi0LyU,3166
16
+ hungerlib/servers/minecraft.py,sha256=ijiW8rHUSOcvRzw0sesWD57qwjlFkfTBHq_XbK6-gVk,4107
16
17
  hungerlib/utils/__init__.py,sha256=xyUldIwkVopZrp0Yp5g18vqGDUp3OOT4KknntLU4oes,504
17
18
  hungerlib/utils/colormaps.py,sha256=88eIDSI1hZYbtXmd7XujgmR1nhOXAkyB8ospQTqSHns,1240
18
19
  hungerlib/utils/time.py,sha256=lhLHMkL5NEP9f7j5k24k5brr1ZvAL22t07eV2rxTZ50,2354
19
20
  hungerlib/utils/utils.py,sha256=rGVXiK-ZaN1riNL_1QHKJZdOAX53vGlSDUzEP1Aqle4,1404
20
- hungerlib-3.2.dev9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
21
- hungerlib-3.2.dev9.dist-info/METADATA,sha256=vAcqjfRaHsF7mCQaaD-lf3FwNpMOJvLr5iPebOpJJ9E,1535
22
- hungerlib-3.2.dev9.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
23
- hungerlib-3.2.dev9.dist-info/top_level.txt,sha256=uHBMIM8b2Gt6daNkDF4uw-M2Hm2IpIVw1jOK9wC0fNQ,10
24
- hungerlib-3.2.dev9.dist-info/RECORD,,
21
+ hungerlib-3.2.dev11.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
22
+ hungerlib-3.2.dev11.dist-info/METADATA,sha256=03T6Mp-oxqqHkStae-8Af59p9XoLYWufOdEXgaF3T1g,1536
23
+ hungerlib-3.2.dev11.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
24
+ hungerlib-3.2.dev11.dist-info/top_level.txt,sha256=uHBMIM8b2Gt6daNkDF4uw-M2Hm2IpIVw1jOK9wC0fNQ,10
25
+ hungerlib-3.2.dev11.dist-info/RECORD,,