Skip to content
This repository has been archived by the owner on Oct 12, 2024. It is now read-only.

Commit

Permalink
Add Cheating Methods, and admin commands (#9)
Browse files Browse the repository at this point in the history
* Admin commands & cheating methods (#7)

* anti spam reaction 

---------

Co-authored-by: Saprinox <pierreemmanuel.marrel@gmail.com>
Co-authored-by: ekomlenovic <emilien.komlenovic@gmail.com>

* Clean code (#8)
  • Loading branch information
ekomlenovic authored Mar 31, 2023
1 parent 7ec57e9 commit 18fa53b
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 77 deletions.
11 changes: 8 additions & 3 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ In **config.json** put your discord bot token in
{
"token": "Your_Bot_Token_Or_Ask_Me_For_It",
"prefix": "!",
"min": 1
"min": 1,
"role" : "The_Role_Optionnal_if_you_have_admin_permission"
}
```
You can also modify the min and the prefix of le bot

**Or go in [release tab](https://github.com/ekomlenovic/RPG-Random-Bot/releases) and download .exe**
And add it to your server : **https://discord.com/oauth2/authorize?client_id=900518092944326686&scope=bot&permissions=8**
And add it to your server :
**https://discord.com/oauth2/authorize?client_id=900518092944326686&scope=bot&permissions=8**

## Usage

Expand All @@ -37,6 +39,9 @@ When the Bot joins your server, you can use the following commands:
```python
!help to see commands
!r [number of sides] # example: !r 20 it's beween 0 and 20
!!!!!!!!!!!!!HIDDEN COMMANDS !!!!!!!!!!!!!
!cheat [NAME] min max # This command creates piped dice for the user
!clear_cheat [NAME] | !cc [NAME] #Clear the cheating dictionnary of the user
```

## Contributing
Expand All @@ -50,7 +55,7 @@ Please make sure to update tests as appropriate.

## Contributor

Special thanks to Saprinox
Special thanks to [Saprinox](https://github.com/Saprinox)

## License

Expand Down
2 changes: 0 additions & 2 deletions bot/commands_aux.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def plot_aux(ctx, name, data):
ax.set_ylabel('Frequency')
ax.set_xticks(bins)
ax.set_title(f'{name}_statistics({plot_data["Number of Rolls"]} rolls)')
#plt.show()
fig.savefig(f"{ctx.guild.name}/users/{name}_plot.png")


Expand Down Expand Up @@ -129,7 +128,6 @@ def stat_player_value(ctx, data):
ax.set_ylabel('Value')
plt.title('Rolls Comparison')
plt.legend()
#plt.show()
fig.savefig(f"{ctx.guild.name}/compare.png")

return f"{ctx.guild.name}/compare.png"
178 changes: 116 additions & 62 deletions bot/commands_discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
TOKEN = config['token']
PREFIX = config['prefix']
MIN = config['min']
ROLE = config['role']

processed_reactions = {}

class Mybot(commands.Bot):
async def on_ready(self):
Expand All @@ -49,89 +52,130 @@ async def on_ready(self):
bot = Mybot(command_prefix=PREFIX,intents=intents)

data = {}
cheating_dictionary = {}

@bot.command(
description='This command rolls a random number between 0 and the specified number (default: 100). For example, to roll a number between 0 and 50, you can use the command "!r 50".',
help='This command rolls a random number between 0 and the specified number (default: 100). For example, to roll a number between 0 and 50, you can use the command "!r 50".'
)
async def r(ctx, number: int = 100):
async def r(ctx, max_: int = 100):
if max_ < 0:
max_ *= -1
if max_ <= MIN:
x = await ctx.send(f"```Your number cannot be less than the minimum which is {str(MIN)} ...```")
return
r_min = MIN
r_max = max_
if ctx.author.display_name in cheating_dictionary.keys():
r_min = int(cheating_dictionary [ctx.author.display_name] [0] / 100 * max_)
r_max = int(cheating_dictionary [ctx.author.display_name] [1] / 100 * max_)
if not os.path.exists(ctx.guild.name):
os.makedirs(ctx.guild.name)
value = random.randrange(MIN, number+1)
_value = value / number * 100
value = random.randrange(r_min, r_max+1)
_value = value / r_max * 100
user = ctx.author.display_name
update_csv(ctx, user, _value, loadCSV(ctx))
x = await ctx.send(f"```{ctx.author.display_name} "+ made + str(value) + space + on + "[" + str(number) + "]```")
x = await ctx.send(f"```{ctx.author.display_name} {made} {str(value)} {on} [{str(max_)}]```")
await ctx.message.delete()

if value == MIN:
await x.add_reaction('\N{CROSS MARK}')
elif value == number:
elif value == max_:
await x.add_reaction('\N{WHITE HEAVY CHECK MARK}')


@bot.command(
description='Deletes all images generated by !stat command in the current server',
help='This command deletes all images generated by !stat command in the current server. To use this command, type "!clear_images".'
description = 'Cheating command, This command creates piped dice for the user like this !cheat NAME min max',
help = 'This command creates piped dice for the user, the command like this !cheat NAME min max',
hidden=True
)
async def clear_image(ctx):
file_list = os.listdir(f"{ctx.guild.name}/users/")
png_files = [f for f in file_list if f.endswith('.png')]
for file_name in png_files:
file_path = os.path.join(f"{ctx.guild.name}/users/", file_name)
os.remove(file_path)
os.remove(f"{ctx.guild.name}/statistic.png")
await ctx.message.delete()
await ctx.send('Clear successful !')


async def cheat(ctx, name, min:int, max:int):
if ctx.author.guild_permissions.manage_roles or discord.utils.get(ctx.author.roles, name = ROLE):
cheating_dictionary [name] = [min, max]
await ctx.message.delete()
else:
await ctx.send("This command do not exist.")
@bot.command(
name='save',
description='Saves the current plot data to a folder',
help='This command saves the current data, you can use the command "!s".'
name = 'clear_cheat',
aliases=['cc'],
description = 'Clear the cheating dictionnary',
help = 'Clear the cheating dictionnary, like this !clear_cheat NAME, you also can use !cc NAME',
hidden=True
)
async def save(ctx):
now = datetime.now()
folder_name = now.strftime("%Y-%m-%d %H.%M")
async def clear_cheating_dictionnary(ctx, name):
if ctx.author.guild_permissions.manage_roles or discord.utils.get(ctx.author.roles, name = ROLE):
if cheating_dictionary [name] is not None:
cheating_dictionary.pop(name)
await ctx.message.delete()
else:
await ctx.send("This command do not exist.")

file_path = ctx.guild.name+"/save/" + folder_name

# Create the save folder if it doesn't exist
if not os.path.exists(file_path):
os.makedirs(file_path)

try:
@bot.command(
name='clear',
aliases=['c'],
description='Deletes all images generated by !stat command in the current server',
help='This command deletes all images generated by !stat command in the current server. To use this command, type "!clear"., you also can use !c.'
)
async def clear_image(ctx):
if ctx.author.guild_permissions.manage_roles or discord.utils.get(ctx.author.roles, name = ROLE):
# Code pour la commande
file_list = os.listdir(f"{ctx.guild.name}/users/")
# Calculate the total width and maximum height of the result image
png_files = [f for f in file_list if f.endswith('.png')]
for file_name in png_files:
# Save the png image to a file in the save folder
with open(ctx.guild.name+ "/users/" + file_name, 'rb') as f:
image = f.read()
with open(os.path.join(file_path, file_name), 'wb') as f:
f.write(image)

with open(ctx.guild.name + "/statistic.png", 'rb') as f:
file_path = os.path.join(f"{ctx.guild.name}/users/", file_name)
os.remove(file_path)
os.remove(f"{ctx.guild.name}/statistic.png")
await ctx.message.delete()
await ctx.send('Clear successful !')
else:
await ctx.send(f"You don't have the permission to use this command, ask admin to do it or {ROLE}.")

@bot.command(
name='save',
aliases=['sa'],
description='Saves the current plot data to a folder',
help='This command saves the current data, you can use the command "!save" or "!sa".'
)
async def save(ctx):
if ctx.author.guild_permissions.manage_roles or discord.utils.get(ctx.author.roles, name = ROLE):
now = datetime.now()
folder_name = now.strftime("%Y-%m-%d %H.%M")
file_path = ctx.guild.name+"/save/" + folder_name
# Create the save folder if it doesn't exist
if not os.path.exists(file_path):
os.makedirs(file_path)
try:
file_list = os.listdir(f"{ctx.guild.name}/users/")
png_files = [f for f in file_list if f.endswith('.png')]
for file_name in png_files:
# Save the png image to a file in the save folder
with open(ctx.guild.name+ "/users/" + file_name, 'rb') as f:
image = f.read()
with open(os.path.join(file_path, file_name), 'wb') as f:
f.write(image)

with open(ctx.guild.name + "/statistic.png", 'rb') as f:
image = f.read()
with open(os.path.join(file_path, "statistic.png"), 'wb') as f:
with open(os.path.join(file_path, "statistic.png"), 'wb') as f:
f.write(image)
with open(ctx.guild.name + "/compare.png", 'rb') as f:
with open(ctx.guild.name + "/compare.png", 'rb') as f:
image = f.read()
with open(os.path.join(file_path, "compare.png"), 'wb') as f:
with open(os.path.join(file_path, "compare.png"), 'wb') as f:
f.write(image)


shutil.copy2(f"{ctx.guild.name}/roll.csv", file_path)
# Send a message to confirm that the save was successful
await ctx.send('Files saved to the save folder!')
except:
await ctx.send(f'There is no data, try running the {PREFIX}plot, {PREFIX}stat commands for saving all data.')
shutil.copy2(f"{ctx.guild.name}/roll.csv", file_path)
# Send a message to confirm that the save was successful
await ctx.send('Files saved to the save folder!')
except:
await ctx.send(f'There is no data, try running the {PREFIX}plot, {PREFIX}stat commands for saving all data.')
else:
await ctx.send(f"You don't have the permission to use this command, ask admin to do it or {ROLE}.")



@bot.command(
name='plot',
aliases=['p'],
description='Plots the data of the current server',
help='This command plots the data of the current server, you can use the command "!plot", you can also specify a user to plot his data, for example "!plot @user".'
help='This command plots the data of the current server, you can use the command "!plot" or "!p", you can also specify a user to plot his data, for example "!plot @user".'
)
async def plot(ctx, user : discord.User = None):
try:
Expand All @@ -149,12 +193,11 @@ async def plot(ctx, user : discord.User = None):
except FileNotFoundError:
await ctx.send(f'There is no data, try running the {PREFIX}r command.')



@bot.command(
name='stat',
aliases=['s'],
description='Compare players rolls',
help='This command Compare players rolls.'
help='This command compare players rolls, you can use the command "!stat" or "!s".'
)
async def stat(ctx):
try:
Expand All @@ -167,12 +210,14 @@ async def stat(ctx):

@bot.event
async def on_command_error(ctx, error):
command_list = '\n'.join([f'\t{c.name}: {c.description}' for c in bot.commands])
command_list = [c for c in bot.commands if not c.hidden]

commands_str = '\n'.join([f' {c.name}: {c.description}' for c in command_list])

# Check if the error is a CommandNotFound error
if isinstance(error, commands.CommandNotFound):
# If the command is not found, send the help message to the user
await ctx.send(f'```Sorry, I don\'t recognize that command. Here is a list of the commands that I know:\n{command_list}```')
await ctx.send(f'```Sorry, I don\'t recognize that command. Here is a list of the commands that I know:\n{commands_str}```')
else:
# For other types of errors, print the error to the console
print(error)
Expand All @@ -181,13 +226,22 @@ async def on_command_error(ctx, error):
@bot.event
async def on_reaction_add(reaction, user):
emoji = reaction.emoji
if user.bot:
if reaction.message.id in processed_reactions and user.id in processed_reactions[reaction.message.id]:
return

if emoji == '\N{CROSS MARK}':
await reaction.message.reply(str(user.display_name) + space + laught)
elif emoji == '\N{WHITE HEAVY CHECK MARK}':
await reaction.message.reply(str(user.display_name) + space + congratulate)
else:
if user.bot:
return
if emoji == '\N{CROSS MARK}':
await reaction.message.reply(str(user.display_name) + space + laught)
if reaction.message.id not in processed_reactions:
processed_reactions[reaction.message.id] = []
processed_reactions[reaction.message.id].append(user.id)
elif emoji == '\N{WHITE HEAVY CHECK MARK}':
await reaction.message.reply(str(user.display_name) + space + congratulate)
if reaction.message.id not in processed_reactions:
processed_reactions[reaction.message.id] = []
processed_reactions[reaction.message.id].append(user.id)
print(processed_reactions)


bot.run(TOKEN)
3 changes: 2 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"token": "Your_Bot_Token_Or_Ask_Me_For_It",
"prefix": "!",
"min": 1
"min": 1,
"role" : "The_Role_Optionnal_if_you_have_admin_permission"
}
4 changes: 2 additions & 2 deletions lang/en.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

login = "Logged in as "
space = " "
made = "has made : "
on = "on "
made = "has made :"
on = "on"
laught = "is making fun of you "
congratulate = "congratulates you ! "
value_of_roll = "Value of Roll"
Expand Down
4 changes: 2 additions & 2 deletions lang/fr.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

login = "Connecté en tant que "
space = " "
made = "a fait : "
on = "sur "
made = "a fait :"
on = "sur"
laught = " se moque de toi ! "
congratulate = " te félicite ! "
value_of_roll = "Valeur de lancer"
Expand Down
4 changes: 2 additions & 2 deletions lang/sr.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

login = "prijavljen kao "
space = " "
made = "je napravio : "
on = "na "
made = "je napravio :"
on = "na"
laught = "ismijava te ! "
congratulate = "on ti čestita ! "
value_of_roll = "Vrednost Roll "
Expand Down
4 changes: 2 additions & 2 deletions lang/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

login = "Logged in as "
space = " "
made = "has made : "
on = "on "
made = "has made :"
on = "on"
laught = "is making fun of you "
congratulate = "congratulates you ! "
value_of_roll = "Value of Roll "
Expand Down
1 change: 0 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
from bot import commands_discord

0 comments on commit 18fa53b

Please sign in to comment.