Compare commits

..

59 Commits
5.0.3 ... 5.0.8

Author SHA1 Message Date
Kwoth
28a9f5682e docs: Updated changelog 2024-05-21 12:27:09 +00:00
Kwoth
06321380ee add: Added .quteedit command
add: Added an edit button to .quoteshow and .exprshow commands that opens a modal which lets you edit the quote or expr in question
2024-05-21 00:53:42 +00:00
Kwoth
b51ce34190 Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-05-21 00:17:10 +00:00
Kwoth
317c94979a fix: .langset and .langsetd should no longer allow unsupported languages and nonsense to be typed in 2024-05-21 00:16:57 +00:00
Kwoth
df2fd1b3f1 Merge branch 'v5' into 'v5'
Docs: update supported versions

See merge request Kwoth/nadekobot!329
2024-05-20 16:23:37 +00:00
Cata
35f0228986 docs: update supported versions 2024-05-20 16:23:36 +00:00
Kwoth
f391027c8c docs: Updated changelog 2024-05-20 00:48:35 +00:00
Kwoth
4e570475df add: Added dropdown menu for .cmds help and group help (part of cmds). Group help will no longer be on .h
fix: paginated response replies will no longer ping the author
2024-05-20 00:37:29 +00:00
Kwoth
e2066f433f fix: Fixed .h not working on some commands
add: Added select menu for the .mdls command
dev: Reworked the way interactions are created and sent. It is much better but far from perfect
2024-05-19 23:24:52 +00:00
Kwoth
78b328dc18 dev: added aliases to fix ci 2024-05-19 11:39:33 +00:00
Kwoth
f0cbacd01a Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-05-19 11:23:04 +00:00
Kwoth
d45c39a5fe fix: .pick command will now show the name of the user who picked the currency 2024-05-18 23:28:55 +00:00
Kwoth
a6010716e8 add: You can now check commands for submodules, for example '.h quote' the same way you can do for command groups like '.h bank' 2024-05-18 23:00:00 +00:00
Kwoth
d2c7563c5c change: Quotes will now use easier to write, alphanumerical ids (same as expressions) 2024-05-18 22:47:25 +00:00
Kwoth
0c167a9382 add: Added .cleanupguilddata command which will delete all guildconfigs, xp stats and other data related to any guild the bot is no longer in. This is a highly destructive and irreversible command.
dev: Added cascade deletes to any tables which have guildconfigs FK, as well as to some other missing places
2024-05-18 22:34:34 +00:00
Kwoth
b9d2e4baf1 Merge branch 'v5' into 'v5'
Missing botperms for setserver commands

See merge request Kwoth/nadekobot!328
2024-05-18 21:42:47 +00:00
Cata
82e230010b fix: added missing botperms for set* commands 2024-05-18 21:42:47 +00:00
Kwoth
03fb1a5ca2 fix: .verbose will now also be respected for expressions 2024-05-18 15:34:16 +00:00
Kwoth
8ac07ce6d7 Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-05-17 11:30:14 +00:00
Kwoth
12da9f3178 Merge branch 'v5' into 'v5'
setserverbanner and setservericon commands

See merge request Kwoth/nadekobot!327
2024-05-17 11:29:51 +00:00
Cata
ae45329d2b add: setserverbanner and setservericon commands 2024-05-17 11:29:51 +00:00
Kwoth
f499380fe8 dev: Updated tests package 2024-05-17 11:20:46 +00:00
Kwoth
0083e9ef68 dev: Don't run docker build on mrs as it will always fail
dev: Fixed remove-migration.ps1 script
2024-05-17 11:19:02 +00:00
Kwoth
22b7cf5e6c Merge branch 'v5' into 'v5'
docs: Rewritten Docker guide

See merge request Kwoth/nadekobot!326
2024-05-16 20:52:58 +00:00
Plarpoon
f973766c73 docs: Rewritten Docker guide 2024-05-16 20:52:58 +00:00
Kwoth
0efdd3300d Merge branch 'UpdateDocsYtdlp' into 'v5'
Docs: Replaced youtube-dl with yt-dlp

See merge request Kwoth/nadekobot!325
2024-05-16 15:51:23 +00:00
Cata
5016377dd1 docs: Replaced youtube-dl with yt-dlp 2024-05-16 15:51:22 +00:00
Kwoth
2d40a35112 Merge branch 'v5' into 'v5'
dev: move template creds.yml file into docker

See merge request Kwoth/nadekobot!323
2024-05-15 19:57:32 +00:00
Plarpoon
9ea6cd0b32 dev: creds_example.yml will now be in the docker's data dir/volume 2024-05-15 19:57:32 +00:00
Kwoth
a52a246982 fix: xplb and xpglb pagination fixed, closes #430
fix: Page number when there is an unknown number of items while paginating is now correct
fix: .stm and .stma fixed and can now mention everyone as long as the user executing the command also can
dev: Cleaned up/improved some code
2024-05-15 13:44:37 +00:00
Kwoth
803fe5db2f Merge branch 'v5' into 'v5'
Updating Dockerfile

See merge request Kwoth/nadekobot!322
2024-05-15 07:29:08 +00:00
Plarpoon
39980a1374 Updating Dockerfile 2024-05-15 07:29:08 +00:00
Kwoth
d2c4af273b dev: Version upped 2024-05-15 07:13:28 +00:00
Kwoth
d51dfa88f1 fix: Fixed .ttt and gifted strings
docs: Updated changelog
dev: Updated some packages
2024-05-14 18:36:33 +00:00
Kwoth
869b9d3b9d change: .hearthstone command will no longer show text
dev: removed html2markdown as it was only used for a fluff text of the hearthstone command
2024-05-13 19:09:35 +00:00
Kwoth
f4b26c5b40 dev: removed docker_compose.yml as you don't need redis.
dev: Removed aws package as we don't need gencmdlist to upload commands anymore, have to find a new way though.
2024-05-13 17:34:06 +00:00
Kwoth
15f629ec53 dev: Using built in rng.Shuffle, using some new .net types, removed some transactions 2024-05-13 17:14:35 +00:00
Kwoth
9406a9cc34 dev: Using collection expressions, no functional change 2024-05-13 14:54:24 +00:00
Kwoth
52438f45e1 dev: Added argumentoutofrange static methods, no functional change 2024-05-13 14:50:55 +00:00
Kwoth
7b2ce072ee dev: removed some unused code 2024-05-13 14:26:45 +00:00
Kwoth
89d93dcffb docs: updated command strings for .repeat command to include targetting channels 2024-05-13 14:18:56 +00:00
Kwoth
0fb34b1c61 docs: Updated changelog 2024-05-13 10:53:47 +00:00
Kwoth
980a6b0af8 dev: removed crowdin.yml 2024-05-13 10:48:55 +00:00
Kwoth
5c7a467caa Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-05-13 10:48:18 +00:00
Kwoth
35fd5c415d fix: Blackjack and .pick command responses will no longer reply as the original message will always be deleted 2024-05-13 10:48:05 +00:00
Kwoth
2762108986 Update Crowdin configuration file 2024-05-13 06:49:15 +00:00
Kwoth
876d63fd8b fix: Fixed a blackjack string usage 2024-05-13 06:32:46 +00:00
Kwoth
263ef4b47f fix: Fixed blackjack strings 2024-05-13 06:22:48 +00:00
Kwoth
1c540476d3 dev: Fixed a build warning and small cleanup 2024-05-12 19:00:16 +00:00
Kwoth
1d0f3d3fd6 docs: Removed ubuntu 16.04 and 18.04 from supoported version as there are issues installing .net8 there due to glibc version 2024-05-11 10:49:53 +00:00
Kwoth
c7cec25a29 change: .greet / .bye will get properly disabled if the bot can't write to the specified channel 2024-05-11 08:08:48 +00:00
Kwoth
23c8dc00e8 dev: Upped version to 5.0.5 2024-05-11 08:02:59 +00:00
Kwoth
0da8190637 fix: repeat, greet, bye, boost messages can now once again mention anyone
fix: .say #channel fixed
2024-05-11 08:00:48 +00:00
Kwoth
d766295286 docs: Updated supported distros (thx cata) 2024-05-11 05:57:31 +00:00
Kwoth
21e3c64e01 Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-05-11 02:30:40 +00:00
Kwoth
9ddcd6d89e docs: Updated changelog 2024-05-11 02:05:56 +00:00
Kwoth
a154d5881c docs: Updated changelog 2024-05-10 15:36:12 +00:00
Kwoth
fb594e50fd fix: .h fixed, .xp fixed, pagination in .lb fixed 2024-05-10 15:29:04 +00:00
Kwoth
75c5a003bf fix: cleverbot:response should now be a valid module name 2024-05-10 09:53:20 +00:00
158 changed files with 15117 additions and 1696 deletions

View File

@@ -123,6 +123,8 @@ publish-medusa-package:
stage: publish-medusa-package stage: publish-medusa-package
allow_failure: true allow_failure: true
rules: rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_TAG - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_TAG
script: script:
- LAST_TAG=$(git describe --tags --abbrev=0) - LAST_TAG=$(git describe --tags --abbrev=0)

View File

@@ -2,7 +2,58 @@
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o
## [5.0.3] - 10.05.2024 ## [5.0.8] - 21.05.2024
### Added
- Added `.setserverbanner` and `.setservericon` commands (thx cata)
- Added overloads section to `.h command` which will show you all versions of command usage with param names
- You can now check commands for submodules, for example `.cmds SelfAssignedRoles` will show brief help for each of the commands in that submodule
- Added dropdown menus for .mdls and .cmds (both module and group versions) which will give you the option to see more detailed help for each specific module, group or command respectively
- Self-Hosters only:
- Added a dangerous cleanup command that you don't have to know about
### Changed
- Quotes will now use alphanumerical ids (like expressions)
### Fixed
- `.verbose` will now be respected for expression errors
- Using `.pick` will now correctly show the name of the user who picked the currency
- Fixed `.h` not working on some commands
- `.langset` and `.langsetd` should no longer allow unsupported languages and nonsense to be typed in
## [5.0.7] - 15.05.2024
### Fixed
- `.streammessage` will once again be able to mention anyone (as long as the user setting the message has the permission to mention everyone)
- `.streammsgall` fixed
- `.xplb` and `.xpglb` pagination fixed
- Fixed page number when the total number of elements is unknown
## [5.0.6] - 14.05.2024
### Changed
- `.greet` and `.bye` will now be automatically disabled if the bot losses permissions to post in the specified channel
- Removed response replies from `.blackjack` and `.pick` as the original message will always be deleted
### Fixed
- Fixed `.blackjack` response string as it contained no user name
- Fixed `.ttt` and `.gift` strings not mentioning the user
## [5.0.5] - 11.05.2024
### Fixed
- `%server.members%` placeholder fixed
- `.say #channel <message>` should now be working properly again
- `.repeat`, `.greet`, `.bye` and `.boost` command can now once again mention anyone
## [5.0.4] - 10.05.2024
### Added ### Added

View File

@@ -1,16 +1,25 @@
# Use the .NET 8.0 SDK as the base image for the build stage
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /source WORKDIR /source
# Copy the .csproj files for each project
COPY src/Nadeko.Medusa/*.csproj src/Nadeko.Medusa/ COPY src/Nadeko.Medusa/*.csproj src/Nadeko.Medusa/
COPY src/NadekoBot/*.csproj src/NadekoBot/ COPY src/NadekoBot/*.csproj src/NadekoBot/
COPY src/NadekoBot.Coordinator/*.csproj src/NadekoBot.Coordinator/ COPY src/NadekoBot.Coordinator/*.csproj src/NadekoBot.Coordinator/
COPY src/NadekoBot.Generators/*.csproj src/NadekoBot.Generators/ COPY src/NadekoBot.Generators/*.csproj src/NadekoBot.Generators/
COPY src/NadekoBot.Voice/*.csproj src/NadekoBot.Voice/ COPY src/NadekoBot.Voice/*.csproj src/NadekoBot.Voice/
COPY NuGet.Config ./ COPY NuGet.Config ./
# Restore the dependencies for the NadekoBot project
RUN dotnet restore src/NadekoBot/ RUN dotnet restore src/NadekoBot/
# Copy the rest of the source code
COPY . . COPY . .
# Set the working directory to the NadekoBot project
WORKDIR /source/src/NadekoBot WORKDIR /source/src/NadekoBot
# Build and publish the NadekoBot project, then clean up unnecessary files
RUN set -xe; \ RUN set -xe; \
dotnet --version; \ dotnet --version; \
dotnet publish -c Release -o /app --no-restore; \ dotnet publish -c Release -o /app --no-restore; \
@@ -19,28 +28,33 @@ RUN set -xe; \
find /app -type f -exec chmod -x {} \; ;\ find /app -type f -exec chmod -x {} \; ;\
chmod +x /app/NadekoBot chmod +x /app/NadekoBot
# final stage/image # Use the .NET 8.0 runtime as the base image for the final stage
FROM mcr.microsoft.com/dotnet/runtime:8.0 FROM mcr.microsoft.com/dotnet/runtime:8.0
WORKDIR /app WORKDIR /app
# Create a new user, install dependencies, and set up sudoers file
RUN set -xe; \ RUN set -xe; \
useradd -m nadeko; \ useradd -m nadeko; \
apt-get update; \ apt-get update; \
apt-get install -y --no-install-recommends libopus0 libsodium23 libsqlite3-0 curl ffmpeg python3 sudo; \ apt-get install -y --no-install-recommends libsqlite3-0 curl ffmpeg sudo python3; \
update-alternatives --install /usr/local/bin/python python /usr/bin/python3.9 1; \
echo 'Defaults>nadeko env_keep+="ASPNETCORE_* DOTNET_* NadekoBot_* shard_id total_shards TZ"' > /etc/sudoers.d/nadeko; \ echo 'Defaults>nadeko env_keep+="ASPNETCORE_* DOTNET_* NadekoBot_* shard_id total_shards TZ"' > /etc/sudoers.d/nadeko; \
curl -Lo /usr/local/bin/yt-dlp https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp; \ curl -Lo /usr/local/bin/yt-dlp https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp; \
chmod a+rx /usr/local/bin/yt-dlp; \ chmod a+rx /usr/local/bin/yt-dlp; \
apt-get autoremove -y; \ apt-get autoremove -y; \
apt-get autoclean -y apt-get autoclean -y
# Copy the built application and the entrypoint script from the build stage
COPY --from=build /app ./ COPY --from=build /app ./
COPY docker-entrypoint.sh /usr/local/sbin COPY docker-entrypoint.sh /usr/local/sbin
# Set environment variables
ENV shard_id=0 ENV shard_id=0
ENV total_shards=1 ENV total_shards=1
ENV NadekoBot__creds=/app/data/creds.yml ENV NadekoBot__creds=/app/data/creds.yml
# Define the data directory as a volume
VOLUME [ "/app/data" ] VOLUME [ "/app/data" ]
# Set the entrypoint and default command
ENTRYPOINT [ "/usr/local/sbin/docker-entrypoint.sh" ] ENTRYPOINT [ "/usr/local/sbin/docker-entrypoint.sh" ]
CMD dotnet NadekoBot.dll "$shard_id" "$total_shards" CMD dotnet NadekoBot.dll "$shard_id" "$total_shards"

View File

@@ -1,23 +0,0 @@
version: "3.7"
services:
nadeko:
image: insert-image-name-here:latest
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:/app/conf: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

View File

@@ -1,46 +1,76 @@
# Setting up NadekoBot with Docker # Deploying NadekoBot with Docker: A Comprehensive Guide
# WORK IN PROGRESS ## Getting Started
### Installation Ensure Docker and Docker Compose are installed on your system. If not, follow the official Docker guides for your specific operating system:
- [Docker Installation Guide](https://docs.docker.com/engine/install/)
- [Docker Compose Installation Guide](https://docs.docker.com/compose/install/)
## Step-by-Step Installation
1. **Choose Your Workspace:** Select a directory where you'll set up your NadekoBot stack. Use your terminal to navigate to this directory. For the purpose of this guide, we'll use `/opt/stacks/nadekobot/` as an example, but you can choose any directory that suits your needs.
2. **Create a Docker Compose File:** In this directory, create a Docker Compose file named `docker-compose.yml`. You can use any text editor for this task. For instance, to use the `nano` editor, type `nano docker-compose.yml`.
3. **Configure Your Docker Compose File:** Populate your Docker Compose file with the following configuration:
1. Create a `/srv/nadeko` folder
- `mkdir -p /srv/nadeko`
2. Create a `docker-compose.yml`
- nano `docker-compose.yml`
- copy the following contents into it:
##### docker-compose.yml
```yml ```yml
version: "3.7"
services: services:
nadeko: nadeko:
image: registry.gitlab.com/kwoth/nadekobot:latest image: registry.gitlab.com/kwoth/nadekobot:latest
depends_on: container_name: nadeko
- redis restart: unless-stopped
environment: environment:
TZ: Europe/Paris TZ: Europe/Rome
NadekoBot_RedisOptions: redis,name=nadeko
#NadekoBot_ShardRunCommand: dotnet
#NadekoBot_ShardRunArguments: /app/NadekoBot.dll {0} {1}
volumes: volumes:
- /srv/nadeko/conf/creds.yml:/app/creds.yml:ro - /opt/stacks/nadekobot/conf/creds.yml:/app/data/creds.yml
- /srv/nadeko/data:/app/data - /opt/stacks/nadekobot/data:/app/data
networks: {}
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
``` ```
3. Save your file and run docker compose
- `docker-compose up`
4. Edit creds in `/srv/nadeko/conf/creds.yml`
5. Run it again with
- `docker-compose up`
### Updating 4. **Prepare Your Credentials File:** Before running Docker Compose, ensure the `creds.yml` file exists in the `/opt/stacks/nadekobot/conf/` directory. If it's missing, create it using `touch /opt/stacks/nadekobot/conf/creds.yml`. You may need to use `sudo`. Remember to replace `/opt/stacks/nadekobot/` with your chosen directory.
- `cd /srv/nadeko`
- `docker-compose pull` 5. **Edit Your Credentials File:** Populate the `creds.yml` file in `/opt/stacks/nadekobot/conf/creds.yml` with your bot's credentials. You can use any text editor for this task. For instance, to use the `nano` editor, type `nano /opt/stacks/nadekobot/conf/creds.yml`. You may need to use `sudo`. Again, replace `/opt/stacks/nadekobot/` with your chosen directory.
- `docker-compose up -d`
6. **Launch Your Bot:** Now, you're ready to run Docker Compose. Use the following command: `docker-compose up -d`.
## Keeping Your Bot Up-to-Date
There are two methods to update your NadekoBot:
### Manual Update
1. **Navigate to Your Directory:** Use `cd /path/to/your/directory` to go to the directory containing your Docker Compose file.
2. **Pull the Latest Images:** Use `docker-compose pull` to fetch the latest images.
3. **Restart Your Containers:** Use `docker-compose up -d` to restart the containers.
### Automatic Update with Watchtower
If you prefer an automated update process, consider using Watchtower. Watchtower automatically updates your Docker containers to the latest versions.
To use Watchtower with NadekoBot, you need to add a specific label to the service in your Docker Compose file. Here's how your Docker Compose file should look:
```yml
services:
nadeko:
image: registry.gitlab.com/kwoth/nadekobot:latest
container_name: nadeko
restart: unless-stopped
labels:
- com.centurylinklabs.watchtower.enable=true
environment:
TZ: Europe/Rome
volumes:
- /opt/stacks/nadekobot/conf/creds.yml:/app/data/creds.yml
- /opt/stacks/nadekobot/data:/app/data
networks: {}
```
Remember to replace `/opt/stacks/nadekobot/` with your chosen directory in the Docker Compose file.
To install and run Watchtower, follow the guide provided by Containrrr:
- [Watchtower Installation and Usage Guide](https://containrrr.dev/watchtower/)

View File

@@ -15,11 +15,13 @@
##### Compatible operating systems: ##### Compatible operating systems:
- Ubuntu: 20.04, 22.04, 22.10 + - Ubuntu: 20.04, 22.04, 24.04
- Debian: 11 + - Mint: 19, 20, 21
- CentOS: 7 - Debian: 10, 11, 12
- openSUSE 15 - RockyLinux: 8, 9
- Fedora: 33, 34, 35 - AlmaLinux: 8, 9
- openSUSE Leap: 15.5, 15.6 & Tumbleweed
- Fedora: 38, 39, 40, 41, 42
## Linux From Source ## Linux From Source
@@ -68,11 +70,11 @@ Open Terminal (if you're on an installation with a window manager) and navigate
1. (Optional) Installing Redis 1. (Optional) Installing Redis
- ubuntu installation command: `sudo apt-get install redis-server` - ubuntu installation command: `sudo apt-get install redis-server`
2. Playing music requires `ffmpeg`, `libopus`, `libsodium` and `youtube-dl` (which in turn requires python3) 2. Playing music requires `ffmpeg`, `libopus`, `libsodium` and `yt-dlp` (which in turn requires python3)
- ubuntu installation command: `sudo apt-get install ffmpeg libopus0 opus-tools libopus-dev libsodium-dev -y` - Ubuntu installation command: `sudo apt-get install ffmpeg libopus0 opus-tools libopus-dev libsodium-dev -y`
- yt-dlp installation command: `sudo wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp && sudo chmod a+rx /usr/local/bin/yt-dlp`
3. Make sure your python is version 3+ with `python --version` 3. Make sure your python is version 3+ with `python --version`
- if it's not, you can install python 3 and make it the default with: `sudo apt-get install python3.8 python-is-python3` - if it's not, you can install python 3 and make it the default with: `sudo apt-get install python3.8 python-is-python3`
*You can use nadeko bash script [prerequisites installer](https://gitlab.com/kwoth/nadeko-bash-installer/-/blob/v5/n-prereq.sh) as a reference* *You can use nadeko bash script [prerequisites installer](https://gitlab.com/kwoth/nadeko-bash-installer/-/blob/v5/n-prereq.sh) as a reference*
##### Installation Instructions ##### Installation Instructions
@@ -266,7 +268,7 @@ This method is similar to the one above, but requires one extra step, with the a
echo '#!/bin/bash' echo '#!/bin/bash'
echo "" echo ""
echo "echo \"Running NadekoBot in the background with auto restart\" echo "echo \"Running NadekoBot in the background with auto restart\"
youtube-dl -U yt-dlp -U
# If you want Nadeko to be compiled prior to every startup, uncomment the lines # If you want Nadeko to be compiled prior to every startup, uncomment the lines
# below. Note that it's not necessary unless you are personally modifying the # below. Note that it's not necessary unless you are personally modifying the
@@ -298,7 +300,7 @@ This method is similar to the one above, but requires one extra step, with the a
echo \"Waiting for 5 seconds...\" echo \"Waiting for 5 seconds...\"
sleep 5 sleep 5
youtube-dl -U yt-dlp -U
echo \"Restarting NadekoBot...\" echo \"Restarting NadekoBot...\"
done done

View File

@@ -93,8 +93,12 @@ Open PowerShell as described above and run the following commands:
- ⚠️ 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 - ⚠️ 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
2. Navigate to your bot's folder, example: 2. Navigate to your bot's folder, example:
- `cd ~/Desktop/nadekobot` - `cd ~/Desktop/nadekobot`
3. Pull the new version 3. Pull the new version, and make sure you're on the v5 branch
- `git pull` - *⚠️ the first 3 lines can be omitted if you're already on v5. If you're updating from v4, you must run them*
- `git remote set-branches origin '*'`
- `git fetch -v --depth=1`
- `git checkout v5`
- `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 - ⚠️ If this fails, you may want to stash or remove your code changes if you don't know how to resolve merge conflicts
4. **Backup** old output in case your data is overwritten 4. **Backup** old output in case your data is overwritten
- `cp -r -fo output/ output-old` - `cp -r -fo output/ output-old`

View File

@@ -1,4 +1,4 @@
dotnet ef migrations remove -c SqliteContext -f dotnet ef migrations remove -c SqliteContext -f -p src/NadekoBot/NadekoBot.csproj
dotnet ef migrations remove -c PostgreSqlContext -f dotnet ef migrations remove -c PostgreSqlContext -f -p src/NadekoBot/NadekoBot.csproj
dotnet ef migrations remove -c MysqlContext -f dotnet ef migrations remove -c MysqlContext -f -p src/NadekoBot/NadekoBot.csproj

View File

@@ -11,7 +11,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Discord.Net.Core" Version="3.204.0" /> <PackageReference Include="Discord.Net.Core" Version="3.204.0" />
<PackageReference Include="Serilog" Version="3.1.1" /> <PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="YamlDotNet" Version="15.1.2" /> <PackageReference Include="YamlDotNet" Version="15.1.4" />
</ItemGroup> </ItemGroup>
<PropertyGroup Condition=" '$(Version)' == '' "> <PropertyGroup Condition=" '$(Version)' == '' ">

View File

@@ -14,7 +14,7 @@
<PackageReference Include="Serilog" Version="3.1.1" /> <PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="YamlDotNet" Version="15.1.2" /> <PackageReference Include="YamlDotNet" Version="15.1.4" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -417,8 +417,7 @@ namespace NadekoBot.Coordinator
{ {
lock (locker) lock (locker)
{ {
if (shardId >= _shardStatuses.Length) ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(shardId, _shardStatuses.Length);
throw new ArgumentOutOfRangeException(nameof(shardId));
return _shardStatuses[shardId]; return _shardStatuses[shardId];
} }

View File

@@ -8,7 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="NUnit" Version="3.13.3" /> <PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" /> <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
</ItemGroup> </ItemGroup>

View File

@@ -80,10 +80,10 @@ public sealed class Bot : IBot
// _interactionService = new(Client.Rest); // _interactionService = new(Client.Rest);
Client.Log += Client_Log; Client.Log += Client_Log;
_loadedAssemblies = new[] _loadedAssemblies =
{ [
typeof(Bot).Assembly, // bot typeof(Bot).Assembly // bot
}; ];
} }

View File

@@ -20,48 +20,48 @@ public static class DiscordUserExtensions
string discrim, string discrim,
string avatarId) string avatarId)
=> ctx.GetTable<DiscordUser>() => ctx.GetTable<DiscordUser>()
.InsertOrUpdate( .InsertOrUpdate(
() => new() () => new()
{ {
UserId = userId, UserId = userId,
Username = username, Username = username,
Discriminator = discrim, Discriminator = discrim,
AvatarId = avatarId, AvatarId = avatarId,
TotalXp = 0, TotalXp = 0,
CurrencyAmount = 0 CurrencyAmount = 0
}, },
old => new() old => new()
{ {
Username = username, Username = username,
Discriminator = discrim, Discriminator = discrim,
AvatarId = avatarId AvatarId = avatarId
}, },
() => new() () => new()
{ {
UserId = userId UserId = userId
}); });
public static Task EnsureUserCreatedAsync( public static Task EnsureUserCreatedAsync(
this DbContext ctx, this DbContext ctx,
ulong userId) ulong userId)
=> ctx.GetTable<DiscordUser>() => ctx.GetTable<DiscordUser>()
.InsertOrUpdateAsync( .InsertOrUpdateAsync(
() => new() () => new()
{ {
UserId = userId, UserId = userId,
Username = "Unknown", Username = "Unknown",
Discriminator = "????", Discriminator = "????",
AvatarId = string.Empty, AvatarId = string.Empty,
TotalXp = 0, TotalXp = 0,
CurrencyAmount = 0 CurrencyAmount = 0
}, },
old => new() old => new()
{ {
}, },
() => new() () => new()
{ {
UserId = userId UserId = userId
}); });
//temp is only used in updatecurrencystate, so that i don't overwrite real usernames/discrims with Unknown //temp is only used in updatecurrencystate, so that i don't overwrite real usernames/discrims with Unknown
public static DiscordUser GetOrCreateUser( public static DiscordUser GetOrCreateUser(
@@ -83,25 +83,29 @@ public static class DiscordUserExtensions
public static int GetUserGlobalRank(this DbSet<DiscordUser> users, ulong id) public static int GetUserGlobalRank(this DbSet<DiscordUser> users, ulong id)
=> users.AsQueryable() => users.AsQueryable()
.Where(x => x.TotalXp .Where(x => x.TotalXp
> users.AsQueryable().Where(y => y.UserId == id).Select(y => y.TotalXp).FirstOrDefault()) > users.AsQueryable().Where(y => y.UserId == id).Select(y => y.TotalXp).FirstOrDefault())
.Count() .Count()
+ 1; + 1;
public static DiscordUser[] GetUsersXpLeaderboardFor(this DbSet<DiscordUser> users, int page, int perPage) public static async Task<IReadOnlyCollection<DiscordUser>> GetUsersXpLeaderboardFor(this DbSet<DiscordUser> users, int page, int perPage)
=> users.AsQueryable().OrderByDescending(x => x.TotalXp).Skip(page * perPage).Take(perPage).AsEnumerable() => await users.ToLinqToDBTable()
.ToArray(); .OrderByDescending(x => x.TotalXp)
.Skip(page * perPage)
.Take(perPage)
.ToArrayAsyncLinqToDB();
public static Task<List<DiscordUser>> GetTopRichest( public static Task<List<DiscordUser>> GetTopRichest(
this DbSet<DiscordUser> users, this DbSet<DiscordUser> users,
ulong botId, ulong botId,
int page = 0, int perPage = 9) int page = 0,
int perPage = 9)
=> users.AsQueryable() => users.AsQueryable()
.Where(c => c.CurrencyAmount > 0 && botId != c.UserId) .Where(c => c.CurrencyAmount > 0 && botId != c.UserId)
.OrderByDescending(c => c.CurrencyAmount) .OrderByDescending(c => c.CurrencyAmount)
.Skip(page * perPage) .Skip(page * perPage)
.Take(perPage) .Take(perPage)
.ToListAsyncLinqToDB(); .ToListAsyncLinqToDB();
public static async Task<long> GetUserCurrencyAsync(this DbSet<DiscordUser> users, ulong userId) public static async Task<long> GetUserCurrencyAsync(this DbSet<DiscordUser> users, ulong userId)
=> (await users.FirstOrDefaultAsyncLinqToDB(x => x.UserId == userId))?.CurrencyAmount ?? 0; => (await users.FirstOrDefaultAsyncLinqToDB(x => x.UserId == userId))?.CurrencyAmount ?? 0;
@@ -118,8 +122,8 @@ public static class DiscordUserExtensions
public static decimal GetTopOnePercentCurrency(this DbSet<DiscordUser> users, ulong botId) public static decimal GetTopOnePercentCurrency(this DbSet<DiscordUser> users, ulong botId)
=> users.AsQueryable() => users.AsQueryable()
.Where(x => x.UserId != botId) .Where(x => x.UserId != botId)
.OrderByDescending(x => x.CurrencyAmount) .OrderByDescending(x => x.CurrencyAmount)
.Take(users.Count() / 100 == 0 ? 1 : users.Count() / 100) .Take(users.Count() / 100 == 0 ? 1 : users.Count() / 100)
.Sum(x => x.CurrencyAmount); .Sum(x => x.CurrencyAmount);
} }

View File

@@ -7,19 +7,20 @@ namespace NadekoBot.Db;
public static class GuildConfigExtensions public static class GuildConfigExtensions
{ {
private static List<WarningPunishment> DefaultWarnPunishments private static List<WarningPunishment> DefaultWarnPunishments
=> new() =>
{ [
new() new()
{ {
Count = 3, Count = 3,
Punishment = PunishmentAction.Kick Punishment = PunishmentAction.Kick
}, },
new() new()
{ {
Count = 5, Count = 5,
Punishment = PunishmentAction.Ban Punishment = PunishmentAction.Ban
} }
}; ];
/// <summary> /// <summary>
/// Gets full stream role settings for the guild with the specified id. /// Gets full stream role settings for the guild with the specified id.

View File

@@ -2,7 +2,6 @@
using LinqToDB; using LinqToDB;
using LinqToDB.EntityFrameworkCore; using LinqToDB.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NadekoBot.Db.Models; using NadekoBot.Db.Models;
namespace NadekoBot.Db; namespace NadekoBot.Db;
@@ -27,33 +26,33 @@ public static class UserXpExtensions
return usr; return usr;
} }
public static List<UserXpStats> GetUsersFor(this DbSet<UserXpStats> xps, ulong guildId, int page) public static async Task<IReadOnlyCollection<UserXpStats>> GetUsersFor(
=> xps.AsQueryable() this DbSet<UserXpStats> xps,
.AsNoTracking() ulong guildId,
.Where(x => x.GuildId == guildId) int page)
.OrderByDescending(x => x.Xp + x.AwardedXp) => await xps.ToLinqToDBTable()
.Skip(page * 9) .Where(x => x.GuildId == guildId)
.Take(9) .OrderByDescending(x => x.Xp + x.AwardedXp)
.ToList(); .Skip(page * 9)
.Take(9)
.ToArrayAsyncLinqToDB();
public static List<UserXpStats> GetTopUserXps(this DbSet<UserXpStats> xps, ulong guildId, int count) public static async Task<List<UserXpStats>> GetTopUserXps(this DbSet<UserXpStats> xps, ulong guildId, int count)
=> xps.AsQueryable() => await xps.ToLinqToDBTable()
.AsNoTracking() .Where(x => x.GuildId == guildId)
.Where(x => x.GuildId == guildId) .OrderByDescending(x => x.Xp + x.AwardedXp)
.OrderByDescending(x => x.Xp + x.AwardedXp) .Take(count)
.Take(count) .ToListAsyncLinqToDB();
.ToList();
public static int GetUserGuildRanking(this DbSet<UserXpStats> xps, ulong userId, ulong guildId) public static async Task<int> GetUserGuildRanking(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
=> xps.AsQueryable() => await xps.ToLinqToDBTable()
.AsNoTracking() .Where(x => x.GuildId == guildId
.Where(x => x.GuildId == guildId && x.Xp + x.AwardedXp
&& x.Xp + x.AwardedXp > xps.AsQueryable()
> xps.AsQueryable() .Where(y => y.UserId == userId && y.GuildId == guildId)
.Where(y => y.UserId == userId && y.GuildId == guildId) .Select(y => y.Xp + y.AwardedXp)
.Select(y => y.Xp + y.AwardedXp) .FirstOrDefault())
.FirstOrDefault()) .CountAsyncLinqToDB()
.Count()
+ 1; + 1;
public static void ResetGuildUserXp(this DbSet<UserXpStats> xps, ulong userId, ulong guildId) public static void ResetGuildUserXp(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
@@ -61,12 +60,11 @@ public static class UserXpExtensions
public static void ResetGuildXp(this DbSet<UserXpStats> xps, ulong guildId) public static void ResetGuildXp(this DbSet<UserXpStats> xps, ulong guildId)
=> xps.Delete(x => x.GuildId == guildId); => xps.Delete(x => x.GuildId == guildId);
public static async Task<LevelStats> GetLevelDataFor(this ITable<UserXpStats> userXp, ulong guildId, ulong userId) public static async Task<LevelStats> GetLevelDataFor(this ITable<UserXpStats> userXp, ulong guildId, ulong userId)
=> await userXp => await userXp
.Where(x => x.GuildId == guildId && x.UserId == userId) .Where(x => x.GuildId == guildId && x.UserId == userId)
.FirstOrDefaultAsyncLinqToDB() is UserXpStats uxs .FirstOrDefaultAsyncLinqToDB() is UserXpStats uxs
? new(uxs.Xp + uxs.AwardedXp) ? new(uxs.Xp + uxs.AwardedXp)
: new(0); : new(0);
} }

View File

@@ -22,8 +22,7 @@ public static class WarningExtensions
string mod, string mod,
int index) int index)
{ {
if (index < 0) ArgumentOutOfRangeException.ThrowIfNegative(index);
throw new ArgumentOutOfRangeException(nameof(index));
var warn = warnings.AsQueryable() var warn = warnings.AsQueryable()
.Where(x => x.GuildId == guildId && x.UserId == userId) .Where(x => x.GuildId == guildId && x.UserId == userId)

View File

@@ -3,6 +3,8 @@ namespace NadekoBot.Db.Models;
public class DelMsgOnCmdChannel : DbEntity public class DelMsgOnCmdChannel : DbEntity
{ {
public int GuildConfigId { get; set; }
public ulong ChannelId { get; set; } public ulong ChannelId { get; set; }
public bool State { get; set; } public bool State { get; set; }

View File

@@ -3,6 +3,7 @@ namespace NadekoBot.Db.Models;
public class GuildConfig : DbEntity public class GuildConfig : DbEntity
{ {
// public bool Keep { get; set; }
public ulong GuildId { get; set; } public ulong GuildId { get; set; }
public string Prefix { get; set; } public string Prefix { get; set; }

View File

@@ -1,8 +0,0 @@
#nullable disable
namespace NadekoBot.Db.Models;
public class IgnoredVoicePresenceChannel : DbEntity
{
public LogSetting LogSetting { get; set; }
public ulong ChannelId { get; set; }
}

View File

@@ -33,10 +33,7 @@ public class Permissionv2 : DbEntity, IIndexed
}; };
public static List<Permissionv2> GetDefaultPermlist public static List<Permissionv2> GetDefaultPermlist
=> new() => [AllowAllPerm];
{
AllowAllPerm
};
} }
public enum PrimaryPermissionType public enum PrimaryPermissionType

View File

@@ -40,6 +40,9 @@ public class StreamRoleSettings : DbEntity
public class StreamRoleBlacklistedUser : DbEntity public class StreamRoleBlacklistedUser : DbEntity
{ {
public int StreamRoleSettingsId { get; set; }
public StreamRoleSettings StreamRoleSettings { get; set; }
public ulong UserId { get; set; } public ulong UserId { get; set; }
public string Username { get; set; } public string Username { get; set; }
@@ -57,6 +60,9 @@ public class StreamRoleBlacklistedUser : DbEntity
public class StreamRoleWhitelistedUser : DbEntity public class StreamRoleWhitelistedUser : DbEntity
{ {
public int StreamRoleSettingsId { get; set; }
public StreamRoleSettings StreamRoleSettings { get; set; }
public ulong UserId { get; set; } public ulong UserId { get; set; }
public string Username { get; set; } public string Username { get; set; }

View File

@@ -2,8 +2,9 @@
public class AntiAltSetting public class AntiAltSetting
{ {
public int Id { get; set; }
public int GuildConfigId { get; set; } public int GuildConfigId { get; set; }
public int Id { get; set; }
public TimeSpan MinAge { get; set; } public TimeSpan MinAge { get; set; }
public PunishmentAction Action { get; set; } public PunishmentAction Action { get; set; }
public int ActionDurationMinutes { get; set; } public int ActionDurationMinutes { get; set; }

View File

@@ -1,12 +1,13 @@
#nullable disable #nullable disable
using System.ComponentModel.DataAnnotations.Schema;
namespace NadekoBot.Db.Models; namespace NadekoBot.Db.Models;
public class AntiRaidSetting : DbEntity public class AntiRaidSetting : DbEntity
{ {
public int GuildConfigId { get; set; } public int GuildConfigId { get; set; }
public GuildConfig GuildConfig { get; set; }
public int UserThreshold { get; set; } public int UserThreshold { get; set; }
public int Seconds { get; set; } public int Seconds { get; set; }
public PunishmentAction Action { get; set; } public PunishmentAction Action { get; set; }

View File

@@ -4,8 +4,7 @@
public class AntiSpamSetting : DbEntity public class AntiSpamSetting : DbEntity
{ {
public int GuildConfigId { get; set; } public int GuildConfigId { get; set; }
public GuildConfig GuildConfig { get; set; }
public PunishmentAction Action { get; set; } public PunishmentAction Action { get; set; }
public int MessageThreshold { get; set; } = 3; public int MessageThreshold { get; set; } = 3;
public int MuteTime { get; set; } public int MuteTime { get; set; }

View File

@@ -14,17 +14,3 @@ public class FilterChannelId : DbEntity
public override int GetHashCode() public override int GetHashCode()
=> ChannelId.GetHashCode(); => ChannelId.GetHashCode();
} }
public class FilterWordsChannelId : DbEntity
{
public ulong ChannelId { get; set; }
public bool Equals(FilterWordsChannelId other)
=> ChannelId == other.ChannelId;
public override bool Equals(object obj)
=> obj is FilterWordsChannelId fci && Equals(fci);
public override int GetHashCode()
=> ChannelId.GetHashCode();
}

View File

@@ -0,0 +1,17 @@
#nullable disable
namespace NadekoBot.Db.Models;
public class FilterWordsChannelId : DbEntity
{
public int? GuildConfigId { get; set; }
public ulong ChannelId { get; set; }
public bool Equals(FilterWordsChannelId other)
=> ChannelId == other.ChannelId;
public override bool Equals(object obj)
=> obj is FilterWordsChannelId fci && Equals(fci);
public override int GetHashCode()
=> ChannelId.GetHashCode();
}

View File

@@ -51,6 +51,8 @@ public class XpCurrencyReward : DbEntity
public class ExcludedItem : DbEntity public class ExcludedItem : DbEntity
{ {
public XpSettings XpSettings { get; set; }
public ulong ItemId { get; set; } public ulong ItemId { get; set; }
public ExcludedItemType ItemType { get; set; } public ExcludedItemType ItemType { get; set; }

View File

@@ -28,7 +28,6 @@ public abstract class NadekoContext : DbContext
//logging //logging
public DbSet<LogSetting> LogSettings { get; set; } public DbSet<LogSetting> LogSettings { get; set; }
public DbSet<IgnoredVoicePresenceChannel> IgnoredVoicePresenceCHannels { get; set; }
public DbSet<IgnoredLogItem> IgnoredLogChannels { get; set; } public DbSet<IgnoredLogItem> IgnoredLogChannels { get; set; }
public DbSet<RotatingPlayingStatus> RotatingStatus { get; set; } public DbSet<RotatingPlayingStatus> RotatingStatus { get; set; }
@@ -55,14 +54,14 @@ public abstract class NadekoContext : DbContext
public DbSet<PatronUser> Patrons { get; set; } public DbSet<PatronUser> Patrons { get; set; }
public DbSet<PatronQuota> PatronQuotas { get; set; } public DbSet<PatronQuota> PatronQuotas { get; set; }
public DbSet<StreamOnlineMessage> StreamOnlineMessages { get; set; } public DbSet<StreamOnlineMessage> StreamOnlineMessages { get; set; }
public DbSet<StickyRole> StickyRoles { get; set; } public DbSet<StickyRole> StickyRoles { get; set; }
public DbSet<TodoModel> Todos { get; set; } public DbSet<TodoModel> Todos { get; set; }
public DbSet<ArchivedTodoListModel> TodosArchive { get; set; } public DbSet<ArchivedTodoListModel> TodosArchive { get; set; }
// todo add guild colors // todo add guild colors
// public DbSet<GuildColors> GuildColors { get; set; } // public DbSet<GuildColors> GuildColors { get; set; }
@@ -86,15 +85,84 @@ public abstract class NadekoContext : DbContext
#region GuildConfig #region GuildConfig
var configEntity = modelBuilder.Entity<GuildConfig>(); var configEntity = modelBuilder.Entity<GuildConfig>();
configEntity.HasIndex(c => c.GuildId) configEntity.HasIndex(c => c.GuildId)
.IsUnique(); .IsUnique();
configEntity.Property(x => x.VerboseErrors) configEntity.Property(x => x.VerboseErrors)
.HasDefaultValue(true); .HasDefaultValue(true);
modelBuilder.Entity<AntiSpamSetting>().HasOne(x => x.GuildConfig).WithOne(x => x.AntiSpamSetting); modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.DelMsgOnCmdChannels)
.WithOne()
.HasForeignKey(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<AntiRaidSetting>().HasOne(x => x.GuildConfig).WithOne(x => x.AntiRaidSetting); modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.FollowedStreams)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.GenerateCurrencyChannelIds)
.WithOne(x => x.GuildConfig)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.Permissions)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.CommandCooldowns)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.FilterInvitesChannelIds)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.FilterLinksChannelIds)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.FilteredWords)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.FilterWordsChannelIds)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.MutedUsers)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasOne(x => x.AntiRaidSetting)
.WithOne()
.HasForeignKey<AntiRaidSetting>(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade);
// start antispam
modelBuilder.Entity<GuildConfig>()
.HasOne(x => x.AntiSpamSetting)
.WithOne()
.HasForeignKey<AntiSpamSetting>(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<AntiSpamSetting>()
.HasMany(x => x.IgnoredChannels)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
// end antispam
modelBuilder.Entity<GuildConfig>() modelBuilder.Entity<GuildConfig>()
.HasOne(x => x.AntiAltSetting) .HasOne(x => x.AntiAltSetting)
@@ -102,6 +170,98 @@ public abstract class NadekoContext : DbContext
.HasForeignKey<AntiAltSetting>(x => x.GuildConfigId) .HasForeignKey<AntiAltSetting>(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.UnmuteTimers)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.UnbanTimer)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.UnroleTimer)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.VcRoleInfos)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.CommandAliases)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.WarnPunishments)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.SlowmodeIgnoredRoles)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.SlowmodeIgnoredUsers)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
// start shop
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.ShopEntries)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<ShopEntry>()
.HasMany(x => x.Items)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
// end shop
// start streamrole
modelBuilder.Entity<GuildConfig>()
.HasOne(x => x.StreamRole)
.WithOne(x => x.GuildConfig)
.HasForeignKey<StreamRoleSettings>(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<StreamRoleSettings>()
.HasMany(x => x.Whitelist)
.WithOne(x => x.StreamRoleSettings)
.HasForeignKey(x => x.StreamRoleSettingsId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<StreamRoleSettings>()
.HasMany(x => x.Blacklist)
.WithOne(x => x.StreamRoleSettings)
.HasForeignKey(x => x.StreamRoleSettingsId)
.OnDelete(DeleteBehavior.Cascade);
// end streamrole
modelBuilder.Entity<GuildConfig>()
.HasOne(x => x.XpSettings)
.WithOne(x => x.GuildConfig)
.HasForeignKey<XpSettings>(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.FeedSubs)
.WithOne(x => x.GuildConfig)
.HasForeignKey(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.SelfAssignableRoleGroupNames)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<FeedSub>() modelBuilder.Entity<FeedSub>()
.HasAlternateKey(x => new .HasAlternateKey(x => new
{ {
@@ -117,11 +277,6 @@ public abstract class NadekoContext : DbContext
#endregion #endregion
#region streamrole
modelBuilder.Entity<StreamRoleSettings>().HasOne(x => x.GuildConfig).WithOne(x => x.StreamRole);
#endregion
#region Self Assignable Roles #region Self Assignable Roles
@@ -217,12 +372,6 @@ public abstract class NadekoContext : DbContext
#endregion #endregion
#region XpSettings
modelBuilder.Entity<XpSettings>().HasOne(x => x.GuildConfig).WithOne(x => x.XpSettings);
#endregion
#region XpRoleReward #region XpRoleReward
modelBuilder.Entity<XpRoleReward>() modelBuilder.Entity<XpRoleReward>()
@@ -233,6 +382,21 @@ public abstract class NadekoContext : DbContext
}) })
.IsUnique(); .IsUnique();
modelBuilder.Entity<XpSettings>()
.HasMany(x => x.RoleRewards)
.WithOne(x => x.XpSettings)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<XpSettings>()
.HasMany(x => x.CurrencyRewards)
.WithOne(x => x.XpSettings)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<XpSettings>()
.HasMany(x => x.ExclusionList)
.WithOne(x => x.XpSettings)
.OnDelete(DeleteBehavior.Cascade);
#endregion #endregion
#region Club #region Club
@@ -331,9 +495,9 @@ public abstract class NadekoContext : DbContext
modelBuilder.Entity<BanTemplate>().HasIndex(x => x.GuildId).IsUnique(); modelBuilder.Entity<BanTemplate>().HasIndex(x => x.GuildId).IsUnique();
modelBuilder.Entity<BanTemplate>() modelBuilder.Entity<BanTemplate>()
.Property(x => x.PruneDays) .Property(x => x.PruneDays)
.HasDefaultValue(null) .HasDefaultValue(null)
.IsRequired(false); .IsRequired(false);
#endregion #endregion
@@ -445,7 +609,7 @@ public abstract class NadekoContext : DbContext
}); });
#endregion #endregion
#region Xp Item Shop #region Xp Item Shop
modelBuilder.Entity<XpShopOwnedItem>( modelBuilder.Entity<XpShopOwnedItem>(
@@ -453,76 +617,77 @@ public abstract class NadekoContext : DbContext
{ {
// user can own only one of each item // user can own only one of each item
x.HasIndex(model => new x.HasIndex(model => new
{ {
model.UserId, model.UserId,
model.ItemType, model.ItemType,
model.ItemKey model.ItemKey
}) })
.IsUnique(); .IsUnique();
}); });
#endregion #endregion
#region AutoPublish #region AutoPublish
modelBuilder.Entity<AutoPublishChannel>(apc => apc modelBuilder.Entity<AutoPublishChannel>(apc => apc
.HasIndex(x => x.GuildId) .HasIndex(x => x.GuildId)
.IsUnique()); .IsUnique());
#endregion #endregion
#region GamblingStats #region GamblingStats
modelBuilder.Entity<GamblingStats>(gs => gs modelBuilder.Entity<GamblingStats>(gs => gs
.HasIndex(x => x.Feature) .HasIndex(x => x.Feature)
.IsUnique()); .IsUnique());
#endregion #endregion
#region Sticky Roles #region Sticky Roles
modelBuilder.Entity<StickyRole>(sr => sr.HasIndex(x => new modelBuilder.Entity<StickyRole>(sr => sr.HasIndex(x => new
{ {
x.GuildId, x.GuildId,
x.UserId x.UserId
}).IsUnique()); })
.IsUnique());
#endregion #endregion
#region Giveaway #region Giveaway
modelBuilder.Entity<GiveawayModel>() modelBuilder.Entity<GiveawayModel>()
.HasMany(x => x.Participants) .HasMany(x => x.Participants)
.WithOne() .WithOne()
.HasForeignKey(x => x.GiveawayId) .HasForeignKey(x => x.GiveawayId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GiveawayUser>(gu => gu modelBuilder.Entity<GiveawayUser>(gu => gu
.HasIndex(x => new .HasIndex(x => new
{ {
x.GiveawayId, x.GiveawayId,
x.UserId x.UserId
}) })
.IsUnique()); .IsUnique());
#endregion #endregion
#region Todo #region Todo
modelBuilder.Entity<TodoModel>() modelBuilder.Entity<TodoModel>()
.HasKey(x => x.Id); .HasKey(x => x.Id);
modelBuilder.Entity<TodoModel>() modelBuilder.Entity<TodoModel>()
.HasIndex(x => x.UserId) .HasIndex(x => x.UserId)
.IsUnique(false); .IsUnique(false);
modelBuilder.Entity<ArchivedTodoListModel>() modelBuilder.Entity<ArchivedTodoListModel>()
.HasMany(x => x.Items) .HasMany(x => x.Items)
.WithOne() .WithOne()
.HasForeignKey(x => x.ArchiveId) .HasForeignKey(x => x.ArchiveId)
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
#endregion #endregion
} }

View File

@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using NadekoBot.Db.Models;
namespace NadekoBot.Migrations; namespace NadekoBot.Migrations;
@@ -39,4 +40,15 @@ left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;")
throw new NotSupportedException("This database provider doesn't have an implementation for MigrateRero"); throw new NotSupportedException("This database provider doesn't have an implementation for MigrateRero");
} }
} }
public static void GuildConfigCleanup(MigrationBuilder builder)
{
builder.Sql($"""
DELETE FROM "StreamRoleBlacklistedUser" WHERE "StreamRoleSettingsId" is NULL;
""");
builder.Sql($"""
DELETE FROM "DelMsgOnCmdChannel" WHERE "GuildConfigId" is NULL;
""");
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,703 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations.Mysql
{
/// <inheritdoc />
public partial class guidlconfigcleanup : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting");
migrationBuilder.DropForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore");
migrationBuilder.DropForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting");
migrationBuilder.DropForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias");
migrationBuilder.DropForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown");
migrationBuilder.DropForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel");
migrationBuilder.DropForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem");
migrationBuilder.DropForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid");
migrationBuilder.DropForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword");
migrationBuilder.DropForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid");
migrationBuilder.DropForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid");
migrationBuilder.DropForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream");
migrationBuilder.DropForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid");
migrationBuilder.DropForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid");
migrationBuilder.DropForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions");
migrationBuilder.DropForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry");
migrationBuilder.DropForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser");
migrationBuilder.DropForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesetti~",
table: "streamroleblacklisteduser");
migrationBuilder.DropForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesetti~",
table: "streamrolewhitelisteduser");
migrationBuilder.DropForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer");
migrationBuilder.DropForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer");
migrationBuilder.DropForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer");
migrationBuilder.DropForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo");
migrationBuilder.DropForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment");
migrationBuilder.DropTable(
name: "ignoredvoicepresencechannels");
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamrolewhitelisteduser",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamroleblacklisteduser",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "guildconfigid",
table: "delmsgoncmdchannel",
type: "int",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "int",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore",
column: "antispamsettingid",
principalTable: "antispamsetting",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem",
column: "xpsettingsid",
principalTable: "xpsettings",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem",
column: "shopentryid",
principalTable: "shopentry",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesetti~",
table: "streamroleblacklisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesetti~",
table: "streamrolewhitelisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting");
migrationBuilder.DropForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore");
migrationBuilder.DropForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting");
migrationBuilder.DropForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias");
migrationBuilder.DropForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown");
migrationBuilder.DropForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel");
migrationBuilder.DropForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem");
migrationBuilder.DropForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid");
migrationBuilder.DropForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword");
migrationBuilder.DropForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid");
migrationBuilder.DropForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid");
migrationBuilder.DropForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream");
migrationBuilder.DropForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid");
migrationBuilder.DropForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid");
migrationBuilder.DropForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions");
migrationBuilder.DropForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry");
migrationBuilder.DropForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser");
migrationBuilder.DropForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesetti~",
table: "streamroleblacklisteduser");
migrationBuilder.DropForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesetti~",
table: "streamrolewhitelisteduser");
migrationBuilder.DropForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer");
migrationBuilder.DropForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer");
migrationBuilder.DropForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer");
migrationBuilder.DropForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo");
migrationBuilder.DropForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment");
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamrolewhitelisteduser",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamroleblacklisteduser",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AlterColumn<int>(
name: "guildconfigid",
table: "delmsgoncmdchannel",
type: "int",
nullable: true,
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.CreateTable(
name: "ignoredvoicepresencechannels",
columns: table => new
{
id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
logsettingid = table.Column<int>(type: "int", nullable: true),
channelid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_ignoredvoicepresencechannels", x => x.id);
table.ForeignKey(
name: "fk_ignoredvoicepresencechannels_logsettings_logsettingid",
column: x => x.logsettingid,
principalTable: "logsettings",
principalColumn: "id");
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "ix_ignoredvoicepresencechannels_logsettingid",
table: "ignoredvoicepresencechannels",
column: "logsettingid");
migrationBuilder.AddForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore",
column: "antispamsettingid",
principalTable: "antispamsetting",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem",
column: "xpsettingsid",
principalTable: "xpsettings",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem",
column: "shopentryid",
principalTable: "shopentry",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesetti~",
table: "streamroleblacklisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesetti~",
table: "streamrolewhitelisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
}
}
}

View File

@@ -673,7 +673,7 @@ namespace NadekoBot.Migrations.Mysql
.HasColumnType("datetime(6)") .HasColumnType("datetime(6)")
.HasColumnName("dateadded"); .HasColumnName("dateadded");
b.Property<int?>("GuildConfigId") b.Property<int>("GuildConfigId")
.HasColumnType("int") .HasColumnType("int")
.HasColumnName("guildconfigid"); .HasColumnName("guildconfigid");
@@ -1423,36 +1423,6 @@ namespace NadekoBot.Migrations.Mysql
b.ToTable("ignoredlogchannels", (string)null); b.ToTable("ignoredlogchannels", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredVoicePresenceChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("id");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<ulong>("ChannelId")
.HasColumnType("bigint unsigned")
.HasColumnName("channelid");
b.Property<DateTime?>("DateAdded")
.HasColumnType("datetime(6)")
.HasColumnName("dateadded");
b.Property<int?>("LogSettingId")
.HasColumnType("int")
.HasColumnName("logsettingid");
b.HasKey("Id")
.HasName("pk_ignoredvoicepresencechannels");
b.HasIndex("LogSettingId")
.HasDatabaseName("ix_ignoredvoicepresencechannels_logsettingid");
b.ToTable("ignoredvoicepresencechannels", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ImageOnlyChannel", b => modelBuilder.Entity("NadekoBot.Db.Models.ImageOnlyChannel", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -2510,7 +2480,7 @@ namespace NadekoBot.Migrations.Mysql
.HasColumnType("datetime(6)") .HasColumnType("datetime(6)")
.HasColumnName("dateadded"); .HasColumnName("dateadded");
b.Property<int?>("StreamRoleSettingsId") b.Property<int>("StreamRoleSettingsId")
.HasColumnType("int") .HasColumnType("int")
.HasColumnName("streamrolesettingsid"); .HasColumnName("streamrolesettingsid");
@@ -2587,7 +2557,7 @@ namespace NadekoBot.Migrations.Mysql
.HasColumnType("datetime(6)") .HasColumnType("datetime(6)")
.HasColumnName("dateadded"); .HasColumnName("dateadded");
b.Property<int?>("StreamRoleSettingsId") b.Property<int>("StreamRoleSettingsId")
.HasColumnType("int") .HasColumnType("int")
.HasColumnName("streamrolesettingsid"); .HasColumnName("streamrolesettingsid");
@@ -3226,14 +3196,12 @@ namespace NadekoBot.Migrations.Mysql
modelBuilder.Entity("NadekoBot.Db.Models.AntiRaidSetting", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiRaidSetting", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithOne("AntiRaidSetting") .WithOne("AntiRaidSetting")
.HasForeignKey("NadekoBot.Db.Models.AntiRaidSetting", "GuildConfigId") .HasForeignKey("NadekoBot.Db.Models.AntiRaidSetting", "GuildConfigId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_antiraidsetting_guildconfigs_guildconfigid"); .HasConstraintName("fk_antiraidsetting_guildconfigs_guildconfigid");
b.Navigation("GuildConfig");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamIgnore", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamIgnore", b =>
@@ -3241,19 +3209,18 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.AntiSpamSetting", null) b.HasOne("NadekoBot.Db.Models.AntiSpamSetting", null)
.WithMany("IgnoredChannels") .WithMany("IgnoredChannels")
.HasForeignKey("AntiSpamSettingId") .HasForeignKey("AntiSpamSettingId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_antispamignore_antispamsetting_antispamsettingid"); .HasConstraintName("fk_antispamignore_antispamsetting_antispamsettingid");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamSetting", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamSetting", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithOne("AntiSpamSetting") .WithOne("AntiSpamSetting")
.HasForeignKey("NadekoBot.Db.Models.AntiSpamSetting", "GuildConfigId") .HasForeignKey("NadekoBot.Db.Models.AntiSpamSetting", "GuildConfigId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_antispamsetting_guildconfigs_guildconfigid"); .HasConstraintName("fk_antispamsetting_guildconfigs_guildconfigid");
b.Navigation("GuildConfig");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AutoTranslateUser", b => modelBuilder.Entity("NadekoBot.Db.Models.AutoTranslateUser", b =>
@@ -3326,6 +3293,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("CommandAliases") .WithMany("CommandAliases")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_commandalias_guildconfigs_guildconfigid"); .HasConstraintName("fk_commandalias_guildconfigs_guildconfigid");
}); });
@@ -3334,6 +3302,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("CommandCooldowns") .WithMany("CommandCooldowns")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_commandcooldown_guildconfigs_guildconfigid"); .HasConstraintName("fk_commandcooldown_guildconfigs_guildconfigid");
}); });
@@ -3342,6 +3311,8 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("DelMsgOnCmdChannels") .WithMany("DelMsgOnCmdChannels")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_delmsgoncmdchannel_guildconfigs_guildconfigid"); .HasConstraintName("fk_delmsgoncmdchannel_guildconfigs_guildconfigid");
}); });
@@ -3358,10 +3329,13 @@ namespace NadekoBot.Migrations.Mysql
modelBuilder.Entity("NadekoBot.Db.Models.ExcludedItem", b => modelBuilder.Entity("NadekoBot.Db.Models.ExcludedItem", b =>
{ {
b.HasOne("NadekoBot.Db.Models.XpSettings", null) b.HasOne("NadekoBot.Db.Models.XpSettings", "XpSettings")
.WithMany("ExclusionList") .WithMany("ExclusionList")
.HasForeignKey("XpSettingsId") .HasForeignKey("XpSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_excludeditem_xpsettings_xpsettingsid"); .HasConstraintName("fk_excludeditem_xpsettings_xpsettingsid");
b.Navigation("XpSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FeedSub", b => modelBuilder.Entity("NadekoBot.Db.Models.FeedSub", b =>
@@ -3381,6 +3355,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterInvitesChannelIds") .WithMany("FilterInvitesChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filterchannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_filterchannelid_guildconfigs_guildconfigid");
}); });
@@ -3389,6 +3364,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterLinksChannelIds") .WithMany("FilterLinksChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filterlinkschannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_filterlinkschannelid_guildconfigs_guildconfigid");
}); });
@@ -3397,6 +3373,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterWordsChannelIds") .WithMany("FilterWordsChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filterwordschannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_filterwordschannelid_guildconfigs_guildconfigid");
}); });
@@ -3405,6 +3382,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilteredWords") .WithMany("FilteredWords")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filteredword_guildconfigs_guildconfigid"); .HasConstraintName("fk_filteredword_guildconfigs_guildconfigid");
}); });
@@ -3413,6 +3391,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FollowedStreams") .WithMany("FollowedStreams")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_followedstream_guildconfigs_guildconfigid"); .HasConstraintName("fk_followedstream_guildconfigs_guildconfigid");
}); });
@@ -3421,6 +3400,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig")
.WithMany("GenerateCurrencyChannelIds") .WithMany("GenerateCurrencyChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_gcchannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_gcchannelid_guildconfigs_guildconfigid");
b.Navigation("GuildConfig"); b.Navigation("GuildConfig");
@@ -3460,21 +3440,12 @@ namespace NadekoBot.Migrations.Mysql
b.Navigation("LogSetting"); b.Navigation("LogSetting");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredVoicePresenceChannel", b =>
{
b.HasOne("NadekoBot.Db.Models.LogSetting", "LogSetting")
.WithMany()
.HasForeignKey("LogSettingId")
.HasConstraintName("fk_ignoredvoicepresencechannels_logsettings_logsettingid");
b.Navigation("LogSetting");
});
modelBuilder.Entity("NadekoBot.Db.Models.MutedUserId", b => modelBuilder.Entity("NadekoBot.Db.Models.MutedUserId", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("MutedUsers") .WithMany("MutedUsers")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_muteduserid_guildconfigs_guildconfigid"); .HasConstraintName("fk_muteduserid_guildconfigs_guildconfigid");
}); });
@@ -3483,6 +3454,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("Permissions") .WithMany("Permissions")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_permissions_guildconfigs_guildconfigid"); .HasConstraintName("fk_permissions_guildconfigs_guildconfigid");
}); });
@@ -3500,6 +3472,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("ShopEntries") .WithMany("ShopEntries")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_shopentry_guildconfigs_guildconfigid"); .HasConstraintName("fk_shopentry_guildconfigs_guildconfigid");
}); });
@@ -3508,6 +3481,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.ShopEntry", null) b.HasOne("NadekoBot.Db.Models.ShopEntry", null)
.WithMany("Items") .WithMany("Items")
.HasForeignKey("ShopEntryId") .HasForeignKey("ShopEntryId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_shopentryitem_shopentry_shopentryid"); .HasConstraintName("fk_shopentryitem_shopentry_shopentryid");
}); });
@@ -3516,6 +3490,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("SlowmodeIgnoredRoles") .WithMany("SlowmodeIgnoredRoles")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_slowmodeignoredrole_guildconfigs_guildconfigid"); .HasConstraintName("fk_slowmodeignoredrole_guildconfigs_guildconfigid");
}); });
@@ -3524,15 +3499,20 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("SlowmodeIgnoredUsers") .WithMany("SlowmodeIgnoredUsers")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_slowmodeignoreduser_guildconfigs_guildconfigid"); .HasConstraintName("fk_slowmodeignoreduser_guildconfigs_guildconfigid");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleBlacklistedUser", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleBlacklistedUser", b =>
{ {
b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", null) b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
.WithMany("Blacklist") .WithMany("Blacklist")
.HasForeignKey("StreamRoleSettingsId") .HasForeignKey("StreamRoleSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_streamroleblacklisteduser_streamrolesettings_streamrolesetti~"); .HasConstraintName("fk_streamroleblacklisteduser_streamrolesettings_streamrolesetti~");
b.Navigation("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleSettings", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleSettings", b =>
@@ -3549,10 +3529,14 @@ namespace NadekoBot.Migrations.Mysql
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleWhitelistedUser", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleWhitelistedUser", b =>
{ {
b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", null) b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
.WithMany("Whitelist") .WithMany("Whitelist")
.HasForeignKey("StreamRoleSettingsId") .HasForeignKey("StreamRoleSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_streamrolewhitelisteduser_streamrolesettings_streamrolesetti~"); .HasConstraintName("fk_streamrolewhitelisteduser_streamrolesettings_streamrolesetti~");
b.Navigation("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b => modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
@@ -3569,6 +3553,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnbanTimer") .WithMany("UnbanTimer")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_unbantimer_guildconfigs_guildconfigid"); .HasConstraintName("fk_unbantimer_guildconfigs_guildconfigid");
}); });
@@ -3577,6 +3562,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnmuteTimers") .WithMany("UnmuteTimers")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_unmutetimer_guildconfigs_guildconfigid"); .HasConstraintName("fk_unmutetimer_guildconfigs_guildconfigid");
}); });
@@ -3585,6 +3571,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnroleTimer") .WithMany("UnroleTimer")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_unroletimer_guildconfigs_guildconfigid"); .HasConstraintName("fk_unroletimer_guildconfigs_guildconfigid");
}); });
@@ -3593,6 +3580,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("VcRoleInfos") .WithMany("VcRoleInfos")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_vcroleinfo_guildconfigs_guildconfigid"); .HasConstraintName("fk_vcroleinfo_guildconfigs_guildconfigid");
}); });
@@ -3663,6 +3651,7 @@ namespace NadekoBot.Migrations.Mysql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("WarnPunishments") .WithMany("WarnPunishments")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_warningpunishment_guildconfigs_guildconfigid"); .HasConstraintName("fk_warningpunishment_guildconfigs_guildconfigid");
}); });

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,702 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class guidlconfigcleanup : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting");
migrationBuilder.DropForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore");
migrationBuilder.DropForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting");
migrationBuilder.DropForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias");
migrationBuilder.DropForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown");
migrationBuilder.DropForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel");
migrationBuilder.DropForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem");
migrationBuilder.DropForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid");
migrationBuilder.DropForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword");
migrationBuilder.DropForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid");
migrationBuilder.DropForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid");
migrationBuilder.DropForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream");
migrationBuilder.DropForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid");
migrationBuilder.DropForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid");
migrationBuilder.DropForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions");
migrationBuilder.DropForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry");
migrationBuilder.DropForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser");
migrationBuilder.DropForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesett~",
table: "streamroleblacklisteduser");
migrationBuilder.DropForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesett~",
table: "streamrolewhitelisteduser");
migrationBuilder.DropForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer");
migrationBuilder.DropForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer");
migrationBuilder.DropForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer");
migrationBuilder.DropForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo");
migrationBuilder.DropForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment");
migrationBuilder.DropTable(
name: "ignoredvoicepresencechannels");
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamrolewhitelisteduser",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamroleblacklisteduser",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "guildconfigid",
table: "delmsgoncmdchannel",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore",
column: "antispamsettingid",
principalTable: "antispamsetting",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem",
column: "xpsettingsid",
principalTable: "xpsettings",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem",
column: "shopentryid",
principalTable: "shopentry",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesett~",
table: "streamroleblacklisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesett~",
table: "streamrolewhitelisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting");
migrationBuilder.DropForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore");
migrationBuilder.DropForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting");
migrationBuilder.DropForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias");
migrationBuilder.DropForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown");
migrationBuilder.DropForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel");
migrationBuilder.DropForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem");
migrationBuilder.DropForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid");
migrationBuilder.DropForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword");
migrationBuilder.DropForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid");
migrationBuilder.DropForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid");
migrationBuilder.DropForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream");
migrationBuilder.DropForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid");
migrationBuilder.DropForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid");
migrationBuilder.DropForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions");
migrationBuilder.DropForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry");
migrationBuilder.DropForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole");
migrationBuilder.DropForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser");
migrationBuilder.DropForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesett~",
table: "streamroleblacklisteduser");
migrationBuilder.DropForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesett~",
table: "streamrolewhitelisteduser");
migrationBuilder.DropForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer");
migrationBuilder.DropForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer");
migrationBuilder.DropForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer");
migrationBuilder.DropForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo");
migrationBuilder.DropForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment");
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamrolewhitelisteduser",
type: "integer",
nullable: true,
oldClrType: typeof(int),
oldType: "integer");
migrationBuilder.AlterColumn<int>(
name: "streamrolesettingsid",
table: "streamroleblacklisteduser",
type: "integer",
nullable: true,
oldClrType: typeof(int),
oldType: "integer");
migrationBuilder.AlterColumn<int>(
name: "guildconfigid",
table: "delmsgoncmdchannel",
type: "integer",
nullable: true,
oldClrType: typeof(int),
oldType: "integer");
migrationBuilder.CreateTable(
name: "ignoredvoicepresencechannels",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
logsettingid = table.Column<int>(type: "integer", nullable: true),
channelid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
dateadded = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_ignoredvoicepresencechannels", x => x.id);
table.ForeignKey(
name: "fk_ignoredvoicepresencechannels_logsettings_logsettingid",
column: x => x.logsettingid,
principalTable: "logsettings",
principalColumn: "id");
});
migrationBuilder.CreateIndex(
name: "ix_ignoredvoicepresencechannels_logsettingid",
table: "ignoredvoicepresencechannels",
column: "logsettingid");
migrationBuilder.AddForeignKey(
name: "fk_antiraidsetting_guildconfigs_guildconfigid",
table: "antiraidsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_antispamignore_antispamsetting_antispamsettingid",
table: "antispamignore",
column: "antispamsettingid",
principalTable: "antispamsetting",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_antispamsetting_guildconfigs_guildconfigid",
table: "antispamsetting",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "fk_commandalias_guildconfigs_guildconfigid",
table: "commandalias",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_commandcooldown_guildconfigs_guildconfigid",
table: "commandcooldown",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_delmsgoncmdchannel_guildconfigs_guildconfigid",
table: "delmsgoncmdchannel",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_excludeditem_xpsettings_xpsettingsid",
table: "excludeditem",
column: "xpsettingsid",
principalTable: "xpsettings",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filterchannelid_guildconfigs_guildconfigid",
table: "filterchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filteredword_guildconfigs_guildconfigid",
table: "filteredword",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filterlinkschannelid_guildconfigs_guildconfigid",
table: "filterlinkschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_filterwordschannelid_guildconfigs_guildconfigid",
table: "filterwordschannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_followedstream_guildconfigs_guildconfigid",
table: "followedstream",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_gcchannelid_guildconfigs_guildconfigid",
table: "gcchannelid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_muteduserid_guildconfigs_guildconfigid",
table: "muteduserid",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_permissions_guildconfigs_guildconfigid",
table: "permissions",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_shopentry_guildconfigs_guildconfigid",
table: "shopentry",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_shopentryitem_shopentry_shopentryid",
table: "shopentryitem",
column: "shopentryid",
principalTable: "shopentry",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoredrole_guildconfigs_guildconfigid",
table: "slowmodeignoredrole",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_slowmodeignoreduser_guildconfigs_guildconfigid",
table: "slowmodeignoreduser",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_streamroleblacklisteduser_streamrolesettings_streamrolesett~",
table: "streamroleblacklisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_streamrolewhitelisteduser_streamrolesettings_streamrolesett~",
table: "streamrolewhitelisteduser",
column: "streamrolesettingsid",
principalTable: "streamrolesettings",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_unbantimer_guildconfigs_guildconfigid",
table: "unbantimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_unmutetimer_guildconfigs_guildconfigid",
table: "unmutetimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_unroletimer_guildconfigs_guildconfigid",
table: "unroletimer",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_vcroleinfo_guildconfigs_guildconfigid",
table: "vcroleinfo",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
migrationBuilder.AddForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id");
}
}
}

View File

@@ -672,7 +672,7 @@ namespace NadekoBot.Migrations.PostgreSql
.HasColumnType("timestamp without time zone") .HasColumnType("timestamp without time zone")
.HasColumnName("dateadded"); .HasColumnName("dateadded");
b.Property<int?>("GuildConfigId") b.Property<int>("GuildConfigId")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("guildconfigid"); .HasColumnName("guildconfigid");
@@ -1422,36 +1422,6 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("ignoredlogchannels", (string)null); b.ToTable("ignoredlogchannels", (string)null);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredVoicePresenceChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("ChannelId")
.HasColumnType("numeric(20,0)")
.HasColumnName("channelid");
b.Property<DateTime?>("DateAdded")
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
b.Property<int?>("LogSettingId")
.HasColumnType("integer")
.HasColumnName("logsettingid");
b.HasKey("Id")
.HasName("pk_ignoredvoicepresencechannels");
b.HasIndex("LogSettingId")
.HasDatabaseName("ix_ignoredvoicepresencechannels_logsettingid");
b.ToTable("ignoredvoicepresencechannels", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ImageOnlyChannel", b => modelBuilder.Entity("NadekoBot.Db.Models.ImageOnlyChannel", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -2507,7 +2477,7 @@ namespace NadekoBot.Migrations.PostgreSql
.HasColumnType("timestamp without time zone") .HasColumnType("timestamp without time zone")
.HasColumnName("dateadded"); .HasColumnName("dateadded");
b.Property<int?>("StreamRoleSettingsId") b.Property<int>("StreamRoleSettingsId")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("streamrolesettingsid"); .HasColumnName("streamrolesettingsid");
@@ -2584,7 +2554,7 @@ namespace NadekoBot.Migrations.PostgreSql
.HasColumnType("timestamp without time zone") .HasColumnType("timestamp without time zone")
.HasColumnName("dateadded"); .HasColumnName("dateadded");
b.Property<int?>("StreamRoleSettingsId") b.Property<int>("StreamRoleSettingsId")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("streamrolesettingsid"); .HasColumnName("streamrolesettingsid");
@@ -3223,14 +3193,12 @@ namespace NadekoBot.Migrations.PostgreSql
modelBuilder.Entity("NadekoBot.Db.Models.AntiRaidSetting", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiRaidSetting", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithOne("AntiRaidSetting") .WithOne("AntiRaidSetting")
.HasForeignKey("NadekoBot.Db.Models.AntiRaidSetting", "GuildConfigId") .HasForeignKey("NadekoBot.Db.Models.AntiRaidSetting", "GuildConfigId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_antiraidsetting_guildconfigs_guildconfigid"); .HasConstraintName("fk_antiraidsetting_guildconfigs_guildconfigid");
b.Navigation("GuildConfig");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamIgnore", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamIgnore", b =>
@@ -3238,19 +3206,18 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.AntiSpamSetting", null) b.HasOne("NadekoBot.Db.Models.AntiSpamSetting", null)
.WithMany("IgnoredChannels") .WithMany("IgnoredChannels")
.HasForeignKey("AntiSpamSettingId") .HasForeignKey("AntiSpamSettingId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_antispamignore_antispamsetting_antispamsettingid"); .HasConstraintName("fk_antispamignore_antispamsetting_antispamsettingid");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamSetting", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamSetting", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithOne("AntiSpamSetting") .WithOne("AntiSpamSetting")
.HasForeignKey("NadekoBot.Db.Models.AntiSpamSetting", "GuildConfigId") .HasForeignKey("NadekoBot.Db.Models.AntiSpamSetting", "GuildConfigId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired() .IsRequired()
.HasConstraintName("fk_antispamsetting_guildconfigs_guildconfigid"); .HasConstraintName("fk_antispamsetting_guildconfigs_guildconfigid");
b.Navigation("GuildConfig");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AutoTranslateUser", b => modelBuilder.Entity("NadekoBot.Db.Models.AutoTranslateUser", b =>
@@ -3323,6 +3290,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("CommandAliases") .WithMany("CommandAliases")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_commandalias_guildconfigs_guildconfigid"); .HasConstraintName("fk_commandalias_guildconfigs_guildconfigid");
}); });
@@ -3331,6 +3299,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("CommandCooldowns") .WithMany("CommandCooldowns")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_commandcooldown_guildconfigs_guildconfigid"); .HasConstraintName("fk_commandcooldown_guildconfigs_guildconfigid");
}); });
@@ -3339,6 +3308,8 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("DelMsgOnCmdChannels") .WithMany("DelMsgOnCmdChannels")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_delmsgoncmdchannel_guildconfigs_guildconfigid"); .HasConstraintName("fk_delmsgoncmdchannel_guildconfigs_guildconfigid");
}); });
@@ -3355,10 +3326,13 @@ namespace NadekoBot.Migrations.PostgreSql
modelBuilder.Entity("NadekoBot.Db.Models.ExcludedItem", b => modelBuilder.Entity("NadekoBot.Db.Models.ExcludedItem", b =>
{ {
b.HasOne("NadekoBot.Db.Models.XpSettings", null) b.HasOne("NadekoBot.Db.Models.XpSettings", "XpSettings")
.WithMany("ExclusionList") .WithMany("ExclusionList")
.HasForeignKey("XpSettingsId") .HasForeignKey("XpSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_excludeditem_xpsettings_xpsettingsid"); .HasConstraintName("fk_excludeditem_xpsettings_xpsettingsid");
b.Navigation("XpSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FeedSub", b => modelBuilder.Entity("NadekoBot.Db.Models.FeedSub", b =>
@@ -3378,6 +3352,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterInvitesChannelIds") .WithMany("FilterInvitesChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filterchannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_filterchannelid_guildconfigs_guildconfigid");
}); });
@@ -3386,6 +3361,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterLinksChannelIds") .WithMany("FilterLinksChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filterlinkschannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_filterlinkschannelid_guildconfigs_guildconfigid");
}); });
@@ -3394,6 +3370,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterWordsChannelIds") .WithMany("FilterWordsChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filterwordschannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_filterwordschannelid_guildconfigs_guildconfigid");
}); });
@@ -3402,6 +3379,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilteredWords") .WithMany("FilteredWords")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_filteredword_guildconfigs_guildconfigid"); .HasConstraintName("fk_filteredword_guildconfigs_guildconfigid");
}); });
@@ -3410,6 +3388,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FollowedStreams") .WithMany("FollowedStreams")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_followedstream_guildconfigs_guildconfigid"); .HasConstraintName("fk_followedstream_guildconfigs_guildconfigid");
}); });
@@ -3418,6 +3397,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig")
.WithMany("GenerateCurrencyChannelIds") .WithMany("GenerateCurrencyChannelIds")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_gcchannelid_guildconfigs_guildconfigid"); .HasConstraintName("fk_gcchannelid_guildconfigs_guildconfigid");
b.Navigation("GuildConfig"); b.Navigation("GuildConfig");
@@ -3457,21 +3437,12 @@ namespace NadekoBot.Migrations.PostgreSql
b.Navigation("LogSetting"); b.Navigation("LogSetting");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredVoicePresenceChannel", b =>
{
b.HasOne("NadekoBot.Db.Models.LogSetting", "LogSetting")
.WithMany()
.HasForeignKey("LogSettingId")
.HasConstraintName("fk_ignoredvoicepresencechannels_logsettings_logsettingid");
b.Navigation("LogSetting");
});
modelBuilder.Entity("NadekoBot.Db.Models.MutedUserId", b => modelBuilder.Entity("NadekoBot.Db.Models.MutedUserId", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("MutedUsers") .WithMany("MutedUsers")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_muteduserid_guildconfigs_guildconfigid"); .HasConstraintName("fk_muteduserid_guildconfigs_guildconfigid");
}); });
@@ -3480,6 +3451,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("Permissions") .WithMany("Permissions")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_permissions_guildconfigs_guildconfigid"); .HasConstraintName("fk_permissions_guildconfigs_guildconfigid");
}); });
@@ -3497,6 +3469,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("ShopEntries") .WithMany("ShopEntries")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_shopentry_guildconfigs_guildconfigid"); .HasConstraintName("fk_shopentry_guildconfigs_guildconfigid");
}); });
@@ -3505,6 +3478,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.ShopEntry", null) b.HasOne("NadekoBot.Db.Models.ShopEntry", null)
.WithMany("Items") .WithMany("Items")
.HasForeignKey("ShopEntryId") .HasForeignKey("ShopEntryId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_shopentryitem_shopentry_shopentryid"); .HasConstraintName("fk_shopentryitem_shopentry_shopentryid");
}); });
@@ -3513,6 +3487,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("SlowmodeIgnoredRoles") .WithMany("SlowmodeIgnoredRoles")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_slowmodeignoredrole_guildconfigs_guildconfigid"); .HasConstraintName("fk_slowmodeignoredrole_guildconfigs_guildconfigid");
}); });
@@ -3521,15 +3496,20 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("SlowmodeIgnoredUsers") .WithMany("SlowmodeIgnoredUsers")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_slowmodeignoreduser_guildconfigs_guildconfigid"); .HasConstraintName("fk_slowmodeignoreduser_guildconfigs_guildconfigid");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleBlacklistedUser", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleBlacklistedUser", b =>
{ {
b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", null) b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
.WithMany("Blacklist") .WithMany("Blacklist")
.HasForeignKey("StreamRoleSettingsId") .HasForeignKey("StreamRoleSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_streamroleblacklisteduser_streamrolesettings_streamrolesett~"); .HasConstraintName("fk_streamroleblacklisteduser_streamrolesettings_streamrolesett~");
b.Navigation("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleSettings", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleSettings", b =>
@@ -3546,10 +3526,14 @@ namespace NadekoBot.Migrations.PostgreSql
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleWhitelistedUser", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleWhitelistedUser", b =>
{ {
b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", null) b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
.WithMany("Whitelist") .WithMany("Whitelist")
.HasForeignKey("StreamRoleSettingsId") .HasForeignKey("StreamRoleSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_streamrolewhitelisteduser_streamrolesettings_streamrolesett~"); .HasConstraintName("fk_streamrolewhitelisteduser_streamrolesettings_streamrolesett~");
b.Navigation("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b => modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
@@ -3566,6 +3550,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnbanTimer") .WithMany("UnbanTimer")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_unbantimer_guildconfigs_guildconfigid"); .HasConstraintName("fk_unbantimer_guildconfigs_guildconfigid");
}); });
@@ -3574,6 +3559,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnmuteTimers") .WithMany("UnmuteTimers")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_unmutetimer_guildconfigs_guildconfigid"); .HasConstraintName("fk_unmutetimer_guildconfigs_guildconfigid");
}); });
@@ -3582,6 +3568,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnroleTimer") .WithMany("UnroleTimer")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_unroletimer_guildconfigs_guildconfigid"); .HasConstraintName("fk_unroletimer_guildconfigs_guildconfigid");
}); });
@@ -3590,6 +3577,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("VcRoleInfos") .WithMany("VcRoleInfos")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_vcroleinfo_guildconfigs_guildconfigid"); .HasConstraintName("fk_vcroleinfo_guildconfigs_guildconfigid");
}); });
@@ -3660,6 +3648,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("WarnPunishments") .WithMany("WarnPunishments")
.HasForeignKey("GuildConfigId") .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_warningpunishment_guildconfigs_guildconfigid"); .HasConstraintName("fk_warningpunishment_guildconfigs_guildconfigid");
}); });

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,701 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class guidlconfigcleanup : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_AntiRaidSetting_GuildConfigs_GuildConfigId",
table: "AntiRaidSetting");
migrationBuilder.DropForeignKey(
name: "FK_AntiSpamIgnore_AntiSpamSetting_AntiSpamSettingId",
table: "AntiSpamIgnore");
migrationBuilder.DropForeignKey(
name: "FK_AntiSpamSetting_GuildConfigs_GuildConfigId",
table: "AntiSpamSetting");
migrationBuilder.DropForeignKey(
name: "FK_CommandAlias_GuildConfigs_GuildConfigId",
table: "CommandAlias");
migrationBuilder.DropForeignKey(
name: "FK_CommandCooldown_GuildConfigs_GuildConfigId",
table: "CommandCooldown");
migrationBuilder.DropForeignKey(
name: "FK_DelMsgOnCmdChannel_GuildConfigs_GuildConfigId",
table: "DelMsgOnCmdChannel");
migrationBuilder.DropForeignKey(
name: "FK_ExcludedItem_XpSettings_XpSettingsId",
table: "ExcludedItem");
migrationBuilder.DropForeignKey(
name: "FK_FilterChannelId_GuildConfigs_GuildConfigId",
table: "FilterChannelId");
migrationBuilder.DropForeignKey(
name: "FK_FilteredWord_GuildConfigs_GuildConfigId",
table: "FilteredWord");
migrationBuilder.DropForeignKey(
name: "FK_FilterLinksChannelId_GuildConfigs_GuildConfigId",
table: "FilterLinksChannelId");
migrationBuilder.DropForeignKey(
name: "FK_FilterWordsChannelId_GuildConfigs_GuildConfigId",
table: "FilterWordsChannelId");
migrationBuilder.DropForeignKey(
name: "FK_FollowedStream_GuildConfigs_GuildConfigId",
table: "FollowedStream");
migrationBuilder.DropForeignKey(
name: "FK_GCChannelId_GuildConfigs_GuildConfigId",
table: "GCChannelId");
migrationBuilder.DropForeignKey(
name: "FK_MutedUserId_GuildConfigs_GuildConfigId",
table: "MutedUserId");
migrationBuilder.DropForeignKey(
name: "FK_Permissions_GuildConfigs_GuildConfigId",
table: "Permissions");
migrationBuilder.DropForeignKey(
name: "FK_ShopEntry_GuildConfigs_GuildConfigId",
table: "ShopEntry");
migrationBuilder.DropForeignKey(
name: "FK_ShopEntryItem_ShopEntry_ShopEntryId",
table: "ShopEntryItem");
migrationBuilder.DropForeignKey(
name: "FK_SlowmodeIgnoredRole_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredRole");
migrationBuilder.DropForeignKey(
name: "FK_SlowmodeIgnoredUser_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredUser");
migrationBuilder.DropForeignKey(
name: "FK_StreamRoleBlacklistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleBlacklistedUser");
migrationBuilder.DropForeignKey(
name: "FK_StreamRoleWhitelistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleWhitelistedUser");
migrationBuilder.DropForeignKey(
name: "FK_UnbanTimer_GuildConfigs_GuildConfigId",
table: "UnbanTimer");
migrationBuilder.DropForeignKey(
name: "FK_UnmuteTimer_GuildConfigs_GuildConfigId",
table: "UnmuteTimer");
migrationBuilder.DropForeignKey(
name: "FK_UnroleTimer_GuildConfigs_GuildConfigId",
table: "UnroleTimer");
migrationBuilder.DropForeignKey(
name: "FK_VcRoleInfo_GuildConfigs_GuildConfigId",
table: "VcRoleInfo");
migrationBuilder.DropForeignKey(
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
table: "WarningPunishment");
migrationBuilder.DropTable(
name: "IgnoredVoicePresenceCHannels");
migrationBuilder.AlterColumn<int>(
name: "StreamRoleSettingsId",
table: "StreamRoleWhitelistedUser",
type: "INTEGER",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "INTEGER",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "StreamRoleSettingsId",
table: "StreamRoleBlacklistedUser",
type: "INTEGER",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "INTEGER",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "GuildConfigId",
table: "DelMsgOnCmdChannel",
type: "INTEGER",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "INTEGER",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_AntiRaidSetting_GuildConfigs_GuildConfigId",
table: "AntiRaidSetting",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_AntiSpamIgnore_AntiSpamSetting_AntiSpamSettingId",
table: "AntiSpamIgnore",
column: "AntiSpamSettingId",
principalTable: "AntiSpamSetting",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_AntiSpamSetting_GuildConfigs_GuildConfigId",
table: "AntiSpamSetting",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_CommandAlias_GuildConfigs_GuildConfigId",
table: "CommandAlias",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_CommandCooldown_GuildConfigs_GuildConfigId",
table: "CommandCooldown",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_DelMsgOnCmdChannel_GuildConfigs_GuildConfigId",
table: "DelMsgOnCmdChannel",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_ExcludedItem_XpSettings_XpSettingsId",
table: "ExcludedItem",
column: "XpSettingsId",
principalTable: "XpSettings",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_FilterChannelId_GuildConfigs_GuildConfigId",
table: "FilterChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_FilteredWord_GuildConfigs_GuildConfigId",
table: "FilteredWord",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_FilterLinksChannelId_GuildConfigs_GuildConfigId",
table: "FilterLinksChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_FilterWordsChannelId_GuildConfigs_GuildConfigId",
table: "FilterWordsChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_FollowedStream_GuildConfigs_GuildConfigId",
table: "FollowedStream",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_GCChannelId_GuildConfigs_GuildConfigId",
table: "GCChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_MutedUserId_GuildConfigs_GuildConfigId",
table: "MutedUserId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Permissions_GuildConfigs_GuildConfigId",
table: "Permissions",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_ShopEntry_GuildConfigs_GuildConfigId",
table: "ShopEntry",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_ShopEntryItem_ShopEntry_ShopEntryId",
table: "ShopEntryItem",
column: "ShopEntryId",
principalTable: "ShopEntry",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_SlowmodeIgnoredRole_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredRole",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_SlowmodeIgnoredUser_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredUser",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_StreamRoleBlacklistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleBlacklistedUser",
column: "StreamRoleSettingsId",
principalTable: "StreamRoleSettings",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_StreamRoleWhitelistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleWhitelistedUser",
column: "StreamRoleSettingsId",
principalTable: "StreamRoleSettings",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_UnbanTimer_GuildConfigs_GuildConfigId",
table: "UnbanTimer",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_UnmuteTimer_GuildConfigs_GuildConfigId",
table: "UnmuteTimer",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_UnroleTimer_GuildConfigs_GuildConfigId",
table: "UnroleTimer",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_VcRoleInfo_GuildConfigs_GuildConfigId",
table: "VcRoleInfo",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
table: "WarningPunishment",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_AntiRaidSetting_GuildConfigs_GuildConfigId",
table: "AntiRaidSetting");
migrationBuilder.DropForeignKey(
name: "FK_AntiSpamIgnore_AntiSpamSetting_AntiSpamSettingId",
table: "AntiSpamIgnore");
migrationBuilder.DropForeignKey(
name: "FK_AntiSpamSetting_GuildConfigs_GuildConfigId",
table: "AntiSpamSetting");
migrationBuilder.DropForeignKey(
name: "FK_CommandAlias_GuildConfigs_GuildConfigId",
table: "CommandAlias");
migrationBuilder.DropForeignKey(
name: "FK_CommandCooldown_GuildConfigs_GuildConfigId",
table: "CommandCooldown");
migrationBuilder.DropForeignKey(
name: "FK_DelMsgOnCmdChannel_GuildConfigs_GuildConfigId",
table: "DelMsgOnCmdChannel");
migrationBuilder.DropForeignKey(
name: "FK_ExcludedItem_XpSettings_XpSettingsId",
table: "ExcludedItem");
migrationBuilder.DropForeignKey(
name: "FK_FilterChannelId_GuildConfigs_GuildConfigId",
table: "FilterChannelId");
migrationBuilder.DropForeignKey(
name: "FK_FilteredWord_GuildConfigs_GuildConfigId",
table: "FilteredWord");
migrationBuilder.DropForeignKey(
name: "FK_FilterLinksChannelId_GuildConfigs_GuildConfigId",
table: "FilterLinksChannelId");
migrationBuilder.DropForeignKey(
name: "FK_FilterWordsChannelId_GuildConfigs_GuildConfigId",
table: "FilterWordsChannelId");
migrationBuilder.DropForeignKey(
name: "FK_FollowedStream_GuildConfigs_GuildConfigId",
table: "FollowedStream");
migrationBuilder.DropForeignKey(
name: "FK_GCChannelId_GuildConfigs_GuildConfigId",
table: "GCChannelId");
migrationBuilder.DropForeignKey(
name: "FK_MutedUserId_GuildConfigs_GuildConfigId",
table: "MutedUserId");
migrationBuilder.DropForeignKey(
name: "FK_Permissions_GuildConfigs_GuildConfigId",
table: "Permissions");
migrationBuilder.DropForeignKey(
name: "FK_ShopEntry_GuildConfigs_GuildConfigId",
table: "ShopEntry");
migrationBuilder.DropForeignKey(
name: "FK_ShopEntryItem_ShopEntry_ShopEntryId",
table: "ShopEntryItem");
migrationBuilder.DropForeignKey(
name: "FK_SlowmodeIgnoredRole_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredRole");
migrationBuilder.DropForeignKey(
name: "FK_SlowmodeIgnoredUser_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredUser");
migrationBuilder.DropForeignKey(
name: "FK_StreamRoleBlacklistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleBlacklistedUser");
migrationBuilder.DropForeignKey(
name: "FK_StreamRoleWhitelistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleWhitelistedUser");
migrationBuilder.DropForeignKey(
name: "FK_UnbanTimer_GuildConfigs_GuildConfigId",
table: "UnbanTimer");
migrationBuilder.DropForeignKey(
name: "FK_UnmuteTimer_GuildConfigs_GuildConfigId",
table: "UnmuteTimer");
migrationBuilder.DropForeignKey(
name: "FK_UnroleTimer_GuildConfigs_GuildConfigId",
table: "UnroleTimer");
migrationBuilder.DropForeignKey(
name: "FK_VcRoleInfo_GuildConfigs_GuildConfigId",
table: "VcRoleInfo");
migrationBuilder.DropForeignKey(
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
table: "WarningPunishment");
migrationBuilder.AlterColumn<int>(
name: "StreamRoleSettingsId",
table: "StreamRoleWhitelistedUser",
type: "INTEGER",
nullable: true,
oldClrType: typeof(int),
oldType: "INTEGER");
migrationBuilder.AlterColumn<int>(
name: "StreamRoleSettingsId",
table: "StreamRoleBlacklistedUser",
type: "INTEGER",
nullable: true,
oldClrType: typeof(int),
oldType: "INTEGER");
migrationBuilder.AlterColumn<int>(
name: "GuildConfigId",
table: "DelMsgOnCmdChannel",
type: "INTEGER",
nullable: true,
oldClrType: typeof(int),
oldType: "INTEGER");
migrationBuilder.CreateTable(
name: "IgnoredVoicePresenceCHannels",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
LogSettingId = table.Column<int>(type: "INTEGER", nullable: true),
ChannelId = table.Column<ulong>(type: "INTEGER", nullable: false),
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_IgnoredVoicePresenceCHannels", x => x.Id);
table.ForeignKey(
name: "FK_IgnoredVoicePresenceCHannels_LogSettings_LogSettingId",
column: x => x.LogSettingId,
principalTable: "LogSettings",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_IgnoredVoicePresenceCHannels_LogSettingId",
table: "IgnoredVoicePresenceCHannels",
column: "LogSettingId");
migrationBuilder.AddForeignKey(
name: "FK_AntiRaidSetting_GuildConfigs_GuildConfigId",
table: "AntiRaidSetting",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_AntiSpamIgnore_AntiSpamSetting_AntiSpamSettingId",
table: "AntiSpamIgnore",
column: "AntiSpamSettingId",
principalTable: "AntiSpamSetting",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_AntiSpamSetting_GuildConfigs_GuildConfigId",
table: "AntiSpamSetting",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_CommandAlias_GuildConfigs_GuildConfigId",
table: "CommandAlias",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_CommandCooldown_GuildConfigs_GuildConfigId",
table: "CommandCooldown",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_DelMsgOnCmdChannel_GuildConfigs_GuildConfigId",
table: "DelMsgOnCmdChannel",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_ExcludedItem_XpSettings_XpSettingsId",
table: "ExcludedItem",
column: "XpSettingsId",
principalTable: "XpSettings",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_FilterChannelId_GuildConfigs_GuildConfigId",
table: "FilterChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_FilteredWord_GuildConfigs_GuildConfigId",
table: "FilteredWord",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_FilterLinksChannelId_GuildConfigs_GuildConfigId",
table: "FilterLinksChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_FilterWordsChannelId_GuildConfigs_GuildConfigId",
table: "FilterWordsChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_FollowedStream_GuildConfigs_GuildConfigId",
table: "FollowedStream",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_GCChannelId_GuildConfigs_GuildConfigId",
table: "GCChannelId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_MutedUserId_GuildConfigs_GuildConfigId",
table: "MutedUserId",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Permissions_GuildConfigs_GuildConfigId",
table: "Permissions",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_ShopEntry_GuildConfigs_GuildConfigId",
table: "ShopEntry",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_ShopEntryItem_ShopEntry_ShopEntryId",
table: "ShopEntryItem",
column: "ShopEntryId",
principalTable: "ShopEntry",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_SlowmodeIgnoredRole_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredRole",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_SlowmodeIgnoredUser_GuildConfigs_GuildConfigId",
table: "SlowmodeIgnoredUser",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_StreamRoleBlacklistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleBlacklistedUser",
column: "StreamRoleSettingsId",
principalTable: "StreamRoleSettings",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_StreamRoleWhitelistedUser_StreamRoleSettings_StreamRoleSettingsId",
table: "StreamRoleWhitelistedUser",
column: "StreamRoleSettingsId",
principalTable: "StreamRoleSettings",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_UnbanTimer_GuildConfigs_GuildConfigId",
table: "UnbanTimer",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_UnmuteTimer_GuildConfigs_GuildConfigId",
table: "UnmuteTimer",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_UnroleTimer_GuildConfigs_GuildConfigId",
table: "UnroleTimer",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_VcRoleInfo_GuildConfigs_GuildConfigId",
table: "VcRoleInfo",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
table: "WarningPunishment",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id");
}
}
}

View File

@@ -501,7 +501,7 @@ namespace NadekoBot.Migrations
b.Property<DateTime?>("DateAdded") b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<int?>("GuildConfigId") b.Property<int>("GuildConfigId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<bool>("State") b.Property<bool>("State")
@@ -1059,28 +1059,6 @@ namespace NadekoBot.Migrations
b.ToTable("IgnoredLogChannels"); b.ToTable("IgnoredLogChannels");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredVoicePresenceChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ulong>("ChannelId")
.HasColumnType("INTEGER");
b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT");
b.Property<int?>("LogSettingId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels");
});
modelBuilder.Entity("NadekoBot.Db.Models.ImageOnlyChannel", b => modelBuilder.Entity("NadekoBot.Db.Models.ImageOnlyChannel", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@@ -1867,7 +1845,7 @@ namespace NadekoBot.Migrations
b.Property<DateTime?>("DateAdded") b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<int?>("StreamRoleSettingsId") b.Property<int>("StreamRoleSettingsId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<ulong>("UserId") b.Property<ulong>("UserId")
@@ -1924,7 +1902,7 @@ namespace NadekoBot.Migrations
b.Property<DateTime?>("DateAdded") b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<int?>("StreamRoleSettingsId") b.Property<int>("StreamRoleSettingsId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<ulong>("UserId") b.Property<ulong>("UserId")
@@ -2397,31 +2375,28 @@ namespace NadekoBot.Migrations
modelBuilder.Entity("NadekoBot.Db.Models.AntiRaidSetting", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiRaidSetting", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithOne("AntiRaidSetting") .WithOne("AntiRaidSetting")
.HasForeignKey("NadekoBot.Db.Models.AntiRaidSetting", "GuildConfigId") .HasForeignKey("NadekoBot.Db.Models.AntiRaidSetting", "GuildConfigId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("GuildConfig");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamIgnore", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamIgnore", b =>
{ {
b.HasOne("NadekoBot.Db.Models.AntiSpamSetting", null) b.HasOne("NadekoBot.Db.Models.AntiSpamSetting", null)
.WithMany("IgnoredChannels") .WithMany("IgnoredChannels")
.HasForeignKey("AntiSpamSettingId"); .HasForeignKey("AntiSpamSettingId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamSetting", b => modelBuilder.Entity("NadekoBot.Db.Models.AntiSpamSetting", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithOne("AntiSpamSetting") .WithOne("AntiSpamSetting")
.HasForeignKey("NadekoBot.Db.Models.AntiSpamSetting", "GuildConfigId") .HasForeignKey("NadekoBot.Db.Models.AntiSpamSetting", "GuildConfigId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("GuildConfig");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.AutoTranslateUser", b => modelBuilder.Entity("NadekoBot.Db.Models.AutoTranslateUser", b =>
@@ -2487,21 +2462,25 @@ namespace NadekoBot.Migrations
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("CommandAliases") .WithMany("CommandAliases")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.CommandCooldown", b => modelBuilder.Entity("NadekoBot.Db.Models.CommandCooldown", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("CommandCooldowns") .WithMany("CommandCooldowns")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.DelMsgOnCmdChannel", b => modelBuilder.Entity("NadekoBot.Db.Models.DelMsgOnCmdChannel", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("DelMsgOnCmdChannels") .WithMany("DelMsgOnCmdChannels")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
}); });
modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b => modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b =>
@@ -2516,9 +2495,12 @@ namespace NadekoBot.Migrations
modelBuilder.Entity("NadekoBot.Db.Models.ExcludedItem", b => modelBuilder.Entity("NadekoBot.Db.Models.ExcludedItem", b =>
{ {
b.HasOne("NadekoBot.Db.Models.XpSettings", null) b.HasOne("NadekoBot.Db.Models.XpSettings", "XpSettings")
.WithMany("ExclusionList") .WithMany("ExclusionList")
.HasForeignKey("XpSettingsId"); .HasForeignKey("XpSettingsId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("XpSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FeedSub", b => modelBuilder.Entity("NadekoBot.Db.Models.FeedSub", b =>
@@ -2536,42 +2518,48 @@ namespace NadekoBot.Migrations
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterInvitesChannelIds") .WithMany("FilterInvitesChannelIds")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FilterLinksChannelId", b => modelBuilder.Entity("NadekoBot.Db.Models.FilterLinksChannelId", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterLinksChannelIds") .WithMany("FilterLinksChannelIds")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FilterWordsChannelId", b => modelBuilder.Entity("NadekoBot.Db.Models.FilterWordsChannelId", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilterWordsChannelIds") .WithMany("FilterWordsChannelIds")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FilteredWord", b => modelBuilder.Entity("NadekoBot.Db.Models.FilteredWord", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FilteredWords") .WithMany("FilteredWords")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b => modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("FollowedStreams") .WithMany("FollowedStreams")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.GCChannelId", b => modelBuilder.Entity("NadekoBot.Db.Models.GCChannelId", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig") b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig")
.WithMany("GenerateCurrencyChannelIds") .WithMany("GenerateCurrencyChannelIds")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
b.Navigation("GuildConfig"); b.Navigation("GuildConfig");
}); });
@@ -2607,27 +2595,20 @@ namespace NadekoBot.Migrations
b.Navigation("LogSetting"); b.Navigation("LogSetting");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredVoicePresenceChannel", b =>
{
b.HasOne("NadekoBot.Db.Models.LogSetting", "LogSetting")
.WithMany()
.HasForeignKey("LogSettingId");
b.Navigation("LogSetting");
});
modelBuilder.Entity("NadekoBot.Db.Models.MutedUserId", b => modelBuilder.Entity("NadekoBot.Db.Models.MutedUserId", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("MutedUsers") .WithMany("MutedUsers")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.Permissionv2", b => modelBuilder.Entity("NadekoBot.Db.Models.Permissionv2", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("Permissions") .WithMany("Permissions")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.PlaylistSong", b => modelBuilder.Entity("NadekoBot.Db.Models.PlaylistSong", b =>
@@ -2642,35 +2623,43 @@ namespace NadekoBot.Migrations
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("ShopEntries") .WithMany("ShopEntries")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.ShopEntryItem", b => modelBuilder.Entity("NadekoBot.Db.Models.ShopEntryItem", b =>
{ {
b.HasOne("NadekoBot.Db.Models.ShopEntry", null) b.HasOne("NadekoBot.Db.Models.ShopEntry", null)
.WithMany("Items") .WithMany("Items")
.HasForeignKey("ShopEntryId"); .HasForeignKey("ShopEntryId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.SlowmodeIgnoredRole", b => modelBuilder.Entity("NadekoBot.Db.Models.SlowmodeIgnoredRole", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("SlowmodeIgnoredRoles") .WithMany("SlowmodeIgnoredRoles")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.SlowmodeIgnoredUser", b => modelBuilder.Entity("NadekoBot.Db.Models.SlowmodeIgnoredUser", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("SlowmodeIgnoredUsers") .WithMany("SlowmodeIgnoredUsers")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleBlacklistedUser", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleBlacklistedUser", b =>
{ {
b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", null) b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
.WithMany("Blacklist") .WithMany("Blacklist")
.HasForeignKey("StreamRoleSettingsId"); .HasForeignKey("StreamRoleSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleSettings", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleSettings", b =>
@@ -2686,9 +2675,13 @@ namespace NadekoBot.Migrations
modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleWhitelistedUser", b => modelBuilder.Entity("NadekoBot.Db.Models.StreamRoleWhitelistedUser", b =>
{ {
b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", null) b.HasOne("NadekoBot.Db.Models.StreamRoleSettings", "StreamRoleSettings")
.WithMany("Whitelist") .WithMany("Whitelist")
.HasForeignKey("StreamRoleSettingsId"); .HasForeignKey("StreamRoleSettingsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("StreamRoleSettings");
}); });
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b => modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
@@ -2703,28 +2696,32 @@ namespace NadekoBot.Migrations
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnbanTimer") .WithMany("UnbanTimer")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.UnmuteTimer", b => modelBuilder.Entity("NadekoBot.Db.Models.UnmuteTimer", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnmuteTimers") .WithMany("UnmuteTimers")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.UnroleTimer", b => modelBuilder.Entity("NadekoBot.Db.Models.UnroleTimer", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("UnroleTimer") .WithMany("UnroleTimer")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.VcRoleInfo", b => modelBuilder.Entity("NadekoBot.Db.Models.VcRoleInfo", b =>
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("VcRoleInfos") .WithMany("VcRoleInfos")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.WaifuInfo", b => modelBuilder.Entity("NadekoBot.Db.Models.WaifuInfo", b =>
@@ -2786,7 +2783,8 @@ namespace NadekoBot.Migrations
{ {
b.HasOne("NadekoBot.Db.Models.GuildConfig", null) b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("WarnPunishments") .WithMany("WarnPunishments")
.HasForeignKey("GuildConfigId"); .HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("NadekoBot.Db.Models.XpCurrencyReward", b => modelBuilder.Entity("NadekoBot.Db.Models.XpCurrencyReward", b =>

View File

@@ -1,5 +1,6 @@
#nullable disable #nullable disable
using NadekoBot.Common.TypeReaders.Models; using NadekoBot.Common.TypeReaders.Models;
using NadekoBot.Modules.Administration._common.results;
using NadekoBot.Modules.Administration.Services; using NadekoBot.Modules.Administration.Services;
namespace NadekoBot.Modules.Administration; namespace NadekoBot.Modules.Administration;
@@ -405,4 +406,94 @@ public partial class Administration : NadekoModule<AdministrationService>
await Response().Confirm(strs.autopublish_disable).SendAsync(); await Response().Confirm(strs.autopublish_disable).SendAsync();
} }
} }
[Cmd]
[UserPerm(GuildPerm.ManageNicknames)]
[BotPerm(GuildPerm.ChangeNickname)]
[Priority(0)]
public async Task SetNick([Leftover] string newNick = null)
{
if (string.IsNullOrWhiteSpace(newNick))
return;
var curUser = await ctx.Guild.GetCurrentUserAsync();
await curUser.ModifyAsync(u => u.Nickname = newNick);
await Response().Confirm(strs.bot_nick(Format.Bold(newNick) ?? "-")).SendAsync();
}
[Cmd]
[BotPerm(GuildPerm.ManageNicknames)]
[UserPerm(GuildPerm.ManageNicknames)]
[Priority(1)]
public async Task SetNick(IGuildUser gu, [Leftover] string newNick = null)
{
var sg = (SocketGuild)ctx.Guild;
if (sg.OwnerId == gu.Id
|| gu.GetRoles().Max(r => r.Position) >= sg.CurrentUser.GetRoles().Max(r => r.Position))
{
await Response().Error(strs.insuf_perms_i).SendAsync();
return;
}
await gu.ModifyAsync(u => u.Nickname = newNick);
await Response()
.Confirm(strs.user_nick(Format.Bold(gu.ToString()), Format.Bold(newNick) ?? "-"))
.SendAsync();
}
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPermission.ManageGuild)]
[BotPerm(GuildPermission.ManageGuild)]
public async Task SetServerBanner([Leftover] string img = null)
{
// Tier2 or higher is required to set a banner.
if (ctx.Guild.PremiumTier is PremiumTier.Tier1 or PremiumTier.None) return;
var result = await _service.SetServerBannerAsync(ctx.Guild, img);
switch (result)
{
case SetServerBannerResult.Success:
await Response().Confirm(strs.set_srvr_banner).SendAsync();
break;
case SetServerBannerResult.InvalidFileType:
await Response().Error(strs.srvr_banner_invalid).SendAsync();
break;
case SetServerBannerResult.Toolarge:
await Response().Error(strs.srvr_banner_too_large).SendAsync();
break;
case SetServerBannerResult.InvalidURL:
await Response().Error(strs.srvr_banner_invalid_url).SendAsync();
break;
default:
throw new ArgumentOutOfRangeException();
}
}
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPermission.ManageGuild)]
[BotPerm(GuildPermission.ManageGuild)]
public async Task SetServerIcon([Leftover] string img = null)
{
var result = await _service.SetServerIconAsync(ctx.Guild, img);
switch (result)
{
case SetServerIconResult.Success:
await Response().Confirm(strs.set_srvr_icon).SendAsync();
break;
case SetServerIconResult.InvalidFileType:
await Response().Error(strs.srvr_banner_invalid).SendAsync();
break;
case SetServerIconResult.InvalidURL:
await Response().Error(strs.srvr_banner_invalid_url).SendAsync();
break;
default:
throw new ArgumentOutOfRangeException();
}
}
} }

View File

@@ -2,6 +2,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NadekoBot.Db; using NadekoBot.Db;
using NadekoBot.Db.Models; using NadekoBot.Db.Models;
using NadekoBot.Modules.Administration._common.results;
namespace NadekoBot.Modules.Administration.Services; namespace NadekoBot.Modules.Administration.Services;
@@ -13,17 +14,20 @@ public class AdministrationService : INService
private readonly DbService _db; private readonly DbService _db;
private readonly IReplacementService _repSvc; private readonly IReplacementService _repSvc;
private readonly ILogCommandService _logService; private readonly ILogCommandService _logService;
private readonly IHttpClientFactory _httpFactory;
public AdministrationService( public AdministrationService(
IBot bot, IBot bot,
CommandHandler cmdHandler, CommandHandler cmdHandler,
DbService db, DbService db,
IReplacementService repSvc, IReplacementService repSvc,
ILogCommandService logService) ILogCommandService logService,
IHttpClientFactory factory)
{ {
_db = db; _db = db;
_repSvc = repSvc; _repSvc = repSvc;
_logService = logService; _logService = logService;
_httpFactory = factory;
DeleteMessagesOnCommand = new(bot.AllGuildConfigs.Where(g => g.DeleteMessageOnCommand).Select(g => g.GuildId)); DeleteMessagesOnCommand = new(bot.AllGuildConfigs.Where(g => g.DeleteMessageOnCommand).Select(g => g.GuildId));
@@ -158,4 +162,45 @@ public class AdministrationService : INService
await umsg.EditAsync(text); await umsg.EditAsync(text);
} }
public async Task<SetServerBannerResult> SetServerBannerAsync(IGuild guild, string img)
{
if (!IsValidUri(img)) return SetServerBannerResult.InvalidURL;
var uri = new Uri(img);
using var http = _httpFactory.CreateClient();
using var sr = await http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
if (!sr.IsImage()) return SetServerBannerResult.InvalidFileType;
if (sr.GetContentLength() > 8.Megabytes())
{
return SetServerBannerResult.Toolarge;
}
await using var imageStream = await sr.Content.ReadAsStreamAsync();
await guild.ModifyAsync(x => x.Banner = new Image(imageStream));
return SetServerBannerResult.Success;
}
public async Task<SetServerIconResult> SetServerIconAsync(IGuild guild, string img)
{
if (!IsValidUri(img)) return SetServerIconResult.InvalidURL;
var uri = new Uri(img);
using var http = _httpFactory.CreateClient();
using var sr = await http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
if (!sr.IsImage()) return SetServerIconResult.InvalidFileType;
await using var imageStream = await sr.Content.ReadAsStreamAsync();
await guild.ModifyAsync(x => x.Icon = new Image(imageStream));
return SetServerIconResult.Success;
}
private bool IsValidUri(string img) => !string.IsNullOrWhiteSpace(img) && Uri.IsWellFormedUriString(img, UriKind.Absolute);
} }

View File

@@ -0,0 +1,31 @@
namespace NadekoBot.Modules.Administration.DangerousCommands;
public partial class Administration
{
[Group]
public class CleanupCommands : CleanupModuleBase
{
private readonly ICleanupService _svc;
public CleanupCommands(ICleanupService svc)
=> _svc = svc;
[Cmd]
[OwnerOnly]
[RequireContext(ContextType.DM)]
public async Task CleanupGuildData()
{
var result = await _svc.DeleteMissingGuildDataAsync();
if (result is null)
{
await ctx.ErrorAsync();
return;
}
await Response()
.Confirm($"{result.GuildCount} guilds' data remain in the database.")
.SendAsync();
}
}
}

View File

@@ -0,0 +1,106 @@
using LinqToDB;
using LinqToDB.Data;
using LinqToDB.EntityFrameworkCore;
using NadekoBot.Common.ModuleBehaviors;
using NadekoBot.Db.Models;
namespace NadekoBot.Modules.Administration.DangerousCommands;
public sealed class CleanupService : ICleanupService, IReadyExecutor, INService
{
private readonly IPubSub _pubSub;
private TypedKey<KeepReport> _keepReportKey = new("cleanup:report");
private TypedKey<bool> _keepTriggerKey = new("cleanup:trigger");
private readonly DiscordSocketClient _client;
private ConcurrentDictionary<int, ulong[]> guildIds = new();
private readonly IBotCredsProvider _creds;
private readonly DbService _db;
public CleanupService(
IPubSub pubSub,
DiscordSocketClient client,
IBotCredsProvider creds,
DbService db)
{
_pubSub = pubSub;
_client = client;
_creds = creds;
_db = db;
}
public async Task<KeepResult?> DeleteMissingGuildDataAsync()
{
guildIds = new();
var totalShards = _creds.GetCreds().TotalShards;
await _pubSub.Pub(_keepTriggerKey, true);
var counter = 0;
while (guildIds.Keys.Count < totalShards)
{
await Task.Delay(1000);
counter++;
if (counter >= 5)
break;
}
if (guildIds.Keys.Count < totalShards)
return default;
var allIds = guildIds.SelectMany(x => x.Value)
.ToArray();
await using var ctx = _db.GetDbContext();
await using var linqCtx = ctx.CreateLinqToDBContext();
await using var tempTable = linqCtx.CreateTempTable<CleanupId>();
foreach (var chunk in allIds.Chunk(20000))
{
await tempTable.BulkCopyAsync(chunk.Select(x => new CleanupId()
{
GuildId = x
}));
}
await ctx.GetTable<GuildConfig>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
await ctx.GetTable<UserXpStats>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
return new()
{
GuildCount = guildIds.Keys.Count,
};
}
private ValueTask OnKeepReport(KeepReport report)
{
guildIds[report.ShardId] = report.GuildIds;
return default;
}
public async Task OnReadyAsync()
{
await _pubSub.Sub(_keepTriggerKey, OnKeepTrigger);
if (_client.ShardId == 0)
await _pubSub.Sub(_keepReportKey, OnKeepReport);
}
private ValueTask OnKeepTrigger(bool arg)
{
_pubSub.Pub(_keepReportKey,
new KeepReport()
{
ShardId = _client.ShardId,
GuildIds = _client.GetGuildIds(),
});
return default;
}
}

View File

@@ -0,0 +1,9 @@
using System.ComponentModel.DataAnnotations;
namespace NadekoBot.Modules.Administration.DangerousCommands;
public sealed class CleanupId
{
[Key]
public ulong GuildId { get; set; }
}

View File

@@ -0,0 +1,6 @@
namespace NadekoBot.Modules.Administration.DangerousCommands;
public interface ICleanupService
{
Task<KeepResult?> DeleteMissingGuildDataAsync();
}

View File

@@ -0,0 +1,7 @@
namespace NadekoBot.Modules.Administration.DangerousCommands;
public sealed class KeepReport
{
public required int ShardId { get; init; }
public required ulong[] GuildIds { get; init; }
}

View File

@@ -0,0 +1,6 @@
namespace NadekoBot.Modules.Administration.DangerousCommands;
public sealed class KeepResult
{
public required int GuildCount { get; init; }
}

View File

@@ -97,7 +97,7 @@ public class GreetService : INService, IReadyExecutor
{ {
var newContent = await _repSvc.ReplaceAsync(toSend, var newContent = await _repSvc.ReplaceAsync(toSend,
new(client: _client, guild: user.Guild, channel: channel, users: user)); new(client: _client, guild: user.Guild, channel: channel, users: user));
var toDelete = await _sender.Response(channel).Text(newContent).SendAsync(); var toDelete = await _sender.Response(channel).Text(newContent).Sanitize(false).SendAsync();
if (conf.BoostMessageDeleteAfter > 0) if (conf.BoostMessageDeleteAfter > 0)
toDelete.DeleteAfter(conf.BoostMessageDeleteAfter); toDelete.DeleteAfter(conf.BoostMessageDeleteAfter);
@@ -202,12 +202,6 @@ public class GreetService : INService, IReadyExecutor
if (!users.Any()) if (!users.Any())
return; return;
// var rep = new ReplacementBuilder().WithChannel(channel)
// .WithClient(_client)
// .WithServer(_client, (SocketGuild)channel.Guild)
// .WithManyUsers(users)
// .Build();
var repCtx = new ReplacementContext(client: _client, var repCtx = new ReplacementContext(client: _client,
guild: channel.Guild, guild: channel.Guild,
channel: channel, channel: channel,
@@ -217,11 +211,12 @@ public class GreetService : INService, IReadyExecutor
text = await _repSvc.ReplaceAsync(text, repCtx); text = await _repSvc.ReplaceAsync(text, repCtx);
try try
{ {
var toDelete = await _sender.Response(channel).Text(text).SendAsync(); var toDelete = await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
if (conf.AutoDeleteByeMessagesTimer > 0) if (conf.AutoDeleteByeMessagesTimer > 0)
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer); toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
} }
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions
|| ex.DiscordCode == DiscordErrorCode.MissingPermissions
|| ex.DiscordCode == DiscordErrorCode.UnknownChannel) || ex.DiscordCode == DiscordErrorCode.UnknownChannel)
{ {
Log.Warning(ex, Log.Warning(ex,
@@ -243,26 +238,21 @@ public class GreetService : INService, IReadyExecutor
if (users.Count == 0) if (users.Count == 0)
return; return;
// var rep = new ReplacementBuilder()
// .WithChannel(channel)
// .WithClient(_client)
// .WithServer(_client, (SocketGuild)channel.Guild)
// .WithManyUsers(users)
// .Build();
var repCtx = new ReplacementContext(client: _client, var repCtx = new ReplacementContext(client: _client,
guild: channel.Guild, guild: channel.Guild,
channel: channel, channel: channel,
users: users.ToArray()); users: users.ToArray());
var text = SmartText.CreateFrom(conf.ChannelGreetMessageText); var text = SmartText.CreateFrom(conf.ChannelGreetMessageText);
text = await _repSvc.ReplaceAsync(text, repCtx); text = await _repSvc.ReplaceAsync(text, repCtx);
try try
{ {
var toDelete = await _sender.Response(channel).Text(text).SendAsync(); var toDelete = await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
if (conf.AutoDeleteGreetMessagesTimer > 0) if (conf.AutoDeleteGreetMessagesTimer > 0)
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer); toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
} }
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions
|| ex.DiscordCode == DiscordErrorCode.MissingPermissions
|| ex.DiscordCode == DiscordErrorCode.UnknownChannel) || ex.DiscordCode == DiscordErrorCode.UnknownChannel)
{ {
Log.Warning(ex, Log.Warning(ex,
@@ -329,13 +319,13 @@ public class GreetService : INService, IReadyExecutor
// if there are no embeds, add an embed with the footer // if there are no embeds, add an embed with the footer
smartText = seta with smartText = seta with
{ {
Embeds = new[] Embeds =
{ [
new SmartEmbedArrayElementText() new SmartEmbedArrayElementText()
{ {
Footer = CreateFooterSource(user) Footer = CreateFooterSource(user)
} }
} ]
}; };
} }
else else
@@ -360,7 +350,7 @@ public class GreetService : INService, IReadyExecutor
} }
} }
await _sender.Response(user).Text(smartText).SendAsync(); await _sender.Response(user).Text(smartText).Sanitize(false).SendAsync();
} }
catch catch
{ {
@@ -573,8 +563,6 @@ public class GreetService : INService, IReadyExecutor
public bool SetBoostMessage(ulong guildId, ref string message) public bool SetBoostMessage(ulong guildId, ref string message)
{ {
message = message.SanitizeMentions();
using var uow = _db.GetDbContext(); using var uow = _db.GetDbContext();
var conf = uow.GuildConfigsForId(guildId, set => set); var conf = uow.GuildConfigsForId(guildId, set => set);
conf.BoostMessage = message; conf.BoostMessage = message;

View File

@@ -175,7 +175,7 @@ public sealed class SomethingOnlyChannelService : IExecOnMessage
// ignore owner and admin // ignore owner and admin
if (user.Id == tch.Guild.OwnerId || user.GuildPermissions.Administrator) if (user.Id == tch.Guild.OwnerId || user.GuildPermissions.Administrator)
{ {
Log.Information("{Type}-Only Channel: Ignoring owner od admin ({ChannelId})", type, msg.Channel.Id); Log.Information("{Type}-Only Channel: Ignoring owner or admin ({ChannelId})", type, msg.Channel.Id);
return false; return false;
} }

View File

@@ -61,7 +61,13 @@ public partial class Administration
} }
else else
{ {
ci = new(name); ci = new CultureInfo(name);
if (!_supportedLocales.ContainsKey(ci.Name))
{
await LanguagesList();
return;
}
_localization.SetGuildCulture(ctx.Guild, ci); _localization.SetGuildCulture(ctx.Guild, ci);
} }
@@ -97,7 +103,12 @@ public partial class Administration
} }
else else
{ {
ci = new(name); ci = new CultureInfo(name);
if (!_supportedLocales.ContainsKey(ci.Name))
{
await LanguagesList();
return;
}
_localization.SetDefaultCulture(ci); _localization.SetDefaultCulture(ci);
} }

View File

@@ -291,8 +291,7 @@ public class MuteService : INService
public async Task<IRole> GetMuteRole(IGuild guild) public async Task<IRole> GetMuteRole(IGuild guild)
{ {
if (guild is null) ArgumentNullException.ThrowIfNull(guild);
throw new ArgumentNullException(nameof(guild));
const string defaultMuteRoleName = "nadeko-mute"; const string defaultMuteRoleName = "nadeko-mute";

View File

@@ -69,8 +69,7 @@ public sealed class PlayingRotateService : INService, IReadyExecutor
public async Task<string> RemovePlayingAsync(int index) public async Task<string> RemovePlayingAsync(int index)
{ {
if (index < 0) ArgumentOutOfRangeException.ThrowIfNegative(index);
throw new ArgumentOutOfRangeException(nameof(index));
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
var toRemove = await uow.Set<RotatingPlayingStatus>().AsQueryable().AsNoTracking().Skip(index).FirstOrDefaultAsync(); var toRemove = await uow.Set<RotatingPlayingStatus>().AsQueryable().AsNoTracking().Skip(index).FirstOrDefaultAsync();

View File

@@ -22,8 +22,7 @@ public class PruneService : INService
ArgumentNullException.ThrowIfNull(channel, nameof(channel)); ArgumentNullException.ThrowIfNull(channel, nameof(channel));
var originalAmount = amount; var originalAmount = amount;
if (amount <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
using var cancelSource = new CancellationTokenSource(); using var cancelSource = new CancellationTokenSource();
if (!_pruningGuilds.TryAdd(channel.GuildId, cancelSource)) if (!_pruningGuilds.TryAdd(channel.GuildId, cancelSource))

View File

@@ -250,11 +250,9 @@ public sealed class ReactionRolesService : IReadyExecutor, INService, IReactionR
int group = 0, int group = 0,
int levelReq = 0) int levelReq = 0)
{ {
if (group < 0) ArgumentOutOfRangeException.ThrowIfNegative(group);
throw new ArgumentOutOfRangeException(nameof(group));
if (levelReq < 0) ArgumentOutOfRangeException.ThrowIfNegative(levelReq);
throw new ArgumentOutOfRangeException(nameof(group));
await using var ctx = _db.GetDbContext(); await using var ctx = _db.GetDbContext();
@@ -307,10 +305,7 @@ public sealed class ReactionRolesService : IReadyExecutor, INService, IReactionR
lock (_cacheLock) lock (_cacheLock)
{ {
_cache.AddOrUpdate(msg.Id, _cache.AddOrUpdate(msg.Id,
_ => new() _ => [obj],
{
obj
},
(_, list) => (_, list) =>
{ {
list.RemoveAll(x => x.Emote == emote); list.RemoveAll(x => x.Emote == emote);

View File

@@ -459,42 +459,7 @@ public partial class Administration
await Response().Confirm(strs.bot_name(Format.Bold(newName))).SendAsync(); await Response().Confirm(strs.bot_name(Format.Bold(newName))).SendAsync();
} }
[Cmd]
[UserPerm(GuildPerm.ManageNicknames)]
[BotPerm(GuildPerm.ChangeNickname)]
[Priority(0)]
public async Task SetNick([Leftover] string newNick = null)
{
if (string.IsNullOrWhiteSpace(newNick))
return;
var curUser = await ctx.Guild.GetCurrentUserAsync();
await curUser.ModifyAsync(u => u.Nickname = newNick);
await Response().Confirm(strs.bot_nick(Format.Bold(newNick) ?? "-")).SendAsync();
}
[Cmd]
[BotPerm(GuildPerm.ManageNicknames)]
[UserPerm(GuildPerm.ManageNicknames)]
[Priority(1)]
public async Task SetNick(IGuildUser gu, [Leftover] string newNick = null)
{
var sg = (SocketGuild)ctx.Guild;
if (sg.OwnerId == gu.Id
|| gu.GetRoles().Max(r => r.Position) >= sg.CurrentUser.GetRoles().Max(r => r.Position))
{
await Response().Error(strs.insuf_perms_i).SendAsync();
return;
}
await gu.ModifyAsync(u => u.Nickname = newNick);
await Response()
.Confirm(strs.user_nick(Format.Bold(gu.ToString()), Format.Bold(newNick) ?? "-"))
.SendAsync();
}
[Cmd] [Cmd]
[OwnerOnly] [OwnerOnly]
public async Task SetStatus([Leftover] SettableUserStatus status) public async Task SetStatus([Leftover] SettableUserStatus status)

View File

@@ -24,7 +24,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
private readonly GuildTimezoneService _tz; private readonly GuildTimezoneService _tz;
private readonly IMemoryCache _memoryCache; private readonly IMemoryCache _memoryCache;
private readonly ConcurrentHashSet<ulong> _ignoreMessageIds = new(); private readonly ConcurrentHashSet<ulong> _ignoreMessageIds = [];
private readonly UserPunishService _punishService; private readonly UserPunishService _punishService;
private readonly IMessageSenderService _sender; private readonly IMessageSenderService _sender;
@@ -115,10 +115,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
strs.user_status_change("👤" + Format.Bold(gu.Username), strs.user_status_change("👤" + Format.Bold(gu.Username),
Format.Bold(after.Status.ToString()))); Format.Bold(after.Status.ToString())));
PresenceUpdates.AddOrUpdate(logChannel, PresenceUpdates.AddOrUpdate(logChannel,
new List<string> [str],
{
str
},
(_, list) => (_, list) =>
{ {
list.Add(str); list.Add(str);
@@ -130,10 +127,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
var str = var str =
$"👾`{PrettyCurrentTime(gu.Guild)}`👤__**{gu.Username}**__ is now playing **{after.Activities.FirstOrDefault()?.Name ?? "-"}**."; $"👾`{PrettyCurrentTime(gu.Guild)}`👤__**{gu.Username}**__ is now playing **{after.Activities.FirstOrDefault()?.Name ?? "-"}**.";
PresenceUpdates.AddOrUpdate(logChannel, PresenceUpdates.AddOrUpdate(logChannel,
new List<string> [str],
{
str
},
(_, list) => (_, list) =>
{ {
list.Add(str); list.Add(str);
@@ -881,10 +875,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
if (!string.IsNullOrWhiteSpace(str)) if (!string.IsNullOrWhiteSpace(str))
{ {
PresenceUpdates.AddOrUpdate(logChannel, PresenceUpdates.AddOrUpdate(logChannel,
new List<string> [str],
{
str
},
(_, list) => (_, list) =>
{ {
list.Add(str); list.Add(str);

View File

@@ -64,8 +64,7 @@ public class UserPunishService : INService, IReadyExecutor
long weight, long weight,
string reason) string reason)
{ {
if (weight <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(weight);
throw new ArgumentOutOfRangeException(nameof(weight));
var modName = mod.ToString(); var modName = mod.ToString();

View File

@@ -130,8 +130,7 @@ public class VcRoleService : INService
public void AddVcRole(ulong guildId, IRole role, ulong vcId) public void AddVcRole(ulong guildId, IRole role, ulong vcId)
{ {
if (role is null) ArgumentNullException.ThrowIfNull(role);
throw new ArgumentNullException(nameof(role));
var guildVcRoles = VcRoles.GetOrAdd(guildId, new ConcurrentDictionary<ulong, IRole>()); var guildVcRoles = VcRoles.GetOrAdd(guildId, new ConcurrentDictionary<ulong, IRole>());

View File

@@ -0,0 +1,9 @@
namespace NadekoBot.Modules.Administration._common.results;
public enum SetServerBannerResult
{
Success,
InvalidFileType,
Toolarge,
InvalidURL
}

View File

@@ -0,0 +1,8 @@
namespace NadekoBot.Modules.Administration._common.results;
public enum SetServerIconResult
{
Success,
InvalidFileType,
InvalidURL
}

View File

@@ -1,5 +1,7 @@
#nullable disable #nullable disable
using NadekoBot.Db.Models;
namespace NadekoBot.Modules.NadekoExpressions; namespace NadekoBot.Modules.NadekoExpressions;
[Name("Expressions")] [Name("Expressions")]
@@ -34,12 +36,12 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
await Response() await Response()
.Embed(_sender.CreateEmbed() .Embed(_sender.CreateEmbed()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.expr_new)) .WithTitle(GetText(strs.expr_new))
.WithDescription($"#{new kwum(ex.Id)}") .WithDescription($"#{new kwum(ex.Id)}")
.AddField(GetText(strs.trigger), key) .AddField(GetText(strs.trigger), key)
.AddField(GetText(strs.response), .AddField(GetText(strs.response),
message.Length > 1024 ? GetText(strs.redacted_too_long) : message)) message.Length > 1024 ? GetText(strs.redacted_too_long) : message))
.SendAsync(); .SendAsync();
} }
@@ -68,9 +70,9 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
[Cmd] [Cmd]
public async Task ExprAdd(string key, [Leftover] string message) public async Task ExprAdd(string trigger, [Leftover] string response)
{ {
if (string.IsNullOrWhiteSpace(message) || string.IsNullOrWhiteSpace(key)) if (string.IsNullOrWhiteSpace(response) || string.IsNullOrWhiteSpace(trigger))
{ {
return; return;
} }
@@ -81,7 +83,7 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
return; return;
} }
await ExprAddInternalAsync(key, message); await ExprAddInternalAsync(trigger, response);
} }
[Cmd] [Cmd]
@@ -93,8 +95,7 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
return; return;
} }
if ((channel is null && !_creds.IsOwner(ctx.User)) if (!IsValidExprEditor())
|| (channel is not null && !((IGuildUser)ctx.User).GuildPermissions.Administrator))
{ {
await Response().Error(strs.expr_insuff_perms).SendAsync(); await Response().Error(strs.expr_insuff_perms).SendAsync();
return; return;
@@ -105,12 +106,12 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
{ {
await Response() await Response()
.Embed(_sender.CreateEmbed() .Embed(_sender.CreateEmbed()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.expr_edited)) .WithTitle(GetText(strs.expr_edited))
.WithDescription($"#{id}") .WithDescription($"#{id}")
.AddField(GetText(strs.trigger), ex.Trigger) .AddField(GetText(strs.trigger), ex.Trigger)
.AddField(GetText(strs.response), .AddField(GetText(strs.response),
message.Length > 1024 ? GetText(strs.redacted_too_long) : message)) message.Length > 1024 ? GetText(strs.redacted_too_long) : message))
.SendAsync(); .SendAsync();
} }
else else
@@ -119,6 +120,10 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
} }
} }
private bool IsValidExprEditor()
=> (ctx.Guild is not null && ((IGuildUser)ctx.User).GuildPermissions.Administrator)
|| (ctx.Guild is null && _creds.IsOwner(ctx.User));
[Cmd] [Cmd]
[Priority(1)] [Priority(1)]
public async Task ExprList(int page = 1) public async Task ExprList(int page = 1)
@@ -132,7 +137,7 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
.OrderBy(x => x.Trigger) .OrderBy(x => x.Trigger)
.ToArray(); .ToArray();
if (allExpressions is null || !allExpressions.Any()) if (!allExpressions.Any())
{ {
await Response().Error(strs.expr_no_found).SendAsync(); await Response().Error(strs.expr_no_found).SendAsync();
return; return;
@@ -171,16 +176,48 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
return; return;
} }
var inter = CreateEditInteraction(id, found);
await Response() await Response()
.Interaction(IsValidExprEditor() ? inter : null)
.Embed(_sender.CreateEmbed() .Embed(_sender.CreateEmbed()
.WithOkColor() .WithOkColor()
.WithDescription($"#{id}") .WithDescription($"#{id}")
.AddField(GetText(strs.trigger), found.Trigger.TrimTo(1024)) .AddField(GetText(strs.trigger), found.Trigger.TrimTo(1024))
.AddField(GetText(strs.response), .AddField(GetText(strs.response),
found.Response.TrimTo(1000).Replace("](", "]\\("))) found.Response.TrimTo(1000).Replace("](", "]\\(")))
.SendAsync(); .SendAsync();
} }
private NadekoInteractionBase CreateEditInteraction(kwum id, NadekoExpression found)
{
var modal = new ModalBuilder()
.WithCustomId("expr:edit_modal")
.WithTitle($"Edit expression {id}")
.AddTextInput(new TextInputBuilder()
.WithLabel(GetText(strs.response))
.WithValue(found.Response)
.WithMinLength(1)
.WithCustomId("expr:edit_modal:response")
.WithStyle(TextInputStyle.Paragraph));
var inter = _inter.Create(ctx.User.Id,
new ButtonBuilder()
.WithEmote(Emoji.Parse("📝"))
.WithLabel("Edit")
.WithStyle(ButtonStyle.Primary)
.WithCustomId("test"),
modal,
async (sm) =>
{
var msg = sm.Data.Components.FirstOrDefault()?.Value;
await ExprEdit(id, msg);
}
);
return inter;
}
public async Task ExprDeleteInternalAsync(kwum id) public async Task ExprDeleteInternalAsync(kwum id)
{ {
var ex = await _service.DeleteAsync(ctx.Guild?.Id, id); var ex = await _service.DeleteAsync(ctx.Guild?.Id, id);
@@ -189,11 +226,11 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
{ {
await Response() await Response()
.Embed(_sender.CreateEmbed() .Embed(_sender.CreateEmbed()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.expr_deleted)) .WithTitle(GetText(strs.expr_deleted))
.WithDescription($"#{id}") .WithDescription($"#{id}")
.AddField(GetText(strs.trigger), ex.Trigger.TrimTo(1024)) .AddField(GetText(strs.trigger), ex.Trigger.TrimTo(1024))
.AddField(GetText(strs.response), ex.Response.TrimTo(1024))) .AddField(GetText(strs.response), ex.Response.TrimTo(1024)))
.SendAsync(); .SendAsync();
} }
else else
@@ -340,8 +377,8 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
public async Task ExprClear() public async Task ExprClear()
{ {
if (await PromptUserConfirmAsync(_sender.CreateEmbed() if (await PromptUserConfirmAsync(_sender.CreateEmbed()
.WithTitle("Expression clear") .WithTitle("Expression clear")
.WithDescription("This will delete all expressions on this server."))) .WithDescription("This will delete all expressions on this server.")))
{ {
var count = _service.DeleteAllExpressions(ctx.Guild.Id); var count = _service.DeleteAllExpressions(ctx.Guild.Id);
await Response().Confirm(strs.exprs_cleared(count)).SendAsync(); await Response().Confirm(strs.exprs_cleared(count)).SendAsync();

View File

@@ -6,6 +6,7 @@ using NadekoBot.Db;
using NadekoBot.Db.Models; using NadekoBot.Db.Models;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using LinqToDB.EntityFrameworkCore; using LinqToDB.EntityFrameworkCore;
using NadekoBot.Modules.Permissions.Services;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NamingConventions;
@@ -77,6 +78,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
private bool ready; private bool ready;
private ConcurrentHashSet<ulong> _disabledGlobalExpressionGuilds; private ConcurrentHashSet<ulong> _disabledGlobalExpressionGuilds;
private readonly PermissionService _pc;
public NadekoExpressionsService( public NadekoExpressionsService(
DbService db, DbService db,
@@ -87,7 +89,8 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
IPubSub pubSub, IPubSub pubSub,
IMessageSenderService sender, IMessageSenderService sender,
IReplacementService repSvc, IReplacementService repSvc,
IPermissionChecker permChecker) IPermissionChecker permChecker,
PermissionService pc)
{ {
_db = db; _db = db;
_client = client; _client = client;
@@ -98,6 +101,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
_sender = sender; _sender = sender;
_repSvc = repSvc; _repSvc = repSvc;
_permChecker = permChecker; _permChecker = permChecker;
_pc = pc;
_rng = new NadekoRandom(); _rng = new NadekoRandom();
_pubSub.Sub(_exprsReloadedKey, OnExprsShouldReload); _pubSub.Sub(_exprsReloadedKey, OnExprsShouldReload);
@@ -138,6 +142,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
var globalItems = uow.Set<NadekoExpression>() var globalItems = uow.Set<NadekoExpression>()
.AsNoTracking() .AsNoTracking()
.Where(x => x.GuildId == null || x.GuildId == 0) .Where(x => x.GuildId == null || x.GuildId == 0)
.Where(x => x.Trigger != null)
.AsEnumerable() .AsEnumerable()
.Select(x => .Select(x =>
{ {
@@ -254,26 +259,30 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
"ACTUALEXPRESSIONS", "ACTUALEXPRESSIONS",
expr.Trigger expr.Trigger
); );
if (!result.IsAllowed) if (!result.IsAllowed)
{ {
if (result.TryPickT3(out var disallowed, out _)) var cache = _pc.GetCacheFor(guild.Id);
if (cache.Verbose)
{ {
var permissionMessage = _strings.GetText(strs.perm_prevent(disallowed.PermIndex + 1, if (result.TryPickT3(out var disallowed, out _))
Format.Bold(disallowed.PermText)),
sg.Id);
try
{ {
await _sender.Response(msg.Channel) var permissionMessage = _strings.GetText(strs.perm_prevent(disallowed.PermIndex + 1,
.Error(permissionMessage) Format.Bold(disallowed.PermText)),
.SendAsync(); sg.Id);
}
catch
{
}
Log.Information("{PermissionMessage}", permissionMessage); try
{
await _sender.Response(msg.Channel)
.Error(permissionMessage)
.SendAsync();
}
catch
{
}
Log.Information("{PermissionMessage}", permissionMessage);
}
} }
return true; return true;
@@ -356,7 +365,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
if (maybeGuildId is { } guildId) if (maybeGuildId is { } guildId)
{ {
newguildExpressions.AddOrUpdate(guildId, newguildExpressions.AddOrUpdate(guildId,
new[] { expr }, [expr],
(_, old) => (_, old) =>
{ {
var newArray = old.ToArray(); var newArray = old.ToArray();
@@ -389,7 +398,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
expr.Trigger = expr.Trigger.Replace(MENTION_PH, _client.CurrentUser.Mention); expr.Trigger = expr.Trigger.Replace(MENTION_PH, _client.CurrentUser.Mention);
if (maybeGuildId is { } guildId) if (maybeGuildId is { } guildId)
newguildExpressions.AddOrUpdate(guildId, new[] { expr }, (_, old) => old.With(expr)); newguildExpressions.AddOrUpdate(guildId, [expr], (_, old) => old.With(expr));
else else
return _pubSub.Pub(_gexprAddedKey, expr); return _pubSub.Pub(_gexprAddedKey, expr);

View File

@@ -61,8 +61,7 @@ public sealed class AnimalRace : IDisposable
public async Task<AnimalRacingUser> JoinRace(ulong userId, string userName, long bet = 0) public async Task<AnimalRacingUser> JoinRace(ulong userId, string userName, long bet = 0)
{ {
if (bet < 0) ArgumentOutOfRangeException.ThrowIfNegative(bet);
throw new ArgumentOutOfRangeException(nameof(bet));
var user = new AnimalRacingUser(userName, userId, bet); var user = new AnimalRacingUser(userName, userId, bet);

View File

@@ -17,8 +17,7 @@ public sealed class BankService : IBankService, INService
public async Task<bool> AwardAsync(ulong userId, long amount) public async Task<bool> AwardAsync(ulong userId, long amount)
{ {
if (amount <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
await using var ctx = _db.GetDbContext(); await using var ctx = _db.GetDbContext();
await ctx.GetTable<BankUser>() await ctx.GetTable<BankUser>()
@@ -41,9 +40,8 @@ public sealed class BankService : IBankService, INService
public async Task<bool> TakeAsync(ulong userId, long amount) public async Task<bool> TakeAsync(ulong userId, long amount)
{ {
if (amount <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
await using var ctx = _db.GetDbContext(); await using var ctx = _db.GetDbContext();
var rows = await ctx.Set<BankUser>() var rows = await ctx.Set<BankUser>()
.ToLinqToDBTable() .ToLinqToDBTable()
@@ -58,9 +56,8 @@ public sealed class BankService : IBankService, INService
public async Task<bool> DepositAsync(ulong userId, long amount) public async Task<bool> DepositAsync(ulong userId, long amount)
{ {
if (amount <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
if (!await _cur.RemoveAsync(userId, amount, new("bank", "deposit"))) if (!await _cur.RemoveAsync(userId, amount, new("bank", "deposit")))
return false; return false;
@@ -86,9 +83,8 @@ public sealed class BankService : IBankService, INService
public async Task<bool> WithdrawAsync(ulong userId, long amount) public async Task<bool> WithdrawAsync(ulong userId, long amount)
{ {
if (amount <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
await using var ctx = _db.GetDbContext(); await using var ctx = _db.GetDbContext();
var rows = await ctx.Set<BankUser>() var rows = await ctx.Set<BankUser>()
.ToLinqToDBTable() .ToLinqToDBTable()

View File

@@ -50,12 +50,12 @@ public partial class Gambling
bj.GameEnded += Bj_GameEnded; bj.GameEnded += Bj_GameEnded;
bj.Start(); bj.Start();
await Response().Confirm(strs.bj_created).SendAsync(); await Response().NoReply().Confirm(strs.bj_created(ctx.User.ToString())).SendAsync();
} }
else else
{ {
if (await bj.Join(ctx.User, amount)) if (await bj.Join(ctx.User, amount))
await Response().Confirm(strs.bj_joined).SendAsync(); await Response().NoReply().Confirm(strs.bj_joined(ctx.User.ToString())).SendAsync();
else else
{ {
Log.Information("{User} can't join a blackjack game as it's in {BlackjackState} state already", Log.Information("{User} can't join a blackjack game as it's in {BlackjackState} state already",

View File

@@ -49,8 +49,7 @@ public class User : Player
public User(IUser user, long bet) public User(IUser user, long bet)
{ {
if (bet <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(bet);
throw new ArgumentOutOfRangeException(nameof(bet));
Bet = bet; Bet = bet;
DiscordUser = user; DiscordUser = user;

View File

@@ -12,9 +12,9 @@ public partial class Gambling
public partial class Connect4Commands : GamblingSubmodule<GamblingService> public partial class Connect4Commands : GamblingSubmodule<GamblingService>
{ {
private static readonly string[] _numbers = private static readonly string[] _numbers =
{ [
":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:" ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:"
}; ];
private int RepostCounter private int RepostCounter
{ {

View File

@@ -16,7 +16,7 @@ public partial class Gambling
private static readonly Regex _fudgeRegex = new(@"^(?<n1>\d+)d(?:F|f)$", RegexOptions.Compiled); private static readonly Regex _fudgeRegex = new(@"^(?<n1>\d+)d(?:F|f)$", RegexOptions.Compiled);
private static readonly char[] _fateRolls = { '-', ' ', '+' }; private static readonly char[] _fateRolls = ['-', ' ', '+'];
private readonly IImageCache _images; private readonly IImageCache _images;
public DiceRollCommands(IImageCache images) public DiceRollCommands(IImageCache images)

View File

@@ -74,7 +74,7 @@ public partial class Gambling : GamblingModule<GamblingService>
var stats = await _gamblingTxTracker.GetAllAsync(); var stats = await _gamblingTxTracker.GetAllAsync();
var eb = _sender.CreateEmbed() var eb = _sender.CreateEmbed()
.WithOkColor(); .WithOkColor();
var str = "` Feature `` Bet ``Paid Out`` RoI `\n"; var str = "` Feature `` Bet ``Paid Out`` RoI `\n";
str += "――――――――――――――――――――\n"; str += "――――――――――――――――――――\n";
@@ -119,15 +119,15 @@ public partial class Gambling : GamblingModule<GamblingService>
// [21:03] Bob Page: Kinda remids me of US economy // [21:03] Bob Page: Kinda remids me of US economy
var embed = _sender.CreateEmbed() var embed = _sender.CreateEmbed()
.WithTitle(GetText(strs.economy_state)) .WithTitle(GetText(strs.economy_state))
.AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot)) .AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot))
.AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%") .AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%")
.AddField(GetText(strs.currency_planted), N(ec.Planted)) .AddField(GetText(strs.currency_planted), N(ec.Planted))
.AddField(GetText(strs.owned_waifus_total), N(ec.Waifus)) .AddField(GetText(strs.owned_waifus_total), N(ec.Waifus))
.AddField(GetText(strs.bot_currency), N(ec.Bot)) .AddField(GetText(strs.bot_currency), N(ec.Bot))
.AddField(GetText(strs.bank_accounts), N(ec.Bank)) .AddField(GetText(strs.bank_accounts), N(ec.Bank))
.AddField(GetText(strs.total), N(ec.Cash + ec.Planted + ec.Waifus + ec.Bank)) .AddField(GetText(strs.total), N(ec.Cash + ec.Planted + ec.Waifus + ec.Bank))
.WithOkColor(); .WithOkColor();
// ec.Cash already contains ec.Bot as it's the total of all values in the CurrencyAmount column of the DiscordUser table // ec.Cash already contains ec.Bot as it's the total of all values in the CurrencyAmount column of the DiscordUser table
await Response().Embed(embed).SendAsync(); await Response().Embed(embed).SendAsync();
@@ -154,18 +154,15 @@ public partial class Gambling : GamblingModule<GamblingService>
await smc.RespondConfirmAsync(_sender, GetText(strs.remind_timely(tt)), ephemeral: true); await smc.RespondConfirmAsync(_sender, GetText(strs.remind_timely(tt)), ephemeral: true);
} }
private NadekoInteraction CreateRemindMeInteraction(int period) private NadekoInteractionBase CreateRemindMeInteraction(int period)
{ => _inter
return _inter
.Create(ctx.User.Id, .Create(ctx.User.Id,
new SimpleInteraction<DateTime>( new ButtonBuilder(
new ButtonBuilder( label: "Remind me",
label: "Remind me", emote: Emoji.Parse("⏰"),
emote: Emoji.Parse("⏰"), customId: "timely:remind_me"),
customId: "timely:remind_me"), (smc) => RemindTimelyAction(smc, DateTime.UtcNow.Add(TimeSpan.FromHours(period)))
RemindTimelyAction, );
DateTime.UtcNow.Add(TimeSpan.FromHours(period))));
}
[Cmd] [Cmd]
public async Task Timely() public async Task Timely()
@@ -311,9 +308,9 @@ public partial class Gambling : GamblingModule<GamblingService>
} }
var embed = _sender.CreateEmbed() var embed = _sender.CreateEmbed()
.WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString() .WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString()
?? $"{userId}"))) ?? $"{userId}")))
.WithOkColor(); .WithOkColor();
var sb = new StringBuilder(); var sb = new StringBuilder();
foreach (var tr in trs) foreach (var tr in trs)
@@ -408,7 +405,7 @@ public partial class Gambling : GamblingModule<GamblingService>
await Response().Confirm(strs.has(Format.Code(userId.ToString()), cur)).SendAsync(); await Response().Confirm(strs.has(Format.Code(userId.ToString()), cur)).SendAsync();
} }
private async Task BankAction(SocketMessageComponent smc, object _) private async Task BankAction(SocketMessageComponent smc)
{ {
var balance = await _bank.GetBalanceAsync(ctx.User.Id); var balance = await _bank.GetBalanceAsync(ctx.User.Id);
@@ -418,12 +415,12 @@ public partial class Gambling : GamblingModule<GamblingService>
.Pipe(text => smc.RespondConfirmAsync(_sender, text, ephemeral: true)); .Pipe(text => smc.RespondConfirmAsync(_sender, text, ephemeral: true));
} }
private NadekoInteraction CreateCashInteraction() private NadekoInteractionBase CreateCashInteraction()
=> _inter.Create<object>(ctx.User.Id, => _inter.Create(ctx.User.Id,
new(new( new ButtonBuilder(
customId: "cash:bank_show_balance", customId: "cash:bank_show_balance",
emote: new Emoji("🏦")), emote: new Emoji("🏦")),
BankAction)); BankAction);
[Cmd] [Cmd]
[Priority(1)] [Priority(1)]
@@ -466,7 +463,7 @@ public partial class Gambling : GamblingModule<GamblingService>
return; return;
} }
await Response().Confirm(strs.gifted(N(amount), Format.Bold(receiver.ToString()))).SendAsync(); await Response().Confirm(strs.gifted(N(amount), Format.Bold(receiver.ToString()), ctx.User)).SendAsync();
} }
[Cmd] [Cmd]
@@ -508,7 +505,7 @@ public partial class Gambling : GamblingModule<GamblingService>
} }
await _cs.AddAsync(usr.Id, amount, new("award", ctx.User.ToString()!, msg, ctx.User.Id)); await _cs.AddAsync(usr.Id, amount, new("award", ctx.User.ToString()!, msg, ctx.User.Id));
await Response().Confirm(strs.awarded(N(amount), $"<@{usrId}>")).SendAsync(); await Response().Confirm(strs.awarded(N(amount), $"<@{usrId}>", ctx.User)).SendAsync();
} }
[Cmd] [Cmd]
@@ -732,10 +729,10 @@ public partial class Gambling : GamblingModule<GamblingService>
} }
var eb = _sender.CreateEmbed() var eb = _sender.CreateEmbed()
.WithAuthor(ctx.User) .WithAuthor(ctx.User)
.WithDescription(Format.Bold(str)) .WithDescription(Format.Bold(str))
.AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture)) .AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture))
.WithOkColor(); .WithOkColor();
await Response().Embed(eb).SendAsync(); await Response().Embed(eb).SendAsync();
} }
@@ -766,7 +763,7 @@ public partial class Gambling : GamblingModule<GamblingService>
} }
async Task<IEnumerable<DiscordUser>> GetTopRichest(int curPage) async Task<IReadOnlyCollection<DiscordUser>> GetTopRichest(int curPage)
{ {
if (opts.Clean) if (opts.Clean)
{ {
@@ -776,7 +773,7 @@ public partial class Gambling : GamblingModule<GamblingService>
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
var cleanRichest = await uow.Set<DiscordUser>() var cleanRichest = await uow.Set<DiscordUser>()
.GetTopRichest(_client.CurrentUser.Id, 0, 10_000); .GetTopRichest(_client.CurrentUser.Id, 0, 1000);
var sg = (SocketGuild)ctx.Guild!; var sg = (SocketGuild)ctx.Guild!;
return cleanRichest.Where(x => sg.GetUser(x.UserId) is not null).ToList(); return cleanRichest.Where(x => sg.GetUser(x.UserId) is not null).ToList();
@@ -788,15 +785,20 @@ public partial class Gambling : GamblingModule<GamblingService>
} }
} }
var res = Response()
.Paginated();
await Response() await Response()
.Paginated() .Paginated()
.PageItems(GetTopRichest) .PageItems(GetTopRichest)
.TotalElements(900)
.PageSize(9) .PageSize(9)
.CurrentPage(page) .CurrentPage(page)
.Page((toSend, curPage) => .Page((toSend, curPage) =>
{ {
var embed = _sender.CreateEmbed().WithOkColor() var embed = _sender.CreateEmbed()
.WithTitle(CurrencySign + " " + GetText(strs.leaderboard)); .WithOkColor()
.WithTitle(CurrencySign + " " + GetText(strs.leaderboard));
if (!toSend.Any()) if (!toSend.Any())
{ {
@@ -919,11 +921,11 @@ public partial class Gambling : GamblingModule<GamblingService>
} }
var eb = _sender.CreateEmbed() var eb = _sender.CreateEmbed()
.WithOkColor() .WithOkColor()
.WithDescription(sb.ToString()) .WithDescription(sb.ToString())
.AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true) .AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true)
.AddField(GetText(strs.won), $"{(long)result.Won}", true) .AddField(GetText(strs.won), $"{(long)result.Won}", true)
.WithAuthor(ctx.User); .WithAuthor(ctx.User);
await Response().Embed(eb).SendAsync(); await Response().Embed(eb).SendAsync();

View File

@@ -131,8 +131,8 @@ public partial class BetRollConfig
public BetRollPair[] Pairs { get; set; } = Array.Empty<BetRollPair>(); public BetRollPair[] Pairs { get; set; } = Array.Empty<BetRollPair>();
public BetRollConfig() public BetRollConfig()
=> Pairs = new BetRollPair[] => Pairs =
{ [
new() new()
{ {
WhenAbove = 99, WhenAbove = 99,
@@ -148,7 +148,7 @@ public partial class BetRollConfig
WhenAbove = 66, WhenAbove = 66,
MultiplyBy = 2 MultiplyBy = 2
} }
}; ];
} }
[Cloneable] [Cloneable]
@@ -207,7 +207,7 @@ public partial class LuckyLadderSettings
public decimal[] Multipliers { get; set; } public decimal[] Multipliers { get; set; }
public LuckyLadderSettings() public LuckyLadderSettings()
=> Multipliers = new[] { 2.4M, 1.7M, 1.5M, 1.2M, 0.5M, 0.3M, 0.2M, 0.1M }; => Multipliers = [2.4M, 1.7M, 1.5M, 1.2M, 0.5M, 0.3M, 0.2M, 0.1M];
} }
[Cloneable] [Cloneable]
@@ -228,11 +228,11 @@ public sealed partial class WaifuConfig
List of items available for gifting. List of items available for gifting.
If negative is true, gift will instead reduce waifu value. If negative is true, gift will instead reduce waifu value.
""")] """)]
public List<WaifuItemModel> Items { get; set; } = new(); public List<WaifuItemModel> Items { get; set; } = [];
public WaifuConfig() public WaifuConfig()
=> Items = new() => Items =
{ [
new("🥔", 5, "Potato"), new("🥔", 5, "Potato"),
new("🍪", 10, "Cookie"), new("🍪", 10, "Cookie"),
new("🥖", 20, "Bread"), new("🥖", 20, "Bread"),
@@ -269,7 +269,7 @@ public sealed partial class WaifuConfig
new("🚁", 20000, "Helicopter"), new("🚁", 20000, "Helicopter"),
new("🚀", 30000, "Spaceship"), new("🚀", 30000, "Spaceship"),
new("🌕", 50000, "Moon") new("🌕", 50000, "Moon")
}; ];
public class WaifuDecayConfig public class WaifuDecayConfig
{ {

View File

@@ -24,6 +24,7 @@ public abstract class GamblingModule<TService> : NadekoModule<TService>
{ {
if (amount < 1) if (amount < 1)
return false; return false;
if (amount < Config.MinBet) if (amount < Config.MinBet)
{ {
await Response().Error(strs.min_bet_limit(Format.Bold(Config.MinBet.ToString()) + CurrencySign)).SendAsync(); await Response().Error(strs.min_bet_limit(Format.Bold(Config.MinBet.ToString()) + CurrencySign)).SendAsync();

View File

@@ -27,7 +27,7 @@ public partial class Gambling
if (picked > 0) if (picked > 0)
{ {
var msg = await Response().Confirm(strs.picked(N(picked))).SendAsync(); var msg = await Response().NoReply().Confirm(strs.picked(N(picked), ctx.User)).SendAsync();
msg.DeleteAfter(10); msg.DeleteAfter(10);
} }
@@ -92,7 +92,7 @@ public partial class Gambling
{ {
if (--page < 0) if (--page < 0)
return Task.CompletedTask; return Task.CompletedTask;
var enabledIn = _service.GetAllGeneratingChannels(); var enabledIn = _service.GetAllGeneratingChannels();
return Response() return Response()

View File

@@ -20,10 +20,8 @@ public class ShopService : IShopService, INService
public async Task<bool> ChangeEntryPriceAsync(ulong guildId, int index, int newPrice) public async Task<bool> ChangeEntryPriceAsync(ulong guildId, int index, int newPrice)
{ {
if (index < 0) ArgumentOutOfRangeException.ThrowIfNegative(index);
throw new ArgumentOutOfRangeException(nameof(index)); ArgumentOutOfRangeException.ThrowIfNegativeOrZero(newPrice);
if (newPrice <= 0)
throw new ArgumentOutOfRangeException(nameof(newPrice));
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
var entries = GetEntriesInternal(uow, guildId); var entries = GetEntriesInternal(uow, guildId);
@@ -38,8 +36,8 @@ public class ShopService : IShopService, INService
public async Task<bool> ChangeEntryNameAsync(ulong guildId, int index, string newName) public async Task<bool> ChangeEntryNameAsync(ulong guildId, int index, string newName)
{ {
if (index < 0) ArgumentOutOfRangeException.ThrowIfNegative(index);
throw new ArgumentOutOfRangeException(nameof(index));
if (string.IsNullOrWhiteSpace(newName)) if (string.IsNullOrWhiteSpace(newName))
throw new ArgumentNullException(nameof(newName)); throw new ArgumentNullException(nameof(newName));
@@ -56,10 +54,8 @@ public class ShopService : IShopService, INService
public async Task<bool> SwapEntriesAsync(ulong guildId, int index1, int index2) public async Task<bool> SwapEntriesAsync(ulong guildId, int index1, int index2)
{ {
if (index1 < 0) ArgumentOutOfRangeException.ThrowIfNegative(index1);
throw new ArgumentOutOfRangeException(nameof(index1)); ArgumentOutOfRangeException.ThrowIfNegative(index2);
if (index2 < 0)
throw new ArgumentOutOfRangeException(nameof(index2));
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
var entries = GetEntriesInternal(uow, guildId); var entries = GetEntriesInternal(uow, guildId);
@@ -76,10 +72,8 @@ public class ShopService : IShopService, INService
public async Task<bool> MoveEntryAsync(ulong guildId, int fromIndex, int toIndex) public async Task<bool> MoveEntryAsync(ulong guildId, int fromIndex, int toIndex)
{ {
if (fromIndex < 0) ArgumentOutOfRangeException.ThrowIfNegative(fromIndex);
throw new ArgumentOutOfRangeException(nameof(fromIndex)); ArgumentOutOfRangeException.ThrowIfNegative(toIndex);
if (toIndex < 0)
throw new ArgumentOutOfRangeException(nameof(toIndex));
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
var entries = GetEntriesInternal(uow, guildId); var entries = GetEntriesInternal(uow, guildId);

View File

@@ -76,9 +76,12 @@ public partial class Gambling
.WithOkColor(); .WithOkColor();
var bb = new ButtonBuilder(emote: Emoji.Parse("🔁"), customId: "slot:again", label: "Pull Again"); var bb = new ButtonBuilder(emote: Emoji.Parse("🔁"), customId: "slot:again", label: "Pull Again");
var si = new SimpleInteraction<long>(bb, (_, amount) => Slot(amount), amount); var inter = _inter.Create(ctx.User.Id, bb, smc =>
{
smc.DeferAsync();
return Slot(amount);
});
var inter = _inter.Create(ctx.User.Id, si);
var msg = await ctx.Channel.SendFileAsync(imgStream, var msg = await ctx.Channel.SendFileAsync(imgStream,
"result.png", "result.png",
embed: eb.Build(), embed: eb.Build(),

View File

@@ -27,10 +27,10 @@ public static class WaifuExtensions
public static IEnumerable<WaifuLbResult> GetTop(this DbSet<WaifuInfo> waifus, int count, int skip = 0) public static IEnumerable<WaifuLbResult> GetTop(this DbSet<WaifuInfo> waifus, int count, int skip = 0)
{ {
if (count < 0) ArgumentOutOfRangeException.ThrowIfNegative(count);
throw new ArgumentOutOfRangeException(nameof(count));
if (count == 0) if (count == 0)
return new List<WaifuLbResult>(); return [];
return waifus.Include(wi => wi.Waifu) return waifus.Include(wi => wi.Waifu)
.Include(wi => wi.Affinity) .Include(wi => wi.Affinity)

View File

@@ -14,5 +14,5 @@ public interface IGamblingService
Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount); Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount);
Task<FlipResult[]> FlipAsync(int count); Task<FlipResult[]> FlipAsync(int count);
Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick); Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick);
Task<OneOf<BetdrawResult, GamblingError>> BetDrawAsync(ulong userId, long amount, byte? guessValue, byte? guessColor); Task<OneOf<BetdrawResult, GamblingError>> BetDrawAsync(ulong userId, long amount, byte? maybeGuessValue, byte? maybeGuessColor);
} }

View File

@@ -20,9 +20,8 @@ public sealed class NewGamblingService : IGamblingService, INService
public async Task<OneOf<LuLaResult, GamblingError>> LulaAsync(ulong userId, long amount) public async Task<OneOf<LuLaResult, GamblingError>> LulaAsync(ulong userId, long amount)
{ {
if (amount < 0) ArgumentOutOfRangeException.ThrowIfNegative(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
if (amount > 0) if (amount > 0)
{ {
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("lula", "bet")); var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("lula", "bet"));
@@ -47,8 +46,7 @@ public sealed class NewGamblingService : IGamblingService, INService
public async Task<OneOf<BetrollResult, GamblingError>> BetRollAsync(ulong userId, long amount) public async Task<OneOf<BetrollResult, GamblingError>> BetRollAsync(ulong userId, long amount)
{ {
if (amount < 0) ArgumentOutOfRangeException.ThrowIfNegative(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
if (amount > 0) if (amount > 0)
{ {
@@ -77,11 +75,9 @@ public sealed class NewGamblingService : IGamblingService, INService
public async Task<OneOf<BetflipResult, GamblingError>> BetFlipAsync(ulong userId, long amount, byte guess) public async Task<OneOf<BetflipResult, GamblingError>> BetFlipAsync(ulong userId, long amount, byte guess)
{ {
if (amount < 0) ArgumentOutOfRangeException.ThrowIfNegative(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
if (guess > 1) ArgumentOutOfRangeException.ThrowIfGreaterThan(guess, 1);
throw new ArgumentOutOfRangeException(nameof(guess));
if (amount > 0) if (amount > 0)
{ {
@@ -105,19 +101,18 @@ public sealed class NewGamblingService : IGamblingService, INService
return result; return result;
} }
public async Task<OneOf<BetdrawResult, GamblingError>> BetDrawAsync(ulong userId, long amount, byte? guessValue, byte? guessColor) public async Task<OneOf<BetdrawResult, GamblingError>> BetDrawAsync(ulong userId, long amount, byte? maybeGuessValue, byte? maybeGuessColor)
{ {
if (amount < 0) ArgumentOutOfRangeException.ThrowIfNegative(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
if (guessColor is null && guessValue is null) if (maybeGuessColor is null && maybeGuessValue is null)
throw new ArgumentNullException(); throw new ArgumentNullException();
if (guessColor > 1) if (maybeGuessColor > 1)
throw new ArgumentOutOfRangeException(nameof(guessColor)); throw new ArgumentOutOfRangeException(nameof(maybeGuessColor));
if (guessValue > 1) if (maybeGuessValue > 1)
throw new ArgumentOutOfRangeException(nameof(guessValue)); throw new ArgumentOutOfRangeException(nameof(maybeGuessValue));
if (amount > 0) if (amount > 0)
{ {
@@ -130,7 +125,7 @@ public sealed class NewGamblingService : IGamblingService, INService
} }
var game = new BetdrawGame(); var game = new BetdrawGame();
var result = game.Draw((BetdrawValueGuess?)guessValue, (BetdrawColorGuess?)guessColor, amount); var result = game.Draw((BetdrawValueGuess?)maybeGuessValue, (BetdrawColorGuess?)maybeGuessColor, amount);
var won = (long)result.Won; var won = (long)result.Won;
if (won > 0) if (won > 0)
@@ -143,9 +138,8 @@ public sealed class NewGamblingService : IGamblingService, INService
public async Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount) public async Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount)
{ {
if (amount < 0) ArgumentOutOfRangeException.ThrowIfNegative(amount);
throw new ArgumentOutOfRangeException(nameof(amount));
if (amount > 0) if (amount > 0)
{ {
var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("slot", "bet")); var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("slot", "bet"));
@@ -170,9 +164,8 @@ public sealed class NewGamblingService : IGamblingService, INService
public Task<FlipResult[]> FlipAsync(int count) public Task<FlipResult[]> FlipAsync(int count)
{ {
if (count < 1) ArgumentOutOfRangeException.ThrowIfLessThan(count, 1);
throw new ArgumentOutOfRangeException(nameof(count));
var game = new BetflipGame(0); var game = new BetflipGame(0);
var results = new FlipResult[count]; var results = new FlipResult[count];
@@ -242,11 +235,8 @@ public sealed class NewGamblingService : IGamblingService, INService
public async Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick) public async Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick)
{ {
if (amount < 0) ArgumentOutOfRangeException.ThrowIfNegative(amount);
throw new ArgumentOutOfRangeException(nameof(amount)); ArgumentOutOfRangeException.ThrowIfGreaterThan(pick, 2);
if (pick > 2)
throw new ArgumentOutOfRangeException(nameof(pick));
if (amount > 0) if (amount > 0)
{ {

View File

@@ -42,7 +42,7 @@ public sealed class AcrophobiaGame : IDisposable
private readonly SemaphoreSlim _locker = new(1, 1); private readonly SemaphoreSlim _locker = new(1, 1);
private readonly NadekoRandom _rng; private readonly NadekoRandom _rng;
private readonly HashSet<ulong> _usersWhoVoted = new(); private readonly HashSet<ulong> _usersWhoVoted = [];
public AcrophobiaGame(Options options) public AcrophobiaGame(Options options)
{ {

View File

@@ -67,7 +67,7 @@ public class ChatterBotService : IExecOnMessage
if (!string.IsNullOrWhiteSpace(_creds.CleverbotApiKey)) if (!string.IsNullOrWhiteSpace(_creds.CleverbotApiKey))
return new OfficialCleverbotSession(_creds.CleverbotApiKey, _httpFactory); return new OfficialCleverbotSession(_creds.CleverbotApiKey, _httpFactory);
Log.Information("Cleverbot will not work as the api key is missing."); Log.Information("Cleverbot will not work as the api key is missing");
return null; return null;
case ChatBotImplementation.Gpt3: case ChatBotImplementation.Gpt3:
if (!string.IsNullOrWhiteSpace(_creds.Gpt3ApiKey)) if (!string.IsNullOrWhiteSpace(_creds.Gpt3ApiKey))
@@ -80,7 +80,7 @@ public class ChatterBotService : IExecOnMessage
_client.CurrentUser.Username, _client.CurrentUser.Username,
_httpFactory); _httpFactory);
Log.Information("Gpt3 will not work as the api key is missing."); Log.Information("Gpt3 will not work as the api key is missing");
return null; return null;
default: default:
return null; return null;
@@ -128,7 +128,7 @@ public class ChatterBotService : IExecOnMessage
var res = await _perms.CheckPermsAsync(sg, var res = await _perms.CheckPermsAsync(sg,
usrMsg.Channel, usrMsg.Channel,
usrMsg.Author, usrMsg.Author,
"games", CleverBotResponseStr.CLEVERBOT_RESPONSE,
CleverBotResponseStr.CLEVERBOT_RESPONSE); CleverBotResponseStr.CLEVERBOT_RESPONSE);
if (!res.IsAllowed) if (!res.IsAllowed)

View File

@@ -24,8 +24,8 @@ public sealed partial class GamesConfig : ICloneable<GamesConfig>
}; };
[Comment("List of responses for the .8ball command. A random one will be selected every time")] [Comment("List of responses for the .8ball command. A random one will be selected every time")]
public List<string> EightBallResponses { get; set; } = new() public List<string> EightBallResponses { get; set; } =
{ [
"Most definitely yes.", "Most definitely yes.",
"For sure.", "For sure.",
"Totally!", "Totally!",
@@ -49,52 +49,59 @@ public sealed partial class GamesConfig : ICloneable<GamesConfig>
"Don't even think about it.", "Don't even think about it.",
"Definitely no.", "Definitely no.",
"NO - It may cause disease contraction!" "NO - It may cause disease contraction!"
}; ];
[Comment("List of animals which will be used for the animal race game (.race)")] [Comment("List of animals which will be used for the animal race game (.race)")]
public List<RaceAnimal> RaceAnimals { get; set; } = new() public List<RaceAnimal> RaceAnimals { get; set; } =
{ [
new() new()
{ {
Icon = "🐼", Icon = "🐼",
Name = "Panda" Name = "Panda"
}, },
new() new()
{ {
Icon = "🐻", Icon = "🐻",
Name = "Bear" Name = "Bear"
}, },
new() new()
{ {
Icon = "🐧", Icon = "🐧",
Name = "Pengu" Name = "Pengu"
}, },
new() new()
{ {
Icon = "🐨", Icon = "🐨",
Name = "Koala" Name = "Koala"
}, },
new() new()
{ {
Icon = "🐬", Icon = "🐬",
Name = "Dolphin" Name = "Dolphin"
}, },
new() new()
{ {
Icon = "🐞", Icon = "🐞",
Name = "Ladybird" Name = "Ladybird"
}, },
new() new()
{ {
Icon = "🦀", Icon = "🦀",
Name = "Crab" Name = "Crab"
}, },
new() new()
{ {
Icon = "🦄", Icon = "🦄",
Name = "Unicorn" Name = "Unicorn"
} }
}; ];
[Comment(@"Which chatbot API should bot use. [Comment(@"Which chatbot API should bot use.
'cleverbot' - bot will use Cleverbot API. 'cleverbot' - bot will use Cleverbot API.

View File

@@ -33,8 +33,8 @@ public sealed class NunchiGame : IDisposable
private readonly SemaphoreSlim _locker = new(1, 1); private readonly SemaphoreSlim _locker = new(1, 1);
private HashSet<(ulong Id, string Name)> participants = new(); private HashSet<(ulong Id, string Name)> participants = [];
private readonly HashSet<(ulong Id, string Name)> _passed = new(); private readonly HashSet<(ulong Id, string Name)> _passed = [];
private Timer killTimer; private Timer killTimer;
public NunchiGame(ulong creatorId, string creatorName) public NunchiGame(ulong creatorId, string creatorName)

View File

@@ -17,9 +17,9 @@ public class TicTacToe
private IGuildUser winner; private IGuildUser winner;
private readonly string[] _numbers = private readonly string[] _numbers =
{ [
":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:" ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:"
}; ];
private IUserMessage previousMessage; private IUserMessage previousMessage;
private Timer timeoutTimer; private Timer timeoutTimer;
@@ -42,7 +42,7 @@ public class TicTacToe
_options = options; _options = options;
_sender = sender; _sender = sender;
_users = new[] { firstUser, null }; _users = [firstUser, null];
_state = new int?[,] { { null, null, null }, { null, null, null }, { null, null, null } }; _state = new int?[,] { { null, null, null }, { null, null, null }, { null, null, null } };
phase = Phase.Starting; phase = Phase.Starting;

View File

@@ -37,7 +37,7 @@ public partial class Games
game = new(Strings, _client, channel, (IGuildUser)ctx.User, options, _sender); game = new(Strings, _client, channel, (IGuildUser)ctx.User, options, _sender);
_service.TicTacToeGames.Add(channel.Id, game); _service.TicTacToeGames.Add(channel.Id, game);
await Response().Confirm(strs.ttt_created).SendAsync(); await Response().Confirm(strs.ttt_created(ctx.User)).SendAsync();
game.OnEnded += _ => game.OnEnded += _ =>
{ {

View File

@@ -9,13 +9,13 @@ public class TriviaQuestion
public const int MAX_STRING_LENGTH = 22; public const int MAX_STRING_LENGTH = 22;
//represents the min size to judge levDistance with //represents the min size to judge levDistance with
private static readonly HashSet<Tuple<int, int>> _strictness = new() private static readonly HashSet<Tuple<int, int>> _strictness =
{ [
new(9, 0), new(9, 0),
new(14, 1), new(14, 1),
new(19, 2), new(19, 2),
new(22, 3) new(22, 3)
}; ];
public string Category public string Category
=> _qModel.Category; => _qModel.Category;

View File

@@ -1,16 +1,13 @@
#nullable disable #nullable disable
using Amazon.S3;
using NadekoBot.Modules.Help.Common; using NadekoBot.Modules.Help.Common;
using NadekoBot.Modules.Help.Services; using NadekoBot.Modules.Help.Services;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Text; using System.Text;
using System.Text.Json;
using Nadeko.Common.Medusa; using Nadeko.Common.Medusa;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace NadekoBot.Modules.Help; namespace NadekoBot.Modules.Help;
public sealed class Help : NadekoModule<HelpService> public sealed partial class Help : NadekoModule<HelpService>
{ {
public const string PATREON_URL = "https://patreon.com/nadekobot"; public const string PATREON_URL = "https://patreon.com/nadekobot";
public const string PAYPAL_URL = "https://paypal.me/Kwoth"; public const string PAYPAL_URL = "https://paypal.me/Kwoth";
@@ -72,7 +69,7 @@ public sealed class Help : NadekoModule<HelpService>
return; return;
var topLevelModules = new List<ModuleInfo>(); var topLevelModules = new List<ModuleInfo>();
foreach (var m in _cmds.Modules.GroupBy(x => x.GetTopLevelModule()).Select(x => x.Key)) foreach (var m in _cmds.Modules.GroupBy(x => x.GetTopLevelModule()).OrderBy(x => x.Key.Name).Select(x => x.Key))
{ {
var result = await _perms.CheckPermsAsync(ctx.Guild, var result = await _perms.CheckPermsAsync(ctx.Guild,
ctx.Channel, ctx.Channel,
@@ -80,14 +77,40 @@ public sealed class Help : NadekoModule<HelpService>
m.Name, m.Name,
null); null);
#if GLOBAL_NADEKO
if (m.Preconditions.Any(x => x is NoPublicBotAttribute))
continue;
#endif
if (result.IsAllowed) if (result.IsAllowed)
topLevelModules.Add(m); topLevelModules.Add(m);
} }
var menu = new SelectMenuBuilder()
.WithPlaceholder("Select a module to see its commands")
.WithCustomId("cmds:modules_select");
foreach (var m in topLevelModules)
menu.AddOption(m.Name, m.Name, GetModuleEmoji(m.Name));
var inter = _inter.Create(ctx.User.Id,
menu,
async (smc) =>
{
await smc.DeferAsync();
var val = smc.Data.Values.FirstOrDefault();
if (val is null)
return;
await Commands(val);
});
await Response() await Response()
.Paginated() .Paginated()
.Items(topLevelModules) .Items(topLevelModules)
.PageSize(12)
.CurrentPage(page) .CurrentPage(page)
.Interaction(inter)
.AddFooter(false) .AddFooter(false)
.Page((items, _) => .Page((items, _) =>
{ {
@@ -99,13 +122,13 @@ public sealed class Help : NadekoModule<HelpService>
return embed; return embed;
} }
items.OrderBy(module => module.Name) items
.ToList() .ToList()
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}", .ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
GetModuleDescription(module.Name) GetModuleDescription(module.Name)
+ "\n" + "\n"
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))), + Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
true)); true));
return embed; return embed;
}) })
@@ -218,10 +241,28 @@ public sealed class Help : NadekoModule<HelpService>
// order by name // order by name
var allowed = new List<CommandInfo>(); var allowed = new List<CommandInfo>();
foreach (var cmd in _cmds.Commands var mdls = _cmds.Commands
.Where(c => c.Module.GetTopLevelModule() .Where(c => c.Module.GetTopLevelModule()
.Name .Name
.StartsWith(module, StringComparison.InvariantCultureIgnoreCase))) .StartsWith(module, StringComparison.InvariantCultureIgnoreCase))
.ToArray();
if (mdls.Length == 0)
{
var group = _cmds.Modules
.Where(x => x.Parent is not null)
.FirstOrDefault(x => string.Equals(x.Name.Replace("Commands", ""),
module,
StringComparison.InvariantCultureIgnoreCase));
if (group is not null)
{
await Group(group);
return;
}
}
foreach (var cmd in mdls)
{ {
var result = await _perms.CheckPermsAsync(ctx.Guild, var result = await _perms.CheckPermsAsync(ctx.Guild,
ctx.Channel, ctx.Channel,
@@ -233,6 +274,7 @@ public sealed class Help : NadekoModule<HelpService>
allowed.Add(cmd); allowed.Add(cmd);
} }
var cmds = allowed.OrderBy(c => c.Aliases[0]) var cmds = allowed.OrderBy(c => c.Aliases[0])
.DistinctBy(x => x.Aliases[0]) .DistinctBy(x => x.Aliases[0])
.ToList(); .ToList();
@@ -243,13 +285,16 @@ public sealed class Help : NadekoModule<HelpService>
var succ = new HashSet<CommandInfo>(); var succ = new HashSet<CommandInfo>();
if (opts.View != CommandsOptions.ViewType.All) if (opts.View != CommandsOptions.ViewType.All)
{ {
succ = new((await cmds.Select(async x => succ =
{ [
var pre = await x.CheckPreconditionsAsync(Context, _services); ..(await cmds.Select(async x =>
return (Cmd: x, Succ: pre.IsSuccess); {
}) var pre = await x.CheckPreconditionsAsync(Context, _services);
.WhenAll()).Where(x => x.Succ) return (Cmd: x, Succ: pre.IsSuccess);
.Select(x => x.Cmd)); })
.WhenAll()).Where(x => x.Succ)
.Select(x => x.Cmd)
];
if (opts.View == CommandsOptions.ViewType.Hide) if (opts.View == CommandsOptions.ViewType.Hide)
// if hidden is specified, completely remove these commands from the list // if hidden is specified, completely remove these commands from the list
@@ -269,55 +314,97 @@ public sealed class Help : NadekoModule<HelpService>
return; return;
} }
var cnt = 0; var sb = new SelectMenuBuilder()
var groups = cmdsWithGroup.GroupBy(_ => cnt++ / 48).ToArray(); .WithCustomId("cmds:submodule_select")
.WithPlaceholder("Select a submodule to see detailed commands");
var groups = cmdsWithGroup.ToArray();
var embed = _sender.CreateEmbed().WithOkColor(); var embed = _sender.CreateEmbed().WithOkColor();
foreach (var g in groups) foreach (var g in groups)
{ {
var last = g.Count(); sb.AddOption(g.Key, g.Key);
for (var i = 0; i < last; i++) var transformed = g
{ .Select(x =>
var transformed = g.ElementAt(i) {
.Select(x => //if cross is specified, and the command doesn't satisfy the requirements, cross it out
{ if (opts.View == CommandsOptions.ViewType.Cross)
//if cross is specified, and the command doesn't satisfy the requirements, cross it out {
if (opts.View == CommandsOptions.ViewType.Cross) return $"{(succ.Contains(x) ? "" : "")} {prefix + x.Aliases[0]}";
{ }
return $"{(succ.Contains(x) ? "" : "")} {prefix + x.Aliases[0]}";
}
if (x.Aliases.Count == 1)
return prefix + x.Aliases[0];
return prefix + x.Aliases[0] + " | " + prefix + x.Aliases[1]; if (x.Aliases.Count == 1)
}); return prefix + x.Aliases[0];
embed.AddField(g.ElementAt(i).Key, "" + string.Join("\n", transformed) + "", true); return prefix + x.Aliases[0] + " | " + prefix + x.Aliases[1];
} });
embed.AddField(g.Key, "" + string.Join("\n", transformed) + "", true);
} }
embed.WithFooter(GetText(strs.commands_instr(prefix))); embed.WithFooter(GetText(strs.commands_instr(prefix)));
await Response().Embed(embed).SendAsync();
var inter = _inter.Create(ctx.User.Id,
sb,
async (smc) =>
{
var groupName = smc.Data.Values.FirstOrDefault();
var mdl = _cmds.Modules.FirstOrDefault(x
=> string.Equals(x.Name.Replace("Commands", ""), groupName, StringComparison.InvariantCultureIgnoreCase));
await smc.DeferAsync();
await Group(mdl);
}
);
await Response().Embed(embed).Interaction(inter).SendAsync();
} }
private async Task Group(ModuleInfo group) private async Task Group(ModuleInfo group)
{ {
var eb = _sender.CreateEmbed() var menu = new SelectMenuBuilder()
.WithTitle(GetText(strs.cmd_group_commands(group.Name))) .WithCustomId("cmds:group_select")
.WithOkColor(); .WithPlaceholder("Select a command to see its details");
foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0])) foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0]))
{ {
string cmdName; menu.AddOption(prefix + cmd.Aliases[0], cmd.Aliases[0]);
if (cmd.Aliases.Count > 1)
cmdName = Format.Code(prefix +cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
else
cmdName = Format.Code(prefix + cmd.Aliases.First());
eb.AddField(cmdName, cmd.RealSummary(_strings, _medusae, Culture, prefix));
} }
await Response().Embed(eb).SendAsync(); var inter = _inter.Create(ctx.User.Id,
menu,
async (smc) =>
{
await smc.DeferAsync();
await H(smc.Data.Values.FirstOrDefault());
});
await Response()
.Paginated()
.Items(group.Commands.DistinctBy(x => x.Aliases[0]).ToArray())
.PageSize(25)
.Interaction(inter)
.Page((items, _) =>
{
var eb = _sender.CreateEmbed()
.WithTitle(GetText(strs.cmd_group_commands(group.Name)))
.WithOkColor();
foreach (var cmd in items)
{
string cmdName;
if (cmd.Aliases.Count > 1)
cmdName = Format.Code(prefix + cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
else
cmdName = Format.Code(prefix + cmd.Aliases.First());
eb.AddField(cmdName, cmd.RealSummary(_strings, _medusae, Culture, prefix));
}
return eb;
})
.SendAsync();
} }
[Cmd] [Cmd]
@@ -337,8 +424,9 @@ public sealed class Help : NadekoModule<HelpService>
var group = _cmds.Modules var group = _cmds.Modules
.SelectMany(x => x.Submodules) .SelectMany(x => x.Submodules)
.Where(x => !string.IsNullOrWhiteSpace(x.Group)) .FirstOrDefault(x => string.Equals(x.Group,
.FirstOrDefault(x => x.Group.Equals(fail, StringComparison.InvariantCultureIgnoreCase)); fail,
StringComparison.InvariantCultureIgnoreCase));
if (group is not null) if (group is not null)
{ {
@@ -354,17 +442,16 @@ public sealed class Help : NadekoModule<HelpService>
public async Task H([Leftover] CommandInfo com = null) public async Task H([Leftover] CommandInfo com = null)
{ {
var channel = ctx.Channel; var channel = ctx.Channel;
if (com is null) if (com is null)
{ {
var ch = channel is ITextChannel ? await ctx.User.CreateDMChannelAsync() : channel;
try try
{ {
var ch = channel is ITextChannel ? await ctx.User.CreateDMChannelAsync() : channel;
var data = await GetHelpString(); var data = await GetHelpString();
if (data == default) if (data == default)
return; return;
await Response().Text(data).SendAsync(); await Response().Channel(ch).Text(data).SendAsync();
try try
{ {
await ctx.OkAsync(); await ctx.OkAsync();
@@ -419,90 +506,8 @@ public sealed class Help : NadekoModule<HelpService>
.ToList()); .ToList());
var readableData = JsonConvert.SerializeObject(cmdData, Formatting.Indented); var readableData = JsonConvert.SerializeObject(cmdData, Formatting.Indented);
var uploadData = JsonConvert.SerializeObject(cmdData, Formatting.None);
// for example https://nyc.digitaloceanspaces.com (without your space name) // send the indented file to chat
var serviceUrl = Environment.GetEnvironmentVariable("do_spaces_address");
// generate spaces access key on https://cloud.digitalocean.com/account/api/tokens
// you will get 2 keys, first, shorter one is id, longer one is secret
var accessKey = Environment.GetEnvironmentVariable("do_access_key_id");
var secretAcccessKey = Environment.GetEnvironmentVariable("do_access_key_secret");
// if all env vars are set, upload the unindented file (to save space) there
if (!(serviceUrl is null || accessKey is null || secretAcccessKey is null))
{
var config = new AmazonS3Config
{
ServiceURL = serviceUrl
};
using var dlClient = new AmazonS3Client(accessKey, secretAcccessKey, config);
using (var client = new AmazonS3Client(accessKey, secretAcccessKey, config))
{
await client.PutObjectAsync(new()
{
BucketName = "nadeko-pictures",
ContentType = "application/json",
ContentBody = uploadData,
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
Key = $"cmds/{StatsService.BotVersion}.json",
CannedACL = S3CannedACL.PublicRead
});
}
var versionListString = "[]";
try
{
using var oldVersionObject = await dlClient.GetObjectAsync(new()
{
BucketName = "nadeko-pictures",
Key = "cmds/versions.json"
});
await using var ms = new MemoryStream();
await oldVersionObject.ResponseStream.CopyToAsync(ms);
versionListString = Encoding.UTF8.GetString(ms.ToArray());
}
catch (Exception)
{
Log.Information("No old version list found. Creating a new one");
}
var versionList = JsonSerializer.Deserialize<List<string>>(versionListString);
if (versionList is not null && !versionList.Contains(StatsService.BotVersion))
{
// save the file with new version added
// versionList.Add(StatsService.BotVersion);
versionListString = JsonSerializer.Serialize(versionList.Prepend(StatsService.BotVersion),
new JsonSerializerOptions
{
WriteIndented = true
});
// upload the updated version list
using var client = new AmazonS3Client(accessKey, secretAcccessKey, config);
await client.PutObjectAsync(new()
{
BucketName = "nadeko-pictures",
ContentType = "application/json",
ContentBody = versionListString,
// either use a path provided in the argument or the default one for public nadeko, other/cmds.json
Key = "cmds/versions.json",
CannedACL = S3CannedACL.PublicRead
});
}
else
{
Log.Warning(
"Version {Version} already exists in the version file. " + "Did you forget to increment it?",
StatsService.BotVersion);
}
}
// also send the file, but indented one, to chat
await using var rDataStream = new MemoryStream(Encoding.ASCII.GetBytes(readableData)); await using var rDataStream = new MemoryStream(Encoding.ASCII.GetBytes(readableData));
await ctx.Channel.SendFileAsync(rDataStream, "cmds.json", GetText(strs.commandlist_regen)); await ctx.Channel.SendFileAsync(rDataStream, "cmds.json", GetText(strs.commandlist_regen));
} }
@@ -515,7 +520,7 @@ public sealed class Help : NadekoModule<HelpService>
.SendAsync(); .SendAsync();
private Task SelfhostAction(SocketMessageComponent smc, object _) private Task SelfhostAction(SocketMessageComponent smc)
=> smc.RespondConfirmAsync(_sender, => smc.RespondConfirmAsync(_sender,
""" """
- In case you don't want or cannot Donate to NadekoBot project, but you - In case you don't want or cannot Donate to NadekoBot project, but you
@@ -533,11 +538,11 @@ public sealed class Help : NadekoModule<HelpService>
public async Task Donate() public async Task Donate()
{ {
var selfhostInter = _inter.Create(ctx.User.Id, var selfhostInter = _inter.Create(ctx.User.Id,
new SimpleInteraction<object>(new ButtonBuilder( new ButtonBuilder(
emote: new Emoji("🖥️"), emote: new Emoji("🖥️"),
customId: "donate:selfhosting", customId: "donate:selfhosting",
label: "Selfhosting"), label: "Selfhosting"),
SelfhostAction)); SelfhostAction);
var eb = _sender.CreateEmbed() var eb = _sender.CreateEmbed()
.WithOkColor() .WithOkColor()
@@ -566,17 +571,9 @@ public sealed class Help : NadekoModule<HelpService>
**Step 3** ⏰ Wait a short while (usually 1-3 minutes) ⏰ **Step 3** ⏰ Wait a short while (usually 1-3 minutes) ⏰
Nadeko will DM you the welcome instructions, and you may will receive your rewards! Nadeko will DM you the welcome instructions, and you will receive your rewards!
🎉 **Enjoy!** 🎉 🎉 **Enjoy!** 🎉
""") """);
.AddField("Troubleshooting",
"""
*In case you didn't receive the rewards within 5 minutes:*
`1.` Make sure your DMs are open to everyone. Maybe your pledge was processed successfully but the bot was unable to DM you. Use the `.patron` command to check your status.
`2.` Make sure you've connected the CORRECT Discord account. Quite often users log in to different Discord accounts in their browser. You may also try disconnecting and reconnecting your account.
`3.` Make sure your payment has been processed and not declined by Patreon.
`4.` If any of the previous steps don't help, you can join the nadeko support server <https://discord.nadeko.bot> and ask for help in the #help channel
""");
try try
{ {

View File

@@ -3,6 +3,7 @@
namespace NadekoBot.Modules; namespace NadekoBot.Modules;
[OwnerOnly] [OwnerOnly]
[NoPublicBot]
public partial class Medusa : NadekoModule<IMedusaLoaderService> public partial class Medusa : NadekoModule<IMedusaLoaderService>
{ {
private readonly IMedusaeRepositoryService _repo; private readonly IMedusaeRepositoryService _repo;

View File

@@ -6,17 +6,62 @@ public class MedusaeRepositoryService : IMedusaeRepositoryService, INService
{ {
// Simulate retrieving data from a database or API // Simulate retrieving data from a database or API
await Task.Delay(100); await Task.Delay(100);
return new List<ModuleItem> return
{ [
new ModuleItem { Name = "RSS Reader", Description = "Keep up to date with your favorite websites", Command = ".meinstall rss" }, new()
new ModuleItem { Name = "Password Manager", Description = "Safely store and manage all your passwords", Command = ".meinstall passwordmanager" }, {
new ModuleItem { Name = "Browser Extension", Description = "Enhance your browsing experience with useful tools", Command = ".meinstall browserextension" }, Name = "RSS Reader",
new ModuleItem { Name = "Video Downloader", Description = "Download videos from popular websites", Command = ".meinstall videodownloader" }, Description = "Keep up to date with your favorite websites",
new ModuleItem { Name = "Virtual Private Network", Description = "Securely browse the web and protect your privacy", Command = ".meinstall vpn" }, Command = ".meinstall rss"
new ModuleItem { Name = "Ad Blocker", Description = "Block annoying ads and improve page load times", Command = ".meinstall adblocker" }, },
new ModuleItem { Name = "Cloud Storage", Description = "Store and share your files online", Command = ".meinstall cloudstorage" }, new()
new ModuleItem { Name = "Social Media Manager", Description = "Manage all your social media accounts in one place", Command = ".meinstall socialmediamanager" }, {
new ModuleItem { Name = "Code Editor", Description = "Write and edit code online", Command = ".meinstall codeeditor" } Name = "Password Manager",
}; Description = "Safely store and manage all your passwords",
Command = ".meinstall passwordmanager"
},
new()
{
Name = "Browser Extension",
Description = "Enhance your browsing experience with useful tools",
Command = ".meinstall browserextension"
},
new()
{
Name = "Video Downloader",
Description = "Download videos from popular websites",
Command = ".meinstall videodownloader"
},
new()
{
Name = "Virtual Private Network",
Description = "Securely browse the web and protect your privacy",
Command = ".meinstall vpn"
},
new()
{
Name = "Ad Blocker",
Description = "Block annoying ads and improve page load times",
Command = ".meinstall adblocker"
},
new()
{
Name = "Cloud Storage",
Description = "Store and share your files online",
Command = ".meinstall cloudstorage"
},
new()
{
Name = "Social Media Manager",
Description = "Manage all your social media accounts in one place",
Command = ".meinstall socialmediamanager"
},
new()
{
Name = "Code Editor",
Description = "Write and edit code online",
Command = ".meinstall codeeditor"
}
];
} }
} }

View File

@@ -28,11 +28,10 @@ public sealed class AyuVoiceStateService : INService
_dnetApiClient = prop.GetValue(_client, null); _dnetApiClient = prop.GetValue(_client, null);
_sendVoiceStateUpdateMethodInfo = _dnetApiClient.GetType() _sendVoiceStateUpdateMethodInfo = _dnetApiClient.GetType()
.GetMethod("SendVoiceStateUpdateAsync", .GetMethod("SendVoiceStateUpdateAsync",
new[] [
{ typeof(ulong), typeof(ulong?), typeof(bool),
typeof(ulong), typeof(ulong?), typeof(bool),
typeof(bool), typeof(RequestOptions) typeof(bool), typeof(RequestOptions)
}); ]);
_client.LeftGuild += ClientOnLeftGuild; _client.LeftGuild += ClientOnLeftGuild;
} }
@@ -55,7 +54,7 @@ public sealed class AyuVoiceStateService : INService
bool isMuted = false) bool isMuted = false)
// return _voiceStateUpdate(guildId, channelId, isDeafened, isMuted); // return _voiceStateUpdate(guildId, channelId, isDeafened, isMuted);
=> (Task)_sendVoiceStateUpdateMethodInfo.Invoke(_dnetApiClient, => (Task)_sendVoiceStateUpdateMethodInfo.Invoke(_dnetApiClient,
new object[] { guildId, channelId, isMuted, isDeafened, null }); [guildId, channelId, isMuted, isDeafened, null]);
private Task SendLeaveVoiceChannelInternalAsync(ulong guildId) private Task SendLeaveVoiceChannelInternalAsync(ulong guildId)
=> InvokeSendVoiceStateUpdateAsync(guildId); => InvokeSendVoiceStateUpdateAsync(guildId);

View File

@@ -11,9 +11,9 @@ public sealed partial class YtLoader : INService
private static readonly byte[] _ytResultJsonEnd = Encoding.UTF8.GetBytes(";<"); private static readonly byte[] _ytResultJsonEnd = Encoding.UTF8.GetBytes(";<");
private static readonly string[] _durationFormats = private static readonly string[] _durationFormats =
{ [
@"m\:ss", @"mm\:ss", @"h\:mm\:ss", @"hh\:mm\:ss", @"hhh\:mm\:ss" @"m\:ss", @"mm\:ss", @"h\:mm\:ss", @"hh\:mm\:ss", @"hhh\:mm\:ss"
}; ];
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;

View File

@@ -201,12 +201,9 @@ public sealed partial class MusicQueue : IMusicQueue
public IQueuedTrackInfo? MoveTrack(int from, int to) public IQueuedTrackInfo? MoveTrack(int from, int to)
{ {
if (from < 0) ArgumentOutOfRangeException.ThrowIfNegative(from);
throw new ArgumentOutOfRangeException(nameof(from)); ArgumentOutOfRangeException.ThrowIfNegative(to);
if (to < 0) ArgumentOutOfRangeException.ThrowIfEqual(to, from);
throw new ArgumentOutOfRangeException(nameof(to));
if (to == from)
throw new ArgumentException($"{nameof(from)} and {nameof(to)} must be different");
lock (_locker) lock (_locker)
{ {
@@ -270,20 +267,8 @@ public sealed partial class MusicQueue : IMusicQueue
{ {
lock (_locker) lock (_locker)
{ {
var list = tracks.ToList(); var list = tracks.ToArray();
rng.Shuffle(list);
for (var i = 0; i < list.Count; i++)
{
var struck = rng.Next(i, list.Count);
(list[struck], list[i]) = (list[i], list[struck]);
// could preserving the index during shuffling be done better?
if (i == index)
index = struck;
else if (struck == index)
index = i;
}
tracks = new(list); tracks = new(list);
} }
} }

View File

@@ -7,9 +7,9 @@ namespace NadekoBot.Modules.Music;
public sealed class YtdlYoutubeResolver : IYoutubeResolver public sealed class YtdlYoutubeResolver : IYoutubeResolver
{ {
private static readonly string[] _durationFormats = private static readonly string[] _durationFormats =
{ [
"ss", "m\\:ss", "mm\\:ss", "h\\:mm\\:ss", "hh\\:mm\\:ss", "hhh\\:mm\\:ss" "ss", "m\\:ss", "mm\\:ss", "h\\:mm\\:ss", "hh\\:mm\\:ss", "hhh\\:mm\\:ss"
}; ];
private static readonly Regex _expiryRegex = new(@"(?:[\?\&]expire\=(?<timestamp>\d+))"); private static readonly Regex _expiryRegex = new(@"(?:[\?\&]expire\=(?<timestamp>\d+))");

View File

@@ -8,8 +8,7 @@ public static class MusicPlaylistExtensions
{ {
public static List<MusicPlaylist> GetPlaylistsOnPage(this DbSet<MusicPlaylist> playlists, int num) public static List<MusicPlaylist> GetPlaylistsOnPage(this DbSet<MusicPlaylist> playlists, int num)
{ {
if (num < 1) ArgumentOutOfRangeException.ThrowIfLessThan(num, 1);
throw new ArgumentOutOfRangeException(nameof(num));
return playlists.AsQueryable().Skip((num - 1) * 20).Take(20).Include(pl => pl.Songs).ToList(); return playlists.AsQueryable().Skip((num - 1) * 20).Take(20).Include(pl => pl.Songs).ToList();
} }

View File

@@ -1,149 +1,156 @@
namespace NadekoBot.Modules.Patronage; using NadekoBot.Modules.Patronage;
[OnlyPublicBot] namespace NadekoBot.Modules.Help;
public partial class Patronage : NadekoModule
public partial class Help
{ {
private readonly PatronageService _service; [OnlyPublicBot]
private readonly PatronageConfig _pConf; public partial class Patronage : NadekoModule
public Patronage(PatronageService service, PatronageConfig pConf)
{ {
_service = service; private readonly PatronageService _service;
_pConf = pConf; private readonly PatronageConfig _pConf;
}
[Cmd] public Patronage(PatronageService service, PatronageConfig pConf)
[Priority(2)]
public Task Patron()
=> InternalPatron(ctx.User);
[Cmd]
[Priority(0)]
[OwnerOnly]
public Task Patron(IUser user)
=> InternalPatron(user);
[Cmd]
[Priority(0)]
[OwnerOnly]
public async Task PatronMessage(PatronTier tierAndHigher, string message)
{
_ = ctx.Channel.TriggerTypingAsync();
var result = await _service.SendMessageToPatronsAsync(tierAndHigher, message);
await Response()
.Confirm(strs.patron_msg_sent(
Format.Code(tierAndHigher.ToString()),
Format.Bold(result.Success.ToString()),
Format.Bold(result.Failed.ToString())))
.SendAsync();
}
// [OwnerOnly]
// public async Task PatronGift(IUser user, int amount)
// {
// // i can't figure out a good way to gift more than one month at the moment.
//
// if (amount < 1)
// return;
//
// var patron = _service.GiftPatronAsync(user, amount);
//
// var eb = _sender.CreateEmbed();
//
// await Response().Embed(eb.WithDescription($"Added **{days}** days of Patron benefits to {user.Mention}!")
// .AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
// .AddField("Amount", $"**{patron.Amount / 100.0f:N1}$**", true)
// .AddField("Until", TimestampTag.FromDateTime(patron.ValidThru.AddDays(1)))).SendAsync();
//
//
// }
private async Task InternalPatron(IUser user)
{
if (!_pConf.Data.IsEnabled)
{ {
await Response().Error(strs.patron_not_enabled).SendAsync(); _service = service;
return; _pConf = pConf;
} }
var patron = await _service.GetPatronAsync(user.Id); [Cmd]
var quotaStats = await _service.GetUserQuotaStatistic(user.Id); [Priority(2)]
public Task Patron()
=> InternalPatron(ctx.User);
var eb = _sender.CreateEmbed() [Cmd]
.WithAuthor(user) [Priority(0)]
.WithTitle(GetText(strs.patron_info)) [OwnerOnly]
.WithOkColor(); public Task Patron(IUser user)
=> InternalPatron(user);
if (quotaStats.Commands.Count == 0 [Cmd]
&& quotaStats.Groups.Count == 0 [Priority(0)]
&& quotaStats.Modules.Count == 0) [OwnerOnly]
public async Task PatronMessage(PatronTier tierAndHigher, string message)
{ {
eb.WithDescription(GetText(strs.no_quota_found)); _ = ctx.Channel.TriggerTypingAsync();
var result = await _service.SendMessageToPatronsAsync(tierAndHigher, message);
await Response()
.Confirm(strs.patron_msg_sent(
Format.Code(tierAndHigher.ToString()),
Format.Bold(result.Success.ToString()),
Format.Bold(result.Failed.ToString())))
.SendAsync();
} }
else
// [OwnerOnly]
// public async Task PatronGift(IUser user, int amount)
// {
// // i can't figure out a good way to gift more than one month at the moment.
//
// if (amount < 1)
// return;
//
// var patron = _service.GiftPatronAsync(user, amount);
//
// var eb = _sender.CreateEmbed();
//
// await Response().Embed(eb.WithDescription($"Added **{days}** days of Patron benefits to {user.Mention}!")
// .AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
// .AddField("Amount", $"**{patron.Amount / 100.0f:N1}$**", true)
// .AddField("Until", TimestampTag.FromDateTime(patron.ValidThru.AddDays(1)))).SendAsync();
//
//
// }
private async Task InternalPatron(IUser user)
{ {
eb.AddField(GetText(strs.tier), Format.Bold(patron.Tier.ToFullName()), true) if (!_pConf.Data.IsEnabled)
.AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true);
if (patron.Tier != PatronTier.None)
eb.AddField(GetText(strs.expires), patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(), true);
eb.AddField(GetText(strs.quotas), "", false);
if (quotaStats.Commands.Count > 0)
{ {
var text = GetQuotaList(quotaStats.Commands); await Response().Error(strs.patron_not_enabled).SendAsync();
if (!string.IsNullOrWhiteSpace(text)) return;
eb.AddField(GetText(strs.commands), text, true);
} }
if (quotaStats.Groups.Count > 0) var patron = await _service.GetPatronAsync(user.Id);
var quotaStats = await _service.GetUserQuotaStatistic(user.Id);
var eb = _sender.CreateEmbed()
.WithAuthor(user)
.WithTitle(GetText(strs.patron_info))
.WithOkColor();
if (quotaStats.Commands.Count == 0
&& quotaStats.Groups.Count == 0
&& quotaStats.Modules.Count == 0)
{ {
var text = GetQuotaList(quotaStats.Groups); eb.WithDescription(GetText(strs.no_quota_found));
if (!string.IsNullOrWhiteSpace(text)) }
eb.AddField(GetText(strs.groups), text, true); else
{
eb.AddField(GetText(strs.tier), Format.Bold(patron.Tier.ToFullName()), true)
.AddField(GetText(strs.pledge), $"**{patron.Amount / 100.0f:N1}$**", true);
if (patron.Tier != PatronTier.None)
eb.AddField(GetText(strs.expires),
patron.ValidThru.AddDays(1).ToShortAndRelativeTimestampTag(),
true);
eb.AddField(GetText(strs.quotas), "", false);
if (quotaStats.Commands.Count > 0)
{
var text = GetQuotaList(quotaStats.Commands);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.commands), text, true);
}
if (quotaStats.Groups.Count > 0)
{
var text = GetQuotaList(quotaStats.Groups);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.groups), text, true);
}
if (quotaStats.Modules.Count > 0)
{
var text = GetQuotaList(quotaStats.Modules);
if (!string.IsNullOrWhiteSpace(text))
eb.AddField(GetText(strs.modules), text, true);
}
} }
if (quotaStats.Modules.Count > 0)
try
{ {
var text = GetQuotaList(quotaStats.Modules); await Response().User(ctx.User).Embed(eb).SendAsync();
if (!string.IsNullOrWhiteSpace(text)) _ = ctx.OkAsync();
eb.AddField(GetText(strs.modules), text, true); }
catch
{
await Response().Error(strs.cant_dm).SendAsync();
} }
} }
private string GetQuotaList(IReadOnlyDictionary<string, FeatureQuotaStats> featureQuotaStats)
{
var text = string.Empty;
foreach (var (key, q) in featureQuotaStats)
{
text += $"\n\t`{key}`\n";
if (q.Hourly != default)
text += $" {GetEmoji(q.Hourly)} {q.Hourly.Cur}/{q.Hourly.Max} per hour\n";
if (q.Daily != default)
text += $" {GetEmoji(q.Daily)} {q.Daily.Cur}/{q.Daily.Max} per day\n";
if (q.Monthly != default)
text += $" {GetEmoji(q.Monthly)} {q.Monthly.Cur}/{q.Monthly.Max} per month\n";
}
try return text;
{
await Response().User(ctx.User).Embed(eb).SendAsync();
_ = ctx.OkAsync();
}
catch
{
await Response().Error(strs.cant_dm).SendAsync();
} }
private string GetEmoji((uint Cur, uint Max) limit)
=> limit.Cur < limit.Max
? "✅"
: "⚠️";
} }
private string GetQuotaList(IReadOnlyDictionary<string, FeatureQuotaStats> featureQuotaStats)
{
var text = string.Empty;
foreach (var (key, q) in featureQuotaStats)
{
text += $"\n\t`{key}`\n";
if (q.Hourly != default)
text += $" {GetEmoji(q.Hourly)} {q.Hourly.Cur}/{q.Hourly.Max} per hour\n";
if (q.Daily != default)
text += $" {GetEmoji(q.Daily)} {q.Daily.Cur}/{q.Daily.Max} per day\n";
if (q.Monthly != default)
text += $" {GetEmoji(q.Monthly)} {q.Monthly.Cur}/{q.Monthly.Max} per month\n";
}
return text;
}
private string GetEmoji((uint Cur, uint Max) limit)
=> limit.Cur < limit.Max
? "✅"
: "⚠️";
} }

View File

@@ -111,7 +111,6 @@ public sealed class PatronageService
var lastDate = lastRun.ToDateOnly(); var lastDate = lastRun.ToDateOnly();
await using var ctx = _db.GetDbContext(); await using var ctx = _db.GetDbContext();
await using var tran = await ctx.Database.BeginTransactionAsync();
if ((lastDate.Day == 1 || (lastDate.Month != nowDate.Month)) && nowDate.Day > 1) if ((lastDate.Day == 1 || (lastDate.Month != nowDate.Month)) && nowDate.Day > 1)
{ {
@@ -141,7 +140,6 @@ public sealed class PatronageService
// assumes that the code above runs in less than an hour // assumes that the code above runs in less than an hour
await _cache.AddAsync(_quotaKey, now.ToBinary()); await _cache.AddAsync(_quotaKey, now.ToBinary());
await tran.CommitAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -171,7 +169,6 @@ public sealed class PatronageService
var lastChargeUtc = subscriber.LastCharge.Value.ToUniversalTime(); var lastChargeUtc = subscriber.LastCharge.Value.ToUniversalTime();
var dateInOneMonth = lastChargeUtc.Date.AddMonths(1); var dateInOneMonth = lastChargeUtc.Date.AddMonths(1);
// await using var tran = await ctx.Database.BeginTransactionAsync();
try try
{ {
var dbPatron = await ctx.GetTable<PatronUser>() var dbPatron = await ctx.GetTable<PatronUser>()

View File

@@ -16,8 +16,7 @@ public partial class Permissions
private async Task ListBlacklistInternal(string title, BlacklistType type, int page = 0) private async Task ListBlacklistInternal(string title, BlacklistType type, int page = 0)
{ {
if (page < 0) ArgumentOutOfRangeException.ThrowIfNegative(page);
throw new ArgumentOutOfRangeException(nameof(page));
var list = _service.GetBlacklist(); var list = _service.GetBlacklist();
var allItems = await list.Where(x => x.Type == type) var allItems = await list.Where(x => x.Type == type)

View File

@@ -112,9 +112,8 @@ public sealed class CmdCdService : IExecPreCommand, IReadyExecutor, INService
public void AddCooldown(ulong guildId, string name, int secs) public void AddCooldown(ulong guildId, string name, int secs)
{ {
if (secs <= 0) ArgumentOutOfRangeException.ThrowIfNegativeOrZero(secs);
throw new ArgumentOutOfRangeException(nameof(secs));
var sett = _settings.GetOrAdd(guildId, static _ => new()); var sett = _settings.GetOrAdd(guildId, static _ => new());
sett[name] = secs; sett[name] = secs;

View File

@@ -162,7 +162,7 @@ public partial class Searches
.AddField(GetText(strs.episodes), animeData.TotalEpisodes.ToString(), true) .AddField(GetText(strs.episodes), animeData.TotalEpisodes.ToString(), true)
.AddField(GetText(strs.status), animeData.AiringStatus, true) .AddField(GetText(strs.status), animeData.AiringStatus, true)
.AddField(GetText(strs.genres), .AddField(GetText(strs.genres),
string.Join(",\n", animeData.Genres.Any() ? animeData.Genres : new[] { "none" }), string.Join(",\n", animeData.Genres.Any() ? animeData.Genres : ["none"]),
true) true)
.WithFooter($"{GetText(strs.score)} {animeData.AverageScore} / 100"); .WithFooter($"{GetText(strs.score)} {animeData.AverageScore} / 100");
await Response().Embed(embed).SendAsync(); await Response().Embed(embed).SendAsync();
@@ -194,7 +194,7 @@ public partial class Searches
.AddField(GetText(strs.chapters), mangaData.TotalChapters.ToString(), true) .AddField(GetText(strs.chapters), mangaData.TotalChapters.ToString(), true)
.AddField(GetText(strs.status), mangaData.PublishingStatus, true) .AddField(GetText(strs.status), mangaData.PublishingStatus, true)
.AddField(GetText(strs.genres), .AddField(GetText(strs.genres),
string.Join(",\n", mangaData.Genres.Any() ? mangaData.Genres : new[] { "none" }), string.Join(",\n", mangaData.Genres.Any() ? mangaData.Genres : ["none"]),
true) true)
.WithFooter($"{GetText(strs.score)} {mangaData.AverageScore} / 100"); .WithFooter($"{GetText(strs.score)} {mangaData.AverageScore} / 100");

View File

@@ -1,13 +0,0 @@
#nullable disable
using System.Text.Json.Serialization;
namespace NadekoBot.Modules.Searches;
public class FinnHubSearchResponse
{
[JsonPropertyName("count")]
public int Count { get; set; }
[JsonPropertyName("result")]
public List<FinnHubSearchResult> Result { get; set; }
}

View File

@@ -1,19 +0,0 @@
#nullable disable
using System.Text.Json.Serialization;
namespace NadekoBot.Modules.Searches;
public class FinnHubSearchResult
{
[JsonPropertyName("description")]
public string Description { get; set; }
[JsonPropertyName("displaySymbol")]
public string DisplaySymbol { get; set; }
[JsonPropertyName("symbol")]
public string Symbol { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; }
}

View File

@@ -1,55 +0,0 @@
// using System.Net.Http.Json;
//
// namespace NadekoBot.Modules.Searches;
//
// public sealed class PolygonApiClient : IDisposable
// {
// private const string BASE_URL = "https://api.polygon.io/v3";
//
// private readonly HttpClient _httpClient;
// private readonly string _apiKey;
//
// public PolygonApiClient(HttpClient httpClient, string apiKey)
// {
// _httpClient = httpClient;
// _apiKey = apiKey;
// }
//
// public async Task<IReadOnlyCollection<PolygonTickerData>> TickersAsync(string? ticker = null, string? query = null)
// {
// if (string.IsNullOrWhiteSpace(query))
// query = null;
//
// if(query is not null)
// query = Uri.EscapeDataString(query);
//
// var requestString = $"{BASE_URL}/reference/tickers"
// + "?type=CS"
// + "&active=true"
// + "&order=asc"
// + "&limit=1000"
// + $"&apiKey={_apiKey}";
//
// if (!string.IsNullOrWhiteSpace(ticker))
// requestString += $"&ticker={ticker}";
//
// if (!string.IsNullOrWhiteSpace(query))
// requestString += $"&search={query}";
//
//
// var response = await _httpClient.GetFromJsonAsync<PolygonTickerResponse>(requestString);
//
// if (response is null)
// return Array.Empty<PolygonTickerData>();
//
// return response.Results;
// }
//
// // public async Task<PolygonTickerDetailsV3> TickerDetailsV3Async(string ticker)
// // {
// // return new();
// // }
//
// public void Dispose()
// => _httpClient.Dispose();
// }

Some files were not shown because too many files have changed in this diff Show More