Skip to content

Commit

Permalink
recode
Browse files Browse the repository at this point in the history
  • Loading branch information
Atluzka authored Jun 8, 2024
1 parent 0904052 commit b97795a
Show file tree
Hide file tree
Showing 4 changed files with 352 additions and 0 deletions.
42 changes: 42 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"token": "DISCORD-BOT-TOKEN",
"guild-id": "DISCORD-SERVER-ID",

"stock-command-silent": false,
"remove-capture-from-stock": true,

"gen-channels": [12345],
"admins": [0],
"roles": [
{
"id": 0,
"cooldown": 60,
"gen-access": ["netflix"]
},
{
"id": 0,
"cooldown": 30,
"gen-access": ["all"]
}
],

"messages": {
"noperms": "You do not have permissions to use this command.",
"wrongchannel": ":thinking: ",
"altsent": "Thank you for using AtluzkaGEN",
"footer-msg": "github.com/Atluzka/account-gen-bot"
},

"generate-settings": {
"gif-img-url": "https://media.discordapp.net/attachments/807809192537882647/1119647605140488242/C02ECC68-ACE2-4293-8992-BE67B45E6378.gif"
},

"colors": {
"error": 16713025,
"success": 1288807,
"stock": 7229605
},

"_comment1": "Size for uploading stock. Default: 2097152 == 2mb",
"maximum-file-size": 2097152
}
228 changes: 228 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
import discord, json, sqlite3
from discord import app_commands
from datetime import timedelta
from typing import List

from src import database
from src import utils

# connect to the database
con = sqlite3.connect('accounts.db'); con.row_factory = sqlite3.Row

# discord bot stuff
bot = discord.Client(intents=discord.Intents.default())
tree = app_commands.CommandTree(bot)
config = json.load(open('config.json'))

serviceList = []
is_everything_ready = False

async def updateServices():
global serviceList
serviceList = await database.getServices(con)
return

user_cooldown = []

@bot.event
async def on_ready():
global is_everything_ready
await tree.sync(guild=discord.Object(id=config["guild-id"]))

await updateServices()
print("Servicelist:", serviceList)

is_everything_ready = True
print("Logged in as {0.user}".format(bot))

async def service_autcom(interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
types = serviceList
return [
app_commands.Choice(name=service, value=service)
for service in types if current.lower() in service.lower()
]

@tree.command(name = "deleteservice", description = "(admin only)", guild=discord.Object(id=config["guild-id"]))
@app_commands.autocomplete(service=service_autcom)
async def deleteservice(interaction: discord.Interaction, service: str):

if not interaction.user.id in config['admins']:
return await interaction.response.send_message(str(config['messages']['noperms']), ephemeral=True)

if not is_everything_ready:
return await interaction.response.send_message("Bot is starting.", ephemeral=True)

db_res1 = await database.deleteService(con, service, serviceList)
if db_res1:
await updateServices()

embd=discord.Embed(
title=f"Delete Service",
description=f'{"Successfully deleted service" if db_res1 else "Error. Service doesnt exist."}',
color=int(config['colors']['success']) if db_res1 else int(config['colors']['error'])
)
embd.set_footer(text=config['messages']['footer-msg'])

return await interaction.response.send_message(embed=embd, ephemeral=True)

async def gen_cooldown(interaction: discord.Interaction):
if interaction.user.id in config['admins']:
return None

userRoles = [role.id for role in interaction.user.roles]
minCooldown = float("inf")

for role in config["roles"]:
if int(role["id"]) in userRoles and float(role["cooldown"]) < minCooldown:
minCooldown = float(role["cooldown"])

if not minCooldown == float("inf"):
if interaction.user.id in user_cooldown:
return app_commands.Cooldown(1, str(timedelta(seconds=minCooldown).total_seconds()))
else:
return None
else:
if interaction.user.id in user_cooldown:
return app_commands.Cooldown(1, str(timedelta(seconds=config['roles'][0]["cooldown"]).total_seconds()))
else:
return None

@tree.command(name = "gen", description = "Generate an account of your choice", guild=discord.Object(id=config["guild-id"]))
@app_commands.autocomplete(service=service_autcom)
@app_commands.checks.dynamic_cooldown(gen_cooldown)
async def gen(interaction: discord.Interaction, service: str):
global user_cooldown

if not is_everything_ready:
return await interaction.response.send_message("Bot is starting.", ephemeral=True)

if service not in serviceList:
return await interaction.response.send_message(f'Invalid service.', ephemeral=True)

if not interaction.user.id in config['admins'] and not interaction.channel_id in config["gen-channels"]:
channel_list = [f"<#{channel}>" for channel in config["gen-channels"]]
return await interaction.response.send_message(str(config['messages']['wrongchannel']) + ', '.join(channel_list), ephemeral=True)

utl_res = await utils.does_user_meet_requirements(interaction.user.roles, config, service)
if not interaction.user.id in config['admins'] and not utl_res:
return await interaction.response.send_message(str(config['messages']['noperms']), ephemeral=True)

# Cooldown
if interaction.user.id in user_cooldown:
user_cooldown.remove(interaction.user.id)
embd=discord.Embed(title="Cooldown",description=f':no_entry_sign: This command is on cooldown.',color=config['colors']['error'])
return await interaction.response.send_message(embed=embd, ephemeral=False)
if interaction.user.id not in config['admins']:
user_cooldown.append(interaction.user.id)

success, account = await database.getAccount(con, service)
if not success:
user_cooldown.remove(interaction.user.id)
return await interaction.response.send_message(f"There is no stock left.", ephemeral=True)
else:

channel = await interaction.user.create_dm()
embd=discord.Embed(
title=f"Account Generated :label: ",
description=config['messages']['altsent'] + f"\n```{account['combo']}```",
color=config['colors']['success']
)
embd.set_footer(text=config['messages']['footer-msg'],icon_url=interaction.user.avatar.url)

embd2=discord.Embed(title=f"`{service}` generated :label: ",description=':incoming_envelope: Check your DMs for the account.',color=config['colors']['success'])
embd2.set_footer(text=config['messages']['footer-msg'],icon_url=interaction.user.avatar.url)
embd2.set_image(url=config["generate-settings"]["gif-img-url"])

await channel.send(embed=embd)
return await interaction.response.send_message(embed=embd2, ephemeral=False)

@gen.error
async def gencmd_error(interaction: discord.Interaction, error):
if isinstance(error, app_commands.CommandOnCooldown):
embd=discord.Embed(title="Cooldown",description=f':no_entry_sign: This command is on cooldown, try again in {(error.retry_after/60):.2f} minutes.',color=config['colors']['error'])
await interaction.response.send_message(embed=embd, ephemeral=False)

@tree.command(name = "addstock", description = "Add stock to database (admin only)", guild=discord.Object(id=config["guild-id"]))
@app_commands.autocomplete(service=service_autcom)
async def addaccounts(interaction: discord.Interaction, service: str, file: discord.Attachment):

if not interaction.user.id in config['admins']:
return await interaction.response.send_message(str(config['messages']['noperms']), ephemeral=True)

if not is_everything_ready:
return await interaction.response.send_message("Bot is starting.", ephemeral=True)

if service not in serviceList:
return await interaction.response.send_message(f'Invalid service.', ephemeral=True)

try:
if not str(file.filename).endswith(".txt"):
return await interaction.response.send_message(f'You can only upload files with .txt extension', ephemeral=True)
except:
return await interaction.response.send_message(f'Error when checking file.', ephemeral=True)

if file.size > config["maximum-file-size"]:
return await interaction.response.send_message(f'Maximum file size: `{config["maximum-file-size"]} bytes`', ephemeral=True)
content = await file.read()

filtered_stock = []
dec_cont = content.decode('utf-8')
content = str(dec_cont).split("\n")
for item in content:
if len(item) > 2:
filtered_stock.append(item)
add_cnt,dupe_cnt = await database.addStock(con, service, filtered_stock, config['remove-capture-from-stock'])
return await interaction.response.send_message(f'`{add_cnt}` accounts have been added to the `{service}` database. `{dupe_cnt}` dupes found.', ephemeral=True)

@tree.command(name = "createservice", description = "(admin only)", guild=discord.Object(id=config["guild-id"]))
async def createservice(interaction: discord.Interaction, servicename: str):

if not interaction.user.id in config['admins']:
return await interaction.response.send_message(str(config['messages']['noperms']), ephemeral=True)

if not is_everything_ready:
return await interaction.response.send_message("Bot is starting.", ephemeral=True)

db_res1 = await database.createService(con, servicename, serviceList)
if db_res1:
await updateServices()

embd=discord.Embed(
title=f"Create Service",
description=f'{"Successfully created service" if db_res1 else "Error. Service already exists."}',
color=int(config['colors']['success']) if db_res1 else int(config['colors']['error'])
)
embd.set_footer(text=config['messages']['footer-msg'])

return await interaction.response.send_message(embed=embd, ephemeral=True)

@tree.command(name = "stock", description = "Get the amount of stock", guild=discord.Object(id=config["guild-id"]))
async def stock(interaction: discord.Interaction):

if not is_everything_ready:
return await interaction.response.send_message("Bot is starting.", ephemeral=True)

stock = await database.getStock(con, serviceList)
if len(stock) <= 0:
embd=discord.Embed(
title=f"Stock - 0 services",
description='There are no services to display',
color=config['colors']['stock'])
embd.set_footer(text=config['messages']['footer-msg'])
return await interaction.response.send_message(embed=embd)

filtered_stock = []
for stk in stock:
stk = (stk.split(':'))
filtered_stock.append(f"**{stk[0]}**: `{stk[1]}`")

embd=discord.Embed(
title=f"Stock - {len(filtered_stock)}",
description='\n'.join(filtered_stock),
color=config['colors']['stock']
)
embd.set_footer(text=config['messages']['footer-msg'])

return await interaction.response.send_message(embed=embd, ephemeral=config['stock-command-silent'])

bot.run(config['token'])
75 changes: 75 additions & 0 deletions src/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
async def getServices(con):
serviceslist = []
cur = con.cursor(); cur.execute("SELECT name FROM sqlite_master WHERE type='table';")
table_names = cur.fetchall(); cur.close()
for table in table_names:
if str(table[0]).split('_')[0] == 'accounts':
serviceslist.append(str(table[0]).split('_')[1].lower())
return serviceslist

async def createService(con, table_name, servicelist):
if table_name.lower() not in servicelist:
cur = con.cursor()
cur.execute(f'CREATE TABLE IF NOT EXISTS accounts_{table_name.lower()}(combo TEXT NOT NULL)')
con.commit()
cur.close()
return True
else:
return False

async def deleteService(con, table_name, servicelist):
if table_name.lower() in servicelist:
cur = con.cursor()
cur.execute(f"DROP TABLE accounts_{table_name.lower()}")
con.commit()
cur.close()
return True
else:
return False

async def getAccount(con, service):
cursor = con.cursor()
name = f"accounts_{service}"
cursor.execute(f"SELECT COUNT(*) FROM {name}")
row_count = cursor.fetchone()[0]
if row_count > 0:
cursor.execute(f"SELECT * FROM {name} ORDER BY RANDOM() LIMIT 1")
account = cursor.fetchone()
cursor.execute(f"DELETE FROM {name} WHERE combo = '{account[0]}'")
con.commit()
cursor.close()
return True,account
else:
cursor.close()
return False,None

async def addStock(con, service, stock, remove_capture):
cursor = con.cursor()
dupe_amount = 0
already_added = []
for account in stock:
try:
if not account in already_added:
already_added.append(account)
if "|" in account and remove_capture:
account = account.split('|')[0]
values = (account)
cursor.execute(f"INSERT INTO accounts_{service}(combo) VALUES(?)",(values,))
else:
dupe_amount += 1
except Exception as e:
print(e)
con.commit()
cursor.close()
return len(already_added),dupe_amount

async def getStock(con, serviceList):
stock = []
cursor = con.cursor()
for service in serviceList:
name = f'accounts_{service}'
cursor.execute(f"SELECT COUNT(*) FROM {name}")
row_count = cursor.fetchone()[0]
txt_cnt = "Out of stock" if row_count <= 0 else row_count
stock.append(f"{service}:{txt_cnt}")
return stock
7 changes: 7 additions & 0 deletions src/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
async def does_user_meet_requirements(user_roles, config, service_input):
user_roles = [role.id for role in user_roles]
for role in config["roles"]:
if role['id'] in user_roles:
if service_input in role['gen-access'] or "all" in role['gen-access']:
return True
return False

0 comments on commit b97795a

Please sign in to comment.