Reputation: 93
I am trying to figure out how to make my bot differentiate between sending a response through that chatroom, or sending a response through PMs. At the moment, it seems to be doing both for the name
method. I can use the !name command in the chatroom, or in a Direct Message to the Bot, and it will always respond in such (If sent in chat, will respond in chat. If sent in PM, will respond in PM)
For the stats
command, it at least only responds in PMs, regardless of if the !stat command is used in chat, or in PM.
I read around in documentations that if you set the decorator to no_pm=True
then that command is forbidden to be ran in PMs, but it still runs in the case of the name
method.
BotCommands.py
import discord
import os
from discord.ext import commands
token = open("token.txt", "r").read()
client = commands.Bot(command_prefix = '!')
@client.command()
async def load(ctx, extension):
client.load_extension("cogs." + extension)
@client.command()
async def unload(ctx, extension):
client.unload_extension("cogs." + extension)
for filename in os.listdir("./cogs"):
if filename.endswith('.py'):
client.load_extension("cogs." + filename[:-3])
client.run(token)
charCreation.py
import discord
from discord.ext import commands
import os
import json
from pathlib import Path
class Character(commands.Cog):
def __init__(self, client):
self.client = client
@commands.Cog.listener()
async def on_ready(self):
print("Bot is Online")
@commands.command(on_pm=True)
async def name(self, ctx, name):
player = str(ctx.message.author)
path = os.getcwd()
charFolder = os.path.join(path + "/characters/")
charFile = Path(charFolder + player + ".txt")
# Get the name of character being created
if charFile.is_file():
await ctx.send("You've already created a character, dumbass.")
else:
await ctx.send("I did it!")
await ctx.send("Your character name is: " + name)
await ctx.send("Your character sheet has been created.")
levelDict = {1: [25, 1, 6, 15, 2, 1, 5, 75]}
characterFile = {}
level = 1
xp = 0
characterFile["name"] = name
characterFile["level"] = level
hp = levelDict[1][0]
characterFile["hp"] = hp
tFeats = levelDict[1][4]
characterFile["total feats"] = tFeats
numberOfDice = levelDict[1][1]
numberOfSides = levelDict[1][2]
characterFile["base damage"] = str(numberOfDice) + "d" + str(numberOfSides)
characterFile["hit"] = levelDict[1][5]
characterFile["damage"] = levelDict[1][5]
characterFile["ac"] = levelDict[1][6]
characterFile["currentxp"] = xp
nextLevel = levelDict[1][7]
characterFile["nextlevel"] = nextLevel
characterFile["strength"] = 0
characterFile["dexterity"] = 0
characterFile["constitution"] = 0
characterFile["remaining feats"] = 2
ap = levelDict[1][3]
characterFile["total ap"] = ap
hasTaken = []
characterFile["feats taken"] = hasTaken
file = open(charFolder + player + ".txt", "w", encoding="utf-8")
json.dump(characterFile, file, ensure_ascii=False, indent=2)
await ctx.send("PM me with '!stats <str> <dex> <con>' to set your abilities. Wouldn't want everyone "
"to see your secrets, would we?")
@commands.command()
async def stats(self, ctx, strength, dexterity, constitution):
private = ctx.author.send
player = str(ctx.message.author)
path = os.getcwd()
charFolder = os.path.join(path + "/characters/")
charFile = Path(charFolder + player + ".txt")
if not charFile.is_file():
await private("You don't even have a character created yet. Type !name <name> in the room. "
"Where <name> is your character's actual name. (Example: !name Joe")
else:
strMod = int(int(strength) / 2)
dexMod = int(int(dexterity) / 2)
conMod = int(int(constitution) * 5)
print(strMod, dexMod, conMod)
await private("Allocating the following: \n\n"
"Strength: " + strength + " (+" + str(strMod) + " bonus to hit and damage.)\n"
"Dexterity: " + dexterity + " (+" + str(dexMod) + " bonus to armor class.)\n"
"Constitution: " + constitution + " (+" + str(conMod) + " bonus to armor class.)\n")
with open(charFolder + player + ".txt", "r+", encoding="utf-8") as file:
print("Am I here?")
charData = json.load(file)
charData["strength"] = int(strength)
charData["dexterity"] = int(dexterity)
charData["constitution"] = int(constitution)
charData["hit"] = int(charData["hit"] + strMod)
charData["damage"] = int(charData["damage"] + strMod)
charData["ac"] = int(charData["ac"] + dexMod)
charData["hp"] = int(charData["hp"] + conMod)
file.seek(0)
file.write(json.dumps(charData, ensure_ascii=False, indent=2))
file.truncate()
file.close()
I want the name
method to ONLY work in the chatroom, and NEVER work in PMs; and the stats
command to ONLY work in PMs, and NEVER work in the chatroom. In fact, if possible, I want the bot to respond with something to the effect of 'The !stats command MUST be used in a PM with me' should it ever be attempted to be used in a chatroom.
Upvotes: 0
Views: 80
Reputation: 60944
You're looking for the guild_only
and dm_only
checks. Usage would be something like:
@commands.command()
@commands.guild_only()
async def name(self, ctx, name):
...
@name.error
async def name_error(ctx, error):
if isinstance(error, commands.NoPrivateMessage):
await ctx.send("The command !name may not be used in a private channel!")
else:
raise error
Upvotes: 1