fix: patch pymumble protocol version and harden mumble connections
- Update reported protocol version from 1.2.4 to 1.5.0 so modern Murmur servers treat PyMumble as a compatible client - Fix OS string to report actual platform instead of "PyMumble 1.6.1" (was shown as [Invalid] by Murmur) - Raise pymumble reconnect retry interval to 15s to prevent autoban when running multiple bots from the same IP - Enable TCP keepalive on control socket (10s idle) to prevent NAT gateways from dropping long-lived connections Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
1. pymumble: ssl.wrap_socket was removed in 3.13
|
1. pymumble: ssl.wrap_socket was removed in 3.13
|
||||||
2. opuslib: ctypes.util.find_library fails on musl-based distros
|
2. opuslib: ctypes.util.find_library fails on musl-based distros
|
||||||
|
3. pymumble: protocol version 1.2.4 is rejected by modern servers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pathlib
|
import pathlib
|
||||||
@@ -65,5 +66,29 @@ new_init = """\
|
|||||||
self.control_socket = None"""
|
self.control_socket = None"""
|
||||||
|
|
||||||
assert old_init in src, "pymumble init_connection socket patch target not found"
|
assert old_init in src, "pymumble init_connection socket patch target not found"
|
||||||
p.write_text(src.replace(old_init, new_init))
|
src = src.replace(old_init, new_init)
|
||||||
print("pymumble reconnect socket patch applied")
|
print("pymumble reconnect socket patch applied")
|
||||||
|
|
||||||
|
p.write_text(src)
|
||||||
|
|
||||||
|
# -- pymumble: report modern protocol version --
|
||||||
|
# PyMumble 1.6.1 reports protocol version 1.2.4, which modern Murmur
|
||||||
|
# (1.5.x) treats as an invalid/legacy client. Update to 1.5.0 so the
|
||||||
|
# server enables full feature set and stops sending warnings.
|
||||||
|
p = pathlib.Path(f"{site}/pymumble_py3/constants.py")
|
||||||
|
src = p.read_text()
|
||||||
|
|
||||||
|
old_ver = "PYMUMBLE_PROTOCOL_VERSION = (1, 2, 4)"
|
||||||
|
new_ver = "PYMUMBLE_PROTOCOL_VERSION = (1, 5, 0)"
|
||||||
|
|
||||||
|
assert old_ver in src, "pymumble version patch target not found"
|
||||||
|
src = src.replace(old_ver, new_ver)
|
||||||
|
|
||||||
|
old_os = 'PYMUMBLE_OS_STRING = "PyMumble %s" % PYMUMBLE_VERSION'
|
||||||
|
new_os = 'PYMUMBLE_OS_STRING = platform.system()'
|
||||||
|
|
||||||
|
assert old_os in src, "pymumble OS string patch target not found"
|
||||||
|
src = src.replace(old_os, new_os)
|
||||||
|
|
||||||
|
p.write_text(src)
|
||||||
|
print("pymumble version patch applied (1.5.0, native OS string)")
|
||||||
|
|||||||
@@ -218,11 +218,27 @@ class MumbleBot:
|
|||||||
self._on_sound_received,
|
self._on_sound_received,
|
||||||
)
|
)
|
||||||
self._mumble.set_receive_sound(self._receive_sound)
|
self._mumble.set_receive_sound(self._receive_sound)
|
||||||
|
# Raise retry interval so 2+ bots on the same IP don't trip
|
||||||
|
# the server's autoban (default: 10 attempts / 120s).
|
||||||
|
import pymumble_py3.mumble as _pm
|
||||||
|
if getattr(_pm, "PYMUMBLE_CONNECTION_RETRY_INTERVAL", 0) < 15:
|
||||||
|
_pm.PYMUMBLE_CONNECTION_RETRY_INTERVAL = 15
|
||||||
self._mumble.start()
|
self._mumble.start()
|
||||||
self._mumble.is_ready()
|
self._mumble.is_ready()
|
||||||
|
|
||||||
def _on_connected(self) -> None:
|
def _on_connected(self) -> None:
|
||||||
"""Callback from pymumble thread: connection established."""
|
"""Callback from pymumble thread: connection established."""
|
||||||
|
# Enable TCP keepalive on the control socket to prevent NAT
|
||||||
|
# gateways from dropping the mapping during idle periods.
|
||||||
|
try:
|
||||||
|
import socket as _sock
|
||||||
|
raw = self._mumble.control_socket
|
||||||
|
raw.setsockopt(_sock.SOL_SOCKET, _sock.SO_KEEPALIVE, 1)
|
||||||
|
raw.setsockopt(_sock.IPPROTO_TCP, _sock.TCP_KEEPIDLE, 10)
|
||||||
|
raw.setsockopt(_sock.IPPROTO_TCP, _sock.TCP_KEEPINTVL, 5)
|
||||||
|
raw.setsockopt(_sock.IPPROTO_TCP, _sock.TCP_KEEPCNT, 3)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
self._connect_count += 1
|
self._connect_count += 1
|
||||||
kind = "reconnected" if self._connect_count > 1 else "connected"
|
kind = "reconnected" if self._connect_count > 1 else "connected"
|
||||||
session = getattr(self._mumble.users, "myself_session", "?")
|
session = getattr(self._mumble.users, "myself_session", "?")
|
||||||
|
|||||||
Reference in New Issue
Block a user