mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 09:48:26 -04:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2d92424dd4 | ||
|
ffba03adbe | ||
|
76ebb87fb5 | ||
|
4a50c30c56 | ||
|
e70a91ae60 | ||
|
3470762b30 | ||
|
2cbb4ecd3d | ||
|
619bee811d | ||
|
a09be96200 | ||
|
81254ed5f6 | ||
|
d82e3bd444 | ||
|
9011646b02 | ||
|
2a1f45819d | ||
|
d2d0cb9e03 |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -4,7 +4,27 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## [3.0.5] - 20.09.2021
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed images not automatically reloading on startup if the keys don't exist
|
||||||
|
- Fixed `.logserver` - it should no longer throw an exception if you had no logsettings previously
|
||||||
|
|
||||||
|
## [3.0.4] - 16.09.2021
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Fully translated to Brazilian Portuguese 🎉
|
||||||
|
- Added `%server.boosters%` and `%server.boost_level%` placeholders
|
||||||
|
- Added `DmHelpTextKeywords` to `data/bot.yml`
|
||||||
|
- Bot now sends dm help text ONLY if the message contains one of the keywords specified
|
||||||
|
- If no keywords are specified, bot will reply to every DM (like before)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Possible fix for `.repeat` bug
|
||||||
|
- Slight adjustment for repeater logic
|
||||||
|
- Timer should no longer increase on some repeaters
|
||||||
|
- Repeaters should no longer have periods when they're missing from the list
|
||||||
|
- Fixed several commands which used error color for success confirmation messages
|
||||||
|
|
||||||
## [3.0.3] - 15.09.2021
|
## [3.0.3] - 15.09.2021
|
||||||
|
|
||||||
|
@@ -1,3 +1,35 @@
|
|||||||
# Setting up NadekoBot with Docker
|
# Setting up NadekoBot with Docker
|
||||||
|
|
||||||
Soon:tm:
|
# DO NOT USE YET - WORK IN PROGRESS
|
||||||
|
|
||||||
|
Upgrade from 2.x to v3 does not work because the file is mount readonly
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
```yml
|
||||||
|
version: "3.7"
|
||||||
|
services:
|
||||||
|
nadeko:
|
||||||
|
image: registry.gitlab.com/veovis/nadekobot:v3-docker
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
environment:
|
||||||
|
TZ: Europe/Paris
|
||||||
|
#NadekoBot_RedisOptions: redis,name=nadeko
|
||||||
|
#NadekoBot_ShardRunCommand: dotnet
|
||||||
|
#NadekoBot_ShardRunArguments: /app/NadekoBot.dll {0} {1}
|
||||||
|
volumes:
|
||||||
|
- /srv/nadeko/conf/creds.yml:/app/creds.yml:ro
|
||||||
|
- /srv/nadeko/data:/app/data
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:4-alpine
|
||||||
|
sysctls:
|
||||||
|
- net.core.somaxconn=511
|
||||||
|
command: redis-server --maxmemory 32M --maxmemory-policy volatile-lru
|
||||||
|
volumes:
|
||||||
|
- /srv/nadeko/redis-data:/data
|
||||||
|
```
|
||||||
|
### Updating
|
||||||
|
- `cd /srv/nadeko`
|
||||||
|
- `docker-compose pull`
|
||||||
|
- `docker-compose up -d`
|
||||||
|
@@ -16,12 +16,12 @@ Open Terminal (if you're on an installation with a window manager) and navigate
|
|||||||
4. Exit the installer in order to set up your `creds.yml`
|
4. Exit the installer in order to set up your `creds.yml`
|
||||||
5. Copy the creds.yml template `cp nadekobot/output/creds_example.yml nadekobot/output/creds.yml`
|
5. Copy the creds.yml template `cp nadekobot/output/creds_example.yml nadekobot/output/creds.yml`
|
||||||
6. Open `nadekobot/output/creds.yml` with your favorite text editor. We will use nano here
|
6. Open `nadekobot/output/creds.yml` with your favorite text editor. We will use nano here
|
||||||
- `nano nadekobot/output/creds.yml`
|
- `nano nadekobot/output/creds.yml`
|
||||||
7. [Enter your bot's token](../../creds-guide)
|
7. [Enter your bot's token](../../creds-guide)
|
||||||
- After you're done, you can close nano (and save the file) by inputting, in order
|
- After you're done, you can close nano (and save the file) by inputting, in order
|
||||||
- `CTRL` + `X`
|
- `CTRL` + `X`
|
||||||
- `Y`
|
- `Y`
|
||||||
- `Enter`
|
- `Enter`
|
||||||
8. Run the bot (type `3` and press enter)
|
8. Run the bot (type `3` and press enter)
|
||||||
|
|
||||||
##### Update Instructions
|
##### Update Instructions
|
||||||
@@ -37,51 +37,51 @@ Open Terminal (if you're on an installation with a window manager) and navigate
|
|||||||
##### Installation Instructions
|
##### Installation Instructions
|
||||||
|
|
||||||
1. Download the latest release from <https://gitlab.com/Kwoth/nadekobot/-/releases>
|
1. Download the latest release from <https://gitlab.com/Kwoth/nadekobot/-/releases>
|
||||||
- Look for the file called "X.XX.X-linux-x64-build.tar" (where X.XX.X is a series of numbers) and download it
|
- Look for the file called "X.XX.X-linux-x64-build.tar" (where X.XX.X is a series of numbers) and download it
|
||||||
2. Untar it
|
2. Untar it
|
||||||
- ⚠ Make sure that you change X.XX.X to the same series of numbers as in step 1!
|
- ⚠ Make sure that you change X.XX.X to the same series of numbers as in step 1!
|
||||||
- `tar xf X.XX.X-linux-x64-build.tar`
|
- `tar xf X.XX.X-linux-x64-build.tar`
|
||||||
3. Rename the `nadekobot-linux-x64` to `nadekobot`
|
3. Rename the `nadekobot-linux-x64` to `nadekobot`
|
||||||
- `mv nadekobot-linux-x64 nadekobot`
|
- `mv nadekobot-linux-x64 nadekobot`
|
||||||
4. Move into nadekobot directory and make NadekoBot executable
|
4. Move into nadekobot directory and make NadekoBot executable
|
||||||
- `cd nadekobot && chmod +x NadekoBot`
|
- `cd nadekobot && chmod +x NadekoBot`
|
||||||
5. Copy the creds.yml template
|
5. Copy the creds.yml template
|
||||||
- `cp creds_example.yml creds.yml`
|
- `cp creds_example.yml creds.yml`
|
||||||
6. Open `creds.yml` with your favorite text editor. We will use nano here
|
6. Open `creds.yml` with your favorite text editor. We will use nano here
|
||||||
- `nano nadekobot/output/creds.yml`
|
- `nano nadekobot/output/creds.yml`
|
||||||
8. [Enter your bot's token](#creds-guide)
|
8. [Enter your bot's token](#creds-guide)
|
||||||
- After you're done, you can close nano (and save the file) by inputting, in order
|
- After you're done, you can close nano (and save the file) by inputting, in order
|
||||||
- `CTRL` + `X`
|
- `CTRL` + `X`
|
||||||
- `Y`
|
- `Y`
|
||||||
- `Enter`
|
- `Enter`
|
||||||
9. Run the bot
|
9. Run the bot
|
||||||
- `./NadekoBot`
|
- `./NadekoBot`
|
||||||
|
|
||||||
##### Update Instructions
|
##### Update Instructions
|
||||||
|
|
||||||
1. Stop the bot
|
1. Stop the bot
|
||||||
2. Download the latest release from <https://gitlab.com/Kwoth/nadekobot/-/releases>
|
2. Download the latest release from <https://gitlab.com/Kwoth/nadekobot/-/releases>
|
||||||
- Look for the file called "X.XX.X-linux-x64-build.tar" (where X.XX.X is a series of numbers) and download it
|
- Look for the file called "x.x.x-linux-x64-build.tar" (where `X.X.X` is a version, for example 3.0.4) and download it
|
||||||
3. Untar it
|
3. Untar it
|
||||||
- ⚠ Make sure that you change X.XX.X to the same series of numbers as in step 2!
|
- ⚠ Make sure that you change `X.X.X` to the same series of numbers as in step 2!
|
||||||
- `tar xf 2.99.8-linux-x64-build.tar`
|
- `tar xf x.x.x-linux-x64-build.tar`
|
||||||
4. Rename the old nadekobot directory to nadekobot-old (remove your old backup first if you have one, or back it up under a different name)
|
4. Rename the old nadekobot directory to nadekobot-old (remove your old backup first if you have one, or back it up under a different name)
|
||||||
- `rm -rf nadekobot-old 2>/dev/null`
|
- `rm -rf nadekobot-old 2>/dev/null`
|
||||||
- `mv nadekobot nadekobot-old`
|
- `mv nadekobot nadekobot-old`
|
||||||
5. Rename the new nadekobot directory to nadekobot
|
5. Rename the new nadekobot directory to nadekobot
|
||||||
- `mv nadekobot-linux-x64 nadekobot`
|
- `mv nadekobot-linux-x64 nadekobot`
|
||||||
6. Remove old strings and aliases to avoid overwriting the updated versions of those files
|
6. Remove old strings and aliases to avoid overwriting the updated versions of those files
|
||||||
- ⚠ If you've modified said files, back them up instead
|
- ⚠ If you've modified said files, back them up instead
|
||||||
- `rm nadekobot-old/data/aliases.yml`
|
- `rm nadekobot-old/data/aliases.yml`
|
||||||
- `rm -r nadekobot-old/data/strings`
|
- `rm -r nadekobot-old/data/strings`
|
||||||
7. Copy old data
|
7. Copy old data
|
||||||
- `cp -RT nadekobot-old/data/ nadekobot/data/`
|
- `cp -RT nadekobot-old/data/ nadekobot/data`
|
||||||
8. Copy creds.yml
|
8. Copy creds.yml
|
||||||
- `cp nadekobot-old/creds.yml nadekobot/`
|
- `cp nadekobot-old/creds.yml nadekobot/`
|
||||||
9. Move into nadekobot directory and make the NadekoBot executable
|
9. Move into nadekobot directory and make the NadekoBot executable
|
||||||
- `cd nadekobot && chmod +x NadekoBot`
|
- `cd nadekobot && chmod +x NadekoBot`
|
||||||
10. Run the bot
|
10. Run the bot
|
||||||
- `./NadekoBot`
|
- `./NadekoBot`
|
||||||
|
|
||||||
🎉 Enjoy
|
🎉 Enjoy
|
||||||
|
|
||||||
@@ -95,7 +95,135 @@ mv nadekobot nadekobot-old && \
|
|||||||
mv nadekobot-linux-x64 nadekobot && \
|
mv nadekobot-linux-x64 nadekobot && \
|
||||||
rm nadekobot-old/data/aliases.yml && \
|
rm nadekobot-old/data/aliases.yml && \
|
||||||
rm -r nadekobot-old/data/strings && \
|
rm -r nadekobot-old/data/strings && \
|
||||||
cp -RT nadekobot-old/data/ nadekobot/data/ && \
|
cp -RT nadekobot-old/data/ nadekobot/data && \
|
||||||
cp nadekobot-old/creds.yml nadekobot/ && \
|
cp nadekobot-old/creds.yml nadekobot/ && \
|
||||||
cd nadekobot && chmod +x NadekoBot
|
cd nadekobot && chmod +x NadekoBot
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Running Nadeko
|
||||||
|
|
||||||
|
While there are two run modes built into the installer, these options only run Nadeko within the current session. Below are 3 methods of running Nadeko as a background process.
|
||||||
|
|
||||||
|
### Tmux (Preferred Method)
|
||||||
|
|
||||||
|
Using `tmux` is the simplest method, and is therefore recommended for most users.
|
||||||
|
|
||||||
|
1. Start a tmux session:
|
||||||
|
- `tmux`
|
||||||
|
2. Navigate to the project's root directory
|
||||||
|
- Project root directory location example: `/home/user/nadekobot/`
|
||||||
|
3. Enter the `output` directory:
|
||||||
|
- `cd output`
|
||||||
|
4. Run the bot using:
|
||||||
|
- `dotnet NadekoBot.dll`
|
||||||
|
5. Detatch the tmux session:
|
||||||
|
- Press `Ctrl` + `B`
|
||||||
|
- Then press `D`
|
||||||
|
|
||||||
|
Nadeko should now be running in the background of your system. To re-open the tmux session to either update, restart, or whatever, execute `tmux a`.
|
||||||
|
|
||||||
|
### Systemd
|
||||||
|
|
||||||
|
Compared to using tmux, this method requires a little bit more work to set up, but has the benefit of allowing Nadeko to automatically start back up after a system reboot or the execution of the `.die` command.
|
||||||
|
|
||||||
|
1. Navigate to the project's root directory
|
||||||
|
- Project root directory location example: `/home/user/nadekobot/`
|
||||||
|
2. Use the following command to create a service that will be used to start Nadeko:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "[Unit]
|
||||||
|
Description=NadekoBot service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=$USER
|
||||||
|
WorkingDirectory=$PWD/output
|
||||||
|
# If you want Nadeko to be compiled prior to every startup, uncomment the lines
|
||||||
|
# below. Note that it's not neccessary unless you are personally modifying the
|
||||||
|
# source code.
|
||||||
|
#ExecStartPre=/usr/bin/dotnet build ../src/NadekoBot/NadekoBot.csproj -c Release -o output/
|
||||||
|
ExecStart=/usr/bin/dotnet NadekoBot.dll
|
||||||
|
StandardOutput=syslog
|
||||||
|
StandardError=syslog
|
||||||
|
SyslogIdentifier=NadekoBot
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/nadeko.service
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Make the new service available:
|
||||||
|
- `sudo systemctl daemon-reload`
|
||||||
|
4. Start Nadeko:
|
||||||
|
- `sudo systemctl start nadeko.service && sudo systemctl enable nadeko.service`
|
||||||
|
|
||||||
|
|
||||||
|
### Systemd + Script
|
||||||
|
|
||||||
|
This method is similar to the one above, but requires one extra step, with the added benefit of better error logging and control over what happens before and after the startup of Nadeko.
|
||||||
|
|
||||||
|
1. Locate the project and move to its parent directory
|
||||||
|
- Project location example: `/home/user/nadekobot/`
|
||||||
|
- Parent directory example: `/home/user/`
|
||||||
|
2. Use the following command to create a service that will be used to execute `NadekoRun.sh`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "[Unit]
|
||||||
|
Description=NadekoBot service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=$USER
|
||||||
|
WorkingDirectory=$PWD
|
||||||
|
ExecStart=/bin/bash NadekoRun.sh
|
||||||
|
StandardOutput=syslog
|
||||||
|
StandardError=syslog
|
||||||
|
SyslogIdentifier=NadekoBot
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/nadeko.service
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Make the new service available:
|
||||||
|
- `sudo systemctl daemon-reload`
|
||||||
|
4. Use the following command to create a script that will be used to start Nadeko:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "#\!/bin/bash
|
||||||
|
|
||||||
|
echo \"\"
|
||||||
|
echo \"Running NadekoBot in the background with auto restart\"
|
||||||
|
youtube-dl -U
|
||||||
|
|
||||||
|
# If you want Nadeko to be compiled prior to every startup, uncomment the lines
|
||||||
|
# below. Note that it's not neccessary unless you are personally modifying the
|
||||||
|
# source code.
|
||||||
|
#echo \"Compiling NadekoBot...\"
|
||||||
|
#cd \"$PWD\"/nadekobot
|
||||||
|
#dotnet build src/NadekoBot/NadekoBot.csproj -c Release -o output/
|
||||||
|
|
||||||
|
echo \"Starting NadekoBot...\"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
{
|
||||||
|
cd \"$PWD\"/nadekobot/output
|
||||||
|
dotnet NadekoBot.dll
|
||||||
|
## If a non-zero exit code is produced, exit this script.
|
||||||
|
} || {
|
||||||
|
error_code=\"\$?\"
|
||||||
|
echo \"An error occurred when trying to start NadekBot\"
|
||||||
|
echo \"EXIT CODE: \$?\"
|
||||||
|
exit \"\$error_code\"
|
||||||
|
}
|
||||||
|
|
||||||
|
youtube-dl -U
|
||||||
|
echo \"Restarting NadekoBot...\"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo \"Stopping NadekoBot...\"" > NadekoRun.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Start Nadeko:
|
||||||
|
- `sudo systemctl start nadeko.service && sudo systemctl enable nadeko.service`
|
@@ -80,6 +80,7 @@ You can still install them manually:
|
|||||||
Open PowerShell (press windows button on your keyboard and type powershell, it should show up; alternatively, right click the start menu and select Windows PowerShell), and navigate to the location where you want to install the bot (for example `cd ~/Desktop/`)
|
Open PowerShell (press windows button on your keyboard and type powershell, it should show up; alternatively, right click the start menu and select Windows PowerShell), and navigate to the location where you want to install the bot (for example `cd ~/Desktop/`)
|
||||||
|
|
||||||
1. `git clone https://gitlab.com/kwoth/nadekobot -b v3 --depth 1`
|
1. `git clone https://gitlab.com/kwoth/nadekobot -b v3 --depth 1`
|
||||||
|
2. `cd nadekobot`
|
||||||
3. `dotnet publish -c Release -o output/ src/NadekoBot/`
|
3. `dotnet publish -c Release -o output/ src/NadekoBot/`
|
||||||
4. `cd output && cp creds_example.yml creds.yml`
|
4. `cd output && cp creds_example.yml creds.yml`
|
||||||
5. Open `creds.yml` with your favorite text editor (Please don't use Notepad or WordPad. You can use Notepad++, VSCode, Atom, Sublime, or something similar)
|
5. Open `creds.yml` with your favorite text editor (Please don't use Notepad or WordPad. You can use Notepad++, VSCode, Atom, Sublime, or something similar)
|
||||||
@@ -91,16 +92,30 @@ Open PowerShell (press windows button on your keyboard and type powershell, it s
|
|||||||
|
|
||||||
Open PowerShell as described above and run the following commands:
|
Open PowerShell as described above and run the following commands:
|
||||||
|
|
||||||
1. Navigate to your bot's folder, for example `cd ~/Desktop/nadekobot/src/NadekoBot`
|
1. Stop the bot
|
||||||
2. Pull the latest updates (this will fail if you have custom code changes).
|
- ⚠️ Make sure you don't have your database, credentials or any other nadekobot folder open in some application, this might prevent some of the steps from executing succesfully
|
||||||
- If you don't have custom code changes, just run `git pull`
|
2. Navigate to your bot's folder, example:
|
||||||
- If you do have custom code changes, You have 3 options
|
- `cd ~/Desktop/nadekobot`
|
||||||
- Undo all changes with `git checkout -- * && git pull`
|
3. Pull the new version
|
||||||
- Stash changes and try to re-apply them `git stash && git pull && git stash apply`
|
- `git pull`
|
||||||
- Commit your changes and resolve merge conflicts `git add . && git commit -m "My commit message" && git pull`
|
- ⚠️ If this fails, you may want to stash or remove your code changes if you don't know how to resolve merge conflicts
|
||||||
3. Re-run the bot `dotnet run -c Release`
|
4. **Backup** old output in case your data is overwritten
|
||||||
|
- `cp -r -fo output/ output-old`
|
||||||
|
5. Build the bot again
|
||||||
|
- `dotnet publish -c Release -o output/ src/NadekoBot/`
|
||||||
|
6. Remove old strings and aliases to avoid overwriting the updated versions of those files
|
||||||
|
- ⚠ If you've modified said files, back them up instead
|
||||||
|
- `rm output-old/data/aliases.yml`
|
||||||
|
- `rm -r output-old/data/strings`
|
||||||
|
7. Copy old data
|
||||||
|
- `cp -Recurse .\output-old\data\ .\output\ -Force`
|
||||||
|
8. Copy creds.yml
|
||||||
|
- `cp output-old/creds.yml output/`
|
||||||
|
9. Run the bot
|
||||||
|
- `cd output`
|
||||||
|
- `dotnet NadekoBot.dll`
|
||||||
|
|
||||||
⚠ You're expected to understand that your database will be in `bin/Release/<framework>/data/`, and if `<framework>` gets changed in the future, you will have to move your database manually.
|
🎉 Enjoy
|
||||||
|
|
||||||
#### Music prerequisites
|
#### Music prerequisites
|
||||||
In order to use music commands, you need ffmpeg and youtube-dl installed.
|
In order to use music commands, you need ffmpeg and youtube-dl installed.
|
||||||
|
@@ -102,7 +102,6 @@ namespace NadekoBot
|
|||||||
.AddSingleton(Client) // discord socket client
|
.AddSingleton(Client) // discord socket client
|
||||||
.AddSingleton(_commandService)
|
.AddSingleton(_commandService)
|
||||||
.AddSingleton(this)
|
.AddSingleton(this)
|
||||||
.AddSingleton<IDataCache, RedisCache>()
|
|
||||||
.AddSingleton<ISeria, JsonSeria>()
|
.AddSingleton<ISeria, JsonSeria>()
|
||||||
.AddSingleton<IPubSub, RedisPubSub>()
|
.AddSingleton<IPubSub, RedisPubSub>()
|
||||||
.AddSingleton<IConfigSeria, YamlSeria>()
|
.AddSingleton<IConfigSeria, YamlSeria>()
|
||||||
@@ -132,10 +131,18 @@ namespace NadekoBot
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
svcs.AddSingleton<ICoordinator, RemoteGrpcCoordinator>()
|
svcs.AddSingleton<RemoteGrpcCoordinator>()
|
||||||
.AddSingleton<IReadyExecutor>(x => (IReadyExecutor)x.GetRequiredService<ICoordinator>());
|
.AddSingleton<ICoordinator>(x => x.GetRequiredService<RemoteGrpcCoordinator>())
|
||||||
|
.AddSingleton<IReadyExecutor>(x => x.GetRequiredService<RemoteGrpcCoordinator>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svcs.AddSingleton<RedisLocalDataCache>()
|
||||||
|
.AddSingleton<ILocalDataCache>(x => x.GetRequiredService<RedisLocalDataCache>())
|
||||||
|
.AddSingleton<RedisImagesCache>()
|
||||||
|
.AddSingleton<IImageCache>(x => x.GetRequiredService<RedisImagesCache>())
|
||||||
|
.AddSingleton<IReadyExecutor>(x => x.GetRequiredService<RedisImagesCache>())
|
||||||
|
.AddSingleton<IDataCache, RedisCache>();
|
||||||
|
|
||||||
svcs.Scan(scan => scan
|
svcs.Scan(scan => scan
|
||||||
.FromAssemblyOf<IReadyExecutor>()
|
.FromAssemblyOf<IReadyExecutor>()
|
||||||
.AddClasses(classes => classes.AssignableToAny(
|
.AddClasses(classes => classes.AssignableToAny(
|
||||||
|
@@ -12,7 +12,7 @@ namespace NadekoBot.Common.Configs
|
|||||||
public sealed partial class BotConfig : ICloneable<BotConfig>
|
public sealed partial class BotConfig : ICloneable<BotConfig>
|
||||||
{
|
{
|
||||||
[Comment(@"DO NOT CHANGE")]
|
[Comment(@"DO NOT CHANGE")]
|
||||||
public int Version { get; set; }
|
public int Version { get; set; } = 2;
|
||||||
|
|
||||||
[Comment(@"Most commands, when executed, have a small colored line
|
[Comment(@"Most commands, when executed, have a small colored line
|
||||||
next to the response. The color depends whether the command
|
next to the response. The color depends whether the command
|
||||||
@@ -48,6 +48,11 @@ they will receive this message. Leave empty for no response. The string which wi
|
|||||||
Supports embeds. How it looks: https://puu.sh/B0BLV.png")]
|
Supports embeds. How it looks: https://puu.sh/B0BLV.png")]
|
||||||
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
||||||
public string DmHelpText { get; set; }
|
public string DmHelpText { get; set; }
|
||||||
|
|
||||||
|
[Comment(@"Only users who send a DM to the bot containing one of the specified words will get a DmHelpText response.
|
||||||
|
Case insensitive.
|
||||||
|
Leave empty to reply with DmHelpText to every DM.")]
|
||||||
|
public List<string> DmHelpTextKeywords { get; set; }
|
||||||
|
|
||||||
[Comment(@"This is the response for the .h command")]
|
[Comment(@"This is the response for the .h command")]
|
||||||
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
||||||
@@ -89,7 +94,6 @@ See RotatingStatuses submodule in Administration.")]
|
|||||||
|
|
||||||
public BotConfig()
|
public BotConfig()
|
||||||
{
|
{
|
||||||
Version = 1;
|
|
||||||
var color = new ColorConfig();
|
var color = new ColorConfig();
|
||||||
Color = color;
|
Color = color;
|
||||||
DefaultLocale = new CultureInfo("en-US");
|
DefaultLocale = new CultureInfo("en-US");
|
||||||
@@ -127,6 +131,14 @@ See RotatingStatuses submodule in Administration.")]
|
|||||||
Prefix = ".";
|
Prefix = ".";
|
||||||
RotateStatuses = false;
|
RotateStatuses = false;
|
||||||
GroupGreets = false;
|
GroupGreets = false;
|
||||||
|
DmHelpTextKeywords = new List<string>()
|
||||||
|
{
|
||||||
|
"help",
|
||||||
|
"commands",
|
||||||
|
"cmds",
|
||||||
|
"module",
|
||||||
|
"can you do"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -89,6 +89,8 @@ namespace NadekoBot.Common.Replacements
|
|||||||
_reps.TryAdd("%server.id%", () => g is null ? "DM" : g.Id.ToString());
|
_reps.TryAdd("%server.id%", () => g is null ? "DM" : g.Id.ToString());
|
||||||
_reps.TryAdd("%server.name%", () => g is null ? "DM" : g.Name);
|
_reps.TryAdd("%server.name%", () => g is null ? "DM" : g.Name);
|
||||||
_reps.TryAdd("%server.members%", () => g != null && g is SocketGuild sg ? sg.MemberCount.ToString() : "?");
|
_reps.TryAdd("%server.members%", () => g != null && g is SocketGuild sg ? sg.MemberCount.ToString() : "?");
|
||||||
|
_reps.TryAdd("%server.boosters%", () => g.PremiumSubscriptionCount.ToString());
|
||||||
|
_reps.TryAdd("%server.boost_level%", () => ((int)g.PremiumTier).ToString());
|
||||||
_reps.TryAdd("%server.time%", () =>
|
_reps.TryAdd("%server.time%", () =>
|
||||||
{
|
{
|
||||||
TimeZoneInfo to = TimeZoneInfo.Local;
|
TimeZoneInfo to = TimeZoneInfo.Local;
|
||||||
|
@@ -120,6 +120,15 @@ namespace NadekoBot.Db
|
|||||||
.Include(x => x.IgnoredChannels)
|
.Include(x => x.IgnoredChannels)
|
||||||
.Where(x => x.GuildId == guildId)
|
.Where(x => x.GuildId == guildId)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (logSetting is null)
|
||||||
|
{
|
||||||
|
ctx.LogSettings.Add(logSetting = new ()
|
||||||
|
{
|
||||||
|
GuildId = guildId
|
||||||
|
});
|
||||||
|
ctx.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
return logSetting;
|
return logSetting;
|
||||||
}
|
}
|
||||||
|
@@ -90,7 +90,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
await _service.TimedMute(user, ctx.User, time.Time, reason: reason).ConfigureAwait(false);
|
await _service.TimedMute(user, ctx.User, time.Time, reason: reason).ConfigureAwait(false);
|
||||||
await ReplyErrorLocalizedAsync(strs.user_muted_time(Format.Bold(user.ToString()), (int)time.Time.TotalMinutes));
|
await ReplyConfirmLocalizedAsync(strs.user_muted_time(Format.Bold(user.ToString()), (int)time.Time.TotalMinutes));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -150,7 +150,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
await _service.TimedMute(user, ctx.User, time.Time, MuteType.Chat, reason: reason).ConfigureAwait(false);
|
await _service.TimedMute(user, ctx.User, time.Time, MuteType.Chat, reason: reason).ConfigureAwait(false);
|
||||||
await ReplyErrorLocalizedAsync(strs.user_chat_mute_time(Format.Bold(user.ToString()), (int)time.Time.TotalMinutes));
|
await ReplyConfirmLocalizedAsync(strs.user_chat_mute_time(Format.Bold(user.ToString()), (int)time.Time.TotalMinutes));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -209,7 +209,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
await _service.TimedMute(user, ctx.User, time.Time, MuteType.Voice, reason: reason).ConfigureAwait(false);
|
await _service.TimedMute(user, ctx.User, time.Time, MuteType.Voice, reason: reason).ConfigureAwait(false);
|
||||||
await ReplyErrorLocalizedAsync(strs.user_voice_mute_time(Format.Bold(user.ToString()), (int)time.Time.TotalMinutes));
|
await ReplyConfirmLocalizedAsync(strs.user_voice_mute_time(Format.Bold(user.ToString()), (int)time.Time.TotalMinutes));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@@ -61,7 +61,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
if (msg is null)
|
if (msg is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.reprm(msg));
|
await ReplyConfirmLocalizedAsync(strs.reprm(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.protection_not_running("Anti-Alt"));
|
await ReplyConfirmLocalizedAsync(strs.protection_not_running("Anti-Alt"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -69,11 +69,11 @@ namespace NadekoBot.Modules.Administration
|
|||||||
{
|
{
|
||||||
if (_service.TryStopAntiRaid(ctx.Guild.Id))
|
if (_service.TryStopAntiRaid(ctx.Guild.Id))
|
||||||
{
|
{
|
||||||
return ReplyErrorLocalizedAsync(strs.prot_disable("Anti-Raid"));
|
return ReplyConfirmLocalizedAsync(strs.prot_disable("Anti-Raid"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ReplyErrorLocalizedAsync(strs.protection_not_running("Anti-Raid"));
|
return ReplyPendingLocalizedAsync(strs.protection_not_running("Anti-Raid"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,11 +145,11 @@ namespace NadekoBot.Modules.Administration
|
|||||||
{
|
{
|
||||||
if (_service.TryStopAntiSpam(ctx.Guild.Id))
|
if (_service.TryStopAntiSpam(ctx.Guild.Id))
|
||||||
{
|
{
|
||||||
return ReplyErrorLocalizedAsync(strs.prot_disable("Anti-Spam"));
|
return ReplyConfirmLocalizedAsync(strs.prot_disable("Anti-Spam"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ReplyErrorLocalizedAsync(strs.protection_not_running("Anti-Spam"));
|
return ReplyPendingLocalizedAsync(strs.protection_not_running("Anti-Spam"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -189,7 +189,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
index--;
|
index--;
|
||||||
var rr = rrs[index];
|
var rr = rrs[index];
|
||||||
_service.Remove(ctx.Guild.Id, index);
|
_service.Remove(ctx.Guild.Id, index);
|
||||||
await ReplyErrorLocalizedAsync(strs.reaction_role_removed(index + 1));
|
await ReplyConfirmLocalizedAsync(strs.reaction_role_removed(index + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -24,11 +24,11 @@ namespace NadekoBot.Modules.Administration
|
|||||||
|
|
||||||
if (newVal)
|
if (newVal)
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.adsarm_enable(Prefix));
|
await ReplyConfirmLocalizedAsync(strs.adsarm_enable(Prefix));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.adsarm_disable(Prefix));
|
await ReplyConfirmLocalizedAsync(strs.adsarm_disable(Prefix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
};
|
};
|
||||||
_service.AddNewAutoCommand(cmd);
|
_service.AddNewAutoCommand(cmd);
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.autocmd_add(Format.Code(Format.Sanitize(cmdText)), cmd.Interval));
|
await ReplyConfirmLocalizedAsync(strs.autocmd_add(Format.Code(Format.Sanitize(cmdText)), cmd.Interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -226,7 +226,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
if (enabled)
|
if (enabled)
|
||||||
await ReplyConfirmLocalizedAsync(strs.fwdm_start).ConfigureAwait(false);
|
await ReplyConfirmLocalizedAsync(strs.fwdm_start).ConfigureAwait(false);
|
||||||
else
|
else
|
||||||
await ReplyConfirmLocalizedAsync(strs.fwdm_stop).ConfigureAwait(false);
|
await ReplyPendingLocalizedAsync(strs.fwdm_stop).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -238,7 +238,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
if (enabled)
|
if (enabled)
|
||||||
await ReplyConfirmLocalizedAsync(strs.fwall_start).ConfigureAwait(false);
|
await ReplyConfirmLocalizedAsync(strs.fwall_start).ConfigureAwait(false);
|
||||||
else
|
else
|
||||||
await ReplyConfirmLocalizedAsync(strs.fwall_stop).ConfigureAwait(false);
|
await ReplyPendingLocalizedAsync(strs.fwall_stop).ConfigureAwait(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +376,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
var curUser = await ctx.Guild.GetCurrentUserAsync().ConfigureAwait(false);
|
var curUser = await ctx.Guild.GetCurrentUserAsync().ConfigureAwait(false);
|
||||||
await curUser.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false);
|
await curUser.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false);
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.bot_nick(Format.Bold(newNick) ?? "-"));
|
await ReplyConfirmLocalizedAsync(strs.bot_nick(Format.Bold(newNick) ?? "-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -395,7 +395,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
|
|
||||||
await gu.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false);
|
await gu.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false);
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.user_nick(Format.Bold(gu.ToString()), Format.Bold(newNick) ?? "-"));
|
await ReplyConfirmLocalizedAsync(strs.user_nick(Format.Bold(gu.ToString()), Format.Bold(newNick) ?? "-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -496,7 +496,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
public async Task ImagesReload()
|
public async Task ImagesReload()
|
||||||
{
|
{
|
||||||
await _service.ReloadImagesAsync();
|
await _service.ReloadImagesAsync();
|
||||||
await ReplyErrorLocalizedAsync(strs.images_loading);
|
await ReplyConfirmLocalizedAsync(strs.images_loading);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -294,7 +294,7 @@ namespace NadekoBot.Modules.CustomReactions
|
|||||||
.WithDescription("This will delete all custom reactions on this server.")).ConfigureAwait(false))
|
.WithDescription("This will delete all custom reactions on this server.")).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
var count = _service.DeleteAllCustomReactions(ctx.Guild.Id);
|
var count = _service.DeleteAllCustomReactions(ctx.Guild.Id);
|
||||||
await ReplyErrorLocalizedAsync(strs.cleared(count));
|
await ReplyConfirmLocalizedAsync(strs.cleared(count));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -217,7 +217,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
[Priority(0)]
|
[Priority(0)]
|
||||||
public async Task Cash(ulong userId)
|
public async Task Cash(ulong userId)
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.has(Format.Code(userId.ToString()), $"{GetCurrency(userId)} {CurrencySign}"));
|
await ReplyConfirmLocalizedAsync(strs.has(Format.Code(userId.ToString()), $"{GetCurrency(userId)} {CurrencySign}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -269,7 +269,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
$"Awarded by bot owner. ({ctx.User.Username}/{ctx.User.Id}) {(msg ?? "")}",
|
$"Awarded by bot owner. ({ctx.User.Username}/{ctx.User.Id}) {(msg ?? "")}",
|
||||||
amount,
|
amount,
|
||||||
gamble: (ctx.Client.CurrentUser.Id != usrId)).ConfigureAwait(false);
|
gamble: (ctx.Client.CurrentUser.Id != usrId)).ConfigureAwait(false);
|
||||||
await ReplyErrorLocalizedAsync(strs.awarded(n(amount) + CurrencySign, $"<@{usrId}>"));
|
await ReplyConfirmLocalizedAsync(strs.awarded(n(amount) + CurrencySign, $"<@{usrId}>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -340,7 +340,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
|
|
||||||
if (await _cs.RemoveAsync(usrId, $"Taken by bot owner.({ctx.User.Username}/{ctx.User.Id})", amount,
|
if (await _cs.RemoveAsync(usrId, $"Taken by bot owner.({ctx.User.Username}/{ctx.User.Id})", amount,
|
||||||
gamble: (ctx.Client.CurrentUser.Id != usrId)).ConfigureAwait(false))
|
gamble: (ctx.Client.CurrentUser.Id != usrId)).ConfigureAwait(false))
|
||||||
await ReplyErrorLocalizedAsync(strs.take(amount + CurrencySign, $"<@{usrId}>"));
|
await ReplyConfirmLocalizedAsync(strs.take(amount + CurrencySign, $"<@{usrId}>"));
|
||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.take_fail(amount + CurrencySign, Format.Code(usrId.ToString()), CurrencySign));
|
await ReplyErrorLocalizedAsync(strs.take_fail(amount + CurrencySign, Format.Code(usrId.ToString()), CurrencySign));
|
||||||
}
|
}
|
||||||
|
@@ -145,11 +145,11 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
|
|
||||||
if (result == DivorceResult.SucessWithPenalty)
|
if (result == DivorceResult.SucessWithPenalty)
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.waifu_divorced_like(Format.Bold(w.Waifu.ToString()), amount + CurrencySign));
|
await ReplyConfirmLocalizedAsync(strs.waifu_divorced_like(Format.Bold(w.Waifu.ToString()), amount + CurrencySign));
|
||||||
}
|
}
|
||||||
else if (result == DivorceResult.Success)
|
else if (result == DivorceResult.Success)
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.waifu_divorced_notlike(amount + CurrencySign));
|
await ReplyConfirmLocalizedAsync(strs.waifu_divorced_notlike(amount + CurrencySign));
|
||||||
}
|
}
|
||||||
else if (result == DivorceResult.NotYourWife)
|
else if (result == DivorceResult.NotYourWife)
|
||||||
{
|
{
|
||||||
@@ -306,7 +306,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
[Priority(1)]
|
[Priority(1)]
|
||||||
public async Task WaifuGift(int page = 1)
|
public async Task WaifuGift(int page = 1)
|
||||||
{
|
{
|
||||||
if (--page < 0 || page > 3)
|
if (--page < 0 || page > (_config.Waifu.Items.Count - 1) / 9)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var waifuItems = _service.GetWaifuItems();
|
var waifuItems = _service.GetWaifuItems();
|
||||||
|
@@ -434,7 +434,7 @@ namespace NadekoBot.Modules.Help
|
|||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
public async Task Donate()
|
public async Task Donate()
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.donate(PatreonUrl, PaypalUrl));
|
await ReplyConfirmLocalizedAsync(strs.donate(PatreonUrl, PaypalUrl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,6 +44,11 @@ namespace NadekoBot.Modules.Help.Services
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(settings.DmHelpText) || settings.DmHelpText == "-")
|
if (string.IsNullOrWhiteSpace(settings.DmHelpText) || settings.DmHelpText == "-")
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
|
// only send dm help text if it contains one of the keywords, if they're specified
|
||||||
|
// if they're not, then reply to every DM
|
||||||
|
if (settings.DmHelpTextKeywords.Any() && !settings.DmHelpTextKeywords.Any(k => msg.Content.Contains(k)))
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
var rep = new ReplacementBuilder()
|
var rep = new ReplacementBuilder()
|
||||||
.WithOverride("%prefix%", () => _bss.Data.Prefix)
|
.WithOverride("%prefix%", () => _bss.Data.Prefix)
|
||||||
|
@@ -125,7 +125,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
queuedMessage?.DeleteAfter(10, _logService);
|
queuedMessage?.DeleteAfter(10, _logService);
|
||||||
if (mp.IsStopped)
|
if (mp.IsStopped)
|
||||||
{
|
{
|
||||||
var msg = await ReplyErrorLocalizedAsync(strs.queue_stopped(Format.Code(Prefix + "play")));
|
var msg = await ReplyPendingLocalizedAsync(strs.queue_stopped(Format.Code(Prefix + "play")));
|
||||||
msg.DeleteAfter(10, _logService);
|
msg.DeleteAfter(10, _logService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +230,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
await _service.SetVolumeAsync(ctx.Guild.Id, vol);
|
await _service.SetVolumeAsync(ctx.Guild.Id, vol);
|
||||||
await ReplyErrorLocalizedAsync(strs.volume_set(vol));
|
await ReplyConfirmLocalizedAsync(strs.volume_set(vol));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -189,7 +189,7 @@ namespace NadekoBot.Modules.NSFW
|
|||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.started(interval));
|
await ReplyConfirmLocalizedAsync(strs.started(interval));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
@@ -229,7 +229,7 @@ namespace NadekoBot.Modules.NSFW
|
|||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.started(interval));
|
await ReplyConfirmLocalizedAsync(strs.started(interval));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -363,9 +363,9 @@ namespace NadekoBot.Modules.NSFW
|
|||||||
var added = _service.ToggleBlacklistedTag(ctx.Guild.Id, tag);
|
var added = _service.ToggleBlacklistedTag(ctx.Guild.Id, tag);
|
||||||
|
|
||||||
if (added)
|
if (added)
|
||||||
await ReplyErrorLocalizedAsync(strs.blacklisted_tag_add(tag));
|
await ReplyPendingLocalizedAsync(strs.blacklisted_tag_add(tag));
|
||||||
else
|
else
|
||||||
await ReplyErrorLocalizedAsync(strs.blacklisted_tag_remove(tag));
|
await ReplyPendingLocalizedAsync(strs.blacklisted_tag_remove(tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -217,7 +217,7 @@ namespace NadekoBot.Modules.Permissions
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await ReplyErrorLocalizedAsync(strs.perm_out_of_range).ConfigureAwait(false);
|
await ReplyConfirmLocalizedAsync(strs.perm_out_of_range).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -66,7 +66,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.feed_not_valid).ConfigureAwait(false);
|
await ReplyConfirmLocalizedAsync(strs.feed_not_valid).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -191,7 +191,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.stream_message_set_all(count));
|
await ReplyConfirmLocalizedAsync(strs.stream_message_set_all(count));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -118,7 +118,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
|
|
||||||
_searches.UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs);
|
_searches.UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs);
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.atl_set(from, to));
|
await ReplyConfirmLocalizedAsync(strs.atl_set(from, to));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -37,7 +37,7 @@ namespace NadekoBot.Modules.Utility
|
|||||||
public async Task AliasesClear()
|
public async Task AliasesClear()
|
||||||
{
|
{
|
||||||
var count = _service.ClearAliases(ctx.Guild.Id);
|
var count = _service.ClearAliases(ctx.Guild.Id);
|
||||||
await ReplyErrorLocalizedAsync(strs.aliases_cleared(count));
|
await ReplyConfirmLocalizedAsync(strs.aliases_cleared(count));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -148,7 +148,7 @@ namespace NadekoBot.Modules.Utility
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalizedAsync(strs.reminder_deleted(index + 1));
|
await ReplyConfirmLocalizedAsync(strs.reminder_deleted(index + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -183,7 +183,9 @@ namespace NadekoBot.Modules.Utility
|
|||||||
private string GetRepeaterInfoString(RunningRepeater runner)
|
private string GetRepeaterInfoString(RunningRepeater runner)
|
||||||
{
|
{
|
||||||
var intervalString = Format.Bold(runner.Repeater.Interval.ToPrettyStringHM());
|
var intervalString = Format.Bold(runner.Repeater.Interval.ToPrettyStringHM());
|
||||||
var executesIn = runner.NextTime - DateTime.UtcNow;
|
var executesIn = runner.NextTime < DateTime.UtcNow
|
||||||
|
? TimeSpan.Zero
|
||||||
|
: runner.NextTime - DateTime.UtcNow;
|
||||||
var executesInString = Format.Bold(executesIn.ToPrettyStringHM());
|
var executesInString = Format.Bold(executesIn.ToPrettyStringHM());
|
||||||
var message = Format.Sanitize(runner.Repeater.Message.TrimTo(50));
|
var message = Format.Sanitize(runner.Repeater.Message.TrimTo(50));
|
||||||
|
|
||||||
|
@@ -76,7 +76,9 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
|
|||||||
// because repeaters might've been modified meanwhile
|
// because repeaters might've been modified meanwhile
|
||||||
if (timeout > TimeSpan.Zero)
|
if (timeout > TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
await Task.Delay(timeout);
|
await Task.Delay(timeout > TimeSpan.FromMinutes(1)
|
||||||
|
? TimeSpan.FromMinutes(1)
|
||||||
|
: timeout);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,16 +86,17 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
|
|||||||
var now = DateTime.UtcNow + TimeSpan.FromSeconds(3);
|
var now = DateTime.UtcNow + TimeSpan.FromSeconds(3);
|
||||||
|
|
||||||
var toExecute = new List<RunningRepeater>();
|
var toExecute = new List<RunningRepeater>();
|
||||||
while (true)
|
lock (_repeaterQueue)
|
||||||
{
|
{
|
||||||
lock (_repeaterQueue)
|
var current = _repeaterQueue.First;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
var current = _repeaterQueue.First;
|
|
||||||
if (current is null || current.Value.NextTime > now)
|
if (current is null || current.Value.NextTime > now)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
toExecute.Add(current.Value);
|
toExecute.Add(current.Value);
|
||||||
_repeaterQueue.RemoveFirst();
|
current = current.Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,14 +124,24 @@ where ((guildid >> 22) % {_creds.TotalShards}) == {_client.ShardId};")
|
|||||||
{
|
{
|
||||||
if (rep.ErrorCount >= 10)
|
if (rep.ErrorCount >= 10)
|
||||||
{
|
{
|
||||||
|
RemoveFromQueue(rep.Repeater.Id);
|
||||||
await RemoveRepeaterInternal(rep.Repeater);
|
await RemoveRepeaterInternal(rep.Repeater);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rep.UpdateNextTime();
|
UpdatePosition(rep);
|
||||||
AddToQueue(rep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdatePosition(RunningRepeater rep)
|
||||||
|
{
|
||||||
|
lock (_queueLocker)
|
||||||
|
{
|
||||||
|
rep.UpdateNextTime();
|
||||||
|
_repeaterQueue.Remove(rep);
|
||||||
|
AddToQueue(rep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> TriggerExternal(ulong guildId, int index)
|
public async Task<bool> TriggerExternal(ulong guildId, int index)
|
||||||
{
|
{
|
||||||
using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
|
@@ -92,5 +92,15 @@ namespace NadekoBot.Modules.Utility.Services
|
|||||||
var initialIntervalMultiplier = 1 - (triggerCount - Math.Truncate(triggerCount));
|
var initialIntervalMultiplier = 1 - (triggerCount - Math.Truncate(triggerCount));
|
||||||
return DateTime.UtcNow + (Repeater.Interval * initialIntervalMultiplier);
|
return DateTime.UtcNow + (Repeater.Interval * initialIntervalMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is RunningRepeater rr && rr.Repeater.Id == this.Repeater.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return this.Repeater.Id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -31,7 +31,7 @@ namespace NadekoBot.Modules.Xp
|
|||||||
|
|
||||||
_service.XpReset(ctx.Guild.Id, userId);
|
_service.XpReset(ctx.Guild.Id, userId);
|
||||||
|
|
||||||
await ReplyErrorLocalizedAsync(strs.reset_user(userId));
|
await ReplyConfirmLocalizedAsync(strs.reset_user(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
|
|
||||||
private void Migrate()
|
private void Migrate()
|
||||||
{
|
{
|
||||||
if (_data.Version <= 1)
|
if (_data.Version < 2)
|
||||||
{
|
{
|
||||||
ModifyConfig(c =>
|
ModifyConfig(c =>
|
||||||
{
|
{
|
||||||
|
@@ -128,7 +128,7 @@ namespace NadekoBot.Modules.Xp
|
|||||||
public async Task XpRoleReward(int level)
|
public async Task XpRoleReward(int level)
|
||||||
{
|
{
|
||||||
_service.ResetRoleReward(ctx.Guild.Id, level);
|
_service.ResetRoleReward(ctx.Guild.Id, level);
|
||||||
await ReplyErrorLocalizedAsync(strs.xp_role_reward_cleared(level));
|
await ReplyConfirmLocalizedAsync(strs.xp_role_reward_cleared(level));
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Aliases]
|
[NadekoCommand, Aliases]
|
||||||
|
@@ -11,11 +11,12 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NadekoBot.Common.ModuleBehaviors;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public sealed class RedisImagesCache : IImageCache
|
public sealed class RedisImagesCache : IImageCache, IReadyExecutor
|
||||||
{
|
{
|
||||||
private readonly ConnectionMultiplexer _con;
|
private readonly ConnectionMultiplexer _con;
|
||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
@@ -73,6 +74,14 @@ namespace NadekoBot.Services
|
|||||||
Currency,
|
Currency,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task OnReadyAsync()
|
||||||
|
{
|
||||||
|
if (await AllKeysExist())
|
||||||
|
return;
|
||||||
|
|
||||||
|
await Reload();
|
||||||
|
}
|
||||||
|
|
||||||
public RedisImagesCache(ConnectionMultiplexer con, IBotCredentials creds)
|
public RedisImagesCache(ConnectionMultiplexer con, IBotCredentials creds)
|
||||||
{
|
{
|
||||||
_con = con;
|
_con = con;
|
||||||
|
@@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Discord;
|
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
@@ -20,12 +19,13 @@ namespace NadekoBot.Services
|
|||||||
private readonly string _redisKey;
|
private readonly string _redisKey;
|
||||||
private readonly EndPoint _redisEndpoint;
|
private readonly EndPoint _redisEndpoint;
|
||||||
|
|
||||||
public RedisCache(ConnectionMultiplexer redis, IBotCredentials creds, DiscordSocketClient client)
|
public RedisCache(ConnectionMultiplexer redis, IBotCredentials creds,
|
||||||
|
IImageCache imageCache, ILocalDataCache dataCache)
|
||||||
{
|
{
|
||||||
Redis = redis;
|
Redis = redis;
|
||||||
_redisEndpoint = Redis.GetEndPoints().First();
|
_redisEndpoint = Redis.GetEndPoints().First();
|
||||||
LocalImages = new RedisImagesCache(Redis, creds);
|
LocalImages = imageCache;
|
||||||
LocalData = new RedisLocalDataCache(Redis, creds, client.ShardId);
|
LocalData = dataCache;
|
||||||
_redisKey = creds.RedisKey();
|
_redisKey = creds.RedisKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,8 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Discord;
|
||||||
|
using Discord.WebSocket;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
@@ -25,56 +27,33 @@ namespace NadekoBot.Services
|
|||||||
|
|
||||||
public IReadOnlyDictionary<string, SearchPokemon> Pokemons
|
public IReadOnlyDictionary<string, SearchPokemon> Pokemons
|
||||||
{
|
{
|
||||||
get
|
get => Get<Dictionary<string, SearchPokemon>>("pokemon_list");
|
||||||
{
|
private set => Set("pokemon_list", value);
|
||||||
return Get<Dictionary<string, SearchPokemon>>("pokemon_list");
|
|
||||||
}
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
Set("pokemon_list", value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, SearchPokemonAbility> PokemonAbilities
|
public IReadOnlyDictionary<string, SearchPokemonAbility> PokemonAbilities
|
||||||
{
|
{
|
||||||
get
|
get => Get<Dictionary<string, SearchPokemonAbility>>("pokemon_abilities");
|
||||||
{
|
private set => Set("pokemon_abilities", value);
|
||||||
return Get<Dictionary<string, SearchPokemonAbility>>("pokemon_abilities");
|
|
||||||
}
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
Set("pokemon_abilities", value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TriviaQuestion[] TriviaQuestions
|
public TriviaQuestion[] TriviaQuestions
|
||||||
{
|
{
|
||||||
get
|
get => Get<TriviaQuestion[]>("trivia_questions");
|
||||||
{
|
private set => Set("trivia_questions", value);
|
||||||
return Get<TriviaQuestion[]>("trivia_questions");
|
|
||||||
}
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
Set("trivia_questions", value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyDictionary<int, string> PokemonMap
|
public IReadOnlyDictionary<int, string> PokemonMap
|
||||||
{
|
{
|
||||||
get
|
get => Get<Dictionary<int, string>>("pokemon_map");
|
||||||
{
|
private set => Set("pokemon_map", value);
|
||||||
return Get<Dictionary<int, string>>("pokemon_map");
|
|
||||||
}
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
Set("pokemon_map", value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RedisLocalDataCache(ConnectionMultiplexer con, IBotCredentials creds, int shardId)
|
public RedisLocalDataCache(ConnectionMultiplexer con, IBotCredentials creds, DiscordSocketClient client)
|
||||||
{
|
{
|
||||||
_con = con;
|
_con = con;
|
||||||
_creds = creds;
|
_creds = creds;
|
||||||
|
var shardId = client.ShardId;
|
||||||
|
|
||||||
if (shardId == 0)
|
if (shardId == 0)
|
||||||
{
|
{
|
||||||
|
@@ -19,7 +19,7 @@ namespace NadekoBot.Services
|
|||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly DateTime _started;
|
private readonly DateTime _started;
|
||||||
|
|
||||||
public const string BotVersion = "3.0.3";
|
public const string BotVersion = "3.0.5";
|
||||||
public string Author => "Kwoth#2452";
|
public string Author => "Kwoth#2452";
|
||||||
public string Library => "Discord.Net";
|
public string Library => "Discord.Net";
|
||||||
|
|
||||||
|
@@ -28,19 +28,15 @@ namespace NadekoBot.Services
|
|||||||
AddParsedProp("locale", bs => bs.DefaultLocale, ConfigParsers.Culture, ConfigPrinters.Culture);
|
AddParsedProp("locale", bs => bs.DefaultLocale, ConfigParsers.Culture, ConfigPrinters.Culture);
|
||||||
AddParsedProp("prefix", bs => bs.Prefix, ConfigParsers.String, ConfigPrinters.ToString);
|
AddParsedProp("prefix", bs => bs.Prefix, ConfigParsers.String, ConfigPrinters.ToString);
|
||||||
|
|
||||||
UpdateColors();
|
Migrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateColors()
|
private void Migrate()
|
||||||
{
|
{
|
||||||
var ok = _data.Color.Ok;
|
if (_data.Version < 2)
|
||||||
var error = _data.Color.Error;
|
{
|
||||||
var pend = _data.Color.Pending;
|
ModifyConfig(c => c.Version = 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStateUpdate()
|
|
||||||
{
|
|
||||||
UpdateColors();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
# DO NOT CHANGE
|
# DO NOT CHANGE
|
||||||
version: 1
|
version: 2
|
||||||
# Most commands, when executed, have a small colored line
|
# Most commands, when executed, have a small colored line
|
||||||
# next to the response. The color depends whether the command
|
# next to the response. The color depends whether the command
|
||||||
# is completed, errored or in progress (pending)
|
# is completed, errored or in progress (pending)
|
||||||
@@ -28,6 +28,15 @@ forwardToAllOwners: false
|
|||||||
# Supports embeds. How it looks: https://puu.sh/B0BLV.png
|
# Supports embeds. How it looks: https://puu.sh/B0BLV.png
|
||||||
dmHelpText: |-
|
dmHelpText: |-
|
||||||
{"description": "Type `%prefix%h` for help."}
|
{"description": "Type `%prefix%h` for help."}
|
||||||
|
# Only users who send a DM to the bot containing one of the specified words will get a DmHelpText response.
|
||||||
|
# Case insensitive.
|
||||||
|
# Leave empty to reply with DmHelpText to every DM.
|
||||||
|
dmHelpTextKeywords:
|
||||||
|
- help
|
||||||
|
- commands
|
||||||
|
- cmds
|
||||||
|
- module
|
||||||
|
- can you do
|
||||||
# This is the response for the .h command
|
# This is the response for the .h command
|
||||||
helpText: |-
|
helpText: |-
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user