mirror of
https://wiilab.wiimart.org/wiimart/WiiMartBot
synced 2025-09-03 20:11:08 +02:00
smol updates
This commit is contained in:
parent
ffdd951be8
commit
dec8e2069c
786
bot.py
786
bot.py
@ -51,101 +51,6 @@ logger = logging.getLogger()
|
|||||||
for handler in logger.handlers:
|
for handler in logger.handlers:
|
||||||
handler.setFormatter(formatter)
|
handler.setFormatter(formatter)
|
||||||
|
|
||||||
TAILSCALE_IP1 = "100.118.134.32"
|
|
||||||
TAILSCALE_IP2 = "100.95.192.63"
|
|
||||||
LOCK_PORT = 30000
|
|
||||||
TIMEOUT = 5.0
|
|
||||||
CHECK_INTERVAL = 10
|
|
||||||
|
|
||||||
class LeaderElection:
|
|
||||||
def __init__(self):
|
|
||||||
self.is_leader = False
|
|
||||||
self.leader_socket = None
|
|
||||||
self.lock = threading.Lock()
|
|
||||||
self.keep_running = True
|
|
||||||
|
|
||||||
def start_leader_server(self):
|
|
||||||
"""Run the leader socket in background"""
|
|
||||||
while self.keep_running and self.is_leader:
|
|
||||||
try:
|
|
||||||
# This will block for TIMEOUT seconds max
|
|
||||||
conn, addr = self.leader_socket.accept()
|
|
||||||
conn.close() # Immediately close connection
|
|
||||||
except socket.timeout:
|
|
||||||
continue # Just keep waiting
|
|
||||||
except:
|
|
||||||
break # Exit on other errors
|
|
||||||
|
|
||||||
def attempt_leadership(self):
|
|
||||||
with self.lock:
|
|
||||||
if self.is_leader:
|
|
||||||
return True
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Check if leader exists
|
|
||||||
if self.check_leader_active():
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Try to become leader
|
|
||||||
self.leader_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.leader_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
self.leader_socket.bind(('0.0.0.0', LOCK_PORT))
|
|
||||||
self.leader_socket.listen(1)
|
|
||||||
self.leader_socket.settimeout(TIMEOUT)
|
|
||||||
self.is_leader = True
|
|
||||||
|
|
||||||
# Start socket server in background thread
|
|
||||||
threading.Thread(target=self.start_leader_server, daemon=True).start()
|
|
||||||
#print("Became leader - Starting bot")
|
|
||||||
logging.info("Became leader - Starting bot")
|
|
||||||
return True
|
|
||||||
|
|
||||||
except OSError as e:
|
|
||||||
#print(f"Leadership attempt failed: {e}")
|
|
||||||
logging.critical(f"Leadership attempt failed: {e}")
|
|
||||||
self.cleanup()
|
|
||||||
return False
|
|
||||||
|
|
||||||
def check_leader_active(self):
|
|
||||||
"""Check if leader is active"""
|
|
||||||
try:
|
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
||||||
s.settimeout(TIMEOUT)
|
|
||||||
s.connect((TAILSCALE_IP2, LOCK_PORT))
|
|
||||||
return True
|
|
||||||
except (ConnectionRefusedError, socket.timeout, OSError):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def cleanup(self):
|
|
||||||
if self.leader_socket:
|
|
||||||
self.leader_socket.close()
|
|
||||||
self.is_leader = False
|
|
||||||
|
|
||||||
def health_check(leader_election):
|
|
||||||
"""Periodically check leader status"""
|
|
||||||
while True:
|
|
||||||
time.sleep(CHECK_INTERVAL)
|
|
||||||
|
|
||||||
if leader_election.is_leader:
|
|
||||||
# Verify we're still leader
|
|
||||||
try:
|
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
||||||
s.settimeout(TIMEOUT)
|
|
||||||
s.connect((TAILSCALE_IP1, LOCK_PORT))
|
|
||||||
except:
|
|
||||||
# Lost leadership
|
|
||||||
#print("Lost leadership")
|
|
||||||
logging.error("Lost leadership")
|
|
||||||
leader_election.cleanup()
|
|
||||||
else:
|
|
||||||
# Check if leader is gone
|
|
||||||
if not leader_election.check_leader_active():
|
|
||||||
#print("Attempting to become leader...")
|
|
||||||
logging.warning("Attempting to become leader...")
|
|
||||||
if leader_election.attempt_leadership():
|
|
||||||
# Start the bot now that we're leader
|
|
||||||
start_bot()
|
|
||||||
|
|
||||||
class Bot(commands.Bot):
|
class Bot(commands.Bot):
|
||||||
def __init__(self, intents: discord.Intents, **kwargs):
|
def __init__(self, intents: discord.Intents, **kwargs):
|
||||||
super().__init__(command_prefix="/", intents=intents, case_insensitive=True)
|
super().__init__(command_prefix="/", intents=intents, case_insensitive=True)
|
||||||
@ -164,326 +69,336 @@ status = os.getenv("status")
|
|||||||
url_status = "Unknown"
|
url_status = "Unknown"
|
||||||
url = "https://oss-auth.thecheese.io/"
|
url = "https://oss-auth.thecheese.io/"
|
||||||
|
|
||||||
error_codes = """
|
error_codes = {
|
||||||
201005: Invalid public key type in certificate
|
"201005": "Invalid public key type in certificate",
|
||||||
201009: Read failure (short read)
|
"201009": "Read failure (short read)",
|
||||||
201010: Write failure (short write)
|
"201010": "Write failure (short write)",
|
||||||
201012: Invalid signature type (for signed blobs)
|
"201012": "Invalid signature type (for signed blobs)",
|
||||||
201016: Maximum amount of handles exceeded (3 handles, as there are only 3 contexts)
|
"201016": "Maximum amount of handles exceeded (3 handles, as there are only 3 contexts)",
|
||||||
201017: Invalid arguments
|
"201017": "Invalid arguments",
|
||||||
201020: Device ID mismatch. Returned by ES_ImportTicket if the ticket is personalised and the device ID from the ticket mismatches with the actual ID.
|
"201020": "Device ID mismatch. Returned by ES_ImportTicket if the ticket is personalised and the device ID from the ticket mismatches with the actual ID.",
|
||||||
201022: Imported content hash does not match with the hash from the TMD. Returned by ES_ImportContentEnd and ES_ImportBoot.
|
"201022": "Imported content hash does not match with the hash from the TMD. Returned by ES_ImportContentEnd and ES_ImportBoot.",
|
||||||
201024: Memory allocation failure
|
"201024": "Memory allocation failure",
|
||||||
201026: Incorrect access rights (according to the TMD)
|
"201026": "Incorrect access rights (according to the TMD)",
|
||||||
201027: Issuer not found in the certificate chain
|
"201027": "Issuer not found in the certificate chain",
|
||||||
201028: Ticket not found
|
"201028": "Ticket not found",
|
||||||
201029: Invalid ticket. This is returned if the common key field contains an invalid value (anything other than 0 or 1). This is also returned from ES_LaunchTitle if the title ID contained in the ticket does not match the TMD title ID.
|
"201029": "Invalid ticket. This is returned if the common key field contains an invalid value (anything other than 0 or 1). This is also returned from ES_LaunchTitle if the title ID contained in the ticket does not match the TMD title ID.",
|
||||||
201031: During LaunchTitle/ImportTitle: installed boot2 version is too old. During ImportBoot: downgrades are not allowed.
|
"201031": "During LaunchTitle/ImportTitle: installed boot2 version is too old. During ImportBoot: downgrades are not allowed.",
|
||||||
201032: Fatal error early in ES initialisation. Can also be returned in ES_CheckHasKoreanKey in all other cases (key is not the Korean Key or a zero key!)
|
"201032": "Fatal error early in ES initialisation. Can also be returned in ES_CheckHasKoreanKey in all other cases (key is not the Korean Key or a zero key!)",
|
||||||
201033: A ticket limit was exceeded (duration or launch count)
|
"201033": "A ticket limit was exceeded (duration or launch count)",
|
||||||
201034: Returned by ES_CheckHasKoreanKey if the key is sensed to be all zeroes
|
"201034": "Returned by ES_CheckHasKoreanKey if the key is sensed to be all zeroes",
|
||||||
201035: A title with a higher version is already installed
|
"201035": "A title with a higher version is already installed",
|
||||||
201036: Required sysversion(IOS) is not installed (only for the system menu [check])
|
"201036": "Required sysversion(IOS) is not installed (only for the system menu [check])",
|
||||||
201037: Installed number of contents doesn't match TMD (only for the system menu [check])
|
"201037": "Installed number of contents doesn't match TMD (only for the system menu [check])",
|
||||||
201039: Returned by DI as an ES error code when TMD not supplied for disc/nand game
|
"201039": "Returned by DI as an ES error code when TMD not supplied for disc/nand game",
|
||||||
202000: Permission denied (returned when accessing an object for which the caller has no permission)
|
"202000": "Permission denied (returned when accessing an object for which the caller has no permission)",
|
||||||
202001: IOSC_EEXIST
|
"202001": "IOSC_EEXIST",
|
||||||
202003: IOSC_EMAX
|
"202003": "IOSC_EMAX",
|
||||||
202004: IOSC_ENOENT
|
"202004": "IOSC_ENOENT",
|
||||||
202005: IOSC_INVALID_OBJTYPE
|
"202005": "IOSC_INVALID_OBJTYPE",
|
||||||
202006: IOSC_INVALID_RNG
|
"202006": "IOSC_INVALID_RNG",
|
||||||
202007: IOSC_INVALID_FLAG
|
"202007": "IOSC_INVALID_FLAG",
|
||||||
202008: IOSC_INVALID_FORMAT
|
"202008": "IOSC_INVALID_FORMAT",
|
||||||
202009: IOSC_INVALID_VERSION
|
"202009": "IOSC_INVALID_VERSION",
|
||||||
202010: IOSC_INVALID_SIGNER
|
"202010": "IOSC_INVALID_SIGNER",
|
||||||
202011: IOSC_FAIL_CHECKVALUE
|
"202011": "IOSC_FAIL_CHECKVALUE",
|
||||||
202012: Internal failure
|
"202012": "Internal failure",
|
||||||
202013: Memory allocation failure. Known to be returned when the keyring is full (contains 0x20 keys)
|
"202013": "Memory allocation failure. Known to be returned when the keyring is full (contains 0x20 keys)",
|
||||||
202014: Invalid size
|
"202014": "Invalid size",
|
||||||
202015: Invalid address
|
"202015": "Invalid address",
|
||||||
202016: Unaligned data
|
"202016": "Unaligned data",
|
||||||
204001: EC_ERROR_FAIL: Generic error
|
"204000": "EC_ERROR_OK: No error",
|
||||||
204002: EC_ERROR_NOT_SUPPORTED: Feature not implemented
|
"204001": "EC_ERROR_FAIL: Generic error",
|
||||||
204003: EC_ERROR_INSUFFICIENT_RESOURCE
|
"204002": "EC_ERROR_NOT_SUPPORTED: Feature not implemented",
|
||||||
204004: EC_ERROR_INVALID
|
"204003": "EC_ERROR_INSUFFICIENT_RESOURCE",
|
||||||
204005: EC_ERROR_NOMEM
|
"204004": "EC_ERROR_INVALID",
|
||||||
204006: EC_ERROR_NOT_FOUND
|
"204005": "EC_ERROR_NOMEM ",
|
||||||
204007: EC_ERROR_NOT_BUSY: no active async operation
|
"204006": "EC_ERROR_NOT_FOUND",
|
||||||
204008: EC_ERROR_BUSY
|
"204007": "EC_ERROR_NOT_BUSY: no active async operation",
|
||||||
204009: EC_ERROR_NOT_DONE
|
"204008": "EC_ERROR_BUSY",
|
||||||
204013: EC_ERROR_NET_NA: Internet access not available
|
"204009": "EC_ERROR_NOT_DONE",
|
||||||
204015: EC_ERROR_WS_REPORT: Server reports a problem
|
"204013": "EC_ERROR_NET_NA: Internet access not available",
|
||||||
204017: EC_ERROR_ECARD: Invalid eCard
|
"204015": "EC_ERROR_WS_REPORT: Server reports a problem",
|
||||||
204018: EC_ERROR_OVERFLOW: Output too big for buf provided
|
"204017": "EC_ERROR_ECARD: Invalid eCard",
|
||||||
204019: EC_ERROR_NET_CONTENT: Error getting content from server
|
"204018": "EC_ERROR_OVERFLOW: Output too big for buf provided",
|
||||||
204020: EC_ERROR_CONTENT_SIZE: Downloaded content size doesn't match tmd
|
"204019": "EC_ERROR_NET_CONTENT: Error getting content from server",
|
||||||
204034: EC_ERROR_WS_RESP: invalid web service response
|
"204020": "EC_ERROR_CONTENT_SIZE: Downloaded content size doesn't match tmd",
|
||||||
204035: EC_ERROR_TICKET: problem importing ticket
|
"204034": "EC_ERROR_WS_RESP: invalid web service response",
|
||||||
204036: EC_ERROR_TITLE: problem importing title
|
"204035": "EC_ERROR_TICKET: problem importing ticket",
|
||||||
204037: EC_ERROR_TITLE_CONTENT: problem importing title content
|
"204036": "EC_ERROR_TITLE: problem importing title",
|
||||||
204038: EC_ERROR_CANCELED: an extended operation was canceled
|
"204037": "EC_ERROR_TITLE_CONTENT: problem importing title content",
|
||||||
204039: EC_ERROR_ALREADY: one time only action was previously done
|
"204038": "EC_ERROR_CANCELED: an extended operation was canceled",
|
||||||
204041: EC_ERROR_INIT: library has not been initialized
|
"204039": "EC_ERROR_ALREADY: one time only action was previously done",
|
||||||
204042: EC_ERROR_REGISTER: device is not registered
|
"204041": "EC_ERROR_INIT: library has not been initialized",
|
||||||
204043: EC_ERROR_WS_RECV: recv error on web service response
|
"204042": "EC_ERROR_REGISTER: device is not registered",
|
||||||
204044: EC_ERROR_NOT_ACTIVE: expected operation is not active op
|
"204043": "EC_ERROR_WS_RECV: recv error on web service response",
|
||||||
204045: EC_ERROR_FILE_READ
|
"204044": "EC_ERROR_NOT_ACTIVE: expected operation is not active op",
|
||||||
204046: EC_ERROR_FILE_WRITE
|
"204045": "EC_ERROR_FILE_READ",
|
||||||
204050: EC_ERROR_NOT_OWNED: Title is not owned
|
"204046": "EC_ERROR_FILE_WRITE",
|
||||||
204052: EC_ERROR_HTTP_HDR_PARSE: Could not parse http header
|
"204050": "EC_ERROR_NOT_OWNED: Title is not owned",
|
||||||
204053: EC_ERROR_CONFIG: Invalid configuration (e.g. url is invalid)
|
"204052": "EC_ERROR_HTTP_HDR_PARSE: Could not parse http header",
|
||||||
204054: EC_ERROR_CANCEL_FAILED: Could not cancel asynchronous operaton
|
"204053": "EC_ERROR_CONFIG: Invalid configuration (e.g. url is invalid)",
|
||||||
204055: EC_ERROR_USER_INODES: Operation would exceed max user inodes
|
"204054": "EC_ERROR_CANCEL_FAILED: Could not cancel asynchronous operaton",
|
||||||
204056: EC_ERROR_USER_BLOCKS: Operation would exceed max user blocks
|
"204055": "EC_ERROR_USER_INODES: Operation would exceed max user inodes",
|
||||||
204057: EC_ERROR_SYS_INODES: Operation would exceed max sys inodes
|
"204056": "EC_ERROR_USER_BLOCKS: Operation would exceed max user blocks",
|
||||||
204058: EC_ERROR_SYS_BLOCKS: Operation would exceed max sys blocks
|
"204057": "EC_ERROR_SYS_INODES: Operation would exceed max sys inodes",
|
||||||
204065: EC_ERROR_NO_DEVICE_CODE: Operation requires device code
|
"204058": "EC_ERROR_SYS_BLOCKS: Operation would exceed max sys blocks",
|
||||||
204066: EC_ERROR_SYNC: Operation requres ticket sync
|
"204065": "EC_ERROR_NO_DEVICE_CODE: Operation requires device code",
|
||||||
204069: EC_ERROR_CONNECT: Operation requires EC_Connect()
|
"204066": "EC_ERROR_SYNC: Operation requres ticket sync",
|
||||||
204070: EC_ERROR_NO_TMD: Title TMD is not on device
|
"204069": "EC_ERROR_CONNECT: Operation requires EC_Connect()",
|
||||||
204071: EC_ERROR_FIRMWARE: Title requires updated firmware
|
"204070": "EC_ERROR_NO_TMD: Title TMD is not on device",
|
||||||
204074: EC_ERROR_INVALID_PCPW: Parental control password doesn't match
|
"204071": "EC_ERROR_FIRMWARE: Title requires updated firmware",
|
||||||
204075: EC_ERROR_PC_DISABLED: Parental control is not enabled
|
"204074": "EC_ERROR_INVALID_PCPW: Parental control password doesn't match",
|
||||||
204076: EC_ERROR_EULA: Customer has not agreed to EULA
|
"204075": "EC_ERROR_PC_DISABLED: Parental control is not enabled",
|
||||||
204077: EC_ERROR_AGE_RESTRICTED: Operation requires parental control password
|
"204076": "EC_ERROR_EULA: Customer has not agreed to EULA",
|
||||||
204078: EC_ERROR_POINTS_RESTRICTED: Operation requires parental control password
|
"204077": "EC_ERROR_AGE_RESTRICTED: Operation requires parental control password",
|
||||||
204079: EC_ERROR_ALREADY_OWN: Attempt purchase already owned item
|
"204078": "EC_ERROR_POINTS_RESTRICTED: Operation requires parental control password",
|
||||||
204080: EC_ERROR_SHOP_SETUP: Shop channel setup not done or cleared
|
"204079": "EC_ERROR_ALREADY_OWN: Attempt purchase already owned item",
|
||||||
204081: EC_ERROR_INSUFFICIENT_FUNDS: Not enough funds to purchase the item
|
"204080": "EC_ERROR_SHOP_SETUP: Shop channel setup not done or cleared",
|
||||||
204501: HTTP 201 Created
|
"204081": "EC_ERROR_INSUFFICIENT_FUNDS: Not enough funds to purchase the item",
|
||||||
204502: HTTP 202 Accepted
|
"204501": "HTTP 201 Created",
|
||||||
204503: HTTP 203 Non-Authoritative Information
|
"204502": "HTTP 202 Accepted",
|
||||||
204504: HTTP 204 No Content
|
"204503": "HTTP 203 Non-Authoritative Information",
|
||||||
204505: HTTP 205 Reset Content
|
"204504": "HTTP 204 No Content",
|
||||||
204506: HTTP 206 Partial Content
|
"204505": "HTTP 205 Reset Content",
|
||||||
204600: HTTP 300 Multiple Choices
|
"204506": "HTTP 206 Partial Content",
|
||||||
204601: HTTP 301 Moved Permanently
|
"204600": "HTTP 300 Multiple Choices",
|
||||||
204602: HTTP 302 Found
|
"204601": "HTTP 301 Moved Permanently",
|
||||||
204603: HTTP 303 See Other
|
"204602": "HTTP 302 Found",
|
||||||
204604: HTTP 304 Not Modified
|
"204603": "HTTP 303 See Other",
|
||||||
204607: HTTP 307 Temporary Redirect
|
"204604": "HTTP 304 Not Modified",
|
||||||
204608: HTTP 308 Permanent Redirect
|
"204607": "HTTP 307 Temporary Redirect",
|
||||||
204700: HTTP 400 Bad Request
|
"204608": "HTTP 308 Permanent Redirect",
|
||||||
204701: HTTP 401 Unauthorized
|
"204700": "HTTP 400 Bad Request",
|
||||||
204702: HTTP 402 Payment Required
|
"204701": "HTTP 401 Unauthorized",
|
||||||
204703: HTTP 403 Forbidden
|
"204702": "HTTP 402 Payment Required",
|
||||||
204704: HTTP 404 Not Found
|
"204703": "HTTP 403 Forbidden",
|
||||||
204705: HTTP 405 Method Not Allowed
|
"204704": "HTTP 404 - Not Found",
|
||||||
204706: HTTP 406 Not Acceptable
|
"204704": "HTTP 404 Not Found",
|
||||||
204707: HTTP 407 Proxy Authentication Required
|
"204705": "HTTP 405 Method Not Allowed",
|
||||||
204708: HTTP 408 Request Timeout
|
"204706": "HTTP 406 Not Acceptable",
|
||||||
204709: HTTP 409 Conflict
|
"204707": "HTTP 407 Proxy Authentication Required",
|
||||||
204710: HTTP 410 Gone
|
"204708": "HTTP 408 Request Timeout",
|
||||||
204711: HTTP 411 Length Required
|
"204709": "HTTP 409 Conflict",
|
||||||
204712: HTTP 412 Precondition Failed
|
"204710": "HTTP 410 Gone",
|
||||||
204713: HTTP 413 Request Too Large
|
"204711": "HTTP 411 Length Required",
|
||||||
204714: HTTP 414 Request-URI Too Long
|
"204712": "HTTP 412 Precondition Failed",
|
||||||
204715: HTTP 415 Unsupported Media Type
|
"204713": "HTTP 413 Request Too Large",
|
||||||
204716: HTTP 416 Range Not Satisfiable
|
"204714": "HTTP 414 Request-URI Too Long",
|
||||||
204717: HTTP 417 Expectation Failed
|
"204715": "HTTP 415 Unsupported Media Type",
|
||||||
204800: HTTP 500 Internal Server Error
|
"204716": "HTTP 416 Range Not Satisfiable",
|
||||||
204801: HTTP 501 Not Implemented
|
"204717": "HTTP 417 Expectation Failed",
|
||||||
204802: HTTP 502 Bad Gateway
|
"204800": "HTTP 500 - Internal Server Error",
|
||||||
204803: HTTP 503 Service Unavailable
|
"204800": "HTTP 500 Internal Server Error",
|
||||||
204804: HTTP 504 Gateway Timeout
|
"204801": "HTTP 501 Not Implemented",
|
||||||
204805: HTTP 505 HTTP Version Not Supported
|
"204802": "HTTP 502 Bad Gateway",
|
||||||
204811: HTTP 511 Network Authentication Required
|
"204803": "HTTP 503 Service Unavailable",
|
||||||
204901: NHTTP_ERROR_ALLOC
|
"204804": "HTTP 504 Gateway Timeout",
|
||||||
204902: NHTTP_ERROR_TOOMANYREQ
|
"204805": "HTTP 505 HTTP Version Not Supported",
|
||||||
204903: NHTTP_ERROR_SOCKET
|
"204811": "HTTP 511 Network Authentication Required",
|
||||||
204904: NHTTP_ERROR_DNS
|
"204901": "NHTTP_ERROR_ALLOC",
|
||||||
204905: NHTTP_ERROR_CONNECT
|
"204902": "NHTTP_ERROR_TOOMANYREQ",
|
||||||
204906: NHTTP_ERROR_BUFFULL
|
"204903": "NHTTP_ERROR_SOCKET",
|
||||||
204907: NHTTP_ERROR_HTTPPARSE
|
"204904": "NHTTP_ERROR_DNS",
|
||||||
204908: NHTTP_ERROR_CANCELED
|
"204905": "NHTTP_ERROR_CONNECT",
|
||||||
204909: NHTTP_ERROR_REVOLUTIONSDK
|
"204906": "NHTTP_ERROR_BUFFULL",
|
||||||
204910: NHTTP_ERROR_REVOLUTIONWIFI
|
"204907": "NHTTP_ERROR_HTTPPARSE",
|
||||||
204911: NHTTP_ERROR_UNKNOWN
|
"204908": "NHTTP_ERROR_CANCELED",
|
||||||
204912: NHTTP_ERROR_DNS_PROXY
|
"204909": "NHTTP_ERROR_REVOLUTIONSDK",
|
||||||
204913: NHTTP_ERROR_CONNECT_PROXY
|
"204910": "NHTTP_ERROR_REVOLUTIONWIFI",
|
||||||
204914: NHTTP_ERROR_SSL
|
"204911": "NHTTP_ERROR_UNKNOWN",
|
||||||
204961: SSL_EFAILED
|
"204912": "NHTTP_ERROR_DNS_PROXY",
|
||||||
204962: SSL_EWANT_READ
|
"204913": "NHTTP_ERROR_CONNECT_PROXY",
|
||||||
204963: SSL_EWANT_WRITE
|
"204914": "NHTTP_ERROR_SSL",
|
||||||
204964: SSL_ESYSCALL
|
"204927": "IAS Unknown issuer of device cert",
|
||||||
204965: SSL_EZERO_RETURN
|
"204961": "SSL_EFAILED",
|
||||||
204966: SSL_EWANT_CONNECT
|
"204962": "SSL_EWANT_READ",
|
||||||
204967: SSL_ESSLID
|
"204963": "SSL_EWANT_WRITE",
|
||||||
204968: SSL_EVERIFY_COMMON_NAME
|
"204964": "SSL_ESYSCALL",
|
||||||
204969: SSL_EVERIFY_ROOT_CA
|
"204965": "SSL_EZERO_RETURN",
|
||||||
204970: SSL_EVERIFY_CHAIN
|
"204966": "SSL_EWANT_CONNECT",
|
||||||
204971: SSL_EVERIFY_DATE
|
"204967": "SSL_ESSLID",
|
||||||
204972: SSL_EGET_SERVER_CERT
|
"204968": "SSL_EVERIFY_COMMON_NAME",
|
||||||
204992: EC_ERROR_NHTTP_CRX
|
"204969": "SSL_EVERIFY_ROOT_CA",
|
||||||
204993: EC_ERROR_NHTTP_AHF
|
"204970": "SSL_EVERIFY_CHAIN",
|
||||||
204994: EC_ERROR_NHTTP_SCCD
|
"204971": "SSL_EVERIFY_DATE",
|
||||||
204995: EC_ERROR_NHTTP_SRCD
|
"204972": "SSL_EGET_SERVER_CERT",
|
||||||
204996: EC_ERROR_NHTTP_SVO
|
"204992": "EC_ERROR_NHTTP_CRX",
|
||||||
204997: EC_ERROR_NHTTP_PDE
|
"204993": "EC_ERROR_NHTTP_AHF",
|
||||||
204998: EC_ERROR_NHTTP_PDR
|
"204994": "EC_ERROR_NHTTP_SCCD",
|
||||||
204999: EC_ERROR_NHTTP_SRA
|
"204995": "EC_ERROR_NHTTP_SRCD",
|
||||||
20955X: 2-7 Timeout occurred between client and server
|
"204996": "EC_ERROR_NHTTP_SVO",
|
||||||
204704: Equivalent to a HTTP 404 error
|
"204997": "EC_ERROR_NHTTP_PDE",
|
||||||
2056XX: ECS Error
|
"204998": "EC_ERROR_NHTTP_PDR",
|
||||||
205625: ECS Gift error
|
"204999": "EC_ERROR_NHTTP_SRA",
|
||||||
2059XX-2064XX: IAS Error
|
"205007": "Invalid NAND Dump (Dolphin only)",
|
||||||
205968: "Bad device code" (?)
|
"051330": "Internet connection error. The Wii needs a 2.4gHz signal with 802.11b/g/n enabled, and the security set to WPA2-PSK (AES). The channel must also either be set to auto or be less than 12.",
|
||||||
205627: Cannot buy DLC for a title you don't own
|
"205104": "Could not retrieve points balance",
|
||||||
2057XX-20570X: ETS Error
|
"205114": "Could not convert points balance to integer",
|
||||||
2058XX-205825: PAS Error
|
"205124": "Cannot find sender friend code",
|
||||||
2066XX: OSS Error
|
"205177": "User already exists in database",
|
||||||
209531: Page was not found
|
"205540": "This software doesn't work in the vWii",
|
||||||
209622: SSL CA unknown / not included in channel
|
"205617": "Wii Points card code invalid",
|
||||||
220003: The requested URL was filtered by Opera's filter
|
"205618": "Wii Points card is for another country",
|
||||||
204927: IAS Unknown issuer of device cert
|
"205621": "Unknown error (possibly ECS gift error?)",
|
||||||
204901-204973: Try another credit card or contact your credit card provider
|
"205623": "Trial period for that title expired, you can't download that again",
|
||||||
205540: This software doesn't work in the vWii
|
"205600": "Generic ECS (ECommerceSOAP) error.",
|
||||||
205617: Wii Points card code invalid
|
"205700": "Generic ETS (ETicket Services?) error.",
|
||||||
205618: Wii Points card is for another country
|
"205800": "Generic PAS (Points Account System?) error.",
|
||||||
205621: Unknown error (possibly ECS gift error?)
|
"205825": "Generic PAS (Points Account System?) error. (PAS_ERROR_CODE)",
|
||||||
205623: Trial period for that title expired, you can't download that again
|
"205900": "Generic IAS (IdentityAuthenticationSOAP) error.",
|
||||||
205626: Unable to send present (ECS gift error)
|
"206400": "Generic IAS (IdentityAuthenticationSOAP) error.",
|
||||||
205642: Unknown error
|
"206600": "Generic OSS error.",
|
||||||
205643: Unknown error
|
"205625": "ECS Gift error",
|
||||||
205644: Credit cards can't be used on this console.
|
"205626": "Unable to send present (ECS gift error)",
|
||||||
205645: Issue with your DSi shop account?
|
"205627": "Can't buy DLC for a title you don't own.",
|
||||||
205646: Unable to send present (ECS gift error)
|
"205642": "Unknown error",
|
||||||
205672: Wii Shop account mismatch
|
"205643": "Unknown error",
|
||||||
20580X: Wii Points Card error
|
"205644": "Credit cards can't be used on this console.",
|
||||||
205810: You don't have enough Wii Points / Error while redeeming your download ticket
|
"205645": "Issue with your DSi shop account?",
|
||||||
205811: Wii Points card expired
|
"205646": "Unable to send present (ECS Gift)",
|
||||||
205812-205814: The Wii Points card can not be used
|
"205672": "ECS Account mismatch",
|
||||||
205815: Wii Points Card was already used
|
"205800": "Wii Points Card error",
|
||||||
205816: Some error with the Wii Points Card
|
"205810": "You don't have enough Wii Points / Error while redeeming your download ticket",
|
||||||
205818: This card number can only be used for a specific title, it is not a Wii Points Card.
|
"205811": "Wii Points card expired",
|
||||||
205819: Wii Points Card code is invalid
|
"205815": "Wii Points Card was already used",
|
||||||
205830: Wii Points Card code is invalid
|
"205816": "Some error with the Wii Points Card",
|
||||||
205831: Wii Points Card is for another Country
|
"205818": "This card number can only be used for a specific title, it is not a Wii Points Card.",
|
||||||
205901: Wii number invalid!
|
"205819": "Wii Points Card code is invalid",
|
||||||
205903: Unknown error
|
"205826": "Server under heavy load",
|
||||||
205906: Problem with your online account
|
"205829": "Server under heavy load",
|
||||||
205921-205925: Wii NAND corrupted
|
"205830": "Wii Points Card code is invalid",
|
||||||
205928: Unknown error
|
"205831": "Wii Points Card is for another country",
|
||||||
205940-250941: Problems with your "Club-Nintendo"-account. It can't get connected with your shop account
|
"205901": "Wii number invalid!",
|
||||||
250943: Problems with your "Club-Nintendo"-account. It can't get connected with your shop account
|
"205903": "Unknown error",
|
||||||
209600-209601: Connection timeout
|
"205906": "Problem with your online account",
|
||||||
205942: Maintenance. Login not possible
|
"205928": "Unknown error",
|
||||||
205958: Unknown error
|
"205942": "Maintenance. Login not possible",
|
||||||
205968: IAS_BAD_DEVICE_CODE
|
"205958": "Unknown error",
|
||||||
206112: The free title promotion has ended (ICR_END)
|
"205968": "Bad device code",
|
||||||
206401: Invalid characters in nick or password
|
"205969": "Server under heavy load",
|
||||||
206499: Maintenance. Login not possible
|
"206112": "The free title promotion has ended (ICR_END)",
|
||||||
206601: OSS_ERROR_INVALID_PARAM. Triggered by B_24 in Wii Shop (Invalid parameter)
|
"206401": "Invalid characters in nick or password",
|
||||||
206602: Error while entering Wii Points Card code. Try again later.
|
"206499": "Maintenance. Login not possible",
|
||||||
206603: Unable to confirm credit card information
|
"206601": "Authentication error, missing required parameters",
|
||||||
206607: Error while retrieving the served content
|
"206602": "Error while entering Wii Points Card code. Try again later.",
|
||||||
206608: Error redeeming Wii Download Ticket
|
"206603": "Unable to confirm credit card information",
|
||||||
206610: Wii download ticket expired
|
"206607": "Error while retrieving the served content",
|
||||||
206611: Wii download ticket invalid
|
"206608": "Error redeeming Wii Download Ticket",
|
||||||
206612: This Wii download ticket can't be used in your country
|
"206610": "Wii download ticket expired",
|
||||||
206613: No software available for this download ticket. May be caused by parental controls.
|
"206611": "Wii download ticket invalid",
|
||||||
206650: Wrong PIN (parental controls)
|
"206612": "This Wii download ticket can't be used in your country",
|
||||||
206651: Mistake while entering the wii serial number
|
"206613": "No software available for this download ticket. May be caused by parental controls.",
|
||||||
206652: Wrong PIN three times (parental controls)
|
"206650": "Wrong PIN (parental controls)",
|
||||||
206653: Nickname or password wrong
|
"206651": "Mistake while entering the wii serial number",
|
||||||
206660: No progress was made in the last operation
|
"206652": "Wrong PIN three times (parental controls)",
|
||||||
206661: Credit card type invalid
|
"206653": "Nickname or password wrong",
|
||||||
206662: Credit card number invalid
|
"206660": "No progress was made in the last operation",
|
||||||
206663: An operation is in progress
|
"206661": "Credit card type invalid",
|
||||||
206664: No security code was provided
|
"206662": "Credit card number invalid",
|
||||||
206667: Wii download ticket invalid
|
"206663": "An operation is in progress",
|
||||||
206668: Happens when current points count + new points would exceed the wii points limit
|
"206664": "No security code was provided",
|
||||||
206669: Wii Points card invalid
|
"206667": "Wii download ticket invalid",
|
||||||
206670: Problem with your Wii Shop Account (invalid Wii number)
|
"206668": "Happens when current points count + new points would exceed the wii points limit",
|
||||||
206671: Problem with your Wii Shop Account (invalid shop app - bad title ID)
|
"206669": "Wii Points card invalid",
|
||||||
206672: Problem with your Wii Shop Account (invalid shop app - no title info)
|
"206670": "Invalid friend code",
|
||||||
206673: Problem with your Wii Shop Account (invalid registration status)
|
"206671": "Invalid/Wrong Wii Shop title ID",
|
||||||
206674: Problem with your Wii Shop Account (unexpected eclib error)
|
"206672": "No title info (Wii Shop)",
|
||||||
206699: Try again later
|
"206673": "Invalid registration status",
|
||||||
208000: You have entered the wrong state ("Bundesland")
|
"206674": "Unexpected eclib error",
|
||||||
208001: Unable to process for credit cards (some kind of blacklist?)
|
"206699": "Try again later",
|
||||||
208002: Billing address invalid
|
"208000": "You have entered the wrong state",
|
||||||
208003: Credit card number doesn't match card type
|
"208001": "Unable to process for credit cards (some kind of blacklist?)",
|
||||||
208004: three-digit security code invalid
|
"208002": "Billing address invalid",
|
||||||
208005: Mistake in credit card data.
|
"208003": "Credit card number doesn't match card type",
|
||||||
208006: Card number invalid
|
"208004": "three-digit security code invalid",
|
||||||
208007: Expiration date invalid
|
"208005": "Mistake in credit card data.",
|
||||||
208008: Postal code invalid
|
"208006": "Card number invalid",
|
||||||
208009: Technical difficulties.
|
"208007": "Expiration date invalid",
|
||||||
208010: Credit card could not get validated. Try again later.
|
"208008": "Postal code invalid",
|
||||||
208011: Credit card declined
|
"208009": "Technical difficulties.",
|
||||||
208012: Credit card declined - no funds available
|
"208010": "Credit card could not get validated. Try again later.",
|
||||||
208013: Credit card declined - inactive
|
"208011": "Credit card declined",
|
||||||
208014: Credit card expired
|
"208012": "Credit card declined - no funds available",
|
||||||
208015: Credit card code invalid
|
"208013": "Credit card declined - inactive",
|
||||||
208016: Credit card number invalid
|
"208014": "Credit card expired",
|
||||||
208017: Credit card limit reached
|
"208015": "Credit card code invalid",
|
||||||
208018: Credit card invalid
|
"208016": "Credit card number invalid",
|
||||||
208019: Postal / zip code invalid
|
"208017": "Credit card limit reached",
|
||||||
208021: Refund is in progress
|
"208018": "Credit card invalid",
|
||||||
208022: Refund was already processed
|
"208019": "Postal / zip code invalid",
|
||||||
208023: Refund error
|
"208021": "Refund is in progress",
|
||||||
208025: Empty security code
|
"208022": "Refund was already processed",
|
||||||
209XXX: Server connection timeout
|
"208023": "Refund error",
|
||||||
209531: Web page not found (WS_ERROR_WWW_HTTP_ERR_NOT_FOUND)
|
"208025": "Empty security code",
|
||||||
209552: Timeout between client and server
|
"209531": "HTTP 404 Not Found",
|
||||||
209557: Timeout Occurred between client and server
|
"209552": "Timeout occurred between client and server",
|
||||||
209593: Access denied by Opera Wii Shop domain filter config
|
"209553": "Timeout occurred between client and server",
|
||||||
209620: Some JS files couldn't be loaded (CheckRegistered.jsp line ~100)
|
"209554": "Timeout occurred between client and server",
|
||||||
209622: SSL CA unknown / not included in channel
|
"209555": "Timeout occurred between client and server",
|
||||||
209631: Invalid SD Card
|
"209556": "Timeout occurred between client and server",
|
||||||
209632: The SD Card is inserted(?)
|
"209557": "Timeout occurred between client and server",
|
||||||
209633: The SD Card is not inserted
|
"209593": "Access denied by Opera's Wii Shop domain filter",
|
||||||
209634: Unknown SD Card cluster (not 32k)
|
"209600": "Connection Timeout, the shop took too long to load",
|
||||||
209635: Incorrect SD Card alignment
|
"209601": "Connection Timeout, the shop took too long to load",
|
||||||
209636: Incorrect SD Card Device
|
"209620": "Some JS files couldn't be loaded (shopErrCheck)",
|
||||||
209637: The title's ticket is not present on the SD
|
"209622": "SSL CA unknown / not included in channel",
|
||||||
209638: SDCARD_ERROR_ACCESS
|
"209622": "SSL CA unknown / not included in channel",
|
||||||
209639: SDCARD_ERROR_CANCELLED (cancelBackupToSDCard successful?)
|
"209631": "Invalid SD Card",
|
||||||
209640: SDCARD_ERROR_CONTENT_INVALID (Banner is not found)
|
"209632": "The SD Card is inserted(?)",
|
||||||
209641: SDCARD_ERROR_MAXFD (?)
|
"209633": "The SD Card is not inserted",
|
||||||
209642: The SD Card is "out of memory"
|
"209634": "Unknown SD Card cluster (not 32k)",
|
||||||
209643: The SD Card is corrupted (NAND_CORRUPT ERROR (Serious error))
|
"209635": "Incorrect SD Card alignment",
|
||||||
209644: SDCARD_ERROR_ECC_CRIT (?)
|
"209636": "Incorrect SD Card Device",
|
||||||
209645: SD Authentication error(?)
|
"209637": "The title's ticket is not present on the SD",
|
||||||
209646: Fatal error with the SD Card
|
"209638": "SDCARD_ERROR_ACCESS",
|
||||||
209647: Unknown SD Card
|
"209639": "SDCARD_ERROR_CANCELLED (cancelBackupToSDCard successful?)",
|
||||||
209648: The SD Card is not inserted
|
"209640": "SDCARD_ERROR_CONTENT_INVALID (Banner is not found)",
|
||||||
209649: The SD Card is not supported
|
"209641": "SDCARD_ERROR_MAXFD (?)",
|
||||||
209650: SD Card File system is broken
|
"209642": "The SD Card is out of memory",
|
||||||
209651: SD is write protected
|
"209643": "The SD Card is corrupted (NAND_CORRUPT ERROR (Serious error))",
|
||||||
209652: No space left in the SD
|
"209644": "SDCARD_ERROR_ECC_CRIT (?)",
|
||||||
209653: Other SD error
|
"209645": "SD Authentication error(?)",
|
||||||
209654: Unknown SD Error
|
"209646": "Fatal error with the SD Card",
|
||||||
209655: SDCARD_ERROR_WANT_OF_CAPACITY (SD full)
|
"209647": "Unknown SD Card",
|
||||||
209656: SDCARD_ERROR_EXIST_CHECK_SOFT (title already present on SD)
|
"209648": "The SD Card is not inserted",
|
||||||
209657: SDCARD_ERROR_EXCEPTION_STATE (Illegal statement and cancelBackupToSDCard error)
|
"209649": "The SD Card is not supported",
|
||||||
209658-209660: Unused
|
"209650": "SD Card File system is broken",
|
||||||
209661: EXIST_CHECK_SOFT_NAND
|
"209651": "SD is write protected",
|
||||||
209662: errChannel
|
"209652": "No space left in the SD",
|
||||||
209663: errInodes
|
"209653": "Other SD error",
|
||||||
209664: SD Backup timeout in B-10
|
"209654": "Unknown SD Error",
|
||||||
209665: JournalFlag error in B-10
|
"209655": "SDCARD_ERROR_WANT_OF_CAPACITY (SD full)",
|
||||||
209666: Available space error in B-09 on checking remain size
|
"209656": "SDCARD_ERROR_EXIST_CHECK_SOFT (title already present on SD)",
|
||||||
209667: Available space is not sufficient (NAND)
|
"209657": "SDCARD_ERROR_EXCEPTION_STATE (Illegal statement and cancelBackupToSDCard error)",
|
||||||
209800 - 209801: Connection timeout (also caused by missing shop.connecting)
|
"209661": "EXIST_CHECK_SOFT_NAND",
|
||||||
220000: Connection failed
|
"209662": "errChannel",
|
||||||
220001: Unknown protocol
|
"209663": "errInodes",
|
||||||
220002: Out of memory
|
"209664": "SD Backup timeout in B-10",
|
||||||
220101: Allocation error
|
"209665": "JournalFlag error in B-10",
|
||||||
220102: Unsupported file
|
"209666": "Available space error in B-09 on checking remain size",
|
||||||
220103: Empty file
|
"209667": "Available space is not sufficient (NAND)",
|
||||||
220104: Invalid file
|
"209800": "No DNS Entry for oss-auth.shop.wii.com",
|
||||||
220105: Javascript error
|
"209XXX": "Server connection timeout",
|
||||||
220106: Plugin error
|
"220000": "Connection failed",
|
||||||
220201: Not found
|
"220001": "Unknown protocol",
|
||||||
220202: Connection refused
|
"220002": "Out of memory",
|
||||||
220301-220302: HTTP error code 100 - 101
|
"220003": "The requested URL was filtered by Opera's filter",
|
||||||
220303-220309: HTTP error code 200 - 206
|
"220101": "Allocation error",
|
||||||
220310-220315: HTTP error code 300 - 305
|
"220102": "Unsupported file",
|
||||||
220316-220331: HTTP error code 400 - 415
|
"220103": "Empty file",
|
||||||
220332-220337: HTTP error code 500 - 505
|
"220104": "Invalid file",
|
||||||
"""
|
"220105": "Javascript error",
|
||||||
|
"220106": "Plugin error",
|
||||||
|
"220201": "Not found",
|
||||||
|
"220202": "Connection refused",
|
||||||
|
"220003": "Filtered URL",
|
||||||
|
"220000": "Connection Failed",
|
||||||
|
"220002": "Out of memory",
|
||||||
|
"220001": "Unknown protocol",
|
||||||
|
"250943": "Problems with your Club Nintendo -account. It can't get connected with your shop account"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def parse_error_codes(error_codes):
|
def parse_error_codes(error_codes):
|
||||||
exact_codes = {}
|
exact_codes = {}
|
||||||
@ -549,6 +464,10 @@ def matches_wildcard(code, wildcard_code):
|
|||||||
return re.fullmatch(pattern, str(code)) is not None
|
return re.fullmatch(pattern, str(code)) is not None
|
||||||
|
|
||||||
def get_error_message(code):
|
def get_error_message(code):
|
||||||
|
if str(code) in error_codes:
|
||||||
|
return f"{code}: {error_codes[str(code)]}"
|
||||||
|
else:
|
||||||
|
return f"{code}: Error code not found."
|
||||||
# Connect to the SQLite database
|
# Connect to the SQLite database
|
||||||
conn = sqlite3.connect('error_codes.db')
|
conn = sqlite3.connect('error_codes.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@ -568,17 +487,17 @@ def get_error_message(code):
|
|||||||
|
|
||||||
return f"{code}: Error code not found."
|
return f"{code}: Error code not found."
|
||||||
|
|
||||||
def check_url():
|
def check_url(uri):
|
||||||
global url_status # Declare the global variable to modify it
|
global url_status # Declare the global variable to modify it
|
||||||
try:
|
try:
|
||||||
response = requests.get(url, verify=False, timeout=10) # Disable SSL verification and set a timeout
|
response = requests.get(uri, verify=False, timeout=10) # Disable SSL verification and set a timeout
|
||||||
url_status = ":green_square: Up" # If we get a response, set status to "Up"
|
url_status = ":green_square: Up" # If we get a response, set status to "Up"
|
||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
url_status = ":red_square: Down" # If there's an exception, set status to "Down"
|
url_status = ":red_square: Down" # If there's an exception, set status to "Down"
|
||||||
|
|
||||||
@bot.hybrid_command(name="status",description="Gets the status of WiiMart")
|
@bot.hybrid_command(name="status",description="Gets the status of WiiMart")
|
||||||
async def statusy(ctx):
|
async def statusy(ctx):
|
||||||
check_url()
|
check_url(url)
|
||||||
if status == "Not Set":
|
if status == "Not Set":
|
||||||
await ctx.send(f"WiiMart Status: {url_status}\nAdmin Status: :person_shrugging: Currently Unset")
|
await ctx.send(f"WiiMart Status: {url_status}\nAdmin Status: :person_shrugging: Currently Unset")
|
||||||
else:
|
else:
|
||||||
@ -657,7 +576,7 @@ async def getfc(ctx, member: discord.Member):
|
|||||||
|
|
||||||
@bot.hybrid_command(name="forceaddfc", description="Force adds the users Wii Friend code to the list of friend codes so that others can add them")
|
@bot.hybrid_command(name="forceaddfc", description="Force adds the users Wii Friend code to the list of friend codes so that others can add them")
|
||||||
@commands.has_any_role("Owner", "Admin", "Moderators")
|
@commands.has_any_role("Owner", "Admin", "Moderators")
|
||||||
async def addfc(ctx, user: discord.Member, fc: int):
|
async def addfcadm(ctx, user: discord.Member, fc: int):
|
||||||
await ctx.defer(ephemeral=True)
|
await ctx.defer(ephemeral=True)
|
||||||
if len(str(fc)) != 16:
|
if len(str(fc)) != 16:
|
||||||
userid = user.id
|
userid = user.id
|
||||||
@ -715,25 +634,12 @@ def start_bot():
|
|||||||
bot.run(token) # Or however you start your bot
|
bot.run(token) # Or however you start your bot
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
#try:
|
||||||
os.remove("error_codes.db")
|
# os.remove("error_codes.db")
|
||||||
except Exception as e:
|
#except Exception as e:
|
||||||
#print("i cant let you do that dave...")
|
# #print("i cant let you do that dave...")
|
||||||
logging.warning("i cant let you do that dave...")
|
# logging.warning("i cant let you do that dave...")
|
||||||
create_database()
|
#create_database()
|
||||||
|
logging.info("Creation of database disabled")
|
||||||
leader_election = LeaderElection()
|
start_bot()
|
||||||
|
|
||||||
# Initial leadership attempt
|
|
||||||
if leader_election.attempt_leadership():
|
|
||||||
start_bot()
|
|
||||||
else:
|
|
||||||
#print("Running in follower mode - waiting for leadership")
|
|
||||||
logging.info("Running in follower mode - waiting for leadership")
|
|
||||||
# Start health check in background
|
|
||||||
threading.Thread(target=health_check, args=(leader_election,), daemon=True).start()
|
|
||||||
|
|
||||||
# Keep the main thread alive
|
|
||||||
while True:
|
|
||||||
time.sleep(3600)
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user