parent
eb4110e1e6
commit
465e22163f
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
bot_secrets.json
|
||||||
@ -0,0 +1 @@
|
|||||||
|
351794468870946827
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"load_list": [
|
||||||
|
"admin",
|
||||||
|
"events",
|
||||||
|
"rcon",
|
||||||
|
"repl",
|
||||||
|
"patreon",
|
||||||
|
"fun",
|
||||||
|
"utils"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"rcon_enabled" : false,
|
||||||
|
"channel_lockdown" : false,
|
||||||
|
"raid_status" : 0,
|
||||||
|
"pg_filter" : true,
|
||||||
|
"patreon_enabled" : false,
|
||||||
|
"referral_enabled" : false
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"type": "service_account",
|
||||||
|
"project_id": "geeksbot-196221",
|
||||||
|
"private_key_id": "0ccc9c634c498b2dd49cd56f5436433f18b88c94",
|
||||||
|
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEOPnlmVQowNFo\nXkiEv2f7l/USSUgPcTt0nj8s3zd5D4kVgkhs0E15bVg1NdeJn+ElA7coRvLqGgF1\n+SwC7WE7t24WwYrRnC9QEMwt0fcpKJkPhdre+HQYOPOILeyhTxN3rh9x9AJAOjA1\nlokYhcnLMVpTnh7qQhvZLCJWPesInqg9WQ18yZCXDBdGzalVSDBMlt7fONtL/P9i\nffT955GQBKdRh3WW/i9oY0IuMRMMeP8EP0T2w9JgnlyhpjIlb6kGYPZfyXQ+hNfe\njpP4pdC+VxkbAfk0f9NiKDODeSCjG2z2Y8tUSVbhN6aeaFd26ZMzAG9cro3vL0dO\nafJWjX3bAgMBAAECggEAEOewY97+A1V6qmlhCbVsfHOphKNKnDCkWiuIrtF7on2Q\n+7OR5h9bZV2NxBEjmh2WPzhJjySZqKCH8AWBDK7YedVs8cnyhJTWS1QUeygZM/MQ\nSL2T+dy23SAJnyRcZsNSHoqiS+YlTCpB3Vle7f1swV7ln3RCc+qGeAMs4Xg2fQij\niqJjyl5EVUxpadyd+Nmcnfwq5Vdh+olRV+139TqNbwymip/3XNkugotQ/EqcvP3o\n4EHj//k1nCA4HvCJjcm5EJs38iT99z7OFu5VebhuUclKTHTygQ8glFbpUxXbl3xX\n81racTiytdOEzUHR8Ox2IfYQ5b2tCnMPfFuVs1DMSQKBgQDrEtfJ8Ms6MovunbO2\nobc89EnjWy/W8mpucb0MWh3gSBtKttQPHiHDZzH+FPR+fK+ZSh3ULYWY13SHPUaH\nPP1asOLUjASJiFcw5ogHx5VQc6EPLASsuyADuwt5yOllPtK4B11YTZLhgHAVsQTJ\n3A7VmYOD8TGjwgvPQdNpT8SUswKBgQDVsL8DckSJwLopkfBD1vksu+p+QyH+HoaY\nG7UDFkeabqa1A2oQBhRdBkVZuonggJVYTHhYvTflXl6m0Aj8A9PBx1KBMSp3jRZq\nRwb9euAe+zWITSpmMH+iRqiElv+pfzQ++K0u3laU4Ysybsj+Vy49endPtOnezDf5\nLNB6T3sWOQKBgQDlo7S2C8scgUB9zAVBxl0Q6Lw9pFjprEsYtXeu12IUNZyjslMa\nqZ7mGquVwLbP0dJg9yyImCfIlcG6U7vQZV5C+EW+yUGtcUlr9eixYOGWhD60aZXv\nf6XYvyKIyCJoy6RiLp+bobx5GlVke1doMtczBxKZFEgf53JN98olOM2bTQKBgA0n\nPfq2U+WuyUa5xvJGDzxjrMFs3HDJ7Dr8qZ2xB2NIIFbQCP1HgoVfV3F4e/gnsgmn\nW1kK/J/PuT/HWmY4zhYFcNym7BhDxPdxu8pqf9UoXVkwdsWngpO4ibLvoHkMbWja\n4b4azXWIlIrcKt8M+rmqCiIL3sFqDJ/31DVTIx5xAoGBANfkldD7z9nveEYwb4L3\nA6W2QK1KrSBLcQSNbw4tcKxiyirY0y5JlPy7NdjzGvfqEujGmaZ0f4yXYuN8R04D\nLM0vdlqpaHPs/dP3K+ukMpvwvqq8Keiw8ERJ7z3L+WJyT/wvx8t5Z1zT3JMbm9b/\n2Yfylx+UKh0DQezFbMzJi4Yc\n-----END PRIVATE KEY-----\n",
|
||||||
|
"client_email": "geeksbot-gsheets@geeksbot-196221.iam.gserviceaccount.com",
|
||||||
|
"client_id": "103726668019205391198",
|
||||||
|
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
"token_uri": "https://accounts.google.com/o/oauth2/token",
|
||||||
|
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||||
|
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/geeksbot-gsheets%40geeksbot-196221.iam.gserviceaccount.com"
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
shit
|
||||||
|
piss
|
||||||
|
fuck
|
||||||
|
cunt
|
||||||
|
cock
|
||||||
|
motherfucker
|
||||||
|
tits
|
||||||
|
ballsack
|
||||||
|
bangbros
|
||||||
|
bitch
|
||||||
|
blow job
|
||||||
|
blowjob
|
||||||
|
clit
|
||||||
|
f u c k
|
||||||
|
gangbang
|
||||||
|
gaylord
|
||||||
|
gaysex
|
||||||
|
god damn
|
||||||
|
goddamn
|
||||||
|
homoerotic
|
||||||
|
hotsex
|
||||||
|
jerk-off
|
||||||
|
jerk off
|
||||||
|
masturbat
|
||||||
|
porn
|
||||||
|
pussy
|
||||||
|
pussi
|
||||||
|
skank
|
||||||
|
whore
|
||||||
@ -0,0 +1 @@
|
|||||||
|
0
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
|||||||
|
{"blobsmirk": "https://discordapp.com/api/emojis/414330931059490827.png", "BlobThinking": "https://discordapp.com/api/emojis/408366351602941952.png", "BlobThinkingCool": "https://discordapp.com/api/emojis/414839939117613057.png", "BlobVote": "https://discordapp.com/api/emojis/414840024266309632.png", "BlobDead": "https://discordapp.com/api/emojis/414840075289886722.png", "BlobIdea": "https://discordapp.com/api/emojis/414840112317333544.png", "BlobOK": "https://discordapp.com/api/emojis/414840149059436544.png", "BlobNausea": "https://discordapp.com/api/emojis/414840414672125992.png", "BlobConfused": "https://discordapp.com/api/emojis/414840484377264158.png", "BlobLenny": "https://discordapp.com/api/emojis/414840707010920459.png", "BlobCrying": "https://discordapp.com/api/emojis/414841411117121556.png", "blobsad": "https://discordapp.com/api/emojis/319122469795397632.png", "blobsmile": "https://discordapp.com/api/emojis/319360049887576074.png", "blobthumbsup": "https://discordapp.com/api/emojis/324917738894000130.png", "blobcouncil": "https://discordapp.com/api/emojis/317793691257274378.png", "FeelsBlobMan": "https://discordapp.com/api/emojis/317969827861889026.png", "BlobPoliceAngry": "https://discordapp.com/api/emojis/317969829854314496.png", "OKBlob": "https://discordapp.com/api/emojis/317970202492928002.png", "blobthinking": "https://discordapp.com/api/emojis/318287662068924416.png", "photoblobs": "https://discordapp.com/api/emojis/318013782662053888.png", "bloblul": "https://discordapp.com/api/emojis/356789385875816448.png", "blobthink": "https://discordapp.com/api/emojis/318799923116113921.png", "blobangry": "https://discordapp.com/api/emojis/319359420997828608.png", "blobsob": "https://discordapp.com/api/emojis/393353541122523136.png", "blobsurprised": "https://discordapp.com/api/emojis/319359953263394817.png", "blobwink": "https://discordapp.com/api/emojis/319360115129974786.png", "blobheadache": "https://discordapp.com/api/emojis/319360532291387392.png", "blobcorner": "https://discordapp.com/api/emojis/319360584703541249.png", "blobrofl": "https://discordapp.com/api/emojis/319360614923370496.png", "blobfacepalm": "https://discordapp.com/api/emojis/319360831626412032.png", "blobdead": "https://discordapp.com/api/emojis/319361012908163072.png", "blobshh": "https://discordapp.com/api/emojis/324917371259060224.png", "blobhammer": "https://discordapp.com/api/emojis/324917546098622466.png", "blobhappy": "https://discordapp.com/api/emojis/324917905257136128.png", "blobexpressionless": "https://discordapp.com/api/emojis/324918006331473923.png", "blobokhand": "https://discordapp.com/api/emojis/324918192763961344.png", "blobwhat": "https://discordapp.com/api/emojis/324918397643128832.png", "blobpat": "https://discordapp.com/api/emojis/324918615994531840.png", "blobpopcorn": "https://discordapp.com/api/emojis/324918859540856832.png", "blobblush": "https://discordapp.com/api/emojis/324918940256174089.png", "blobstraightface": "https://discordapp.com/api/emojis/324919073903476766.png", "blobhifive": "https://discordapp.com/api/emojis/324919278845427713.png", "sadblob": "https://discordapp.com/api/emojis/414017193890545685.png", "blob": "https://discordapp.com/api/emojis/401869697588527105.png"}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,269 @@
|
|||||||
|
import discord
|
||||||
|
from discord.ext import commands
|
||||||
|
import json
|
||||||
|
from srcds import rcon as rcon_con
|
||||||
|
import time, logging, math
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
import asyncio, inspect
|
||||||
|
import aiohttp, async_timeout
|
||||||
|
from bs4 import BeautifulSoup as bs
|
||||||
|
import traceback
|
||||||
|
import os, sys
|
||||||
|
from .imports import checks
|
||||||
|
|
||||||
|
config_dir = 'config/'
|
||||||
|
admin_id_file = 'admin_ids'
|
||||||
|
extension_dir = 'extensions'
|
||||||
|
owner_id = 351794468870946827
|
||||||
|
embed_color = discord.Colour.from_rgb(49,107,111)
|
||||||
|
bot_config_file = 'bot_config.json'
|
||||||
|
invite_match = '(https?://)?(www.)?discord(app.com/(invite|oauth2)|.gg|.io)/[\w\d_\-?=&/]+'
|
||||||
|
|
||||||
|
admin_log = logging.getLogger('admin')
|
||||||
|
|
||||||
|
class admin():
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
def _get_config_string(self, guild_config):
|
||||||
|
config_str = ''
|
||||||
|
for config in guild_config:
|
||||||
|
if isinstance(guild_config[config], dict):
|
||||||
|
config_str = f'{config_str}\n{" "*4}{config}'
|
||||||
|
for item in guild_config[config]:
|
||||||
|
config_str = f'{config_str}\n{" "*8}{item}: {guild_config[config][item]}'
|
||||||
|
elif isinstance(guild_config[config], list):
|
||||||
|
config_str = f'{config_str}\n{" "*4}{config}'
|
||||||
|
for item in guild_config[config]:
|
||||||
|
config_str = f'{config_str}\n{" "*8}{item}'
|
||||||
|
else:
|
||||||
|
config_str = f'{config_str}\n{" "*4}{config}: {guild_config[config]}'
|
||||||
|
return config_str
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def reload_bot_config(self, ctx):
|
||||||
|
with open(f'{config_dir}{bot_config_file}') as file:
|
||||||
|
self.bot.bot_config = json.load(file)
|
||||||
|
del self.bot.bot_config['token']
|
||||||
|
del self.bot.bot_config['db_con']
|
||||||
|
await ctx.send('Config reloaded.')
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def reboot(self, ctx):
|
||||||
|
await ctx.send('Geeksbot is restarting.')
|
||||||
|
with open(f'{config_dir}reboot', 'w') as f:
|
||||||
|
f.write(f'1\n{ctx.channel.id}')
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def get_bot_config(self, ctx):
|
||||||
|
n = 2000
|
||||||
|
config = [str(self.bot.bot_config)[i:i+n] for i in range(0, len(str(self.bot.bot_config)), n)]
|
||||||
|
for conf in config:
|
||||||
|
await ctx.message.author.send(conf)
|
||||||
|
await ctx.send(f'{ctx.message.author.mention} check your DMs.')
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def update_emojis(self, ctx):
|
||||||
|
emojis = self.bot.emojis
|
||||||
|
for emoji in emojis:
|
||||||
|
if emoji.animated:
|
||||||
|
emoji_code = f'<a:{emoji.name}:{emoji.id}>'
|
||||||
|
else:
|
||||||
|
emoji_code = f'<:{emoji.name}:{emoji.id}>'
|
||||||
|
if self.bot.con.all(f'select id from geeksbot_emojis where id = %(id)s', {'id':emoji.id}):
|
||||||
|
self.bot.con.run(f"update geeksbot_emojis set id = %(id)s, name = %(name)s, code = %(emoji_code)s where name = %(name)s", {'name':emoji.name,'id':emoji.id,'emoji_code':emoji_code})
|
||||||
|
else:
|
||||||
|
self.bot.con.run(f"insert into geeksbot_emojis(id,name,code) values (%(id)s,%(name)s,%(emoji_code)s)", {'name':emoji.name,'id':emoji.id,'emoji_code':emoji_code})
|
||||||
|
await ctx.message.add_reaction('✅')
|
||||||
|
await ctx.send(f'Emojis have been updated in the database.')
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.check(checks.is_guild_owner)
|
||||||
|
async def get_guild_config(self, ctx):
|
||||||
|
config = self.bot.con.one(f'select * from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
configs = [str(config)[i:i+1990] for i in range(0, len(config), 1990)]
|
||||||
|
await ctx.message.author.send(f'The current config for the {ctx.guild.name} guild is:\n')
|
||||||
|
admin_log.info(configs)
|
||||||
|
for config in configs:
|
||||||
|
await ctx.message.author.send(f'```{config}```')
|
||||||
|
await ctx.send(f'{ctx.message.author.mention} check your DMs.')
|
||||||
|
|
||||||
|
@commands.group(case_insensitive=True)
|
||||||
|
async def set(self, ctx):
|
||||||
|
'''Run help set for more info'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
@commands.group(case_insensitive=True)
|
||||||
|
async def add(self, ctx):
|
||||||
|
'''Run help set for more info'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
@commands.group(case_insensitive=True)
|
||||||
|
async def remove(self, ctx):
|
||||||
|
'''Run help set for more info'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
@set.command(name='admin_chan', aliases=['ac', 'admin_chat', 'admin chat'])
|
||||||
|
async def _admin_channel(self, ctx, channel:discord.TextChannel=None):
|
||||||
|
if ctx.guild:
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
if channel != None:
|
||||||
|
self.bot.con.run(f'update guild_config set admin_chat = %(chan)s where guild_id = {ctx.guild.id}', {'chan': channel.id})
|
||||||
|
await ctx.send(f'{channel.name} is now set as the Admin Chat channel for this guild.')
|
||||||
|
|
||||||
|
@set.command(name='channel_lockdown', aliases=['lockdown', 'restrict_access', 'cl'])
|
||||||
|
async def _channel_lockdown(self, ctx, config='true'):
|
||||||
|
if ctx.guild:
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
if str(config).lower() == 'true':
|
||||||
|
if self.bot.con.one(f'select allowed_channels from guild_config where guild_id = {ctx.guild.id}') == []:
|
||||||
|
await ctx.send('Please set at least one allowed channel before running this command.')
|
||||||
|
else:
|
||||||
|
self.bot.con.run(f'update guild_config set channel_lockdown = True where guild_id = {ctx.guild.id}')
|
||||||
|
await ctx.send('Channel Lockdown is now active.')
|
||||||
|
elif str(config).lower() == 'false':
|
||||||
|
if self.bot.con.one(f'select channel_lockdown from guild_config where guild_id = {ctx.guild.id}'):
|
||||||
|
self.bot.con.run(f'update guild_config set channel_lockdown = False where guild_id = {ctx.guild.id}')
|
||||||
|
await ctx.send('Channel Lockdown has been deactivated.')
|
||||||
|
else:
|
||||||
|
await ctx.send('Channel Lockdown is already deactivated.')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'You are not authorized to run this command.')
|
||||||
|
else:
|
||||||
|
await ctx.send('This command must be run from inside a guild.')
|
||||||
|
|
||||||
|
|
||||||
|
@add.command(name='allowed_channels', aliases=['channel','ac'])
|
||||||
|
async def _allowed_channels(self, ctx, *, channels):
|
||||||
|
if ctx.guild:
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
channels = channels.lower().replace(' ','').split(',')
|
||||||
|
added = ''
|
||||||
|
for channel in channels:
|
||||||
|
chnl = discord.utils.get(ctx.guild.channels, name=channel)
|
||||||
|
if chnl == None:
|
||||||
|
await ctx.send(f'{channel} is not a valid text channel in this guild.')
|
||||||
|
else:
|
||||||
|
admin_log.info('Chan found')
|
||||||
|
if self.bot.con.one(f'select allowed_channels from guild_config where guild_id = {ctx.guild.id}'):
|
||||||
|
if chnl.id in json.loads(self.bot.con.one(f'select allowed_channels from guild_config where guild_id = {ctx.guild.id}')):
|
||||||
|
admin_log.info('Chan found in config')
|
||||||
|
await ctx.send(f'{channel} is already in the list of allowed channels. Skipping...')
|
||||||
|
else:
|
||||||
|
admin_log.info('Chan not found in config')
|
||||||
|
allowed_channels = json.loads(self.bot.con.one(f'select allowed_channels from guild_config where guild_id = {ctx.guild.id}')).append(chnl.id)
|
||||||
|
self.bot.con.run(f"update guild_config set allowed_channels = %(channels)s where guild_id = {ctx.guild.id}", {'channels':allowed_channels})
|
||||||
|
added = f'{added}\n{channel}'
|
||||||
|
else:
|
||||||
|
admin_log.info('Chan not found in config')
|
||||||
|
allowed_channels = [chnl.id]
|
||||||
|
self.bot.con.run(f"update guild_config set allowed_channels = %(channels)s where guild_id = {ctx.guild.id}", {'channels':allowed_channels})
|
||||||
|
added = f'{added}\n{channel}'
|
||||||
|
if added != '':
|
||||||
|
await ctx.send(f'The following channels have been added to the allowed channel list: {added}')
|
||||||
|
await ctx.message.add_reaction('✅')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'You are not authorized to run this command.')
|
||||||
|
else:
|
||||||
|
await ctx.send('This command must be run from inside a guild.')
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@commands.is_owner()
|
||||||
|
async def view_code(self, ctx, code_name):
|
||||||
|
await ctx.send(f"```py\n{inspect.getsource(self.bot.get_command(code_name).callback)}\n```")
|
||||||
|
|
||||||
|
@add.command(aliases=['prefix','p'])
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
|
async def add_prefix(self, ctx, *, prefix=None):
|
||||||
|
if ctx.guild:
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
prefixes = self.bot.con.one(f'select prefix from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
if prefix == None:
|
||||||
|
await ctx.send(prefixes)
|
||||||
|
return
|
||||||
|
elif prefixes == None:
|
||||||
|
prefixes = prefix.replace(' ',',').split(',')
|
||||||
|
else:
|
||||||
|
for p in prefix.replace(' ',',').split(','):
|
||||||
|
prefixes.append(p)
|
||||||
|
if len(prefixes) > 10:
|
||||||
|
await ctx.send(f'Only 10 prefixes are allowed per guild.\nPlease remove some before adding more.')
|
||||||
|
prefixes = prefixes[:10]
|
||||||
|
self.bot.con.run(f"update guild_config set prefix = %(prefixes)s where guild_id = {ctx.guild.id}", {'prefixes':prefixes})
|
||||||
|
await ctx.guild.me.edit(nick=f'[{prefixes[0]}] Geeksbot')
|
||||||
|
await ctx.send(f"Updated. You currently have {len(prefixes)} {'prefix' if len(prefixes) == 1 else 'prefixes'} in your config.\n{', '.join(prefixes)}")
|
||||||
|
else:
|
||||||
|
await ctx.send(f'You are not authorized to run this command.')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'This command must be run from inside a guild.')
|
||||||
|
|
||||||
|
@remove.command(aliases=['prefix','p'])
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
|
async def remove_prefix(self, ctx, *, prefix=None):
|
||||||
|
if ctx.guild:
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
prefixes = []
|
||||||
|
prefixes = self.bot.con.one(f'select prefix from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
found = 0
|
||||||
|
if prefix == None:
|
||||||
|
await ctx.send(prefixes)
|
||||||
|
return
|
||||||
|
elif prefixes == None or prefixes == []:
|
||||||
|
await ctx.send('There are no custom prefixes setup for this guild.')
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
prefix = prefix.replace(' ',',').split(',')
|
||||||
|
for p in prefix:
|
||||||
|
if p in prefixes:
|
||||||
|
prefixes.remove(p)
|
||||||
|
found = 1
|
||||||
|
else:
|
||||||
|
await ctx.send(f'The prefix {p} is not in the config for this guild.')
|
||||||
|
if found:
|
||||||
|
self.bot.con.run(f"update guild_config set prefix = %(prefixes)s where guild_id = {ctx.guild.id}", {'prefixes':prefixes})
|
||||||
|
await ctx.guild.me.edit(nick=f'[{prefixes[0] if len(prefixes) != 0 else self.bot.default_prefix}] Geeksbot')
|
||||||
|
await ctx.send(f"Updated. You currently have {len(prefixes)} {'prefix' if len(prefixes) == 1 else 'prefixes'} in your config.\n{', '.join(prefixes)}")
|
||||||
|
else:
|
||||||
|
await ctx.send(f'You are not authorized to run this command.')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'This command must be run from inside a guild.')
|
||||||
|
|
||||||
|
@add.command(name='admin_role', aliases=['admin'])
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
|
@commands.check(checks.is_guild_owner)
|
||||||
|
async def _add_admin_role(self, ctx, role=None):
|
||||||
|
role = discord.utils.get(ctx.guild.roles, name=role)
|
||||||
|
if role != None:
|
||||||
|
roles = json.loads(self.bot.con.one(f'select admin_roles from guild_config where guild_id = {ctx.guild.id}'))
|
||||||
|
if role.name in roles:
|
||||||
|
await ctx.send(f'{role.name} is already registered as an admin role in this guild.')
|
||||||
|
else:
|
||||||
|
roles[role.name] = role.id
|
||||||
|
self.bot.con.run(f"update guild_config set admin_roles = %(roles)s where guild_id = {ctx.guild.id}", {'roles':json.dumps(roles)})
|
||||||
|
await ctx.send(f'{role.name} has been added to the list of admin roles for this guild.')
|
||||||
|
else:
|
||||||
|
await ctx.send('You must include a role with this command.')
|
||||||
|
|
||||||
|
@remove.command(name='admin_role', aliases=['admin'])
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
|
@commands.check(checks.is_guild_owner)
|
||||||
|
async def _remove_admin_role(self, ctx, role=None):
|
||||||
|
role = discord.utils.get(ctx.guild.roles, name=role)
|
||||||
|
if role != None:
|
||||||
|
roles = json.loads(self.bot.con.one(f'select admin_roles from guild_config where guild_id = {ctx.guild.id}'))
|
||||||
|
if role.name in roles:
|
||||||
|
del roles[role.name]
|
||||||
|
self.bot.con.run(f"update guild_config set admin_roles = %(roles)s where guild_id = {ctx.guild.id}", {'roles':roles})
|
||||||
|
await ctx.send(f'{role.name} has been removed from the list of admin roles for this guild.')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'{role.name} is not registered as an admin role in this guild.')
|
||||||
|
else:
|
||||||
|
await ctx.send('You must include a role with this command.')
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(admin(bot))
|
||||||
@ -0,0 +1,143 @@
|
|||||||
|
import discord
|
||||||
|
from discord.ext import commands
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
import json, asyncio
|
||||||
|
import os, re, aiohttp, async_timeout
|
||||||
|
|
||||||
|
config_dir = 'config/'
|
||||||
|
admin_id_file = 'admin_ids'
|
||||||
|
extension_dir = 'extensions'
|
||||||
|
owner_id = 351794468870946827
|
||||||
|
guild_config_dir = 'guild_config/'
|
||||||
|
rcon_config_file = 'server_rcon_config'
|
||||||
|
dododex_url = 'http://www.dododex.com'
|
||||||
|
embed_color = discord.Colour.from_rgb(49,107,111)
|
||||||
|
bot_config_file = 'bot_config'
|
||||||
|
default_guild_config_file = 'default_guild_config.json'
|
||||||
|
emoji_guild = 408524303164899338
|
||||||
|
|
||||||
|
events_log = logging.getLogger('events')
|
||||||
|
|
||||||
|
emojis = {
|
||||||
|
'x': '❌',
|
||||||
|
'y': '✅',
|
||||||
|
'poop': '💩'
|
||||||
|
}
|
||||||
|
|
||||||
|
class fun():
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@commands.cooldown(1, 30, type=commands.BucketType.user)
|
||||||
|
async def infect(self, ctx, member:discord.Member, emoji):
|
||||||
|
if member.id == self.bot.user.id and ctx.author.id != owner_id:
|
||||||
|
await ctx.send(f'You rolled a Critical Fail...\nInfection bounces off and rebounds on the attacker.')
|
||||||
|
member = ctx.author
|
||||||
|
if member in self.bot.infected:
|
||||||
|
await ctx.send(f'{member.display_name} is already infected. Please wait until they are healed before infecting them again...')
|
||||||
|
else:
|
||||||
|
emoji = self.bot.get_emoji(int(emoji.split(':')[2].strip('>'))) if '<:' in emoji or '<a:' in emoji else emoji
|
||||||
|
self.bot.infected[member] = [emoji,datetime.now().timestamp()]
|
||||||
|
await ctx.send(f"{member.display_name} has been infected with {emoji}")
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
||||||
|
async def heal(self, ctx, member:discord.Member):
|
||||||
|
if ctx.author == member and ctx.author.id != owner_id:
|
||||||
|
await ctx.send('You can\'t heal yourself silly...')
|
||||||
|
else:
|
||||||
|
if member in self.bot.infected:
|
||||||
|
del self.bot.infected[member]
|
||||||
|
await ctx.send(f'{member.mention} You have been healed by {ctx.author.display_name}.')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'{member.display_name} is not infected...')
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@commands.is_owner()
|
||||||
|
async def print_infections(self, ctx):
|
||||||
|
await ctx.author.send(f'```{self.bot.infected}```')
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
||||||
|
async def slap(self, ctx, member:discord.Member):
|
||||||
|
if member.id == self.bot.user.id and ctx.author.id != owner_id:
|
||||||
|
await ctx.send(f'You rolled a Critical Fail...\nThe trout bounces off and rebounds on the attacker.')
|
||||||
|
member = ctx.author
|
||||||
|
await ctx.send(f'{ctx.author.mention} You slap yourself in the face with a large trout <:trout:408543365085397013>')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'{ctx.author.display_name} slaps {member.mention} around a bit with a large trout <:trout:408543365085397013>')
|
||||||
|
|
||||||
|
def get_factorial(self,number):
|
||||||
|
a = 1
|
||||||
|
for i in range(1,int(number)):
|
||||||
|
a = a * (i + 1)
|
||||||
|
return a
|
||||||
|
|
||||||
|
# @commands.command()
|
||||||
|
# @commands.cooldown(1, 5, type=commands.BucketType.user)
|
||||||
|
# async def fact(self, ctx, number:int):
|
||||||
|
# if number < 20001 and number > 0:
|
||||||
|
# n = 1990
|
||||||
|
# with ctx.channel.typing():
|
||||||
|
# a = await self.bot.loop.run_in_executor(None, self.get_factorial, number)
|
||||||
|
# if len(str(a)) > 6000:
|
||||||
|
# for b in [str(a)[i:i+n] for i in range(0, len(str(a)), n)]:
|
||||||
|
# await ctx.author.send(f'```py\n{b}```')
|
||||||
|
# await ctx.send(f"{ctx.author.mention} Check your DMs.")
|
||||||
|
# else:
|
||||||
|
# for b in [str(a)[i:i+n] for i in range(0, len(str(a)), n)]:
|
||||||
|
# await ctx.send(f'```py\n{b}```')
|
||||||
|
# else:
|
||||||
|
# await ctx.send("Invalid number. Please enter a number between 0 and 20,000")
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def play(self, ctx, url=None):
|
||||||
|
if ctx.author.voice.channel.name in self.bot.voice_chans:
|
||||||
|
if self.bot.voice_chans[ctx.author.voice.channel.name].is_playing():
|
||||||
|
await ctx.send('There is currently a song playing. Please wait until it is done...')
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.bot.voice_chans[ctx.author.voice.channel.name] = await ctx.author.voice.channel.connect()
|
||||||
|
asyncio.sleep(5)
|
||||||
|
if url:
|
||||||
|
import youtube_dl
|
||||||
|
opts = {"format": 'webm[abr>0]/bestaudio/best',"ignoreerrors": True,"default_search": "auto","source_address": "0.0.0.0",'quiet': True}
|
||||||
|
ydl = youtube_dl.YoutubeDL(opts)
|
||||||
|
info = ydl.extract_info(url, download=False)
|
||||||
|
self.bot.player = discord.FFmpegPCMAudio(info['url'])
|
||||||
|
else:
|
||||||
|
self.bot.player = discord.FFmpegPCMAudio('dead_puppies.mp3')
|
||||||
|
self.bot.player = discord.PCMVolumeTransformer(self.bot.player, volume=0.3)
|
||||||
|
self.bot.voice_chans[ctx.author.voice.channel.name].play(self.bot.player)
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def stop(self, ctx):
|
||||||
|
if ctx.author.voice.channel.name in self.bot.voice_chans:
|
||||||
|
if self.bot.voice_chans[ctx.author.voice.channel.name].is_playing():
|
||||||
|
self.bot.voice_chans[ctx.author.voice.channel.name].stop()
|
||||||
|
else:
|
||||||
|
await ctx.send('Nothing is playing...')
|
||||||
|
else:
|
||||||
|
await ctx.send('Not connected to that voice channel.')
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def disconnect(self, ctx):
|
||||||
|
if ctx.author.voice.channel.name in self.bot.voice_chans:
|
||||||
|
await self.bot.voice_chans[ctx.author.voice.channel.name].disconnect()
|
||||||
|
del self.bot.voice_chans[ctx.author.voice.channel.name]
|
||||||
|
else:
|
||||||
|
await ctx.send('Not connected to that voice channel.')
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def volume(self, ctx, volume:float):
|
||||||
|
self.bot.player.volume = volume
|
||||||
|
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(fun(bot))
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,64 @@
|
|||||||
|
import discord, json, asyncio
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
owner_id = 351794468870946827
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def check_admin_role(bot, ctx, member):
|
||||||
|
admin_roles = json.loads(bot.con.one(f"select admin_roles from guild_config where guild_id = {ctx.guild.id}"))
|
||||||
|
for role in admin_roles:
|
||||||
|
if discord.utils.get(ctx.guild.roles, id=admin_roles[role]) in member.roles:
|
||||||
|
return True
|
||||||
|
return member.id == ctx.guild.owner.id or member.id == owner_id
|
||||||
|
|
||||||
|
def check_rcon_role(bot, ctx, member):
|
||||||
|
rcon_admin_roles = json.loads(bot.con.one(f"select rcon_admin_roles from guild_config where guild_id = {ctx.guild.id}"))
|
||||||
|
for role in rcon_admin_roles:
|
||||||
|
if discord.utils.get(ctx.guild.roles, id=rcon_admin_roles[role]) in member.roles:
|
||||||
|
return True
|
||||||
|
return member.id == ctx.guild.owner.id or member.id == owner_id
|
||||||
|
|
||||||
|
def is_admin(bot, ctx):
|
||||||
|
admin_roles = json.loads(bot.con.one(f"select admin_roles from guild_config where guild_id = {ctx.guild.id}"))
|
||||||
|
for role in admin_roles:
|
||||||
|
if discord.utils.get(ctx.guild.roles, id=admin_roles[role]) in ctx.message.author.roles:
|
||||||
|
return True
|
||||||
|
return ctx.message.author.id == ctx.guild.owner.id or ctx.message.author.id == owner_id
|
||||||
|
|
||||||
|
def is_guild_owner(ctx):
|
||||||
|
if ctx.guild:
|
||||||
|
return ctx.message.author.id == ctx.guild.owner.id or ctx.message.author.id == owner_id
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_rcon_admin(bot, ctx):
|
||||||
|
rcon_admin_roles = json.loads(bot.con.one(f"select rcon_admin_roles from guild_config where guild_id = {ctx.guild.id}"))
|
||||||
|
for role in rcon_admin_roles:
|
||||||
|
if discord.utils.get(ctx.guild.roles, id=rcon_admin_roles[role]) in ctx.message.author.roles:
|
||||||
|
return True
|
||||||
|
return ctx.message.author.id == ctx.guild.owner.id or ctx.message.author.id == owner_id
|
||||||
|
|
||||||
|
def is_restricted_chan(ctx):
|
||||||
|
if ctx.guild:
|
||||||
|
if ctx.channel.overwrites_for(ctx.guild.default_role).read_messages == False:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def is_spam(bot, ctx):
|
||||||
|
max_rep = 5
|
||||||
|
rep_time = 20
|
||||||
|
spam_rep = 5
|
||||||
|
spam_time = 3
|
||||||
|
spam_check = 0
|
||||||
|
msg_check = 0
|
||||||
|
for msg in bot.recent_msgs[ctx.guild.id]:
|
||||||
|
if msg['author'] == ctx.author:
|
||||||
|
if msg['time'] > ctx.message.created_at.timestamp() - spam_time:
|
||||||
|
spam_check += 1
|
||||||
|
if msg['content'].lower() == ctx.content.lower() and msg['time'] > ctx.message.created_at.timestamp() - rep_time:
|
||||||
|
msg_check += 1
|
||||||
|
if spam_check == spam_rep - 1 or msg_check == max_rep - 1:
|
||||||
|
await utils.mute(bot, ctx, admin=1, member=ctx.author.id)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
from io import StringIO
|
||||||
|
import sys, asyncio
|
||||||
|
from discord.ext.commands.formatter import Paginator
|
||||||
|
from . import checks
|
||||||
|
|
||||||
|
|
||||||
|
class Capturing(list):
|
||||||
|
def __enter__(self):
|
||||||
|
self._stdout = sys.stdout
|
||||||
|
sys.stdout = self._stringio = StringIO()
|
||||||
|
return self
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.extend(self._stringio.getvalue().splitlines())
|
||||||
|
del self._stringio # free up some memory
|
||||||
|
sys.stdout = self._stdout
|
||||||
|
|
||||||
|
async def mute(bot, ctx, admin=0, member_id=None):
|
||||||
|
mute_role = self.bot.con.one(f'select muted_role from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
if muted_role:
|
||||||
|
if admin or checks.is_admin(bot, ctx):
|
||||||
|
if ctx.guild.me.guild_permissions.manage_roles:
|
||||||
|
if member:
|
||||||
|
ctx.guild.get_member(member_id).edit(roles=[discord.utils.get(ctx.guild.roles, id=mute_role)])
|
||||||
|
|
||||||
|
def to_list_of_str(items, out:list=[], level=1, recurse=0):
|
||||||
|
def rec_loop(item, key, out, level):
|
||||||
|
quote = '"'
|
||||||
|
if type(item) == list:
|
||||||
|
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}[')
|
||||||
|
new_level = level + 1
|
||||||
|
out = to_list_of_str(item, out, new_level, 1)
|
||||||
|
out.append(f'{" "*level}]')
|
||||||
|
elif type(item) == dict:
|
||||||
|
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{{')
|
||||||
|
new_level = level + 1
|
||||||
|
out = to_list_of_str(item, out, new_level, 1)
|
||||||
|
out.append(f'{" "*level}}}')
|
||||||
|
else:
|
||||||
|
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{repr(item)},')
|
||||||
|
|
||||||
|
if type(items) == list:
|
||||||
|
if not recurse:
|
||||||
|
out = []
|
||||||
|
out.append('[')
|
||||||
|
for item in items:
|
||||||
|
rec_loop(item, None, out, level)
|
||||||
|
if not recurse:
|
||||||
|
out.append(']')
|
||||||
|
elif type(items) == dict:
|
||||||
|
if not recurse:
|
||||||
|
out = []
|
||||||
|
out.append('{')
|
||||||
|
for key in items:
|
||||||
|
rec_loop(items[key], key, out, level)
|
||||||
|
if not recurse:
|
||||||
|
out.append('}')
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
def paginate(text):
|
||||||
|
data = []
|
||||||
|
paginator = Paginator(prefix='```py')
|
||||||
|
if type(text) == list:
|
||||||
|
data = to_list_of_str(text)
|
||||||
|
elif type(text) == dict:
|
||||||
|
data = to_list_of_str(text)
|
||||||
|
else:
|
||||||
|
data = str(text).split('\n')
|
||||||
|
for line in data:
|
||||||
|
if len(line) > 1900:
|
||||||
|
n = 1900
|
||||||
|
for l in [line[i:i+n] for i in range(0, len(line), n)]:
|
||||||
|
paginator.add_line(l)
|
||||||
|
else:
|
||||||
|
paginator.add_line(line)
|
||||||
|
return paginator.pages
|
||||||
|
|
||||||
|
async def run_command(*args):
|
||||||
|
# Create subprocess
|
||||||
|
process = await asyncio.create_subprocess_exec(
|
||||||
|
*args,
|
||||||
|
# stdout must a pipe to be accessible as process.stdout
|
||||||
|
stdout=asyncio.subprocess.PIPE)
|
||||||
|
# Wait for the subprocess to finish
|
||||||
|
stdout, stderr = await process.communicate()
|
||||||
|
# Return stdout
|
||||||
|
return stdout.decode().strip()
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
import discord
|
||||||
|
from discord.ext import commands
|
||||||
|
import json
|
||||||
|
from .imports import checks
|
||||||
|
|
||||||
|
config_dir = 'config'
|
||||||
|
extension_dir = 'extensions'
|
||||||
|
owner_id = 351794468870946827
|
||||||
|
|
||||||
|
class patreon():
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
|
||||||
|
@commands.command(aliases=['get_patreon','patreon'])
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
||||||
|
async def get_patreon_links(self, ctx, target: discord.Member=None):
|
||||||
|
'Prints Patreon information for creators on the server.'
|
||||||
|
if self.bot.con.one(f'select patreon_enabled from guild_config where guild_id = {ctx.guild.id}'):
|
||||||
|
patreon_info = self.bot.con.one(f'select patreon_message,patreon_links from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
message = patreon_info[0].replace('\\n','\n')
|
||||||
|
patreon_links = json.loads(patreon_info[1])
|
||||||
|
for key in patreon_links:
|
||||||
|
message = message + '\n{0}: {1}'.format(key, patreon_links[key])
|
||||||
|
if target == None:
|
||||||
|
await ctx.send(message)
|
||||||
|
else:
|
||||||
|
await ctx.send('{0}\n{1}'.format(target.mention, message))
|
||||||
|
else:
|
||||||
|
await ctx.send('Patreon links are not enabled on this guild.')
|
||||||
|
|
||||||
|
@commands.command(aliases=['patreon_message'])
|
||||||
|
async def set_patreon_message(self, ctx, message):
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
patreon_message = self.bot.con.one(f'select patreon_message from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
if message == patreon_message:
|
||||||
|
await ctx.send('That is already the current message for this guild.')
|
||||||
|
else:
|
||||||
|
self.bot.con.run(f'update guild_config set patreon_message = %(message)s where guild_id = {ctx.guild.id}', {'message': message})
|
||||||
|
await ctx.send(f'The patreon message for this guild has been set to:\n{message}')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'You are not authorized to run this command.')
|
||||||
|
|
||||||
|
@commands.command(aliases=['add_patreon', 'set_patreon'])
|
||||||
|
async def add_patreon_info(self, ctx, name, url):
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
patreon_info = self.bot.con.one(f'select patreon_links from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
patreon_links = {}
|
||||||
|
update = 0
|
||||||
|
if patreon_info:
|
||||||
|
patreon_links = json.loads(patreon_info)
|
||||||
|
if name in patreon_links:
|
||||||
|
update = 1
|
||||||
|
patreon_links[name] = url
|
||||||
|
self.bot.con.run(f'update guild_config set patreon_links = %(links)s where guild_id = {ctx.guild.id}', {'links': json.dumps(patreon_links)})
|
||||||
|
await ctx.send(f"The Patreon link for {name} has been {'updated to the new url.' if update else'added to the config for this guild.'}")
|
||||||
|
else:
|
||||||
|
await ctx.send(f'You are not authorized to run this command.')
|
||||||
|
|
||||||
|
@commands.command(aliases=['remove_patreon'])
|
||||||
|
async def remove_patreon_info(self, ctx, name):
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
patreon_info = self.bot.con.one(f'select patreon_links from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
patreon_links = {}
|
||||||
|
if patreon_info:
|
||||||
|
patreon_links = json.loads(patreon_info)
|
||||||
|
if name in patreon_links:
|
||||||
|
del patreon_links[name]
|
||||||
|
self.bot.con.run(f'update guild_config set patreon_links = %(links)s where guild_id = {ctx.guild.id}', {'links': json.dumps(patreon_links)})
|
||||||
|
await ctx.send(f'The Patreon link for {name} has been removed from the config for this guild.')
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
await ctx.send(f'{name} is not in the Patreon config for this guild.')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'There is no Patreon config for this guild.')
|
||||||
|
else:
|
||||||
|
await ctx.send(f'You are not authorized to run this command.')
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def enable_patreon(self, ctx, state:bool=True):
|
||||||
|
if checks.is_admin(self.bot, ctx):
|
||||||
|
patreon_status = self.bot.con.one(f'select patreon_enabled from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
if patreon_status and state:
|
||||||
|
await ctx.send('Patreon is already enabled for this guild.')
|
||||||
|
elif patreon_status and not state:
|
||||||
|
self.bot.con.run(f'update guild_config set patreon_enabled = %(state)s where guild_id = {ctx.guild.id}', {'state': state})
|
||||||
|
await ctx.send('Patreon has been disabled for this guild.')
|
||||||
|
elif not patreon_status and state:
|
||||||
|
self.bot.con.run(f'update guild_config set patreon_enabled = %(state)s where guild_id = {ctx.guild.id}', {'state': state})
|
||||||
|
await ctx.send('Patreon has been enabled for this guild.')
|
||||||
|
elif not patreon_status and not state:
|
||||||
|
await ctx.send('Patreon is already disabled for this guild.')
|
||||||
|
|
||||||
|
@commands.command(aliases=['referral','ref'])
|
||||||
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
||||||
|
async def referral_links(self, ctx, target: discord.Member=None):
|
||||||
|
'Prints G-Portal Referral Links.'
|
||||||
|
if self.bot.con.one(f'select referral_enabled from guild_config where guild_id = {ctx.guild.id}'):
|
||||||
|
referral_info = self.bot.con.one(f'select referral_message,referral_links from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
message = referral_info[0]
|
||||||
|
referral_links = json.loads(referral_info[1])
|
||||||
|
for key in referral_links:
|
||||||
|
message = message + '\n{0}: {1}'.format(key, referral_links[key])
|
||||||
|
if target == None:
|
||||||
|
await ctx.send(message)
|
||||||
|
else:
|
||||||
|
await ctx.send('{0}\n{1}'.format(target.mention, message))
|
||||||
|
else:
|
||||||
|
await ctx.send('Referrals are not enabled on this guild.')
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(patreon(bot))
|
||||||
@ -0,0 +1,175 @@
|
|||||||
|
|
||||||
|
from discord.ext import commands
|
||||||
|
import time
|
||||||
|
import datetime
|
||||||
|
import math
|
||||||
|
import asyncio
|
||||||
|
import traceback
|
||||||
|
import discord
|
||||||
|
import inspect
|
||||||
|
import textwrap
|
||||||
|
from contextlib import redirect_stdout
|
||||||
|
import io
|
||||||
|
import os, sys
|
||||||
|
import subprocess
|
||||||
|
import async_timeout
|
||||||
|
from .imports.utils import paginate, run_command
|
||||||
|
|
||||||
|
ownerids = [351794468870946827,275280442884751360]
|
||||||
|
ownerid = 351794468870946827
|
||||||
|
|
||||||
|
class REPL():
|
||||||
|
|
||||||
|
def __init__(self, bot):
|
||||||
|
self.bot = bot
|
||||||
|
self._last_result = None
|
||||||
|
self.sessions = set()
|
||||||
|
|
||||||
|
def cleanup_code(self, content):
|
||||||
|
'Automatically removes code blocks from the code.'
|
||||||
|
if content.startswith('```') and content.endswith('```'):
|
||||||
|
return '\n'.join(content.split('\n')[1:(- 1)])
|
||||||
|
return content.strip('` \n')
|
||||||
|
|
||||||
|
def get_syntax_error(self, e):
|
||||||
|
if e.text is None:
|
||||||
|
return '```py\n{0.__class__.__name__}: {0}\n```'.format(e)
|
||||||
|
return '```py\n{0.text}{1:>{0.offset}}\n{2}: {0}```'.format(e, '^', type(e).__name__)
|
||||||
|
|
||||||
|
@commands.command(hidden=True, name='exec')
|
||||||
|
async def _eval(self, ctx, *, body: str):
|
||||||
|
if ctx.author.id != ownerid:
|
||||||
|
return
|
||||||
|
env = {
|
||||||
|
'bot': self.bot,
|
||||||
|
'ctx': ctx,
|
||||||
|
'channel': ctx.channel,
|
||||||
|
'author': ctx.author,
|
||||||
|
'server': ctx.guild,
|
||||||
|
'message': ctx.message,
|
||||||
|
'_': self._last_result,
|
||||||
|
}
|
||||||
|
env.update(globals())
|
||||||
|
body = self.cleanup_code(body)
|
||||||
|
stdout = io.StringIO()
|
||||||
|
to_compile = 'async def func():\n%s' % textwrap.indent(body, ' ')
|
||||||
|
try:
|
||||||
|
exec(to_compile, env)
|
||||||
|
except SyntaxError as e:
|
||||||
|
return await ctx.send(self.get_syntax_error(e))
|
||||||
|
func = env['func']
|
||||||
|
try:
|
||||||
|
with redirect_stdout(stdout):
|
||||||
|
ret = await func()
|
||||||
|
except Exception as e:
|
||||||
|
value = stdout.getvalue()
|
||||||
|
await ctx.send('```py\n{}{}\n```'.format(value, traceback.format_exc()))
|
||||||
|
else:
|
||||||
|
value = stdout.getvalue()
|
||||||
|
try:
|
||||||
|
await ctx.message.add_reaction('✅')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if ret is None:
|
||||||
|
if value:
|
||||||
|
for page in paginate(value):
|
||||||
|
await ctx.send(page)
|
||||||
|
else:
|
||||||
|
self._last_result = ret
|
||||||
|
if value:
|
||||||
|
for page in paginate(value):
|
||||||
|
await ctx.send(page)
|
||||||
|
for page in paginate(ret):
|
||||||
|
await ctx.send(page)
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
async def repl(self, ctx):
|
||||||
|
if ctx.author.id != ownerid:
|
||||||
|
return
|
||||||
|
msg = ctx.message
|
||||||
|
variables = {
|
||||||
|
'ctx': ctx,
|
||||||
|
'bot': self.bot,
|
||||||
|
'message': msg,
|
||||||
|
'server': msg.guild,
|
||||||
|
'channel': msg.channel,
|
||||||
|
'author': msg.author,
|
||||||
|
'_': None,
|
||||||
|
}
|
||||||
|
if msg.channel.id in self.sessions:
|
||||||
|
await ctx.send('Already running a REPL session in this channel. Exit it with `quit`.')
|
||||||
|
return
|
||||||
|
self.sessions.add(msg.channel.id)
|
||||||
|
await ctx.send('Enter code to execute or evaluate. `exit()` or `quit` to exit.')
|
||||||
|
while True:
|
||||||
|
response = await self.bot.wait_for('message', check=(lambda m: m.content.startswith('`')))
|
||||||
|
if response.author.id == ownerid:
|
||||||
|
cleaned = self.cleanup_code(response.content)
|
||||||
|
if cleaned in ('quit', 'exit', 'exit()'):
|
||||||
|
await response.channel.send('Exiting.')
|
||||||
|
self.sessions.remove(msg.channel.id)
|
||||||
|
return
|
||||||
|
executor = exec
|
||||||
|
if cleaned.count('\n') == 0:
|
||||||
|
try:
|
||||||
|
code = compile(cleaned, '<repl session>', 'eval')
|
||||||
|
except SyntaxError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
executor = eval
|
||||||
|
if executor is exec:
|
||||||
|
try:
|
||||||
|
code = compile(cleaned, '<repl session>', 'exec')
|
||||||
|
except SyntaxError as e:
|
||||||
|
await response.channel.send(self.get_syntax_error(e))
|
||||||
|
continue
|
||||||
|
variables['message'] = response
|
||||||
|
fmt = None
|
||||||
|
stdout = io.StringIO()
|
||||||
|
try:
|
||||||
|
with redirect_stdout(stdout):
|
||||||
|
result = executor(code, variables)
|
||||||
|
if inspect.isawaitable(result):
|
||||||
|
result = await result
|
||||||
|
except Exception as e:
|
||||||
|
value = stdout.getvalue()
|
||||||
|
fmt = '{}{}'.format(value, traceback.format_exc())
|
||||||
|
else:
|
||||||
|
value = stdout.getvalue()
|
||||||
|
if result is not None:
|
||||||
|
fmt = '{}{}'.format(value, result)
|
||||||
|
variables['_'] = result
|
||||||
|
elif value:
|
||||||
|
fmt = '{}'.format(value)
|
||||||
|
try:
|
||||||
|
if fmt is not None:
|
||||||
|
if len(fmt) > 1990:
|
||||||
|
for page in paginate(fmt):
|
||||||
|
await response.channel.send(page)
|
||||||
|
await ctx.send(response.channel)
|
||||||
|
else:
|
||||||
|
await response.channel.send(f'```py\n{fmt}\n```')
|
||||||
|
except discord.Forbidden:
|
||||||
|
pass
|
||||||
|
except discord.HTTPException as e:
|
||||||
|
await msg.channel.send('Unexpected error: `{}`'.format(e))
|
||||||
|
|
||||||
|
@commands.command(hidden=True)
|
||||||
|
async def os(self, ctx, *, body: str):
|
||||||
|
if ctx.author.id != ownerid:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
body = self.cleanup_code(body).split(' ')
|
||||||
|
result = await asyncio.wait_for(self.bot.loop.create_task(run_command(*body)),10)
|
||||||
|
value = result
|
||||||
|
for page in paginate(value):
|
||||||
|
await ctx.send(page)
|
||||||
|
await ctx.message.add_reaction('✅')
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
value = f"Command did not complete in the time allowed."
|
||||||
|
for page in paginate(value):
|
||||||
|
await ctx.send(page)
|
||||||
|
await ctx.message.add_reaction('❌')
|
||||||
|
|
||||||
|
def setup(bot):
|
||||||
|
bot.add_cog(REPL(bot))
|
||||||
@ -0,0 +1,146 @@
|
|||||||
|
import discord
|
||||||
|
from discord.ext import commands
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
import json, asyncio
|
||||||
|
from srcds import rcon as rcon_con
|
||||||
|
import re, aiohttp, async_timeout
|
||||||
|
from bs4 import BeautifulSoup as bs
|
||||||
|
from postgres import Postgres
|
||||||
|
from collections import deque
|
||||||
|
from googleapiclient.discovery import build
|
||||||
|
|
||||||
|
log_format = '{asctime}.{msecs:03.0f}|{levelname:<8}|{name}::{message}'
|
||||||
|
date_format = '%Y.%m.%d %H.%M.%S'
|
||||||
|
|
||||||
|
log_dir = 'logs'
|
||||||
|
|
||||||
|
log_file = '{0}/geeksbot_{1}.log'.format(log_dir, datetime.now().strftime('%Y%m%d_%H%M%S%f'))
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG, style='{', filename=log_file, datefmt=date_format, format=log_format)
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
console_handler.setLevel(logging.INFO)
|
||||||
|
formatter = logging.Formatter(log_format, style='{', datefmt=date_format)
|
||||||
|
console_handler.setFormatter(formatter)
|
||||||
|
logging.getLogger('').addHandler(console_handler)
|
||||||
|
|
||||||
|
config_dir = 'config/'
|
||||||
|
admin_id_file = 'admin_ids'
|
||||||
|
extension_dir = 'exts'
|
||||||
|
owner_id = 351794468870946827
|
||||||
|
bot_config_file = 'bot_config.json'
|
||||||
|
secrets_file = 'bot_secrets.json'
|
||||||
|
profane_words_file = 'profane_words'
|
||||||
|
|
||||||
|
emojis = {
|
||||||
|
'x': '❌',
|
||||||
|
'y': '✅',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
description = 'I am Geeksbot! Fear me!'
|
||||||
|
|
||||||
|
class Geeksbot(commands.Bot):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
kwargs["command_prefix"] = self.command_prefix
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.aio_session = aiohttp.ClientSession(loop=self.loop)
|
||||||
|
with open(f'{config_dir}{bot_config_file}') as file:
|
||||||
|
self.bot_config = json.load(file)
|
||||||
|
with open(f'{config_dir}{secrets_file}') as file:
|
||||||
|
self.bot_secrets = son.load(file)
|
||||||
|
# with open(f'{config_dir}{profane_words_file}') as file:
|
||||||
|
# self.profane_words = file.readlines()
|
||||||
|
self.guild_config = {}
|
||||||
|
self.infected = {}
|
||||||
|
self.TOKEN = self.bot_secrets['token']
|
||||||
|
del self.bot_secrets['token']
|
||||||
|
self.con = Postgres(f"host={self.bot_secrets['db_con']['host']} port={self.bot_secrets['db_con']['port']} dbname={self.bot_secrets['db_con']['db_name']} connect_timeout=10 user={self.bot_secrets['db_con']['user']} password={self.bot_secrets['db_con']['password']}")
|
||||||
|
del self.bot_secrets['db_con']
|
||||||
|
self.default_prefix = 'g$'
|
||||||
|
self.voice_chans = {}
|
||||||
|
self.spam_list = {}
|
||||||
|
self.gcs_service = build('customsearch', 'v1', developerKey='AIzaSyAfGHj5alDWMsnVMeGUD53dI0RQij94PU4')
|
||||||
|
|
||||||
|
async def command_prefix(self, bot, message):
|
||||||
|
return self.con.one(f'select prefix from guild_config where guild_id = {message.guild.id}') or self.default_prefix
|
||||||
|
|
||||||
|
async def load_ext(self, ctx, mod):
|
||||||
|
bot.load_extension('{0}.{1}'.format(extension_dir,mod))
|
||||||
|
if ctx != None:
|
||||||
|
await ctx.send('{0} loaded.'.format(mod))
|
||||||
|
|
||||||
|
async def unload_ext(self, ctx, mod):
|
||||||
|
bot.unload_extension('{0}.{1}'.format(extension_dir,mod))
|
||||||
|
if ctx != None:
|
||||||
|
await ctx.send('{0} unloaded.'.format(mod))
|
||||||
|
|
||||||
|
async def close(self):
|
||||||
|
await super().close()
|
||||||
|
self.aio_session.close() # aiohttp is drunk and can't decide if it's a coro or not
|
||||||
|
|
||||||
|
|
||||||
|
bot = Geeksbot(description=description, case_insensitive=True)
|
||||||
|
|
||||||
|
@bot.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def load(ctx, mod):
|
||||||
|
'Allows the owner to load extensions dynamically'
|
||||||
|
await bot.load_ext(ctx, mod)
|
||||||
|
|
||||||
|
@bot.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def reload(ctx, mod=None):
|
||||||
|
'''Allows the owner to reload extensions dynamically'''
|
||||||
|
if mod == 'all':
|
||||||
|
load_list = bot.bot_config['load_list']
|
||||||
|
for load_item in load_list:
|
||||||
|
await bot.unload_ext(ctx,f'{load_item}')
|
||||||
|
await bot.load_ext(ctx,f'{load_item}')
|
||||||
|
else:
|
||||||
|
await bot.unload_ext(ctx, mod)
|
||||||
|
await bot.load_ext(ctx, mod)
|
||||||
|
|
||||||
|
@bot.command(hidden=True)
|
||||||
|
@commands.is_owner()
|
||||||
|
async def unload(ctx, mod):
|
||||||
|
'Allows the owner to unload extensions dynamically'
|
||||||
|
await bot.unload_ext(ctx, mod)
|
||||||
|
|
||||||
|
@bot.event
|
||||||
|
async def on_message(ctx):
|
||||||
|
if not ctx.author.bot:
|
||||||
|
if ctx.guild:
|
||||||
|
if int(bot.con.one(f"select channel_lockdown from guild_config where guild_id = {ctx.guild.id}")):
|
||||||
|
if ctx.channel.id in json.loads(bot.con.one(f"select allowed_channels from guild_config where guild_id = {ctx.guild.id}")):
|
||||||
|
await bot.process_commands(ctx)
|
||||||
|
elif ctx.channel.id == 418452585683484680:
|
||||||
|
prefix = bot.con.one(f'select prefix from guild_config where guild_id = {ctx.guild.id}')
|
||||||
|
prefix = prefix[0] if prefix else bot.default_prefix
|
||||||
|
ctx.content = f'{prefix}{ctx.content}'
|
||||||
|
await bot.process_commands(ctx)
|
||||||
|
else:
|
||||||
|
await bot.process_commands(ctx)
|
||||||
|
else:
|
||||||
|
await bot.process_commands(ctx)
|
||||||
|
|
||||||
|
@bot.event
|
||||||
|
async def on_ready():
|
||||||
|
bot.recent_msgs = {}
|
||||||
|
for guild in bot.guilds:
|
||||||
|
bot.recent_msgs[guild.id] = deque(maxlen=50)
|
||||||
|
logging.info('Logged in as {0.name}|{0.id}'.format(bot.user))
|
||||||
|
load_list = bot.bot_config['load_list']
|
||||||
|
for load_item in load_list:
|
||||||
|
await bot.load_ext(None,f'{load_item}')
|
||||||
|
logging.info('Extension Loaded: {0}'.format(load_item))
|
||||||
|
logging.info('Done loading, Geeksbot is active.')
|
||||||
|
with open(f'{config_dir}reboot', 'r') as f:
|
||||||
|
reboot = f.readlines()
|
||||||
|
if int(reboot[0]) == 1:
|
||||||
|
await bot.get_channel(int(reboot[1])).send('Restart Finished.')
|
||||||
|
with open(f'{config_dir}reboot', 'w') as f:
|
||||||
|
f.write(f'0')
|
||||||
|
|
||||||
|
bot.run(bot.TOKEN)
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
until python /home/dusty/bin/geeksbot/geeksbot.py; do
|
||||||
|
echo "Geeksbot shutdown with error: $?. Restarting..." >&2
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
@checks.no_bots()
|
||||||
|
@commands.cooldown(1,5,commands.BucketType.user)
|
||||||
|
@commands.command()
|
||||||
|
async def captcha(self, ctx, type, *, text):
|
||||||
|
type = type.lower()
|
||||||
|
if type not in "checked unchecked loading".split():
|
||||||
|
raise commands.BadArgument(f"Invalid type {type!r}. Available "
|
||||||
|
"types: `unchecked`, `loading`, `checked`")
|
||||||
|
font = ImageFont.truetype("Roboto-Regular.ttf", 14)
|
||||||
|
async with ctx.typing():
|
||||||
|
img = Image.open(f"blank-captcha-{type}.png")
|
||||||
|
img.load()
|
||||||
|
d = ImageDraw.Draw(img)
|
||||||
|
fnc = functools.partial(d.text, (53,30), text, fill=(0,0,0,255),
|
||||||
|
font=font)
|
||||||
|
await self.bot.loop.run_in_executor(None, fnc)
|
||||||
|
img.save("captcha.png")
|
||||||
|
await ctx.send(file=discord.File("captcha.png"))
|
||||||
|
os.system("rm captcha.png")
|
||||||
|
img.close()
|
||||||
|
|
||||||
|
|
||||||
|
import functools, youtube_dl
|
||||||
|
#bot.voice_chan = await ctx.author.voice.channel.connect()
|
||||||
|
bot.voice_chan.stop()
|
||||||
|
opts = {"format": 'webm[abr>0]/bestaudio/best',"ignoreerrors": True,"default_search": "auto","source_address": "0.0.0.0",'quiet': True}
|
||||||
|
ydl = youtube_dl.YoutubeDL(opts)
|
||||||
|
url = 'https://www.youtube.com/watch?v=hjbPszSt5Pc'
|
||||||
|
func = functools.partial(ydl.extract_info, url, download=False)
|
||||||
|
info = func()
|
||||||
|
#bot.voice_chan.play(discord.FFmpegPCMAudio('dead_puppies.mp3'))
|
||||||
|
bot.voice_chan.play(discord.FFmpegPCMAudio(info['url']))
|
||||||
|
#async while bot.voice_chan.is_playing():
|
||||||
|
# pass
|
||||||
|
#await bot.voice_chan.disconnect()
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// The tab key will cycle through the settings when first created
|
||||||
|
// Visit http://wbond.net/sublime_packages/sftp/settings for help
|
||||||
|
|
||||||
|
// sftp, ftp or ftps
|
||||||
|
"type": "sftp",
|
||||||
|
|
||||||
|
"save_before_upload": true,
|
||||||
|
"upload_on_save": true,
|
||||||
|
"sync_down_on_open": true,
|
||||||
|
"sync_skip_deletes": false,
|
||||||
|
"sync_same_age": true,
|
||||||
|
"confirm_downloads": false,
|
||||||
|
"confirm_sync": false,
|
||||||
|
"confirm_overwrite_newer": false,
|
||||||
|
|
||||||
|
"host": "10.10.0.70",
|
||||||
|
"user": "dusty",
|
||||||
|
"password": "SunFeb07",
|
||||||
|
"port": "22",
|
||||||
|
|
||||||
|
"remote_path": "/home/dusty/bin/geeksbot/",
|
||||||
|
"ignore_regexes": [
|
||||||
|
"\\.sublime-(project|workspace)", "sftp-config(-alt\\d?)?\\.json",
|
||||||
|
"sftp-settings\\.json", "/venv/", "\\.svn/", "\\.hg/", "\\.git/",
|
||||||
|
"\\.bzr", "_darcs", "CVS", "\\.DS_Store", "Thumbs\\.db", "desktop\\.ini", "\\.log"
|
||||||
|
],
|
||||||
|
//"file_permissions": "664",
|
||||||
|
//"dir_permissions": "775",
|
||||||
|
|
||||||
|
//"extra_list_connections": 0,
|
||||||
|
|
||||||
|
"connect_timeout": 30,
|
||||||
|
//"keepalive": 120,
|
||||||
|
//"ftp_passive_mode": true,
|
||||||
|
//"ftp_obey_passive_host": false,
|
||||||
|
//"ssh_key_file": "~/.ssh/id_rsa",
|
||||||
|
//"sftp_flags": ["-F", "/path/to/ssh_config"],
|
||||||
|
|
||||||
|
//"preserve_modification_times": false,
|
||||||
|
//"remote_time_offset_in_hours": 0,
|
||||||
|
//"remote_encoding": "utf-8",
|
||||||
|
//"remote_locale": "C",
|
||||||
|
//"allow_config_upload": false,
|
||||||
|
}
|
||||||
Loading…
Reference in new issue