Compare commits
68 Commits
Author | SHA1 | Date |
---|---|---|
Profitroll | 5c5a620d65 | |
Renovate | 1c05efa0f4 | |
Profitroll | f5de2457ba | |
Renovate | 8cec182435 | |
Profitroll | ad0ab65c5d | |
Profitroll | 0029cdaa30 | |
Profitroll | e94883f6ad | |
Renovate | 465838a196 | |
Profitroll | a059fb0518 | |
Renovate | c4ee74753b | |
Profitroll | 492edc242f | |
Renovate | 66c0ad7ee8 | |
Profitroll | c1ee1b50ab | |
Profitroll | 7a379cf97e | |
Profitroll | 388e27fdff | |
Profitroll | 65a0e1097e | |
Profitroll | 3fe67e18b0 | |
Profitroll | 91eecb4b0b | |
Profitroll | 740c6a1464 | |
Profitroll | 3ca44dcd2d | |
Profitroll | 301439f144 | |
Profitroll | 3435d59d96 | |
Renovate | d560bce8c6 | |
Profitroll | 528604b6b4 | |
Profitroll | 76c7812284 | |
Profitroll | 8e48334cea | |
Renovate | bc9cebbec6 | |
Profitroll | a178aa2af9 | |
Profitroll | fb3e291d77 | |
Profitroll | 75c1889477 | |
Profitroll | 5329b4c727 | |
Profitroll | 0f3a6121d6 | |
Profitroll | 7f1f86ca03 | |
Profitroll | c600747848 | |
Profitroll | a2bd55dcdf | |
Profitroll | 98ac531a36 | |
Profitroll | af24a055b6 | |
Profitroll | 97fe10bb96 | |
Profitroll | bad83b0266 | |
Profitroll | 97d05866e2 | |
Profitroll | e56268543c | |
Profitroll | be9ed44614 | |
Profitroll | eec975ce36 | |
Profitroll | 512517f76e | |
Profitroll | af29a7ced6 | |
Profitroll | 9b8d389031 | |
Profitroll | 0f7a860dad | |
Profitroll | a3a0aaa72b | |
Profitroll | 78239c7e5d | |
Profitroll | 79fb14b1bc | |
Profitroll | 0379d99e69 | |
Profitroll | 462f4c7a09 | |
Profitroll | 078eac1446 | |
Profitroll | 6334002068 | |
Profitroll | ffa3babb45 | |
Profitroll | fba819ce29 | |
Profitroll | 7ccb674b9f | |
Profitroll | b6e9f5089c | |
Profitroll | 85480c7658 | |
Profitroll | 78a845a99b | |
Profitroll | 9b138781a6 | |
Profitroll | 83431d7371 | |
Profitroll | 3ec769d017 | |
Profitroll | be209de3e0 | |
Profitroll | c06031e893 | |
Profitroll | 4254570efc | |
Profitroll | 62c7a70aec | |
Profitroll | 95d95b1014 |
|
@ -0,0 +1,173 @@
|
||||||
|
# ---> Python
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
# For a library or package, you might want to ignore these files since the code is
|
||||||
|
# intended to run in multiple environments; otherwise, check them in:
|
||||||
|
# .python-version
|
||||||
|
|
||||||
|
# pipenv
|
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||||
|
# install all needed dependencies.
|
||||||
|
#Pipfile.lock
|
||||||
|
|
||||||
|
# poetry
|
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||||
|
# commonly ignored for libraries.
|
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||||
|
#poetry.lock
|
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||||
|
__pypackages__/
|
||||||
|
|
||||||
|
# Celery stuff
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
# pytype static type analyzer
|
||||||
|
.pytype/
|
||||||
|
|
||||||
|
# Cython debug symbols
|
||||||
|
cython_debug/
|
||||||
|
|
||||||
|
# PyCharm
|
||||||
|
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
#.idea/
|
||||||
|
|
||||||
|
# ---> VisualStudioCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
# Project
|
||||||
|
venv
|
||||||
|
venv_linux
|
||||||
|
venv_windows
|
||||||
|
|
||||||
|
config.json
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
]
|
||||||
|
}
|
64
README.md
64
README.md
|
@ -1,32 +1,57 @@
|
||||||
# YusarinBot
|
<h1 align="center">YusarinBot</h1>
|
||||||
|
|
||||||
Simple, clear, easy, reliable.
|
<p align="center">
|
||||||
A specially designed bot for creating private voice channels at your servers.
|
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html">
|
||||||
|
<img alt="License: GPL v2" src="https://img.shields.io/badge/License-GPL_v2-blue.svg">
|
||||||
|
</a>
|
||||||
|
<a href="https://weblate.end-play.xyz/engage/yusarinbot/">
|
||||||
|
<img src="https://weblate.end-play.xyz/widget/yusarinbot/svg-badge.svg" alt="Translation status" />
|
||||||
|
</a>
|
||||||
|
<a href="https://git.end-play.xyz/profitroll/YusarinBot">
|
||||||
|
<img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg">
|
||||||
|
</a>
|
||||||
|
<a href="https://discord.com/invite/2zpzErtnNT">
|
||||||
|
<img alt="Discord" src="https://img.shields.io/discord/940760922346123284">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
Simple, easy to set up, yet reliable.
|
||||||
|
A specially designed bot for creating private voice channels on your Discord servers.
|
||||||
Installation instructions are listed below. Please, make sure you have installed dependencies before opening issue here.
|
Installation instructions are listed below. Please, make sure you have installed dependencies before opening issue here.
|
||||||
|
|
||||||
|
> Since version 1.5 only slash commands are supported. If you'd like to use old-fashioned commands and commands prefix feature – consider installing [1.4 version](https://git.end-play.xyz/profitroll/YusarinBot/releases/tag/v1.4) which is the last one compatible with those.
|
||||||
|
|
||||||
## Installation (Short)
|
## Installation (Short)
|
||||||
1. `git clone https://github.com/profitrollgame/YusarinBot`
|
|
||||||
|
1. `git clone https://git.end-play.xyz/profitroll/YusarinBot`
|
||||||
2. `cd YusarinBot`
|
2. `cd YusarinBot`
|
||||||
3. `pip install -r requirements.txt`
|
3. `pip install -r requirements.txt`
|
||||||
4. `nano config.json`
|
4. `cp config_example.json config.json`
|
||||||
5. `python yusarin.py`
|
5. `nano config.json`
|
||||||
|
6. `python yusarin.py`
|
||||||
|
|
||||||
## Installation (Detailed)
|
## Installation (Detailed)
|
||||||
1. Download and install Python 3 (3.6+ should be fine)
|
|
||||||
2. Download bot's release: https://github.com/profitrollgame/YusarinBot/releases/latest
|
1. Download and install Python 3.8+
|
||||||
|
2. Download bot's release: <https://git.end-play.xyz/profitroll/YusarinBot/releases/latest>
|
||||||
3. Unpack your archive to folder. Name it YusarinBot for example
|
3. Unpack your archive to folder. Name it YusarinBot for example
|
||||||
4. Change working directory using `cd YusarinBot` or `cd FolderYouHaveCreated`
|
4. Change working directory using `cd YusarinBot` or `cd FolderYouHaveCreated`
|
||||||
5. Run `pip install -r requirements.txt` to install dependencies
|
5. If you're using Linux system - install [dependencies for Pycord](https://docs.pycord.dev/en/stable/installing.html#installing)
|
||||||
6. Create new Discord application at https://discord.com/developers/applications
|
6. Run `pip install -r requirements.txt` to install dependencies
|
||||||
7. You can rename it however you want, set needed descriptions etc
|
7. [Optionally] run `pip install -r requirements-optional.txt` to install optional dependencies
|
||||||
8. Go to "Bot" tab and enable application as bot
|
8. Create new Discord application at <https://discord.com/developers/applications>
|
||||||
9. Copy token of your bot
|
9. You can rename it however you want, set needed descriptions etc
|
||||||
10. Open file `config.json` with your favorite text editor and paste your token as value of "bot_token" key
|
10. Go to "Bot" tab and enable application as bot
|
||||||
11. Copy your own Discord ID and paste it as value of "owner" key (How to get ID: https://support.playhive.com/discord-user-id/)
|
11. Copy token of your bot
|
||||||
12. Bot is ready! Run it using `python yusarin.py`
|
12. Copy `config_example.json` to `config.json`
|
||||||
|
13. Open file `config.json` with your favorite text editor and paste your token as value of "bot_token" key
|
||||||
|
14. Copy your own Discord ID and paste it as value of "owner" key (How to get ID: <https://support.playhive.com/discord-user-id/>)
|
||||||
|
15. Bot is ready! Run it using `python yusarin.py`
|
||||||
|
|
||||||
## Config explanation
|
## Config explanation
|
||||||
Default configuration file is [available here](https://github.com/profitrollgame/YusarinBot/blob/main/config.json)
|
|
||||||
|
Default configuration file is [available here](https://git.profitroll.eu/profitroll/YusarinBot/src/branch/main/config.json)
|
||||||
|
|
||||||
- "debug" - Option that enables more detailed log messages [Boolean]
|
- "debug" - Option that enables more detailed log messages [Boolean]
|
||||||
- "owner" - Discord ID of user who will be able to execute admin commands (`$shutdown` for example) [Integer]
|
- "owner" - Discord ID of user who will be able to execute admin commands (`$shutdown` for example) [Integer]
|
||||||
- "bot_name" - Name of your bot. Is not used anywhere yet [String]
|
- "bot_name" - Name of your bot. Is not used anywhere yet [String]
|
||||||
|
@ -38,6 +63,7 @@ Default configuration file is [available here](https://github.com/profitrollgame
|
||||||
- "color_ok" - HTML color used on command success embed [String]
|
- "color_ok" - HTML color used on command success embed [String]
|
||||||
- "color_warn" - HTML color used in all warning embeds [String]
|
- "color_warn" - HTML color used in all warning embeds [String]
|
||||||
- "color_error" - HTML color used on command error embed [String]
|
- "color_error" - HTML color used on command error embed [String]
|
||||||
|
- "enable_nomic" - Option that allows you to create additional text channel for "nomic" purposes [Boolean]
|
||||||
- "bot_site" - http or https link that will be used in help message header [String]
|
- "bot_site" - http or https link that will be used in help message header [String]
|
||||||
- "bot_icon" - http or https link that will be used in help message header's icon [String]
|
- "bot_icon" - http or https link that will be used in help message header's icon [String]
|
||||||
- "check_for_updates" - Option that defines whether bot should check for a new version available [Boolean]
|
- "check_for_updates" - Option that defines whether bot should check for a new version available [Boolean]
|
||||||
|
@ -45,5 +71,7 @@ Default configuration file is [available here](https://github.com/profitrollgame
|
||||||
- "auto_clear_timer" - Option that defines how often "auto_clear_trash" will do its job [Integer]
|
- "auto_clear_timer" - Option that defines how often "auto_clear_trash" will do its job [Integer]
|
||||||
|
|
||||||
## Extra
|
## Extra
|
||||||
|
|
||||||
1. Bot doesn't have any self updaters **yet**
|
1. Bot doesn't have any self updaters **yet**
|
||||||
2. You can add public version of the bot to your Discord server using this link: https://discord.com/api/oauth2/authorize?client_id=937839388853944390&permissions=318769168&scope=bot
|
2. You can add public version of the bot to your Discord server using this link: <https://www.end-play.xyz/yusarin/invite>
|
||||||
|
3. If you have questions/suggestions - just join our [Discord Support Server](https://discord.com/invite/2zpzErtnNT)
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
from discord import ApplicationContext, CategoryChannel, Option, SlashCommandGroup
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
from functions import (
|
||||||
|
getMsg,
|
||||||
|
guildConfGet,
|
||||||
|
guildConfReset,
|
||||||
|
guildConfSet,
|
||||||
|
loadJson,
|
||||||
|
makeEmbed,
|
||||||
|
strToColor,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
||||||
|
class CogCategory(commands.Cog):
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
category = SlashCommandGroup(
|
||||||
|
"category", "Commands related to parent channels category"
|
||||||
|
)
|
||||||
|
|
||||||
|
@category.command(
|
||||||
|
name="set",
|
||||||
|
description="Select the voice channel that will be parent to private ones",
|
||||||
|
)
|
||||||
|
async def category_set(self, ctx: ApplicationContext, category: Option(CategoryChannel, "Parent Channel Category")): # type: ignore
|
||||||
|
config = loadJson("config.json")
|
||||||
|
if ctx.guild is not None:
|
||||||
|
guildConfSet(ctx.guild, "category", category.id)
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("set_category_title", ctx.guild),
|
||||||
|
description=getMsg("set_category_description", ctx.guild).format(
|
||||||
|
category.name
|
||||||
|
),
|
||||||
|
color=strToColor(config["color_ok"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if guildConfGet(ctx.guild, "channel") is None:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("hint_none_channel_title", ctx.guild),
|
||||||
|
description=getMsg("hint_none_channel_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_warn"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("dm_title", ctx.guild),
|
||||||
|
description=getMsg("dm_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@category.command(
|
||||||
|
name="reset", description="Reset the currently selected parent channel category"
|
||||||
|
)
|
||||||
|
async def category_reset(self, ctx: ApplicationContext): # type: ignore
|
||||||
|
config = loadJson("config.json")
|
||||||
|
if ctx.guild is not None:
|
||||||
|
if guildConfGet(ctx.guild, "category") is not None:
|
||||||
|
guildConfReset(ctx.guild, "category")
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("reset_category_title", ctx.guild),
|
||||||
|
description=getMsg("reset_category_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_ok"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("hint_none_category_title", ctx.guild),
|
||||||
|
description=getMsg("hint_none_category_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_warn"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("dm_title", ctx.guild),
|
||||||
|
description=getMsg("dm_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
|
@ -0,0 +1,155 @@
|
||||||
|
from discord import (
|
||||||
|
ApplicationContext,
|
||||||
|
Cog,
|
||||||
|
Member,
|
||||||
|
SlashCommandGroup,
|
||||||
|
VoiceChannel,
|
||||||
|
VoiceState,
|
||||||
|
option,
|
||||||
|
utils,
|
||||||
|
)
|
||||||
|
from discord.ext import commands
|
||||||
|
from discord.abc import GuildChannel
|
||||||
|
|
||||||
|
from functions import (
|
||||||
|
appendLog,
|
||||||
|
changeNomicPerms,
|
||||||
|
createUserVoice,
|
||||||
|
getMsg,
|
||||||
|
guildConfGet,
|
||||||
|
guildConfReset,
|
||||||
|
guildConfSet,
|
||||||
|
isUserVoice,
|
||||||
|
isVoiceOfUser,
|
||||||
|
loadJson,
|
||||||
|
makeEmbed,
|
||||||
|
removeUserVoice,
|
||||||
|
strToColor,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
||||||
|
class CogChannel(commands.Cog):
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_guild_channel_delete(self, channel: GuildChannel):
|
||||||
|
if isUserVoice(channel):
|
||||||
|
await removeUserVoice(channel)
|
||||||
|
|
||||||
|
@Cog.listener()
|
||||||
|
async def on_voice_state_update(
|
||||||
|
self, member: Member, before: VoiceState, after: VoiceState
|
||||||
|
):
|
||||||
|
config = loadJson("config.json")
|
||||||
|
|
||||||
|
vc_from = before.channel
|
||||||
|
vc_to = after.channel
|
||||||
|
|
||||||
|
# If user left vc
|
||||||
|
if before.channel is not None and len(before.channel.members) == 0:
|
||||||
|
if isUserVoice(vc_from):
|
||||||
|
if not isVoiceOfUser(vc_from, member):
|
||||||
|
if loadJson("config.json")["enable_nomic"]:
|
||||||
|
await changeNomicPerms("deny", vc_from, member)
|
||||||
|
await removeUserVoice(vc_from)
|
||||||
|
|
||||||
|
# If user joined vc
|
||||||
|
if after.channel is not None and after.channel.id == guildConfGet(
|
||||||
|
member.guild, "channel"
|
||||||
|
):
|
||||||
|
if isUserVoice(vc_to):
|
||||||
|
if loadJson("config.json")["enable_nomic"]:
|
||||||
|
await changeNomicPerms("allow", vc_to, member)
|
||||||
|
if vc_to.id == guildConfGet(vc_to.guild, "channel"):
|
||||||
|
if guildConfGet(vc_to.guild, "category") is not None:
|
||||||
|
voice_chan = await createUserVoice(
|
||||||
|
vc_to,
|
||||||
|
utils.get(
|
||||||
|
vc_to.guild.categories,
|
||||||
|
id=guildConfGet(vc_to.guild, "category"),
|
||||||
|
),
|
||||||
|
member,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
await member.move_to(voice_chan)
|
||||||
|
except:
|
||||||
|
await removeUserVoice(voice_chan)
|
||||||
|
else:
|
||||||
|
appendLog(
|
||||||
|
f"Category for guild {vc_to.guild} ({str(vc_to.guild.id)}) is not set",
|
||||||
|
guild=vc_to.guild,
|
||||||
|
)
|
||||||
|
|
||||||
|
channel = SlashCommandGroup("channel", "Commands related to parent voice channel")
|
||||||
|
|
||||||
|
@channel.command(
|
||||||
|
name="set",
|
||||||
|
description="Select the voice channel that will be parent to private ones",
|
||||||
|
)
|
||||||
|
@option("channel", description="Parent Voice Channel")
|
||||||
|
async def channel_set(self, ctx: ApplicationContext, channel: VoiceChannel):
|
||||||
|
config = loadJson("config.json")
|
||||||
|
if ctx.guild is not None:
|
||||||
|
guildConfSet(ctx.guild, "channel", channel.id)
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("set_channel_title", ctx.guild),
|
||||||
|
description=getMsg("set_channel_description", ctx.guild).format(
|
||||||
|
channel.name
|
||||||
|
),
|
||||||
|
color=strToColor(config["color_ok"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if guildConfGet(ctx.guild, "category") is None:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("hint_none_category_title", ctx.guild),
|
||||||
|
description=getMsg("hint_none_category_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_warn"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("dm_title", ctx.guild),
|
||||||
|
description=getMsg("dm_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@channel.command(
|
||||||
|
name="reset", description="Reset the currently selected parent voice channel"
|
||||||
|
)
|
||||||
|
async def channel_reset(self, ctx: ApplicationContext):
|
||||||
|
config = loadJson("config.json")
|
||||||
|
if ctx.guild is not None:
|
||||||
|
if guildConfGet(ctx.guild, "channel") is not None:
|
||||||
|
guildConfReset(ctx.guild, "channel")
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("reset_channel_title", ctx.guild),
|
||||||
|
description=getMsg("reset_channel_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_ok"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("hint_none_channel_title", ctx.guild),
|
||||||
|
description=getMsg("hint_none_channel_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_warn"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("dm_title", ctx.guild),
|
||||||
|
description=getMsg("dm_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
|
@ -0,0 +1,105 @@
|
||||||
|
from os import listdir
|
||||||
|
|
||||||
|
from discord import ApplicationContext, Option, SlashCommandGroup
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
from functions import (
|
||||||
|
appendLog,
|
||||||
|
getMsg,
|
||||||
|
guildConfGet,
|
||||||
|
guildConfReset,
|
||||||
|
guildConfSet,
|
||||||
|
loadJson,
|
||||||
|
makeEmbed,
|
||||||
|
strToColor,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
||||||
|
class CogLocale(commands.Cog):
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
locale = SlashCommandGroup("locale", "Commands related to bot's locale")
|
||||||
|
|
||||||
|
valid_locales = []
|
||||||
|
files_locales = listdir(f"locale/")
|
||||||
|
for entry in files_locales:
|
||||||
|
valid_locales.append(".".join(entry.split(".")[:-1]))
|
||||||
|
|
||||||
|
@locale.command(name="set", description="Set bot's messages language")
|
||||||
|
async def locale_set(self, ctx: ApplicationContext, language: Option(str, "One of the languages in list", choices=valid_locales)): # type: ignore
|
||||||
|
config = loadJson("config.json")
|
||||||
|
if ctx.guild is not None:
|
||||||
|
if language + ".json" in listdir(f"locale/"):
|
||||||
|
guildConfSet(ctx.guild, "locale", language)
|
||||||
|
appendLog(f"Server's locale is now set to {language}", ctx.guild)
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("set_locale_title", ctx.guild),
|
||||||
|
description=getMsg("set_locale_description", ctx.guild).format(
|
||||||
|
getMsg("locale_name", ctx.guild)
|
||||||
|
),
|
||||||
|
color=strToColor(config["color_ok"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
valid_locales = []
|
||||||
|
files_locales = listdir(f"locale/")
|
||||||
|
for entry in files_locales:
|
||||||
|
valid_locales.append(entry.split(".")[:-1])
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("error_locale_title", ctx.guild),
|
||||||
|
description=getMsg(
|
||||||
|
"error_locale_description", ctx.guild
|
||||||
|
).format(", ".join(valid_locales)),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("dm_title", ctx.guild),
|
||||||
|
description=getMsg("dm_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@locale.command(name="reset", description="Reset the bot's language in this guild")
|
||||||
|
async def locale_reset(self, ctx: ApplicationContext): # type: ignore
|
||||||
|
config = loadJson("config.json")
|
||||||
|
if ctx.guild is not None:
|
||||||
|
if guildConfGet(ctx.guild, "locale") is not None:
|
||||||
|
guildConfReset(ctx.guild, "locale")
|
||||||
|
appendLog(f"Server's locale has been reset", ctx.guild)
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("reset_locale_title", ctx.guild),
|
||||||
|
description=getMsg(
|
||||||
|
"reset_locale_description", ctx.guild
|
||||||
|
).format(getMsg("locale_name", ctx.guild)),
|
||||||
|
color=strToColor(config["color_ok"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("hint_none_locale_title", ctx.guild),
|
||||||
|
description=getMsg(
|
||||||
|
"hint_none_locale_description", ctx.guild
|
||||||
|
).format(getMsg("locale_name", ctx.guild)),
|
||||||
|
color=strToColor(config["color_warn"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("dm_title", ctx.guild),
|
||||||
|
description=getMsg("dm_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
|
@ -0,0 +1,53 @@
|
||||||
|
from os import getpid, makedirs, system
|
||||||
|
from shutil import rmtree
|
||||||
|
|
||||||
|
from discord import ApplicationContext, Cog, Guild, slash_command
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
from functions import appendLog, getMsg, loadJson, makeEmbed, saveJson, strToColor
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
||||||
|
class CogUtility(commands.Cog):
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
@Cog.listener()
|
||||||
|
async def on_guild_join(self, guild: Guild):
|
||||||
|
makedirs(f"guilds/{str(guild.id)}", exist_ok=True)
|
||||||
|
makedirs(f"guilds/{str(guild.id)}/channels", exist_ok=True)
|
||||||
|
saveJson({}, f"guilds/{str(guild.id)}/config.json")
|
||||||
|
|
||||||
|
appendLog(f"Joined guild '{guild}' with id {str(guild.id)}")
|
||||||
|
|
||||||
|
@Cog.listener()
|
||||||
|
async def on_guild_remove(self, guild: Guild):
|
||||||
|
try:
|
||||||
|
rmtree(f"guilds/{str(guild.id)}")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
appendLog(f"Left guild '{guild}' with id {str(guild.id)}")
|
||||||
|
|
||||||
|
@slash_command(name="shutdown", description="Restart the bot")
|
||||||
|
async def shutdown(self, ctx: ApplicationContext):
|
||||||
|
config = loadJson("config.json")
|
||||||
|
if ctx.author.id == config["owner"]:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
description=getMsg("shutdown", ctx.guild).format(ctx.author),
|
||||||
|
color=strToColor(config["color_default"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
system(f"kill -9 {str(getpid())}")
|
||||||
|
else:
|
||||||
|
await ctx.respond(
|
||||||
|
embed=makeEmbed(
|
||||||
|
title=getMsg("admin_title", ctx.guild),
|
||||||
|
description=getMsg("admin_description", ctx.guild),
|
||||||
|
color=strToColor(config["color_error"]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
|
@ -10,6 +10,7 @@
|
||||||
"color_ok": "#226699",
|
"color_ok": "#226699",
|
||||||
"color_warn": "#FFCC4D",
|
"color_warn": "#FFCC4D",
|
||||||
"color_error": "#DD2E44",
|
"color_error": "#DD2E44",
|
||||||
|
"enable_nomic": false,
|
||||||
"bot_site": "https://www.end-play.xyz/yusarin",
|
"bot_site": "https://www.end-play.xyz/yusarin",
|
||||||
"bot_icon": "https://www.end-play.xyz/yusarin/logo",
|
"bot_icon": "https://www.end-play.xyz/yusarin/logo",
|
||||||
"check_for_updates": true,
|
"check_for_updates": true,
|
520
functions.py
520
functions.py
|
@ -1,13 +1,29 @@
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import json
|
|
||||||
import shutil
|
|
||||||
import discord
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from gzip import open as gzipopen
|
||||||
|
from os import listdir, makedirs, path, remove, stat
|
||||||
|
from shutil import copyfileobj
|
||||||
|
from typing import Any, Literal, Union
|
||||||
|
|
||||||
path = Path(__file__).resolve().parent
|
from discord import (
|
||||||
|
ApplicationContext,
|
||||||
|
CategoryChannel,
|
||||||
|
Client,
|
||||||
|
Embed,
|
||||||
|
Guild,
|
||||||
|
Member,
|
||||||
|
Message,
|
||||||
|
PermissionOverwrite,
|
||||||
|
TextChannel,
|
||||||
|
VoiceChannel,
|
||||||
|
utils,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ujson import dumps, loads
|
||||||
|
except ImportError:
|
||||||
|
from json import dumps, loads
|
||||||
|
|
||||||
|
# path = Path(__file__).resolve().parent
|
||||||
|
|
||||||
log_size = 512
|
log_size = 512
|
||||||
|
|
||||||
|
@ -17,40 +33,42 @@ log_size = 512
|
||||||
debug = False
|
debug = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open("config.json", 'r', encoding="utf-8") as json_file:
|
with open("config.json", "r", encoding="utf-8") as json_file:
|
||||||
output = json.load(json_file)
|
output = loads(json_file.read())
|
||||||
json_file.close()
|
json_file.close()
|
||||||
debug = output["debug"]
|
debug = output["debug"]
|
||||||
except:
|
except:
|
||||||
debug = debug
|
debug = debug
|
||||||
|
|
||||||
|
|
||||||
# Check latest log size
|
# Check latest log size
|
||||||
def checkSize():
|
def checkSize():
|
||||||
global path
|
|
||||||
path = str(path)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(f"{path}/logs"):
|
if not path.isdir("logs"):
|
||||||
os.mkdir(f"{path}/logs")
|
makedirs("logs", exist_ok=True)
|
||||||
|
|
||||||
log = os.stat(path + '/logs/latest.log')
|
log = stat("logs/latest.log")
|
||||||
global log_size
|
global log_size
|
||||||
|
|
||||||
if (log.st_size / 1024) > log_size:
|
if (log.st_size / 1024) > log_size:
|
||||||
with open(path + '/logs/latest.log', 'rb') as f_in:
|
with open("logs/latest.log", "rb") as f_in:
|
||||||
with gzip.open(f'{path}/logs/{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.log.gz', 'wb') as f_out:
|
with gzipopen(
|
||||||
shutil.copyfileobj(f_in, f_out)
|
f'logs/{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.log.gz', "wb"
|
||||||
print(f'Copied {path}/logs/{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.log.gz')
|
) as f_out:
|
||||||
open(path + '/logs/latest.log', 'w').close()
|
copyfileobj(f_in, f_out)
|
||||||
|
print(
|
||||||
|
f'Copied logs/{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.log.gz'
|
||||||
|
)
|
||||||
|
open("logs/latest.log", "w").close()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print('Not found')
|
print("Not found")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Append string to log
|
# Append string to log
|
||||||
def appendLog(message, guild=None, announce=True):
|
def appendLog(message: str, guild: Union[Guild, None] = None, announce=True) -> None:
|
||||||
global debug
|
global debug
|
||||||
global path
|
|
||||||
|
|
||||||
if guild == None:
|
if guild == None:
|
||||||
message_formatted = f'[{datetime.now().strftime("%d.%m.%Y")}] [{datetime.now().strftime("%H:%M:%S")}] {message}'
|
message_formatted = f'[{datetime.now().strftime("%d.%m.%Y")}] [{datetime.now().strftime("%H:%M:%S")}] {message}'
|
||||||
else:
|
else:
|
||||||
|
@ -58,26 +76,28 @@ def appendLog(message, guild=None, announce=True):
|
||||||
message_formatted = f'[{datetime.now().strftime("%d.%m.%Y")}] [{datetime.now().strftime("%H:%M:%S")}] [{guild} | {str(guild.id)}] {message}'
|
message_formatted = f'[{datetime.now().strftime("%d.%m.%Y")}] [{datetime.now().strftime("%H:%M:%S")}] [{guild} | {str(guild.id)}] {message}'
|
||||||
else:
|
else:
|
||||||
message_formatted = f'[{datetime.now().strftime("%d.%m.%Y")}] [{datetime.now().strftime("%H:%M:%S")}] [{guild}] {message}'
|
message_formatted = f'[{datetime.now().strftime("%d.%m.%Y")}] [{datetime.now().strftime("%H:%M:%S")}] [{guild}] {message}'
|
||||||
|
|
||||||
if announce:
|
if announce:
|
||||||
print(message_formatted)
|
print(message_formatted, flush=True)
|
||||||
|
|
||||||
checkSize()
|
checkSize()
|
||||||
|
|
||||||
log = open(path + '/logs/latest.log', 'a')
|
log = open("logs/latest.log", "a") # type: ignore
|
||||||
log.write(f'{message_formatted}\n')
|
log.write(f"{message_formatted}\n")
|
||||||
log.close()
|
log.close()
|
||||||
|
|
||||||
def saveJson(value, filename):
|
|
||||||
with open(filename, 'w', encoding="utf-8") as f:
|
def saveJson(value: Any, filename: str) -> None:
|
||||||
json.dump(value, f, indent=4, ensure_ascii=False)
|
with open(filename, "w", encoding="utf-8") as f:
|
||||||
|
f.write(dumps(value, indent=4, ensure_ascii=False))
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def loadJson(filename):
|
|
||||||
|
def loadJson(filename: str) -> Any:
|
||||||
global debug
|
global debug
|
||||||
try:
|
try:
|
||||||
with open(filename, 'r', encoding="utf-8") as json_file:
|
with open(filename, "r", encoding="utf-8") as json_file:
|
||||||
output = json.load(json_file)
|
output = loads(json_file.read())
|
||||||
json_file.close()
|
json_file.close()
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
if debug:
|
if debug:
|
||||||
|
@ -85,60 +105,68 @@ def loadJson(filename):
|
||||||
output = {}
|
output = {}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def colorToStr():
|
def colorToStr():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def strToColor(string):
|
|
||||||
|
def strToColor(string: str) -> int:
|
||||||
return int(hex(int(string.replace("#", ""), 16)), 0)
|
return int(hex(int(string.replace("#", ""), 16)), 0)
|
||||||
|
|
||||||
def gotCommand(message):
|
|
||||||
|
def gotCommand(message: Message) -> None:
|
||||||
global debug
|
global debug
|
||||||
if debug:
|
if debug:
|
||||||
appendLog(f"Command '{message.content}' from {message.author} ({str(message.author.id)})", message.guild)
|
appendLog(
|
||||||
|
f"Command '{message.content}' from {message.author} ({str(message.author.id)})",
|
||||||
|
message.guild,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
appendLog(f"Command '{message.content}' from {message.author}", message.guild)
|
appendLog(f"Command '{message.content}' from {message.author}", message.guild)
|
||||||
|
|
||||||
def guildConfGet(guild, variable):
|
|
||||||
global path
|
def guildConfGet(guild: Guild, variable: str) -> Any:
|
||||||
global debug
|
global debug
|
||||||
try:
|
try:
|
||||||
config = loadJson(f"{path}/guilds/{str(guild.id)}/config.json")
|
config = loadJson(f"guilds/{str(guild.id)}/config.json")
|
||||||
return config[variable]
|
return config[variable]
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
if debug:
|
if debug:
|
||||||
appendLog(f"Could not get guild config key '{variable}' due to {exp}", guild)
|
appendLog(
|
||||||
|
f"Could not get guild config key '{variable}' due to {exp}", guild
|
||||||
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def guildConfSet(guild, variable, value):
|
|
||||||
global path
|
def guildConfSet(guild: Guild, variable: str, value: Any) -> None:
|
||||||
config = loadJson(f"{path}/guilds/{str(guild.id)}/config.json")
|
config = loadJson(f"guilds/{str(guild.id)}/config.json")
|
||||||
config[variable] = value
|
config[variable] = value
|
||||||
try:
|
try:
|
||||||
saveJson(config, f"{path}/guilds/{str(guild.id)}/config.json")
|
saveJson(config, f"guilds/{str(guild.id)}/config.json")
|
||||||
except:
|
except:
|
||||||
os.mkdir(f"{path}/guilds/{str(guild.id)}")
|
makedirs(f"guilds/{str(guild.id)}", exist_ok=True)
|
||||||
os.mkdir(f"{path}/guilds/{str(guild.id)}/channels")
|
makedirs(f"guilds/{str(guild.id)}/channels", exist_ok=True)
|
||||||
saveJson(config, f"{path}/guilds/{str(guild.id)}/config.json")
|
saveJson(config, f"guilds/{str(guild.id)}/config.json")
|
||||||
appendLog(f"Guild config key '{variable}' is now set to '{value}'", guild)
|
appendLog(f"Guild config key '{variable}' is now set to '{value}'", guild)
|
||||||
|
|
||||||
def guildConfReset(guild, variable):
|
|
||||||
global path
|
def guildConfReset(guild: Guild, variable: str) -> None:
|
||||||
try:
|
try:
|
||||||
config = loadJson(f"{path}/guilds/{str(guild.id)}/config.json")
|
config = loadJson(f"guilds/{str(guild.id)}/config.json")
|
||||||
del config[variable]
|
del config[variable]
|
||||||
try:
|
try:
|
||||||
saveJson(config, f"{path}/guilds/{str(guild.id)}/config.json")
|
saveJson(config, f"guilds/{str(guild.id)}/config.json")
|
||||||
except:
|
except:
|
||||||
os.mkdir(f"{path}/guilds/{str(guild.id)}")
|
makedirs(f"guilds/{str(guild.id)}", exist_ok=True)
|
||||||
os.mkdir(f"{path}/guilds/{str(guild.id)}/channels")
|
makedirs(f"guilds/{str(guild.id)}/channels", exist_ok=True)
|
||||||
saveJson(config, f"{path}/guilds/{str(guild.id)}/config.json")
|
saveJson(config, f"guilds/{str(guild.id)}/config.json")
|
||||||
appendLog(f"Guild config key '{variable}' has been reset", guild)
|
appendLog(f"Guild config key '{variable}' has been reset", guild)
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
appendLog(f"Could not reset guild config key '{variable}' due to {exp}", guild)
|
appendLog(f"Could not reset guild config key '{variable}' due to {exp}", guild)
|
||||||
|
|
||||||
def guildLocaleGet(guild):
|
|
||||||
global path
|
def guildLocaleGet(guild: Guild) -> str:
|
||||||
config = loadJson(f"{path}/config.json")
|
config = loadJson(f"config.json")
|
||||||
try:
|
try:
|
||||||
locale = guildConfGet(guild, "locale")
|
locale = guildConfGet(guild, "locale")
|
||||||
except:
|
except:
|
||||||
|
@ -148,156 +176,232 @@ def guildLocaleGet(guild):
|
||||||
else:
|
else:
|
||||||
return locale
|
return locale
|
||||||
|
|
||||||
def getMsg(string, guild=None):
|
|
||||||
global path
|
def getMsg(string: str, guild: Union[Guild, None] = None) -> str:
|
||||||
config = loadJson("config.json")
|
|
||||||
try:
|
try:
|
||||||
locale = loadJson(f'{path}/locale/{guildLocaleGet(guild)}.json')
|
locale = loadJson(f"locale/{guildLocaleGet(guild)}.json")
|
||||||
return locale["messages"][string]
|
return locale["messages"][string]
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
appendLog(f"Could not get locale string named {string} due to exception {exp}", guild)
|
appendLog(
|
||||||
|
f"Could not get locale string named {string} due to exception {exp}", guild
|
||||||
|
)
|
||||||
return string
|
return string
|
||||||
|
|
||||||
def makeEmbed(title="", description="", footer="", color=0xffffff):
|
|
||||||
embed=discord.Embed(title=title, description=description, color=color)
|
def makeEmbed(title="", description="", footer="", color=0xFFFFFF) -> Embed:
|
||||||
|
embed = Embed(title=title, description=description, color=color)
|
||||||
if footer is not None:
|
if footer is not None:
|
||||||
embed.set_footer(text=footer)
|
embed.set_footer(text=footer)
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
def channelExists(number, guild, type="Any"):
|
|
||||||
|
def channelExists(
|
||||||
|
number: int, guild: Guild, type: Literal["Any", "Text", "Voice"] = "Any"
|
||||||
|
) -> bool:
|
||||||
global debug
|
global debug
|
||||||
if number == None:
|
if number == None:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
if type == "Voice":
|
if type == "Voice":
|
||||||
selected_channel = discord.utils.get(guild.channels, id=number)
|
selected_channel = utils.get(guild.channels, id=number)
|
||||||
if isinstance(selected_channel, discord.VoiceChannel):
|
if isinstance(selected_channel, VoiceChannel):
|
||||||
return True
|
return True
|
||||||
elif type == "Text":
|
elif type == "Text":
|
||||||
selected_channel = discord.utils.get(guild.channels, id=number)
|
selected_channel = utils.get(guild.channels, id=number)
|
||||||
if isinstance(selected_channel, discord.TextChannel):
|
if isinstance(selected_channel, TextChannel):
|
||||||
return True
|
return True
|
||||||
elif type == "Any":
|
elif type == "Any":
|
||||||
selected_channel = discord.utils.get(guild.channels, id=number)
|
selected_channel = utils.get(guild.channels, id=number)
|
||||||
return True
|
return True
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
if debug:
|
if debug:
|
||||||
appendLog(f"Channel ID {str(number)} is not a channel due to {exp}")
|
appendLog(f"Channel ID {str(number)} is not a channel due to {exp}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def channelGetName(number, guild):
|
|
||||||
|
def channelGetName(number: int, guild: Guild):
|
||||||
global debug
|
global debug
|
||||||
try:
|
try:
|
||||||
selected_channel = discord.utils.get(guild.channels, id=number)
|
selected_channel = utils.get(guild.channels, id=number)
|
||||||
return selected_channel.name
|
return selected_channel.name
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
if debug:
|
if debug:
|
||||||
appendLog(f"Channel ID {str(number)} is not a channel due to {exp}")
|
appendLog(f"Channel ID {str(number)} is not a channel due to {exp}")
|
||||||
return "Channel doesn't exist"
|
return "Channel doesn't exist"
|
||||||
|
|
||||||
def isUserVoice(vc):
|
|
||||||
global path
|
def isUserVoice(vc: VoiceChannel) -> bool:
|
||||||
try:
|
try:
|
||||||
channels_list = os.listdir(f"{path}/guilds/{str(vc.guild.id)}/channels/")
|
channels_list = listdir(f"guilds/{str(vc.guild.id)}/channels/")
|
||||||
if f"{str(vc.id)}.json" in channels_list:
|
if f"{str(vc.id)}.json" in channels_list:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def removeUserVoice(vc):
|
|
||||||
global path
|
async def removeUserVoice(vc: VoiceChannel) -> None:
|
||||||
global debug
|
global debug
|
||||||
channels_list = os.listdir(f"{path}/guilds/{str(vc.guild.id)}/channels/")
|
channels_list = listdir(f"guilds/{str(vc.guild.id)}/channels/")
|
||||||
if f"{vc.id}.json" in channels_list:
|
if f"{vc.id}.json" in channels_list:
|
||||||
vc_file = f"{path}/guilds/{str(vc.guild.id)}/channels/{str(vc.id)}.json"
|
vc_file = f"guilds/{str(vc.guild.id)}/channels/{str(vc.id)}.json"
|
||||||
vc_conf = loadJson(vc_file)
|
vc_conf = loadJson(vc_file)
|
||||||
|
|
||||||
|
needed_channel = utils.get(vc.guild.channels, id=vc.id)
|
||||||
|
if loadJson("config.json")["enable_nomic"]:
|
||||||
|
nomic_channel = utils.get(vc.guild.channels, id=vc_conf["nomic"])
|
||||||
|
|
||||||
|
remove(vc_file)
|
||||||
|
|
||||||
needed_channel = discord.utils.get(vc.guild.channels, id=vc.id)
|
if needed_channel is None:
|
||||||
nomic_channel = discord.utils.get(vc.guild.channels, id=vc_conf["nomic"])
|
appendLog(
|
||||||
|
f"Removed voice channel '{needed_channel}' of user with id {str(vc_conf['ownerid'])}",
|
||||||
os.remove(vc_file)
|
guild=vc.guild,
|
||||||
|
)
|
||||||
await needed_channel.delete()
|
|
||||||
if debug:
|
|
||||||
appendLog(f"Removed voice channel '{needed_channel}' ({str(needed_channel.id)}) of user with id {str(vc_conf['ownerid'])}", guild=vc.guild)
|
|
||||||
else:
|
else:
|
||||||
appendLog(f"Removed voice channel '{needed_channel}' of user with id {str(vc_conf['ownerid'])}", guild=vc.guild)
|
await needed_channel.delete()
|
||||||
await nomic_channel.delete()
|
|
||||||
if debug:
|
if debug:
|
||||||
appendLog(f"Removed nomic channel {nomic_channel} ({str(nomic_channel.id)}) of channel with id {str(needed_channel.id)}", guild=vc.guild)
|
appendLog(
|
||||||
else:
|
f"Removed voice channel '{needed_channel}' ({str(needed_channel.id)}) of user with id {str(vc_conf['ownerid'])}",
|
||||||
appendLog(f"Removed nomic channel '{nomic_channel}' of channel with id {str(needed_channel.id)}", guild=vc.guild)
|
guild=vc.guild,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
appendLog(
|
||||||
|
f"Removed voice channel '{needed_channel}' of user with id {str(vc_conf['ownerid'])}",
|
||||||
|
guild=vc.guild,
|
||||||
|
)
|
||||||
|
|
||||||
|
if loadJson("config.json")["enable_nomic"]:
|
||||||
|
if nomic_channel is None:
|
||||||
|
appendLog(
|
||||||
|
f"Removed nomic channel '{nomic_channel}' of channel with id {str(needed_channel.id)}",
|
||||||
|
guild=vc.guild,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await nomic_channel.delete()
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
appendLog(
|
||||||
|
f"Removed nomic channel '{nomic_channel}' ({str(nomic_channel.id)}) of channel with id {str(needed_channel.id)}",
|
||||||
|
guild=vc.guild,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
appendLog(
|
||||||
|
f"Removed nomic channel '{nomic_channel}' of channel with id {str(needed_channel.id)}",
|
||||||
|
guild=vc.guild,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
async def createUserVoice(vc, category, member):
|
|
||||||
global path
|
async def createUserVoice(
|
||||||
|
vc: VoiceChannel, category: CategoryChannel, member: Member
|
||||||
|
) -> VoiceChannel:
|
||||||
global debug
|
global debug
|
||||||
chan = {}
|
chan = {}
|
||||||
overwrites_channel = {
|
overwrites_channel = {
|
||||||
vc.guild.default_role: discord.PermissionOverwrite(view_channel=True),
|
vc.guild.default_role: PermissionOverwrite(view_channel=True),
|
||||||
vc.guild.me: discord.PermissionOverwrite(read_messages=True, view_channel=True, manage_channels=True),
|
vc.guild.me: PermissionOverwrite(
|
||||||
member: discord.PermissionOverwrite(read_messages=True, view_channel=True, manage_channels=True)
|
read_messages=True, view_channel=True, manage_channels=True
|
||||||
|
),
|
||||||
|
member: PermissionOverwrite(
|
||||||
|
read_messages=True, view_channel=True, manage_channels=True
|
||||||
|
),
|
||||||
}
|
}
|
||||||
overwrites_nomic = {
|
overwrites_nomic = {
|
||||||
vc.guild.default_role: discord.PermissionOverwrite(view_channel=False, read_messages=False),
|
vc.guild.default_role: PermissionOverwrite(
|
||||||
vc.guild.me: discord.PermissionOverwrite(read_messages=True, view_channel=True, manage_channels=True),
|
view_channel=False, read_messages=False
|
||||||
member: discord.PermissionOverwrite(read_messages=True, view_channel=True, manage_channels=True)
|
),
|
||||||
|
vc.guild.me: PermissionOverwrite(
|
||||||
|
read_messages=True, view_channel=True, manage_channels=True
|
||||||
|
),
|
||||||
|
member: PermissionOverwrite(
|
||||||
|
read_messages=True, view_channel=True, manage_channels=True
|
||||||
|
),
|
||||||
}
|
}
|
||||||
created_channel = await vc.guild.create_voice_channel(getMsg("name_voice", vc.guild).format(member.name), category=category, overwrites=overwrites_channel)
|
created_channel = await vc.guild.create_voice_channel(
|
||||||
|
getMsg("name_voice", vc.guild).format(member.name),
|
||||||
|
category=category,
|
||||||
|
overwrites=overwrites_channel,
|
||||||
|
)
|
||||||
if debug:
|
if debug:
|
||||||
appendLog(f"Created voice channel '{created_channel}' ({str(created_channel.id)}) for user {member} ({str(member.id)})", guild=vc.guild)
|
appendLog(
|
||||||
|
f"Created voice channel '{created_channel}' ({str(created_channel.id)}) for user {member} ({str(member.id)})",
|
||||||
|
guild=vc.guild,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
appendLog(f"Created voice channel '{created_channel}' for user {member}", guild=vc.guild)
|
appendLog(
|
||||||
if not os.path.isdir(f"{path}/guilds/{str(created_channel.guild.id)}/channels"):
|
f"Created voice channel '{created_channel}' for user {member}",
|
||||||
os.mkdir(f"{path}/guilds/{str(created_channel.guild.id)}/channels")
|
guild=vc.guild,
|
||||||
vc_file = f"{path}/guilds/{str(created_channel.guild.id)}/channels/{str(created_channel.id)}.json"
|
)
|
||||||
|
if not path.isdir(f"guilds/{str(created_channel.guild.id)}/channels"):
|
||||||
|
makedirs(f"guilds/{str(created_channel.guild.id)}/channels", exist_ok=True)
|
||||||
|
vc_file = f"guilds/{str(created_channel.guild.id)}/channels/{str(created_channel.id)}.json"
|
||||||
chan["ownerid"] = member.id
|
chan["ownerid"] = member.id
|
||||||
saveJson(chan, vc_file)
|
saveJson(chan, vc_file)
|
||||||
nomic_channel = await vc.guild.create_text_channel(getMsg("name_nomic", vc.guild).format(created_channel.id), category=category, overwrites=overwrites_nomic, topic=getMsg("description_nomic", vc.guild).format(str(created_channel.id)))
|
if loadJson("config.json")["enable_nomic"]:
|
||||||
if debug:
|
nomic_channel = await vc.guild.create_text_channel(
|
||||||
appendLog(f"Created nomic channel '{nomic_channel}' ({str(nomic_channel.id)}) for channel '{created_channel}' ({str(created_channel.id)})", guild=vc.guild)
|
getMsg("name_nomic", vc.guild).format(created_channel.id),
|
||||||
else:
|
category=category,
|
||||||
appendLog(f"Created nomic channel '{nomic_channel}' for channel '{created_channel}'", guild=vc.guild)
|
overwrites=overwrites_nomic,
|
||||||
chan["nomic"] = nomic_channel.id
|
topic=getMsg("description_nomic", vc.guild).format(str(created_channel.id)),
|
||||||
saveJson(chan, vc_file)
|
)
|
||||||
|
if debug:
|
||||||
|
appendLog(
|
||||||
|
f"Created nomic channel '{nomic_channel}' ({str(nomic_channel.id)}) for channel '{created_channel}' ({str(created_channel.id)})",
|
||||||
|
guild=vc.guild,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
appendLog(
|
||||||
|
f"Created nomic channel '{nomic_channel}' for channel '{created_channel}'",
|
||||||
|
guild=vc.guild,
|
||||||
|
)
|
||||||
|
chan["nomic"] = nomic_channel.id
|
||||||
|
saveJson(chan, vc_file)
|
||||||
return created_channel
|
return created_channel
|
||||||
|
|
||||||
def isVoiceOfUser(vc, member):
|
|
||||||
global path
|
def isVoiceOfUser(vc: VoiceChannel, member: Member) -> bool:
|
||||||
vc_file = f"{path}/guilds/{str(vc.guild.id)}/channels/{str(vc.id)}.json"
|
vc_file = f"guilds/{str(vc.guild.id)}/channels/{str(vc.id)}.json"
|
||||||
vc_conf = loadJson(vc_file)
|
vc_conf = loadJson(vc_file)
|
||||||
if vc_conf["ownerid"] == member.id:
|
if vc_conf["ownerid"] == member.id:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def changeNomicPerms(mode, vc, member):
|
|
||||||
global path
|
|
||||||
vc_file = f"{path}/guilds/{str(vc.guild.id)}/channels/{str(vc.id)}.json"
|
|
||||||
vc_conf = loadJson(vc_file)
|
|
||||||
nomic_channel = discord.utils.get(vc.guild.channels, id=vc_conf["nomic"])
|
|
||||||
if mode == "deny":
|
|
||||||
await nomic_channel.set_permissions(member, view_channel=False)
|
|
||||||
else:
|
|
||||||
await nomic_channel.set_permissions(member, view_channel=True)
|
|
||||||
|
|
||||||
async def clearTrash(client):
|
async def changeNomicPerms(
|
||||||
global path
|
mode: Literal["deny", "allow"], vc: VoiceChannel, member: Member
|
||||||
if not os.path.isdir(f"{path}/guilds/"):
|
) -> None:
|
||||||
os.mkdir(f"{path}/guilds")
|
vc_file = f"guilds/{str(vc.guild.id)}/channels/{str(vc.id)}.json"
|
||||||
guilds_list = os.listdir(f"{path}/guilds/")
|
vc_conf = loadJson(vc_file)
|
||||||
|
if loadJson("config.json")["enable_nomic"]:
|
||||||
|
nomic_channel = utils.get(vc.guild.channels, id=vc_conf["nomic"])
|
||||||
|
if mode == "deny":
|
||||||
|
await nomic_channel.set_permissions(member, view_channel=False)
|
||||||
|
else:
|
||||||
|
await nomic_channel.set_permissions(member, view_channel=True)
|
||||||
|
|
||||||
|
|
||||||
|
async def clearTrash(client: Client):
|
||||||
|
if not path.isdir(f"guilds/"):
|
||||||
|
makedirs(f"guilds", exist_ok=True)
|
||||||
|
guilds_list = listdir(f"guilds/")
|
||||||
for guild in guilds_list:
|
for guild in guilds_list:
|
||||||
guild_object = client.get_guild(int(guild))
|
guild_object = client.get_guild(int(guild))
|
||||||
if os.path.isdir(f"{path}/guilds/{guild}/channels"):
|
if path.isdir(f"guilds/{guild}/channels"):
|
||||||
channels_list = os.listdir(f"{path}/guilds/{guild}/channels/")
|
channels_list = listdir(f"guilds/{guild}/channels/")
|
||||||
for channel in channels_list:
|
for channel in channels_list:
|
||||||
channel_id = channel[:-5]
|
channel_id = channel[:-5]
|
||||||
try:
|
try:
|
||||||
selected_channel = discord.utils.get(guild_object.voice_channels, id=int(channel_id))
|
selected_channel = utils.get(
|
||||||
channel_owner = loadJson(f"{path}/guilds/{guild}/channels/{channel}")["ownerid"]
|
guild_object.voice_channels, id=int(channel_id)
|
||||||
|
)
|
||||||
|
channel_owner = loadJson(f"guilds/{guild}/channels/{channel}")[
|
||||||
|
"ownerid"
|
||||||
|
]
|
||||||
remove_channel = True
|
remove_channel = True
|
||||||
for member in selected_channel.members:
|
for member in selected_channel.members:
|
||||||
if member.id == channel_owner:
|
if member.id == channel_owner:
|
||||||
|
@ -305,79 +409,101 @@ async def clearTrash(client):
|
||||||
if remove_channel:
|
if remove_channel:
|
||||||
await removeUserVoice(selected_channel)
|
await removeUserVoice(selected_channel)
|
||||||
except:
|
except:
|
||||||
os.remove(f"{path}/guilds/{guild}/channels/{channel_id}.json")
|
remove(f"guilds/{guild}/channels/{channel_id}.json")
|
||||||
|
|
||||||
#async def autoClearTrash(client):
|
|
||||||
# execute clearTrash every 120 seconds
|
|
||||||
|
|
||||||
def getHelpMessage(message, version, prefix=loadJson("config.json")["bot_prefix"]):
|
# async def autoClearTrash(client):
|
||||||
|
# execute clearTrash every 120 seconds
|
||||||
#channelExists(number, guild, type="Voice")
|
|
||||||
|
|
||||||
|
def getHelpMessage(ctx: ApplicationContext, version: float) -> Embed:
|
||||||
|
# channelExists(number, guild, type="Voice")
|
||||||
|
|
||||||
config = loadJson("config.json")
|
config = loadJson("config.json")
|
||||||
|
|
||||||
if message.guild is not None:
|
|
||||||
if channelExists(guildConfGet(message.guild, 'channel'), message.guild, type="Voice"):
|
|
||||||
desc_channel = getMsg("help_channel_set", guild=message.guild).format(channelGetName(guildConfGet(message.guild, 'channel'), message.guild))
|
|
||||||
else:
|
|
||||||
desc_channel = getMsg("help_channel_none", guild=message.guild)
|
|
||||||
|
|
||||||
if channelExists(guildConfGet(message.guild, 'category'), message.guild, type="Any"):
|
|
||||||
desc_category = getMsg("help_category_set", guild=message.guild).format(channelGetName(guildConfGet(message.guild, 'category'), message.guild))
|
|
||||||
else:
|
|
||||||
desc_category = getMsg("help_category_none", guild=message.guild)
|
|
||||||
|
|
||||||
desc_prefix = getMsg("help_prefix", guild=message.guild).format(prefix)
|
|
||||||
desc_locale = getMsg("help_locale", guild=message.guild).format(getMsg("locale_name", message.guild))
|
|
||||||
|
|
||||||
description = "\n".join([desc_prefix, desc_locale, desc_channel, desc_category])
|
if ctx.guild is not None:
|
||||||
|
if channelExists(guildConfGet(ctx.guild, "channel"), ctx.guild, type="Voice"):
|
||||||
|
desc_channel = getMsg("help_channel_set", guild=ctx.guild).format(
|
||||||
|
channelGetName(guildConfGet(ctx.guild, "channel"), ctx.guild)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
desc_channel = getMsg("help_channel_none", guild=ctx.guild)
|
||||||
|
|
||||||
embed=discord.Embed(title=getMsg("help_title", message.guild), description=description, color=strToColor(config["color_default"]))
|
if channelExists(guildConfGet(ctx.guild, "category"), ctx.guild, type="Any"):
|
||||||
|
desc_category = getMsg("help_category_set", guild=ctx.guild).format(
|
||||||
|
channelGetName(guildConfGet(ctx.guild, "category"), ctx.guild)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
desc_category = getMsg("help_category_none", guild=ctx.guild)
|
||||||
|
|
||||||
|
desc_locale = getMsg("help_locale", guild=ctx.guild).format(
|
||||||
|
getMsg("locale_name", ctx.guild)
|
||||||
|
)
|
||||||
|
|
||||||
|
description = "\n".join([desc_locale, desc_channel, desc_category])
|
||||||
|
|
||||||
|
embed = Embed(
|
||||||
|
title=getMsg("help_title", ctx.guild),
|
||||||
|
description=description,
|
||||||
|
color=strToColor(config["color_default"]),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
embed=discord.Embed(title=getMsg("help_title_dm", message.guild), color=strToColor(config["color_default"]))
|
embed = Embed(
|
||||||
|
title=getMsg("help_title_dm", ctx.guild),
|
||||||
embed.set_author(name=f'{config["bot_name"]} v{str(version)}', url=config["bot_site"], icon_url=config["bot_icon"])
|
color=strToColor(config["color_default"]),
|
||||||
|
)
|
||||||
if message.author.id == config["owner"]:
|
|
||||||
embed.add_field(name=f"{prefix}shutdown", value=getMsg("help_cmd_shutdown", message.guild), inline=False)
|
embed.set_author(
|
||||||
|
name=f'{config["bot_name"]} v{str(version)}',
|
||||||
embed.add_field(name=f"{prefix}channel ID", value=getMsg("help_cmd_channel", message.guild), inline=False)
|
url=config["bot_site"],
|
||||||
embed.add_field(name=f"{prefix}category ID", value=getMsg("help_cmd_category", message.guild), inline=False)
|
icon_url=config["bot_icon"],
|
||||||
embed.add_field(name=f"{prefix}prefix SYMBOL", value=getMsg("help_cmd_prefix", message.guild), inline=False)
|
)
|
||||||
embed.add_field(name=f"{prefix}locale LOCALE", value=getMsg("help_cmd_locale", message.guild), inline=False)
|
|
||||||
|
if ctx.author.id == config["owner"]:
|
||||||
if message.guild is None:
|
embed.add_field(
|
||||||
embed.set_footer(text=getMsg("help_server", message.guild))
|
name=f"/shutdown",
|
||||||
|
value=getMsg("help_cmd_shutdown", ctx.guild),
|
||||||
|
inline=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
embed.add_field(
|
||||||
|
name=f"/channel set", value=getMsg("help_cmd_channel", ctx.guild), inline=False
|
||||||
|
)
|
||||||
|
embed.add_field(
|
||||||
|
name=f"/category set",
|
||||||
|
value=getMsg("help_cmd_category", ctx.guild),
|
||||||
|
inline=False,
|
||||||
|
)
|
||||||
|
embed.add_field(
|
||||||
|
name=f"/locale set", value=getMsg("help_cmd_locale", ctx.guild), inline=False
|
||||||
|
)
|
||||||
|
|
||||||
|
if ctx.guild is None:
|
||||||
|
embed.set_footer(text=getMsg("help_server", ctx.guild))
|
||||||
else:
|
else:
|
||||||
embed.set_footer(text=getMsg("help_notice_id", message.guild))
|
embed.set_footer(text=getMsg("help_notice_id", ctx.guild))
|
||||||
|
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
async def guildConfigured(guild):
|
|
||||||
|
|
||||||
|
async def guildConfigured(guild: Guild) -> str:
|
||||||
output = {}
|
output = {}
|
||||||
config = loadJson("config.json")
|
config = loadJson("config.json")
|
||||||
|
|
||||||
for kind in ["channel", "category", "prefix"]:
|
for kind in ["channel", "category"]:
|
||||||
if guildConfGet(guild, kind) is not None:
|
if guildConfGet(guild, kind) is not None:
|
||||||
try:
|
try:
|
||||||
if kind == "channel":
|
guild_object = utils.get(guild.categories, id=guildConfGet(guild, kind))
|
||||||
guild_object = discord.utils.get(guild.channels, id=guildConfGet(guild, kind))
|
output[kind] = getMsg("configured_" + kind, guild).format(
|
||||||
output[kind] = getMsg("configured_"+kind, guild).format(guild_object.name)
|
guild_object.name
|
||||||
elif kind == "category":
|
)
|
||||||
guild_object = discord.utils.get(guild.categories, id=guildConfGet(guild, kind))
|
|
||||||
output[kind] = getMsg("configured_"+kind, guild).format(guild_object.name)
|
|
||||||
elif kind == "prefix":
|
|
||||||
output[kind] = getMsg("info_prefix", guild).format(guildConfGet(guild, kind))
|
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
if kind == "prefix":
|
output[kind] = getMsg("unconfigured_" + kind, guild)
|
||||||
output[kind] = getMsg("info_prefix", guild).format(config["bot_prefix"])
|
|
||||||
else:
|
|
||||||
output[kind] = getMsg("unconfigured_"+kind, guild)
|
|
||||||
else:
|
else:
|
||||||
if kind == "prefix":
|
output[kind] = getMsg("unconfigured_" + kind, guild)
|
||||||
output[kind] = getMsg("info_prefix", guild).format(config["bot_prefix"])
|
|
||||||
else:
|
|
||||||
output[kind] = getMsg("unconfigured_"+kind, guild)
|
|
||||||
|
|
||||||
return getMsg("server_config", guild).format(output["prefix"], getMsg("info_locale", guild).format(getMsg("locale_name", guild)), output["channel"], output["category"])
|
return getMsg("server_config", guild).format(
|
||||||
|
getMsg("info_locale", guild).format(getMsg("locale_name", guild)),
|
||||||
|
output["channel"],
|
||||||
|
output["category"],
|
||||||
|
)
|
||||||
|
|
|
@ -9,40 +9,31 @@
|
||||||
"set_channel_description": "Voice channel `{0}` has been set as a parent.",
|
"set_channel_description": "Voice channel `{0}` has been set as a parent.",
|
||||||
"set_category_title": "☑ Parent category set",
|
"set_category_title": "☑ Parent category set",
|
||||||
"set_category_description": "Category `{0}` has been set as the parent category.",
|
"set_category_description": "Category `{0}` has been set as the parent category.",
|
||||||
"set_prefix_title": "☑ Command prefix set",
|
|
||||||
"set_prefix_description": "On this server, all commands are now prefixed with `{0}`",
|
|
||||||
"set_locale_title": "☑ Bot language set",
|
"set_locale_title": "☑ Bot language set",
|
||||||
"set_locale_description": "This server is now using `{0}`",
|
"set_locale_description": "This server is now using `{0}`",
|
||||||
"reset_channel_title": "☑ Parent channel reset",
|
"reset_channel_title": "☑ Parent channel reset",
|
||||||
"reset_channel_description": "Use `{0}channel CHANNELID` to select a new channel",
|
"reset_channel_description": "Use `/channel set` to select a new channel",
|
||||||
"reset_category_title": "☑ Parent category reset",
|
"reset_category_title": "☑ Parent category reset",
|
||||||
"reset_category_description": "Use `{0}category ID-CATEGORY` to select a new category",
|
"reset_category_description": "Use `/category set` to select a new category",
|
||||||
"reset_prefix_title": "☑ Command Prefix Reset",
|
|
||||||
"reset_prefix_description": "The default prefix `{0}` is now used.\nUse `{1}prefix CHAR` to select a new one",
|
|
||||||
"reset_locale_title": "☑ Bot language reset",
|
"reset_locale_title": "☑ Bot language reset",
|
||||||
"reset_locale_description": "The default locale `{0}` is now used.\nUse `{1}locale LANGUAGE` to select a different one",
|
"reset_locale_description": "The default locale `{0}` is now used.\nUse `/locale set` to select a different one",
|
||||||
"error_channel_title": "🚫 Error installing channel",
|
"error_channel_title": "🚫 Error installing channel",
|
||||||
"error_channel_description": "Correct Usage: `{0}channel CHANNELID`",
|
"error_channel_description": "Correct Usage: `/channel set`",
|
||||||
"error_category_title": "🚫 Error setting category",
|
"error_category_title": "🚫 Error setting category",
|
||||||
"error_category_description": "Correct Usage: `{0}category CATEGORY-ID`",
|
"error_category_description": "Correct Usage: `/category set`",
|
||||||
"error_prefix_title": "🚫 Error setting prefix",
|
|
||||||
"error_prefix_description": "Correct Usage: `{0}prefix SYMBOL`",
|
|
||||||
"error_locale_title": "🚫 Error installing language",
|
"error_locale_title": "🚫 Error installing language",
|
||||||
"error_locale_description": "Correct Usage: `{0}locale LANGUAGE`\nAvailable languages: {1}",
|
"error_locale_description": "Correct Usage: `/locale set`\nAvailable languages: {1}",
|
||||||
"hint_none_channel_title": "⚠ No parent channel set",
|
"hint_none_channel_title": "⚠ No parent channel set",
|
||||||
"hint_none_channel_description": "For the bot to work properly, you need to set the parent channel, by entering which the user can create his own private voice channel. Set the parent channel with the command `{0}channel CHANNEL-ID`",
|
"hint_none_channel_description": "For the bot to work properly, you need to set the parent channel, by entering which the user can create his own private voice channel. Set the parent channel with the command `/channel set`",
|
||||||
"hint_none_category_title": "⚠ No parent category set",
|
"hint_none_category_title": "⚠ No parent category set",
|
||||||
"hint_none_category_description": "For the bot to work properly, you need to set a parent category, within which a private channel will be created for the user. Set the parent category with the command `{0}category ID-CATEGORY`",
|
"hint_none_category_description": "For the bot to work properly, you need to set a parent category, within which a private channel will be created for the user. Set the parent category with the command `/category set`",
|
||||||
"hint_none_prefix_title": "⚠ No prefix set",
|
|
||||||
"hint_none_prefix_description": "This server uses the default `{0}`.\nTo change it use `{1}prefix CHAR`",
|
|
||||||
"hint_none_locale_title": "⚠ Bot language not set",
|
"hint_none_locale_title": "⚠ Bot language not set",
|
||||||
"hint_none_locale_description": "This server uses default `{0}`.\nTo change it use `{1}locale LANGUAGE`",
|
"hint_none_locale_description": "This server uses default `{0}`.\nTo change it use `/locale set`",
|
||||||
"error_text_channel_title": "🚫 Error installing channel",
|
"error_text_channel_title": "🚫 Error installing channel",
|
||||||
"error_text_channel_description": "The selected channel must be a voice channel.",
|
"error_text_channel_description": "The selected channel must be a voice channel.",
|
||||||
"help_title": "Server Information",
|
"help_title": "Server Information",
|
||||||
"help_title_dm": "Bot Commands",
|
"help_title_dm": "Bot Commands",
|
||||||
"help_server": "Commands must be run on the server",
|
"help_server": "Commands must be run on the server",
|
||||||
"help_prefix": "ℹ Command prefix: `{0}`",
|
|
||||||
"help_locale": "ℹ Server bot language: `{0}`",
|
"help_locale": "ℹ Server bot language: `{0}`",
|
||||||
"help_channel_set": "☑ Parent channel: `{0}`",
|
"help_channel_set": "☑ Parent channel: `{0}`",
|
||||||
"help_channel_none": "⚠ Parent channel not installed",
|
"help_channel_none": "⚠ Parent channel not installed",
|
||||||
|
@ -51,13 +42,14 @@
|
||||||
"help_cmd_shutdown": "Shut the bot down",
|
"help_cmd_shutdown": "Shut the bot down",
|
||||||
"help_cmd_channel": "Set parent channel\nMust be a voice channel",
|
"help_cmd_channel": "Set parent channel\nMust be a voice channel",
|
||||||
"help_cmd_category": "Set parent category",
|
"help_cmd_category": "Set parent category",
|
||||||
"help_cmd_prefix": "Set command prefix",
|
|
||||||
"help_cmd_locale": "Change bot language on server",
|
"help_cmd_locale": "Change bot language on server",
|
||||||
"help_notice_id": "Note that channel name ≠ channel ID",
|
"help_notice_id": "Note that channel name ≠ channel ID",
|
||||||
"help_notice_id_category": "Note that category name ≠ category ID",
|
"help_notice_id_category": "Note that category name ≠ category ID",
|
||||||
"forbidden_title": "🚫 Access Denied",
|
"forbidden_title": "🚫 Access Denied",
|
||||||
"forbidden_description": "You must have **Administrator** right to set up private channels",
|
"forbidden_description": "You must have **Administrator** right to set up private channels",
|
||||||
"dm_title": "🚫 Execution error",
|
"dm_title": "🚫 Execution error",
|
||||||
"dm_description": "Commands can only be executed while on the server"
|
"dm_description": "Commands can only be executed while on the server",
|
||||||
|
"admin_title": "🚫 Permission denied",
|
||||||
|
"admin_description": "You must be bot owner to perform this"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,63 +0,0 @@
|
||||||
{
|
|
||||||
"messages": {
|
|
||||||
"shutdown": "**{0}** Выключаюсь...",
|
|
||||||
"locale_name": "Русский",
|
|
||||||
"name_voice": "Канал {0}",
|
|
||||||
"name_nomic": "без-микро-{0}",
|
|
||||||
"description_nomic": "Текстовый канал для коммуникации без микрофона\nID голосовой комнаты: {0}",
|
|
||||||
"set_channel_title": "☑ Родительский канал установлен",
|
|
||||||
"set_channel_description": "Голосовой канал `{0}` был установлен как родительский.",
|
|
||||||
"set_category_title": "☑ Родительская категория установлена",
|
|
||||||
"set_category_description": "Категория `{0}` была установлена как родительская.",
|
|
||||||
"set_prefix_title": "☑ Префикс команд установлен",
|
|
||||||
"set_prefix_description": "На этом сервере префикс всех команд теперь `{0}`",
|
|
||||||
"set_locale_title": "☑ Язык бота установлен",
|
|
||||||
"set_locale_description": "На этом сервере теперь используется `{0}`",
|
|
||||||
"reset_channel_title": "☑ Родительский канал сброшен",
|
|
||||||
"reset_channel_description": "Для выбора нового канала используйте `{0}channel ID-КАНАЛА`",
|
|
||||||
"reset_category_title": "☑ Родительская категория сброшена",
|
|
||||||
"reset_category_description": "Для выбора новой категории используйте `{0}category ID-КАТЕГОРИИ`",
|
|
||||||
"reset_prefix_title": "☑ Префикс команд сброшен",
|
|
||||||
"reset_prefix_description": "Теперь используется стандартный префикс `{0}`.\nДля выбора нового используйте `{1}prefix СИМВОЛ`",
|
|
||||||
"reset_locale_title": "☑ Язык бота сброшен",
|
|
||||||
"reset_locale_description": "Теперь используется стандартный язык `{0}`.\nДля выбора другого используйте `{1}locale ЯЗЫК`",
|
|
||||||
"error_channel_title": "🚫 Ошибка установки канала",
|
|
||||||
"error_channel_description": "Правильное использование: `{0}channel ID-КАНАЛА`",
|
|
||||||
"error_category_title": "🚫 Ошибка установки категории",
|
|
||||||
"error_category_description": "Правильное использование: `{0}category ID-КАТЕГОРИИ`",
|
|
||||||
"error_prefix_title": "🚫 Ошибка установки префикса",
|
|
||||||
"error_prefix_description": "Правильное использование: `{0}prefix СИМВОЛ`",
|
|
||||||
"error_locale_title": "🚫 Ошибка установки языка",
|
|
||||||
"error_locale_description": "Правильное использование: `{0}locale ЯЗЫК`\nДоступные языки: {1}",
|
|
||||||
"hint_none_channel_title": "⚠ Родительский канал не задан",
|
|
||||||
"hint_none_channel_description": "Для правильной работы бота необходимо задать родительский канал, входя в который пользователь сможет создать свой приватный голосовой канал. Установите родительский канал командой `{0}channel ID-КАНАЛА`",
|
|
||||||
"hint_none_category_title": "⚠ Родительская категория не задана",
|
|
||||||
"hint_none_category_description": "Для правильной работы бота необходимо задать родительскую категорию, внутри которой для пользователя будет создан его приватный канал. Установите родительскую категорию командой `{0}category ID-КАТЕГОРИИ`",
|
|
||||||
"hint_none_prefix_title": "⚠ Префикс не задан",
|
|
||||||
"hint_none_prefix_description": "На этом сервере используется стандартный `{0}`.\nЧтобы сменить его используйте `{1}prefix СИМВОЛ`",
|
|
||||||
"hint_none_locale_title": "⚠ Язык бота не задан",
|
|
||||||
"hint_none_locale_description": "На этом сервере используется стандартный `{0}`.\nЧтобы сменить его используйте `{1}locale ЯЗЫК`",
|
|
||||||
"error_text_channel_title": "🚫 Ошибка установки канала",
|
|
||||||
"error_text_channel_description": "Выбранный канал должен быть голосовым.",
|
|
||||||
"help_title": "Информация о сервере",
|
|
||||||
"help_title_dm": "Команды бота",
|
|
||||||
"help_server": "Команды должны выполняться на сервере",
|
|
||||||
"help_prefix": "ℹ Префикс команд: `{0}`",
|
|
||||||
"help_locale": "ℹ Язык бота на сервере: `{0}`",
|
|
||||||
"help_channel_set": "☑ Родительский канал: `{0}`",
|
|
||||||
"help_channel_none": "⚠ Родительский канал не установлен",
|
|
||||||
"help_category_set": "☑ Родительская категория: `{0}`",
|
|
||||||
"help_category_none": "⚠ Родительская категория не установлена",
|
|
||||||
"help_cmd_shutdown": "Выключить бота",
|
|
||||||
"help_cmd_channel": "Установить родительский канал\nКанал должен быть голосовым",
|
|
||||||
"help_cmd_category": "Установить родительскую категорию",
|
|
||||||
"help_cmd_prefix": "Установить префикс команд",
|
|
||||||
"help_cmd_locale": "Сменить язык бота на сервере",
|
|
||||||
"help_notice_id": "Обратите внимание, что имя канала ≠ ID канала",
|
|
||||||
"help_notice_id_category": "Обратите внимание, что имя категории ≠ ID категории",
|
|
||||||
"forbidden_title": "🚫 Отказано в доступе",
|
|
||||||
"forbidden_description": "Для настройки приватных каналов нужно иметь право **Администратор**",
|
|
||||||
"dm_title": "🚫 Ошибка исполнения",
|
|
||||||
"dm_description": "Команды можно исполнять только находясь на сервере"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,60 +4,52 @@
|
||||||
"locale_name": "Українська",
|
"locale_name": "Українська",
|
||||||
"name_voice": "Канал {0}",
|
"name_voice": "Канал {0}",
|
||||||
"name_nomic": "без-мікро-{0}",
|
"name_nomic": "без-мікро-{0}",
|
||||||
"description_nomic": "Текстовий канал для комунікації без мікрофона\nID голосової кімнати: {0}",
|
"description_nomic": "Текстовий канал для комунікації без мікрофона\\nID голосової кімнати: {0}",
|
||||||
"set_channel_title": "☑ Твірний канал встановлено",
|
"set_channel_title": "☑ Твірний канал встановлено",
|
||||||
"set_channel_description": "Голосовий канал `{0}` був встановлений як твірний.",
|
"set_channel_description": "Голосовий канал `{0}` був встановлений як твірний.",
|
||||||
"set_category_title": "☑ Твірну категорію встановлено",
|
"set_category_title": "☑ Твірну категорію встановлено",
|
||||||
"set_category_description": "Категорія `{0}` була встановлена як твірна.",
|
"set_category_description": "Категорія `{0}` була встановлена як твірна.",
|
||||||
"set_prefix_title": "☑ Префікс команд встановлено",
|
|
||||||
"set_prefix_description": "На цьому сервері префікс усіх команд тепер `{0}`",
|
|
||||||
"set_locale_title": "☑ Мова бота встановлена",
|
"set_locale_title": "☑ Мова бота встановлена",
|
||||||
"set_locale_description": "На цьому сервері тепер використовується `{0}`",
|
"set_locale_description": "На цьому сервері тепер використовується `{0}`",
|
||||||
"reset_channel_title": "☑ Твірний канал скинутий",
|
"reset_channel_title": "☑ Твірний канал скинутий",
|
||||||
"reset_channel_description": "Для вибору нового каналу використовуйте `{0}channel ID-КАНАЛу`",
|
"reset_channel_description": "Для вибору нового каналу використовуйте `/channel set`",
|
||||||
"reset_category_title": "☑ Твірна категорія скинута",
|
"reset_category_title": "☑ Твірну категорію скинуто",
|
||||||
"reset_category_description": "Для вибору нової категорії використовуйте `{0}category ID-КАТЕГОРІЇ`",
|
"reset_category_description": "Використовуйте `/category set` для вибору нової категорії",
|
||||||
"reset_prefix_title": "☑ Префікс команд скинутий",
|
|
||||||
"reset_prefix_description": "Тепер використовується стандартний префікс `{0}`.\nДля вибору нового використовуйте `{1}prefix СИМВОЛ`",
|
|
||||||
"reset_locale_title": "☑ Мова бота скинута",
|
"reset_locale_title": "☑ Мова бота скинута",
|
||||||
"reset_locale_description": "Тепер використовується стандартна мова `{0}`.\nДля вибору іншого використовуйте `{1}locale МОВА`",
|
"reset_locale_description": "Тепер використовується стандартна мова `{0}`.\\nДля вибору іншого використовуйте `/locale set`",
|
||||||
"error_channel_title": "🚫 Помилка установки каналу",
|
"error_channel_title": "🚫 Помилка встановлення каналу",
|
||||||
"error_channel_description": "Правильне використання: `{0}channel ID-КАНАЛу`",
|
"error_channel_description": "Правильне використання: `/channel set`",
|
||||||
"error_category_title": "🚫 Помилка установки категорії",
|
"error_category_title": "🚫 Помилка налаштування категорії",
|
||||||
"error_category_description": "Правильне використання: `{0}category ID-КАТЕГОРІЇ`",
|
"error_category_description": "Правильне використання: `/category set`",
|
||||||
"error_prefix_title": "🚫 Помилка встановлення префіксу",
|
|
||||||
"error_prefix_description": "Правильне використання: `{0}prefix СИМВОЛ`",
|
|
||||||
"error_locale_title": "🚫 Помилка встановлення мови",
|
"error_locale_title": "🚫 Помилка встановлення мови",
|
||||||
"error_locale_description": "Правильне використання: `{0}locale МОВА`\nДоступні мови: {1}",
|
"error_locale_description": "Правильне використання: `/locale set`\\nДоступні мови: {1}",
|
||||||
"hint_none_channel_title": "⚠ Твірний канал не заданий",
|
"hint_none_channel_title": "⚠ Твірний канал не заданий",
|
||||||
"hint_none_channel_description": "Для правильної роботи робота необхідно задати твірний канал, входячи в який користувач зможе створити свій приватний голосовий канал. Встановіть твірний канал командою `{0}channel ID-КАНАЛУ",
|
"hint_none_channel_description": "Для правильної роботи робота необхідно задати твірний канал, входячи в який користувач зможе створити свій приватний голосовий канал. Встановіть твірний канал командою `/channel set`",
|
||||||
"hint_none_category_title": "⚠ Твірна категорія не задана",
|
"hint_none_category_title": "⚠ Твірна категорія не встановлена",
|
||||||
"hint_none_category_description": "Для правильної роботи робота необхідно задати твірну категорію, всередині якої для користувача буде створено його приватний канал. Встановіть твірну категорію командою `{0}category ID-КАТЕГОРІЇ`",
|
"hint_none_category_description": "Для правильної роботи робота необхідно задати твірну категорію, всередині якої для користувача буде створено його приватний канал. Встановіть твірну категорію командою `/category set`",
|
||||||
"hint_none_prefix_title": "⚠ Префікс не заданий",
|
"hint_none_locale_title": "⚠ Мова бота не встановлена",
|
||||||
"hint_none_prefix_description": "На цьому сервері використовується стандартний `{0}`.\nЩоб змінити його використовуйте `{1}prefix СИМВОЛ`",
|
"hint_none_locale_description": "На цьому сервері використовується стандартний `{0}`.\\nЩоб змінити його використовуйте `/locale set`",
|
||||||
"hint_none_locale_title": "⚠ Мова бота не задана",
|
"error_text_channel_title": "🚫 Помилка встановлення каналу",
|
||||||
"hint_none_locale_description": "На цьому сервері використовується стандартний `{0}`.\nЩоб змінити його використовуйте `{1}locale МОВА`",
|
"error_text_channel_description": "Обраний канал має бути голосовим каналом.",
|
||||||
"error_text_channel_title": "🚫 Помилка установки каналу",
|
|
||||||
"error_text_channel_description": "Вибраний канал повинен бути голосовим.",
|
|
||||||
"help_title": "Інформація про сервер",
|
"help_title": "Інформація про сервер",
|
||||||
"help_title_dm": "Команда бота",
|
"help_title_dm": "Команда бота",
|
||||||
"help_server": "Команди повинні виконуватись на сервері",
|
"help_server": "Команди слід запускати на сервері",
|
||||||
"help_prefix": "ℹ Префікс команд: `{0}`",
|
|
||||||
"help_locale": "ℹ Мова бота на сервері: `{0}`",
|
"help_locale": "ℹ Мова бота на сервері: `{0}`",
|
||||||
"help_channel_set": "☑ Твірний канал: `{0}`",
|
"help_channel_set": "☑ Твірний канал: `{0}`",
|
||||||
"help_channel_none": "⚠ Твірний канал не встановлено",
|
"help_channel_none": "⚠ Твірний канал не встановлено",
|
||||||
"help_category_set": "☑ Твірна категорія: `{0}`",
|
"help_category_set": "☑ Твірна категорія: `{0}`",
|
||||||
"help_category_none": "⚠ Твірна категорія не встановлена",
|
"help_category_none": "⚠ Твірна категорія не встановлена",
|
||||||
"help_cmd_shutdown": "Вимкнути бота",
|
"help_cmd_shutdown": "Вимкнути бота",
|
||||||
"help_cmd_channel": "Встановити твірний канал\nКанал повинен бути голосовим",
|
"help_cmd_channel": "Встановити твірний канал\\nКанал повинен бути голосовим",
|
||||||
"help_cmd_category": "Встановити твірну категорію",
|
"help_cmd_category": "Встановити твірну категорію",
|
||||||
"help_cmd_prefix": "Встановити префікс команд",
|
|
||||||
"help_cmd_locale": "Змінити мову бота на сервері",
|
"help_cmd_locale": "Змінити мову бота на сервері",
|
||||||
"help_notice_id": "Зверніть увагу, що ім'я каналу ≠ ID каналу",
|
"help_notice_id": "Зверніть увагу, що ім'я каналу ≠ ID каналу",
|
||||||
"help_notice_id_category": "Зверніть увагу, що ім'я категорії ≠ ID категорії",
|
"help_notice_id_category": "Зверніть увагу, що ім'я категорії ≠ ID категорії",
|
||||||
"forbidden_title": "🚫 Відмовлено у доступі",
|
"forbidden_title": "🚫 Немає прав доступу",
|
||||||
"forbidden_description": "Для налаштування приватних каналів потрібно мати право **Адміністратор**",
|
"forbidden_description": "Для налаштування приватних каналів потрібно мати право **Адміністратор**",
|
||||||
"dm_title": "🚫 Помилка виконання",
|
"dm_title": "🚫 Помилка виконання",
|
||||||
"dm_description": "Команди можна виконувати лише перебуваючи на сервері"
|
"dm_description": "Команди можна виконувати лише перебуваючи на сервері",
|
||||||
|
"admin_title": "🚫 Немає прав доступу",
|
||||||
|
"admin_description": "Треба бути адміністратором бота щоб зробити це"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
ujson==5.9.0
|
||||||
|
py-cord[speed]==2.5.0
|
|
@ -1 +1,2 @@
|
||||||
discord.py
|
py-cord==2.5.0
|
||||||
|
requests==2.31.0
|
389
yusarin.py
389
yusarin.py
|
@ -1,356 +1,75 @@
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import json
|
|
||||||
import shutil
|
|
||||||
import requests
|
|
||||||
import threading
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import discord
|
from discord import Activity, ActivityType, ApplicationContext, Bot, Intents
|
||||||
|
from requests import get
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
print(f"Module discord.py is not installed. Make sure to run 'pip install -r requirements.txt' before first start")
|
print(
|
||||||
sys.exit()
|
f"Dependencies not installed. Make sure to run 'pip install -r requirements.txt' before first start"
|
||||||
|
)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
from os import getpid, path
|
||||||
|
|
||||||
from functions import *
|
from functions import *
|
||||||
pid = os.getpid()
|
|
||||||
version = 1.4
|
|
||||||
|
|
||||||
if loadJson("config.json")["owner"] == "SET-OWNER-ID" or loadJson("config.json")["bot_token"] == "SET-BOT-TOKEN":
|
pid = getpid()
|
||||||
print(f"Bot is not correctly configured.\nMake sure you've set up owner id and bot token in {path}/config.json\nLearn more here: https://github.com/profitrollgame/YusarinBot")
|
version = 2.3
|
||||||
sys.exit()
|
|
||||||
|
if (
|
||||||
|
not path.exists("config.json")
|
||||||
|
or loadJson("config.json")["owner"] == "SET-OWNER-ID"
|
||||||
|
or loadJson("config.json")["bot_token"] == "SET-BOT-TOKEN"
|
||||||
|
):
|
||||||
|
print(
|
||||||
|
f"Bot is not correctly configured.\nMake sure you've set up owner id and bot token in 'config.json'\nLearn more here: https://git.end-play.xyz/profitroll/YusarinBot"
|
||||||
|
)
|
||||||
|
exit()
|
||||||
|
|
||||||
if loadJson("config.json")["check_for_updates"]:
|
if loadJson("config.json")["check_for_updates"]:
|
||||||
|
appendLog(f"Currently using YusarinBot v{str(version)}")
|
||||||
try:
|
try:
|
||||||
serv_ver = requests.get("https://www.end-play.xyz/yusarin/version.txt").text.replace('\n', '')
|
releases = get(
|
||||||
if float(serv_ver) > version:
|
"https://git.end-play.xyz/api/v1/repos/profitroll/YusarinBot/releases?draft=false&pre-release=false&page=1&limit=1"
|
||||||
appendLog(f"YusarinBot version {serv_ver} is available. Download new version here: https://github.com/profitrollgame/YusarinBot/releases/latest")
|
).json()
|
||||||
appendLog(f"Currently using YusarinBot v{str(version)}")
|
if float(releases[0]["tag_name"].replace("v", "")) > version:
|
||||||
|
appendLog(
|
||||||
|
f"YusarinBot version {releases[0]['tag_name']} is available. Download new version here: {releases[0]['html_url']}"
|
||||||
|
)
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
appendLog(f"Could not get YusarinBot cloud version due to {exp}. Currently using {str(version)}")
|
appendLog(
|
||||||
|
f"Could not get YusarinBot cloud version due to {exp}. Currently using {str(version)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
intents = Intents().all()
|
||||||
|
client = Bot(intents=intents)
|
||||||
|
|
||||||
|
from cogs.cogCategory import CogCategory
|
||||||
|
from cogs.cogChannel import CogChannel
|
||||||
|
from cogs.cogLocale import CogLocale
|
||||||
|
from cogs.cogUtility import CogUtility
|
||||||
|
|
||||||
|
|
||||||
|
@client.slash_command(name="help", description="Get information about this server")
|
||||||
|
async def help(ctx: ApplicationContext):
|
||||||
|
await ctx.respond(embed=getHelpMessage(ctx, version))
|
||||||
|
|
||||||
intents = discord.Intents().all()
|
|
||||||
client = discord.Client(intents=intents)
|
|
||||||
|
|
||||||
@client.event
|
@client.event
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
|
|
||||||
appendLog(f"Logged in as {client.user}")
|
appendLog(f"Logged in as {client.user}")
|
||||||
|
|
||||||
config = loadJson("config.json")
|
config = loadJson("config.json")
|
||||||
|
|
||||||
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=config["bot_activity"]))
|
await client.change_presence(
|
||||||
|
activity=Activity(type=ActivityType.listening, name=config["bot_activity"])
|
||||||
|
)
|
||||||
|
|
||||||
await clearTrash(client)
|
await clearTrash(client)
|
||||||
|
|
||||||
@client.event
|
|
||||||
async def on_guild_join(guild):
|
|
||||||
|
|
||||||
global path
|
|
||||||
|
|
||||||
os.mkdir(f"{path}/guilds/{str(guild.id)}")
|
|
||||||
os.mkdir(f"{path}/guilds/{str(guild.id)}/channels")
|
|
||||||
saveJson({}, f"{path}/guilds/{str(guild.id)}/config.json")
|
|
||||||
|
|
||||||
appendLog(f"Joined guild '{guild}' with id {str(guild.id)}")
|
|
||||||
|
|
||||||
@client.event
|
client.add_cog(CogCategory(client))
|
||||||
async def on_guild_remove(guild):
|
client.add_cog(CogChannel(client))
|
||||||
|
client.add_cog(CogLocale(client))
|
||||||
global path
|
client.add_cog(CogUtility(client))
|
||||||
|
|
||||||
try:
|
|
||||||
shutil.rmtree(f"{path}/guilds/{str(guild.id)}")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
appendLog(f"Left guild '{guild}' with id {str(guild.id)}")
|
|
||||||
|
|
||||||
@client.event
|
|
||||||
async def on_voice_state_update(member, before, after):
|
|
||||||
|
|
||||||
global debug
|
|
||||||
|
|
||||||
config = loadJson("config.json")
|
|
||||||
|
|
||||||
vc_from = before.channel
|
|
||||||
vc_to = after.channel
|
|
||||||
|
|
||||||
# If user left vc
|
|
||||||
if vc_to is None:
|
|
||||||
if isUserVoice(vc_from):
|
|
||||||
if isVoiceOfUser(vc_from, member):
|
|
||||||
await removeUserVoice(vc_from)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
await changeNomicPerms("deny", vc_from, member)
|
|
||||||
|
|
||||||
# If user joined vc
|
|
||||||
else:
|
|
||||||
if isUserVoice(vc_from):
|
|
||||||
if isVoiceOfUser(vc_from, member):
|
|
||||||
await removeUserVoice(vc_from)
|
|
||||||
else:
|
|
||||||
await changeNomicPerms("deny", vc_from, member)
|
|
||||||
if isUserVoice(vc_to):
|
|
||||||
await changeNomicPerms("allow", vc_to, member)
|
|
||||||
if vc_to.id == guildConfGet(vc_to.guild, "channel"):
|
|
||||||
if guildConfGet(vc_to.guild, "category") is not None:
|
|
||||||
voice_chan = await createUserVoice(vc_to, discord.utils.get(vc_to.guild.categories, id=guildConfGet(vc_to.guild, "category")), member)
|
|
||||||
try:
|
|
||||||
await member.move_to(voice_chan)
|
|
||||||
except:
|
|
||||||
await removeUserVoice(voice_chan)
|
|
||||||
else:
|
|
||||||
if debug:
|
|
||||||
appendLog(f"Category for guild {vc_to.guild} ({str(vc_to.guild.id)}) is not set", guild=vc_to.guild)
|
|
||||||
else:
|
|
||||||
appendLog(f"Category for guild {vc_to.guild} is not set", guild=vc_to.guild)
|
|
||||||
|
|
||||||
# ==========================================================================================
|
|
||||||
|
|
||||||
@client.event
|
|
||||||
async def on_message(message):
|
|
||||||
|
|
||||||
config = loadJson("config.json")
|
|
||||||
|
|
||||||
if message.guild is not None:
|
|
||||||
try:
|
|
||||||
prefix = guildConfGet(message.guild, "prefix")
|
|
||||||
if prefix is None:
|
|
||||||
prefix = config["bot_prefix"]
|
|
||||||
except Exception as exp:
|
|
||||||
print(exp)
|
|
||||||
prefix = config["bot_prefix"]
|
|
||||||
else:
|
|
||||||
prefix = config["bot_prefix"]
|
|
||||||
|
|
||||||
if message.author == client.user:
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
if message.content in [f"{prefix}reboot", f"{prefix}restart", f"{prefix}shutdown", f"{prefix}die"]:
|
|
||||||
|
|
||||||
gotCommand(message)
|
|
||||||
|
|
||||||
if message.author.id == config["owner"]:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(description=getMsg("shutdown", message.guild).format(message.author), color=strToColor(config["color_default"])), mention_author=False)
|
|
||||||
os.system(f"kill -9 {str(pid)}")
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
elif message.content.startswith(f"{prefix}channel"):
|
|
||||||
|
|
||||||
gotCommand(message)
|
|
||||||
|
|
||||||
fullcmd = message.content.split()
|
|
||||||
|
|
||||||
if message.guild is not None:
|
|
||||||
|
|
||||||
if message.author.guild_permissions.administrator:
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
if fullcmd[1] == "reset":
|
|
||||||
|
|
||||||
if guildConfGet(message.guild, "channel") is not None:
|
|
||||||
|
|
||||||
guildConfReset(message.guild, "channel")
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("reset_channel_title", message.guild), description=getMsg("reset_channel_description", message.guild).format(prefix), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("hint_none_channel_title", message.guild), description=getMsg("hint_none_channel_description", message.guild).format(prefix), color=strToColor(config["color_warn"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
selected_channel = discord.utils.get(message.guild.channels, id=int(fullcmd[1]))
|
|
||||||
|
|
||||||
if isinstance(selected_channel, discord.VoiceChannel):
|
|
||||||
|
|
||||||
guildConfSet(message.guild, "channel", int(fullcmd[1]))
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("set_channel_title", message.guild), description=getMsg("set_channel_description", message.guild).format(selected_channel.name), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
|
|
||||||
if guildConfGet(message.guild, "category") is None:
|
|
||||||
|
|
||||||
await message.channel.send(embed=makeEmbed(title=getMsg("hint_none_category_title", message.guild), description=getMsg("hint_none_category_description", message.guild).format(prefix), color=strToColor(config["color_warn"])))
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("error_text_channel_title", message.guild), description=getMsg("error_text_channel_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
except Exception as exp:
|
|
||||||
|
|
||||||
if debug:
|
|
||||||
print(exp)
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("error_channel_title", message.guild), description=getMsg("error_channel_description", message.guild).format(prefix), footer=getMsg("help_notice_id", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("forbidden_title", message.guild), description=getMsg("forbidden_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("dm_title", message.guild), description=getMsg("dm_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
elif message.content.startswith(f"{prefix}category"):
|
|
||||||
|
|
||||||
gotCommand(message)
|
|
||||||
|
|
||||||
fullcmd = message.content.split()
|
|
||||||
|
|
||||||
if message.guild is not None:
|
|
||||||
|
|
||||||
if message.author.guild_permissions.administrator:
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
if fullcmd[1] == "reset":
|
|
||||||
|
|
||||||
if guildConfGet(message.guild, "category") is not None:
|
|
||||||
|
|
||||||
guildConfReset(message.guild, "category")
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("reset_category_title", message.guild), description=getMsg("reset_category_description", message.guild).format(prefix), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("hint_none_category_title", message.guild), description=getMsg("hint_none_category_description", message.guild).format(prefix), color=strToColor(config["color_warn"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
selected_category = discord.utils.get(message.guild.channels, id=int(fullcmd[1]))
|
|
||||||
|
|
||||||
guildConfSet(message.guild, "category", int(fullcmd[1]))
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("set_category_title", message.guild), description=getMsg("set_category_description", message.guild).format(selected_category.name), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
|
|
||||||
if guildConfGet(message.guild, "channel") is None:
|
|
||||||
|
|
||||||
await message.channel.send(embed=makeEmbed(title=getMsg("hint_none_channel_title", message.guild), description=getMsg("hint_none_channel_description", message.guild).format(prefix), color=strToColor(config["color_warn"])))
|
|
||||||
|
|
||||||
except Exception as exp:
|
|
||||||
|
|
||||||
if debug:
|
|
||||||
print(exp)
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("error_category_title", message.guild), description=getMsg("error_category_description", message.guild).format(prefix), footer=getMsg("help_notice_id_category", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("forbidden_title", message.guild), description=getMsg("forbidden_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("dm_title", message.guild), description=getMsg("dm_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
elif message.content.startswith(f"{prefix}prefix"):
|
|
||||||
|
|
||||||
gotCommand(message)
|
|
||||||
|
|
||||||
fullcmd = message.content.split()
|
|
||||||
|
|
||||||
if message.guild is not None:
|
|
||||||
|
|
||||||
if message.author.guild_permissions.administrator:
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
if fullcmd[1] == "reset":
|
|
||||||
|
|
||||||
if guildConfGet(message.guild, "prefix") is not None:
|
|
||||||
|
|
||||||
guildConfReset(message.guild, "prefix")
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("reset_prefix_title", message.guild), description=getMsg("reset_prefix_description", message.guild).format(config["bot_prefix"], config["bot_prefix"]), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("hint_none_prefix_title", message.guild), description=getMsg("hint_none_prefix_description", message.guild).format(prefix, prefix), color=strToColor(config["color_warn"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
guildConfSet(message.guild, "prefix", fullcmd[1])
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("set_prefix_title", message.guild), description=getMsg("set_prefix_description", message.guild).format(fullcmd[1]), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
|
|
||||||
except:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("error_prefix_title", message.guild), description=getMsg("error_prefix_description", message.guild).format(prefix), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("forbidden_title", message.guild), description=getMsg("forbidden_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("dm_title", message.guild), description=getMsg("dm_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
elif message.content.startswith(f"{prefix}locale"):
|
|
||||||
|
|
||||||
gotCommand(message)
|
|
||||||
|
|
||||||
fullcmd = message.content.split()
|
|
||||||
|
|
||||||
if message.guild is not None:
|
|
||||||
|
|
||||||
if message.author.guild_permissions.administrator:
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
if fullcmd[1] == "reset":
|
|
||||||
|
|
||||||
if guildConfGet(message.guild, "locale") is not None:
|
|
||||||
|
|
||||||
guildConfReset(message.guild, "locale")
|
|
||||||
appendLog(f"Server's locale has been reset", message.guild)
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("reset_locale_title", message.guild), description=getMsg("reset_locale_description", message.guild).format(getMsg("locale_name", message.guild), prefix), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("hint_none_locale_title", message.guild), description=getMsg("hint_none_locale_description", message.guild).format(getMsg("locale_name", message.guild), prefix), color=strToColor(config["color_warn"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
for locale_file in os.listdir(f"{path}/locale/"):
|
|
||||||
if locale_file[:-5] == fullcmd[1]:
|
|
||||||
guildConfSet(message.guild, "locale", fullcmd[1])
|
|
||||||
appendLog(f"Server's locale is now set to {fullcmd[1]}", message.guild)
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("set_locale_title", message.guild), description=getMsg("set_locale_description", message.guild).format(getMsg("locale_name", message.guild)), color=strToColor(config["color_ok"])), mention_author=False)
|
|
||||||
return
|
|
||||||
|
|
||||||
locales = []
|
|
||||||
|
|
||||||
for locale_file in os.listdir(f"{path}/locale/"):
|
|
||||||
locales.append(f"`{locale_file[:-5]}`")
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("error_locale_title", message.guild), description=getMsg("error_locale_description", message.guild).format(prefix, ", ".join(locales)), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
except:
|
|
||||||
|
|
||||||
locales = []
|
|
||||||
|
|
||||||
for locale_file in os.listdir(f"{path}/locale/"):
|
|
||||||
locales.append(f"`{locale_file[:-5]}`")
|
|
||||||
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("error_locale_title", message.guild), description=getMsg("error_locale_description", message.guild).format(prefix, ", ".join(locales)), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("forbidden_title", message.guild), description=getMsg("forbidden_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
else:
|
|
||||||
await message.reply(embed=makeEmbed(title=getMsg("dm_title", message.guild), description=getMsg("dm_description", message.guild), color=strToColor(config["color_error"])), mention_author=False)
|
|
||||||
|
|
||||||
elif message.content.startswith(f"{prefix}help"):
|
|
||||||
|
|
||||||
gotCommand(message)
|
|
||||||
|
|
||||||
await message.reply(embed=getHelpMessage(message, version, prefix=prefix), mention_author=False)
|
|
||||||
|
|
||||||
#if loadJson("config.json")["auto_clear_trash"]:
|
|
||||||
# run func
|
|
||||||
|
|
||||||
appendLog(f"Trying to log in...")
|
appendLog(f"Trying to log in...")
|
||||||
|
|
||||||
client.run(loadJson("config.json")["bot_token"])
|
client.run(loadJson("config.json")["bot_token"])
|
||||||
|
|
Loading…
Reference in New Issue