### Initialize and Run Discord Bot Source: https://context7.com/hextree/curry-bot/llms.txt Configure bot intents and event handlers to start the Discord client. ```python # Bot setup in curry_bot.py from nextcord import Game, Intents, Status from nextcord.ext.commands import Bot from discord_tools.auth import get_token TOKEN = get_token() intents = Intents.default() intents.message_content = True client = Bot(command_prefix='!', status=Status.online, activity=Game("Azure Dreams"), intents=intents) @client.event async def on_ready(): print("Logged in as " + client.user.name) @client.event async def on_disconnect(): await client.change_presence(activity=None, status=Status.offline) print("Disconnect") # Run the bot client.run(TOKEN) # Shell command to start: # python curry_bot.py # Or use the provided script: # ./run.sh ``` -------------------------------- ### Validate Seeds to Exclude HiKewne Source: https://context7.com/hextree/curry-bot/llms.txt Validates seeds to exclude those that would result in starting with the HiKewne familiar. It calculates the starter monster ID based on a SHA256 hash of the seed. ```python # Seed validator in ad_rando/seed_generator.py import hashlib import math import struct class NoHiKewneSeedValidator(SeedValidator): STARTER_MONSTER_HASH_HEX_INDEX = 6 MONSTERS_NUMBER = 45 HIKEWNE_MONSTER_ID = 1 def validate(self, seed): return self._calculate_starter_monster_id(self._calculate_sha256(seed)) != self.HIKEWNE_MONSTER_ID def _calculate_sha256(self, seed): m = hashlib.sha256() m.update(str.encode(str(seed))) return m.digest() def _calculate_starter_monster_id(self, seed_hash): return (1 + self._calculate_used_hash_hex(seed_hash) % self.MONSTERS_NUMBER) def _calculate_used_hash_hex(self, seed_hash): seed_hash_start_byte = self.STARTER_MONSTER_HASH_HEX_INDEX * 4 seed_hash_end_byte = seed_hash_start_byte + 4 return int(math.fabs(struct.unpack('!i', seed_hash[seed_hash_start_byte:seed_hash_end_byte])[0])) # Example usage: validator = NoHiKewneSeedValidator() is_valid = validator.validate(1699123456789) # Returns True/False based on starter monster ``` -------------------------------- ### Define Hello Command Source: https://context7.com/hextree/curry-bot/llms.txt Defines the !hello command for the Discord bot. It sends a personalized greeting to the user. ```python # Command definition in curry_bot.py @client.command(description="Say Hello", brief="Say Hello") async def hello(ctx): await ctx.send(curry_message("Hello {}!".format(get_author(ctx.message)))) ``` -------------------------------- ### Fetch Speedrun Leaderboard Source: https://context7.com/hextree/curry-bot/llms.txt Fetches and displays the speedrun leaderboard for Azure Dreams from Speedrun.com. It uses fuzzy matching to find the best category and retrieves player names and times. ```python # API wrapper in speedrunapi/speedrunapi.py import srcomapi import srcomapi.datatypes as dt from difflib import SequenceMatcher api = srcomapi.SpeedrunCom() api.debug = 1 game = api.search(srcomapi.datatypes.Game, {"name": "azure dreams"})[0] def fetch_leaderboard(query): best_guess = max(game.categories, key=lambda cat: SequenceMatcher(None, query.lower(), cat.name.lower()).ratio()) yield best_guess.name for r in dt.Leaderboard(api, data=api.get("leaderboards/{}/category/{}?embed=variables".format(game.id, best_guess.id))).runs: yield r['place'], r['run'].players[0].name, r['run'].times['primary_t'] ``` -------------------------------- ### Initialize Timestamp Objects Source: https://context7.com/hextree/curry-bot/llms.txt Create and parse time durations using the Timestamp class. ```python t = Timestamp("3h 53m 23s 380ms") print(t) # Output: 3h 53m 23s 380ms t2 = Timestamp.from_milliseconds(14003380) print(t2) # Output: 3h 53m 23s 380ms ``` -------------------------------- ### Load Discord Bot Token Source: https://context7.com/hextree/curry-bot/llms.txt Retrieve the bot token from a local JSON credentials file. ```python # Token loading in discord_tools/auth.py import json def get_token(): with open('discord_tools/creds.json', 'r') as f: return json.load(f)['token'] # creds.json format: # { # "token": "your-discord-bot-token-here" # } ``` -------------------------------- ### Countdown Timer Command (Python) Source: https://context7.com/hextree/curry-bot/llms.txt Defines a Discord command '!countdown' that initiates a countdown from a specified number (default 10) or a user-provided number up to 10. Includes error handling for invalid inputs. ```python COUNTDOWN_START = 10 @client.command(description="Type '!countdown' to start a countdown from 10.\nType '!countdown ' to countdown from start, where start is a positive integer <= 10.", brief="Start a countdown") async def countdown(ctx, *args): if args and not args[0].isdigit(): await ctx.send(curry_message("I can't count starting from {}.".format(args[0]))) else: start = int(args[0]) if args else COUNTDOWN_START if start <= 0: await ctx.send(curry_message("Why not just say 'go'?")) elif start > COUNTDOWN_START: await ctx.send(curry_message("That sounds like a lot of work. Ask me to start counting from {} or less.".format(COUNTDOWN_START))) else: for n in range(0, start): await ctx.send(curry_message("{}".format(start - n))) time.sleep(1) await ctx.send(curry_message("Go!")) ``` -------------------------------- ### Create BingoSync Room (Python) Source: https://context7.com/hextree/curry-bot/llms.txt Integrates with the BingoSync API to create a new bingo room. It obtains a CSRF token, sets room parameters, and extracts the room code from the response. Requires 'requests' and 'BeautifulSoup'. ```python import re import requests from bs4 import BeautifulSoup URL = "https://bingosync.com/" DATA = {'nickname':'CurryBot', 'game_type':18, 'variant_type':18, 'lockout_mode':1, 'seed':1, 'is_spectator':'on'} def create_room(name, passphrase, bingo_data): # Obtain CSRF token csrf = requests.get(url=URL).cookies.get('csrftoken') cookies = {'csrftoken': csrf} data = DATA.copy() data['room_name'] = name data['csrfmiddlewaretoken'] = csrf data['custom_json'] = bingo_data data['passphrase'] = passphrase data['game_type'] = 18 data['variant_type'] = 172 data['seed'] = '' data['lockout_mode'] = 1 data['hide_card'] = 'on' # Create room via POST res = requests.post(URL, cookies=cookies, data=data) # Extract room code from response soup = BeautifulSoup(res.text, 'html.parser') pattern = r"/room/(.+)/disconnect" roomcode = None for link in soup.find_all('a'): m = re.match(pattern, link.get('href')) if m: roomcode = m.group(1) break if roomcode: return URL + "room/" + roomcode ``` -------------------------------- ### Adrando Seed Generator Command Handler Source: https://context7.com/hextree/curry-bot/llms.txt Handles commands for generating Azure Dreams Randomizer seeds. It supports fetching current seeds, listing presets, and generating new seeds based on provided arguments. ```python # Command handler class in ad_rando/seed_generator.py class AdrandoCommandHandler: RANDO_LINKS = [SeedsGenerator.ADRANDO_BASE] def __init__(self, args): self._args = args def handle(self): if len(self._args) == 0: return self._current_rando_seed_links() preset_name = self._args[0] if preset_name.startswith('preset'): return self._available_presets() else: return self._generate_seeds(preset_name) ``` -------------------------------- ### Create Bingo Room Source: https://context7.com/hextree/curry-bot/llms.txt Generates a bingo room URL and passphrase. Reads bingo card data and selects a random passphrase from a file. ```python def get_room(name=None): with open('bingo/bingo_cards.json', 'r') as f: data = f.read() with open('bingo/passphrases.txt', 'r') as f: passphrase = random.choice(f.readlines()).strip() room_url = create_room(name if name else "Azure Dreams", passphrase, data) return room_url, passphrase # Example programmatic usage: room_url, password = get_room("My Tournament") print(f"Room: {room_url}, Password: {password}") ``` -------------------------------- ### Format Speedrun Timestamps Source: https://context7.com/hextree/curry-bot/llms.txt Parses and formats speedrun timestamps in the standard speedrun.com format. It can initialize from a string or from milliseconds and provides a string representation. ```python # Timestamp class in common/common.py class Timestamp: def __init__(self, s): self.hours, self.minutes, self.seconds, self.milliseconds = 0, 0, 0, 0 for arg in s.split(): if arg.endswith("ms"): self.milliseconds += int(arg[:-2]) elif arg.endswith("s"): self.seconds += int(arg[:-1]) elif arg.endswith("m"): self.minutes += int(arg[:-1]) elif arg.endswith("h"): self.hours += int(arg[:-1]) @staticmethod def from_milliseconds(ms): t = Timestamp("0ms") temp = ms t.hours = temp // 3600000 temp %= 3600000 t.minutes = temp // 60000 temp %= 60000 t.seconds = temp // 1000 t.milliseconds = temp % 1000 return t def __str__(self): result = [] if self.hours != 0: result.append("{}h".format(self.hours)) if not (self.hours == 0 and self.minutes == 0): result.append("{}m".format(self.minutes)) result.append("{}s".format(self.seconds)) if self.milliseconds > 0: result.append("{}ms".format(self.milliseconds)) return ' '.join(result) ``` -------------------------------- ### Generate Randomizer Seeds Source: https://context7.com/hextree/curry-bot/llms.txt Generates Azure Dreams Randomizer seeds with preset configurations and validation. Creates a specified number of seeds and formats them as Adrando links. ```python # Seed generation classes in ad_rando/seed_generator.py class SeedGenerator: def __init__(self, validator): self._validator = validator self._seed_base = time.time() * 1000 self._seed_floor = math.floor(self._seed_base) self._offset = math.floor((self._seed_base - self._seed_floor) * 1000) + 50 self._index = 0 def next(self): seed = self._generate() while not self._validator.validate(seed): seed = self._generate() return seed class SeedsGenerator: ADRANDO_BASE = 'https://adrando.com/' def __init__(self, randomizer_params, validator, seeds_number): self._randomizer_params = randomizer_params self._validator = validator self._seeds_number = seeds_number def generate(self): seed_generator = SeedGenerator(self._validator) return [self._create_adrando_link(seed_generator.next()) for _ in range(self._seeds_number)] def _create_adrando_link(self, seed): return f"{self.ADRANDO_BASE}?{self._randomizer_params.params()},,{seed}" # Example usage - generate Random Toolkit tournament seeds: from ad_rando.seed_generator import SeedsGenerator, ManualRandomizerParams, NoHiKewneSeedValidator params = ManualRandomizerParams('dE:-2,fh:1,iIlnS:0,tux') validator = NoHiKewneSeedValidator() # Excludes seeds that start with HiKewne generator = SeedsGenerator(params, validator, seeds_number=3) seeds = generator.generate() # Output: ['https://adrando.com/?dE:-2,fh:1,iIlnS:0,tux,,1699123456789', ...] ``` -------------------------------- ### Discord Bot Token Configuration Source: https://github.com/hextree/curry-bot/blob/master/README.md Paste your Discord bot token into the 'creds.json' file within the 'discord_tools' folder. Ensure the JSON structure is correct. ```json { "token" : "..." } ``` -------------------------------- ### Define Bingo Command Source: https://context7.com/hextree/curry-bot/llms.txt Defines the !bingo command to create a BingoSync room for Azure Dreams. It returns the room URL and password. ```python # Command definition in curry_bot.py @client.command(description="Creates a Bingo room at https://bingosync.com/ and provides the link and password.", brief="Create a Bingo game") async def bingo(ctx): await ctx.send(curry_message("Creating Bingo room. Please wait a moment...")) room_url, password = get_room() if not room_url: await ctx.send(curry_message("Error! I wasn't able to create the room. Curry.")) else: await ctx.send(curry_message("...done. Room created at URL: {} with password: {}\nGo do your best! Don't stumble!".format(room_url, italics(password)))) ``` -------------------------------- ### Flip Coin Command (Python) Source: https://context7.com/hextree/curry-bot/llms.txt Implements a Discord command '!flip' that uses the dice_roll function to simulate a coin flip, returning Heads or Tails. Requires the dice_roll function from the previous snippet. ```python @client.command(description="Flip a coin, resulting in Heads or Tails. Uses random bits from random.org", brief="Flip a coin") async def flip(ctx): await ctx.send(curry_message("Flipping coin...")) if dice_roll(1, 2) == 1: await ctx.send(curry_message("Heads " + HEADS)) else: await ctx.send(curry_message("Tails " + TAILS)) ``` -------------------------------- ### Format Discord Messages Source: https://context7.com/hextree/curry-bot/llms.txt Helper functions for applying Discord markdown and the bot's signature curry emoji to messages. ```python # Formatting utilities in discord_tools/discord_formatting.py CURRY = '<:Curry:689531071217270878>' def bold(s): return '**' + s + '**' def italics(s): return '*' + s + '*' def curry_message(s): return CURRY + " " + s def curry_format(s, *args): return curry_message(s.format(*args)) def get_author(message): return str(message.author)[:str(message.author).find('#')] # Example usage: msg = curry_message("Hello World!") # Output: <:Curry:689531071217270878> Hello World! formatted = curry_format("Welcome {}, you have {} points!", "Player", 100) # Output: <:Curry:689531071217270878> Welcome Player, you have 100 points! styled = curry_message("The password is: " + italics("secretword")) # Output: <:Curry:689531071217270878> The password is: *secretword* ``` -------------------------------- ### Roll Dice with True Randomness (Python) Source: https://context7.com/hextree/curry-bot/llms.txt Rolls dice using random.org for true randomness, with a fallback to Python's random module if the API fails. Use for commands like !roll, !roll d6, or !roll 2d8. ```python import random import requests URL = 'https://www.random.org/integers/' DATA = {'base': 10, 'format': 'plain', 'rnd': 'new'} def dice_roll_random_org(num, sides): data = DATA.copy() data['num'] = num data['col'] = num data['min'] = 1 data['max'] = sides res = requests.get(URL, data) if res.status_code != 200: return -1 return sum(int(x) for x in res.text.split()) ``` ```python def dice_roll(num, sides): result = dice_roll_random_org(num, sides) if result == -1: return sum(random.randint(1, sides) for _ in range(num)) return result ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.