WiiMartBot/bot.py
2025-11-02 23:56:31 +00:00

736 lines
35 KiB
Python

import socket
import threading
import time
import discord
import re
import requests
import logging
import os
import sqlite3
import mysql.connector
import sys
from discord.ext import commands
from mysql.connector import Error
from dotenv import load_dotenv
from colorama import Fore, init, Style
init()
class ColoredFormatter(logging.Formatter):
"""Adds colors to log levels"""
COLORS = {
'DEBUG': Fore.CYAN,
'INFO': Fore.BLUE,
'WARNING': Fore.YELLOW,
'ERROR': Fore.RED,
'CRITICAL': Fore.RED + Style.BRIGHT
}
def format(self, record):
level_color = self.COLORS.get(record.levelname, Fore.WHITE)
# Apply color to levelname only
record.levelname = f"{level_color}{record.levelname}{Style.RESET_ALL}"
return super().format(record)
# Your original config with colors added
logging.basicConfig(
level=logging.DEBUG,
format='%(levelname)s at %(asctime)s : %(message)s',
datefmt='%H:%M:%S',
handlers=[logging.StreamHandler(sys.stderr)]
)
# Apply the colored formatter
formatter = ColoredFormatter(
fmt='%(levelname)s at %(asctime)s : %(message)s',
datefmt='%H:%M:%S'
)
# Update the handler
logger = logging.getLogger()
for handler in logger.handlers:
handler.setFormatter(formatter)
class Bot(commands.Bot):
def __init__(self, intents: discord.Intents, **kwargs):
super().__init__(command_prefix="/", intents=intents, case_insensitive=True)
async def on_ready(self):
#print(f'{self.user} has connected to Discord!')
logging.info(f'{self.user} has connected to Discord!')
await self.tree.sync()
load_dotenv()
intents = discord.Intents.all()
bot = Bot(intents=intents)
client = discord.Client(intents=intents)
token = os.getenv("token")
status = os.getenv("status")
url_status = "Unknown"
url = "https://oss-auth.thecheese.io/"
error_codes = {
"201012": "Invalid signature type (for signed blobs)",
"201016": "Maximum amount of handles exceeded (3 handles, as there are only 3 contexts)",
"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.",
"201022": "Imported content hash does not match with the hash from the TMD. Returned by ES_ImportContentEnd and ES_ImportBoot.",
"201024": "Memory allocation failure",
"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.",
"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!)",
"201033": "A ticket limit was exceeded (duration or launch count)",
"201034": "Returned by ES_CheckHasKoreanKey if the key is sensed to be all zeroes",
"201035": "A title with a higher version is already installed",
"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])",
"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)",
"201009": "Read failure (short read)",
"201010": "Write failure (short write)",
"209631": "Invalid SD Card",
"209632": "The SD Card is inserted(?)",
"209633": "The SD Card is not inserted",
"209634": "Unknown SD Card cluster (not 32k)",
"209635": "Incorrect SD Card alignment",
"209636": "Incorrect SD Card Device",
"209637": "The title's ticket is not present on the SD",
"209638": "SDCARD_ERROR_ACCESS",
"209639": "SDCARD_ERROR_CANCELLED (cancelBackupToSDCard successful?)",
"209640": "SDCARD_ERROR_CONTENT_INVALID (Banner is not found)",
"209641": "SDCARD_ERROR_MAXFD (?)",
"209642": "The SD Card is out of memory",
"209643": "The SD Card is corrupted (NAND_CORRUPT ERROR (Serious error))",
"209644": "SDCARD_ERROR_ECC_CRIT: Critical error(?)",
"209645": "SD Authentication error(?)",
"209646": "Fatal error with the SD Card",
"209647": "Unknown SD Card",
"209648": "The SD Card is not inserted",
"209649": "The SD Card is not supported",
"209650": "SD Card File system is broken",
"209651": "SD is write protected",
"209652": "No space left in the SD",
"209653": "Other SD error",
"209654": "Unknown SD Error",
"209655": "SDCARD_ERROR_WANT_OF_CAPACITY (SD full)",
"209656": "SDCARD_ERROR_EXIST_CHECK_SOFT (title already present on SD)",
"209657": "SDCARD_ERROR_EXCEPTION_STATE (Illegal statement and cancelBackupToSDCard error)",
"209661": "EXIST_CHECK_SOFT_NAND",
"209662": "errChannel",
"209663": "errInodes",
"209664": "SD Backup timeout in B-10",
"209665": "JournalFlag error in B-10",
"209666": "Available space error in B-09 on checking remain size",
"209667": "Available space is not sufficient (NAND)",
"206674": "Unexpected ECLib error",
"201005": "Invalid public key type in certificate",
"201026": "Incorrect access rights (according to the TMD)",
"201027": "Issuer not found in the certificate chain",
"209622": "SSL CA unknown / not included in channel",
"209593": "Access denied by Opera's domain filter",
"209800": "No DNS Entry for oss-auth.shop.wii.com",
"206671": "Invalid/Wrong Wii Shop title ID",
"206672": "No title info (Wii Shop)",
"220000": "Connection failed",
"220001": "Unknown protocol",
"220002": "Out of memory",
"220003": "The requested URL was filtered by Opera's filter",
"220101": "Allocation error",
"220102": "Unsupported file",
"220103": "Empty file",
"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",
"202012": "Internal failure",
"202013": "Memory allocation failure. Known to be returned when the keyring is full (contains 0x20 keys)",
"202014": "Invalid size",
"202015": "Invalid address",
"202016": "Unaligned data",
"202001": "IOSC_EEXIST",
"202003": "IOSC_EMAX",
"202004": "IOSC_ENOENT",
"202005": "IOSC_INVALID_OBJTYPE",
"202006": "IOSC_INVALID_RNG",
"202007": "IOSC_INVALID_FLAG",
"202008": "IOSC_INVALID_FORMAT",
"202009": "IOSC_INVALID_VERSION",
"202010": "IOSC_INVALID_SIGNER",
"202011": "IOSC_FAIL_CHECKVALUE",
"204000": "EC_ERROR_OK: No error",
"204001": "EC_ERROR_FAIL: Generic error",
"204002": "EC_ERROR_NOT_SUPPORTED: Feature not implemented",
"204003": "EC_ERROR_INSUFFICIENT_RESOURCE",
"204004": "EC_ERROR_INVALID",
"204005": "EC_ERROR_NOMEM",
"204006": "EC_ERROR_NOT_FOUND",
"204007": "EC_ERROR_NOT_BUSY: no active async operation",
"204008": "EC_ERROR_BUSY",
"204009": "EC_ERROR_NOT_DONE",
"204013": "EC_ERROR_NET_NA: Internet access not available",
"204015": "EC_ERROR_WS_REPORT: Server reports a problem",
"204017": "EC_ERROR_ECARD: Invalid eCard",
"204018": "EC_ERROR_OVERFLOW: Output too big for buf provided",
"204019": "EC_ERROR_NET_CONTENT: Error getting content from server",
"204020": "EC_ERROR_CONTENT_SIZE: Downloaded content size doesn't match tmd",
"204034": "EC_ERROR_WS_RESP: invalid web service response",
"204035": "EC_ERROR_TICKET: problem importing ticket",
"204036": "EC_ERROR_TITLE: problem importing title",
"204037": "EC_ERROR_TITLE_CONTENT: problem importing title content",
"204038": "EC_ERROR_CANCELED: an extended operation was canceled",
"204039": "EC_ERROR_ALREADY: one time only action was previously done",
"204041": "EC_ERROR_INIT: library has not been initialized",
"204042": "EC_ERROR_REGISTER: device is not registered",
"204043": "EC_ERROR_WS_RECV: recv error on web service response",
"204044": "EC_ERROR_NOT_ACTIVE: expected operation is not active op",
"204045": "EC_ERROR_FILE_READ",
"204046": "EC_ERROR_FILE_WRITE",
"204050": "EC_ERROR_NOT_OWNED: Title is not owned",
"204052": "EC_ERROR_HTTP_HDR_PARSE: Could not parse http header",
"204053": "EC_ERROR_CONFIG: Invalid configuration (e.g. url is invalid)",
"204054": "EC_ERROR_CANCEL_FAILED: Could not cancel asynchronous operaton",
"204055": "EC_ERROR_USER_INODES: Operation would exceed max user inodes",
"204056": "EC_ERROR_USER_BLOCKS: Operation would exceed max user blocks",
"204057": "EC_ERROR_SYS_INODES: Operation would exceed max sys inodes",
"204058": "EC_ERROR_SYS_BLOCKS: Operation would exceed max sys blocks",
"204065": "EC_ERROR_NO_DEVICE_CODE: Operation requires device code",
"204066": "EC_ERROR_SYNC: Operation requres ticket sync",
"204069": "EC_ERROR_CONNECT: Operation requires EC_Connect()",
"204070": "EC_ERROR_NO_TMD: Title TMD is not on device",
"204071": "EC_ERROR_FIRMWARE: Title requires updated firmware",
"204074": "EC_ERROR_INVALID_PCPW: Parental control password doesn't match",
"204075": "EC_ERROR_PC_DISABLED: Parental control is not enabled",
"204076": "EC_ERROR_EULA: Customer has not agreed to EULA",
"204077": "EC_ERROR_AGE_RESTRICTED: Operation requires parental control password",
"204078": "EC_ERROR_POINTS_RESTRICTED: Operation requires parental control password",
"204079": "EC_ERROR_ALREADY_OWN: Attempt purchase already owned item",
"204080": "EC_ERROR_SHOP_SETUP: Shop channel setup not done or cleared",
"204081": "EC_ERROR_INSUFFICIENT_FUNDS: Not enough funds to purchase the item",
"204992": "EC_ERROR_NHTTP_CRX",
"204993": "EC_ERROR_NHTTP_AHF",
"204994": "EC_ERROR_NHTTP_SCCD",
"204995": "EC_ERROR_NHTTP_SRCD",
"204996": "EC_ERROR_NHTTP_SVO",
"204997": "EC_ERROR_NHTTP_PDE",
"204998": "EC_ERROR_NHTTP_PDR",
"204999": "EC_ERROR_NHTTP_SRA",
"204501": "HTTP 201 Created",
"204502": "HTTP 202 Accepted",
"204503": "HTTP 203 Non-Authoritative Information",
"204504": "HTTP 204 No Content",
"204505": "HTTP 205 Reset Content",
"204506": "HTTP 206 Partial Content",
"204600": "HTTP 300 Multiple Choices",
"204601": "HTTP 301 Moved Permanently",
"204602": "HTTP 302 Found",
"204603": "HTTP 303 See Other",
"204604": "HTTP 304 Not Modified",
"204605": "HTTP 305 Use Proxy",
"204606": "HTTP 306 Switch Proxy (unused)",
"204607": "HTTP 307 Temporary Redirect",
"204608": "HTTP 308 Permanent Redirect",
"204700": "HTTP 400 Bad Request",
"204701": "HTTP 401 Unauthorized",
"204702": "HTTP 402 Payment Required",
"204703": "HTTP 403 Forbidden",
"204704": "HTTP 404 Not Found",
"209531": "HTTP 404 Not Found",
"204705": "HTTP 405 Method Not Allowed",
"204706": "HTTP 406 Not Acceptable",
"204707": "HTTP 407 Proxy Authentication Required",
"204708": "HTTP 408 Request Timeout",
"204709": "HTTP 409 Conflict",
"204710": "HTTP 410 Gone",
"204711": "HTTP 411 Length Required",
"204712": "HTTP 412 Precondition Failed",
"204713": "HTTP 413 Request Too Large",
"204714": "HTTP 414 Request-URI Too Long",
"204715": "HTTP 415 Unsupported Media Type",
"204716": "HTTP 416 Range Not Satisfiable",
"204717": "HTTP 417 Expectation Failed",
"209527": "HTTP 418 <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/418\">I'm a Teapot</a>",
"209721": "HTTP 421 Misdirected Request",
"372422": "HTTP 422 Unprocessable Content",
"372423": "HTTP 423 Locked",
"372424": "HTTP 424 Failed Dependency",
"372425": "HTTP 425 Too Early",
"372426": "HTTP 426 Upgrade Required",
"372428": "HTTP 428 Precondition Required",
"372429": "HTTP 429 Too Many Requests",
"372431": "HTTP 431 Request Header Fields Too Large",
"372451": "HTTP 451 Unavailable For Legal Reasons",
"204800": "HTTP 500 Internal Server Error",
"204801": "HTTP 501 Not Implemented",
"204802": "HTTP 502 Bad Gateway",
"204803": "HTTP 503 Service Unavailable",
"204804": "HTTP 504 Gateway Timeout",
"204805": "HTTP 505 HTTP Version Not Supported",
"204811": "HTTP 511 Network Authentication Required",
"204900": "NHTTP_ERROR_NONE: No NHTTP error.",
"204901": "NHTTP_ERROR_ALLOC: Allocation has failed.",
"204902": "NHTTP_ERROR_TOOMANYREQ: Too many requests (This error never occurs).",
"204903": "NHTTP_ERROR_SOCKET: Socket error.",
"204904": "NHTTP_ERROR_DNS: DNS resolution failed.",
"204905": "NHTTP_ERROR_CONNECT: Connection failure (Returned if the DNS has been resolved, but communication is interrupted before the connection can be made to the requested server's URL).",
"204906": "NHTTP_ERROR_BUFFULL: The receive buffer is full.",
"204907": "NHTTP_ERROR_HTTPPARSE: HTTP header parsing failed.",
"204908": "NHTTP_ERROR_CANCELED: The request was cancelled.",
"204909": "NHTTP_ERROR_SDK: NHTTP_Thread generation failed.<br><small>This error is also known as <code>NHTTP_ERROR_REVOLUTIONSDK</code> and <code>NHTTP_ERROR_TWLSDK</code></small>",
"204910": "NHTTP_ERROR_WIFI: Returned when there is a problem with sending, receiving, or socket termination. Also returned when communication is blocked during sending, receiving, or termination.<br/><small>This error is also known as <code>NHTTP_ERROR_REVOLUTIONWIFI</code> and <code>NHTTP_ERROR_TWLWIFI</code></small>",
"204911": "NHTTP_ERROR_UNKNOWN: An abnormal/unknown value has been set to a method by NHTTP_CreateConnection.",
"204912": "NHTTP_ERROR_DNS_PROXY: DNS resolution failed for the proxy server.",
"204913": "NHTTP_ERROR_CONNECT_PROXY: Connection with the proxy server failed.",
"204914": "NHTTP_ERROR_SSL: SSL communications failed.",
"204915": "NHTTP_ERROR_BUSY: Indicates that a request is currently running.",
"204916": "NHTTP_ERROR_ROOTCA: Root Certificate Authority (CA) configuration failed.",
"204917": "NHTTP_ERROR_CLIENTCA: Client certificate configuration failed.",
"205900": "Generic IAS (IdentityAuthenticationSOAP) error.",
"206400": "Generic IAS (IdentityAuthenticationSOAP) error.",
"204927": "IAS Unknown issuer of device cert",
"205600": "Generic ECS (ECommerceSOAP) error.",
"205646": "Unable to send present (ECS Gift)",
"205672": "ECS Account mismatch",
"205625": "ECS Gift error",
"205626": "Unable to send present (ECS gift error)",
"205621": "Unknown error (possibly ECS gift error?)",
"205627": "Can't buy DLC for a title you don't own.",
"205800": "Generic PAS (PaymentAuthorizationSOAP) error.",
"205825": "Generic PAS (PaymentAuthorizationSOAP) error. (PAS_ERROR_CODE)",
"205700": "Generic ETS (ETicketSOAP) error.",
"206600": "Generic OSS error.",
"206652": "Wrong PIN three times (parental controls)",
"206650": "Wrong PIN (parental controls)",
"209620": "Some JavaScript files couldn't be loaded (caused by shopErrCheck)",
"209552": "Timeout occurred between client and server",
"209553": "Timeout occurred between client and server",
"209554": "Timeout occurred between client and server",
"209555": "Timeout occurred between client and server",
"209556": "Timeout occurred between client and server",
"209557": "Timeout occurred between client and server",
"209600": "Connection Timeout, the shop took too long to load",
"209601": "Connection Timeout, the shop took too long to load",
"205826": "Server under heavy load",
"205829": "Server under heavy load",
"205969": "Server under heavy load",
"206601": "Authentication error, missing required parameters",
"206651": "Mistake while entering the console's serial number",
"206663": "An operation is in progress",
"250943": "Problems with your Club Nintendo account. It can't get connected with your shop account", // is this correct actually?
"206653": "Nickname or password wrong",
"206660": "No progress was made in the last operation",
"241000": "Not enough RAM",
"241001": "Not enough RAM (to load Flash element)",
"240021": "This function is not available in this Opera version.",
"240008": "HTTP Auth in URL (GET parameters, URL)",
"240003": "Invalid URL",
"240004": "Address unreachable from this client.",
"240007": "Access denied.",
"240016": "Unsupported protocol.",
"240017": "Internal communication error.",
"240019": "Unknown or unsupported address type.",
"240020": "Unsupported file format",
"244002": "SSL handshake failed.",
"244003": "Invalid Root CA",
"204961": "SSL_EFAILED",
"204962": "SSL_EWANT_READ",
"204963": "SSL_EWANT_WRITE",
"204964": "SSL_ESYSCALL",
"204965": "SSL_EZERO_RETURN",
"204966": "SSL_EWANT_CONNECT",
"204967": "SSL_ESSLID",
"204968": "SSL_EVERIFY_COMMON_NAME",
"204969": "SSL_EVERIFY_ROOT_CA",
"204970": "SSL_EVERIFY_CHAIN",
"204971": "SSL_EVERIFY_DATE",
"204972": "SSL_EGET_SERVER_CERT",
"205007": "Invalid NAND Dump (Dolphin only)",
"205540": "This software doesn't work in the vWii",
"206670": "Invalid friend code",
"205968": "Invalid friend code",
"205901": "Wii number invalid!",
"205104": "Could not retrieve points balance",
"205114": "Could not convert points balance to integer",
"205124": "Cannot find sender friend code",
"205177": "User already exists in database",
"205623": "Trial period for that title expired, you can't download that again",
"205644": "Credit cards can't be used on this console.",
"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.",
"205906": "Problem with your online account",
"206668": "Happens when current points count + new points would exceed the wii points limit",
"206673": "Invalid registration status",
"222001": "There is a NWC24 error, but it could not be obtained.",
"107006": "NWC24_ERR_FULL: The file NWC24 tried to download is too large.",
"206602": "Error while entering Wii Points Card code. Try again later.",
"206669": "Wii Points card invalid",
"206607": "Error while retrieving the served content",
"206608": "Error redeeming Wii Download Ticket",
"205800": "Wii Points Card error",
"205831": "Wii Points Card is for another country",
"205617": "Wii Points card code invalid",
"205618": "Wii Points card is for another country",
"206610": "Wii download ticket expired",
"206611": "Wii download ticket invalid",
"206612": "This Wii download ticket can't be used in your country",
"206613": "No software available for this download ticket. May be caused by parental controls.",
"205811": "Wii Points card expired",
"205815": "Wii Points Card was already used",
"205816": "Some error with the Wii Points Card",
"206667": "Wii download ticket invalid",
"205830": "Wii Points Card code is invalid",
"205819": "Wii Points Card code is invalid",
"208000": "You have entered the wrong state",
"208001": "Unable to process for credit cards (some kind of blacklist?)",
"208002": "Billing address invalid",
"206603": "Unable to confirm credit card information",
"208003": "Credit card number doesn't match card type",
"208004": "three-digit security code invalid",
"208005": "Mistake in credit card data.",
"208006": "Card number invalid",
"208007": "Expiration date invalid",
"208008": "Postal code invalid",
"208009": "Technical difficulties.",
"206664": "No security code was provided",
"208010": "Credit card could not get validated. Try again later.",
"208011": "Credit card declined",
"208012": "Credit card declined - no funds available",
"208013": "Credit card declined - inactive",
"208014": "Credit card expired",
"208015": "Credit card code invalid",
"208016": "Credit card number invalid",
"208017": "Credit card limit reached",
"208018": "Credit card invalid",
"208019": "Postal / zip code invalid",
"208021": "Refund is in progress",
"208022": "Refund was already processed",
"208023": "Refund error",
"208025": "Empty security code",
"206661": "Credit card type invalid",
"206662": "Credit card number invalid",
"205928": "Unknown error",
"205958": "Unknown error",
"205642": "Unknown error",
"205643": "Unknown error",
"205903": "Unknown error",
"205645": "Issue with your DSi shop account?",
"206699": "Try again later",
"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.",
"206112": "The free title promotion has ended (ICR_END)",
"206401": "Invalid characters in nick or password",
"206499": "Maintenance. Login not possible",
"205942": "Maintenance. Login not possible",
"20110": "Nintendo Wi-Fi Connection for the title has been discontinued. (The title/game was not patched with <a href=\"https://wiimmfi.de\">Wiimmfi</a>)",
"371410": "Unable to contact YouTube (applies if <a href=\"https://revivemii.xyz/\">RiiviveTube</a> is installed).",
"372201": "Flash channel returned HTTP 201 Created",
"372202": "Flash channel returned HTTP 202 Accepted",
"372203": "Flash channel returned HTTP 203 Non-Authoritative Information",
"372204": "Flash channel returned HTTP 204 No Content",
"372205": "Flash channel returned HTTP 205 Reset Content",
"372206": "Flash channel returned HTTP 206 Partial Content",
"372207": "Flash channel returned HTTP 207 Multi-Status",
"372208": "Flash channel returned HTTP 208 Already Reported",
"372226": "Flash channel returned HTTP 226 IM Used",
"372300": "Flash channel returned HTTP 300 Multiple Choices",
"372301": "Flash channel returned HTTP 301 Moved Permanently",
"372302": "Flash channel returned HTTP 302 Found",
"372303": "Flash channel returned HTTP 303 See Other",
"372304": "Flash channel returned HTTP 304 Not Modified",
"372305": "Flash channel returned HTTP 305 Use Proxy",
"372306": "Flash channel returned HTTP 306 Switch Proxy (unused)",
"372307": "Flash channel returned HTTP 307 Temporary Redirect",
"372308": "Flash channel returned HTTP 308 Permanent Redirect",
"372400": "Flash channel returned HTTP 400 Bad Request",
"372401": "Flash channel returned HTTP 401 Unauthorized",
"372402": "Flash channel returned HTTP 402 Payment Required",
"372403": "Flash channel returned HTTP 403 Forbidden",
"372404": "Flash channel returned HTTP 404 Not Found",
"372405": "Flash channel returned HTTP 405 Method Not Allowed",
"372406": "Flash channel returned HTTP 406 Not Acceptable",
"372407": "Flash channel returned HTTP 407 Proxy Authentication Required",
"372408": "Flash channel returned HTTP 408 Request Timeout",
"372409": "Flash channel returned HTTP 409 Conflict",
"372410": "Flash channel returned HTTP 410 Gone",
"372411": "Flash channel returned HTTP 411 Length Required",
"372412": "Flash channel returned HTTP 412 Precondition Failed",
"372413": "Flash channel returned HTTP 413 Payload Too Large",
"372414": "Flash channel returned HTTP 414 URI Too Long",
"372415": "Flash channel returned HTTP 415 Unsupported Media Type",
"372416": "Flash channel returned HTTP 416 Range Not Satisfiable",
"372417": "Flash channel returned HTTP 417 Expectation Failed",
"372418": "Flash channel returned HTTP 418 I'm a teapot",
"372421": "Flash channel returned HTTP 421 Misdirected Request",
"372422": "Flash channel returned HTTP 422 Unprocessable Content",
"372423": "Flash channel returned HTTP 423 Locked",
"372424": "Flash channel returned HTTP 424 Failed Dependency",
"372425": "Flash channel returned HTTP 425 Too Early",
"372426": "Flash channel returned HTTP 426 Upgrade Required",
"372428": "Flash channel returned HTTP 428 Precondition Required",
"372429": "Flash channel returned HTTP 429 Too Many Requests",
"372431": "Flash channel returned HTTP 431 Request Header Fields Too Large",
"372451": "Flash channel returned HTTP 451 Unavailable For Legal Reasons",
"372500": "Flash channel returned HTTP 500 Internal Server Error",
"372501": "Flash channel returned HTTP 501 Not Implemented",
"372502": "Flash channel returned HTTP 502 Bad Gateway",
"372503": "Flash channel returned HTTP 503 Service Unavailable",
"372504": "Flash channel returned HTTP 504 Gateway Timeout",
"372505": "Flash channel returned HTTP 505 HTTP Version Not Supported",
"372506": "Flash channel returned HTTP 506 Variant Also Negotiates",
"372507": "Flash channel returned HTTP 507 Insufficient Storage",
"372508": "Flash channel returned HTTP 508 Loop Detected",
"372510": "Flash channel returned HTTP 510 Not Extended",
"372511": "Flash channel returned HTTP 511 Network Authentication Required",
"362523": "Flash channel returned HTTP 523 Origin Is Unreachable"
}
def parse_error_codes(error_codes):
exact_codes = {}
wildcard_codes = {}
for line in error_codes.strip().split('\n'):
code, message = line.split(':', 1)
code = code.strip()
message = message.strip()
if 'X' in code:
wildcard_codes[code] = message
elif '-' in code:
# Handle ranges by expanding them into individual codes
ranges = code.split(',')
for r in ranges:
r = r.strip() # Clean up any extra spaces
if '-' in r: # Ensure it is a valid range
start, end = r.split('-')
start = start.strip()
end = end.strip()
# Generate all codes in the range
for num in range(int(start), int(end) + 1):
exact_codes[str(num)] = message
else:
# If it's not a valid range, treat it as an exact code
exact_codes[r] = message
else:
exact_codes[code] = message
return exact_codes, wildcard_codes
def create_database(db_name='error_codes.db'):
# Connect to the SQLite database (or create it)
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
# Create a table for error codes
cursor.execute('''
CREATE TABLE IF NOT EXISTS error_codes (
code TEXT PRIMARY KEY,
message TEXT
)
''')
# Parse the error codes
exact_codes, wildcard_codes = parse_error_codes(error_codes)
# Insert exact codes into the database
for code, message in exact_codes.items():
cursor.execute('INSERT OR IGNORE INTO error_codes (code, message) VALUES (?, ?)', (code, message))
# Insert wildcard codes into the database
for code, message in wildcard_codes.items():
cursor.execute('INSERT OR IGNORE INTO error_codes (code, message) VALUES (?, ?)', (code, message))
# Commit changes and close the connection
conn.commit()
conn.close()
def matches_wildcard(code, wildcard_code):
pattern = wildcard_code.replace('X', '[0-9]')
return re.fullmatch(pattern, str(code)) is not None
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
conn = sqlite3.connect('error_codes.db')
cursor = conn.cursor()
# Check for exact matches
cursor.execute('SELECT message FROM error_codes WHERE code = ?', (str(code),))
result = cursor.fetchone()
if result:
return f"{code}: {result[0]}"
# Check for wildcard matches
cursor.execute('SELECT code, message FROM error_codes')
for row in cursor.fetchall():
if matches_wildcard(code, row[0]):
return f"{code}: {row[1]}"
return f"{code}: Error code not found."
def check_url(uri):
global url_status # Declare the global variable to modify it
try:
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"
except requests.exceptions.RequestException:
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")
async def statusy(ctx):
check_url(url)
if status == "Not Set":
await ctx.send(f"WiiMart Status: {url_status}\nAdmin Status: :person_shrugging: Currently Unset")
else:
await ctx.send(f"WiiMart Status: {url_status}\nAdmin Status: {status}")
@bot.hybrid_command(name="setstatus",description="Sets the current server status to your liking")
@commands.has_any_role("Owner", "Admin", "Moderators", "Hoster")
async def setstatus(ctx, stat: str):
global status
status = stat
await ctx.send(f"Status has been set to: {status}")
@bot.hybrid_command(name="unsetstatus", description="Unsets the current status")
@commands.has_any_role("Owner", "Admin", "Moderators", "Hoster")
async def unset(ctx):
global status
status = "Not Set"
await ctx.send("Status has been unset.")
@bot.hybrid_command(name="error", description="Gets the error message linked with the shop error code")
async def geterror(ctx, errorcode: commands.Range[int, 51330, 372511]):
try:
errormessage = get_error_message(errorcode)
except ValueError:
errormessage = "Error Code was not found."
await ctx.send(errormessage)
@bot.hybrid_command(name="addfc", description="Adds your Wii Friend code to the list of friend codes so that others can add you")
async def addfc(ctx, fc: int):
await ctx.defer(ephemeral=True)
if len(str(fc)) != 16:
await ctx.send(f"You need to input a friendcode that is of 16 numbers not {len(str(fc))}", ephemeral=True)
else:
userid = ctx.author.id
#print(userid)
conn = mysql.connector.connect(host=os.getenv("mqur"), user=os.getenv("mqlu"), password=os.getenv("mqlp"), database=os.getenv("mqld"), port=os.getenv("mqpo"))
cur = conn.cursor(buffered=True)
cur.execute(f"SELECT fc FROM usersfc WHERE userid = '{userid}'")
try:
fethcy = cur.fetchall()
except Error as e:
fetchy = False
if fethcy:
cur.close()
cur = conn.cursor(buffered=True)
cur.execute(f"UPDATE usersfc SET fc = '{fc}' WHERE userid = '{userid}'")
conn.commit()
cur.close()
conn.close()
await ctx.send("Updated your friend code", ephemeral=True)
else:
cur.close()
cur = conn.cursor(buffered=True)
cur.execute(f"INSERT INTO usersfc (userid, fc) VALUES ('{userid}', '{fc}')")
conn.commit()
cur.close()
conn.close()
await ctx.send("Added your friend code", ephemeral=True)
@bot.hybrid_command(name="getfc", description="Gets the friend code of the selected user")
async def getfc(ctx, member: discord.Member):
await ctx.defer(ephemeral=True)
userid = member.id
#print(userid)
conn = mysql.connector.connect(host=os.getenv("mqur"), user=os.getenv("mqlu"), password=os.getenv("mqlp"), database=os.getenv("mqld"), port=os.getenv("mqpo"))
cur = conn.cursor(buffered=True)
cur.execute(f"SELECT fc FROM usersfc WHERE userid = '{userid}'")
fetchy = cur.fetchone()[0]
fetchy = " ".join([fetchy[i:i+4] for i in range(0, len(fetchy), 4)])
if fetchy:
await ctx.send(f"<@{userid}> Friend code is: {fetchy}", ephemeral=True)
else:
await ctx.send(f"<@{userid}> did not share his friend code.", ephemeral=True)
cur.close()
conn.close()
@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")
async def addfcadm(ctx, user: discord.Member, fc: int):
await ctx.defer(ephemeral=True)
if len(str(fc)) != 16:
userid = user.id
await ctx.send(f"You need to input a friendcode that is of 16 numbers not {len(str(fc))} for <@{userid}>", ephemeral=True)
else:
userid = user.id
#print(userid)
conn = mysql.connector.connect(host=os.getenv("mqur"), user=os.getenv("mqlu"), password=os.getenv("mqlp"), database=os.getenv("mqld"), port=os.getenv("mqpo"))
cur = conn.cursor(buffered=True)
cur.execute(f"SELECT fc FROM usersfc WHERE userid = '{userid}'")
try:
fethcy = cur.fetchall()
except Error as e:
fetchy = False
if fethcy:
cur.close()
cur = conn.cursor(buffered=True)
cur.execute(f"UPDATE usersfc SET fc = '{fc}' WHERE userid = '{userid}'")
conn.commit()
cur.close()
conn.close()
await ctx.send(f"Updated <@{userid}> friend code", ephemeral=True)
else:
cur.close()
cur = conn.cursor(buffered=True)
cur.execute(f"INSERT INTO usersfc (userid, fc) VALUES ('{userid}', '{fc}')")
conn.commit()
cur.close()
conn.close()
await ctx.send(f"Added <@{userid}> friend code", ephemeral=True)
@bot.event
async def on_message(message):
if bot.user.mentioned_in(message) and message.guild:
try:
await message.add_reaction('👀')
#await message.reply("Please dont ping me...")
except Exception as e:
#print(f'Failed to react to mention: {e}')
logging.error(f'Failed to react to mention: {e}')
if isinstance(message.channel, discord.DMChannel) and message.author != bot.user:
try:
await message.add_reaction('👀')
await message.reply("Dont dm me please... If you have an issue, make a post in <#1350084638726553632> or send an email to us at support@wiimart.org")
except Exception as e:
#print(f'Failed to react to DM: {e}')
logging.error(f'Failed to react to mention: {e}')
await bot.process_commands(message)
def start_bot():
"""Start the bot application"""
bot.run(token) # Or however you start your bot
if __name__ == "__main__":
#try:
# os.remove("error_codes.db")
#except Exception as e:
# #print("i cant let you do that dave...")
# logging.warning("i cant let you do that dave...")
#create_database()
logging.info("Creation of database disabled")
start_bot()