So I tried everything I could to make my Discord Bot save the amount of money the users have that use him. But every time my Discord bot goes offline, every user is losing his whole money. here is the code: (the important part with saving the wallet and stuff is in the top)
import discord
from discord.ext import commands,tasks # Import 'tasks' separately
from datetime import datetime, timedelta
import random
import json
import youtube_dl
import os
import atexit
intents = discord.Intents.default()
intents.typing = False
intents.presences = False
DATA_FILE = os.path.join(os.path.expanduser('~'), 'Desktop', 'wallet_data.json')
if not os.path.exists(DATA_FILE):
with open(DATA_FILE, 'w') as file:
json.dump({}, file)
bot = commands.Bot(command_prefix='.', intents=discord.Intents.all())
TOKEN = 'MTE4NDkzMTMxNTM2NDE0NzI4Mg.GWByxt.jB2ofEdhI4VCKKI870Ao2maa2WWT-qkt7VA3Eg' # Replace with your bot token
user_wallets = {}
last_saved_wallets = {} # Keep track of the last saved wallet state
@tasks.loop(seconds=10)
async def autosave_wallet():
global user_wallets, last_saved_wallets
if user_wallets != last_saved_wallets:
try:
with open(DATA_FILE, 'w') as file:
json.dump(user_wallets, file, indent=4)
last_saved_wallets = user_wallets
print("Wallet data saved successfully.")
except Exception as e:
print(f"Error saving wallet data: {e}")
@autosave_wallet.before_loop
async def before_autosave_wallet():
print('Waiting for bot to be ready...')
await bot.wait_until_ready()
def save_wallet_on_exit():
global user_wallets
print('Bot is shutting down. Saving wallet data...')
try:
with open(DATA_FILE, 'w') as file:
json.dump(user_wallets, file, indent=4)
except Exception as e:
print(f"Error saving wallet data: {e}")
atexit.register(save_wallet_on_exit)
@bot.event
async def on_ready():
global user_wallets
print(f'We have logged in as {bot.user}')
try:
with open(DATA_FILE, 'r') as file:
user_wallets = json.load(file)
except FileNotFoundError:
user_wallets = {}
print("No wallet data file found. Starting with empty wallet data.")
# Ensure autosave loop is started
autosave_wallet.start()
user_command_usage = {}
# File to store command usage data
COMMANDS_FILE = 'commands_data.json'
@bot.event
async def on_ready():
print(f'We have logged in as {bot.user}')
# Load user command usage data from the file
try:
with open(COMMANDS_FILE, 'r') as file:
user_command_usage = json.load(file)
except FileNotFoundError:
user_command_usage = {}
@bot.event
async def on_disconnect():
# Save user command usage data to the file when the bot goes offline
with open(COMMANDS_FILE, 'w') as file:
json.dump(user_command_usage, file, indent=4)
@bot.event
async def on_disconnect():
# Save user wallet data to the file when the bot goes offline
with open(DATA_FILE, 'w') as file:
json.dump(user_wallets, file, indent=4)
@bot.event
async def on_shutdown():
# Save user wallet data to the file when the bot shuts down
with open(DATA_FILE, 'w') as file:
json.dump(user_wallets, file, indent=4)
@bot.command()
async def globalstats(ctx):
top_users = sorted(user_command_usage.items(), key=lambda x: x[1], reverse=True)[:10]
# Prepare the leaderboard message
leaderboard_message = "**Top 10 Users Global (Commands Used):**\n"
for index, (user_id, command_count) in enumerate(top_users):
user = bot.get_user(int(user_id))
username = user.display_name if user else "Unknown User"
if index == 0:
leaderboard_message += f":first_place: {username}: {command_count} commands\n"
elif index == 1:
leaderboard_message += f":second_place: {username}: {command_count} commands\n"
elif index == 2:
leaderboard_message += f":third_place: {username}: {command_count} commands\n"
else:
leaderboard_message += f"{username}: {command_count} commands\n"
await ctx.send(leaderboard_message)
@bot.command()
async def daily(ctx):
user_id = str(ctx.author.id)
if user_id not in user_wallets:
user_wallets[user_id] = 0
cooldown = 20 # hours
last_daily_time = user_wallets.get(user_id + "_daily", datetime.min)
remaining_time = last_daily_time + timedelta(hours=cooldown) - datetime.now()
remaining_hours, remaining_minutes = divmod(remaining_time.seconds, 3600)
remaining_minutes //= 60
if datetime.now() - last_daily_time >= timedelta(hours=cooldown):
amount = random.randint(250, 800)
user_wallets[user_id] += amount
user_wallets[user_id + "_daily"] = datetime.now()
await ctx.send(f"Received daily reward: ${amount}")
else:
await ctx.send(f"Cooldown not expired for daily reward. Try again in {remaining_hours} hours and {remaining_minutes} minutes.")
@bot.command()
async def join(ctx):
channel = ctx.author.voice.channel
await channel.connect()
@bot.command(name='ilian', aliases=['love', 'liebe', 'angela'])
async def command_love(ctx):
await ctx.send("Love you my Cutie <3 You will always be stuck in 2018 with me my sunshine <3")
@bot.command()
async def play(ctx, url):
voice_channel = ctx.author.voice.channel
vc = await voice_channel.connect()
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegVideo',
'preferredcodec': 'mp4',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=False)
url2 = info['formats'][0]['url']
vc.play(discord.FFmpegPCMAudio(url2))
@bot.command()
async def hourly(ctx):
user_id = str(ctx.author.id)
if user_id not in user_wallets:
user_wallets[user_id] = 0
cooldown = 1 # hour
last_hourly_time = user_wallets.get(user_id + "_hourly", datetime.min)
remaining_time = last_hourly_time + timedelta(hours=cooldown) - datetime.now()
remaining_hours, remaining_minutes = divmod(remaining_time.seconds, 3600)
remaining_minutes //= 60
if datetime.now() - last_hourly_time >= timedelta(hours=cooldown):
amount = random.randint(34, 59)
user_wallets[user_id] += amount
user_wallets[user_id + "_hourly"] = datetime.now()
await ctx.send(f"Received hourly reward: ${amount}")
else:
await ctx.send(f"Cooldown not expired for hourly reward. Try again in {remaining_hours} hours and {remaining_minutes} minutes.")
@bot.command()
async def loot(ctx):
user_id = str(ctx.author.id)
if user_id not in user_wallets:
user_wallets[user_id] = 0
# Determine the outcome based on the chances provided
outcome = random.choices(
['spoons', 'v9_battery', 'worm', 'baseball_bat', 'glue', 'tube', 'keyboard', 'car_wheel', 'steel_helmet', 'butterfly_marble_fade'],
weights=[10.00, 10.00, 30.00, 10.00, 10.00, 10.00, 5.00, 5.00, 9.96, 0.04]
)[0]
if outcome == 'spoons':
amount = 3
user_wallets[user_id] += amount
await ctx.send(f"You found spoons and earned: ${amount}")
elif outcome == 'v9_battery':
amount = 5
user_wallets[user_id] += amount
await ctx.send(f"You found a V9-Battery and earned: ${amount}")
elif outcome == 'worm':
amount = 1
user_wallets[user_id] += amount
await ctx.send(f"You found a worm and earned: ${amount}")
elif outcome == 'baseball_bat':
amount = 7
user_wallets[user_id] += amount
await ctx.send(f"You found a baseball bat and earned: ${amount}")
elif outcome == 'glue':
amount = 4
user_wallets[user_id] += amount
await ctx.send(f"You found 450g of glue and earned: ${amount}")
elif outcome == 'tube':
amount = 2
user_wallets[user_id] += amount
await ctx.send(f"You found a tube and earned: ${amount}")
elif outcome == 'keyboard':
amount = 20
user_wallets[user_id] += amount
await ctx.send(f"You found a keyboard and earned: ${amount}")
elif outcome == 'car_wheel':
amount = 22
user_wallets[user_id] += amount
await ctx.send(f"You found a car wheel and earned: ${amount}")
elif outcome == 'steel_helmet':
amount = 25
user_wallets[user_id] += amount
await ctx.send(f"You found a steel helmet and earned: ${amount}")
elif outcome == 'butterfly_marble_fade':
amount = 3337
user_wallets[user_id] += amount
await ctx.send(f"You found a Butterfly Marble Fade and earned: ${amount}")
@bot.command()
async def work(ctx):
user_id = str(ctx.author.id)
if user_id not in user_wallets:
user_wallets[user_id] = 0
cooldown = 10 # minutes
last_work_time = user_wallets.get(user_id + "_work", datetime.min)
remaining_time = last_work_time + timedelta(minutes=cooldown) - datetime.now()
remaining_minutes = remaining_time.seconds // 60
if datetime.now() - last_work_time >= timedelta(minutes=cooldown):
amount = random.randint(5, 20)
user_wallets[user_id] += amount
user_wallets[user_id + "_work"] = datetime.now()
await ctx.send(f"Earned money from work: ${amount}")
else:
await ctx.send(f"Cooldown not expired for work. Try again in {remaining_minutes} minutes.")
@bot.command()
async def slots(ctx, bet: int):
user_id = str(ctx.author.id)
if user_id not in user_wallets:
user_wallets[user_id] = 0
# Check if the user has enough money to place the bet
if user_wallets[user_id] >= bet:
user_wallets[user_id] -= bet
# Determine the outcome based on the chances provided
outcome = random.choices(['win', 'lose', 'blessed', 'cs_knife'], weights=[0.49, 0.49, 0.0096, 0.0004])[0]
if outcome == 'win':
user_wallets[user_id] += 2 * bet
await ctx.send(f"You won! Doubled your bet: ${2 * bet}")
elif outcome == 'blessed':
user_wallets[user_id] += 10 * bet
await ctx.send(f"You got blessed by the Universe -> 10x your bet!")
elif outcome == 'cs_knife':
user_wallets[user_id] += 500 * bet
await ctx.send(f"x500 !!!!! The Chances of hitting this are 0.04% which is similar to pulling a CS Knife!")
else:
await ctx.send(f"You lost. Better luck next time!")
else:
await ctx.send("Insufficient funds to place the bet.")
@bot.command()
async def money(ctx):
user_id = str(ctx.author.id)
if user_id not in user_wallets:
user_wallets[user_id] = 0
await ctx.send(f"Your current wallet balance: ${user_wallets[user_id]}")
@bot.command()
async def top(ctx):
top_users = sorted(user_wallets.items(), key=lambda x: x[1] if isinstance(x[1], int) else 0, reverse=True)[:10]
# Prepare the leaderboard message
leaderboard_message = "**Top 10 Users Global:**\n"
for index, (user_id, money) in enumerate(top_users):
user = bot.get_user(int(user_id))
username = user.display_name if user else "Unknown User"
if index == 0:
leaderboard_message += f":first_place: {username}: ${money}\n"
elif index == 1:
leaderboard_message += f":second_place: {username}: ${money}\n"
elif index == 2:
leaderboard_message += f":third_place: {username}: ${money}\n"
else:
leaderboard_message += f"{username}: ${money}\n"
await ctx.send(leaderboard_message)
@bot.command()
async def givemoney(ctx, username: discord.Member, amount: int):
sender_id = str(ctx.author.id)
recipient_id = str(username.id)
# Check if the sender and recipient are different users
if sender_id != recipient_id:
# Check if the sender has enough money to send
if user_wallets.get(sender_id, 0) >= amount > 0:
# Deduct money from the sender
user_wallets[sender_id] -= amount
# Add money to the recipient
if recipient_id not in user_wallets:
user_wallets[recipient_id] = 0
user_wallets[recipient_id] += amount
await ctx.send(f"Successfully sent ${amount} to {username.display_name}.")
else:
await ctx.send("Invalid amount or insufficient funds to send money.")
else:
await ctx.send("Cannot send money to yourself.")
DATA_FILE = 'wallet_data.json'
# Load user wallet data from the file
try:
with open(DATA_FILE, 'r') as file:
user_wallets = json.load(file)
except FileNotFoundError:
user_wallets = {}
@bot.event
async def on_ready():
print(f'We have logged in as {bot.user}')
@bot.event
async def on_disconnect():
# Save user wallet data to the file when the bot goes offline
with open(DATA_FILE, 'w') as file:
json.dump(user_wallets, file, indent=4)
Rest of your code…
Ensure that the following line is aligned with the outermost indentation
bot.run(TOKEN)