mirror of
https://wiilab.wiimart.org/wiimart/WiiMartBot
synced 2025-09-02 19:41:03 +02:00
648 lines
29 KiB
Python
648 lines
29 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 = {
|
|
"201005": "Invalid public key type in certificate",
|
|
"201009": "Read failure (short read)",
|
|
"201010": "Write failure (short write)",
|
|
"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",
|
|
"201026": "Incorrect access rights (according to the TMD)",
|
|
"201027": "Issuer not found in the certificate chain",
|
|
"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)",
|
|
"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",
|
|
"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",
|
|
"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",
|
|
"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",
|
|
"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",
|
|
"204704": "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",
|
|
"204800": "HTTP 500 - Internal Server Error",
|
|
"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",
|
|
"204901": "NHTTP_ERROR_ALLOC",
|
|
"204902": "NHTTP_ERROR_TOOMANYREQ",
|
|
"204903": "NHTTP_ERROR_SOCKET",
|
|
"204904": "NHTTP_ERROR_DNS",
|
|
"204905": "NHTTP_ERROR_CONNECT",
|
|
"204906": "NHTTP_ERROR_BUFFULL",
|
|
"204907": "NHTTP_ERROR_HTTPPARSE",
|
|
"204908": "NHTTP_ERROR_CANCELED",
|
|
"204909": "NHTTP_ERROR_REVOLUTIONSDK",
|
|
"204910": "NHTTP_ERROR_REVOLUTIONWIFI",
|
|
"204911": "NHTTP_ERROR_UNKNOWN",
|
|
"204912": "NHTTP_ERROR_DNS_PROXY",
|
|
"204913": "NHTTP_ERROR_CONNECT_PROXY",
|
|
"204914": "NHTTP_ERROR_SSL",
|
|
"204927": "IAS Unknown issuer of device cert",
|
|
"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",
|
|
"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",
|
|
"205007": "Invalid NAND Dump (Dolphin only)",
|
|
"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.",
|
|
"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",
|
|
"205540": "This software doesn't work in the vWii",
|
|
"205617": "Wii Points card code invalid",
|
|
"205618": "Wii Points card is for another country",
|
|
"205621": "Unknown error (possibly ECS gift error?)",
|
|
"205623": "Trial period for that title expired, you can't download that again",
|
|
"205600": "Generic ECS (ECommerceSOAP) error.",
|
|
"205700": "Generic ETS (ETicket Services?) error.",
|
|
"205800": "Generic PAS (Points Account System?) error.",
|
|
"205825": "Generic PAS (Points Account System?) error. (PAS_ERROR_CODE)",
|
|
"205900": "Generic IAS (IdentityAuthenticationSOAP) error.",
|
|
"206400": "Generic IAS (IdentityAuthenticationSOAP) error.",
|
|
"206600": "Generic OSS error.",
|
|
"205625": "ECS Gift error",
|
|
"205626": "Unable to send present (ECS gift error)",
|
|
"205627": "Can't buy DLC for a title you don't own.",
|
|
"205642": "Unknown error",
|
|
"205643": "Unknown error",
|
|
"205644": "Credit cards can't be used on this console.",
|
|
"205645": "Issue with your DSi shop account?",
|
|
"205646": "Unable to send present (ECS Gift)",
|
|
"205672": "ECS Account mismatch",
|
|
"205800": "Wii Points Card error",
|
|
"205810": "You don't have enough Wii Points / Error while redeeming your download ticket",
|
|
"205811": "Wii Points card expired",
|
|
"205815": "Wii Points Card was already used",
|
|
"205816": "Some error with the Wii Points Card",
|
|
"205818": "This card number can only be used for a specific title, it is not a Wii Points Card.",
|
|
"205819": "Wii Points Card code is invalid",
|
|
"205826": "Server under heavy load",
|
|
"205829": "Server under heavy load",
|
|
"205830": "Wii Points Card code is invalid",
|
|
"205831": "Wii Points Card is for another country",
|
|
"205901": "Wii number invalid!",
|
|
"205903": "Unknown error",
|
|
"205906": "Problem with your online account",
|
|
"205928": "Unknown error",
|
|
"205942": "Maintenance. Login not possible",
|
|
"205958": "Unknown error",
|
|
"205968": "Bad device code",
|
|
"205969": "Server under heavy load",
|
|
"206112": "The free title promotion has ended (ICR_END)",
|
|
"206401": "Invalid characters in nick or password",
|
|
"206499": "Maintenance. Login not possible",
|
|
"206601": "Authentication error, missing required parameters",
|
|
"206602": "Error while entering Wii Points Card code. Try again later.",
|
|
"206603": "Unable to confirm credit card information",
|
|
"206607": "Error while retrieving the served content",
|
|
"206608": "Error redeeming Wii Download Ticket",
|
|
"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.",
|
|
"206650": "Wrong PIN (parental controls)",
|
|
"206651": "Mistake while entering the wii serial number",
|
|
"206652": "Wrong PIN three times (parental controls)",
|
|
"206653": "Nickname or password wrong",
|
|
"206660": "No progress was made in the last operation",
|
|
"206661": "Credit card type invalid",
|
|
"206662": "Credit card number invalid",
|
|
"206663": "An operation is in progress",
|
|
"206664": "No security code was provided",
|
|
"206667": "Wii download ticket invalid",
|
|
"206668": "Happens when current points count + new points would exceed the wii points limit",
|
|
"206669": "Wii Points card invalid",
|
|
"206670": "Invalid friend code",
|
|
"206671": "Invalid/Wrong Wii Shop title ID",
|
|
"206672": "No title info (Wii Shop)",
|
|
"206673": "Invalid registration status",
|
|
"206674": "Unexpected eclib error",
|
|
"206699": "Try again later",
|
|
"208000": "You have entered the wrong state",
|
|
"208001": "Unable to process for credit cards (some kind of blacklist?)",
|
|
"208002": "Billing address invalid",
|
|
"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.",
|
|
"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",
|
|
"209531": "HTTP 404 Not Found",
|
|
"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",
|
|
"209593": "Access denied by Opera's Wii Shop domain filter",
|
|
"209600": "Connection Timeout, the shop took too long to load",
|
|
"209601": "Connection Timeout, the shop took too long to load",
|
|
"209620": "Some JS files couldn't be loaded (shopErrCheck)",
|
|
"209622": "SSL CA unknown / not included in channel",
|
|
"209622": "SSL CA unknown / not included in channel",
|
|
"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 (?)",
|
|
"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)",
|
|
"209800": "No DNS Entry for oss-auth.shop.wii.com",
|
|
"209XXX": "Server connection timeout",
|
|
"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",
|
|
"250943": "Problems with your Club Nintendo -account. It can't get connected with your shop account",
|
|
"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.",
|
|
"51330": "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."
|
|
}
|
|
|
|
|
|
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, 250943]):
|
|
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()
|
|
|