mirror of
https://github.com/osmarks/autobotrobot
synced 2025-01-21 12:46:53 +00:00
New commands and stuff
- ++apioform - ++random using py-rolldice - ++choose - random choice with new AutoBias™ algorithm - ban andrew - minor general fixes - cheat at esobot typeraces autonomously
This commit is contained in:
parent
ef993de7e3
commit
26f5247acf
98
src/main.py
98
src/main.py
@ -9,6 +9,8 @@ import asyncio
|
||||
import json
|
||||
import argparse
|
||||
import traceback
|
||||
import random
|
||||
import rolldice
|
||||
from datetime import timezone, datetime
|
||||
|
||||
import tio
|
||||
@ -45,10 +47,35 @@ cleaner = discord.ext.commands.clean_content()
|
||||
def clean(ctx, text):
|
||||
return cleaner.convert(ctx, text)
|
||||
|
||||
@bot.event
|
||||
async def on_message(message):
|
||||
words = message.content.split(" ")
|
||||
if len(words) == 10 and message.author.id == 435756251205468160:
|
||||
await message.channel.send(util.unlyric(message.content))
|
||||
else:
|
||||
if message.author.id == bot.user.id: return
|
||||
ctx = await bot.get_context(message)
|
||||
if not ctx.valid: return
|
||||
await bot.invoke(ctx)
|
||||
|
||||
@bot.event
|
||||
async def on_command_error(ctx, err):
|
||||
print(ctx, err)
|
||||
if isinstance(err, commands.CommandNotFound, commands.CheckFailure): return
|
||||
try:
|
||||
trace = re.sub("\n\n+", "\n", "\n".join(traceback.format_exception(err, err, err.__traceback__)))
|
||||
print(trace)
|
||||
await ctx.send(embed=error_embed(gen_codeblock(trace), title="Internal error"))
|
||||
except Exception as e: print("meta-error:", e)
|
||||
|
||||
@bot.command(help="Gives you a random fortune as generated by `fortune`.")
|
||||
async def fortune(ctx):
|
||||
await ctx.send(subprocess.run(["fortune"], stdout=subprocess.PIPE, encoding="UTF-8").stdout)
|
||||
|
||||
@bot.command(help="Generates an apioform type.")
|
||||
async def apioform(ctx):
|
||||
await ctx.send(util.apioform())
|
||||
|
||||
@bot.command(help="Says Pong.")
|
||||
async def ping(ctx):
|
||||
await ctx.send("Pong.")
|
||||
@ -97,6 +124,9 @@ exec_flag_parser = NonExitingArgumentParser(add_help=False)
|
||||
exec_flag_parser.add_argument("--verbose", "-v", action="store_true")
|
||||
exec_flag_parser.add_argument("--language", "-L")
|
||||
|
||||
def gen_codeblock(content):
|
||||
return "```\n" + content.replace("```", "\\`\\`\\`")[:1900] + "\n```"
|
||||
|
||||
@bot.command(rest_is_raw=True, help="Execute provided code (in a codeblock) using TIO.run.")
|
||||
async def exec(ctx, *, arg):
|
||||
match = re.match(EXEC_REGEX, arg, flags=re.DOTALL)
|
||||
@ -115,11 +145,11 @@ async def exec(ctx, *, arg):
|
||||
async with ctx.typing():
|
||||
ok, real_lang, result, debug = await tio.run(lang, code)
|
||||
if not ok:
|
||||
await ctx.send(embed=error_embed(f"""```{result}```""", "Execution error"))
|
||||
await ctx.send(embed=error_embed(gen_codeblock(result), "Execution failed"))
|
||||
else:
|
||||
out = result
|
||||
if flags.verbose:
|
||||
debug_block = f"""\n```{debug}\nLanguage: {real_lang}```"""
|
||||
debug_block = "\n" + gen_codeblock(f"""{debug}\nLanguage: {real_lang}""")
|
||||
out = out[:2000 - len(debug_block)] + debug_block
|
||||
else:
|
||||
out = out[:2000]
|
||||
@ -143,11 +173,12 @@ Reminders are checked every minute, so while precise times are not guaranteed, r
|
||||
async def remind(ctx, time, *, reminder):
|
||||
reminder = reminder.strip()
|
||||
if len(reminder) > 512:
|
||||
await ctx.send(embed=error_embed("Maximum reminder length is 512 characters"))
|
||||
await ctx.send(embed=error_embed("Maximum reminder length is 512 characters", "Foolish user error"))
|
||||
return
|
||||
extra_data = {
|
||||
"author_id": ctx.author.id,
|
||||
"channel_id": ctx.message.channel.id,
|
||||
"message_id": ctx.message.id,
|
||||
"original_time_spec": time
|
||||
}
|
||||
try:
|
||||
@ -192,12 +223,59 @@ AutoBotRobot is open source - the code is available at <https://github.com/osmar
|
||||
You can also invite it to your server: <https://discordapp.com/oauth2/authorize?&client_id=509849474647064576&scope=bot&permissions=68608>
|
||||
""")
|
||||
|
||||
@bot.command(help="Randomly generate an integer using dice syntax.", name="random", rest_is_raw=True)
|
||||
async def random_int(ctx, *, dice):
|
||||
await ctx.send(rolldice.roll_dice(dice)[0])
|
||||
|
||||
bad_things = ["lyric", "endos", "solarflame", "lyric", "319753218592866315", "andrew", "6", "c++"]
|
||||
good_things = ["potato", "heav", "gollark", "helloboi", "bees", "hellboy", "rust", "ferris", "crab", "transistor"]
|
||||
negations = ["not", "bad", "un", "kill", "n't"]
|
||||
def weight(thing):
|
||||
lthing = thing.lower()
|
||||
weight = 1.0
|
||||
if lthing == "c": weight *= 0.3
|
||||
for bad_thing in bad_things:
|
||||
if bad_thing in lthing: weight *= 0.5
|
||||
for good_thing in good_things:
|
||||
if good_thing in lthing: weight *= 2.0
|
||||
for negation in negations:
|
||||
for _ in range(lthing.count(negation)): weight = 1 / weight
|
||||
return weight
|
||||
|
||||
@bot.command(help="'Randomly' choose between the specified options.", name="choice", aliases=["choose"])
|
||||
async def random_choice(ctx, *choices):
|
||||
choicelist = list(choices)
|
||||
samples = 1
|
||||
try:
|
||||
samples = int(choices[0])
|
||||
choicelist.pop(0)
|
||||
except: pass
|
||||
|
||||
if samples > 1e5:
|
||||
await ctx.send("No.")
|
||||
return
|
||||
|
||||
choices = random.choices(choicelist, weights=map(weight, choicelist), k=samples)
|
||||
|
||||
if len(choices) == 1:
|
||||
await ctx.send(choices[0])
|
||||
else:
|
||||
counts = {}
|
||||
for choice in choices:
|
||||
counts[choice] = counts.get(choice, 0) + 1
|
||||
await ctx.send("\n".join(map(lambda x: f"{x[0]} x{x[1]}", counts.items())))
|
||||
|
||||
async def admin_check(ctx):
|
||||
if not await bot.is_owner(ctx.author):
|
||||
await ctx.send(embed=error_embed(f"{ctx.author.name} is not in the sudoers file. This incident has been reported."))
|
||||
# apparently this has to be a pure function because ++help calls it for some reason because of course
|
||||
#await ctx.send(embed=error_embed(f"{ctx.author.name} is not in the sudoers file. This incident has been reported."))
|
||||
return False
|
||||
return True
|
||||
|
||||
@bot.check
|
||||
async def andrew_bad(ctx):
|
||||
return ctx.message.author.id != 543131534685765673
|
||||
|
||||
@bot.group()
|
||||
@commands.check(admin_check)
|
||||
async def magic(ctx):
|
||||
@ -212,14 +290,18 @@ async def py(ctx, *, code):
|
||||
**locals(),
|
||||
"bot": bot,
|
||||
"ctx": ctx,
|
||||
"db": database
|
||||
}
|
||||
result = await asyncio.wait_for(util.async_exec(code, loc, globals()), timeout=5.0)
|
||||
if result != None:
|
||||
await ctx.send("```\n" + repr(result).replace("```", "\\`\\`\\`")[:1900] + "\n```")
|
||||
if isinstance(result, str):
|
||||
await ctx.send(result[:1999])
|
||||
else:
|
||||
await ctx.send(gen_codeblock(repr(result)))
|
||||
except TimeoutError:
|
||||
await ctx.send(embed=error_embed("Timed out."))
|
||||
except BaseException as e:
|
||||
await ctx.send("Error:\n```\n" + traceback.format_exc().replace("```", "\\`\\`\\`")[:1900] + "\n```")
|
||||
await ctx.send(embed=error_embed(gen_codeblock(traceback.format_exc())))
|
||||
|
||||
@magic.command(rest_is_raw=True)
|
||||
async def sql(ctx, *, code):
|
||||
@ -230,10 +312,10 @@ async def sql(ctx, *, code):
|
||||
async with csr as cursor:
|
||||
async for row in cursor:
|
||||
out += " ".join(map(repr, row)) + "\n"
|
||||
await ctx.send("```\n" + out[:1990] + "```")
|
||||
await ctx.send(gen_codeblock(out))
|
||||
await database.commit()
|
||||
except Exception as e:
|
||||
await ctx.send(embed=error_embed("```\n" + traceback.format_exc() + "```"))
|
||||
await ctx.send(embed=error_embed(gen_codeblock(traceback.format_exc())))
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
|
51
src/util.py
51
src/util.py
@ -3,17 +3,18 @@ import datetime
|
||||
import parsedatetime
|
||||
import ast
|
||||
import copy
|
||||
import random
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
# from here: https://github.com/Rapptz/RoboDanny/blob/18b92ae2f53927aedebc25fb5eca02c8f6d7a874/cogs/utils/time.py
|
||||
short_timedelta_regex = re.compile("""
|
||||
(?:(?P<years>[0-9]{1,8})(?:years?|y))? # e.g. 2y
|
||||
(?:(?P<months>[0-9]{1,8})(?:months?|mo))? # e.g. 2months
|
||||
(?:(?P<weeks>[0-9]{1,8})(?:weeks?|w))? # e.g. 10w
|
||||
(?:(?P<days>[0-9]{1,8})(?:days?|d))? # e.g. 14d
|
||||
(?:(?P<hours>[0-9]{1,8})(?:hours?|h))? # e.g. 12h
|
||||
(?:(?P<minutes>[0-9]{1,8})(?:minutes?|m))? # e.g. 10m
|
||||
(?:(?P<seconds>[0-9]{1,8})(?:seconds?|s))? # e.g. 15s """, re.VERBOSE)
|
||||
(?:(?P<years>[0-9]{1,12})(?:years?|y))? # e.g. 2y
|
||||
(?:(?P<months>[0-9]{1,12})(?:months?|mo))? # e.g. 2months
|
||||
(?:(?P<weeks>[0-9]{1,12})(?:weeks?|w))? # e.g. 10w
|
||||
(?:(?P<days>[0-9]{1,12})(?:days?|d))? # e.g. 14d
|
||||
(?:(?P<hours>[0-9]{1,12})(?:hours?|h))? # e.g. 12h
|
||||
(?:(?P<minutes>[0-9]{1,12})(?:minutes?|m))? # e.g. 10m
|
||||
(?:(?P<seconds>[0-9]{1,12})(?:seconds?|s))? # e.g. 15s """, re.VERBOSE)
|
||||
|
||||
def parse_short_timedelta(text):
|
||||
match = short_timedelta_regex.fullmatch(text)
|
||||
@ -70,4 +71,38 @@ async def async_exec(code, loc, glob):
|
||||
ast.fix_missing_locations(wrapper)
|
||||
|
||||
exec(compile(wrapper, "<repl>", "exec"), loc, glob)
|
||||
return await (loc.get("repl_coroutine") or glob.get("repl_coroutine"))()
|
||||
return await (loc.get("repl_coroutine") or glob.get("repl_coroutine"))()
|
||||
|
||||
# https://github.com/LyricLy/Esobot/blob/bcc9e548c84ea9b23fc832d0b0aaa8288de64886/cogs/general.py
|
||||
lyrictable_raw = {
|
||||
"a": "а",
|
||||
"c": "с",
|
||||
"e": "е",
|
||||
"s": "ѕ",
|
||||
"i": "і",
|
||||
"j": "ј",
|
||||
"o": "о",
|
||||
"p": "р",
|
||||
"y": "у",
|
||||
"x": "х"
|
||||
}
|
||||
lyrictable = str.maketrans({v: k for k, v in lyrictable_raw.items()})
|
||||
|
||||
apioprefixes = ["cryo", "meta", "chrono", "contra", "ortho", "macro", "micro"]
|
||||
apioinfixes = ["cryo", "pyro", "chrono", "meta", "anarcho", "arachno", "aqua",
|
||||
"hydro", "radio", "xeno", "morto", "thanato", "memeto", "contra", "umbra", "macrono"]
|
||||
apiosuffixes = ["hazard", "form"]
|
||||
|
||||
def apioform():
|
||||
out = ""
|
||||
if random.randint(0, 4) == 0:
|
||||
out += random.choice(apioprefixes)
|
||||
out += "apio"
|
||||
while True:
|
||||
out += random.choice(apioinfixes)
|
||||
if random.randint(0, 1) == 0: break
|
||||
out += random.choice(apiosuffixes)
|
||||
return out
|
||||
|
||||
def unlyric(text):
|
||||
return text.translate(lyrictable).replace("\u200b", "")
|
Loading…
Reference in New Issue
Block a user