问题描述
所以我正在为我的服务器开发带有 discord.py 的不和谐机器人.我正在使用replit的数据库系统.当我尝试将我的类 Player 的实例添加到该数据库的键时,它说:
So I'm developing discord bot with discord.py for my server. I'm using replit's database system. When I try to add instance of my class Player to key of that database it says:
Traceback (most recent call last): File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 85, in wrapped ret = await coro(*args, **kwargs) File "main.py", line 36, in jointothefun db[f"{context.message.author.id}"] = p File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 486, in __setitem__ self.set(key, value) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 495, in set self.set_raw(key, _dumps(value)) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 56, in dumps return json.dumps(val, separators=(",", ":"), cls=DBJSONEncoder) File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps return cls( File "/usr/lib/python3.8/json/encoder.py", line 199, in encode chunks = self.iterencode(o, _one_shot=True) File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode return _iterencode(o, 0) ValueError: Circular reference detected The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/bot.py", line 902, in invoke await ctx.command.invoke(ctx) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 864, in invoke await injected(*ctx.args, **ctx.kwargs) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/ext/commands/core.py", line 94, in wrapped raise CommandInvokeError(exc) from exc discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ValueError: Circular reference detected
我不知道为什么它根本不起作用.有人可以帮忙吗?
I have no idea why it's not working at all. Some one could help?
哦,还有源代码(是的,我知道我正在制作意大利面条代码)
Oh and source code (yes i know i'm making spaghetti code)
机器人的主文件
from discord.ext import commands from replit import db from alive import startup from playerclass import Player print(db.keys()) class PlayerClient(discord.Client): async def on_member_join(self,member): print(f"{member} joined") async def on_ready(self): print("Bot ready to work!") def __init__(self): self.intents = discord.Intents(messages = True, guilds = True, reactions = True, members = True, presences = True) self.bot = commands.Bot(command_prefix = '~rpg ', intents = intents) intents = discord.Intents(messages = True, guilds = True, reactions = True, members = True, presences = True) client = bot = commands.Bot(command_prefix = '~rpg ', intents = intents) @client.command(name='join') async def jointothefun(context): keys = db.keys() rpgc = client.get_channel(811518285634863124) if context.message.channel == rpgc: if not f"{context.message.author.id}" in keys: await context.message.channel.send("Hi "+str(context.message.author.mention)) #not working code db[f"{context.message.author.id}"] = Player(100,0,0,0,0,1) else: await context.message.channel.send("Bruh you've joined already") else: await context.message.channel.send('Yo wrong channel!') @client.command(name='stats') async def stats(context): rpgc = client.get_channel(811518285634863124) if context.message.channel==rpgc: keys = db.keys() if str(context.message.author.id) in keys: embed=db[str(context.message.author.id)].displayEquipment await context.send(embed=embed) else: await context.message.channel.send("Join first to access stats!") else: await context.message.channel.send(f"XD {context.message.author.mention} to nie ten kana?! Pisz na #rpg") @client.command() async def ping(ctx): await ctx.send("Pong!") startup() #yes i know that will not work but it's private i guess it's obvious client.run("my bot token")
播放器类
from item_class import Weapon import discord class Player: def __init__(self,h,m,de,c,t,dm): self.hp=h self.mana=m self.defense=de self.coins=c self.truecoins=t self.weapon=Weapon("Stick",10,1,1,100,1,0) self.dmg=dm+self.weapon.dmg self.itlist=[] def addItemToEq(self,it): self.itlist.append(it) def displayEquipment(self,client,context): embed = discord.Embed( title="Inventory",colour=discord.Colour.Green) for i in self.itlist: if type(i)==Weapon: embed.add_field(i.self.name,"Weapon",False) else: embed.add_field(i.self.name,"Item",False) return embed
物品类别
import random class Item: def __init__(self,name): self.name = name def use(self): print("its normal item bruh") class Food(Item): def __init__(self,name,nutrition): self.name=name self.hpboost=nutrition class Weapon(Item): def __init__(self,name,durablity,dmgboost,critchcmin,critchcmax,crit,boost): self.name=name self.durablity=durablity self.dmg=dmgboost self.critmin=critchcmin self.critmax=critchcmax self.critdmg=crit self.fnc=boost def attack(self): print(self.dmg) print(str(self.calcCrit())) self.durablity-=1 def calcCrit(self): if random.randint(self.critmin,self.critmax)<=self.critmax/2: return True else: return False def useBoost(self): self.boost()
如果有人能帮助我,我将不胜感激:)
I would be so grateful if someone would help me :)
推荐答案
如回答 here,值 的 repli 数据库必须是 JSON 可序列化的.这意味着,您必须(很可能)传递一个 dict 而不是类对象,但是您将无法使用该对象的函数.
as answered here, the values of replit's database must be JSON-serializable. This means, you'd have to pass (most likely) a dict instead of a class object, but then you won't be able to use the object's functions.