import discord from discord.ext import commands import sqlite3 import asyncio import random from datetime import datetime, timedelta import time # Bot configuration VERSION = "1.3.7" GAMENAME = "BrickRigs" ADMIN_ROLE_ID = 1104093921434402856 # Shitty code for the bot intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix='*', intents=intents) # Database setup db_connection = sqlite3.connect('ecobot.db') db_cursor = db_connection.cursor() db_cursor.execute('''CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY, raw_materials INTEGER DEFAULT 0, processed_materials INTEGER DEFAULT 0 )''') db_cursor.execute('''CREATE TABLE IF NOT EXISTS factories ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, level INTEGER DEFAULT 1, FOREIGN KEY(user_id) REFERENCES users(id) )''') db_cursor.execute('''CREATE TABLE IF NOT EXISTS mines ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, level INTEGER DEFAULT 1, FOREIGN KEY(user_id) REFERENCES users(id) )''') db_cursor.execute('''CREATE TABLE IF NOT EXISTS collect_data ( user_id INTEGER PRIMARY KEY, last_collect INTEGER )''') db_cursor.execute('''CREATE TABLE IF NOT EXISTS process_data ( user_id INTEGER PRIMARY KEY, last_process INTEGER )''') db_connection.commit() # Commands @bot.event async def on_ready(): print(f'Ecobot V{VERSION} is logged in as {bot.user}!') await bot.change_presence(activity=discord.Game(name=GAMENAME)) channel = bot.get_channel(1217238238834589847) @bot.command() async def about(ctx): """Shows information about the bot.""" embed=discord.Embed(title=f"Ecobot", color=0x002aff) embed.add_field(name="Creator", value="Der_Eisbear", inline=False) embed.add_field(name="Powered by", value=" Discord.py, SQLite", inline=False) embed.set_footer(text=f"Version: {VERSION}") await ctx.send(embed=embed) #about_message = ( # f"# **Ecobot V{VERSION}**\n" # "- **Creator**: Der_Eisbear\n" # "- **Powered by**: Discord.py, SQLite\n" #) #await ctx.send(about_message) @bot.command() async def shutdown(ctx): """Shuts down the bot. (Admin Only)""" if ADMIN_ROLE_ID not in [role.id for role in ctx.author.roles]: await ctx.send('*You do not have permission to use this command!*') return await ctx.send('Shutting down...') await bot.close() @bot.command() async def bal(ctx, member: discord.Member = None): """Shows the balance of the user.""" user = member or ctx.author user_id = user.id # Ensure user exists in database db_cursor.execute('INSERT OR IGNORE INTO users (id) VALUES (?)', (user_id,)) db_connection.commit() # Fetch data db_cursor.execute('SELECT raw_materials, processed_materials FROM users WHERE id = ?', (user_id,)) user_data = db_cursor.fetchone() raw_materials, processed_materials = user_data db_cursor.execute('SELECT id, level FROM factories WHERE user_id = ?', (user_id,)) factories = db_cursor.fetchall() db_cursor.execute('SELECT id, level FROM mines WHERE user_id = ?', (user_id,)) mines = db_cursor.fetchall() # Format response factory_levels = "\n".join([f"ID: {factory[0]} 🏭 Level: {factory[1]}" for factory in factories]) or "None" mine_levels = "\n".join([f"ID: {mine[0]} 🪨 Level: {mine[1]}" for mine in mines]) or "None" embed = discord.Embed(title=f"{user.display_name}'s Balance", color=discord.Color.blue()) embed.add_field(name="Factories", value=factory_levels, inline=False) embed.add_field(name="Mines", value=mine_levels, inline=False) embed.add_field(name="Raw Materials", value=f"🌾 {raw_materials}", inline=True) embed.add_field(name="Processed Materials", value=f"⚙️ {processed_materials}", inline=True) await ctx.send(embed=embed) @bot.command() async def pay(ctx, member: discord.Member, material_type: str, amount: int): """Pay a user. *pay <@user> """ user_id = ctx.author.id target_id = member.id if material_type.lower() not in ["ore", "mat", "raw"]: await ctx.send("Invalid material type! Use `Ore`, `Raw` or `Mat`.") return if material_type.lower() == "ore" or material_type.lower() == "raw": db_column = "raw_materials" emoji = "🌾" mat_name = "raw materials" elif material_type.lower() == "mat": db_column = "processed_materials" emoji = "⚙️" mat_name = "processed materials" # Ensure both users exist in the database db_cursor.execute('INSERT OR IGNORE INTO users (id) VALUES (?)', (user_id,)) db_cursor.execute('INSERT OR IGNORE INTO users (id) VALUES (?)', (target_id,)) db_connection.commit() # Fetch sender's balance db_cursor.execute(f'SELECT {db_column} FROM users WHERE id = ?', (user_id,)) sender_balance = db_cursor.fetchone()[0] if sender_balance < amount: embed = discord.Embed(color=discord.Color.red()) embed.add_field(name=f":x: Not enough resources!", value = f"You have {sender_balance} {mat_name}!") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) return try: # Perform the transaction db_cursor.execute(f'UPDATE users SET {db_column} = {db_column} - ? WHERE id = ?', (amount, user_id)) db_cursor.execute(f'UPDATE users SET {db_column} = {db_column} + ? WHERE id = ?', (amount, target_id)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f"{ctx.author.display_name}", value = f":white_check_mark: <@{member.id}> has received your {emoji}{amount}") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) except Exception as e: await ctx.send(f"An error occurred during the transaction: {e}") # Admin Commands @bot.command() async def add(ctx, member: discord.Member, item_type: str, amount: int): """Adds items to a user. (Admin Only) *add <@user> """ if ADMIN_ROLE_ID not in [role.id for role in ctx.author.roles]: await ctx.send("You do not have permission to use this command!") return target_id = member.id db_cursor.execute('INSERT OR IGNORE INTO users (id) VALUES (?)', (target_id,)) db_connection.commit() if item_type.lower() == "ore" or item_type.lower() == "raw": db_column = "raw_materials" db_cursor.execute(f'UPDATE users SET {db_column} = {db_column} + ? WHERE id = ?', (amount, target_id)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Added {amount} raw materials to <@{member.id}>") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) elif item_type.lower() == "mat": db_column = "processed_materials" db_cursor.execute(f'UPDATE users SET {db_column} = {db_column} + ? WHERE id = ?', (amount, target_id)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Added {amount} processed materials to <@{member.id}>") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) elif item_type.lower() == "factory": db_cursor.execute('INSERT INTO factories (user_id, level) VALUES (?, ?)', (target_id, amount)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Added a level {amount} factory to <@{member.id}>") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) elif item_type.lower() == "mine": db_cursor.execute('INSERT INTO mines (user_id, level) VALUES (?, ?)', (target_id, amount)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Added a level {amount} mine to <@{member.id}>") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) else: await ctx.send("Invalid item type! Use `ore`, `raw`, `mat`, `factory` or `mine`.") @bot.command() async def remove(ctx, member: discord.Member, item_type: str, amount: int): """Removes resources from a user. (Admin Only) *remove <@user> """ if ADMIN_ROLE_ID not in [role.id for role in ctx.author.roles]: await ctx.send("You do not have permission to use this command!") return target_id = member.id db_cursor.execute('INSERT OR IGNORE INTO users (id) VALUES (?)', (target_id,)) db_connection.commit() if item_type.lower() == "ore" or item_type.lower() == "raw": db_column = "raw_materials" db_cursor.execute(f'UPDATE users SET {db_column} = {db_column} - ? WHERE id = ?', (amount, target_id)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Removed {amount} raw materials from <@{member.id}>") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) elif item_type.lower() == "mat": db_column = "processed_materials" db_cursor.execute(f'UPDATE users SET {db_column} = {db_column} - ? WHERE id = ?', (amount, target_id)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Removed {amount} processed materials from <@{member.id}>") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) else: await ctx.send("Invalid item type! Use `ore`, `raw` or `mat`.") @bot.command() async def level(ctx, item_type: str, item_id: int, level: int): """Upgrades or Downgrades a building (Admin Only) *level """ if ADMIN_ROLE_ID not in [role.id for role in ctx.author.roles]: await ctx.send("You do not have permission to use this command!") return if item_type.lower() == "factory": db_cursor.execute('UPDATE factories SET level = ? WHERE id = ?', (level, item_id)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Upgraded factory id {item_id} to level {level}!") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) elif item_type.lower() == "mine": db_cursor.execute('UPDATE mines SET level = ? WHERE id = ?', (level, item_id)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Upgraded mine id {item_id} to level {level}!") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) @bot.command() async def removeb(ctx, item_type: str, item_id: int): """Removes buildings from a user (Admin Only) *removeb """ if ADMIN_ROLE_ID not in [role.id for role in ctx.author.roles]: await ctx.send("You do not have permission to use this command!") return if item_type.lower() == "factory": db_cursor.execute('DELETE FROM factories WHERE id = ?', (item_id,)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Removed factory id {item_id}!") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) elif item_type.lower() == "mine": db_cursor.execute('DELETE FROM mines WHERE id = ?', (item_id,)) db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=f":white_check_mark:", value = f"Removed mine id {item_id}!") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) else: await ctx.send("Invalid item type! Use `mine` or `factory`.") @bot.command() async def drop(ctx): """Removes all data from the table (Admin Only) *drop""" if ADMIN_ROLE_ID not in [role.id for role in ctx.author.roles]: await ctx.send("You do not have permission to use this command!") return embed = discord.Embed(color = discord.Color.orange(), title="Confirmation Needed") embed.add_field(name="Confirm your actions:", value = "Are you sure you want to delete all data in the table? This can not be undone. To confirm, press the button within the next 1 minute.") message = await ctx.send(embed=embed, view = discord.ui.View(timeout = 60).add_item(discord.ui.Button(label = "Confirm", style = discord.ButtonStyle.green))) def check(i): return i.user == ctx.author and i.message == message try: interaction = await bot.wait_for("interaction", check=check, timeout = 60) db_cursor.execute('DELETE FROM users;') db_cursor.execute('DELETE FROM factories;') db_cursor.execute('DELETE FROM mines;') db_cursor.execute('DELETE FROM collect_data;') db_cursor.execute('DELETE FROM process_data;') db_connection.commit() embed = discord.Embed(color=discord.Color.green()) embed.add_field(name=":white_check_mark:", value="Successfully dropped all data from table!") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await interaction.response.edit_message(embed=embed, view = None) except asyncio.TimeoutError: embed = discord.Embed(color=discord.Color.red()) embed.add_field(name=":x:", value = "No confirmation has been given. Deletion aborted.") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await message.edit(embed=embed, view=None) @bot.command() async def collect(ctx): """Collects resources from mines (Once every 24 hours)""" user_id = ctx.author.id embed = discord.Embed() # Ensure user exists in database db_cursor.execute('INSERT OR IGNORE INTO users (id) VALUES (?)', (user_id,)) #db_connection.commit() db_cursor.execute('SELECT last_collect FROM collect_data WHERE user_id = ?', (user_id,)) last_collect_data = db_cursor.fetchone() if last_collect_data: last_collect = last_collect_data[0] else: last_collect = 0 db_cursor.execute('SELECT level FROM mines WHERE user_id = ?', (user_id,)) mines = db_cursor.fetchall() if not mines: embed.color = discord.Color.red() embed.add_field(name="You do not own any mines to collect from.", value="\u200b") # Add a zero-width space for formatting. embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed=embed) return time_since_collect = int(time.time()) - last_collect current_time = int(time.time()) if time_since_collect < 24 * 3600: next_collect = last_collect + 24 * 3600 embed.color = discord.Color.red() embed.add_field(name=f"You can collect again at ", value="\u200b") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed=embed) return db_cursor.execute('SELECT id, level FROM mines WHERE user_id = ?', (user_id,)) # Fetch ID too mines = db_cursor.fetchall() if not mines: embed.color = discord.Color.red() embed.add_field(name="No Mines", value="You do not own any mines to collect from.") await ctx.send(embed=embed) return # --- Calculate Production --- total_ore_collected = 0 collected_from_mines = [] # Optional: To list details for mine_id, mine_level in mines: if mine_level <= 0: # Skip invalid mines continue # Calculate ore: 1 to level * 2 (inclusive) ore_produced = random.randint(1, mine_level * 2) total_ore_collected += ore_produced collected_from_mines.append(f"Mine ID {mine_id} (Lvl {mine_level}): +{ore_produced} 🌾") # --- Update Database --- if total_ore_collected > 0: try: db_cursor.execute('UPDATE users SET raw_materials = raw_materials + ? WHERE id = ?', (total_ore_collected, user_id)) db_cursor.execute('INSERT OR REPLACE INTO collect_data (user_id, last_collect) VALUES (?, ?)', (user_id, current_time)) db_connection.commit() embed.color = discord.Color.green() embed.add_field(name="Collection Successful!", value=f"You collected a total of **{total_ore_collected}** 🌾 raw materials.", inline=False) # Optional: Add details field # if collected_from_mines: # details = "\n".join(collected_from_mines) # embed.add_field(name="Details", value=f"```{details}```", inline=False) except sqlite3.Error as e: db_connection.rollback() embed.color = discord.Color.red() embed.add_field(name="Database Error", value=f"Could not save collection data: {e}") except Exception as e: db_connection.rollback() embed.color = discord.Color.red() embed.add_field(name="Unexpected Error", value=f"An error occurred: {e}") else: # This case should only happen if all mines had level 0 or less embed.color = discord.Color.orange() embed.add_field(name="No Materials Collected", value="Your mines produced no materials this cycle (maybe they are level 0?).", inline=False) # Still update cooldown even if nothing was collected try: db_cursor.execute('INSERT OR REPLACE INTO collect_data (user_id, last_collect) VALUES (?, ?)', (user_id, current_time)) db_connection.commit() except sqlite3.Error as e: print(f"DB Error updating cooldown after 0 collection: {e}") # Log error db_connection.rollback() await ctx.send(embed=embed) @bot.command() async def process(ctx): """Processes raw materials into processed materials (Once every 24 hours)""" user_id = ctx.author.id embed = discord.Embed() db_cursor.execute('INSERT OR IGNORE INTO users (id) VALUES (?)', (user_id,)) db_connection.commit() db_cursor.execute('SELECT last_process FROM process_data WHERE user_id = ?', (user_id,)) last_process_data = db_cursor.fetchone() if last_process_data: last_process = last_process_data[0] else: last_process = 0 db_cursor.execute('SELECT level FROM factories WHERE user_id = ?', (user_id,)) factories = db_cursor.fetchall() if not factories: embed.color = discord.Color.red() embed.add_field(name="You do not own any factories to process raw resources.", value="\u200b") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed=embed) return time_since_process = int(time.time()) - last_process if time_since_process < 24 * 3600: next_process = last_process + 24 * 3600 embed.color = discord.Color.red() embed.add_field(name=f"You can process again ", value="\u200b") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed=embed) return db_cursor.execute('SELECT raw_materials FROM users WHERE id = ?', (user_id,)) user_data = db_cursor.fetchone() raw_materials = user_data[0] total_mat = 0 for factory in factories: factory_level = factory[0] if raw_materials <= 0: embed.color = discord.Color.red() embed.add_field(name="Not enough Raw Materials!", value=f"You need more raw materials to process. You currently have {raw_materials}.") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed = embed) return if factory_level == 1: processed_amount = random.randint(10, 30) mat = processed_amount // 10 if processed_amount % 10 > 7: mat += 1 embed.add_field(name="Bonus!", value="Your factory produced some bonus materials!", inline = False) if random.random() < 0.10: db_cursor.execute('DELETE FROM factories WHERE user_id = ? AND level = 1', (user_id,)) db_connection.commit() embed.add_field(name="Factory Collapsed!", value="Your level 1 factory has suffered catastrophic damage! It has been removed!", inline = False) break # Stop processing if factory breaks elif factory_level == 2: processed_amount = random.randint(20, 50) mat = processed_amount // 10 if processed_amount % 10 > 5: mat += 1 embed.add_field(name="Bonus!", value="Your factory produced some bonus materials!", inline=False) elif factory_level == 3: processed_amount = random.randint(40, 80) mat = processed_amount // 10 if processed_amount % 10 > 5: mat += 1 embed.add_field(name="Bonus!", value="Your factory produced some bonus materials!", inline=False) rand = random.random() if rand < 0.05: db_cursor.execute(f'UPDATE factories SET level = 2 WHERE user_id = ? AND level = 3', (user_id,)) db_connection.commit() embed.add_field(name="Downgrade!", value="Your level 3 factory has lost efficiency, reducing it to level 2.", inline=False) elif rand < 0.001: db_cursor.execute(f'UPDATE factories SET level = 4 WHERE user_id = ? AND level = 3', (user_id,)) db_connection.commit() embed.add_field(name="Upgrade!", value="Your level 3 factory has had an efficiency upgrade, increasing it to level 4.", inline=False) elif factory_level == 4: processed_amount = random.randint(50, 90) mat = processed_amount // 10 if processed_amount % 10 > 5: mat += 1 embed.add_field(name="Bonus!", value="Your factory produced some bonus materials!", inline=False) elif factory_level == 5: processed_amount = random.randint(60, 110) mat = processed_amount // 10 if processed_amount % 10 > 5: mat += 1 embed.add_field(name="Bonus!", value="Your factory produced some bonus materials!", inline=False) rand = random.random() if rand < 0.10: db_cursor.execute(f'UPDATE factories SET level = 4 WHERE user_id = ? AND level = 5', (user_id,)) db_connection.commit() embed.add_field(name="Downgrade!", value="Your level 5 factory has lost efficiency, reducing it to level 4.", inline=False) elif rand < 0.01: db_cursor.execute(f'UPDATE factories SET level = 3 WHERE user_id = ? AND level = 5', (user_id,)) db_connection.commit() embed.add_field(name="Downgrade!", value="Your level 5 factory has lost efficiency, reducing it to level 3.", inline=False) elif rand < 0.08: db_cursor.execute(f'UPDATE factories SET level = 6 WHERE user_id = ? AND level = 5', (user_id,)) db_connection.commit() embed.add_field(name="Upgrade!", value="Your level 5 factory has had an efficiency upgrade, increasing it to level 6!", inline=False) elif factory_level == 6: processed_amount = random.randint(70, 120) mat = processed_amount // 10 if processed_amount % 10 > 5: mat += 1 embed.add_field(name="Bonus!", value="Your factory produced some bonus materials!", inline=False) elif factory_level == 7: processed_amount = random.randint(80, 130) mat = processed_amount // 10 if processed_amount % 10 > 5: mat += 1 embed.add_field(name = "Bonus!", value="Your factory produced some bonus materials!", inline=False) elif factory_level == 8: processed_amount = random.randint(100, 150) mat = processed_amount // 10 if processed_amount % 10 > 5: mat += 1 embed.add_field(name="Bonus!", value="Your factory produced some bonus materials!", inline=False) if random.random() < 0.0001: db_cursor.execute(f'UPDATE factories SET level = 7 WHERE user_id = ? AND level = 8', (user_id,)) db_connection.commit() embed.add_field(name="Downgrade!", value="Your level 8 factory has lost efficiency, reducing it to level 7.", inline=False) else: mat = 0 raw_materials -= mat total_mat += mat db_cursor.execute('UPDATE users SET raw_materials = ? WHERE id = ?', (raw_materials, user_id)) db_cursor.execute('UPDATE users SET processed_materials = processed_materials + ? WHERE id = ?', (total_mat, user_id)) db_connection.commit() now = int(time.time()) db_cursor.execute('INSERT OR REPLACE INTO process_data (user_id, last_process) VALUES (?,?)', (user_id, now)) db_connection.commit() embed.color = discord.Color.green() embed.add_field(name=f"You processed {total_mat} raw resources into processed resources.", value="\u200b", inline=False) # Zero-width space for formatting embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed=embed) @bot.event async def on_command_error(ctx, error): if isinstance(error, commands.MissingRequiredArgument): await ctx.send(f"You're missing an argument, please check usage using *cmds {ctx.command.name}") elif isinstance(error, commands.BadArgument): await ctx.send(f"Invalid argument. Please check the order using *cmds {ctx.command.name}") elif isinstance(error, commands.CommandNotFound): await ctx.send(f"Command was not found. Please use *cmds for a list of all available commands.") else: print(f"An unhandled error occurred: {error}") await ctx.send("An unexpected error occurred. Please check the console or notify the administrator.") @bot.command(name="cmds") async def cmds(ctx): embed = discord.Embed(title="Available Commands", color=discord.Color.purple()) for command in bot.commands: if not command.hidden: embed.add_field(name=f"*{command.name}", value=f"{command.help or 'No description available.'}", inline=False) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar) await ctx.send(embed=embed) # Run bot with open('token.txt', 'r') as file: token = file.read().strip() bot.run(token)