├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── README.md ├── .gitignore ├── Chintu-Chat-Model ├── ChintuChat │ └── 1620415410 │ │ ├── saved_model.pb │ │ └── variables │ │ ├── variables.data-00000-of-00001 │ │ └── variables.index ├── TrainChintu.py ├── classes.pkl ├── intents.json └── words.pkl ├── LICENSE ├── Procfile ├── cogs ├── Chess.py ├── Fonts.py ├── Fun.py ├── GitHub.py ├── Help.py ├── Images.py ├── Info.py ├── Memes.py ├── Minigames.py ├── Moderation.py ├── Utilities.py ├── currency.py └── utils │ ├── GameGrid.py │ ├── __init__.py │ ├── chess_utils.py │ ├── currency_utils.py │ └── db_utils.py ├── dummy.env ├── main.py ├── main_resources ├── Assets │ ├── currency_values.json │ ├── fonts.json │ ├── kill.json │ ├── roast.json │ └── shop_items.json ├── ChintuAI.py ├── Images │ ├── coffindance.jpg │ ├── fart.jpg │ ├── gay.jpg │ ├── pee.jpg │ ├── profile.jpg │ ├── send.jpg │ ├── slap.jpg │ ├── smash.jpg │ ├── stop.jpg │ ├── wantted.jpg │ └── worthless.jpg ├── __init__.py ├── events.py ├── functions.py ├── item_use.py └── loops.py └── requirements.txt /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | noobcodersgang@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/README.md: -------------------------------------------------------------------------------- 1 | # Chintu Bot 2 | 3 | Chintu bot is a multi-purpose discord bot written in discord.py 4 | 5 | ## Getting Started 6 | 7 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. 8 | 9 | ### Prerequisites 10 | 11 | * `Python` 3.x 12 | * `pip` 13 | * [`virtualenv`](https://virtualenv.pypa.io/en/latest/) 14 | * Reddit API Client ID and Secret ([Reddit App](https://www.reddit.com/prefs/apps)) 15 | * A MongoDB database (preferably MongoDB Atlas) 16 | * A JSON Blob at [jsonblob.com](https://jsonblob.com) 17 | * A discord bot token ([How to get a discord bot token](https://gist.github.com/frank-dspeed/db39a021c1cb006ddc5b9b771667d273)) 18 | 19 | ### Running the bot 20 | 21 | * Clone the repository 22 | 23 | ```shell script 24 | $ git clone https://github.com/Noob-Coders-Gang/Chintu-Bot.git 25 | $ cd Chintu-Bot 26 | ``` 27 | 28 | * Create new virtual environment 29 | 30 | ```shell script 31 | $ virtualenv venv 32 | ``` 33 | * Activate virtual environment 34 | 35 | ```shell script 36 | # Windows (CMD.exe) 37 | $ path\to\venv\Scripts\activate.bat 38 | # Unix 39 | $ source path/to/venv//bin/activate 40 | ``` 41 | * Install Dependencies 42 | ```shell script 43 | $ pip install -r requirements.txt 44 | ``` 45 | * Create a copy of [`dummy.env`](dummy.env) file and name it `.env` in the project root 46 | 47 | * Fill in the environment variables in the said `.env` file 48 | 49 | * Run the bot 50 | ```shell script 51 | $ python main.py 52 | ``` 53 | * Output 54 | ``` 55 | loading extensions... 56 | logging in... 57 | updating databases... 58 | Logged in as Chintu#2757 59 | ``` 60 | ![Bot Online](https://cdn.discordapp.com/attachments/819532187820883968/843057699167535124/unknown.png) 61 | 62 | #### Note 63 | If an extension is not working properly, you can turn it off by adding the extension file name to this line in [main.py](./main.py): 64 | ```python 65 | load_extensions(bot, ["manage_commands.py", "Help.py", "Error_extension.py"]) 66 | ``` 67 | 68 | ## Built With 69 | 70 | * [discord.py](https://github.com/Rapptz/discord.py) - API wrapper for Discord written in Python 71 | 72 | ## Contributing 73 | 74 | If you want to contribute to a project and make it better, your help is very welcome. Contributing is also a great way to learn more about social coding on Github, new technologies and and their ecosystems and how to make constructive, helpful bug reports, feature requests and the noblest of all contributions: a good, clean pull request. 75 | 76 | ### How to make a clean pull request 77 | 78 | - Create a personal fork of the project on Github. 79 | - Clone the fork on your local machine. Your remote repo on Github is called `origin`. 80 | - Add the original repository as a remote called `upstream`. 81 | - If you created your fork a while ago be sure to pull upstream changes into your local repository. 82 | - Create a new branch to work on! Branch from `development` if it exists, else from `master`. 83 | - Implement/fix your feature, comment your code. 84 | - Follow the code style of the project. 85 | - Add or change the documentation as needed. 86 | - Squash your commits into a single commit with git's [interactive rebase](https://help.github.com/articles/interactive-rebase). Create a new branch if necessary. 87 | - Push your branch to your fork on Github, the remote `origin`. 88 | - From your fork open a pull request in the correct branch. Target the project's `development` branch if there is one, else go for `master`! 89 | - If the maintainer requests further changes just push them to your branch. The pull request will be updated automatically. 90 | - Once the pull request is approved and merged you can pull the changes from `upstream` to your local repo and delete 91 | your extra branch(es). 92 | 93 | And last but not least: Always write your commit messages in the present tense. Your commit message should describe what the commit, when applied, does to the code – not what you did to the code. 94 | 95 | ## Authors 96 | 97 | * [**ProgrammerGaurav**](https://github.com/programmergaurav) 98 | * [**swasthikshetty10**](https://github.com/swasthikshetty10) 99 | * [**Devansh-bit**](https://github.com/Devansh-bit) 100 | 101 | See also the list of [contributors](https://github.com/Noob-Coders-Gang/Chintu-Bot/contributors) who participated in this project. 102 | 103 | ## License 104 | 105 | This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details 106 | 107 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .vscode 3 | __pycache__ 4 | db-tests 5 | venv 6 | test.py 7 | .idea -------------------------------------------------------------------------------- /Chintu-Chat-Model/ChintuChat/1620415410/saved_model.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/Chintu-Chat-Model/ChintuChat/1620415410/saved_model.pb -------------------------------------------------------------------------------- /Chintu-Chat-Model/ChintuChat/1620415410/variables/variables.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/Chintu-Chat-Model/ChintuChat/1620415410/variables/variables.data-00000-of-00001 -------------------------------------------------------------------------------- /Chintu-Chat-Model/ChintuChat/1620415410/variables/variables.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/Chintu-Chat-Model/ChintuChat/1620415410/variables/variables.index -------------------------------------------------------------------------------- /Chintu-Chat-Model/TrainChintu.py: -------------------------------------------------------------------------------- 1 | import json 2 | import pickle 3 | import random 4 | 5 | import nltk 6 | import numpy as np 7 | from keras.layers import Dense, Dropout 8 | from keras.models import Sequential 9 | from keras.optimizers import SGD 10 | from nltk.stem import WordNetLemmatizer 11 | 12 | nltk.download('punkt') 13 | nltk.download('wordnet') 14 | lemmatizer = WordNetLemmatizer() 15 | 16 | words = [] 17 | classes = [] 18 | documents = [] 19 | ignore_words = ['?', '!'] 20 | data_file = open('intents.json').read() 21 | intents = json.loads(data_file) 22 | 23 | for intent in intents['intents']: 24 | for pattern in intent['patterns']: 25 | 26 | # take each word and tokenize it 27 | w = nltk.word_tokenize(pattern) 28 | words.extend(w) 29 | # adding documents 30 | documents.append((w, intent['tag'])) 31 | 32 | # adding classes to our class list 33 | if intent['tag'] not in classes: 34 | classes.append(intent['tag']) 35 | 36 | words = [lemmatizer.lemmatize(w.lower()) 37 | for w in words if w not in ignore_words] 38 | words = sorted(list(set(words))) 39 | 40 | classes = sorted(list(set(classes))) 41 | 42 | print(len(documents), "documents") 43 | 44 | print(len(classes), "classes", classes) 45 | 46 | print(len(words), "unique lemmatized words", words) 47 | 48 | pickle.dump(words, open('words.pkl', 'wb')) 49 | pickle.dump(classes, open('classes.pkl', 'wb')) 50 | 51 | # initializing training data 52 | training = [] 53 | output_empty = [0] * len(classes) 54 | for document in documents: 55 | # initializing bag of words 56 | bag = [] 57 | # list of tokenized words for the pattern 58 | pattern_words = document[0] 59 | # lemmatize each word - create base word, in attempt to represent related words 60 | pattern_words = [lemmatizer.lemmatize( 61 | word.lower()) for word in pattern_words] 62 | # create our bag of words array with 1, if word match found in current pattern 63 | for word in words: 64 | bag.append(1) if word in pattern_words else bag.append(0) 65 | 66 | # output is a '0' for each tag and '1' for current tag (for each pattern) 67 | output_row = list(output_empty) 68 | output_row[classes.index(document[1])] = 1 69 | 70 | training.append([bag, output_row]) 71 | # shuffle our features and turn into np.array 72 | random.shuffle(training) 73 | training = np.array(training) 74 | # create train and test lists. X - patterns, Y - intents 75 | train_x = list(training[:, 0]) 76 | train_y = list(training[:, 1]) 77 | print("Training data created") 78 | 79 | # Create model - 3 layers. First layer 128 neurons, second layer 64 neurons and 3rd output layer contains number of neurons 80 | # equal to number of intents to predict output intent with softmax 81 | model = Sequential() 82 | model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu')) 83 | model.add(Dropout(0.5)) 84 | model.add(Dense(64, activation='relu')) 85 | model.add(Dropout(0.5)) 86 | model.add(Dense(len(train_y[0]), activation='softmax')) 87 | 88 | # Compile model. Stochastic gradient descent with Nesterov accelerated gradient gives good results for this model 89 | sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) 90 | model.compile(loss='categorical_crossentropy', 91 | optimizer=sgd, metrics=['accuracy']) 92 | 93 | # fitting and saving the model 94 | hist = model.fit(np.array(train_x), np.array(train_y), 95 | epochs=3000, batch_size=100, verbose=2) 96 | model.save('ChintuChat.h5', hist) 97 | 98 | print("created") 99 | -------------------------------------------------------------------------------- /Chintu-Chat-Model/classes.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/Chintu-Chat-Model/classes.pkl -------------------------------------------------------------------------------- /Chintu-Chat-Model/words.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/Chintu-Chat-Model/words.pkl -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Noob Coders 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: python main.py -------------------------------------------------------------------------------- /cogs/Chess.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import asyncio 4 | 5 | import chess 6 | import discord 7 | from discord.ext import commands, tasks 8 | from discord.ext.commands import Context 9 | from cogs.utils.chess_utils import ChessUtils 10 | import berserk 11 | 12 | """ 13 | {'type': 'gameState', 14 | 'moves': 'g1f3', 15 | 'wtime': datetime.datetime(1970, 1, 25, 20, 31, 23, 647000, tzinfo=datetime.timezone.utc), 16 | 'btime': datetime.datetime(1970, 1, 25, 20, 31, 23, 647000, tzinfo=datetime.timezone.utc), 17 | 'winc': datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), 18 | 'binc': datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), 19 | 'wdraw': False, 20 | 'bdraw': False, 21 | 'status': 'started'} 22 | 23 | """ 24 | 25 | 26 | class Chess(commands.Cog): 27 | def __init__(self, bot: commands.Bot): 28 | self.bot = bot 29 | session = berserk.TokenSession(os.getenv("ACCESS_TOKEN")) 30 | self.client = berserk.Client(session) 31 | self.utils = ChessUtils(self.client) 32 | 33 | @commands.group(invoke_without_command=True, name="chess") 34 | async def chess(self, ctx: Context): 35 | if ctx.invoked_subcommand is None: 36 | await ctx.send("Please enter a subcommand") 37 | 38 | @chess.command(name="import") 39 | async def _import(self, ctx: Context, lichess_game_id: str): 40 | """Show a game from Lichess.org""" 41 | dump_channel = self.bot.get_channel(int(os.getenv("DUMP_CHANNEL", "868392499348144180"))) 42 | game = self.utils.import_game_by_id(lichess_game_id) 43 | positions = list(game.mainline()) 44 | position_index = 0 45 | embed, image_file = self.utils.create_position_embed(game, game.board()) 46 | dump_message = await dump_channel.send(file=image_file) 47 | message = await ctx.send(embed=embed.set_image(url=dump_message.attachments[0].url)) 48 | await message.add_reaction("◀") 49 | await message.add_reaction("▶") 50 | 51 | def check(reaction, user): 52 | return user.id == ctx.author.id and reaction.message.id == message.id and (str( 53 | reaction.emoji) == "◀" or str( 54 | reaction.emoji) == "▶") 55 | 56 | try: 57 | while True: 58 | reaction, user = await self.bot.wait_for("reaction_add", timeout=60, check=check) 59 | if str(reaction.emoji) == "▶": 60 | if position_index < len(positions) - 1: 61 | position_index += 1 62 | if position_index == len(positions) - 1: 63 | embed, image_file = self.utils.create_position_embed(game, 64 | positions[position_index].board(), 65 | end=True) 66 | else: 67 | embed, image_file = self.utils.create_position_embed(game, 68 | positions[position_index].board()) 69 | dump_message = await dump_channel.send(file=image_file) 70 | await message.edit(embed=embed.set_image(url=dump_message.attachments[0].url)) 71 | elif str(reaction.emoji) == "◀": 72 | if position_index > 0: 73 | position_index -= 1 74 | embed, image_file = self.utils.create_position_embed(game, positions[position_index].board()) 75 | dump_message = await dump_channel.send(file=image_file) 76 | await message.edit(embed=embed.set_image(url=dump_message.attachments[0].url)) 77 | await reaction.remove(user) 78 | except asyncio.TimeoutError: 79 | return 80 | 81 | @chess.command(name="play") 82 | async def play(self, ctx: Context, level: int, color: str = "white"): 83 | dump_channel = self.bot.get_channel(int(os.getenv("DUMP_CHANNEL", "868392499348144180"))) 84 | WHITE = berserk.Color.WHITE 85 | BLACK = berserk.Color.BLACK 86 | level, color, headers, board = setup_game(ctx, level, color) 87 | game_dict = self.utils.create_ai_game(level, color) 88 | game_id = game_dict["id"] 89 | message = await send_attachment_embed(ctx, dump_channel, **self.utils.render_board(board, headers)) 90 | looper = Loop_creator(self.bot, self.client, game_id) 91 | looper.start_gameState_listener.start() 92 | 93 | def check(game_id_check, last_move_check, len_moves): 94 | return game_id_check == game_dict["id"] 95 | 96 | def check_user_move(msg): 97 | return msg.author.id == ctx.author.id and len(msg.content) == 4 98 | 99 | if color == WHITE: 100 | await ask_user_for_move(ctx, self.client, self.bot, check_user_move, board, game_id) 101 | 102 | while True: 103 | await edit_attachment_embed(message, dump_channel, **self.utils.render_board(board, headers)) 104 | game_id, last_move, len_moves = await self.bot.wait_for('move', check=check) 105 | if len_moves % 2 == 0: 106 | if color == WHITE: 107 | await ask_user_for_move(ctx, self.client, self.bot, check_user_move, board, game_id) 108 | else: 109 | continue 110 | else: 111 | if color == WHITE: 112 | continue 113 | else: 114 | await ask_user_for_move(ctx, self.client, self.bot, check_user_move, board, game_id) 115 | 116 | 117 | class Loop_creator: 118 | def __init__(self, bot, client, game_id): 119 | self.game_id = game_id 120 | self.client = client 121 | self.bot = bot 122 | 123 | @tasks.loop(count=1) 124 | async def start_gameState_listener(self): 125 | stream = self.client.bots.stream_game_state(self.game_id) 126 | for event in stream: 127 | if event['type'] == 'gameState': 128 | last_move = event['moves'].split()[-1] 129 | len_moves = len(event['moves'].split()) 130 | self.bot.dispatch("move", self.game_id, last_move, len_moves) 131 | 132 | 133 | async def send_attachment_embed(ctx: Context, dump_channel: discord.TextChannel, embed, file): 134 | dump_message = await dump_channel.send(file=file) 135 | message = await ctx.send(embed=embed.set_image(url=dump_message.attachments[0].url)) 136 | return message 137 | 138 | 139 | async def edit_attachment_embed(message: discord.Message, dump_channel: discord.TextChannel, embed, file): 140 | dump_message = await dump_channel.send(file=file) 141 | message = await message.edit(embed=embed.set_image(url=dump_message.attachments[0].url)) 142 | return message 143 | 144 | 145 | async def ask_user_for_move(ctx, client, bot, check, board, game_id): 146 | legal = False 147 | while not legal: 148 | await ctx.send(f"{ctx.author.mention} Make a move, You have 30 seconds to make a move") 149 | message = await bot.wait_for("message", check=check, timeout=30.0) 150 | content = message.content.lower() 151 | try: 152 | client.bots.make_move(game_id, content) 153 | board.push(content) 154 | legal = True 155 | except: 156 | await ctx.send(f"{ctx.author.mention} Please make a legal move") 157 | 158 | 159 | def setup_game(ctx, level: int, color: str): 160 | if level < 0: 161 | level = 0 162 | elif level > 8: 163 | level = 8 164 | if color.lower() == "black": 165 | color = berserk.Color.BLACK 166 | headers = { 167 | "White": "Stockfish", 168 | "Black": ctx.author.name, 169 | "WhiteElo": f"Level {level}", 170 | "BlackElo": "Unkown", 171 | "Event": "Unrated Versus AI", 172 | "Result": "Unkown" 173 | } 174 | else: 175 | color = berserk.Color.WHITE 176 | headers = { 177 | "White": ctx.author.name, 178 | "Black": "Stockfish", 179 | "WhiteElo": "Unkown", 180 | "BlackElo": f"Level {level}", 181 | "Event": "Unrated Versus AI", 182 | "Result": "Unkown" 183 | } 184 | board = chess.Board() 185 | return level, color, headers, board 186 | 187 | 188 | def setup(bot): 189 | bot.add_cog(Chess(bot)) 190 | -------------------------------------------------------------------------------- /cogs/Fonts.py: -------------------------------------------------------------------------------- 1 | import json 2 | import random 3 | 4 | import discord 5 | from discord.ext import commands 6 | from main import DEFAULT_PREFIX 7 | 8 | fonts = json.loads(open('./main_resources/Assets/fonts.json', 9 | encoding='utf-8').read()) 10 | 11 | 12 | def fontify(message: str, font: str): 13 | normal = str(fonts['normal']) 14 | if font == 'random': 15 | content = [] 16 | for key, value in fonts.items(): 17 | content.append(key) 18 | randtext = "" 19 | for letter in message: 20 | if letter not in normal: 21 | randtext += letter 22 | continue 23 | selected = fonts[random.choice(content)] 24 | i = normal.index(letter) 25 | randtext += selected[i] 26 | return randtext 27 | 28 | selected = str(fonts[font.lower()]) 29 | text = "" 30 | for letter in message: 31 | if letter not in normal: 32 | text += letter 33 | continue 34 | i = normal.index(letter) 35 | text += selected[i] 36 | 37 | return text 38 | 39 | 40 | class Fonts(commands.Cog): 41 | """Custom Fonts Generator""" 42 | 43 | def __init__(self, bot): 44 | self.bot = bot 45 | 46 | @commands.command(name="fontlist", aliases=['fonts']) 47 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 48 | async def fontlist(self, ctx): 49 | """Display all Font List""" 50 | 51 | embed = discord.Embed(title="Fonts List", 52 | color=discord.Colour.green()) 53 | 54 | for key, value in fonts.items(): 55 | if key == 'normal': 56 | continue 57 | embed.add_field(name=key, value=f"{value[0:3]}{value[26:29]}{value[52:55]}") 58 | 59 | embed.add_field(name="random", value="Random letters") 60 | embed.set_footer(text=f"Use {DEFAULT_PREFIX}fontify ") 61 | await ctx.send(embed=embed) 62 | 63 | @commands.command(name="fontify", aliases=["font"]) 64 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 65 | async def fontify(self, ctx, font_type: str, *, message): 66 | """Change font and send the message""" 67 | if font_type in fonts or font_type == 'random': 68 | text = fontify(message, font_type) 69 | await ctx.send(text) 70 | else: 71 | embed = discord.Embed(description=fontify(message, 'random'), 72 | color=discord.Colour.orange()).set_footer( 73 | text="Use $fontlist to get a list of fonts to choose from") 74 | await ctx.send(embed=embed) 75 | 76 | 77 | def setup(bot): 78 | bot.add_cog(Fonts(bot)) 79 | 80 | # ------------------------------------------------------------# 81 | -------------------------------------------------------------------------------- /cogs/Fun.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import json 3 | import math 4 | import random 5 | import urllib.request 6 | from typing import Optional 7 | from urllib import parse 8 | 9 | import discord 10 | import requests 11 | import wikipedia 12 | from aiohttp import request 13 | from bs4 import BeautifulSoup 14 | from discord import Member 15 | from discord.ext import commands 16 | from discord.ext.commands import command 17 | 18 | roasts = json.loads( 19 | open('./main_resources/Assets/roast.json', encoding='utf-8').read())['roasts'] 20 | kills = json.loads(open('./main_resources/Assets/kill.json', 21 | encoding='utf-8').read())['kills'] 22 | 23 | 24 | class Fun(commands.Cog): 25 | """Fun commands """ 26 | 27 | def __init__(self, bot): 28 | self.bot = bot 29 | 30 | @commands.command(name="gsearch", aliases=['google', 'search']) 31 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 32 | async def gsearch(self, ctx: discord.ext.commands.Context, *, query): 33 | """Sends top google search result with page description""" 34 | searchInput = "https://google.com/search?q=" + \ 35 | parse.quote(query) + "&num=2" # Query url for top 2 results 36 | res = requests.get(searchInput) # Gets the google search results page 37 | # Parses the google search results page 38 | soup = BeautifulSoup(res.text, "html.parser") 39 | tag = list(soup.find('div', {'class': 'BNeawe vvjwJb AP7Wnd'}).parent.parent.parent.parent.find('div', { 40 | 'class': 'BNeawe s3v9rd AP7Wnd'}).find_all('div', {'class': 'BNeawe s3v9rd AP7Wnd'})) # Creates a list of parsable search results 41 | # Gets the description for the parsable search result 42 | text = "" 43 | for div in tag: 44 | if div.find(text=True, recursive=False) != " " and div.find(text=True, recursive=False) is not None: 45 | text = div.find(text=True, recursive=False) 46 | break 47 | # Creates an embed with the relevant data, ie Result title, its url and its description 48 | embed = discord.Embed(title=soup.find('div', {'class': 'BNeawe vvjwJb AP7Wnd'}).get_text(), 49 | url=soup.find('div', {'class': 'BNeawe vvjwJb AP7Wnd'}).parent.parent.get( 50 | "href").split('=')[1], 51 | description=text) 52 | await ctx.send(embed=embed) 53 | 54 | @commands.command(name="8ball", aliases=['ask']) 55 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 56 | async def _8ball(self, ctx, *, question): 57 | """ Ask question and get advice from me 🎱""" 58 | responses = ["It is certain.", 59 | "It is decidedly so.", 60 | "Without a doubt.", 61 | "Yes - definitely.", 62 | "You may rely on it.", 63 | "As I see it, yes.", 64 | "Most likely.", 65 | "Outlook good.", 66 | "Yes.", 67 | "Signs point to yes.", 68 | "Reply hazy, try again.", 69 | "Ask again later." 70 | "Better not tell you now.", 71 | "Cannot predict now.", 72 | "Concentrate and ask again.", 73 | "Don't count on it.", 74 | "My reply is no.", 75 | "My sources say no.", 76 | "Outlook not so good.", 77 | "Very doubtful."] 78 | em = discord.Embed(title='Magic 8ball!', 79 | colour=discord.Colour.orange()) 80 | em.add_field(name=f"**Question:** {question}", 81 | value=f"**Answer:** {random.choice(responses)}") 82 | await ctx.send(embed=em) 83 | 84 | @commands.command(name="urban") 85 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 86 | async def urban(self, ctx, *, search: str): 87 | """ Find the 'best' definition to your words 📚""" 88 | async with ctx.channel.typing(): 89 | try: 90 | with urllib.request.urlopen(f"https://api.urbandictionary.com/v0/define?term={search}") as url: 91 | url = json.loads(url.read().decode()) 92 | except Exception: 93 | return await ctx.send("Urban API returned invalid data... might be down atm.") 94 | 95 | if not url: 96 | return await ctx.send("I think the API broke...") 97 | 98 | if not len(url["list"]): 99 | return await ctx.send("Couldn't find your search in the dictionary...") 100 | 101 | result = sorted(url["list"], reverse=True, 102 | key=lambda g: int(g["thumbs_up"]))[0] 103 | 104 | definition = result["definition"] 105 | if len(definition) >= 1000: 106 | definition = definition[:1000] 107 | definition = definition.rsplit(" ", 1)[0] 108 | definition += "..." 109 | definition = definition.replace('[', "").replace("]", "") 110 | em = discord.Embed( 111 | title=f"📚 Definitions for **{result['word']}**", description=f"\n{definition}", 112 | color=discord.Colour.red()) 113 | await ctx.send(embed=em) 114 | 115 | @commands.command(name="jokes", aliases=["joke", "funjoke"]) 116 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 117 | async def jokes(self, ctx): 118 | """ Request I'll tell a joke 🤣""" 119 | async with ctx.channel.typing(): 120 | try: 121 | with urllib.request.urlopen("https://v2.jokeapi.dev/joke/Any") as url: 122 | url = json.loads(url.read().decode()) 123 | 124 | def check(author): 125 | def inner_check(message): 126 | return message.author == author 127 | 128 | return inner_check 129 | 130 | if not url['error']: 131 | if url["type"] == "twopart": 132 | await ctx.send(url['setup']) 133 | ans = await self.bot.wait_for('message', check=check, timeout=30) 134 | if ans.content.lower().strip() == url['delivery'].lower().strip(): 135 | await ctx.send('Impresive , correct answer ') 136 | else: 137 | await ctx.send(url['delivery']) 138 | 139 | else: 140 | await ctx.send(url['joke']) 141 | 142 | except Exception: 143 | return await ctx.send("I am busy dude, I can't think any joke right now") 144 | 145 | @commands.command(name="beer") 146 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 147 | async def beer(self, ctx, user: discord.Member = None, *, reason: commands.clean_content = ""): 148 | """ Give someone a beer! 🍻 """ 149 | if not user or user.id == ctx.author.id: 150 | return await ctx.send(f"**{ctx.author.name}**: paaaarty!🎉🍺") 151 | if user.id == self.bot.user.id: 152 | return await ctx.send("*drinks beer with you* 🍻") 153 | if user.bot: 154 | return await ctx.send( 155 | f"I would love to give beer to the bot **{ctx.author.name}**, but I don't think it will respond to you :/") 156 | 157 | beer_offer = f"**{user.name}**, you got a 🍺 offer from **{ctx.author.name}**" 158 | beer_offer = beer_offer + f"\n\n**Reason:** {reason}" if reason else beer_offer 159 | msg = await ctx.send(beer_offer) 160 | 161 | def reaction_check(m): 162 | if m.message_id == msg.id and m.user_id == user.id and str(m.emoji) == "🍻": 163 | return True 164 | return False 165 | 166 | try: 167 | await msg.add_reaction("🍻") 168 | await self.bot.wait_for("raw_reaction_add", timeout=30.0, check=reaction_check) 169 | await msg.edit(content=f"**{user.name}** and **{ctx.author.name}** are enjoying a lovely beer together 🍻") 170 | except asyncio.TimeoutError: 171 | await msg.delete() 172 | await ctx.send(f"well, doesn't seem like **{user.name}** wanted a beer with you **{ctx.author.name}** ;-;") 173 | except discord.Forbidden: 174 | # Yeah so, bot doesn't have reaction permission, drop the "offer" word 175 | beer_offer = f"**{user.name}**, you got a 🍺 from **{ctx.author.name}**" 176 | beer_offer = beer_offer + f"\n\n**Reason:** {reason}" if reason else beer_offer 177 | await msg.edit(content=beer_offer) 178 | 179 | @commands.command(name="howhot", aliases=["hotcalc", "hot"]) 180 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 181 | async def howhot(self, ctx, *, user: discord.Member = None): 182 | """ Returns a percent for how hot is a discord user 🥵""" 183 | user = user or ctx.author 184 | random.seed(user.id) 185 | r = random.randint(1, 100) 186 | hot = r / 1.17 187 | 188 | if hot > 25: 189 | emoji = "❤" 190 | elif hot > 50: 191 | emoji = "💖" 192 | elif hot > 75: 193 | emoji = "💞" 194 | else: 195 | emoji = "💔" 196 | 197 | await ctx.send(f"**{user.name}** is **{hot:.2f}%** hot {emoji}") 198 | 199 | @commands.command(name="f") 200 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 201 | async def f(self, ctx): 202 | """ Press F to pay respect 🇫 """ 203 | try: 204 | await ctx.message.delete() 205 | except: 206 | pass 207 | finally: 208 | await ctx.send(f"**{ctx.author.mention}** has paid their respects") 209 | 210 | 211 | @commands.command(name="coinflip", aliases=["flip", "coin"]) 212 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 213 | async def coinflip(self, ctx): 214 | """ Coinflip! :coin: """ 215 | coinsides = ["Heads", "Tails"] 216 | await ctx.send(f"**{ctx.author.name}** flipped a coin and got **{random.choice(coinsides)}**!") 217 | 218 | @commands.command(name="wiki", aliases=['wikipedia']) 219 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 220 | async def wiki(self, ctx, *, querry_: str): 221 | """ Search wikipedia for any information 🔍""" 222 | async with ctx.channel.typing(): 223 | try: 224 | results = wikipedia.search(querry_, results=5) 225 | result_summary = wikipedia.summary(results[0]) 226 | result_title = results[0] 227 | em = discord.Embed(title=result_title, 228 | color=discord.Color(0xf58742)) 229 | em.set_footer(text=result_summary) 230 | 231 | # em2.set_footer(text=f'Recommended searches : ' + 232 | # f'{results[1:-1]}'[1:-1]) 233 | await ctx.send(embed=em) 234 | # await ctx.send(embed=em2) 235 | except Exception: 236 | await ctx.send("Sorry, I can find " + querry_ + " in Wikipedia") 237 | 238 | @commands.command(name="kill") 239 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 240 | async def kill(self, ctx, user: Optional[Member]): 241 | """ kill someone ⚰️""" 242 | if not user: 243 | user = ctx.author 244 | await ctx.send(f'{user.display_name} {random.choice(kills)}') 245 | 246 | @commands.command(name="roast") 247 | @commands.cooldown(rate=1, per=1, type=commands.BucketType.user) 248 | async def roast(self, ctx, user: discord.Member = None): 249 | """ roast someone 🍳""" 250 | if user is None: 251 | user = ctx.author 252 | await ctx.send(f'{user.display_name}, {random.choice(roasts)}') 253 | 254 | @commands.command(name="pp", aliases=['ppsize', 'size', 'penis']) 255 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 256 | async def pp(self, ctx, member: discord.Member = None): 257 | """ To check pp size 🍆""" 258 | if member is None: 259 | member = ctx.author 260 | i = random.randint(0, 40) 261 | size = "=" * i 262 | em = discord.Embed(color=discord.Colour.blue(), 263 | title="PeePee size calculator") 264 | 265 | em.add_field(name=f"{member.display_name}'s penis:eggplant:", 266 | value=f"8{size}D") 267 | await ctx.send(embed=em) 268 | 269 | @commands.command(name="howgay", aliases=['how gay', 'gaypercent']) 270 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 271 | async def howgay(self, ctx, member: discord.Member = None): 272 | """ To check gayness 🏳️‍🌈""" 273 | if member is None: 274 | member = ctx.author 275 | user = str(member.id) 276 | s = sum([int(x) for x in user]) 277 | 278 | per = float((abs(math.sin((s / 18)))) * 100) 279 | if per >= 50: 280 | gay = 'GAY' 281 | else: 282 | gay = "Not Gay" 283 | per = "{:.2f}".format(per) 284 | em = discord.Embed(title=member.display_name, 285 | description=":two_men_holding_hands: gay result:", color=discord.Colour.red()) 286 | em.add_field( 287 | name=gay, value=f"{member.display_name} is :rainbow_flag: {per}% gay ") 288 | em.set_thumbnail(url=member.avatar_url) 289 | 290 | await ctx.send(embed=em) 291 | 292 | @commands.command(name="password", aliases=['pass', 'generator', 'passwordgenerator']) 293 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 294 | async def password(self, ctx, amt: int = 8): 295 | """ Get random password in DM 🔒""" 296 | try: 297 | nwpss = [] 298 | lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 299 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '!', '@', 300 | '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=', '{', ",", '}', ']', 301 | '[', ';', ':', '<', '>', '?', '/', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '`', '~', 302 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 303 | 'U', 'V', 'W', 'X', 'Y', 'Z'] 304 | for x in range(amt): 305 | newpass = random.choice(lst) 306 | nwpss.append(newpass) 307 | fnpss = ''.join(nwpss) 308 | await ctx.send(f'{ctx.author} attempting to send you the genereated password in dms.') 309 | await ctx.author.send(f':white_check_mark:Password Generated: {fnpss}') 310 | except Exception as e: 311 | print(e) 312 | 313 | @command(name="insult") 314 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 315 | async def insult(self, ctx): 316 | """"Returns some evil insults""" 317 | URL = f"https://evilinsult.com/generate_insult.php?lang=en&type=json" 318 | async with request("GET", URL) as res: 319 | if res.status == 200: 320 | evil_insult = await res.json() 321 | await ctx.send(f"{evil_insult['insult']}") 322 | 323 | @command(name="say", hidden=True) 324 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 325 | async def say(self, ctx:commands.Context, *, message:str): 326 | await ctx.send(message) 327 | 328 | 329 | def setup(bot): 330 | bot.add_cog(Fun(bot)) 331 | 332 | # ----------------------------------------------------------------# 333 | -------------------------------------------------------------------------------- /cogs/GitHub.py: -------------------------------------------------------------------------------- 1 | import discord 2 | import requests 3 | from discord.ext import commands 4 | from discord.ext.commands import CommandError 5 | 6 | 7 | class GitHub(commands.Cog): 8 | ''' Search Github Profile ''' 9 | 10 | def __init__(self, commands): 11 | self.commands = commands 12 | 13 | def __srt__(self): 14 | return ''' Search Github Profile ''' 15 | 16 | @commands.command(name="repos", aliases=["repositories", "github"]) 17 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 18 | async def repos(self, ctx: discord.ext.commands.Context, username): 19 | """Sends top 5 repositories of the requested user""" 20 | user_data = requests.get( 21 | f"https://api.github.com/users/{username}").json() 22 | if "message" in user_data: 23 | em = discord.Embed(title=f"User {username} not found! Please check the username.", 24 | color=discord.Color.red()) 25 | await ctx.send(embed=em) 26 | raise CommandError 27 | repos_data = requests.get( 28 | f"https://api.github.com/users/{username}/repos").json() 29 | embed = discord.Embed( 30 | title=f"Top 5 repositories of {username}", color=discord.Color.blue()) 31 | embed.set_thumbnail(url=user_data["avatar_url"]) 32 | embed.set_footer( 33 | text=f"{username} has {user_data['public_repos']} repositories!") 34 | if len(repos_data) > 5: 35 | repos_data = repos_data[:5] 36 | for result in repos_data: 37 | embed.add_field(name=result["name"], 38 | value=result["html_url"], inline=False) 39 | await ctx.send(embed=embed) 40 | 41 | @commands.command(name="gituser", aliases=["gitmember"]) 42 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 43 | async def gituser(self, ctx, username): 44 | """Sends info about a github user""" 45 | user_data = requests.get( 46 | f"https://api.github.com/users/{username}").json() 47 | if "message" in user_data: 48 | em = discord.Embed(title=f"User {username} not found! Please check the username.", 49 | color=discord.Color.red()) 50 | await ctx.send(embed=em) 51 | raise CommandError 52 | embed = discord.Embed(title=username, color=discord.Color.blue()) 53 | embed.set_thumbnail(url=user_data["avatar_url"]) 54 | embed.add_field(name="URL", value=user_data["html_url"]) 55 | attributes = {"name": "Name", "company": "Company", "blog": "Website", "location": "Location", 56 | "bio": "Github Bio", "twitter_username": "Twitter Handle", "public_repos": "Total Repos"} 57 | for attribute in attributes: 58 | if user_data[attribute] is not None: 59 | if user_data[attribute] != "": 60 | embed.add_field( 61 | name=attributes[attribute], value=user_data[attribute], inline=False) 62 | await ctx.send(embed=embed) 63 | 64 | 65 | def setup(bot): 66 | bot.add_cog(GitHub(bot)) 67 | -------------------------------------------------------------------------------- /cogs/Help.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.errors import Forbidden 3 | from discord.ext import commands 4 | from main import guild_prefix_storage, database, DEFAULT_PREFIX 5 | from main import guild_prefix_storage, database, DEFAULT_PREFIX 6 | from main_resources.functions import * 7 | 8 | 9 | async def send_embed(ctx, embed): 10 | """ 11 | function to send the embed in dm in the case of bot don't have permission to send message in particular channel 12 | """ 13 | try: 14 | await ctx.send(embed=embed) 15 | except Forbidden: 16 | try: 17 | await ctx.send("Hey, seems like I can't send embeds. Please check my permissions :)") 18 | except Forbidden: 19 | await ctx.author.send( 20 | f"Hey, seems like I can't send any message in {ctx.channel.name} on {ctx.guild.name}\n" 21 | f"May you inform the server team about this issue? :slight_smile: ", embed=embed) 22 | 23 | 24 | def prebuild_embed(bot): 25 | # starting to build embed 26 | 27 | # ------------------- iterating trough cogs, gathering descriptions------------------# 28 | 29 | cogs_desc = '' 30 | for cog in bot.cogs: 31 | cogs_desc += f'`{cog}` {bot.cogs[cog].__doc__}\n' 32 | 33 | # ------------------- Adding all cogs to Help embed ------------------# 34 | 35 | # integrating trough uncategorized commands 36 | commands_desc = '' 37 | for command in bot.walk_commands(): 38 | # if cog not in a cog 39 | # listing command if cog name is None and command isn't hidden 40 | if not command.cog_name and not command.hidden: 41 | commands_desc += f'{command.name} - {command.help}\n' 42 | 43 | return cogs_desc, commands_desc 44 | 45 | 46 | def get_prefix(bot, message: discord.Message): 47 | guild_id = message.guild.id 48 | if guild_id in guild_prefix_storage: 49 | return guild_prefix_storage[guild_id] 50 | else: 51 | add_guild(database["guilds_data"], guild_id, DEFAULT_PREFIX) 52 | return DEFAULT_PREFIX 53 | 54 | 55 | class Help(commands.Cog): 56 | """ Sends this help message """ 57 | 58 | def __init__(self, bot): 59 | self.bot = bot 60 | cogs = {} 61 | for cog in bot.cogs: 62 | cogs[cog.lower()] = cog 63 | self.cogs = cogs 64 | bot_commands = {} 65 | for command in bot.walk_commands(): 66 | bot_commands[command.name] = command 67 | self.cogs_desc, self.commands_desc = prebuild_embed(bot) 68 | self.bot_commands = bot_commands 69 | 70 | @commands.command() 71 | async def help(self, ctx, *input): 72 | """Shows all modules of the bot""" 73 | prefix = get_prefix(self.bot, ctx.message) 74 | if not input: 75 | # default help embed 76 | emb = discord.Embed(title='Commands and modules', color=discord.Color.blue(), 77 | description=f'Use `{prefix}help ` to gain more information about that module ' 78 | f':smiley:\n') 79 | emb.add_field(name='Modules', value=self.cogs_desc, inline=False) 80 | if self.commands_desc: 81 | emb.add_field(name='Not belonging to a module', 82 | value=self.commands_desc, inline=False) 83 | emb.add_field( 84 | name="About", 85 | value=f"Please visit https://github.com/Noob-Coders-Gang/Chintu-Bot to submit ideas or bugs.") 86 | # block called when one cog-name is given 87 | # trying to find matching cog and it's commands 88 | elif len(input) == 1: 89 | # check if cog is the matching one 90 | if input[0].lower() in self.cogs: 91 | cog_name = self.cogs[input[0].lower()] 92 | # making title - getting description from doc-string below class 93 | emb = discord.Embed(title=f'{cog_name} - Commands', description=self.bot.cogs[cog_name].__doc__, 94 | color=discord.Color.green()) 95 | 96 | # getting commands from cog 97 | for command in self.bot.get_cog(cog_name).get_commands(): 98 | # if cog is not hidden 99 | if not command.hidden: 100 | if command.help: 101 | emb.add_field( 102 | name=f"`{prefix}{command.name}`", value=command.help, inline=True) 103 | else: 104 | emb.add_field( 105 | name=f"`{prefix}{command.name}`", value="ㅤ", inline=True) 106 | 107 | elif input[0].lower() in self.bot_commands: 108 | command = self.bot_commands[input[0].lower()] 109 | if not command.hidden: 110 | emb = discord.Embed(title=f"{prefix}{command.name} - Information", color=discord.Colour.green()) 111 | emb.add_field(name="Description:", value=command.help, inline=False) 112 | if len(command.aliases) > 0: 113 | emb.add_field(name="Aliases:", value=", ".join(command.aliases), inline=False) 114 | emb.add_field(name="Usage:", value=f"{prefix}{command.name} {command.signature}", inline=False) 115 | else: 116 | emb = discord.Embed(title="What's that?!", 117 | description=f"I've never heard of a module or command called `{input[0]}` before :scream:", 118 | color=discord.Color.orange()) 119 | 120 | # if input not found 121 | else: 122 | emb = discord.Embed(title="What's that?!", 123 | description=f"I've never heard of a module or command called `{input[0]}` before :scream:", 124 | color=discord.Color.orange()) 125 | 126 | # too many cogs requested - only one at a time allowed 127 | elif len(input) > 1: 128 | emb = discord.Embed(title="That's too much.", 129 | description="Please request only one module at once :sweat_smile:", 130 | color=discord.Color.orange()) 131 | 132 | else: 133 | emb = discord.Embed(title="Oops Something went wrong.", 134 | description='''Would you please be so kind to report that issue to me on github?\n" 135 | "https://github.com/Noob-Coders-Gang/Chintu-Bot\n''', 136 | color=discord.Color.red()) 137 | 138 | # sending reply embed using our own function defined above 139 | await send_embed(ctx, emb) 140 | 141 | @commands.command(hidden=True) 142 | async def invoked_help(self, ctx: commands.Context): 143 | prefix = get_prefix(self.bot, ctx.message) 144 | emb = discord.Embed(title='Commands and modules', color=discord.Color.blue(), 145 | description=f'Use `{prefix}help ` to gain more information about that module ' 146 | f':smiley:\n') 147 | emb.add_field(name='Modules', value=self.cogs_desc, inline=False) 148 | if self.commands_desc: 149 | emb.add_field(name='Not belonging to a module', 150 | value=self.commands_desc, inline=False) 151 | emb.add_field( 152 | name="About", 153 | value=f"Please visit https://github.com/Noob-Coders-Gang/Chintu-Bot to submit ideas or bugs.") 154 | emb.set_footer(text=f"Chintu's prefix in this guild is \"{prefix}\"") 155 | await ctx.send(embed=emb) 156 | 157 | @commands.Cog.listener() 158 | async def on_update_prefix(self, ctx, prefix): 159 | update_guild_storage(guild_prefix_storage, ctx.guild.id, prefix) 160 | 161 | 162 | def setup(bot): 163 | bot.add_cog(Help(bot)) 164 | -------------------------------------------------------------------------------- /cogs/Images.py: -------------------------------------------------------------------------------- 1 | from io import BytesIO 2 | from typing import Optional 3 | 4 | import discord 5 | from PIL import Image 6 | from discord import Member 7 | from discord.ext import commands 8 | 9 | 10 | class Images(commands.Cog): 11 | """ Roast From Images """ 12 | 13 | @commands.command(name="slap") 14 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 15 | async def slap(self, ctx, user: Optional[Member]): 16 | user1 = ctx.author 17 | user2 = user if user else user1 18 | 19 | slap = Image.open("main_resources/Images/slap.jpg") 20 | 21 | asset1 = user1.avatar_url_as(size=256) 22 | asset2 = user2.avatar_url_as(size=256) 23 | 24 | data1 = BytesIO(await asset1.read()) 25 | data2 = BytesIO(await asset2.read()) 26 | 27 | pfp1 = Image.open(data1) 28 | pfp1 = pfp1.resize((72, 72)) 29 | 30 | slap.paste(pfp1, (131, 11)) 31 | slap.save("main_resources/Images/send.jpg") 32 | pfp2 = Image.open(data2) 33 | pfp2 = pfp2.resize((72, 72)) 34 | slap.paste(pfp2, (11, 33)) 35 | slap.save("main_resources/Images/send.jpg") 36 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 37 | 38 | @commands.command(name="worthless") 39 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 40 | async def worthless(self, ctx, user: Optional[Member]): 41 | if not user: 42 | user = ctx.author 43 | worthless = Image.open("main_resources/Images/worthless.jpg") 44 | asset = user.avatar_url_as(size=128) 45 | data = BytesIO(await asset.read()) 46 | pfp = Image.open(data) 47 | pfp = pfp.resize((120, 120)) 48 | worthless.paste(pfp, (148, 76)) 49 | worthless.save("main_resources/Images/send.jpg") 50 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 51 | 52 | @commands.command(name="keepquiet", aliases=['kq']) 53 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 54 | async def keepquiet(self, ctx, user: Optional[Member]): 55 | if not user: 56 | user = ctx.author 57 | stop = Image.open("main_resources/Images/stop.jpg") 58 | asset = user.avatar_url_as(size=128) 59 | data = BytesIO(await asset.read()) 60 | pfp = Image.open(data) 61 | pfp = pfp.resize((220, 220)) 62 | stop.paste(pfp, (695, 42)) 63 | stop.save("main_resources/Images/send.jpg") 64 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 65 | 66 | @commands.command(name="fart") 67 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 68 | async def fart(self, ctx, user: Optional[Member]): 69 | if not user: 70 | user = ctx.author 71 | 72 | fart = Image.open("main_resources/Images/fart.jpg") 73 | asset = user.avatar_url_as(size=128) 74 | data = BytesIO(await asset.read()) 75 | pfp = Image.open(data) 76 | pfp = pfp.resize((200, 200)) 77 | fart.paste(pfp, (532, 120)) 78 | fart.save("main_resources/Images/send.jpg") 79 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 80 | 81 | @commands.command(name="pee") 82 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 83 | async def pee(self, ctx, user: Optional[Member]): 84 | if not user: 85 | user = ctx.author 86 | 87 | pee = Image.open("main_resources/Images/pee.jpg") 88 | asset = user.avatar_url_as(size=128) 89 | data = BytesIO(await asset.read()) 90 | pfp = Image.open(data) 91 | pfp = pfp.resize((210, 210)) 92 | pee.paste(pfp, (432, 61)) 93 | pee.save("main_resources/Images/send.jpg") 94 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 95 | 96 | @commands.command(name="coffindance") 97 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 98 | async def coffindance(self, ctx, user: Optional[Member]): 99 | if not user: 100 | user = ctx.author 101 | 102 | pee = Image.open("main_resources/Images/coffindance.jpg") 103 | asset = user.avatar_url_as(size=128) 104 | data = BytesIO(await asset.read()) 105 | pfp = Image.open(data) 106 | pfp = pfp.resize((127, 127)) 107 | pee.paste(pfp, (196, 32)) 108 | pee.save("main_resources/Images/send.jpg") 109 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 110 | 111 | @commands.command(name="smash") 112 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 113 | async def smash(self, ctx, user: Optional[Member]): 114 | user1 = ctx.author 115 | user2 = user if user else user1 116 | 117 | smash = Image.open("main_resources/Images/smash.jpg") 118 | 119 | asset1 = user1.avatar_url_as(size=256) 120 | asset2 = user2.avatar_url_as(size=256) 121 | data1 = BytesIO(await asset1.read()) 122 | data2 = BytesIO(await asset2.read()) 123 | pfp1 = Image.open(data1) 124 | pfp1 = pfp1.resize((91, 91)) 125 | smash.paste(pfp1, (122, 167)) 126 | smash.save("main_resources/Images/send.jpg") 127 | pfp2 = Image.open(data2) 128 | pfp2 = pfp2.resize((88, 88)) 129 | smash.paste(pfp2, (326, 290)) 130 | smash.save("main_resources/Images/send.jpg") 131 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 132 | 133 | @commands.command(name="wanted") 134 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 135 | async def wanted(self, ctx, user: Optional[Member]): 136 | if user is None: 137 | user = ctx.author 138 | wanted = Image.open("main_resources/Images/wantted.jpg") 139 | 140 | asset = user.avatar_url_as(size=128) 141 | data = BytesIO(await asset.read()) 142 | pfp = Image.open(data) 143 | pfp = pfp.resize((300, 300)) 144 | wanted.paste(pfp, (81, 224)) 145 | wanted.save("main_resources/Images/profile.jpg") 146 | await ctx.send(file=discord.File("main_resources/Images/profile.jpg")) 147 | 148 | @commands.command(name="gay") 149 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 150 | async def gay(self, ctx, user: Optional[Member]): 151 | if user is None: 152 | user = ctx.author 153 | gay = Image.open("main_resources/Images/gay.jpg") 154 | 155 | asset = user.avatar_url_as(size=128) 156 | data = BytesIO(await asset.read()) 157 | pfp = Image.open(data) 158 | pfp = pfp.resize((199, 199)) 159 | gay.paste(pfp, (32, 96)) 160 | gay.save("main_resources/Images/send.jpg") 161 | await ctx.send(file=discord.File("main_resources/Images/send.jpg")) 162 | 163 | 164 | def setup(bot): 165 | bot.add_cog(Images(bot)) 166 | -------------------------------------------------------------------------------- /cogs/Info.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from discord import Member, Status, Embed, Colour, TextChannel 4 | from discord.ext import commands 5 | 6 | 7 | class Info(commands.Cog): 8 | """ Server , User Info and more""" 9 | 10 | def __init__(self, bot): 11 | self.bot = bot 12 | 13 | @commands.command(name="avatar") 14 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 15 | async def avatar(self, ctx:commands.Context, *, member: Member = None): 16 | ''' Get user avatar ''' 17 | member = member or ctx.author 18 | userAvatarUrl = member.avatar_url 19 | embed = Embed(title=f'{member} avatar!!', url=f"{userAvatarUrl}") 20 | embed.set_image(url=userAvatarUrl) 21 | await ctx.send(embed=embed) 22 | 23 | @commands.command(name="channel_info", aliases=['channelstats']) 24 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 25 | async def channel_info(self, ctx:commands.Context, channel: TextChannel): 26 | ''' get channel stats/info ''' 27 | channel = channel or ctx.channel 28 | nsfw = self.bot.get_channel(channel.id).is_nsfw() 29 | news = self.bot.get_channel(channel.id).is_news() 30 | embed = Embed(title='Channel Infromation: ' + str(channel), 31 | colour=Colour.from_rgb(54, 151, 255)) 32 | embed.add_field(name='Channel Name: ', value=str(channel.name)) 33 | embed.add_field(name="Channel's NSFW Status: ", value=str(nsfw)) 34 | embed.add_field(name="Channel's id: ", value=str(channel.id)) 35 | embed.add_field(name='Channel Created At: ', value=str( 36 | channel.created_at.strftime("%a, %d %B %Y, %I:%M %p UTC"))) 37 | embed.add_field(name='Channel Type: ', value=str(channel.type)) 38 | embed.add_field(name="Channel's Announcement Status: ", 39 | value=str(news)) 40 | await ctx.send(embed=embed) 41 | 42 | @commands.command(name="server", aliases=['guild']) 43 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 44 | async def server(self, ctx): 45 | ''' Get Server Info ''' 46 | findbots = sum(1 for member in ctx.guild.members if member.bot) 47 | embed = Embed(title='Infomation about ' + ctx.guild.name + 48 | '.', colour=Colour.from_rgb(54, 151, 255)) 49 | embed.set_thumbnail(url=str(ctx.guild.icon_url)) 50 | embed.add_field(name="Guild's name: ", value=ctx.guild.name) 51 | embed.add_field(name="Guild's owner: ", value=str(ctx.guild.owner)) 52 | embed.add_field(name="Guild's verification level: ", 53 | value=str(ctx.guild.verification_level)) 54 | embed.add_field(name="Guild's id: ", value=str(ctx.guild.id)) 55 | embed.add_field(name="Guild's member count: ", 56 | value=str(ctx.guild.member_count)) 57 | embed.add_field(name="Bots", value=f"{findbots}", inline=True) 58 | embed.add_field(name="Guild created at: ", value=str( 59 | ctx.guild.created_at.strftime("%a, %d %B %Y, %I:%M %p UTC"))) 60 | await ctx.send(embed=embed) 61 | 62 | @commands.command(name="user", aliases=['whois', 'userinfo']) 63 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 64 | async def user(self, ctx:commands.Context, member: Member = None): 65 | ''' Get User Info ''' 66 | if member is None: 67 | member = ctx.author 68 | # pos = sum(m.joined_at < member.joined_at for m in ctx.guild.members if m.joined_at is not None) 69 | #TODO: will not work without enabling members intent 70 | roles = [role for role in member.roles] 71 | embed = Embed(color=Colour.gold(), 72 | timestamp=datetime.datetime.utcnow()) 73 | embed.set_author(name=f"{member}", icon_url=member.avatar_url) 74 | embed.set_thumbnail(url=member.avatar_url) 75 | embed.add_field(name="Joined at:", value=member.joined_at.strftime( 76 | "%a, %#d %B %Y, %I:%M %p")) 77 | embed.add_field(name='Registered at:', value=member.created_at.strftime( 78 | '%a, %#d %B %Y, %I:%M %p')) 79 | embed.add_field(name='Bot?', value=f'{member.bot}') 80 | 81 | if member.status == Status.online: 82 | status = "Online" 83 | elif member.status == (Status.do_not_disturb or Status.dnd): 84 | status = "DnD" 85 | else: 86 | status = "Offline" 87 | 88 | embed.add_field(name='Status?', value=f'{status}') 89 | embed.add_field(name='Top Role?', value=f'{member.top_role}') 90 | display_roles = "" 91 | for role in roles: 92 | display_roles += role.mention 93 | embed.add_field(name=f"Roles ({len(roles)})", value=f"{display_roles}") 94 | # embed.add_field(name='Join position', value=f"{pos}") #TODO: will not work without enabling members intent 95 | embed.set_footer(icon_url=member.avatar_url, 96 | text=f'Requested By: {ctx.author.name}') 97 | await ctx.send(embed=embed) 98 | 99 | 100 | def setup(bot): 101 | bot.add_cog(Info(bot)) 102 | -------------------------------------------------------------------------------- /cogs/Memes.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | 4 | import discord 5 | import praw 6 | import requests 7 | from discord.ext import commands 8 | from dotenv import load_dotenv 9 | 10 | load_dotenv() 11 | 12 | reddit = praw.Reddit( 13 | client_id=os.getenv("CLIENT_ID"), 14 | client_secret=os.getenv("SECRET"), 15 | user_agent='chintubot', 16 | ) 17 | 18 | 19 | def get_memes(subreddit): 20 | memes = reddit.subreddit(subreddit) 21 | 22 | all_memes = [meme for meme in memes.top(limit=100)] 23 | # for meme in top: 24 | # all_memes.append(meme) 25 | meme = random.choice(all_memes) 26 | meme_title = meme.title 27 | meme_url = meme.url 28 | for i in range(100): 29 | if meme_url[-4:] in [".jpg", ".png"]: 30 | return meme_title, meme_url 31 | else: 32 | meme = random.choice(all_memes) 33 | meme_title = meme.title 34 | meme_url = meme.url 35 | return 'Opps' 36 | 37 | 38 | class Memes(commands.Cog): 39 | """ Meme commads """ 40 | 41 | def __init__(self, commands): 42 | self.commands = commands 43 | 44 | @commands.command(name="csmeme") 45 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 46 | async def csmeme(self, ctx): 47 | try: 48 | title, url = get_memes('ProgrammerHumor') 49 | em = discord.Embed(title=title, color=discord.Colour.red()) 50 | em.set_image(url=url) 51 | em.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=str( 52 | ctx.author.avatar_url)) 53 | await ctx.send(embed=em) 54 | except Exception as e: 55 | await ctx.send('f') 56 | 57 | @commands.command(name="meme", aliases=['memes', 'dankmemes']) 58 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 59 | async def meme(self, ctx): 60 | title, url = get_memes('Memes') 61 | em = discord.Embed(title=title, color=discord.Colour.red()) 62 | em.set_image(url=url) 63 | em.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=str( 64 | ctx.author.avatar_url)) 65 | await ctx.send(embed=em) 66 | 67 | @commands.command(name="foodporn") 68 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 69 | async def foodporn(self, ctx): 70 | title, url = get_memes('FoodPorn') 71 | em = discord.Embed(color=discord.Colour.red()) 72 | em.set_image(url=url) 73 | await ctx.send(embed=em) 74 | 75 | @commands.command(name="wsmeme") 76 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 77 | async def wsmeme(self, ctx): 78 | title, url = get_memes('WholesomeMemes') 79 | em = discord.Embed(title=title, color=discord.Colour.red()) 80 | em.set_image(url=url) 81 | await ctx.send(embed=em) 82 | 83 | @commands.command(name="uwu") 84 | @commands.cooldown(rate=1, per=2.0, type=commands.BucketType.user) 85 | async def uwu(self, ctx): 86 | rand = random.randint(0, 2) 87 | if rand == 0: 88 | json = requests.get( 89 | "https://api.thecatapi.com/v1/images/search").json() 90 | url = str(json[0]["url"]) 91 | title = "Here is a cat for you, uwu" 92 | elif rand == 1: 93 | json = requests.get( 94 | "https://dog.ceo/api/breeds/image/random").json() 95 | url = str(json["message"]).replace('\\', "/") 96 | title = "Here is a dog for you, owo" 97 | else: 98 | json = requests.get("https://randomfox.ca/floof/").json() 99 | url = str(json["image"]).replace('\\', "/") 100 | title = "Here is a fox for you, uwu" 101 | em = discord.Embed(title=title, color=discord.Colour.red()) 102 | em.set_image(url=url) 103 | em.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=str( 104 | ctx.author.avatar_url)) 105 | await ctx.channel.send(embed=em) 106 | 107 | 108 | def setup(bot): 109 | bot.add_cog(Memes(bot)) 110 | -------------------------------------------------------------------------------- /cogs/Minigames.py: -------------------------------------------------------------------------------- 1 | from discord.ext import commands 2 | from cogs.utils import GameGrid 3 | 4 | 5 | class Minigames(commands.Cog): 6 | """Minigames""" 7 | 8 | def __init__(self, bot): 9 | self.bot = bot 10 | 11 | @commands.command(name="2048") 12 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 13 | async def _2048(self, ctx): 14 | """Play 2048""" 15 | 16 | if GameGrid.getGamesByUser(str(ctx.author.id)) is not None: 17 | game = GameGrid.getGamesByUser(str(ctx.author.id)) 18 | message = await ctx.send(game.getEmojiMessage()) 19 | 20 | game.setMessageId(str(message.id)) 21 | game.setChannelId(str(ctx.channel.id)) 22 | 23 | await message.add_reaction('⬆') 24 | await message.add_reaction('⬇') 25 | await message.add_reaction('➡') 26 | await message.add_reaction('⬅') 27 | await message.add_reaction('❌') 28 | return 29 | 30 | game = GameGrid.GameGrid(str(ctx.author.id), str(ctx.author.name), str(ctx.author.avatar_url)) 31 | game.start() 32 | 33 | message = await ctx.send(game.getEmojiMessage()) 34 | 35 | game.setMessageId(str(message.id)) 36 | game.setChannelId(str(ctx.channel.id)) 37 | 38 | await message.add_reaction('⬆') 39 | await message.add_reaction('⬇') 40 | await message.add_reaction('➡') 41 | await message.add_reaction('⬅') 42 | await message.add_reaction('❌') 43 | 44 | 45 | def setup(bot): 46 | bot.add_cog(Minigames(bot)) 47 | -------------------------------------------------------------------------------- /cogs/Moderation.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import random 3 | from datetime import datetime 4 | 5 | import discord 6 | from discord.ext import commands 7 | from discord.utils import find 8 | from cogs.utils.db_utils import db_utils 9 | import main 10 | 11 | 12 | class BannedUser(commands.Converter): 13 | async def convert(self, ctx, arg): 14 | banned = [e.user for e in await ctx.guild.bans()] 15 | if banned: 16 | user = find(lambda u: str(u) == str(arg), banned) 17 | if user: 18 | return user 19 | elif str(arg).isdigit(): 20 | user = find(lambda u: u.id == int(arg), banned) 21 | if user: 22 | return user 23 | else: 24 | raise commands.BadArgument 25 | 26 | 27 | class Moderation(commands.Cog): 28 | """ Moderator Commands """ 29 | 30 | def __init__(self, bot: commands.Bot): 31 | self.bot = bot 32 | self.warn_collection = main.database["warns"] 33 | self.db_util = db_utils(main.database["warns"]) 34 | 35 | @commands.command(name="warn") 36 | @commands.has_permissions(kick_members=True) 37 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 38 | async def warn(self, ctx: commands.Context, warned_member: discord.Member, *, reason: str = None): 39 | if reason is None: 40 | reason = "No reason was provided" 41 | warn_id = random.randint(10000000, 99999999) 42 | while self.warn_collection.find_one({"_id": warn_id}): 43 | warn_id = random.randint(10000000, 9999999) 44 | self.db_util.initialize().add( 45 | _id=warn_id, 46 | guild_id=ctx.guild.id, 47 | member_id=warned_member.id, 48 | member_name=warned_member.name, 49 | reason=reason, 50 | message_id=ctx.message.id, 51 | moderator_id=ctx.author.id, 52 | moderator_name=ctx.author.name, 53 | channel_id=ctx.channel.id, 54 | time=datetime.utcnow().timetuple() 55 | ).insert_one() 56 | try: 57 | user_embed = discord.Embed(title=f"You have been warned in {ctx.guild.name}", 58 | description=f"Reason: {reason} | ID:{warn_id}", color=discord.Colour.orange()) 59 | await warned_member.send(embed=user_embed) 60 | channel_embed = discord.Embed(title=f"{warned_member.name} has been warned", 61 | description=f"Reason: {reason}", color=discord.Colour.orange()) 62 | channel_embed.set_footer(text=f"Warned by {ctx.author.name}", icon_url=ctx.author.avatar_url) 63 | await ctx.send(embed=channel_embed) 64 | except Exception: 65 | channel_embed = discord.Embed( 66 | title=f"Warning for {warned_member.name} has been logged. I couldn't DM them.", 67 | description=f"Reason: {reason} | ID:{warn_id}", color=discord.Colour.orange()) 68 | channel_embed.set_footer(text=f"Warned by {ctx.author.name}", icon_url=ctx.author.avatar_url) 69 | await ctx.send(embed=channel_embed) 70 | 71 | @commands.command(name="warns") 72 | @commands.has_permissions(kick_members=True) 73 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 74 | async def warns(self, ctx: commands.Context, member: discord.Member): 75 | warns = list(self.warn_collection.find( 76 | {"member_id": member.id, "guild_id": ctx.guild.id})) 77 | embed = discord.Embed( 78 | title=f"{member.name} has been warned {len(warns)} times", color=discord.Colour.orange()) 79 | for warn in warns: 80 | embed.add_field( 81 | name=f"Warn ID: {warn['_id']}", 82 | value=f"Reason: {str(warn['reason'])}, Warned by: {warn['moderator_name']}", inline=False) 83 | await ctx.send(embed=embed) 84 | 85 | @commands.command(name="warninfo") 86 | @commands.has_permissions(kick_members=True) 87 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 88 | async def warninfo(self, ctx: commands.Context, warn_id: int): 89 | warn = self.warn_collection.find_one({'_id': warn_id}) 90 | if warn is not None: 91 | if ctx.guild.id == warn['guild_id']: 92 | embed = discord.Embed( 93 | title=f"Warn information for warn ID:{warn_id}", color=discord.Colour.orange()) 94 | embed.add_field(name="Warned member", 95 | value=warn['member_name'], inline=False) 96 | embed.add_field(name="Warned by", 97 | value=warn['moderator_name'], inline=False) 98 | embed.add_field( 99 | name="Warn link", 100 | value=f"[Message Link](https://discord.com/channels/{warn['guild_id']}/{warn['channel_id']}/{warn['message_id']})", 101 | inline=False) 102 | embed.add_field(name="Reason", value=warn['reason'], inline=False) 103 | timetuple = warn['time'] 104 | embed.add_field( 105 | name="Warned at", 106 | value=f"{timetuple[2]}/{timetuple[1]}/{timetuple[0]} {timetuple[3]}:{timetuple[4]} (UTC)", 107 | inline=False) 108 | await ctx.send(embed=embed) 109 | else: 110 | await ctx.send(f"{ctx.author.mention} Warn not found!") 111 | else: 112 | await ctx.send(f"{ctx.author.mention} Warn not found!") 113 | 114 | @commands.command(name="kick") 115 | @commands.has_permissions(kick_members=True) 116 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 117 | async def kick(self, ctx, member: discord.Member, *, reason): 118 | """Kicks the mentioned member""" 119 | embed = discord.Embed(title=str(str(member) + " is Kicked | reason = " + reason), colour=discord.Colour.green()) 120 | await member.send(embed=embed) 121 | await member.kick(reason=reason) 122 | 123 | @commands.command(name="ban") 124 | @commands.has_permissions(ban_members=True) 125 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 126 | async def ban(self, ctx, member: discord.Member, *, reason=None): 127 | """Bans the mentioned member""" 128 | if not reason: 129 | reason = "No reason was provided" 130 | await member.ban(reason=reason) 131 | embed_guild = discord.Embed(title=str(member) + " has been banned | reason = " + reason, 132 | colour=discord.Colour.green()) 133 | embed = discord.Embed(title=f"{str(member)}, You have been banned from {str(ctx.guild)}", 134 | color=discord.Color.red()) 135 | await ctx.send(embed=embed_guild) 136 | try: 137 | await member.send(embed=embed) 138 | except Exception: 139 | return 140 | 141 | @commands.command(name="unban") 142 | @commands.has_permissions(ban_members=True) 143 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 144 | async def unban(self, ctx, user: BannedUser, reason: str = None): 145 | """Unbans the mentioned member""" 146 | if not reason: 147 | reason = "No reason was provided" 148 | await ctx.guild.unban(user, reason=reason) 149 | embed_guild = discord.Embed(title=f"{str(user)} has been unbanned{' | reason = ' + reason if reason else ''}", 150 | colour=discord.Colour.green()) 151 | embed = discord.Embed(title=f"{str(user)}, You have been banned from {str(ctx.guild)}", 152 | color=discord.Colour.red()) 153 | await ctx.send(embed=embed_guild) 154 | try: 155 | await user.send(embed=embed) 156 | except Exception: 157 | return 158 | 159 | @commands.command(name="mute") 160 | @commands.has_permissions(manage_roles=True) 161 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 162 | async def mute(self, ctx: commands.Context, member: discord.Member, *, reason=None): 163 | mutedRole = discord.utils.get(ctx.guild.roles, name="Muted") 164 | if not mutedRole: 165 | bot_integration_role = ctx.guild.me.roles[-1] 166 | mutedRole = await ctx.guild.create_role(name="Muted", color=0x010101) 167 | await mutedRole.edit(position=bot_integration_role.position - 1) 168 | for channel in ctx.guild.channels: 169 | await channel.set_permissions(mutedRole, send_messages=False) 170 | if not reason: 171 | reason = "No reason was provided." 172 | embed = discord.Embed(title=str(str(member) + " has been Muted | reason = " + reason), 173 | colour=discord.Colour.red()) 174 | await ctx.send(embed=embed) 175 | await member.add_roles(mutedRole, reason=reason) 176 | try: 177 | await member.send(f" you have been muted in {ctx.guild.name} | Reason: {reason}") 178 | except Exception: 179 | return 180 | 181 | @commands.command(name="unmute") 182 | @commands.has_permissions(kick_members=True) 183 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 184 | async def unmute(self, ctx, member: discord.Member, *, reason="No reason specified"): 185 | """Unmutes the mentioned member""" 186 | Muted = discord.utils.get(ctx.guild.roles, name="Muted") 187 | await member.remove_roles(Muted) 188 | embed = discord.Embed( 189 | title=str(str(member) + " has been Unmuted | reason = " + reason), colour=discord.Colour.green()) 190 | await member.send(embed=embed) 191 | 192 | @commands.command(name="clear", aliases=["purge"]) 193 | @commands.has_permissions(manage_messages=True) 194 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 195 | async def clear(self, ctx, number_of_messages: int = 5): 196 | """Purges specified number of messages""" 197 | await ctx.channel.purge(limit=number_of_messages + 1) 198 | embed = discord.Embed(title=f"Deleted {number_of_messages} in {ctx.channel.name}") 199 | emb_msg = await ctx.send(embed=embed) 200 | await asyncio.sleep(3) 201 | await emb_msg.delete() 202 | 203 | 204 | def setup(bot): 205 | bot.add_cog(Moderation(bot)) 206 | -------------------------------------------------------------------------------- /cogs/Utilities.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import math 3 | import re 4 | 5 | from discord.ext import commands 6 | 7 | from main import database 8 | from main_resources.functions import * 9 | 10 | intervals = ( 11 | ('years', 604800 * 52), 12 | ('months', 604800 * 4), 13 | ('weeks', 604800), # 60 * 60 * 24 * 7 14 | ('days', 86400), # 60 * 60 * 24 15 | ('hours', 3600), # 60 * 60 16 | ('minutes', 60), 17 | ('seconds', 1), 18 | ) 19 | 20 | 21 | class Utility(commands.Cog): 22 | ''' Utility Commands ''' 23 | 24 | def __init__(self, bot: commands.Bot): 25 | self.emojis = None 26 | self.bot = bot 27 | self.count = 0 28 | self.cmd_list = [] 29 | self.user_data = database["user_data"] 30 | self.guild_data = database["guilds_data"] 31 | for cmd in bot.commands: 32 | # Get all commands registered with the bot 33 | self.cmd_list.append(cmd.name) 34 | 35 | @commands.command(name="ping") 36 | async def ping(self, ctx): 37 | """Sends the latency of the bot""" 38 | em = discord.Embed(title='Latency', description='🏓Pong {0}'.format(math.trunc(self.bot.latency * 1000)) + 'ms', 39 | color=discord.Color(0x4293f5)) 40 | await ctx.send(embed=em) 41 | 42 | @commands.command(name="suggest") 43 | async def suggest(self, ctx: discord.ext.commands.Context, *, suggestion: str): 44 | """Suggest a feature or an improvement for chintu!""" 45 | em = discord.Embed( 46 | title="Your suggestion has been recorded!", color=discord.Color.green()) 47 | sugg_em = discord.Embed( 48 | title=f"Suggestion from {ctx.author.name}#{ctx.author.discriminator}", description=suggestion) 49 | await self.bot.get_channel(813268502839820318).send(embed=sugg_em) 50 | await ctx.send(embed=em) 51 | 52 | @commands.command(name="invite") 53 | async def invite(self, ctx): 54 | """Invite Chintu to your server!!!""" 55 | await ctx.send( 56 | "https://discord.com/oauth2/authorize?client_id=790900950885203978&permissions=2026368118&scope=bot") 57 | 58 | @commands.command(name="prefix", aliases=["changeprefix"]) 59 | @commands.has_permissions(manage_guild=True) 60 | async def prefix(self, ctx, prefix: str): 61 | """Change Chintu's prefix (Use double quotes [" "] around the prefix to add whitespace [$prefix "pls "])""" 62 | update_prefix(database["guilds_data"], ctx.guild.id, prefix) 63 | self.bot.dispatch("update_prefix", ctx, prefix) 64 | embed = discord.Embed(title=f"The prefix of your guild was changed to {prefix}", 65 | color=discord.Colour.green()) 66 | await ctx.send(embed=embed) 67 | 68 | @commands.command(name="add") 69 | @commands.has_permissions(manage_guild=True) 70 | async def add(self, ctx, command_name: str): 71 | """Add a previously removed command back to your server""" 72 | if command_name in self.cmd_list: 73 | remove_cmd_from_collection(database["guilds_data"], ctx.guild.id, command_name, os.getenv("PREFIX")) 74 | self.bot.dispatch("add_command", ctx, command_name) 75 | embed = discord.Embed(title=f"I have added the {command_name} command back to your server!", 76 | color=discord.Colour.green()) 77 | await ctx.send(embed=embed) 78 | else: 79 | embed = discord.Embed( 80 | title=f"I don't have any command named {command_name}", color=discord.Colour.red()) 81 | await ctx.send(embed=embed) 82 | 83 | @commands.command(name="remove") 84 | @commands.has_permissions(manage_guild=True) 85 | async def remove(self, ctx, command_name: str): 86 | """Remove a command from your server""" 87 | if command_name in self.cmd_list: 88 | add_cmd_to_collection(database["guilds_data"], ctx.guild.id, command_name, os.getenv("PREFIX")) 89 | self.bot.dispatch("remove_command", ctx, command_name) 90 | embed = discord.Embed(title=f"I have removed the {command_name} command from your server!", 91 | color=discord.Colour.green()) 92 | await ctx.send(embed=embed) 93 | else: 94 | embed = discord.Embed( 95 | title=f"I don't have any command named {command_name}", color=discord.Colour.red()) 96 | await ctx.send(embed=embed) 97 | 98 | @commands.command(name="formemb", hidden=True) 99 | @commands.is_owner() 100 | async def formemb(self, ctx: commands.Context, channel: discord.TextChannel, *, title): 101 | """Create embed for announcement and stuff""" 102 | try: 103 | await ctx.send("Send description") 104 | 105 | def check(message): 106 | return message.channel == ctx.channel and message.author.id == ctx.author.id 107 | 108 | msg = await self.bot.wait_for('message', timeout=90.0, check=check) 109 | if msg.content.lower() != "none": 110 | emb = discord.Embed(title=title, description=msg.content) 111 | else: 112 | emb = discord.Embed(title=title) 113 | while True: 114 | await ctx.send("Add `field name` or `done` to send or `cancel` to cancel") 115 | msg = await self.bot.wait_for('message', timeout=90.0, check=check) 116 | if msg.content.lower() == "cancel": 117 | await ctx.send("Cancelled") 118 | return 119 | if msg.content.lower() == "done": 120 | await channel.send(embed=emb) 121 | await ctx.send("Done") 122 | return 123 | name = msg.content 124 | await ctx.send("Add `field value` and add `inline` to set to True") 125 | msg = await self.bot.wait_for('message', timeout=90.0, check=check) 126 | if "inline" in msg.content.lower(): 127 | value = msg.content.replace("inline", "") 128 | emb.add_field(name=name, value=value, inline=True) 129 | else: 130 | value = msg.content 131 | emb.add_field(name=name, value=value, inline=False) 132 | 133 | except asyncio.TimeoutError: 134 | await ctx.send("Cancelled") 135 | return 136 | 137 | def get_emoji(self, match): 138 | try: 139 | return self.emojis[str(match.group()).replace(":", "")] 140 | except KeyError: 141 | return str(match.group()) 142 | 143 | @commands.command(name="nitro", aliases=["n"]) 144 | async def nitro(self, ctx: commands.Context, *, message): 145 | """Use any emote that Chintu has access to in your message!""" 146 | sent = False 147 | if self.emojis is None: 148 | self.emojis = {e.name.lower(): str(e) for e in self.bot.emojis} 149 | message = re.sub(r':[^:]+:', self.get_emoji, message, count=0) 150 | webhooks = await ctx.channel.webhooks() 151 | await ctx.message.delete() 152 | if len(webhooks) > 0: 153 | for webhook in webhooks: 154 | try: 155 | await webhook.send(message, username=ctx.author.name, avatar_url=ctx.author.avatar_url) 156 | sent = True 157 | break 158 | except discord.errors.InvalidArgument: 159 | continue 160 | if not sent: 161 | webhook = await ctx.channel.create_webhook(name=self.bot.user.name) 162 | await webhook.send(message, username=ctx.author.name, avatar_url=ctx.author.avatar_url) 163 | else: 164 | webhook = await ctx.channel.create_webhook(name=ctx.author.name) 165 | await webhook.send(message, username=ctx.author.name, avatar_url=ctx.author.avatar_url) 166 | 167 | @commands.command(name="default_nitro") 168 | async def default_nitro(self, ctx: commands.Context, set_value: str = None): 169 | """Turn on or off default nitro, converts emojis in your messages to emojis if your server allows it""" 170 | set_value = set_value.lower() 171 | current_status = self.user_data.find_one({"_id": ctx.author.id}, {"nitro": 1}) 172 | if set_value == "on" or set_value == "true": 173 | if current_status and "nitro" in current_status and current_status["nitro"]: 174 | await ctx.send("Your default nitro is already on") 175 | else: 176 | self.user_data.update_one({"_id": ctx.author.id}, {"$set": {"nitro": True}}, upsert=True) 177 | self.bot.dispatch("user_data_update", ctx.author.id) 178 | await ctx.send("Your default nitro has been turned on!") 179 | elif set_value == "off" or set_value == "false": 180 | if current_status and "nitro" in current_status and current_status["nitro"]: 181 | self.user_data.update_one({"_id": ctx.author.id}, {"$set": {"nitro": False}}, upsert=True) 182 | self.bot.dispatch("user_data_update", ctx.author.id) 183 | await ctx.send("Your default nitro has been turned off!") 184 | else: 185 | await ctx.send("Your default nitro is already off") 186 | else: 187 | if current_status and "nitro" in current_status and current_status["nitro"]: 188 | await ctx.send("Your default nitro status is ON") 189 | else: 190 | await ctx.send("Your default nitro status is OFF") 191 | 192 | @commands.command(name="server_nitro") 193 | @commands.has_permissions(manage_guild=True) 194 | async def server_nitro(self, ctx: commands.Context, set_value: str): 195 | """Turn on or off default nitro for your server""" 196 | set_value = set_value.lower() 197 | current_status = self.guild_data.find_one({"_id": ctx.guild.id}, {"nitro": 1}) 198 | if set_value == "on" or set_value == "true": 199 | if current_status and "nitro" in current_status and current_status["nitro"]: 200 | await ctx.send("Default nitro for your server is already on") 201 | else: 202 | self.guild_data.update_one({"_id": ctx.guild.id}, {"$set": {"nitro": True}}, upsert=True) 203 | self.bot.dispatch("guild_data_update", ctx.guild.id) 204 | await ctx.send("Default nitro for your server has been turned on!") 205 | elif set_value == "off" or set_value == "false": 206 | if current_status and "nitro" in current_status and current_status["nitro"]: 207 | self.guild_data.update_one({"_id": ctx.guild.id}, {"$set": {"nitro": False}}, upsert=True) 208 | self.bot.dispatch("guild_data_update", ctx.guild.id) 209 | await ctx.send("Default nitro for your server has been turned off!") 210 | else: 211 | await ctx.send("Default nitro for your server is already off") 212 | else: 213 | if current_status and "nitro" in current_status and current_status["nitro"]: 214 | await ctx.send("Default nitro for your server is ON") 215 | else: 216 | await ctx.send("Default nitro for your server OFF") 217 | 218 | 219 | def setup(bot): 220 | bot.add_cog(Utility(bot)) 221 | -------------------------------------------------------------------------------- /cogs/currency.py: -------------------------------------------------------------------------------- 1 | import html 2 | import json 3 | from datetime import datetime, timedelta 4 | 5 | import numpy as np 6 | import requests 7 | from cogs.utils.db_utils import db_utils 8 | from cogs.utils.db_utils import create_dict 9 | from main_resources.item_use import * 10 | 11 | 12 | class Currency(commands.Cog): 13 | """🤑 Everything related to da money 🤑""" 14 | 15 | def __init__(self, bot: commands.Bot): 16 | self.bot = bot 17 | self.collection = database["currency"] 18 | self.utils = currency_utils(self.collection) 19 | self.db_utils = db_utils(self.collection, 20 | wallet=0, 21 | bank=0, 22 | bank_limit=0, 23 | commands=0, 24 | inventory=None, 25 | t_daily=0, 26 | t_weekly=0, 27 | t_monthly=0 28 | ) 29 | self.defined_currencies = json.loads( 30 | open('./main_resources/Assets/currency_values.json', encoding='utf-8').read()) 31 | self.items_by_id = json.loads( 32 | open('./main_resources/Assets/shop_items.json', encoding='utf-8').read())["by_id"] 33 | self.id_by_name = json.loads( 34 | open('./main_resources/Assets/shop_items.json', encoding='utf-8').read())["by_name"] 35 | self.paged_shop, self.pages = create_paged_shop(self.items_by_id) 36 | self.houses = { 37 | 1: "5 of a kind", 38 | 2: "4 of a kind", 39 | 3: "3 of a kind and a pair", 40 | 4: "2 pairs", 41 | 5: "1 pair", 42 | 6: "None of the accepted combinations" 43 | } 44 | self.prizes = { 45 | 5: 2, 46 | 4: 1.5, 47 | 3: 1.3, 48 | 2: 1.2, 49 | 1: 1 50 | } 51 | self.quiz_categories = { 52 | "gk": 9, 53 | "books": 10, 54 | "film": 11, 55 | "music": 12, 56 | "theatre": 13, 57 | "tv": 14, 58 | "games": 15, 59 | "bgames": 16, 60 | "sci": 17, 61 | "cs": 18, 62 | "math": 19, 63 | "myth": 20, 64 | "sports": 21, 65 | "geography": 22, 66 | "history": 23, 67 | "pol": 24, 68 | "art": 25, 69 | "celeb": 26, 70 | "animals": 27 71 | } 72 | self.quiz_help_dict = { 73 | "gk": "General Knowldege", 74 | "books": "Books", 75 | "film": "Films", 76 | "music": "Music", 77 | "theatre": "Musicals and Theatre", 78 | "tv": "Television", 79 | "games": "Video Games", 80 | "bgames": "Board Games", 81 | "sci": "Science and Nature", 82 | "cs": "Computer Science", 83 | "math": "Mathematics", 84 | "myth": "Mythology", 85 | "sports": "Sports", 86 | "geography": "Geography", 87 | "history": "History", 88 | "pol": "Politics", 89 | "art": "Art", 90 | "celeb": "Celebrities", 91 | "animals": "Animals" 92 | } 93 | 94 | @commands.Cog.listener(name="on_message") 95 | async def on_message(self, message: discord.Message): 96 | await on_message(self.bot, message) 97 | 98 | @commands.command(name="daily") 99 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 100 | async def daily(self, ctx: commands.Context): 101 | """Daily dose of sweet cash 💰💰💰""" 102 | daily_time = self.collection.find_one({"_id": ctx.author.id}, {"t_daily": 1}) 103 | 104 | if daily_time is None \ 105 | or daily_time['t_daily'] == 0 \ 106 | or (datetime.utcnow() - daily_time['t_daily']) >= timedelta(days=1): 107 | 108 | self.db_utils.initialize_template().add_operators( 109 | inc=create_dict(wallet=self.defined_currencies['daily']), 110 | set=create_dict(t_daily=datetime.utcnow()) 111 | ).upsert_from_template(create_dict(_id=ctx.author.id), wallet=0, t_daily=0) 112 | 113 | emb = discord.Embed(title="Enjoy your daily cold hard cash 🤑", 114 | description=f"{self.defined_currencies['daily']} coins were placed in your wallet!", 115 | color=discord.Colour.green()) 116 | emb.add_field(name="You can claim your daily again in:", value="24 hours") 117 | await ctx.send(embed=emb) 118 | 119 | else: 120 | emb = discord.Embed(title="You have already claimed your daily coins", color=discord.Colour.red()) 121 | del_time = (daily_time['t_daily'] + timedelta(days=1)) - datetime.utcnow() 122 | days, seconds = del_time.days, del_time.seconds 123 | hours = days * 24 + seconds // 3600 124 | minutes = (seconds % 3600) // 60 125 | seconds = seconds % 60 126 | emb.add_field(name="You can claim your daily again in:", 127 | value=f"{hours} hours, {minutes} minutes and {seconds} seconds") 128 | await ctx.send(embed=emb) 129 | raise CommandError 130 | 131 | @commands.command(name="weekly") 132 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 133 | async def weekly(self, ctx: commands.Context): 134 | """Weekly dose of sweet cash 💰💰💰""" 135 | weekly_time = self.collection.find_one({"_id": ctx.author.id}, {"t_weekly": 1}) 136 | 137 | if weekly_time is None \ 138 | or weekly_time['t_weekly'] == 0 \ 139 | or (datetime.utcnow() - weekly_time['t_weekly']) >= timedelta(days=7): 140 | self.db_utils.initialize_template().add_operators( 141 | inc=create_dict(wallet=self.defined_currencies['weekly']), 142 | set=create_dict(t_weekly=datetime.utcnow()) 143 | ).upsert_from_template(create_dict(_id=ctx.author.id), wallet=0, t_weekly=0) 144 | emb = discord.Embed(title="Enjoy your weekly cold hard cash 🤑", 145 | description=f"{self.defined_currencies['weekly']} coins were placed in your wallet!", 146 | color=discord.Colour.green()) 147 | emb.add_field(name="You can claim your weekly again in:", value="7 days") 148 | await ctx.send(embed=emb) 149 | 150 | else: 151 | emb = discord.Embed(title="You have already claimed your weekly coins", color=discord.Colour.red()) 152 | del_time = (weekly_time['t_weekly'] + timedelta(days=7)) - datetime.utcnow() 153 | days, seconds = del_time.days, del_time.seconds 154 | hours = (days * 24 + seconds // 3600) % 24 155 | minutes = (seconds % 3600) // 60 156 | # seconds = seconds % 60 157 | emb.add_field(name="You can claim your weekly again in:", 158 | value=f"{days} days, {hours} hours and {minutes} minutes") 159 | await ctx.send(embed=emb) 160 | raise CommandError 161 | 162 | @commands.command(name="monthly") 163 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 164 | async def monthly(self, ctx: commands.Context): 165 | """Monthly dose of sweet cash 💰💰💰""" 166 | monthly_time = self.collection.find_one({"_id": ctx.author.id}, {"t_monthly": 1}) 167 | 168 | if monthly_time is None \ 169 | or monthly_time['t_monthly'] == 0 \ 170 | or (datetime.utcnow() - monthly_time['t_monthly']) >= timedelta(days=30): 171 | self.db_utils.initialize_template().add_operators( 172 | inc=create_dict(wallet=self.defined_currencies['monthly']), 173 | set=create_dict(t_monthly=datetime.utcnow()) 174 | ).upsert_from_template(create_dict(_id=ctx.author.id), wallet=0, t_monthly=0) 175 | emb = discord.Embed(title="Enjoy your monthly cold hard cash 🤑", 176 | description=f"{self.defined_currencies['monthly']} coins were placed in your wallet!", 177 | color=discord.Colour.green()) 178 | emb.add_field(name="You can claim your monthly again in:", value="30 days") 179 | await ctx.send(embed=emb) 180 | 181 | else: 182 | emb = discord.Embed(title="You have already claimed your monthly coins", color=discord.Colour.red()) 183 | del_time = (monthly_time['t_monthly'] + timedelta(days=30)) - datetime.utcnow() 184 | days, seconds = del_time.days, del_time.seconds 185 | hours = (days * 24 + seconds // 3600) % 24 186 | minutes = (seconds % 3600) // 60 187 | # seconds = seconds % 60 188 | emb.add_field(name="You can claim your monthly again in:", 189 | value=f"{days} days, {hours} hours and {minutes} minutes") 190 | await ctx.send(embed=emb) 191 | raise CommandError 192 | 193 | @commands.command(name="balance", aliases=['bal']) 194 | @commands.cooldown(rate=1, per=1.0, type=commands.BucketType.user) 195 | async def balance(self, ctx: commands.Context, targeted_user: discord.Member = None): 196 | """Check the balance of those pesky scrubs""" 197 | if targeted_user is None: 198 | targeted_user = ctx.author 199 | wallet_coins, bank_coins = self.utils.get_balance(targeted_user.id) 200 | desc_str = f"**Wallet: **" \ 201 | f"{wallet_coins}\n**Bank: **" \ 202 | f"{bank_coins}" 203 | emb = discord.Embed(title=f"**{targeted_user.display_name}'s Account details**", description=desc_str, 204 | color=discord.Colour.green()) 205 | if wallet_coins + bank_coins == 0: 206 | emb.set_footer(text="Poor much?") 207 | await ctx.send(embed=emb) 208 | 209 | @commands.command(name="withdraw", aliases=['with']) 210 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 211 | async def withdraw(self, ctx: commands.Context, amount: str): 212 | wallet_coins, bank_coins = self.utils.get_balance(ctx.author.id) 213 | if bank_coins == 0: 214 | await ctx.send(f"{ctx.author.mention} Your bank account is empty lmfao") 215 | raise CommandError 216 | if amount.lower() == "max" or amount.lower() == "all": 217 | amount = bank_coins 218 | else: 219 | try: 220 | amount = int(amount) 221 | except ValueError: 222 | await ctx.send(f"{ctx.author.mention} Enter a valid amount or max/all") 223 | raise CommandError 224 | if amount <= 0: 225 | await ctx.send(f"{ctx.author.mention} Enter a valid amount or max/all") 226 | raise CommandError 227 | if amount > bank_coins: 228 | await ctx.send(f"{ctx.author.mention} You do not have {amount} coins in your bank account") 229 | raise CommandError 230 | self.db_utils.initialize().add_operators( 231 | inc=create_dict(wallet=amount, bank=-amount) 232 | ).update_one(create_dict(_id=ctx.author.id)) 233 | emb = discord.Embed(title=f"{ctx.author.display_name} Withdrew {amount} coins", 234 | description=f"**Wallet: **" 235 | f"{wallet_coins + amount}\n**Bank: **" 236 | f"{bank_coins - amount}", 237 | color=discord.Colour.green()) 238 | await ctx.send(embed=emb) 239 | 240 | @commands.command(name="deposit", aliases=['dep']) 241 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 242 | async def deposit(self, ctx: commands.Context, amount: str): 243 | wallet_coins, bank_coins = self.utils.get_balance(ctx.author.id) 244 | if wallet_coins == 0: 245 | await ctx.send(f"{ctx.author.mention} Your wallet is empty lmfao") 246 | raise CommandError 247 | if amount.lower() == "max" or amount.lower() == "all": 248 | amount = wallet_coins 249 | else: 250 | try: 251 | amount = int(amount) 252 | except ValueError: 253 | await ctx.send(f"{ctx.author.mention} Enter a valid amount or max/all") 254 | raise CommandError 255 | if amount <= 0: 256 | await ctx.send(f"{ctx.author.mention} Enter a valid amount or max/all") 257 | raise CommandError 258 | if amount > wallet_coins: 259 | await ctx.send(f"{ctx.author.mention} You do not have {amount} coins in your wallet") 260 | raise CommandError 261 | self.db_utils.initialize().add_operators( 262 | inc=create_dict(wallet=-amount, bank=amount) 263 | ).update_one(create_dict(_id=ctx.author.id)) 264 | emb = discord.Embed(title=f"{ctx.author.display_name} Deposited {amount} coins", 265 | description=f"**Wallet: **" 266 | f"{wallet_coins - amount}\n**Bank: **" 267 | f"{bank_coins + amount}", 268 | color=discord.Colour.green()) 269 | await ctx.send(embed=emb) 270 | 271 | @commands.command(name="give", aliases=['pay']) 272 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 273 | async def give(self, ctx: commands.Context, targeted_user: discord.Member, amount: int): 274 | """Give away your hard earned cash 🎁""" 275 | if ctx.author.id == targeted_user.id: 276 | await ctx.send(f"{ctx.author.mention}, you can't give coins to yourself. 😡") 277 | raise CommandError 278 | if amount <= 0: 279 | await ctx.send(f"{ctx.author.mention}, enter a value greater than 0. You can't fool me. 😡") 280 | raise CommandError 281 | wallet_coins, bank_coins = self.utils.get_balance(ctx.author.id) 282 | if wallet_coins < amount or wallet_coins == 0: 283 | await ctx.send(f"{ctx.author.mention} You don't have enough coins lmao, get a job.") 284 | raise CommandError 285 | else: 286 | self.db_utils.initialize().add_operators( 287 | inc=create_dict(wallet=-amount) 288 | ).update_one(create_dict(_id=ctx.author.id)) 289 | self.db_utils.initialize_template().add_operators( 290 | inc=create_dict(wallet=amount) 291 | ).upsert_from_template(create_dict(_id=targeted_user.id), wallet=0) 292 | await ctx.send( 293 | f"** {ctx.author.mention} gave {amount} coins to {targeted_user.display_name} " 294 | f"**") 295 | 296 | @commands.command(name="shop") 297 | @commands.cooldown(rate=1, per=1.0, type=commands.BucketType.user) 298 | async def shop(self, ctx: commands.Context, page: int = 1): 299 | """See what treasures await your purchase""" 300 | if self.pages >= page >= 1: 301 | embed = self.paged_shop[page - 1].set_footer(text=f"Page {page} of {self.pages}") 302 | await ctx.send(embed=embed) 303 | else: 304 | await ctx.send(f"{ctx.author.mention} Enter a valid page number") 305 | raise CommandError 306 | 307 | @commands.command(name="gift") 308 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 309 | async def gift(self, ctx: commands.Context, target_user: discord.Member, item: str, amount: int = 1): 310 | """Give away your precious items 🎁""" 311 | item_dict = None 312 | item_id = None 313 | item = item.lower() 314 | if item in self.items_by_id: 315 | item_dict = self.items_by_id[item] 316 | item_id = item 317 | elif item in self.id_by_name: 318 | item_dict = self.items_by_id[str(self.id_by_name[item])] 319 | item_id = str(self.id_by_name[item]) 320 | 321 | if item_dict is not None and item_id is not None: 322 | if amount > 0: 323 | inventory = self.collection.find_one({"_id": ctx.author.id}, {"inventory": 1}) 324 | if inventory is not None: 325 | inventory = inventory["inventory"] 326 | if item_id in inventory and inventory[item_id] >= amount: 327 | embed = discord.Embed( 328 | title=f"Do you want to gift {amount} {item_dict['name']} to {target_user.name}?", 329 | description="React with 👍 within 15 seconds to confirm", color=discord.Colour.green()) 330 | embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.avatar_url) 331 | message = await ctx.send(embed=embed) 332 | await message.add_reaction("👍") 333 | 334 | def check(reaction, user): 335 | return user.id == ctx.author.id and str( 336 | reaction.emoji) == '👍' and reaction.message.id == message.id 337 | 338 | try: 339 | await self.bot.wait_for('reaction_add', timeout=15.0, check=check) 340 | self.db_utils.initialize().add_operators( 341 | inc={f"inventory.{item_id}": -amount} 342 | ).update_one(create_dict(_id=ctx.author.id)) 343 | self.db_utils.initialize_template().add_operators( 344 | inc={f"inventory.{item_id}": amount} 345 | ).upsert_from_template(create_dict(_id=target_user.id), inventory=0) 346 | await ctx.send( 347 | f"{ctx.author.mention} You have successfully " 348 | f"gifted {amount} {item_dict['name']} to {target_user.name}") 349 | except asyncio.TimeoutError: 350 | embed = discord.Embed( 351 | title=f"Do you want to gift {amount} {item_dict['name']} to {target_user.name}?", 352 | description="Gift failed. Please try again", color=discord.Colour.red()) 353 | embed.set_footer(text=f"Requested by {ctx.author.display_name}", 354 | icon_url=ctx.author.avatar_url) 355 | await message.edit(embed=embed) 356 | await message.clear_reactions() 357 | raise CommandError 358 | else: 359 | await ctx.send(f"{ctx.author.mention} Lmao you don't have {amount} {item_dict['name']} to" 360 | f" gift.") 361 | raise CommandError 362 | else: 363 | self.db_utils.initialize_template().insert_from_template(_id=ctx.author.id) 364 | await ctx.send(f"{ctx.author.mention} Lmao you don't have {amount} {item_dict['name']} to gift.") 365 | raise CommandError 366 | else: 367 | await ctx.send(f"{ctx.author.mention} Enter a valid amount") 368 | raise CommandError 369 | else: 370 | await ctx.send(f"{ctx.author.mention} Enter a valid item ID or name") 371 | raise CommandError 372 | 373 | @commands.command(name="buy") 374 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 375 | async def buy(self, ctx: commands.Context, item, amount: int = 1): 376 | """Buy the items of your dreams from the shop """ 377 | item_dict = None 378 | item = item.lower() 379 | try: 380 | item = int(item) 381 | if str(item) in self.items_by_id: 382 | item_dict = self.items_by_id[str(item)] 383 | except Exception: 384 | if item in self.id_by_name: 385 | item_dict = self.items_by_id[str(self.id_by_name[item])] 386 | item = self.id_by_name[item] 387 | if item_dict is None: 388 | await ctx.send(f"{ctx.author.mention} Enter a valid item ID or name") 389 | raise CommandError 390 | if amount < 0: 391 | await ctx.send(f"{ctx.author.mention} Enter a valid amount") 392 | raise CommandError 393 | wallet_coins, bank_coins = self.utils.get_balance(ctx.author.id) 394 | if wallet_coins <= 0 or wallet_coins < self.items_by_id[str(item)]["value"] * amount: 395 | await ctx.send( 396 | f"{ctx.author.mention} You don't have enough money" + 397 | f" for buying {self.items_by_id[str(item)]['name']}. Get a job lmao.") 398 | raise CommandError 399 | 400 | embed = discord.Embed( 401 | title=f"Do you want to purchase {amount} {item_dict['name']} for {item_dict['value'] * amount}?", 402 | description="React with 👍 within 15 seconds to purchase", color=discord.Colour.green()) 403 | embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.avatar_url) 404 | message = await ctx.send(embed=embed) 405 | await message.add_reaction("👍") 406 | 407 | def check(reaction, user): 408 | return user.id == ctx.author.id and str( 409 | reaction.emoji) == '👍' and reaction.message.id == message.id 410 | 411 | try: 412 | await self.bot.wait_for('reaction_add', timeout=15.0, check=check) 413 | self.db_utils.initialize().add_operators( 414 | inc={"wallet": -item_dict["value"] * amount, 415 | f"inventory.{str(item)}": amount} 416 | ).update_one(create_dict(_id=ctx.author.id)) 417 | await ctx.send( 418 | f"{ctx.author.mention} You have successfully " 419 | f"purchased {amount} {item_dict['name']} for {item_dict['value'] * amount}") 420 | except asyncio.TimeoutError: 421 | embed = discord.Embed( 422 | title=f"Do you want to purchase {amount} {item_dict['name']} for {item_dict['value'] * amount}?", 423 | description="Purchase failed. Please try again", color=discord.Colour.red()) 424 | embed.set_footer(text=f"Requested by {ctx.author.display_name}", 425 | icon_url=ctx.author.avatar_url) 426 | await message.edit(embed=embed) 427 | await message.clear_reactions() 428 | raise CommandError 429 | 430 | @commands.command(name="bet") 431 | @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.user) 432 | async def bet(self, ctx: commands.Context, amount: str): 433 | """Join in on some gambling action, similar to Klondike dice game""" 434 | wallet_coins, bank_coins = self.utils.get_balance(ctx.author.id) 435 | try: 436 | amount = int(amount) 437 | except ValueError: 438 | if amount.lower() == "max" or amount.lower() == "all": 439 | if wallet_coins <= 0: 440 | await ctx.send(f"{ctx.author.mention} Lmao you don't have enough coins to bet.") 441 | raise CommandError 442 | if wallet_coins >= 250000: 443 | amount = 250000 444 | else: 445 | amount = wallet_coins 446 | else: 447 | await ctx.send(f"{ctx.author.mention} Enter a proper amount or max/all.") 448 | raise CommandError 449 | 450 | if 250000 >= amount >= 50: 451 | if wallet_coins >= amount and wallet_coins > 0: 452 | bot_pair, user_pair = find_pairs(np.random.randint(1, 6, 5)), find_pairs(np.random.randint(1, 6, 5)) 453 | if bot_pair <= user_pair: 454 | embed = discord.Embed(title=f"{ctx.author.display_name}'s losing bet", 455 | description=f"You lost {amount} coins", 456 | color=discord.Colour.red()) 457 | embed.add_field(name="Chintu rolled:", value=self.houses[bot_pair]) 458 | embed.add_field(name="You rolled:", value=self.houses[user_pair]) 459 | self.db_utils.initialize().add_operators( 460 | inc=create_dict(wallet=-amount) 461 | ).update_one(create_dict(_id=ctx.author.id)) 462 | else: 463 | embed = discord.Embed(title=f"{ctx.author.display_name}'s winning bet", 464 | description=f"You won {int(amount * self.prizes[bot_pair - user_pair] + amount)} coins", 465 | color=discord.Colour.green()) 466 | embed.add_field(name="Chintu rolled:", value=self.houses[bot_pair]) 467 | embed.add_field(name="You rolled:", value=self.houses[user_pair]) 468 | self.db_utils.initialize().add_operators( 469 | inc=create_dict(wallet=int(amount * self.prizes[bot_pair - user_pair])) 470 | ).update_one(create_dict(_id=ctx.author.id)) 471 | await ctx.send(embed=embed) 472 | else: 473 | await ctx.send(f"{ctx.author.mention} Lmao you don't have enough coins to bet.") 474 | raise CommandError 475 | elif amount >= 250000: 476 | await ctx.send(f"{ctx.author.mention} If I let you bet more than 50,000 coins, you'd be broke in no time.") 477 | raise CommandError 478 | else: 479 | await ctx.send(f"{ctx.author.mention} Enter an amount greater than 50 coins") 480 | raise CommandError 481 | 482 | @commands.command(name="use") 483 | @commands.cooldown(rate=1, per=8.0, type=commands.BucketType.user) 484 | async def use(self, ctx: commands.Context, item): 485 | """Use the items you got there in your inventory""" 486 | item_dict = None 487 | item = item.lower() 488 | try: 489 | item = int(item) 490 | if str(item) in self.items_by_id: 491 | item_dict = self.items_by_id[str(item)] 492 | except Exception: 493 | if item in self.id_by_name: 494 | item_dict = self.items_by_id[str(self.id_by_name[item])] 495 | item = self.id_by_name[item] 496 | if item_dict: 497 | if item_dict['type'] == "item": 498 | await ctx.send("This item cannot be used.") 499 | raise CommandError 500 | inventory_dict = self.collection.find_one({"_id": ctx.author.id}, {"inventory": 1}) 501 | if inventory_dict is not None and \ 502 | str(item) in inventory_dict["inventory"] and \ 503 | inventory_dict["inventory"][str(item)] > 0: 504 | try: 505 | await eval(item_dict['type'] + '(self.bot, ctx, item_dict)') 506 | except Exception as e: 507 | if not isinstance(e, CommandError): 508 | await ctx.send(f"Could't use {item_dict['name']}. Please report this issue using $suggest.") 509 | raise CommandError 510 | else: 511 | await ctx.send( 512 | f"You do not have {item_dict['name']}. Buy it from the shop ($shop) before trying again.") 513 | raise CommandError 514 | else: 515 | await ctx.send(f"Could not find item with name or id {item}") 516 | raise CommandError 517 | 518 | @commands.command(name="iteminfo") 519 | @commands.cooldown(rate=1, per=10.0, type=commands.BucketType.user) 520 | async def iteminfo(self, ctx: commands.Context, item_name): 521 | item_dict = None 522 | item = item_name.lower() 523 | try: 524 | item = int(item) 525 | if str(item) in self.items_by_id: 526 | item_dict = self.items_by_id[str(item)] 527 | except Exception: 528 | if item in self.id_by_name: 529 | item_dict = self.items_by_id[str(self.id_by_name[item])] 530 | item = self.id_by_name[item] 531 | if item_dict: 532 | if item_dict["properties"]: 533 | await ctx.send(eval(f"properties_{item}(ctx)")) 534 | else: 535 | await ctx.send(f"{ctx.author.mention} No info available for this item") 536 | else: 537 | await ctx.send(f"Could not find item with name or id {item}") 538 | raise CommandError 539 | 540 | @commands.command(name="inventory", aliases=["inv"]) 541 | @commands.cooldown(rate=1, per=3.0, type=commands.BucketType.user) 542 | async def inventory(self, ctx: commands.Context, target_user=None, page_number=1): 543 | """Check what you have in your inventory""" 544 | if target_user is None: 545 | target_user = ctx.author 546 | page_number = 1 547 | else: 548 | try: 549 | converter = commands.MemberConverter() 550 | target_user = await converter.convert(ctx, target_user) 551 | page_number = page_number 552 | except Exception: 553 | try: 554 | page_number = int(target_user) 555 | target_user = ctx.author 556 | except Exception: 557 | await ctx.send("Enter a valid page number") 558 | raise CommandError 559 | inventory_dict = self.collection.find_one({"_id": target_user.id}, {"inventory": 1}) 560 | if inventory_dict is not None: 561 | inventory_dict = inventory_dict['inventory'] 562 | inventory_dict = {key: val for key, val in inventory_dict.items() if val != 0} 563 | total_items = len(inventory_dict) 564 | pages = int((total_items - 1) // 5 + 1 + (total_items - 1) % 5 / 10) 565 | if pages != 0: 566 | if 0 < page_number <= pages: 567 | keys = list(inventory_dict.keys()) 568 | embed = discord.Embed(title=f"{target_user.name}'s Inventory", color=discord.Colour.orange()) 569 | if page_number == pages: 570 | limit = total_items 571 | else: 572 | limit = page_number * 5 573 | for i in range((page_number - 1) * 5, limit): 574 | item_id_str = keys[i] 575 | embed.add_field( 576 | name=f"{self.items_by_id[item_id_str]['emoji']} {self.items_by_id[item_id_str]['name']} ─ {inventory_dict[item_id_str]}", 577 | value=f"(ID - {item_id_str}) {self.items_by_id[item_id_str]['description']}", inline=False) 578 | embed.set_footer(icon_url=target_user.avatar_url, 579 | text=f"Requested by {ctx.author.display_name} • Page {page_number}/{pages}") 580 | await ctx.send(embed=embed) 581 | else: 582 | await ctx.send(f"Enter a valid page number") 583 | raise CommandError 584 | else: 585 | await ctx.send("The inventory is empty lmao. To buy something use $shop") 586 | raise CommandError 587 | else: 588 | self.db_utils.initialize_template().insert_from_template(_id=target_user.id) 589 | await ctx.send("The inventory is empty lmao. To buy something use $shop") 590 | raise CommandError 591 | 592 | @commands.command(name="quiz") 593 | @commands.cooldown(rate=1, per=10.0, type=commands.BucketType.user) 594 | async def quiz(self, ctx: commands.Context, category: str = None): 595 | """Get coins for answering questions.""" 596 | if category is None: 597 | category = "none" 598 | category = category.lower() 599 | if category == "help": 600 | embed = discord.Embed(title="Available Quiz Categories: ", color=discord.Colour.orange()) 601 | for avl_category in self.quiz_help_dict: 602 | embed.add_field(name=self.quiz_help_dict[avl_category], value=f"$quiz {avl_category}") 603 | await ctx.send(embed=embed) 604 | return 605 | create_footer = False 606 | if category in self.quiz_categories: 607 | category = self.quiz_categories[category] 608 | else: 609 | category = random.randint(9, 28) 610 | create_footer = True 611 | response = requests.get( 612 | f"https://opentdb.com/api.php?amount=1&type=multiple&category={category}").json()[ 613 | "results"][0] 614 | options = response["incorrect_answers"] 615 | options.append(response["correct_answer"]) 616 | random.shuffle(options) 617 | correct_option = options.index(response["correct_answer"]) 618 | desc_str = "" 619 | num_to_alphabet = {0: "A", 1: "B", 2: "C", 3: "D"} 620 | alphabet_to_num = {"A": 0, "B": 1, "C": 2, "D": 3} 621 | for i in range(len(options)): 622 | desc_str += f"**{num_to_alphabet[i]}: ** {options[i]}\n" 623 | q_embed = discord.Embed(title=html.unescape(response["question"]), description=html.unescape(desc_str), 624 | color=discord.Colour.orange()) 625 | if create_footer: 626 | q_embed.set_footer(text="Use $quiz help to get a list of categories") 627 | sent_embed = await ctx.send(embed=q_embed) 628 | 629 | def check(message): 630 | return message.channel == ctx.channel and message.author.id == ctx.author.id 631 | 632 | try: 633 | msg: discord.Message = await self.bot.wait_for('message', timeout=10.0, check=check) 634 | if msg.content.upper() in alphabet_to_num: 635 | if alphabet_to_num[msg.content.upper()] == correct_option: 636 | r_embed = discord.Embed(title=f"{ctx.author.display_name} gave the correct answer", 637 | description=f"{self.defined_currencies['quiz']} coins were added to your wallet", 638 | color=discord.Colour.green()) 639 | if create_footer: 640 | r_embed.set_footer(text="Use $quiz help to get a list of categories") 641 | self.db_utils.initialize_template().add_operators( 642 | inc=create_dict(wallet=self.defined_currencies['quiz']) 643 | ).upsert_from_template(create_dict(_id=ctx.author.id), wallet=0) 644 | await sent_embed.edit(embed=r_embed) 645 | else: 646 | r_embed = discord.Embed(title=f"{ctx.author.display_name} gave the incorrect answer", 647 | description=f"The correct answer was **{num_to_alphabet[correct_option]}: {html.unescape(options[correct_option])}**", 648 | color=discord.Colour.red()) 649 | if create_footer: 650 | r_embed.set_footer(text="Use $quiz help to get a list of categories") 651 | await sent_embed.edit(embed=r_embed) 652 | else: 653 | await ctx.send(f"{ctx.author.mention} Bruh enter a proper option next time (A/B/C/D)") 654 | except asyncio.TimeoutError: 655 | r_embed = discord.Embed(title=f"{ctx.author.display_name}'s answer time ran out", 656 | description=f"The correct answer was **{num_to_alphabet[correct_option]}: {html.unescape(options[correct_option])}** (Timeout = 10 seconds)", 657 | color=discord.Colour.red()) 658 | await sent_embed.edit(embed=r_embed) 659 | raise CommandError 660 | 661 | @commands.command(name="addmoney", hidden=True) 662 | @commands.is_owner() 663 | async def addmoney(self, ctx: commands.Context, amount: int, targeted_user: discord.Member = None): 664 | if targeted_user is None: 665 | targeted_user = ctx.author 666 | self.db_utils.initialize_template().add_operators( 667 | inc=create_dict(wallet=amount) 668 | ).upsert_from_template(create_dict(_id=targeted_user.id), wallet=0) 669 | emb = discord.Embed(description=f"***Added {amount} coins to {targeted_user.display_name}'s balance.***", 670 | color=discord.Colour.green()) 671 | await ctx.send(embed=emb) 672 | 673 | 674 | def create_paged_shop(items: dict): 675 | items = {key: val for key, val in items.items() if not val['archive']} 676 | shop_items_len = len(items) 677 | pages = shop_items_len // 5 678 | if shop_items_len % 5 != 0: 679 | pages += 1 680 | i = 0 681 | j = -1 682 | embeds = [] 683 | for item in items: 684 | if i % 5 == 0: 685 | j += 1 686 | embeds.append(discord.Embed(title="Chintu Store", color=discord.Colour.green())) 687 | embeds[j].add_field(name=f"{items[item]['name']} ─ {items[item]['value']}", 688 | value=f"(ID - {item}) {items[item]['description']}", inline=False) 689 | i += 1 690 | return embeds, pages 691 | 692 | 693 | def find_pairs(array: np.ndarray): 694 | len_without_dup = len(set(array)) 695 | arr_set = list(set(array)) 696 | arr_sum = np.sum(array) 697 | if len_without_dup > 3: 698 | return len_without_dup + 1 699 | elif len_without_dup == 1: 700 | return len_without_dup 701 | elif len_without_dup == 3: 702 | set_sum = np.sum(arr_set) 703 | if arr_sum - arr_set[0] * 3 == set_sum - arr_set[0] or arr_sum - arr_set[1] * 3 == set_sum - arr_set[1] \ 704 | or arr_sum - arr_set[0] * 3 == set_sum - arr_set[0]: 705 | return 6 706 | else: 707 | return 4 708 | if arr_set[0] * 4 + arr_set[1] == arr_sum or arr_set[1] * 4 + arr_set[0] == arr_sum: 709 | return 2 710 | else: 711 | return 3 712 | 713 | 714 | def setup(bot): 715 | bot.add_cog(Currency(bot)) 716 | -------------------------------------------------------------------------------- /cogs/utils/GameGrid.py: -------------------------------------------------------------------------------- 1 | import random 2 | import numpy as np 3 | import datetime 4 | 5 | games = [] 6 | 7 | 8 | def getGames(): 9 | return games 10 | 11 | 12 | def getGamesByUser(user: str): 13 | for game in games: 14 | userid = str(game.getId()) 15 | if userid == user: 16 | return game 17 | 18 | 19 | def getGamesByMessage(message: str): 20 | for game in games: 21 | if game.getMessageId() == message: 22 | return game 23 | 24 | 25 | class GameGrid: 26 | 27 | def __init__(self, user_id: str, name: str, url: str): 28 | self.message_id = '' 29 | self.channel = '' 30 | self.matrix = np.array([[0, 0, 0, 0], 31 | [0, 0, 0, 0], 32 | [0, 0, 0, 0], 33 | [0, 0, 0, 0]]) 34 | self.user = user_id 35 | self.name = name 36 | self.url = url 37 | self.last_update = datetime.datetime.now() 38 | self.point = 0 39 | self.running = True 40 | 41 | def randomNumber(self): 42 | x = random.randint(0, 3) 43 | y = random.randint(0, 3) 44 | 45 | if self.matrix[x, y] == 0: 46 | self.matrix[x, y] = 2 47 | else: 48 | self.randomNumber() 49 | 50 | def getEmojiMessage(self): 51 | self.updateLastUpdate() 52 | message = '' 53 | 54 | for y in range(0, 4): 55 | for x in range(0, 4): 56 | num = self.matrix[y, x] 57 | 58 | if num == 0: 59 | message += '<:blank:845902891487199243>' 60 | elif num == 2: 61 | message += '<:2_:845901774539194369>' 62 | elif num == 4: 63 | message += '<:4_:845901774959149056>' 64 | elif num == 8: 65 | message += '<:8_:845901775101493248>' 66 | elif num == 16: 67 | message += '<:16:845901775206875166>' 68 | elif num == 32: 69 | message += '<:32:845901775193636894>' 70 | elif num == 64: 71 | message += '<:64:845901775060074496>' 72 | elif num == 128: 73 | message += '<:128:845901774762147851>' 74 | elif num == 256: 75 | message += '<:256:845901774938177547>' 76 | elif num == 512: 77 | message += '<:512:845901775118663710>' 78 | elif num == 1024: 79 | message += '<:1024:845901775122857984>' 80 | elif num == 2048: 81 | message += '<:2048:845901775273459767>' 82 | elif num == 4096: 83 | message += '<:4096:845901775265726474>' 84 | message += '\n' 85 | 86 | return message 87 | 88 | 89 | 90 | def slideUp(self): 91 | 92 | def shiftUp(): 93 | for p in range(0, 3): 94 | for yin in range(1, 4): 95 | for xin in range(0, 4): 96 | if self.matrix[yin, xin] != 0 and self.matrix[yin - 1, xin] == 0: 97 | self.matrix[yin - 1, xin] = self.matrix[yin, xin] 98 | self.matrix[yin, xin] = 0 99 | 100 | shiftUp() 101 | for y in range(1, 4): 102 | for x in range(0, 4): 103 | if self.matrix[y, x] == self.matrix[y - 1, x]: 104 | self.matrix[y - 1, x] = self.matrix[y - 1, x] * 2 105 | self.matrix[y, x] = 0 106 | self.updatePoint(self.matrix[y - 1, x] / 2) 107 | 108 | shiftUp() 109 | 110 | def slideDown(self): 111 | 112 | def shiftDown(): 113 | for p in range(0, 3): 114 | for yin in range(2, -1, -1): 115 | for xin in range(3, -1, -1): 116 | if self.matrix[yin, xin] != 0 and self.matrix[yin + 1, xin] == 0: 117 | self.matrix[yin + 1, xin] = self.matrix[yin, xin] 118 | self.matrix[yin, xin] = 0 119 | 120 | shiftDown() 121 | for y in range(2, -1, -1): 122 | for x in range(3, -1, -1): 123 | if self.matrix[y, x] == self.matrix[y + 1, x]: 124 | self.matrix[y + 1, x] = self.matrix[y + 1, x] * 2 125 | self.matrix[y, x] = 0 126 | self.updatePoint(self.matrix[y + 1, x] / 2) 127 | 128 | shiftDown() 129 | 130 | def slideLeft(self): 131 | 132 | def shiftLeft(): 133 | for p in range(0, 3): 134 | for xin in range(1, 4): 135 | for yin in range(0, 4): 136 | if self.matrix[yin, xin] != 0 and self.matrix[yin, xin - 1] == 0: 137 | self.matrix[yin, xin - 1] = self.matrix[yin, xin] 138 | self.matrix[yin, xin] = 0 139 | 140 | shiftLeft() 141 | for x in range(1, 4): 142 | for y in range(0, 4): 143 | if self.matrix[y, x] == self.matrix[y, x - 1]: 144 | self.matrix[y, x - 1] = self.matrix[y, x - 1] * 2 145 | self.matrix[y, x] = 0 146 | self.updatePoint(self.matrix[y, x - 1] / 2) 147 | 148 | shiftLeft() 149 | 150 | def slideRight(self): 151 | 152 | def shiftRight(): 153 | for p in range(0, 3): 154 | for xin in range(2, -1, -1): 155 | for yin in range(3, -1, -1): 156 | if self.matrix[yin, xin] != 0 and self.matrix[yin, xin + 1] == 0: 157 | self.matrix[yin, xin + 1] = self.matrix[yin, xin] 158 | self.matrix[yin, xin] = 0 159 | 160 | shiftRight() 161 | for x in range(2, -1, -1): 162 | for y in range(3, -1, -1): 163 | if self.matrix[y, x] == self.matrix[y, x + 1]: 164 | self.matrix[y, x + 1] = self.matrix[y, x + 1] * 2 165 | self.matrix[y, x] = 0 166 | self.updatePoint(self.matrix[y, x + 1] / 2) 167 | 168 | shiftRight() 169 | 170 | def start(self): 171 | if getGamesByUser(self.user): 172 | self.stop() 173 | self.running = True 174 | self.randomNumber() 175 | self.randomNumber() 176 | games.append(self) 177 | 178 | def isGameOver(self): 179 | if 0 in self.matrix: 180 | return False 181 | 182 | for y in range(0, 4): 183 | for x in range(0, 4): 184 | num = self.matrix[y, x] 185 | 186 | try: 187 | if self.matrix[y - 1, x] == num: 188 | return False 189 | except Exception: 190 | pass 191 | 192 | try: 193 | if self.matrix[y + 1, x] == num: 194 | return False 195 | except Exception: 196 | pass 197 | 198 | try: 199 | if self.matrix[y, x - 1] == num: 200 | return False 201 | except Exception: 202 | pass 203 | 204 | try: 205 | if self.matrix[y, x + 1] == num: 206 | return False 207 | except Exception: 208 | pass 209 | 210 | return True 211 | 212 | def isGameWon(self): 213 | if 4096 in self.matrix: 214 | return True 215 | return False 216 | 217 | def stop(self): 218 | self.running = False 219 | games.remove(self) 220 | 221 | def updatePoint(self, point: int): 222 | self.point += point 223 | 224 | def getPoint(self): 225 | return self.point 226 | 227 | def isRunning(self): 228 | return self.running 229 | 230 | def setMessageId(self, msgid: str): 231 | self.message_id = msgid 232 | 233 | def getMessageId(self): 234 | return self.message_id 235 | 236 | def updateLastUpdate(self): 237 | self.last_update = datetime.datetime.now() 238 | 239 | def getLastUpdate(self): 240 | return (datetime.datetime.now() - self.last_update).total_seconds() 241 | 242 | def setChannelId(self, channel: str): 243 | self.channel = channel 244 | 245 | def getChannelId(self): 246 | return self.channel 247 | 248 | def getMatrix(self): 249 | return self.matrix 250 | 251 | def getId(self): 252 | return self.user 253 | -------------------------------------------------------------------------------- /cogs/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/cogs/utils/__init__.py -------------------------------------------------------------------------------- /cogs/utils/chess_utils.py: -------------------------------------------------------------------------------- 1 | import io 2 | 3 | import cairosvg 4 | import chess 5 | import chess.pgn 6 | import chess.svg 7 | import discord 8 | from abc import ABC 9 | """ 10 | sus={'id': 'WXyKWw1q', 11 | 'variant': {'key': 'standard', 'name': 'Standard', 'short': 'Std'}, 12 | 'speed': 'correspondence', 13 | 'perf': 'correspondence', 14 | 'rated': False, 15 | 'initialFen': 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1', 16 | 'fen': 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1', 17 | 'player': 'white', 18 | 'turns': 0, 19 | 'startedAtTurn': 0, 20 | 'source': 'ai', 21 | 'status': {'id': 20, 'name': 'started'}, 22 | 'createdAt': 1627135755014 23 | } 24 | """ 25 | 26 | 27 | class ChessUtils: 28 | def __init__(self, client): 29 | self.client = client 30 | 31 | def import_game_by_id(self, game_id: str): 32 | pgn = str(self.client.games.export(game_id, as_pgn=True)) 33 | game = chess.pgn.read_game(io.StringIO(pgn)) 34 | return game 35 | 36 | def import_last_game_by_player(self, player_name: str): 37 | pgn = list(self.client.games.export_by_player(player_name, max=1, as_pgn=True))[0] 38 | game = chess.pgn.read_game(io.StringIO(pgn)) 39 | return game 40 | 41 | def save_moves_as_png(self, game: chess.pgn.GameNode): 42 | ply = 1 43 | for position in game.mainline(): 44 | self.save_position_as_png(position.board(), ply) 45 | ply += 1 46 | 47 | def create_ai_game(self, level:int, color): 48 | if level < 0: 49 | level = 0 50 | elif level > 8: 51 | level = 8 52 | return self.client.challenges.create_ai(level=level, color=color) 53 | 54 | @classmethod 55 | def save_position_as_png(cls, board: chess.Board, ply: int): 56 | boardsvg = chess.svg.board(board=board) 57 | cairosvg.svg2png(file_obj=io.StringIO(str(boardsvg)), write_to=f"move{ply}.png") 58 | 59 | @classmethod 60 | def create_position_embed(cls, game: chess.pgn.Game, board: chess.Board, end=False): 61 | board_svg = chess.svg.board(board) 62 | png_bytes = cairosvg.svg2png(file_obj=io.StringIO(str(board_svg))) 63 | file = discord.File(io.BytesIO(png_bytes), filename="chess.png") 64 | embed = discord.Embed( 65 | title=f":white_circle: {game.headers['White']}({game.headers['WhiteElo']}) vs. " 66 | f":black_circle: {game.headers['Black']}({game.headers['BlackElo']})", 67 | description=f"Event: {game.headers['Event']} | Result: {game.headers['Result']}{' | End of game' if end else ''}" 68 | ) 69 | return embed, file 70 | 71 | @classmethod 72 | def render_board(cls, board:chess.Board, headers): 73 | board_svg = chess.svg.board(board) 74 | png_bytes = cairosvg.svg2png(file_obj=io.StringIO(str(board_svg))) 75 | file = discord.File(io.BytesIO(png_bytes), filename="chess.png") 76 | embed = discord.Embed( 77 | title=f":white_circle: {headers['White']}({headers['WhiteElo']}) vs. " 78 | f":black_circle: {headers['Black']}({headers['BlackElo']})", 79 | description=f"Event: {headers['Event']} | Result: {headers['Result']}" 80 | ) 81 | return embed, file 82 | -------------------------------------------------------------------------------- /cogs/utils/currency_utils.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | from datetime import datetime 3 | from cogs.utils.db_utils import db_utils 4 | 5 | 6 | class currency_utils: 7 | def __init__(self, collection: pymongo.collection.Collection): 8 | self.collection = collection 9 | self.db_utils = db_utils(collection) 10 | 11 | # def update_and_insert(self, doc_id: int, inc_vals=None, set_vals=None, wallet=True, bank=True, bank_limit=True, 12 | # inventory=True, t_daily=True, t_weekly=True, t_monthly=True, commands=True): 13 | # bool_dict = { 14 | # "wallet": wallet, 15 | # "bank": bank, 16 | # "bank_limit": bank_limit, 17 | # "commands": commands, 18 | # "t_daily": t_daily, 19 | # "t_weekly": t_weekly, 20 | # "t_monthly": t_monthly 21 | # } 22 | # set_on_insert_dict = {} 23 | # update_dict = {} 24 | # if inc_vals: 25 | # update_dict["$inc"] = inc_vals 26 | # if set_vals: 27 | # update_dict["$set"] = set_vals 28 | # if inventory: 29 | # set_on_insert_dict["inventory"] = {} 30 | # for key in bool_dict: 31 | # if bool_dict[key]: 32 | # set_on_insert_dict[key] = 0 33 | # 34 | # update_dict["$setOnInsert"] = set_on_insert_dict 35 | # self.collection.update_one({"_id": doc_id}, update_dict, upsert=True) 36 | 37 | # def update(self, doc_id: int, inc_vals=None, set_vals=None): 38 | # update_dict = {} 39 | # if inc_vals: 40 | # update_dict["$inc"] = inc_vals 41 | # if set_vals: 42 | # update_dict["$set"] = set_vals 43 | # self.collection.update_one({"_id": doc_id}, update_dict) 44 | # 45 | # def insert_new_document(self, 46 | # doc_id: int, 47 | # wallet: int = 0, 48 | # bank: int = 0, 49 | # bank_limit: int = 0, 50 | # commands: int = 0, 51 | # inventory=None, 52 | # t_daily: datetime = 0, 53 | # t_weekly: datetime = 0, 54 | # t_monthly: datetime = 0): 55 | # if inventory is None: 56 | # inventory = {} 57 | # self.collection.insert_one({ 58 | # "_id": doc_id, 59 | # "wallet": wallet, 60 | # "bank": bank, 61 | # "bank_limit": bank_limit, 62 | # "commands": commands, 63 | # "inventory": inventory, 64 | # "t_daily": t_daily, 65 | # "t_weekly": t_weekly, 66 | # "t_monthly": t_monthly 67 | # }) 68 | 69 | def get_balance(self, user_id: int): 70 | coins = self.collection.find_one({"_id": user_id}, {"wallet": 1, "bank": 1}) 71 | try: 72 | return coins['wallet'], coins['bank'] 73 | except TypeError: 74 | self.insert_new_document(user_id) 75 | return 0, 0 76 | -------------------------------------------------------------------------------- /cogs/utils/db_utils.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | 3 | 4 | def create_dict(**kwargs): 5 | return kwargs 6 | 7 | 8 | class db_utils: 9 | def __init__(self, collection, **template): 10 | self.collection = collection 11 | self.template = template 12 | 13 | def initialize(self): 14 | return utils(self.collection) 15 | 16 | def initialize_template(self): 17 | return utils(self.collection, self.template) 18 | 19 | @classmethod 20 | def create_dict(cls, **kwargs): 21 | return kwargs 22 | 23 | 24 | class utils: 25 | def __init__(self, collection: pymongo.collection.Collection, template=None): 26 | if template is None: 27 | template = {} 28 | self.db_dict = {} 29 | self.collection = collection 30 | self.template = template 31 | 32 | def initialize_dict(self): 33 | """Initialize/reset dictionary for the object""" 34 | self.db_dict = {} 35 | return self 36 | 37 | def add(self, **kwargs): 38 | """Add to dictionary""" 39 | self.db_dict.update(kwargs) 40 | return self 41 | 42 | def add_operators(self, **kwargs): 43 | """Add operators to dictionary (start with a $)""" 44 | self.db_dict.update({f"${key}": kwargs[key] for key in kwargs}) 45 | return self 46 | 47 | def insert_one(self): 48 | """Insert dictionary into database""" 49 | self.collection.insert_one(self.db_dict) 50 | 51 | def update_one(self, update_filter, upsert: bool = False): 52 | """Update database with given filter and if upsert is needed""" 53 | self.collection.update_one(update_filter, self.db_dict, upsert=upsert) 54 | 55 | def upsert_from_template(self, update_filter, **template_extras): 56 | self.add_operators(setOnInsert={key: self.template[key] for key in self.template if key not in template_extras}) 57 | self.collection.update_one(update_filter, self.db_dict, upsert=True) 58 | 59 | def insert_from_template(self, **kwargs): 60 | self.add(**kwargs, **self.template) 61 | self.insert_one() 62 | 63 | -------------------------------------------------------------------------------- /dummy.env: -------------------------------------------------------------------------------- 1 | TOKEN = YOUR_BOT_TOKEN 2 | CLIENT_ID = REDDIT_API_CLIENT_ID 3 | SECRET = REDDIT_API_CLIENT_SECRET 4 | TOTAL_GUILDS_API_URI = https://jsonblob.com/api/jsonBlob/YOUR_JSON_BLOB_ID 5 | MONGODB_URL = YOUR_MONGODB_URL 6 | PREFIX = $ -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import discord 3 | from discord.ext import commands, tasks 4 | from dotenv import load_dotenv 5 | 6 | from main_resources.events import Events 7 | from main_resources.functions import * 8 | from main_resources.loops import Loops 9 | 10 | # --------------------------------Variables--------------------------------# 11 | 12 | load_dotenv() # Load env to initialize all dataset 13 | 14 | # The url for updating server count. 15 | total_guilds_api_url = os.getenv('TOTAL_GUILDS_API_URI') 16 | database = create_database_connection(os.getenv('MONGODB_URL')) 17 | guilds_data = database['guilds_data'] 18 | guild_prefix_storage = create_guild_store(guilds_data) 19 | disabled_commands_store = create_disabled_commands_store(guilds_data) 20 | # ---------------------------------Prefix----------------------------------# 21 | 22 | DEFAULT_PREFIX = os.getenv('PREFIX') 23 | 24 | 25 | # Get prefix per server 26 | def get_prefix(bot, message: discord.Message): 27 | guild_id = message.guild.id 28 | if guild_id in guild_prefix_storage: 29 | return guild_prefix_storage[guild_id] 30 | else: 31 | add_guild(guilds_data, guild_id, DEFAULT_PREFIX) 32 | return DEFAULT_PREFIX 33 | 34 | 35 | # -----------------------------------Bot-----------------------------------# 36 | 37 | bot = commands.Bot(command_prefix=get_prefix, help_command=None, case_insensitive=True) 38 | custom_statuses = [f'{DEFAULT_PREFIX}help', 'WhiteHatJr SEO', ' with wolf gupta', 'ChintuAI'] 39 | check_class = before_invoke(disabled_commands_store) 40 | bot.before_invoke(check_class.check_before_invoke) 41 | 42 | 43 | # --------------------------------Main startup event--------------------------------# 44 | @bot.event 45 | async def on_ready(): 46 | change_status.start() 47 | clear_game.start() 48 | print("Updating databases...") 49 | update_guilds_data(bot, guilds_data, DEFAULT_PREFIX) 50 | print(f'Logged in as {bot.user.name}#{bot.user.discriminator} ID = {bot.user.id}') 51 | 52 | # --------------------------------Task loops--------------------------------# 53 | 54 | loops = Loops(bot, custom_statuses, database) 55 | change_status = tasks.loop(seconds=60)(loops.change_status) 56 | clear_game = tasks.loop(seconds=10)(loops.clear_game) 57 | 58 | # --------------------------------Events--------------------------------# 59 | events = Events(bot, database, total_guilds_api_url, guild_prefix_storage, disabled_commands_store, DEFAULT_PREFIX, 60 | ["help", "kick", "ban", "warn", "warninfo", "warns", "mute", "unmute", "clear"], 61 | ChintuAI=True) 62 | 63 | bot.event(events.on_command_error) 64 | bot.event(events.on_message) 65 | bot.event(events.on_guild_join) 66 | bot.event(events.on_command_completion) 67 | bot.event(events.on_update_prefix) 68 | bot.event(events.on_add_command) 69 | bot.event(events.on_remove_command) 70 | bot.event(events.on_reaction_add) 71 | bot.event(events.on_user_data_update) 72 | bot.event(events.on_guild_data_update) 73 | 74 | 75 | # --------------------------------Load Extensions/cogs--------------------------------# 76 | def load_extensions(fun_bot, unloaded_cogs: list): 77 | """Loads all extensions (Cogs) from the cogs directory""" 78 | if unloaded_cogs is None: 79 | unloaded_cogs = [] 80 | for filename in os.listdir('./cogs'): 81 | if filename.endswith(".py"): 82 | if filename not in unloaded_cogs: 83 | fun_bot.load_extension(f'cogs.{filename[:-3]}') 84 | 85 | 86 | if __name__ == '__main__': 87 | print("Loading extensions...") 88 | load_extensions(bot, ["Utilities.py", "Help.py"]) 89 | bot.load_extension("cogs.Utilities") 90 | bot.load_extension("cogs.Help") 91 | print("Logging in...") 92 | bot.run(os.getenv("TOKEN")) 93 | -------------------------------------------------------------------------------- /main_resources/Assets/currency_values.json: -------------------------------------------------------------------------------- 1 | { 2 | "daily": 2000, 3 | "weekly": 10000, 4 | "monthly": 50000, 5 | "per_command_set": 100, 6 | "command_set": 5, 7 | "quiz": 100 8 | } 9 | -------------------------------------------------------------------------------- /main_resources/Assets/fonts.json: -------------------------------------------------------------------------------- 1 | { 2 | "normal": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890", 3 | "upsidedown": "∀ᙠƆᗡƎℲ⅁HIſ⋊˥WNOԀΌᴚS⊥∩ΛMX⅄Zɐqɔpǝɟɓɥıɾʞlɯuodbɹsʇnʌʍxʎz⇂ᄅƐㄣގ9ㄥ860", 4 | "subscript": "ₐBCDₑFGₕᵢⱼₖₗₘₙₒₚQᵣₛₜᵤᵥWₓYZₐbcdₑfgₕᵢⱼₖₗₘₙₒₚqᵣₛₜᵤᵥwₓyz₁₂₃₄₅₆₇₈₉₀", 5 | "block": "🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉1234567890", 6 | "cursive": "𝒜𝐵𝒞𝒟𝐸𝐹𝒢𝐻𝐼𝒥𝒦𝐿𝑀𝒩❁𝒫𝒬𝑅𝒮𝒯𝒰𝒱𝒲𝒳𝒴𝒵𝒶𝒷𝒸𝒹𝑒𝒻𝑔𝒽𝒾𝒿𝓀𝓁𝓂𝓃❁𝓅𝓆𝓇𝓈𝓉𝓊𝓋𝓌𝓍𝓎𝓏𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟫", 7 | "boldcursive": "𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃1234567890", 8 | "outline": "𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡𝟘", 9 | "small": "ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘQʀꜱᴛᴜᴠᴡxʏᴢᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘQʀꜱᴛᴜᴠᴡxʏᴢ1234567890", 10 | "scripted": "𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷1234567890", 11 | "boxed": "🄰🄱🄲🄳🄴🄵🄶🄷🄸🄹🄺🄻🄼🄽🄾🄿🅀🅁🅂🅃🅄🅅🅆🅇🅈🅉🄰🄱🄲🄳🄴🄵🄶🄷🄸🄹🄺🄻🄼🄽🄾🄿🅀🅁🅂🅃🅄🅅🅆🅇🅈🅉1234567890", 12 | "cursed": "AᙠƆᗡƎꟻᎮHIႱ⋊⅃MͶOꟼỌЯꙄTUVWXYƸɒdɔbɘᎸǫʜiꞁʞ|mᴎoqpɿꙅƚuvwxʏƹ890", 13 | "enchanted": "Ầ̵̛̬̪͚͊̆B̶̨̹̮̭̗͈͆̾͑͐ͅC̷̝̲̝̩̰̦͓̮̼͆̆̈́̒͆̍̕͜͠͝Ḏ̷̳͕̫̪̜̐̋͘E̴̬͛F̵͕̄̈̇ͅǦ̴͖̜͚̰͂̕H̸̗̦̏̈́I̴͖̥̣̹̫͖̖͎̔̀̐̏͝Ĵ̵̨̤̳͔͓̇̀̈̀͌͠K̶͖̘̺͈͖̽̊̽̀͝L̵̮̗̯͈͇̼̋̔͆̔̾͆̈͝͝M̶̘̰͉̹͉̮̖͚͛̐̓͆͘͘N̸̦̫͌̾Ô̵̡̳̬̹̣͔͉̳̼̇P̴̡̠͉͔̼͎̣͔̞̀̆͜Q̷̨̙͚̬͔͛̇͐R̶̬̬̩̣̰̰͔̲̉́̍͝͝S̸̡̡̠̞̝̙̆̈́̒̿͂͐͘̚̚͠ͅT̵̡̻͎̑͌͝ͅƯ̴̞͛͂̉̔͆̍̚V̵͕͍̑͑̀̂̀̐̕W̴̲̉̌͊X̸̢̢̤̮͖̰͕͈̻̉̂̕Y̵̨̛̳̭͉̲͍̪̞̻̔͌̑͂̎́͜͝Z̶͛̃ͅḁ̷̛͉̙̞͍̥̪̓b̷̢̛͚̯̜̗̩͈̋͒̄̊̿̊́̄͝č̴͈̼̗̼̩͙̳̫̝́d̷̙̣̙̯̤̱̘͒̒̓̍̈́̾̔̓e̵̡̛̼͉͓̳̥̰̺̚f̶̛̗̙͍̖̆̊͑͑͊̅g̵̢̡͚͓̝̬̙̈́̈́͂͌͌̚̚ḧ̶̛̟͍̼̘́̃̈́̐͑į̷̞̦͓̣͇̘̅̿͂̈́j̴̧͖̖̰͎͎̫̱͛̒͌̕k̶͖̼̼̳̒̏͊̎̀̒̇l̵͔̖͊̕ḿ̵͙̥̿͊͌͊͘ņ̸̻̞̺͊̔̀͝o̵̢̬̥̤̯͓̅̅́p̷̧̡̻̫̩̯͂̅̊̔͌͝q̸̡̢̧͖͕̞̜͇̣͗͂ͅȑ̷̫͙͎̥͇̝̈́̍̑̕s̸̳͚͌̎̿͆̅͊̏̌t̵̢̛̰̳͉̯̼̖̂̅͑͒͒͝û̵̬̝̟͖̬̍͒̃͋̓̕̚v̸̟͉̮͆́̾̿̑͗͜w̵̜̅́́̂͂͐̉̅̓̈x̸̫̹̩̩̹͓͍͓͂͑͗́̃̀̿̀̓̚y̶̨̮͔̭̯̙̥̘͌̓͊̄̐̅͘z̴̼̣̰̤̣͚̅̇̄̍1̸̹̦͖̭̗͔͑̀̌̀2̶̗͚͋3̶̫̭͑́̍̔͒4̵͉͕̂͐́̈́̔̇5̷͔̙̻̼̺͙̇͗͜6̷̧̡̫͈̻̠̅̇7̵̡̢̼͇͔͉͔͔̫̲̋̀͂̇̾͂͊8̴̞̩͐̅̎̿́̈́͋̍̆̈́9̷̨͑̓̄̽̈̿0̶̟͂́ͅ", 14 | "royal": "𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟1234567890", 15 | "iconized": "ⓐ乃Ćᗪᵉғģʰίᒎķᒪм𝓃ỖᵖᵠŘ𝕤ᵗU𝓿𝔴ⓧⓎ𝓏𝕒в𝐂∂€ⓕǤ𝐡𝐈𝕛𝓚ℓмⓃØ𝔭ɊŘş𝕥UⓋ𝐰𝕩Yz❶➁❸❹➄➅➆➇❾0", 16 | "circle": "ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ①②③④⑤⑥⑦⑧⑨⓪", 17 | "joker": "ค๒ς๔єŦﻮђเןкɭ๓ภ๏קợгรՇยשฬאץչค๒ς๔єŦﻮђเןкɭ๓ภ๏קợгรՇยשฬאץչ1234567890", 18 | "hongkong": "丹日亡句ヨ乍呂廾工勹片し冊几回尸甲尺己卞凵レ山メと乙丹日亡句ヨ乍呂廾工勹片し冊几回尸甲尺己卞凵レ山メと乙1234567890", 19 | "tokyo": "卂乃匚ᗪ乇千Ꮆ卄丨フҜㄥ爪几ㄖ卩Ɋ尺丂ㄒㄩᐯ山乂ㄚ乙卂乃匚ᗪ乇千Ꮆ卄丨フҜㄥ爪几ㄖ卩Ɋ尺丂ㄒㄩᐯ山乂ㄚ乙1234567890", 20 | "scramble": "douɯlʞɾıɥɓɟǝpɔqɐ068ㄥ9ގㄣƐᄅ⇂Ԁqɔㄣ˥⋊ſɥı⅁ℲƎᗡƆᙠ∀bʎsʍʌnʇsɹb⇂⅄ƐpΛ∩⊥8ᴚΌ", 21 | "striked": "₳฿₵ĐɆ₣₲ⱧłJ₭Ⱡ₥₦Ø₱QⱤ₴₮ɄV₩ӾɎⱫ₳฿₵ĐɆ₣₲ⱧłJ₭Ⱡ₥₦Ø₱QⱤ₴₮ɄV₩ӾɎⱫ1234567890", 22 | "fancy": "ᗩᗷᑕᗪEᖴGᕼIᒍKᒪᗰᑎOᑭᑫᖇᔕTᑌᐯᗯ᙭YᘔᗩᗷᑕᗪEᖴGᕼIᒍKᒪᗰᑎOᑭᑫᖇᔕTᑌᐯᗯ᙭Yᘔ1234567890", 23 | "padded": "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890", 24 | "insect": "ꁲꋰꀯꂠꈼꄞꁅꍩꂑ꒻ꀗ꒒ꂵꋊꂦꉣꁷꌅꌚꋖꐇꀰꅏꇒꐞꁴꁲꋰꀯꂠꈼꄞꁅꍩꂑ꒻ꀗ꒒ꂵꋊꂦꉣꁷꌅꌚꋖꐇꀰꅏꇒꐞꁴ1234567890", 25 | "mixed": "𝔸𝓑Č𝓓乇𝔽Ꮆн𝓲ⒿЌ𝓛M𝓃ⓞ卩Ⓠŕˢţⓤ𝕍ᗯ𝓍ʸ𝓏ⓐ𝒷ČDᵉᖴĞ卄𝓲𝓙𝐤ℓ𝕄𝔫𝕠ρⓠŘŞ丅υѶωˣⓎ𝕫❶➁➂➃❺➅78❾Ѳ" 26 | 27 | } -------------------------------------------------------------------------------- /main_resources/Assets/kill.json: -------------------------------------------------------------------------------- 1 | { 2 | "kills": [ 3 | "died from a creeper explosion", 4 | "died from lack of quality memes on Dank Memer", 5 | "disappeared from the universe.", 6 | "died from subscribing to t-series", 7 | "died from not subscribing to Pewdiepie", 8 | "ripped their own heart out to show their love for jhonny sins", 9 | "dies because they were just too angry😡 ", 10 | "chokes on cheerios and dies. What an idiot...", 11 | "died from patta se head shot 🔫", 12 | "was killed for being too noob.. what a noob", 13 | "died after fapping 50 times in a row with no break.", 14 | "because they were just too Lazy.", 15 | "was killed by imposter", 16 | "died from lack of ***, U got that 😁", 17 | "drowned in their own tears 😭.", 18 | "was eaten by the duolingo owl🦉 ", 19 | "dies, but don't let this distract you from the fact that in 1998, The Undertaker threw", 20 | "died from a nightmare👻 dream", 21 | "died while playing hopscotch on seemingly deactivated land mines.", 22 | "loses the will to live🤥", 23 | "died from whacking it too much. (There's a healthy balance, boys)", 24 | "eats too much copypasta and explodes", 25 | "reads memes till they die.", 26 | "dies of starvation.", 27 | "died somehow 🤷‍♂️", 28 | "died by taking sefi🤳 with lion🦁 ..such a idiot ", 29 | "died in 2020 for not wearing mask😷", 30 | "died from subscribing to t-series", 31 | "is dead. How 🤷🏼‍♂️", 32 | "died of scurvy, eat oranges kids", 33 | "cranks up the music system only to realize the volume was at max and the song playing was Baby by Justin Beiber..", 34 | "cranks up the music system only to realize the volume was at max and the song playing was selfie Maine le liya..", 35 | "died from watching to much of P**n 🤦‍♂️", 36 | "died from COVID-69, new virus transmitted from ga* s** 🚫🧑‍🤝‍🧑" 37 | ] 38 | } -------------------------------------------------------------------------------- /main_resources/Assets/roast.json: -------------------------------------------------------------------------------- 1 | { 2 | "roasts": [ 3 | "The best comeback is not through violence, it is to outsmart your opponent by insulting them intelligently with none swearing replies, also known as a punchline. Punching or physically assaulting someone is a crime, you will end up in prison with a bad record, however, insulting without using any curse word is not a crime. Without further ado, here are 55 insulting quotes for fake friends, ex bf, ex gf, enemies and haters, share it on your Facebook or Tweeter as an indirect message.", 4 | " I'm sorry I hurt your feelings when I called you stupid. I really thought you already knew.", 5 | " I'm not insulting you. I'm describing you.", 6 | " It's ok if you disagree with me. I can't force you to be right.", 7 | " I'm actually not funny. I'm just mean and people think I'm joking.", 8 | " If you don't want a sarcastic answer, don't ask a stupid question.", 9 | " I'm busy right now, can I ignore you some other time?", 10 | " I was wondering how you comb your hair so the horns don't show.", 11 | " I love rumors. I always find out amazing things about myself I never knew.", 12 | " Light travels faster than sound. This is why some people appear bright until they speak.", 13 | " Some people just need a high five. In the face. With a chair.", 14 | " If you don't like me, take a map, get a car, drive to hell. Have a nice trip.", 15 | " Oh, my bad. I'm sorry for bothering you. I forgot I only exist when you need me for something.", 16 | " If I wanted to kill myself I would climb your ego and jump to your IQ.", 17 | " I'm sorry I offended you with my common sense.", 18 | " Ignore me, I don't care I'm used to it anyways, I'm invisible.", 19 | " I love that super cute thing you do where you don't text me back for hours, adorable.", 20 | " I'm sorry if you don't like my honesty, but to be fair, I don't like your lies.", 21 | " I'm sorry you were offended when I called you a hoe. I didn't know it was a secret.", 22 | " If lying was a job, I know some people who would be billionaires.", 23 | " I may be drunk, miss, but in the morning I will be sober and you will still be ugly.", 24 | " Oh I didn't realize you're an expert in my life and how I should live it. Please continue while I take notes.", 25 | " I am just so talented. I can listen to music and ignore you at the same time.", 26 | " Excuse me miss, you've got a bit of face on your make up.", 27 | " Are you always this stupid, or are you making a special effort today?", 28 | " Is your ass jealous of all the shit that comes out of your mouth?", 29 | " The last thing I want to do is hurt you' But it's still on the list.", 30 | " You must have been born on a highway because that's where most accidents happen.", 31 | " If common sense is common why are you without it?", 32 | " Zombies eat brains, don't worry, you're safe.", 33 | " Keep rolling your eyes, maybe you'll find a brain back there.", 34 | " You sound better with your mouth closed.", 35 | " I'd slap you but that would be animal abuse.", 36 | " Without stupid people like you, we would have no one to laugh at. Thank you for your contribution to society.", 37 | " Bitch, I'd kick you in the V, but I'm afraid I'd lose my shoe.", 38 | " I'm not saying I hate you, but I'd unplug your life support to charge my phone.", 39 | " Your birth certificate is an apology letter from durex.", 40 | " I would love to insult you, but I'm afraid I won't do as well as your own genetics.", 41 | " Somewhere out there is a tree working hard to replace the oxygen you wasted, now go apologize to it.", 42 | " You are like the first piece of bread, everybody touches you but no one wants you.", 43 | " You should eat some make up, at least you'll be pretty on the inside.", 44 | " When your parents dropped you off at pre school, they were arrested for littering.", 45 | " I'd like to see things from your point of view but I can't seem to get my head that far up my ass.", 46 | " If I had a gun with two bullets and I was in a room with Hitler, Bin Laden, and you, I would shoot you twice.", 47 | " You have a face only a mother could love. I bet she tells you you're special too.", 48 | " Your mom should've swallowed.", 49 | " Stupidity is not a crime, if it is, you'll end up in jail.", 50 | " I can remove 90% of your beauty with a wet tissue.", 51 | " Learn from your parents' mistakes, use birth control.", 52 | " You look like something I'd draw with my left hand.", 53 | " You're so ugly, when you were born your mom said 'What a treasure' and your dad said 'Lets go bury it!'", 54 | " Your life is useless, just like your dad's condom.", 55 | " Why don't you slip into something more comfortable, like a coma.", 56 | " The best part about me, is I'm not you.", 57 | " I don't hate you but I'm just not necessarily excited about your existence.", 58 | " Don't blame a clown for acting like a clown, blame yourself for going to the circus.", 59 | " Oh, I'm sorry. I forgot I only exist when you need something.", 60 | " Listen, I'm a nice person. So if I'm an asshole to you, you need to ask yourself why.", 61 | " Don't take yourself so seriously, no one else does.", 62 | " I would like to confirm that I do not care.", 63 | " I would like to apologize to anyone I have not yet offended. Please be patient. I will get to you shortly.", 64 | " I'm sorry that my forced apology sounded insincere, I'll try to make it more convincing next time.", 65 | " I'm sorry for what I said when I wanted you to disappear.", 66 | " I'm sorry for whatever I did to make you think I give a shit about your feelings." 67 | ] 68 | } -------------------------------------------------------------------------------- /main_resources/Assets/shop_items.json: -------------------------------------------------------------------------------- 1 | { 2 | "by_id": { 3 | "100": { 4 | "name": "Joe Mama", 5 | "value": 10000, 6 | "resell": 2000, 7 | "emoji": "", 8 | "description": "Take Joe Mama from me if you can :sunglasses: [usable]", 9 | "type": "mom", 10 | "properties": true, 11 | "archive": false 12 | }, 13 | "101": { 14 | "name": "Autograph Notebook", 15 | "value": 20000, 16 | "resell": 0, 17 | "emoji": "\uD83D\uDCDD", 18 | "description": "Collect as many autographs as you can and ask legends to leave their mark on your notebook", 19 | "type": "notebook", 20 | "properties": false, 21 | "archive": true 22 | }, 23 | "102": { 24 | "name": "Rick Roll Disc [Limited]", 25 | "value": 50000, 26 | "resell": 1000, 27 | "emoji": "<:rick_disc:839577178400489565>", 28 | "description": "Rick roll your friends with this music disc :sunglasses: [usable]", 29 | "type": "disc", 30 | "url": "https://www.youtube.com/watch?v=w5_fiYGOeLY", 31 | "properties": false, 32 | "archive": false 33 | }, 34 | "103": { 35 | "name": "QUACK QUACK disc [Limited]", 36 | "value": 50000, 37 | "resell": 1000, 38 | "emoji": "<:rick_disc:839577178400489565>", 39 | "description": "Quack Quack Quack Quack :duck: :duck: :duck: [usable]", 40 | "type": "disc", 41 | "url": "https://www.youtube.com/watch?v=dDgGMInTqTo", 42 | "properties": false, 43 | "archive": false 44 | }, 45 | "104": { 46 | "name": "Dirt Ring", 47 | "value": 20000, 48 | "resell": 500, 49 | "emoji": ":ring:", 50 | "description": "Marry the love of your life with this cheap ring (Not Recommended) [usable]", 51 | "type": "ring", 52 | "properties": true, 53 | "archive": false, 54 | "id": 104 55 | }, 56 | "105": { 57 | "name": "Mutahar Laugh [Limited]", 58 | "value": 50000, 59 | "resell": 1000, 60 | "emoji": "<:rick_disc:839577178400489565>", 61 | "description": "Listen to mutahar from SOG laughing in multiple variations [usable]", 62 | "type": "disc", 63 | "url": "https://www.youtube.com/watch?v=6_Ti78RgzlY", 64 | "properties": false, 65 | "archive": false 66 | }, 67 | "106": { 68 | "name": "Divorce Papers", 69 | "value": 20000, 70 | "resell": 1000, 71 | "emoji": ":newspaper:", 72 | "description": "Divorce someone you are married to and become a loner again! [Under development]", 73 | "type": "item", 74 | "properties": false, 75 | "archive": false 76 | } 77 | }, 78 | "by_name": { 79 | "joe": 100, 80 | "mama": 100, 81 | "joemama": 100, 82 | 83 | "autograph": 101, 84 | "notebook": 101, 85 | "anb": 101, 86 | 87 | "rickroll": 102, 88 | "rick": 102, 89 | "roll": 102, 90 | 91 | "quack": 103, 92 | 93 | "ring": 104, 94 | "dirt": 104, 95 | "dirtring": 104, 96 | 97 | "muta": 105, 98 | "mutahar": 105, 99 | "laugh": 105 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /main_resources/ChintuAI.py: -------------------------------------------------------------------------------- 1 | import json 2 | import random 3 | 4 | import numpy as np 5 | import pickle 6 | import nltk 7 | import requests 8 | from nltk.stem import WordNetLemmatizer 9 | 10 | nltk.download('punkt') 11 | nltk.download('wordnet') 12 | lemmatizer = WordNetLemmatizer() 13 | 14 | # --------------------------------Importing ChatModels--------------------------------# 15 | intents = json.loads(open('./Chintu-Chat-Model/intents.json', 16 | encoding='utf-8', errors='ignore').read()) 17 | words = pickle.load(open('./Chintu-Chat-Model/words.pkl', 'rb')) 18 | classes = pickle.load(open('./Chintu-Chat-Model/classes.pkl', 'rb')) 19 | messages = ["Stop pinging me, I can\'t understand you", "I'm a human and still I can't understand what you're talking about", 20 | "I'll block you if you keep pinging me", 'Bruh, can you stop already?', 21 | 'Yes, I acknowledge you are here, now stop disturbing me', 'Okay', 'Stop, you attention-whore', 22 | 'Only if you had a life', '**Dies*'] 23 | data = {} 24 | for intent in intents['intents']: 25 | data[intent['tag']] = intent['responses'] 26 | 27 | url = 'https://chintu-ai.herokuapp.com/v1/models/chintuchat:predict' 28 | 29 | 30 | def clean_up_sentence(sentence): 31 | sentence_words = nltk.word_tokenize(sentence) 32 | sentence_words = [lemmatizer.lemmatize( 33 | word.lower()) for word in sentence_words] 34 | return sentence_words 35 | 36 | 37 | def bow(sentence, words, show_details=True): 38 | # tokenize the pattern 39 | sentence_words = clean_up_sentence(sentence) 40 | # bag of words - matrix of N words, vocabulary matrix 41 | bag = [0] * len(words) 42 | for s in sentence_words: 43 | for i, w in enumerate(words): 44 | if w == s: 45 | # assign 1 if current word is in the vocabulary position 46 | bag[i] = 1 47 | if show_details: 48 | print("found in bag: %s" % w) 49 | return np.array(bag) 50 | 51 | 52 | def make_arr(sentence): 53 | p = bow(sentence, words, show_details=False) 54 | return np.array([p]) 55 | 56 | 57 | def create_return_list(res): 58 | ERROR_THRESHOLD = 0.9 59 | results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD] 60 | results.sort(key=lambda x: x[1], reverse=True) 61 | return_list = [] 62 | try: 63 | if results[0]: 64 | for r in results: 65 | return_list.append( 66 | {"intent": classes[r[0]], "probability": str(r[1])}) 67 | else: 68 | return_list.append({"intent": 'noanswer', "probability": '1'}) 69 | except: 70 | return_list.append({"intent": 'noanswer', "probability": '1'}) 71 | # print(return_list) 72 | return return_list 73 | 74 | 75 | def docker_ask(sentence): 76 | instances = make_arr(sentence) 77 | data = json.dumps({"signature_name": "serving_default", "instances": instances.tolist()}) 78 | headers = {"content-type": "application/json"} 79 | json_response = requests.post(url, data=data, headers=headers) 80 | predictions = json.loads(json_response.text)['predictions'][0] 81 | return_list = create_return_list(predictions) 82 | return return_list 83 | 84 | 85 | def getResponse(ints): 86 | result = random.choice(messages) 87 | tag = ints[0]['intent'] 88 | if tag in data: 89 | result = random.choice(data[tag]) 90 | return result, tag 91 | 92 | 93 | def prediction(msg): 94 | ints = docker_ask(msg) 95 | res, tag = getResponse(ints) 96 | if float(ints[0]['probability']) > 0.97: 97 | result = {"response": res, 98 | "tag": tag 99 | } 100 | else: 101 | result = {"response": "Dont talk bullsh*t, I cant understand", 102 | "tag": "couldnotunderstand" 103 | } 104 | return result 105 | 106 | 107 | # --------------------------------get response--------------------------------# 108 | def AskChintu(query): 109 | try: 110 | if query is None or query.strip() == "": 111 | return {'response': random.choice( 112 | ['what?', "Hey ssup! 🙋‍♂️", "what⁉️", "what you want?", "why did you ping me sir?"]), 'tag': "nonemsg"} 113 | 114 | Bot_Response = prediction(query) 115 | 116 | except Exception as e: 117 | Bot_Response = { 118 | 'response': 'I have headache I cant understand', 'tag': "error"} 119 | # print(e) 120 | 121 | return Bot_Response 122 | -------------------------------------------------------------------------------- /main_resources/Images/coffindance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/coffindance.jpg -------------------------------------------------------------------------------- /main_resources/Images/fart.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/fart.jpg -------------------------------------------------------------------------------- /main_resources/Images/gay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/gay.jpg -------------------------------------------------------------------------------- /main_resources/Images/pee.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/pee.jpg -------------------------------------------------------------------------------- /main_resources/Images/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/profile.jpg -------------------------------------------------------------------------------- /main_resources/Images/send.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/send.jpg -------------------------------------------------------------------------------- /main_resources/Images/slap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/slap.jpg -------------------------------------------------------------------------------- /main_resources/Images/smash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/smash.jpg -------------------------------------------------------------------------------- /main_resources/Images/stop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/stop.jpg -------------------------------------------------------------------------------- /main_resources/Images/wantted.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/wantted.jpg -------------------------------------------------------------------------------- /main_resources/Images/worthless.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/Images/worthless.jpg -------------------------------------------------------------------------------- /main_resources/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Noob-Coders-Gang/Chintu-Bot/730f88768f02218f6c82a76e042d98a607214b3a/main_resources/__init__.py -------------------------------------------------------------------------------- /main_resources/events.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import re 3 | 4 | from discord.ext import commands 5 | 6 | from cogs.utils.db_utils import db_utils, create_dict 7 | from cogs.utils import GameGrid 8 | from main_resources.ChintuAI import AskChintu 9 | from main_resources.functions import * 10 | 11 | 12 | def update_user_data(database): 13 | user_data = {} 14 | for document in database["user_data"].find({}): 15 | user_data[document["_id"]] = {key: document[key] for key in document if key != "_id"} 16 | return user_data 17 | 18 | 19 | def update_guilds_data(database): 20 | guilds_data = {} 21 | for document in database["guilds_data"].find({}): 22 | guilds_data[document["_id"]] = {key: document[key] for key in document if key != "_id"} 23 | return guilds_data 24 | 25 | 26 | def update_single_user_data(database, user_data, user_id): 27 | document = database["user_data"].find_one({"_id": user_id}) 28 | if document: 29 | user_data[user_id] = {key: document[key] for key in document if key != "_id"} 30 | 31 | 32 | def update_single_guild_data(database, guild_data, guild_id): 33 | document = database["guilds_data"].find_one({"_id": guild_id}) 34 | if document: 35 | guild_data[guild_id] = {key: document[key] for key in document if key != "_id"} 36 | 37 | 38 | class Events: 39 | def __init__(self, bot: commands.Bot, database, total_guilds_api_url, guild_prefix_store, disabled_commands, 40 | default_prefix, infinite_use_commands: list, 41 | ChintuAI: bool = False): 42 | self.emojis = None 43 | self.bot = bot 44 | self.database = database 45 | self.infinite_use_commands = infinite_use_commands 46 | self.total_guilds_api_url = total_guilds_api_url 47 | self.db_utils = db_utils(database["currency"], 48 | wallet=0, 49 | bank=0, 50 | bank_limit=0, 51 | commands=0, 52 | inventory=None, 53 | t_daily=0, 54 | t_weekly=0, 55 | t_monthly=0) 56 | self.ChintuAI = ChintuAI 57 | self.guild_prefix_store = guild_prefix_store 58 | self.default_prefix = default_prefix 59 | self.disabled_commands = disabled_commands 60 | self.user_data = update_user_data(database) 61 | self.guilds_data = update_guilds_data(database) 62 | 63 | if ChintuAI: 64 | from main_resources.ChintuAI import AskChintu 65 | 66 | async def on_guild_join(self, guild: discord.Guild): 67 | guilds = self.bot.guilds 68 | update_total_guilds(guilds, self.total_guilds_api_url) 69 | add_guild(self.guilds_data, guild.id, self.default_prefix) 70 | update_guild_storage(self.guild_prefix_store, guild.id, self.default_prefix) 71 | 72 | async def on_user_data_update(self, user_id: int): 73 | update_single_user_data(self.database, self.user_data, user_id) 74 | 75 | async def on_guild_data_update(self, guild_id: int): 76 | update_single_guild_data(self.database, self.guilds_data, guild_id) 77 | 78 | def get_emoji(self, match): 79 | try: 80 | return self.emojis[str(match.group()).replace(":", "")] 81 | except KeyError: 82 | return str(match.group()) 83 | 84 | async def on_message(self, message: discord.Message): 85 | ctx: commands.Context = await self.bot.get_context(message) 86 | if ctx.command is None: 87 | if message.content.startswith("$help"): 88 | message.content = message.content.lower() 89 | await ctx.invoke(self.bot.get_command("invoked_help")) 90 | elif self.ChintuAI: 91 | message.content = message.content.lower() 92 | if message.author == self.bot or message.content.startswith(self.default_prefix): 93 | return 94 | mention = f'<@!{self.bot.user.id}>' 95 | if self.bot.user.mentioned_in(message): 96 | user_message = message.content.replace(mention, "") 97 | await message.channel.send(AskChintu(user_message)['response']) 98 | 99 | if message.guild.id in self.guilds_data and \ 100 | "nitro" in self.guilds_data[message.guild.id] and \ 101 | self.guilds_data[message.guild.id]["nitro"] and \ 102 | message.author.id in self.user_data and \ 103 | "nitro" in self.user_data[message.author.id] and \ 104 | self.user_data[message.author.id]["nitro"]: 105 | if self.emojis is None: 106 | self.emojis = {e.name.lower(): str(e) for e in self.bot.emojis} 107 | sent = False 108 | webhooks = await message.channel.webhooks() 109 | message_text = re.sub(r':[^:]+:', self.get_emoji, message.content, count=0) 110 | if message_text != message.content: 111 | if len(webhooks) > 0: 112 | for webhook in webhooks: 113 | try: 114 | await webhook.send(message_text, username=ctx.author.name, 115 | avatar_url=ctx.author.avatar_url) 116 | await message.delete() 117 | sent = True 118 | break 119 | except discord.errors.InvalidArgument: 120 | continue 121 | if not sent: 122 | webhook = await ctx.channel.create_webhook(name=self.bot.user.name) 123 | await webhook.send(message_text, username=ctx.author.name, avatar_url=ctx.author.avatar_url) 124 | await message.delete() 125 | else: 126 | webhook = await ctx.channel.create_webhook(name=ctx.author.name) 127 | await webhook.send(message_text, username=ctx.author.name, avatar_url=ctx.author.avatar_url) 128 | await message.delete() 129 | else: 130 | await self.bot.invoke(ctx) 131 | 132 | async def on_command_error(self, ctx, error): 133 | if isinstance(error, commands.CommandOnCooldown): 134 | em = discord.Embed(title=f"Slow it down bro!", 135 | description=f"Try again in {error.retry_after:.2f}s.\n The default cooldown is {error.cooldown.per}s", 136 | color=discord.Color.red()) 137 | await ctx.send(embed=em) 138 | elif isinstance(error, commands.CheckFailure): 139 | embed = discord.Embed(title=':x: oops! You do not have permission to use this command.', 140 | color=discord.Colour.red()) 141 | await ctx.send(embed=embed) 142 | elif isinstance(error, commands.MissingRequiredArgument): 143 | embed = discord.Embed( 144 | title=':x: You are missing the required arguments. Please check if your command requires an addition arguement.', 145 | color=discord.Colour.red()) 146 | await ctx.send(embed=embed) 147 | elif isinstance(error, commands.MissingPermissions): 148 | embed = discord.Embed( 149 | title=':x: Chintu is missing the required permissions. Please check if Chintu has appropriate permissions.', 150 | color=discord.Colour.red()) 151 | await ctx.send(embed=embed) 152 | elif isinstance(error, commands.CommandNotFound): 153 | pass 154 | elif isinstance(error, commands.MemberNotFound): 155 | embed = discord.Embed( 156 | title=':x: Could not find the mentioned user. Please mention a valid user.', 157 | color=discord.Colour.red()) 158 | await ctx.send(embed=embed) 159 | elif isinstance(error, commands.BadArgument): 160 | embed = discord.Embed( 161 | title=':x: Enter a valid argument', 162 | color=discord.Colour.red()) 163 | await ctx.send(embed=embed) 164 | 165 | async def on_command_completion(self, ctx: commands.Context): 166 | if ctx.command.name not in self.infinite_use_commands: 167 | self.db_utils.initialize_template().add_operators( 168 | inc=create_dict(commands=1) 169 | ).upsert_from_template(create_dict(_id=ctx.author.id), commands=0) 170 | 171 | async def on_update_prefix(self, ctx, prefix): 172 | update_guild_storage(self.guild_prefix_store, ctx.guild.id, prefix) 173 | await ctx.guild.me.edit(nick=self.bot.user.name.replace(self.default_prefix, prefix)) 174 | 175 | async def on_add_command(self, ctx, command_name): 176 | try: 177 | remove_disabled_command(self.disabled_commands, ctx.guild.id, command_name) 178 | except ValueError: 179 | pass 180 | 181 | async def on_remove_command(self, ctx, command_name): 182 | try: 183 | add_disabled_command(self.disabled_commands, ctx.guild.id, command_name) 184 | except ValueError: 185 | pass 186 | 187 | async def on_reaction_add(self, reaction, user): 188 | if user.id == self.bot.user.id: 189 | return 190 | 191 | message = reaction.message 192 | 193 | if GameGrid.getGamesByUser(str(user.id)) is not None: 194 | game = GameGrid.getGamesByUser(str(user.id)) 195 | if str(game.getMessageId()) == str(message.id): 196 | if str(reaction.emoji) == '⬆': 197 | prev = game.getEmojiMessage() 198 | game.slideUp() 199 | elif str(reaction.emoji) == '⬇': 200 | prev = game.getEmojiMessage() 201 | game.slideDown() 202 | elif str(reaction.emoji) == '➡': 203 | prev = game.getEmojiMessage() 204 | game.slideRight() 205 | elif str(reaction.emoji) == '⬅': 206 | prev = game.getEmojiMessage() 207 | game.slideLeft() 208 | elif str(reaction.emoji) == '❌': 209 | msg = game.getEmojiMessage() 210 | point = game.getPoint() 211 | game.stop() 212 | await message.delete() 213 | embed = discord.Embed(title="2048 Game Over!", 214 | description=f"Points: {point}\n\n{msg}", 215 | color=discord.Color.orange()) 216 | embed.set_footer(text=f'Game session of {user.name}', icon_url=user.avatar_url) 217 | await message.channel.send(embed=embed) 218 | return 219 | 220 | await message.remove_reaction(reaction, user) 221 | 222 | if prev == game.getEmojiMessage(): 223 | return 224 | game.randomNumber() 225 | game.updatePoint(1) 226 | msg = game.getEmojiMessage() 227 | 228 | await message.edit(content=msg) 229 | 230 | if game.isGameWon(): 231 | await asyncio.sleep(5) 232 | msg = game.getEmojiMessage() 233 | point = game.getPoint() 234 | coins = int((point / 2) + 1000) 235 | game.stop() 236 | await message.delete() 237 | embed = discord.Embed(title="Congratulations!", 238 | description=f"You won the game!\n**Points:** {point}\n**Coins:** {coins}\n\n{msg}", 239 | color=discord.Color.green()) 240 | embed.set_footer(text=f'Game session of {user.name}', icon_url=user.avatar_url) 241 | self.db_utils.initialize_template().add_operators( 242 | inc=create_dict(wallet=coins) 243 | ).upsert_from_template(create_dict(_id=int(user.id)), wallet=0) 244 | await message.channel.send(embed=embed) 245 | return 246 | 247 | if game.isGameOver(): 248 | await asyncio.sleep(5) 249 | msg = game.getEmojiMessage() 250 | point = game.getPoint() 251 | coins = int(point / 2) 252 | game.stop() 253 | await message.delete() 254 | embed = discord.Embed(title="2048 Game Over!", 255 | description=f"**Points:** {point}\n**Coins:** {coins}\n\n{msg}", 256 | color=discord.Color.orange()) 257 | embed.set_footer(text=f'Game session of {user.name}', icon_url=user.avatar_url) 258 | self.db_utils.initialize_template().add_operators( 259 | inc=create_dict(wallet=coins) 260 | ).upsert_from_template(create_dict(_id=int(user.id)), wallet=0) 261 | await message.channel.send(embed=embed) 262 | return 263 | -------------------------------------------------------------------------------- /main_resources/functions.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import discord 4 | import pymongo 5 | import requests 6 | from discord.ext.commands import CommandError 7 | 8 | 9 | def update_total_guilds(guild_list, total_guilds_api_url): 10 | """Update the number of guilds in the total guilds API""" 11 | headers = {'Content-Type': 'application/json'} 12 | data = {"total_servers": len(guild_list)} 13 | requests.put(total_guilds_api_url, json=data, headers=headers) 14 | 15 | 16 | def load_extensions(bot, unloaded_cogs=None): 17 | """Loads all extensions (Cogs) from the cogs directory""" 18 | if unloaded_cogs is None: 19 | unloaded_cogs = [] 20 | for filename in os.listdir('./cogs'): 21 | if filename.endswith(".py"): 22 | if filename not in unloaded_cogs: 23 | bot.load_extension(f'cogs.{filename[:-3]}') 24 | 25 | 26 | # Database functions 27 | def create_database_connection(mongo_db_url: str): 28 | client = pymongo.MongoClient(mongo_db_url) # Connect to MongoDB using URI in .env file 29 | return client["Chintu-Bot"] # Return the Chintu-Bot database 30 | 31 | 32 | def update_guilds_data(bot, collection, default_prefix): 33 | guilds_to_add = [] 34 | current_guilds = list( 35 | collection.find({}, {"_id": 1})) # Get the list of already registered guilds 36 | for guild in bot.guilds: 37 | if {"_id": guild.id} not in current_guilds: 38 | guilds_to_add.append( 39 | {"_id": guild.id, "disabled_commands": [], 40 | "prefix": default_prefix}) # Add all the guilds that are not registered to a list 41 | if len(guilds_to_add) > 0: 42 | collection.insert_many(guilds_to_add) # update the collection with the list 43 | 44 | 45 | def add_guild(collection, guild_id: int, default_prefix): 46 | collection.update_one({"_id": guild_id}, { 47 | "$setOnInsert": { 48 | "disabled_commands": [], 49 | "prefix": default_prefix 50 | } 51 | }, upsert=True) 52 | 53 | 54 | def update_guild_storage(guild_store, guild_id, prefix): 55 | guild_store[guild_id] = prefix 56 | 57 | 58 | def add_disabled_command(disabled_commands_store, guild_id, disabled_command): 59 | disabled_commands_store[guild_id].append(disabled_command) 60 | 61 | 62 | def remove_disabled_command(disabled_commands_store: dict, guild_id, enabled_command): 63 | disabled_commands_store[guild_id].remove(enabled_command) 64 | 65 | 66 | def create_guild_store(collection): 67 | guild_store = {} 68 | for document in collection.find({}, {"_id": 1, "prefix": 1}): 69 | guild_store[document["_id"]] = document["prefix"] 70 | return guild_store 71 | 72 | 73 | def create_disabled_commands_store(collection): 74 | guild_store = {} 75 | for document in collection.find({}, {"_id": 1, "disabled_commands": 1}): 76 | guild_store[document["_id"]] = document["disabled_commands"] 77 | return guild_store 78 | 79 | 80 | def update_prefix(collection, server_id, prefix): 81 | collection.update_one({"_id": server_id}, { 82 | "$set": {"prefix": prefix}, 83 | "$setOnInsert": {"disabled_commands": []} 84 | }, upsert=True) 85 | 86 | 87 | def add_cmd_to_collection(collection, server_id, disabled_command, default_prefix): 88 | collection.update_one({"_id": server_id}, { 89 | "$addToSet": {"disabled_commands": disabled_command}, 90 | "$setOnInsert": {"prefix": default_prefix} 91 | }, upsert=True) 92 | 93 | 94 | def remove_cmd_from_collection(collection, server_id, disabled_command, default_prefix): 95 | collection.update_one({"_id": server_id}, { 96 | "$pull": {"disabled_commands": disabled_command}, 97 | "$setOnInsert": {"prefix": default_prefix} 98 | }, upsert=True) 99 | 100 | 101 | class before_invoke: 102 | def __init__(self, disabled_commands): 103 | self.disabled_commands = disabled_commands 104 | 105 | async def check_before_invoke(self, ctx): 106 | command_name = ctx.command.name 107 | if command_name != "add": 108 | try: 109 | if command_name in self.disabled_commands[ctx.guild.id]: 110 | embed = discord.Embed(title=f"This command is disabled in your server!", 111 | color=discord.Colour.red()) 112 | await ctx.send(embed=embed) 113 | raise CommandError 114 | except KeyError: 115 | self.disabled_commands[ctx.guild.id] = [] 116 | -------------------------------------------------------------------------------- /main_resources/item_use.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import random 3 | import traceback 4 | from datetime import datetime 5 | 6 | import discord 7 | import youtube_dl 8 | from discord.ext import commands 9 | from discord.ext.commands import CommandError 10 | 11 | from cogs.utils.currency_utils import currency_utils 12 | from main import database 13 | 14 | collection = database["currency"] 15 | utils = currency_utils(collection) 16 | 17 | properties = {} 18 | for doc in collection.find({}, {"properties": 1, "_id": 1}): 19 | if "properties" in doc: 20 | properties[doc["_id"]] = doc["properties"] 21 | 22 | 23 | def update_properties(): 24 | properties.clear() 25 | for document in collection.find({}, {"properties": 1, "_id": 1}): 26 | if "properties" in document: 27 | properties[document["_id"]] = document["properties"] 28 | 29 | 30 | def update_user_properties(id_: int): 31 | document = collection.find_one({"_id": id_}, {"properties": 1, "_id": 1}) 32 | properties[id_] = document["properties"] 33 | 34 | 35 | async def disc(bot, ctx: commands.Context, item_dict: dict): 36 | try: 37 | channel = ctx.author.voice.channel 38 | except AttributeError: 39 | await ctx.send(f"{ctx.author.mention} You must be in a voice channel to use this item.") 40 | return 41 | if ctx.voice_client is None: 42 | client = await channel.connect() 43 | else: 44 | client = ctx.voice_client 45 | if client.channel != channel: 46 | await client.move_to(channel) 47 | try: 48 | msg = await ctx.send("Playing your disc now.") 49 | url = item_dict['url'] 50 | player = await YTDLSource.from_url(url, loop=bot.loop, stream=True) 51 | if client.is_playing(): 52 | client.stop() 53 | client.play(player) 54 | await msg.add_reaction("✅") 55 | while client.is_playing(): 56 | await asyncio.sleep(1) 57 | await client.disconnect() 58 | except: 59 | if client: 60 | await client.disconnect() 61 | traceback.print_exc() 62 | 63 | 64 | async def notebook(bot, ctx: commands.Context, item_dict: dict): 65 | await ctx.send("Under Development") 66 | 67 | 68 | async def mom(bot, ctx: commands.Context, item_dict: dict): 69 | uses = random.randint(10, 50) 70 | utils.update(ctx.author.id, inc_vals={"properties.100_uses": uses, "inventory.100":-1}) 71 | update_user_properties(ctx.author.id) 72 | await ctx.send( 73 | f"{ctx.author.mention} You used Joe Mama. {uses} uses were added and a total of {properties[ctx.author.id]['100_uses']} uses are left.") 74 | 75 | 76 | async def ring(bot, ctx: commands.Context, item_dict: dict): 77 | converter = commands.MemberConverter() 78 | message_list = ctx.message.content.replace(ctx.prefix, "").split(" ") 79 | if len(message_list) != 3: 80 | await ctx.send(f"{ctx.author.mention} Mention a user to marry them!") 81 | raise CommandError 82 | try: 83 | mentioned_user = await converter.convert(ctx, message_list[2]) 84 | except: 85 | await ctx.send(f"{ctx.author.mention} Couldn't find user {message_list[2]}") 86 | raise CommandError 87 | if ctx.author.id in properties and f"{item_dict['id']}_member" in properties[ctx.author.id] and \ 88 | properties[ctx.author.id][f"{item_dict['id']}_member"]["married"]: 89 | await ctx.send( 90 | f"{ctx.author.mention} You are already married! Buy and use Divorce papers from the shop to marry someone else") 91 | raise CommandError 92 | if mentioned_user.id in properties and f"{item_dict['id']}_member" in properties[mentioned_user.id] and \ 93 | properties[mentioned_user.id][f"{item_dict['id']}_member"]["married"]: 94 | await ctx.send( 95 | f"{ctx.author.mention}, {mentioned_user.display_name} is already married to someone else! Ask them to divorce their significant other using Divorce papers from the shop") 96 | raise CommandError 97 | embed = discord.Embed( 98 | title=f"{mentioned_user.display_name}, {ctx.author.display_name} has proposed you with a {item_dict['name']} " 99 | f"ring! Would you like to marry them?", 100 | description="React with 👍 within 15 seconds to confirm", color=discord.Colour.green()) 101 | embed.set_footer(text=f"Pls marry this loner", icon_url=ctx.author.avatar_url) 102 | message = await ctx.send(mentioned_user.mention, embed=embed) 103 | await message.add_reaction("👍") 104 | 105 | def check(reaction, user): 106 | return user.id == mentioned_user.id and str( 107 | reaction.emoji) == '👍' and reaction.message.id == message.id 108 | 109 | try: 110 | await bot.wait_for('reaction_add', timeout=15.0, check=check) 111 | time_of_marriage = datetime.utcnow() 112 | utils.update(ctx.author.id, 113 | set_vals={f"properties.{item_dict['id']}_member.id": mentioned_user.id, 114 | f"properties.{item_dict['id']}_member.name": mentioned_user.display_name, 115 | f"properties.{item_dict['id']}_member.married": True, 116 | f"properties.{item_dict['id']}_member.datetime": time_of_marriage}, 117 | inc_vals={f"inventory.{item_dict['id']}": -1}) 118 | utils.update(mentioned_user.id, 119 | set_vals={f"properties.{item_dict['id']}_member.id": ctx.author.id, 120 | f"properties.{item_dict['id']}_member.name": ctx.author.display_name, 121 | f"properties.{item_dict['id']}_member.married": True, 122 | f"properties.{item_dict['id']}_member.datetime": time_of_marriage}) 123 | await ctx.send( 124 | f"{ctx.author.mention} and {mentioned_user.mention} are now married to each other! Please don't ask them to invite you on their honeymoon") 125 | except asyncio.TimeoutError: 126 | embed = discord.Embed( 127 | title=f"{mentioned_user.display_name}, {ctx.author.display_name} has proposed you with a {item_dict['name']} " 128 | f"ring! Would you like to marry them?", 129 | description=f"Proposal failed. I guess {mentioned_user.display_name} doesn't like you", 130 | color=discord.Colour.red()) 131 | await message.edit(embed=embed) 132 | await message.clear_reactions() 133 | raise CommandError 134 | finally: 135 | update_user_properties(ctx.author.id) 136 | update_user_properties(mentioned_user.id) 137 | 138 | 139 | def properties_100(ctx: commands.Context): 140 | if ctx.author.id not in properties or "100_uses" not in properties[ctx.author.id] or \ 141 | properties[ctx.author.id]["100_uses"] <= 0: 142 | return f"{ctx.author.mention} You have 0 Joe Mama replies." 143 | else: 144 | return f'{ctx.author.mention} You have {properties[ctx.author.id]["100_uses"]} Joe Mama replies.' 145 | 146 | 147 | def properties_104(ctx: commands.Context): 148 | if ctx.author.id not in properties or "104_member" not in properties[ctx.author.id] or not properties[ctx.author.id]["104_member"]["married"]: 149 | return f"{ctx.author.mention} You are not married to any user." 150 | else: 151 | del_time = datetime.utcnow() - properties[ctx.author.id]['104_member']['datetime'] 152 | days, seconds = del_time.days, del_time.seconds 153 | hours = days * 24 + seconds // 3600 154 | minutes = (seconds % 3600) // 60 155 | return f"{ctx.author.mention} You are married to {properties[ctx.author.id]['104_member']['name']} since {days} " \ 156 | f"days, {hours} hours and {minutes} minutes" 157 | 158 | 159 | async def on_message(bot: commands.Bot, message: discord.Message): 160 | if len(message.mentions) > 0: 161 | mentioned_member: discord.User = message.mentions[0] 162 | else: 163 | return 164 | if mentioned_member.id not in properties or "100_uses" not in properties[mentioned_member.id] or \ 165 | properties[mentioned_member.id][ 166 | "100_uses"] <= 0 or mentioned_member.id == message.author.id or message.author.id == bot.user.id: 167 | return 168 | message_contents_list = message.content.lower().split(" ") 169 | if "ur" in message_contents_list or "you're" in message_contents_list or "youre" in message_contents_list or "you are" in message_contents_list: 170 | try: 171 | webhook: discord.Webhook = await message.channel.create_webhook(name=mentioned_member.name) 172 | await webhook.send(f"{message.author.mention} no ur mom", username=mentioned_member.name, 173 | avatar_url=mentioned_member.avatar_url) 174 | await webhook.delete() 175 | except discord.errors.Forbidden: 176 | await message.channel.send(f"{message.author.mention} no ur mom") 177 | finally: 178 | properties[mentioned_member.id]["100_uses"] -= 1 179 | utils.update(mentioned_member.id, inc_vals={"properties.100_uses": -1}) 180 | 181 | 182 | ytdl_format_options = { 183 | 'format': 'bestaudio/best', 184 | 'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s', 185 | 'restrictfilenames': True, 186 | 'noplaylist': True, 187 | 'nocheckcertificate': True, 188 | 'ignoreerrors': False, 189 | 'logtostderr': False, 190 | 'quiet': True, 191 | 'no_warnings': True, 192 | 'default_search': 'auto', 193 | 'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes 194 | } 195 | 196 | ffmpeg_options = { 197 | 'options': '-vn' 198 | } 199 | 200 | ytdl = youtube_dl.YoutubeDL(ytdl_format_options) 201 | 202 | 203 | class YTDLSource(discord.PCMVolumeTransformer): 204 | def __init__(self, source, *, data, volume=0.5): 205 | super().__init__(source, volume) 206 | 207 | self.data = data 208 | self.title = data.get('title') 209 | self.url = data.get('url') 210 | 211 | @classmethod 212 | async def from_url(cls, url, *, loop=None, stream=False): 213 | loop = loop or asyncio.get_event_loop() 214 | data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream)) 215 | 216 | if 'entries' in data: 217 | data = data['entries'][0] 218 | 219 | filename = data['url'] if stream else ytdl.prepare_filename(data) 220 | return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data) 221 | -------------------------------------------------------------------------------- /main_resources/loops.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from itertools import cycle 4 | from cogs.utils import GameGrid 5 | from cogs.utils.currency_utils import currency_utils 6 | 7 | 8 | class Loops: 9 | def __init__(self, bot: commands.Bot, custom_statuses, database): 10 | self.bot = bot 11 | self.custom_statuses = custom_statuses 12 | self.collection = database["currency"] 13 | self.utils = currency_utils(self.collection) 14 | 15 | async def change_status(self): 16 | """Task loop for changing bot statuses""" 17 | await self.bot.change_presence(activity=discord.Game(next(cycle(self.custom_statuses)))) 18 | 19 | async def clear_game(self): 20 | """Task loop for clearing 2048 games""" 21 | 22 | for game in GameGrid.getGames(): 23 | if game.getLastUpdate() > 60.0: 24 | msg = game.getEmojiMessage() 25 | point = game.getPoint() 26 | coins = int(point / 2) 27 | channel = self.bot.get_channel(int(game.getChannelId())) 28 | # user = self.bot.get_user(int(game.getId())) 29 | game.stop() 30 | embed = discord.Embed(title="2048 Game Over!", 31 | description=f"**Points:** {point}\n**Coins:** {coins}\n\n{msg}", 32 | color=discord.Color.orange()) 33 | embed.set_footer(text=f'Game session of {game.name}', icon_url=game.url) 34 | self.utils.update_and_insert(int(game.getId()), inc_vals={"wallet": coins}, wallet=False) 35 | await channel.send(embed=embed) 36 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | discord.py 2 | Pillow~=8.2.0 3 | praw~=7.2.0 4 | asyncio~=3.4.3 5 | python-dotenv~=0.17.1 6 | requests~=2.25.1 7 | discord~=1.0.1 8 | numpy~=1.19.5 9 | keras~=2.4.3 10 | nltk~=3.6.2 11 | pymongo~=3.11.4 12 | dnspython 13 | bs4~=0.0.1 14 | wikipedia~=1.4.0 15 | beautifulsoup4~=4.9.3 16 | pynacl 17 | youtube_dl 18 | berserk 19 | python-chess==0.31.4 20 | cairosvg --------------------------------------------------------------------------------