我的整个代码:
from discord.ext.commands import Bot, CheckFailure, has_role
import discord
import os
import random
from replit import db
from keep_alive import keep_alive
from statistics import mode
from operators import embeds
from datetime import date
#embed preset
'''
embed = discord.Embed(title="title", description="desc", color=PURPLE)
embed.set_author(name="Jäger Bot", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="name", value="value", inline=True)
embed.set_footer(text="requested by " + authormention + "| " + send_date)
await ctx.send(embed=embed)
'''
bot = Bot(command_prefix="j!", help_command=None)
# bot ready and activity
@bot.event
async def on_ready():
print("Bot started")
game = discord.Game("with Jäger")
await bot.change_presence(status=discord.Status.online, activity=game)
# --------------------
PURPLE = 0x800080
STAFF_ROLE_ID = 817476654297383002
SOTW_ROLE_ID = 817458661982994463
FORMER_SOTW_ROLE_ID = 817030310663028736
JAGER_ROLE_ID = 818950349016137739
today = date.today()
global is_voting
is_voting = False
global send_date
send_date = today.strftime("%d-%m-%Y")
#update db
@bot.event
async def update_db(key, value):
if key in db.keys():
old_value = db[key]
old_value.append(value)
db[key] = old_value
else:
db[key] = [value]
#keys:
#nominating_perons ppl who have nominated
#nominated_persons ppl who have been nominated
#voting_perons ppl who have voted
#voted_persons ppl who have been voted for
#----commands----
#help
@bot.command()
async def help(ctx ,category=None):
print("command: help")
staff_category = "staff"
sotw_category = "sotw"
misc_category = "misc"
if category is None:
print("no category")
embed = discord.Embed(title="Select a category with `j!help \"category\"`", description="Prefix = j!", color=PURPLE)
embed.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="Categories:", value="`staff` `sotw` `misc`", inline=True)
embed.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=embed)
else:
if category == staff_category:
print("staffhelp")
staff = discord.Embed(title="Staff commands", description="prefix = j!", color=PURPLE)
staff.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
staff.add_field(name="startvote", value="Starts the voting process", inline=False)
staff.add_field(name="finishvote", value="Finishes the voting process", inline=False)
staff.add_field(name="list <key> | debug only", value="Shows all the items in a specific list", inline=False)
staff.add_field(name="clear <key> | debug only", value="Clears all the items in a specific list", inline=False)
staff.add_field(name="ph <key> | debug only", value="Adds a `place_holder` to a specific list", inline=False)
staff.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=staff)
else:
if category == sotw_category:
print("sotwhelp")
sotw = discord.Embed(title="Sotw commands", description="prefix = j!", color=PURPLE)
sotw.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
sotw.add_field(name="nominate <member>", value="Nominate a member", inline=False)
sotw.add_field(name="vote <member>", value="Vote for a member", inline=False)
sotw.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=sotw)
else:
if category == misc_category:
print("mischelp")
misc = discord.Embed(title="Misc commands", description="prefix = j!", color=PURPLE)
misc.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
misc.add_field(name="quote", value="A random siege operator quote", inline=False)
misc.add_field(name="profile <operator>", value="Shows the profile of the specified siege operator", inline=True)
misc.add_field(name="shoot <member>", value="Shoot someone", inline=False)
misc.add_field(name="sexy <member>", value="Shows how sexy someone is", inline=False)
misc.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=misc)
else:
print("wrong category")
embed = discord.Embed(title="Select a category with `j!help \"category\"`", description="Prefix = j!", color=PURPLE)
embed.set_author(name="Jäger Bot | Help menu", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="Categories:", value="`staff` `sotw` `miscellaneous`", inline=True)
embed.set_footer(text="Made by ZoutigeWolf#0002 | Big thx to gang#5039 for helping")
await ctx.send(embed=embed)
#help end
#SOTW
#nominate
@bot.command()
async def nominate(ctx, nominatedperson: discord.Member):
print("command: nominate")
print(nominatedperson)
nominated_person = nominatedperson.mention
nominating_person = ctx.author.mention
former_sotw_role = discord.utils.get(ctx.guild.roles, id=FORMER_SOTW_ROLE_ID)
if not is_voting:
print("is_voting was false")
nominated_persons = db["nominated_persons"]
nominating_persons = db["nominating_persons"]
if nominating_person not in nominating_persons:
print("nominating person wasnt in nominating persons")
if nominated_person in nominated_persons:
print("nominated_person was in nominated_persons")
await ctx.send("That member has already been nominated!")
else:
print("nominated_person wasnt in nominated_persons")
former_sotw_role = discord.utils.get(ctx.guild.roles, id=FORMER_SOTW_ROLE_ID)
if former_sotw_role in nominatedperson.roles:
print("nominated_person was former sotw")
await ctx.send("That member has already been SOTW this year!")
else:
print("nominated_person wasnt former sotw")
embed = discord.Embed(title="Member nominated:", description=nominated_person, color=PURPLE)
embed.set_author(name="Jäger Bot", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="By:", value=nominating_person, inline=True)
embed.set_footer(text=send_date)
print(nominated_persons)
await update_db(nominated_persons, nominated_person)
await update_db(nominating_persons, nominating_person)
await ctx.send(embed=embed)
else:
print("nominating_person was in nominating_persons")
await ctx.send("You already nominated someone")
else:
print("is_voting was true")
await ctx.send("You can't nominate while we are voting for the next SOTW!")
#nominate end
#SOTW end
#insert place_holder
@bot.command()
@has_role(STAFF_ROLE_ID)
async def ph(ctx, key):
print("command: ph")
await update_db(key, "place_holder")
await ctx.send("Placeholder has been added to " + key)
@ph.error
async def ph_error(ctx, error):
if isinstance(error, CheckFailure):
await ctx.send("Only staff members can use this command")
#insert place_holder end
#list
@bot.command()
@has_role(STAFF_ROLE_ID)
async def list(ctx, to_list):
print("command: list")
if to_list in db.keys():
requester = ctx.author
requestermention = str(requester)
items = db[to_list]
embed = discord.Embed(title="List", description=to_list, color=PURPLE)
embed.set_author(name="Jäger Bot", icon_url="https://cdn.discordapp.com/avatars/816636186323189780/019dbb41d6f5b301c1fce6980d487f23.webp?size=128")
embed.add_field(name="Items:", value=items, inline=True)
embed.set_footer(text="requested by " + requestermention + " | " + send_date)
await ctx.send(embed=embed)
else:
await ctx.send("That list doesn't exist")
@list.error
async def list_error(ctx, error):
if isinstance(error, CheckFailure):
await ctx.send("Only staff members can use this command")
#list end
#list keys
@bot.command()
async def keys(ctx):
allkeys = db.keys()
await ctx.send(allkeys)
#list keys end
#clear
@bot.command()
@has_role(STAFF_ROLE_ID)
async def clear(ctx, to_clear):
print("command: clear")
str_userid = ctx.author.id
str_zoutigewolfid = "298516275322290188"
userid = int(str_userid)
zoutigewolfid = int(str_zoutigewolfid)
if userid == zoutigewolfid:
if to_clear in db.keys():
del db[to_clear]
await ctx.send("List " + to_clear + " has been cleared")
else:
await ctx.send("That list doesn't exist")
else:
await ctx.send("Only my daddy Wolf can use this command!")
@clear.error
async def clear_error(ctx, error):
if isinstance(error, CheckFailure):
await ctx.send("Only staff members can use this command")
#clear end
#quote
# preset {"title": "", "description": ""},
quotes_list = [
{"title": "A really big fucking hole coming right up!", "description": "Jordan 'Thermite' Trace"},
{"title": "Pass those plates around!", "description":"Julien 'Rook' Nizan"},
{"title": "You can stop worrying about grenades now!", "description": "Marius 'Jäger' Streicher"},
{"title": "if it runs on batteries, I'll see it!", "description": "Monica 'IQ' Weiss"},
{"title": "Fookin' laser sights!", "description": "Mike 'Thatcher' Baker"},
{"title": "Toxic babes are in position!", "description": "James 'Smoke' Porter"},
{"title": "Jammah in position!", "description": "Mark 'Mute' R. Chandar"},
{"title": "EDD primed, let them come!", "description": "Maxim 'Kapkan' Basuda"},
{"title": "Mine flying out!", "description": "Elżbieta 'Ela' Bosak"},
{"title": "You're mine bloody asshole!", "description": "Taina 'Caveira' Pereira"},
{"title": "Malbodan haengdong-iji (말보단 행동이지)", "description": "Chul 'Vigil' Kyung Hwa"},
{"title": "Launching override!", "description": "Grace 'Dokkaebi' Nam"},
{"title": "Camera in position!", "description": "Meghan 'Valkyrie' J. Castellano"},
{"title": "As my friend would say: A really big fucking hole coming right up.", "description": "Yumiko 'Hibana' Imagawa"},
{"title": "Big brother coming in for overwatch!", "description": "Olivier 'Lion' Flament"},
{"title": "Time for a wakeup call", "description": "Grace 'Dokkaebi' Nam"},
{"title": "No runnin' in the halls!", "description": "Morowa 'Clash' Evans"},
{"title": "LMG mounted and loaded!", "description": "Alexsandr 'Tachanka' Senaviev, RIP old tachanka"},
{"title": "Rtila active!", "description": "Jalal 'Kaid' El Fassi"},
{"title": "Now you see me, now you don't!", "description": "Elena 'Mira' María Álvarez"},
{"title": "Why do it yourself when robots do it better?", "description": "Masaru 'Echo' Enatsu"},
{"title": "Bullseye, got us a drone", "description": "Max 'Mozzie' Goose"},
]
@bot.command()
async def quote(ctx):
requester = ctx.author
requestermention = str(requester)
random_index = random.randint(0,21)
quote = quotes_list[random_index]
embed = discord.Embed(**quote, color=PURPLE)
embed.set_footer(text="Requested by " + requestermention + " | " + send_date)
await ctx.send(embed=embed)
#quote end
#operator profile
@bot.command()
async def profile(ctx, operator_name):
await ctx.send(embed=embeds[operator_name])
#operator profile end
#sexy
@bot.command()
async def sexy(ctx, person: discord.Member):
jager_role = discord.utils.get(ctx.guild.roles, id=JAGER_ROLE_ID)
sexyperson = person.mention
if jager_role in person.roles:
print("person was jager")
embed = discord.Embed(title="Sexy meter", description="Lord Jäger is 69420% sexy", color=PURPLE)
await ctx.send(embed=embed)
else:
print("person wasnt jager")
outputint = random.randint(0,100)
output = str(outputint)
embed = discord.Embed(title="Sexy meter", description=sexyperson + " is " + output + "% sexy", color=PURPLE)
await ctx.send(embed=embed)
#sexy end
#gun list
guns_list = [
"MP5",
"M4",
"AK-47",
"MP7",
"SCAR-L",
"Desert Eagle",
"MP5K",
"AUG A2",
"M249",
"AR15"
]
#title list
title_list = [
"Elimination",
"Homicide",
"Assasination",
"Drive-by",
"Sniped",
"Popped",
"Capped",
"No-scoped",
]
#shoot
@bot.command()
async def shoot(ctx, person: discord.Member):
print("command: shoot")
shooter = ctx.author.mention
shotperson = person.mention
shooterid = ctx.author.id
shotpersonid = person.id
randomnumber = random.randint(0,9)
randomgun = guns_list[randomnumber]
randomtitlenumber = random.randint(0,7)
title = title_list[randomtitlenumber]
if shooterid != shotpersonid:
embed = discord.Embed(title=title, description=shooter + " shot " + shotperson + " with " + randomgun, color=PURPLE)
await ctx.send(embed=embed)
else:
await ctx.send("Shooting yourself is a very dumb idea")
#shoot end
#anti nword
racist_words = [
"nigga",
"niggas",
"nigger",
"niggers",
"/Vigga",
"/Viggas",
"/Vigger",
"/Viggers",
"niga",
"nega",
"negga",
"nibba",
"/vigga",
"/viggas",
"/vigger",
"/viggers",
]
# racist detector 9000
"""
@bot.event
async def on_message(msg):
if any(word in msg.content for word in racist_words):
print("someone said the n word")
await msg.channel.send(msg.author.mention + " did you just seriously say the n-word?")
await msg.channel.send("Not poggers bro, not poggers")
await msg.channel.send(f"<@&{STAFF_ROLE_ID}> come get this bitch")
await msg.delete()
await bot.process_commands(msg)
"""
#racist end
#commands end
keep_alive()
bot.run(os.getenv("TOKEN"))
当我执行命令 j!nominate @discord 时,它会给出错误“命令引发异常:TypeError: unhashable type: 'list'”但不记得对任何列表进行哈希处理。有人可以告诉我为什么会这样吗?如果你需要知道,数据库的格式是这样的 ["1", "2", "3"]
错误:
Ignoring exception in command nominate:
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 148, in nominate
await update_db(nominated_persons, nominated_person)
File "main.py", line 53, in update_db
db[key] = [value]
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 182, in __setitem__
r = self.sess.post(self.db_url, data={key: j})
TypeError: unhashable type: 'list'
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: TypeError: unhashable type: 'list'
答案 0 :(得分:0)
未经测试但请尝试以下操作
async def update_db(key, value):
if key in db.keys():
db[key].append(value)
else:
db[key] = [value]
通过比较我的代码和你的代码,你能明白为什么你会得到 TypeError 吗?
答案 1 :(得分:0)
好的,感谢您使用完整代码和回溯更新问题。
违规行是 db[key] = [value]
,它抛出一个 TypeError
:unhashable type list
,
这意味着您传递了一个列表类型作为 update_db
函数的关键参数。
这是不可能的,因为正如回溯明确指出的那样,您无法对列表类型进行哈希处理(这意味着您无法使用列表类型的键访问字典值)。
但痛苦的真正根源就在那条线之上:
if key in db.keys():
key = db[key]
key.append(value)
db[key] = key
那是很多key
,不是吗?这里的问题是你用变量名 key
指代不同的东西,结果有点混乱,所以我建议你用不同的变量来表示不同的东西:
async def update_db(key, value):
if key in db.keys():
old_value = db[key]
old_value.append(value)
db[key] = old_value
else:
db[key] = [value]
这样一来,数据库中实际更新的是 value
而不是 key
,因此后者永远不会成为列表。
最后一个只是出于好奇。你为什么要定义一个函数来更新数据库,没有定义的方法来做到这一点吗?你用的是什么数据库?
答案 2 :(得分:0)
我找到了答案!
问题出在await update_db(nominated_persons, nominated_person)
就像那样,它不会更新数据库,因为 nominated_persons
未定义,所以我用 nominated_persons = db["nominated_persons"]
定义了它。但后来我会得到哈希错误,因为这是一个列表,我不能使用它,所以我只是做了 nominated_persons = "nominated_persons"
所以 nominated_persons 被定义为“nominated_persons”这个词。所以现在它起作用了
我觉得自己好傻
这是更新的代码:
@bot.command()
async def nominate(ctx, nominatedperson: discord.Member):
print("command: nominate")
nominated_person = nominatedperson.mention
nominated_persons = "nominated_persons"
await update_db(nominated_persons, nominated_person)
await ctx.send("whatever")
(旁注:你可以在 update_db 命令中加入“nominated_persons”,你不必像我那样用变量来引用它。)