@ -13,7 +13,7 @@ import paramiko
# import subprocess
bot = commands . Bot ( command_prefix = " . " , intents = discord . Intents . all ( ) , chunk_guilds_at_startup = True ,
bot = commands . Bot ( command_prefix = " . " , intents = discord . Intents . default ( ) ,
case_insensitive = True )
load_dotenv ( )
@ -51,10 +51,6 @@ logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
async def on_ready ( ) :
# Marks bot as running
logging . info ( ' I am running. ' )
servers = bot . guilds
logging . info ( " I am in the following " + str ( len ( servers ) ) + " servers: " )
for server in servers :
print ( server . name + " by " + server . owner . name + " # " + server . owner . discriminator )
@bot . event
async def on_message ( message ) :
@ -89,50 +85,6 @@ async def on_message(message):
await timings . analyze_timings ( message )
await bot . process_commands ( message )
@bot . event
async def on_raw_reaction_add ( payload ) :
if running_on_panel :
global verification_message
global verification_channel
if payload . message_id != verification_message :
return
if payload . user_id == bot . user . id :
return
# Remove the reaction
guild = discord . utils . get ( bot . guilds , id = guild_id )
verification_channel_obj = await bot . fetch_channel ( verification_channel )
verification_message_obj = await verification_channel_obj . fetch_message ( verification_message )
member = guild . get_member ( payload . user_id )
await verification_message_obj . remove_reaction ( payload . emoji , member )
if str ( payload . emoji ) == " ✅ " :
await member . send (
" Hey there! It looks like you ' d like to verify your account. I ' m here to help you with that! \n \n If you ' re confused at any point, see https://birdflop.com/verification for a tutorial. \n \n With that said, let ' s get started! You ' ll want to start by grabbing some API credentials for your account by signing into https://panel.birdflop.com. Head over to the **Account** section in the top right, then click on the **API Credentials tab**. You ' ll want to create an API key with description `Verification` and `172.18.0.2` in the **Allowed IPs section**. \n \n When you finish entering the necessary information, hit the blue **Create **button. \n \n Next, you ' ll want to copy your API credentials. After clicking **Create**, you ' ll receive a long string. Copy it with `ctrl+c` (`cmnd+c` on Mac) or by right-clicking it and selecting **Copy**. \n \n If you click on the **Close **button before copying the API key, no worries! Delete your API key and create a new one with the same information. \n \n Finally, direct message your API key to Botflop: that ' s me! \n \n To verify that you are messaging the key to the correct user, please ensure that the my ID is `Botflop#2403` and that my username is marked with a blue **BOT** badge. Additionally, the only server under the **Mutual Servers** tab should be Birdflop Hosting. \n \n After messaging me your API key, you should receive a success message. If you do not receive a success message, please create a ticket in the Birdflop Discord ' s #support channel. " )
logging . info ( " sent verification challenge to " + member . name + " # " + str ( member . discriminator ) + " ( " + str (
member . id ) + " ) " )
else :
file = open ( ' users.json ' , ' r ' )
data = json . load ( file )
file . close ( )
i = 0
j = - 1
for client in data [ ' users ' ] :
j + = 1
if client [ ' discord_id ' ] == member . id :
data [ ' users ' ] . pop ( j )
i = 1
if i == 1 :
json_dumps = json . dumps ( data , indent = 2 )
file = open ( ' users.json ' , ' w ' )
file . write ( json_dumps )
file . close ( )
await member . edit ( roles = [ ] )
await member . send ( " Your Discord account has successfully been unlinked from your Panel account! " )
logging . info (
' successfully unlinked ' + member . name + " # " + str ( member . discriminator ) + " ( " + str (
member . id ) + " ) " )
@bot . command ( )
async def ping ( ctx ) :
if running_on_panel :
@ -141,7 +93,6 @@ async def ping(ctx):
if not running_on_panel :
await ctx . send ( f ' Public bot ping is { round ( bot . latency * 1000 ) } ms ' )
@bot . command ( name = " react " , pass_context = True )
@has_permissions ( administrator = True )
async def react ( ctx , url , reaction ) :
@ -152,133 +103,6 @@ async def react(ctx, url, reaction):
logging . info ( ' reacted to ' + url + ' with ' + reaction )
@tasks . loop ( minutes = 10 )
async def updater ( ) :
# Update backups
logging . info ( ' Ensuring backups ' )
url = " https://panel.birdflop.com/api/application/servers "
headers = {
' Accept ' : ' application/json ' ,
' Content-Type ' : ' application/json ' ,
' Authorization ' : ' Bearer ' + application_api_key ,
}
# response = requests.get(url, headers=headers)
async with aiohttp . ClientSession ( ) as session :
async with session . get ( url , headers = headers ) as response :
servers_json_response = await response . json ( )
file = open ( ' modified_servers.json ' , ' r ' )
modified_servers = json . load ( file )
file . close ( )
i = - 1
for server in servers_json_response [ ' data ' ] :
i + = 1
already_exists = False
for server2 in modified_servers [ ' servers ' ] :
if not already_exists :
if server [ ' attributes ' ] [ ' uuid ' ] == server2 [ ' uuid ' ] :
already_exists = True
if not already_exists :
headers = {
' Accept ' : ' application/json ' ,
' Content-Type ' : ' application/json ' ,
' Authorization ' : ' Bearer ' + application_api_key ,
}
data = ' { " allocation " : ' + str ( server [ ' attributes ' ] [ ' allocation ' ] ) + ' , " memory " : ' + str (
server [ ' attributes ' ] [ ' limits ' ] [ ' memory ' ] ) + ' , " swap " : 0, " disk " : ' + str (
server [ ' attributes ' ] [ ' limits ' ] [ ' disk ' ] ) + ' , " io " : ' + str (
server [ ' attributes ' ] [ ' limits ' ] [ ' io ' ] ) + ' , " cpu " : ' + str (
server [ ' attributes ' ] [ ' limits ' ] [
' cpu ' ] ) + ' , " threads " : null, " feature_limits " : { " databases " : ' + str (
server [ ' attributes ' ] [ ' feature_limits ' ] [ ' databases ' ] ) + ' , " allocations " : ' + str (
server [ ' attributes ' ] [ ' feature_limits ' ] [ ' allocations ' ] ) + ' , " backups " : 3 } } '
async with aiohttp . ClientSession ( ) as session :
async with session . patch ( ' https://panel.birdflop.com/api/application/servers/ ' + str (
server [ ' attributes ' ] [ ' id ' ] ) + ' /build ' , headers = headers , data = data ) as response :
if response . status == 200 :
modified_servers [ ' servers ' ] . append ( {
' uuid ' : str ( server [ ' attributes ' ] [ ' uuid ' ] )
} )
file = open ( ' modified_servers.json ' , ' w ' )
json_dumps = json . dumps ( modified_servers , indent = 2 )
file . write ( json_dumps )
file . close ( )
logging . info ( " modified " + str ( server [ ' attributes ' ] [ ' name ' ] ) + ' with data ' + data )
else :
logging . info (
" failed to modify " + str ( server [ ' attributes ' ] [ ' name ' ] ) + ' with data ' + data )
# Plugin Updater
# @bot.command()
# async def update(ctx, server, plugin):
# command_discord_id = ctx.message.author.id
# await ctx.send (f'your discord ID is {command_discord_id}')
# file = open('users.json', 'r')
# data = json.load(file)
# file.close()
# i=-1
# for client in data['users']:
# if i==-1:
# if client["discord_id"] == command_discord_id:
# i=0
# command_client_id = client["client_id"]
# command_client_api_key = client["client_api_key"]
# if i==-1:
# await ctx.send("You must be verified to use this command.")
# else:
# if plugin.lower() == "votingplugin":
# subprocess.call(['java', '-jar', 'spiget-downloader.jar', '--url', 'https://www.spigotmc.org/resources/votingplugin.15358/download?version=373388', '--file', 'ProtocolLib.jar'])
#
# print("Finding latest VotingPlugin")
#
# headers = {
# "cache-control": "max-age=1800",
# "content-type": "application/json; charset=utf-8"
# }
#
# response = requests.get("https://api.spiget.org/v2/resources/15358/versions/latest")
# spiget_json = response.json()
# print("Latest Version = " + str(spiget_json["id"]))
#
# url = "https://www.spigotmc.org/resources/votingplugin.15358/download?version=373388"
# headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0'}
# r = requests.get(url, headers=headers)
# open('VotingPlugin1.jar', 'wb').write(r.content)
#
#
# #urllib.request.urlretrieve("https://api.spiget.org/v2/resources/15358/versions/373388/download",'/home/container/zzzcache/VotingPlugin1.jar')
# #urllib.request.urlretrieve("https://www.spigotmc.org/resources/votingplugin.15358/download?version=373388",'/home/container/zzzcache/VotingPlugin2.jar')
#
#
#
# headers = {
# 'Accept': 'application/json',
# 'Content-Type': 'application/json',
# 'Authorization': 'Bearer ' + command_client_api_key,
# }
#
# response = requests.get(f'https://panel.birdflop.com/api/client/servers/{server}/files/upload', headers=headers)
# print(str(response))
# update_json = response.json()
# transfer_url = update_json["attributes"]["url"]
# print(transfer_url)
# else:
# await ctx.send("Sorry, that is not a valid plugin.")
@updater . before_loop
async def before_updater ( ) :
await bot . wait_until_ready ( )
if running_on_panel :
for file_name in os . listdir ( ' ./cogs ' ) :
if file_name . endswith ( ' _panel.py ' ) :