Compare commits
No commits in common. "v5" and "5.1.6" have entirely different histories.
256 changed files with 84731 additions and 16522 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -20,8 +20,9 @@ src/EllieBot/credentials.json
|
||||||
src/EllieBot/old_credentials.json
|
src/EllieBot/old_credentials.json
|
||||||
src/EllieBot/credentials.json.bak
|
src/EllieBot/credentials.json.bak
|
||||||
src/EllieBot/data/EllieBot.db
|
src/EllieBot/data/EllieBot.db
|
||||||
ellie-menu.ps1
|
build.ps1
|
||||||
package.sh
|
build.sh
|
||||||
|
test.ps1
|
||||||
|
|
||||||
# Created by https://www.gitignore.io/api/visualstudio,visualstudiocode,windows,linux,macos
|
# Created by https://www.gitignore.io/api/visualstudio,visualstudiocode,windows,linux,macos
|
||||||
|
|
||||||
|
|
170
CHANGELOG.md
170
CHANGELOG.md
|
@ -2,199 +2,87 @@
|
||||||
|
|
||||||
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except date format. a-c-f-r-o
|
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except date format. a-c-f-r-o
|
||||||
|
|
||||||
## [5.1.14] - 03.10.2024
|
|
||||||
|
|
||||||
## Changed
|
|
||||||
|
|
||||||
- Improved `.xplb -c`, it will now correctly only show users who are still in the server with no count limit
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
|
|
||||||
- Fixed marmalade load error on startup
|
|
||||||
|
|
||||||
## [5.1.13] - 03.10.2024
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Grpc api server will no longer start unless enabled in creds
|
|
||||||
- Seq comment in creds fixed
|
|
||||||
|
|
||||||
## [5.1.12] - 03.10.2024
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Added support for `seq` for logging. If you fill in seq url and apiKey in creds.yml, bot will sends logs to it
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed the Check for updates service not using the right URL and spitting an error in the console.
|
|
||||||
- Fixed another bug in `.greet` / `.bye` system, which caused it to show wrong message on a wrong server occasionally
|
|
||||||
|
|
||||||
## [5.1.11] - 03.10.2024
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Added `%user.displayname%` placeholder. It will show users nickname, if there is one, otherwise it will show the username.
|
|
||||||
- Nickname won't be shown in bye messages.
|
|
||||||
- Added initial version of grpc api. Beta
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed a bug which caused `.bye` and `.greet` messages to be randomly disabled
|
|
||||||
- Fixed `.lb -c` breaking sometimes, and fixed pagination
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Youtube now always uses `yt-dlp`. Dropped support for `youtube-dl`
|
|
||||||
- If you've previously renamed your yt-dlp file to youtube-dl, please rename it back.
|
|
||||||
- ytProvider in data/searches.yml now also controls where you're getting your song streams from.
|
|
||||||
- (Invidious support added for .q)
|
|
||||||
|
|
||||||
## [5.1.10] - 24.09.2024
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed claimed waifu decay in `games.yml`
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Added some logs for greet service in case there are unforeseen issues, for easier debugging
|
|
||||||
|
|
||||||
## [5.1.9] - 21.09.2024
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed `.greettest`, and other `.*test` commands if you didn't have them enabled.
|
|
||||||
- Fixed `.greetdmtest` sending messages twice.
|
|
||||||
- Fixed a serious bug which caused greet messages to be jumbled up, and wrong ones to be sent for the wrong events.
|
|
||||||
- There is no database issue, all greet messages are safe, the cache was caching any setting every 3 seconds with no regard for the type of the event
|
|
||||||
- This also caused `.greetdm` messages to not be sent if `.greet` is enabled
|
|
||||||
- This bug was introduced in 5.1.8. PLEASE UPDATE if you are on 5.1.8
|
|
||||||
- Selfhosters only: Fixed marmalade dependency loading
|
|
||||||
- Note: Make sure to not publish any other DLLs besides the ones you are sure you will need, as there can be version conflicts which didn't happen before.
|
|
||||||
|
|
||||||
## [5.1.8] - 20.09.2024
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Added `.leaveunkeptservers` which will make the bot leave all servers on all shards whose owners didn't run `.keep` command.
|
|
||||||
- This is a dangerous and irreversible command, don't use it. Meant for use on the public bot.
|
|
||||||
- `.adpl` now supports custom statuses (you no longer need to specify Playing, Watching, etc...)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- `.quote` commands cleaned up and improved
|
|
||||||
- All quote commands now start with `.q<whatever>` and follow the same naming pattern as Expression commands
|
|
||||||
- `.liqu` renamed to `.qli`
|
|
||||||
- `.quotesearch` / `.qse` is now paginated for easier searching
|
|
||||||
- `.whosplaying` is now paginated
|
|
||||||
- `.img` is now paginated
|
|
||||||
- `.setgame` renamed to`.setactivity` and now supports custom text activity. You don't have to specify playing, listening etc before the activity
|
|
||||||
- Clarified and added some embed / placeholder links to command help where needed
|
|
||||||
- dev: A lot of code cleanup and internal improvements
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed `.xpcurrew` breaking xp gain if user gains 0 xp from being in a voice channel
|
|
||||||
- Fixed a bug in `.gatari` command
|
|
||||||
- Fixed some waifu related strings
|
|
||||||
- Fixed `.quoteshow` and `.quoteid` commands
|
|
||||||
- Fixed some placeholders not working in `.greetdm`
|
|
||||||
- Fixed postgres support
|
|
||||||
- Fixed and clarified some command strings/parameter descriptions
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
- Removed mysql support as it didn't work for a while, and requires some special handling/maintenance
|
|
||||||
- Sqlite and Postgres support stays
|
|
||||||
|
|
||||||
## [5.1.7] - 09.08.2024
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fixed some command groups incorrectly showing up as modules
|
|
||||||
|
|
||||||
## [5.1.6] - 08.08.2024
|
## [5.1.6] - 08.08.2024
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `.serverlist` is now paginated
|
- `'serverlist` is now paginated
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `.listservers` renamed to `.serverlist`
|
- `'listservers` renamed to `'serverlist`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- `.afk` messages can no longer ping, and the response is moved to DMs to avoid abuse
|
- `'afk` messages can no longer ping, and the response is moved to DMs to avoid abuse
|
||||||
- Possible fix for `.remind` timestamp
|
- Possible fix for `'remind` timestamp
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Removed old bloat / semi broken / dumb commands
|
- Removed old bloat / semi broken / dumb commands
|
||||||
- `.memelist` / `.memegen` (too inconvenient to use)
|
- `'memelist` / `'memegen` (too inconvenient to use)
|
||||||
- `.activity` (useless owner-only command)
|
- `'activity` (useless owner-only command)
|
||||||
- `.rafflecur` (Just use raffle and then award manually instead)
|
- `'rafflecur` (Just use raffle and then award manually instead)
|
||||||
- `.rollduel` (we had this command?)
|
- `'rollduel` (we had this command?)
|
||||||
- You can no longer bet on `.connect4`
|
- You can no longer bet on `'connect4`
|
||||||
- `.economy` Removed.
|
- `'economy` Removed.
|
||||||
- Was buggy and didn.t really show the real state of the economy.
|
- Was buggy and didn't really show the real state of the economy.
|
||||||
- It might come back improved in the future
|
- It might come back improved in the future
|
||||||
- `.mal` Removed. Useless information / semi broken
|
- `'mal` Removed. Useless information / semi broken
|
||||||
|
|
||||||
## [5.1.5] - 01.08.2024
|
## [5.1.5] - 01.08.2024
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added: Added a `.afk <msg>?` command which sets an afk message which will trigger whenever someone pings you
|
- Added: Added a `'afk <msg>?` command which sets an afk message which will trigger whenever someone pings you
|
||||||
- Message will when you type a message in any channel that the bot sees, or after 8 hours, whichever comes first
|
- Message will when you type a message in any channel that the bot sees, or after 8 hours, whichever comes first
|
||||||
- The specified message will be prefixed with "The user is afk: "
|
- The specified message will be prefixed with "The user is afk: "
|
||||||
- The afk message will disappear 30 seconds after being triggered
|
- The afk message will disappear 30 seconds after being triggered
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Bot now shows a message when .prune fails due to already running error
|
- Bot now shows a message when 'prune fails due to already running error
|
||||||
- Updated some bet descriptions to include 'all' 'half' usage instructions
|
- Updated some bet descriptions to include 'all' 'half' usage instructions
|
||||||
- Updated some command strings
|
- Updated some command strings
|
||||||
- dev: Vastly simplified marmalade creation using dotnet templates, docs updated
|
- dev: Vastly simplified marmalade creation using dotnet templates, docs updated
|
||||||
- Slight refactor of .wiki, .time, .catfact, .wikia, .define, .bible and .quran commands, no significant change in functionality
|
- Slight refactor of 'wiki, 'time, 'catfact, 'wikia, 'define, 'bible and 'quran commands, no significant change in functionality
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- .coins will no longer show double minus sign for negative changes
|
- 'coins will no longer show double minus sign for negative changes
|
||||||
- You can once again disable cleverbot responses using fake 'cleverbot:response' module name in permission commands
|
- You can once again disable cleverbot responses using fake 'cleverbot:response' module name in permission commands
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- Removed .rip command
|
- Removed 'rip command
|
||||||
|
|
||||||
## [5.1.4] - 15.07.2024
|
## [5.1.4] - 15.07.2024
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added `.coins` command which lists top 10 cryptos ordered by marketcap
|
- Added `'coins` command which lists top 10 cryptos ordered by marketcap
|
||||||
- Added Clubs rank in the leaderboard to `.clubinfo`
|
- Added Clubs rank in the leaderboard to `'clubinfo`
|
||||||
- Bot owners can now check other people's bank balance (Not server owners, only bot owner, the person who is hosting the bot)
|
- Bot owners can now check other people's bank balance (Not server owners, only bot owner, the person who is hosting the bot)
|
||||||
- You can now send multiple waifu gifts at once to waifus. For example `.waifugift 3xRose @user` will give that user 3 roses
|
- You can now send multiple waifu gifts at once to waifus. For example `'waifugift 3xRose @user` will give that user 3 roses
|
||||||
- The format is `<NUMBER>x<ITEM>`, no spaces
|
- The format is `<NUMBER>x<ITEM>`, no spaces
|
||||||
- Added `.boosttest` command
|
- Added `'boosttest` command
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Updated command strings to clarify `.say` and `.send` usages
|
- Updated command strings to clarify `'say` and `'send` usages
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed `.waifugift` help string
|
- Fixed `'waifugift` help string
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- Removed selfhost button from `.donate` command, no idea why it was there in the first place
|
- Removed selfhost button from `'donate` command, no idea why it was there in the first place
|
||||||
|
|
||||||
## [5.1.3] - 08.07.2024
|
## [5.1.3] - 08.07.2024
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added `.quran` command, which will show the provided ayah in english and arabic, including recitation by Alafasy
|
- Added `'quran` command, which will show the provided ayah in english and arabic, including recitation by Alafasy
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -202,7 +90,7 @@ Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except da
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed `.stickeradd` it now properly supports 300x300 image uploads.
|
- Fixed `'stickeradd` it now properly supports 300x300 image uploads.
|
||||||
- Bot should now trim the invalid characters from chatterbot usernames to avoid openai errors
|
- Bot should now trim the invalid characters from chatterbot usernames to avoid openai errors
|
||||||
- Fixed prompt triggering chatterbot responses twice
|
- Fixed prompt triggering chatterbot responses twice
|
||||||
- Honeypot commands now actually works
|
- Honeypot commands now actually works
|
||||||
|
@ -217,15 +105,15 @@ Mostly based on [keepachangelog](https://keepachangelog.com/en/1.1.0/) except da
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added `.honeypot` command, which automatically softbans (ban and immediate unban) any user who posts in that channel.
|
- Added `'honeypot` command, which automatically softbans (ban and immediate unban) any user who posts in that channel.
|
||||||
- Useful to auto softban bots who spam every channel upon joining
|
- Useful to auto softban bots who spam every channel upon joining
|
||||||
- Users who run commands or expressions won't be softbanned.
|
- Users who run commands or expressions won't be softbanned.
|
||||||
- Users who have ban member permissions are also excluded.
|
- Users who have ban member permissions are also excluded.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed `.betdraw` not respecting maxbet
|
- Fixed `'betdraw` not respecting maxbet
|
||||||
- Fixed `.xpshop` pagination for real this time?
|
- Fixed `'xpshop` pagination for real this time?
|
||||||
|
|
||||||
## [5.1.0] - 28.06.2024
|
## [5.1.0] - 28.06.2024
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
CHANGELOG.md = CHANGELOG.md
|
CHANGELOG.md = CHANGELOG.md
|
||||||
Dockerfile = Dockerfile
|
Dockerfile = Dockerfile
|
||||||
ellie-menu.ps1 = ellie-menu.ps1
|
|
||||||
LICENSE = LICENSE
|
LICENSE = LICENSE
|
||||||
migrate.ps1 = migrate.ps1
|
migrate.ps1 = migrate.ps1
|
||||||
README.md = README.md
|
README.md = README.md
|
||||||
|
@ -30,8 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ellie.Marmalade", "src\Elli
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EllieBot.Voice", "src\EllieBot.Voice\EllieBot.Voice.csproj", "{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EllieBot.Voice", "src\EllieBot.Voice\EllieBot.Voice.csproj", "{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EllieBot.GrpcApiBase", "src\EllieBot.GrpcApiBase\EllieBot.GrpcApiBase.csproj", "{3B71F0BF-AE6C-480C-AB88-FCE23EDC7D91}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -66,10 +63,6 @@ Global
|
||||||
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3B71F0BF-AE6C-480C-AB88-FCE23EDC7D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3B71F0BF-AE6C-480C-AB88-FCE23EDC7D91}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3B71F0BF-AE6C-480C-AB88-FCE23EDC7D91}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3B71F0BF-AE6C-480C-AB88-FCE23EDC7D91}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -82,7 +75,6 @@ Global
|
||||||
{F1A77F56-71B0-430E-AE46-94CDD7D43874} = {B28FB883-9688-41EB-BF5A-945F4A4EB628}
|
{F1A77F56-71B0-430E-AE46-94CDD7D43874} = {B28FB883-9688-41EB-BF5A-945F4A4EB628}
|
||||||
{76AC715D-12FF-4CBE-9585-A861139A2D0C} = {B28FB883-9688-41EB-BF5A-945F4A4EB628}
|
{76AC715D-12FF-4CBE-9585-A861139A2D0C} = {B28FB883-9688-41EB-BF5A-945F4A4EB628}
|
||||||
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC} = {B28FB883-9688-41EB-BF5A-945F4A4EB628}
|
{1D93CE3C-80B4-49C7-A9A2-99988920AAEC} = {B28FB883-9688-41EB-BF5A-945F4A4EB628}
|
||||||
{3B71F0BF-AE6C-480C-AB88-FCE23EDC7D91} = {B28FB883-9688-41EB-BF5A-945F4A4EB628}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {79F61C2C-CDBB-4361-A234-91A0B334CFE4}
|
SolutionGuid = {79F61C2C-CDBB-4361-A234-91A0B334CFE4}
|
||||||
|
|
|
@ -5,4 +5,5 @@ else {
|
||||||
$migrationName = $args[0]
|
$migrationName = $args[0]
|
||||||
dotnet ef migrations add $migrationName -o Migrations/Mysql -c SqliteContext -p src/EllieBot/EllieBot.csproj
|
dotnet ef migrations add $migrationName -o Migrations/Mysql -c SqliteContext -p src/EllieBot/EllieBot.csproj
|
||||||
dotnet ef migrations add $migrationName -o Migrations/PostgreSql -c PostgreSqlContext -p src/EllieBot/EllieBot.csproj
|
dotnet ef migrations add $migrationName -o Migrations/PostgreSql -c PostgreSqlContext -p src/EllieBot/EllieBot.csproj
|
||||||
|
dotnet ef migrations add $migrationName -o Migrations/Sqlite -c MysqlContext -p src/EllieBot/EllieBot.csproj
|
||||||
}
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
dotnet ef migrations remove -c SqliteContext -f -p src/EllieBot/EllieBot.csproj
|
dotnet ef migrations remove -c SqliteContext -f -p src/EllieBot/EllieBot.csproj
|
||||||
dotnet ef migrations remove -c PostgreSqlContext -f -p src/EllieBot/EllieBot.csproj
|
dotnet ef migrations remove -c PostgreSqlContext -f -p src/EllieBot/EllieBot.csproj
|
||||||
|
dotnet ef migrations remove -c MysqlContext -f -p src/EllieBot/EllieBot.csproj
|
|
@ -9,7 +9,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" PrivateAssets="all" GeneratePathProperty="true" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" PrivateAssets="all" GeneratePathProperty="true" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
#nullable enable
|
|
||||||
using System.CodeDom.Compiler;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
using Microsoft.CodeAnalysis.Text;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace EllieBot.Generators
|
|
||||||
{
|
|
||||||
public readonly record struct MethodPermData
|
|
||||||
{
|
|
||||||
public readonly string Name;
|
|
||||||
public readonly string Value;
|
|
||||||
|
|
||||||
public MethodPermData(string name, string value)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
Value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Generator]
|
|
||||||
public class GrpcApiPermGenerator : IIncrementalGenerator
|
|
||||||
{
|
|
||||||
public const string Attribute =
|
|
||||||
"""
|
|
||||||
namespace EllieBot.GrpcApi;
|
|
||||||
|
|
||||||
[System.AttributeUsage(System.AttributeTargets.Method)]
|
|
||||||
public class GrpcApiPermAttribute : System.Attribute
|
|
||||||
{
|
|
||||||
public GuildPerm Value { get; }
|
|
||||||
public GrpcApiPermAttribute(GuildPerm value) => Value = value;
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
|
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
|
||||||
{
|
|
||||||
context.RegisterPostInitializationOutput(ctx => ctx.AddSource("GrpcApiPermAttribute.cs",
|
|
||||||
SourceText.From(Attribute, Encoding.UTF8)));
|
|
||||||
|
|
||||||
var enumsToGenerate = context.SyntaxProvider
|
|
||||||
.ForAttributeWithMetadataName(
|
|
||||||
"EllieBot.GrpcApi.GrpcApiPermAttribute",
|
|
||||||
predicate: static (s, _) => s is MethodDeclarationSyntax,
|
|
||||||
transform: static (ctx, _) => GetMethodSemanticTargets(ctx.SemanticModel, ctx.TargetNode))
|
|
||||||
.Where(static m => m is not null)
|
|
||||||
.Select(static (x, _) => x!.Value)
|
|
||||||
.Collect();
|
|
||||||
|
|
||||||
context.RegisterSourceOutput(enumsToGenerate,
|
|
||||||
static (spc, source) => Execute(source, spc));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MethodPermData? GetMethodSemanticTargets(SemanticModel model, SyntaxNode node)
|
|
||||||
{
|
|
||||||
var method = (MethodDeclarationSyntax)node;
|
|
||||||
|
|
||||||
var name = method.Identifier.Text;
|
|
||||||
var attr = method.AttributeLists
|
|
||||||
.SelectMany(x => x.Attributes)
|
|
||||||
.FirstOrDefault();
|
|
||||||
// .FirstOrDefault(x => x.Name.ToString() == "GrpcApiPermAttribute");
|
|
||||||
|
|
||||||
|
|
||||||
if (attr is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// if (model.GetSymbolInfo(attr).Symbol is not IMethodSymbol attrSymbol)
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
return new MethodPermData(name, attr.ArgumentList.Arguments[0].ToString() ?? "__missing_perm__");
|
|
||||||
// return new MethodPermData(name, attrSymbol.Parameters[0].ContainingType.ToDisplayString() + "." + attrSymbol.Parameters[0].Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Execute(ImmutableArray<MethodPermData> fields, SourceProductionContext ctx)
|
|
||||||
{
|
|
||||||
using (var stringWriter = new StringWriter())
|
|
||||||
using (var sw = new IndentedTextWriter(stringWriter))
|
|
||||||
{
|
|
||||||
sw.WriteLine("using System.Collections.Frozen;");
|
|
||||||
sw.WriteLine();
|
|
||||||
sw.WriteLine("namespace EllieBot.GrpcApi;");
|
|
||||||
sw.WriteLine();
|
|
||||||
|
|
||||||
sw.WriteLine("public partial class PermsInterceptor");
|
|
||||||
sw.WriteLine("{");
|
|
||||||
|
|
||||||
sw.Indent++;
|
|
||||||
|
|
||||||
sw.WriteLine("public static FrozenDictionary<string, GuildPerm> perms = new Dictionary<string, GuildPerm>()");
|
|
||||||
sw.WriteLine("{");
|
|
||||||
|
|
||||||
sw.Indent++;
|
|
||||||
foreach (var field in fields)
|
|
||||||
{
|
|
||||||
sw.WriteLine("{{ \"{0}\", {1} }},", field.Name, field.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
sw.Indent--;
|
|
||||||
sw.WriteLine("}.ToFrozenDictionary();");
|
|
||||||
|
|
||||||
sw.Indent--;
|
|
||||||
sw.WriteLine("}");
|
|
||||||
|
|
||||||
sw.Flush();
|
|
||||||
ctx.AddSource("GrpcApiInterceptor.g.cs", stringWriter.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<TranslationPair> GetFields(string? dataText)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(dataText))
|
|
||||||
return new();
|
|
||||||
|
|
||||||
Dictionary<string, string> data;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var output = JsonConvert.DeserializeObject<Dictionary<string, string>>(dataText!);
|
|
||||||
if (output is null)
|
|
||||||
return new();
|
|
||||||
|
|
||||||
data = output;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Debug.WriteLine("Failed parsing responses file.");
|
|
||||||
return new();
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = new List<TranslationPair>();
|
|
||||||
foreach (var entry in data)
|
|
||||||
{
|
|
||||||
list.Add(new(
|
|
||||||
entry.Key,
|
|
||||||
entry.Value
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.28.2" />
|
|
||||||
<PackageReference Include="Grpc" Version="2.46.6" />
|
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.66.0" PrivateAssets="All" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Protobuf Include="protos/*.proto">
|
|
||||||
<GrpcServices>Server</GrpcServices>
|
|
||||||
</Protobuf>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,26 +0,0 @@
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option csharp_namespace = "EllieBot.GrpcApi";
|
|
||||||
|
|
||||||
package econ;
|
|
||||||
|
|
||||||
service GrpcEcon {
|
|
||||||
rpc GetEconomy(EconomyRequest) returns (EconomyReply);
|
|
||||||
}
|
|
||||||
|
|
||||||
message EconomyRequest {
|
|
||||||
string guildId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message EconomyReply {
|
|
||||||
uint64 totalOwned = 1;
|
|
||||||
uint64 byTopOnePercent = 2;
|
|
||||||
uint64 plantedAmount = 3;
|
|
||||||
uint64 ownedByTheBot = 4;
|
|
||||||
uint64 inTheBank = 5;
|
|
||||||
uint64 totalEconomy = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CurrencyLbRequest {
|
|
||||||
int32 page = 1;
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option csharp_namespace = "EllieBot.GrpcApi";
|
|
||||||
|
|
||||||
import "google/protobuf/empty.proto";
|
|
||||||
|
|
||||||
package exprs;
|
|
||||||
|
|
||||||
service GrpcExprs {
|
|
||||||
rpc GetExprs(GetExprsRequest) returns (GetExprsReply);
|
|
||||||
rpc AddExpr(AddExprRequest) returns (AddExprReply);
|
|
||||||
rpc DeleteExpr(DeleteExprRequest) returns (google.protobuf.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
message DeleteExprRequest {
|
|
||||||
string id = 1;
|
|
||||||
uint64 guildId = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetExprsRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
string query = 2;
|
|
||||||
int32 page = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetExprsReply {
|
|
||||||
repeated ExprDto expressions = 1;
|
|
||||||
int32 totalCount = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ExprDto {
|
|
||||||
string id = 1;
|
|
||||||
string trigger = 2;
|
|
||||||
string response = 3;
|
|
||||||
|
|
||||||
bool ca = 4;
|
|
||||||
bool ad = 5;
|
|
||||||
bool dm = 6;
|
|
||||||
bool at = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
message AddExprRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
ExprDto expr = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message AddExprReply {
|
|
||||||
string id = 1;
|
|
||||||
bool success = 2;
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option csharp_namespace = "EllieBot.GrpcApi";
|
|
||||||
|
|
||||||
package greet;
|
|
||||||
|
|
||||||
service GrpcGreet {
|
|
||||||
rpc GetGreetSettings (GetGreetRequest) returns (GetGreetReply);
|
|
||||||
rpc UpdateGreet (UpdateGreetRequest) returns (UpdateGreetReply);
|
|
||||||
rpc TestGreet (TestGreetRequest) returns (TestGreetReply);
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetGreetReply {
|
|
||||||
GrpcGreetSettings greet = 1;
|
|
||||||
GrpcGreetSettings greetDm = 2;
|
|
||||||
GrpcGreetSettings bye = 3;
|
|
||||||
GrpcGreetSettings boost = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GrpcGreetSettings {
|
|
||||||
optional uint64 channelId = 1;
|
|
||||||
string message = 2;
|
|
||||||
bool isEnabled = 3;
|
|
||||||
GrpcGreetType type = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetGreetRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message UpdateGreetRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
GrpcGreetSettings settings = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum GrpcGreetType {
|
|
||||||
Greet = 0;
|
|
||||||
GreetDm = 1;
|
|
||||||
Bye = 2;
|
|
||||||
Boost = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message UpdateGreetReply {
|
|
||||||
bool success = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TestGreetRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
uint64 channelId = 2;
|
|
||||||
uint64 userId = 3;
|
|
||||||
GrpcGreetType type = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TestGreetReply {
|
|
||||||
bool success = 1;
|
|
||||||
string error = 2;
|
|
||||||
}
|
|
|
@ -1,137 +0,0 @@
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option csharp_namespace = "EllieBot.GrpcApi";
|
|
||||||
|
|
||||||
import "google/protobuf/empty.proto";
|
|
||||||
import "google/protobuf/timestamp.proto";
|
|
||||||
|
|
||||||
package other;
|
|
||||||
|
|
||||||
service GrpcOther {
|
|
||||||
|
|
||||||
rpc GetGuilds(google.protobuf.Empty) returns (GetGuildsReply);
|
|
||||||
rpc GetTextChannels(GetTextChannelsRequest) returns (GetTextChannelsReply);
|
|
||||||
|
|
||||||
rpc GetCurrencyLb(GetLbRequest) returns (CurrencyLbReply);
|
|
||||||
rpc GetXpLb(GetLbRequest) returns (XpLbReply);
|
|
||||||
rpc GetWaifuLb(GetLbRequest) returns (WaifuLbReply);
|
|
||||||
|
|
||||||
rpc GetShardStatuses(google.protobuf.Empty) returns (GetShardStatusesReply);
|
|
||||||
rpc GetServerInfo(ServerInfoRequest) returns (GetServerInfoReply);
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetGuildsReply {
|
|
||||||
repeated GuildReply guilds = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GuildReply {
|
|
||||||
uint64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
string iconUrl = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetShardStatusesReply {
|
|
||||||
repeated ShardStatusReply shards = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ShardStatusReply {
|
|
||||||
int32 id = 1;
|
|
||||||
string status = 2;
|
|
||||||
|
|
||||||
int32 guildCount = 3;
|
|
||||||
google.protobuf.Timestamp lastUpdate = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetTextChannelsRequest{
|
|
||||||
uint64 guildId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetTextChannelsReply {
|
|
||||||
repeated TextChannelReply textChannels = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message TextChannelReply {
|
|
||||||
uint64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CurrencyLbReply {
|
|
||||||
repeated CurrencyLbEntryReply entries = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CurrencyLbEntryReply {
|
|
||||||
string user = 1;
|
|
||||||
uint64 userId = 2;
|
|
||||||
int64 amount = 3;
|
|
||||||
string avatar = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetLbRequest {
|
|
||||||
int32 page = 1;
|
|
||||||
int32 perPage = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message XpLbReply {
|
|
||||||
repeated XpLbEntryReply entries = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message XpLbEntryReply {
|
|
||||||
string user = 1;
|
|
||||||
uint64 userId = 2;
|
|
||||||
int64 totalXp = 3;
|
|
||||||
int64 level = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message WaifuLbReply {
|
|
||||||
repeated WaifuLbEntry entries = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message WaifuLbEntry {
|
|
||||||
string user = 1;
|
|
||||||
string claimedBy = 2;
|
|
||||||
int64 value = 3;
|
|
||||||
bool isMutual = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ServerInfoRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetServerInfoReply {
|
|
||||||
uint64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
string iconUrl = 3;
|
|
||||||
uint64 ownerId = 4;
|
|
||||||
string ownerName = 5;
|
|
||||||
repeated RoleReply roles = 6;
|
|
||||||
repeated EmojiReply emojis = 7;
|
|
||||||
repeated string features = 8;
|
|
||||||
int32 textChannels = 9;
|
|
||||||
int32 voiceChannels = 10;
|
|
||||||
int32 memberCount = 11;
|
|
||||||
int64 createdAt = 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RoleReply {
|
|
||||||
uint64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
string iconUrl = 3;
|
|
||||||
string color = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message EmojiReply {
|
|
||||||
string name = 1;
|
|
||||||
string url = 2;
|
|
||||||
string code = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ChannelReply {
|
|
||||||
uint64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
ChannelType type = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ChannelType {
|
|
||||||
Text = 0;
|
|
||||||
Voice = 1;
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
option csharp_namespace = "EllieBot.GrpcApi";
|
|
||||||
|
|
||||||
package warn;
|
|
||||||
|
|
||||||
service GrpcWarn {
|
|
||||||
rpc GetWarnSettings (WarnSettingsRequest) returns (WarnSettingsReply);
|
|
||||||
rpc AddWarnp (AddWarnpRequest) returns (AddWarnpReply);
|
|
||||||
rpc DeleteWarnp (DeleteWarnpRequest) returns (DeleteWarnpReply);
|
|
||||||
rpc GetUserWarnings(GetUserWarningsRequest) returns (GetUserWarningsReply);
|
|
||||||
rpc ClearWarning(ClearWarningRequest) returns (ClearWarningReply);
|
|
||||||
rpc SetWarnExpiry(SetWarnExpiryRequest) returns (SetWarnExpiryReply);
|
|
||||||
}
|
|
||||||
message WarnSettingsRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message WarnPunishment {
|
|
||||||
int32 threshold = 1;
|
|
||||||
string action = 2;
|
|
||||||
int64 duration = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message WarnSettingsReply {
|
|
||||||
repeated WarnPunishment punishments = 1;
|
|
||||||
int32 expiryDays = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message AddWarnpRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
WarnPunishment punishment = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message AddWarnpReply {
|
|
||||||
bool success = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DeleteWarnpRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
int32 warnpIndex = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message DeleteWarnpReply {
|
|
||||||
bool success = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetUserWarningsRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
uint64 user_id = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetUserWarningsReply {
|
|
||||||
repeated Warning warnings = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Warning {
|
|
||||||
int32 id = 1;
|
|
||||||
string reason = 2;
|
|
||||||
int64 timestamp = 3;
|
|
||||||
int64 expiry_timestamp = 4;
|
|
||||||
bool cleared = 5;
|
|
||||||
string clearedBy = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ClearWarningRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
uint64 userId = 2;
|
|
||||||
optional int32 warnId = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ClearWarningReply {
|
|
||||||
bool success = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetWarnExpiryRequest {
|
|
||||||
uint64 guildId = 1;
|
|
||||||
int32 expiryDays = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetWarnExpiryReply {
|
|
||||||
bool success = 1;
|
|
||||||
}
|
|
76
src/EllieBot.Tests/GroupGreetTests.cs
Normal file
76
src/EllieBot.Tests/GroupGreetTests.cs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ellie.Common;
|
||||||
|
using EllieBot.Services;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace EllieBot.Tests
|
||||||
|
{
|
||||||
|
public class GroupGreetTests
|
||||||
|
{
|
||||||
|
private GreetGrouper<int> _grouper;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
=> _grouper = new GreetGrouper<int>();
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateTest()
|
||||||
|
{
|
||||||
|
var created = _grouper.CreateOrAdd(0, 5);
|
||||||
|
|
||||||
|
Assert.True(created);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateClearTest()
|
||||||
|
{
|
||||||
|
_grouper.CreateOrAdd(0, 5);
|
||||||
|
_grouper.ClearGroup(0, 5, out var items);
|
||||||
|
|
||||||
|
Assert.AreEqual(0, items.Count());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void NotCreatedTest()
|
||||||
|
{
|
||||||
|
_grouper.CreateOrAdd(0, 5);
|
||||||
|
var created = _grouper.CreateOrAdd(0, 4);
|
||||||
|
|
||||||
|
Assert.False(created);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ClearAddedTest()
|
||||||
|
{
|
||||||
|
_grouper.CreateOrAdd(0, 5);
|
||||||
|
_grouper.CreateOrAdd(0, 4);
|
||||||
|
_grouper.ClearGroup(0, 5, out var items);
|
||||||
|
|
||||||
|
var list = items.ToList();
|
||||||
|
|
||||||
|
Assert.AreEqual(1, list.Count, $"Count was {list.Count}");
|
||||||
|
Assert.AreEqual(4, list[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task ClearManyTest()
|
||||||
|
{
|
||||||
|
_grouper.CreateOrAdd(0, 5);
|
||||||
|
|
||||||
|
// add 15 items
|
||||||
|
await Enumerable.Range(10, 15)
|
||||||
|
.Select(x => Task.Run(() => _grouper.CreateOrAdd(0, x))).WhenAll();
|
||||||
|
|
||||||
|
// get 5 at most
|
||||||
|
_grouper.ClearGroup(0, 5, out var items);
|
||||||
|
var list = items.ToList();
|
||||||
|
Assert.AreEqual(5, list.Count, $"Count was {list.Count}");
|
||||||
|
|
||||||
|
// try to get 15, but there should be 10 left
|
||||||
|
_grouper.ClearGroup(0, 15, out items);
|
||||||
|
list = items.ToList();
|
||||||
|
Assert.AreEqual(10, list.Count, $"Count was {list.Count}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using DryIoc;
|
using DryIoc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using EllieBot.Common.Configs;
|
using EllieBot.Common.Configs;
|
||||||
|
@ -25,7 +24,7 @@ public sealed class Bot : IBot
|
||||||
public bool IsReady { get; private set; }
|
public bool IsReady { get; private set; }
|
||||||
public int ShardId { get; set; }
|
public int ShardId { get; set; }
|
||||||
|
|
||||||
private readonly IBotCreds _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly CommandService _commandService;
|
private readonly CommandService _commandService;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
|
||||||
|
@ -42,9 +41,6 @@ public sealed class Bot : IBot
|
||||||
_credsProvider = new BotCredsProvider(totalShards, credPath);
|
_credsProvider = new BotCredsProvider(totalShards, credPath);
|
||||||
_creds = _credsProvider.GetCreds();
|
_creds = _credsProvider.GetCreds();
|
||||||
|
|
||||||
LogSetup.SetupLogger(shardId, _creds);
|
|
||||||
Log.Information("Pid: {ProcessId}", Environment.ProcessId);
|
|
||||||
|
|
||||||
_db = new EllieDbService(_credsProvider);
|
_db = new EllieDbService(_credsProvider);
|
||||||
|
|
||||||
var messageCacheSize =
|
var messageCacheSize =
|
||||||
|
@ -92,18 +88,18 @@ public sealed class Bot : IBot
|
||||||
|
|
||||||
|
|
||||||
public IReadOnlyList<ulong> GetCurrentGuildIds()
|
public IReadOnlyList<ulong> GetCurrentGuildIds()
|
||||||
=> Client.Guilds.Select(x => x.Id).ToList().AsReadOnly();
|
=> Client.Guilds.Select(x => x.Id).ToList().ToList();
|
||||||
|
|
||||||
private async Task AddServices()
|
private void AddServices()
|
||||||
{
|
{
|
||||||
var startingGuildIdList = GetCurrentGuildIds().ToList();
|
var startingGuildIdList = GetCurrentGuildIds();
|
||||||
var startTime = Stopwatch.GetTimestamp();
|
var startTime = Stopwatch.GetTimestamp();
|
||||||
var bot = Client.CurrentUser;
|
var bot = Client.CurrentUser;
|
||||||
|
|
||||||
await using (var uow = _db.GetDbContext())
|
using (var uow = _db.GetDbContext())
|
||||||
{
|
{
|
||||||
AllGuildConfigs = await uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList);
|
|
||||||
uow.EnsureUserCreated(bot.Id, bot.Username, bot.Discriminator, bot.AvatarId);
|
uow.EnsureUserCreated(bot.Id, bot.Username, bot.Discriminator, bot.AvatarId);
|
||||||
|
AllGuildConfigs = uow.Set<GuildConfig>().GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// var svcs = new StandardKernel(new NinjectSettings()
|
// var svcs = new StandardKernel(new NinjectSettings()
|
||||||
|
@ -118,7 +114,7 @@ public sealed class Bot : IBot
|
||||||
// svcs.Components.Remove<IPlanner, Planner>();
|
// svcs.Components.Remove<IPlanner, Planner>();
|
||||||
// svcs.Components.Add<IPlanner, RemovablePlanner>();
|
// svcs.Components.Add<IPlanner, RemovablePlanner>();
|
||||||
|
|
||||||
svcs.AddSingleton<IBotCreds>(_ => _credsProvider.GetCreds());
|
svcs.AddSingleton<IBotCredentials>(_ => _credsProvider.GetCreds());
|
||||||
svcs.AddSingleton<DbService, DbService>(_db);
|
svcs.AddSingleton<DbService, DbService>(_db);
|
||||||
svcs.AddSingleton<IBotCredsProvider>(_credsProvider);
|
svcs.AddSingleton<IBotCredsProvider>(_credsProvider);
|
||||||
svcs.AddSingleton<DiscordSocketClient>(Client);
|
svcs.AddSingleton<DiscordSocketClient>(Client);
|
||||||
|
@ -165,8 +161,7 @@ public sealed class Bot : IBot
|
||||||
LoadTypeReaders(a);
|
LoadTypeReaders(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Information("All services loaded in {ServiceLoadTime:F2}s",
|
Log.Information("All services loaded in {ServiceLoadTime:F2}s", Stopwatch.GetElapsedTime(startTime).TotalSeconds);
|
||||||
Stopwatch.GetElapsedTime(startTime).TotalSeconds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadTypeReaders(Assembly assembly)
|
private void LoadTypeReaders(Assembly assembly)
|
||||||
|
@ -270,7 +265,7 @@ public sealed class Bot : IBot
|
||||||
Log.Information("Shard {ShardId} loading services...", Client.ShardId);
|
Log.Information("Shard {ShardId} loading services...", Client.ShardId);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await AddServices();
|
AddServices();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -278,9 +273,7 @@ public sealed class Bot : IBot
|
||||||
Helpers.ReadErrorAndExit(9);
|
Helpers.ReadErrorAndExit(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Information("Shard {ShardId} connected in {Elapsed:F2}s",
|
Log.Information("Shard {ShardId} connected in {Elapsed:F2}s", Client.ShardId, Stopwatch.GetElapsedTime(startTime).TotalSeconds);
|
||||||
Client.ShardId,
|
|
||||||
Stopwatch.GetElapsedTime(startTime).TotalSeconds);
|
|
||||||
var commandHandler = Services.GetRequiredService<CommandHandler>();
|
var commandHandler = Services.GetRequiredService<CommandHandler>();
|
||||||
|
|
||||||
// start handling messages received in commandhandler
|
// start handling messages received in commandhandler
|
||||||
|
@ -345,26 +338,26 @@ public sealed class Bot : IBot
|
||||||
if (arg.Exception is { InnerException: WebSocketClosedException { CloseCode: 4014 } })
|
if (arg.Exception is { InnerException: WebSocketClosedException { CloseCode: 4014 } })
|
||||||
{
|
{
|
||||||
Log.Error("""
|
Log.Error("""
|
||||||
Login failed.
|
Login failed.
|
||||||
|
|
||||||
*** Please enable privileged intents ***
|
*** Please enable privileged intents ***
|
||||||
|
|
||||||
Certain Ellie features require Discord's privileged gateway intents.
|
Certain Ellie features require Discord's privileged gateway intents.
|
||||||
These include greeting and goodbye messages, as well as creating the Owner message channels for DM forwarding.
|
These include greeting and goodbye messages, as well as creating the Owner message channels for DM forwarding.
|
||||||
|
|
||||||
How to enable privileged intents:
|
How to enable privileged intents:
|
||||||
1. Head over to the Discord Developer Portal https://discord.com/developers/applications/
|
1. Head over to the Discord Developer Portal https://discord.com/developers/applications/
|
||||||
2. Select your Application.
|
2. Select your Application.
|
||||||
3. Click on `Bot` in the left side navigation panel, and scroll down to the intents section.
|
3. Click on `Bot` in the left side navigation panel, and scroll down to the intents section.
|
||||||
4. Enable all intents.
|
4. Enable all intents.
|
||||||
5. Restart your bot.
|
5. Restart your bot.
|
||||||
|
|
||||||
Read this only if your bot is in 100 or more servers:
|
Read this only if your bot is in 100 or more servers:
|
||||||
|
|
||||||
You'll need to apply to use the intents with Discord, but for small selfhosts, all that is required is enabling the intents in the developer portal.
|
You'll need to apply to use the intents with Discord, but for small selfhosts, all that is required is enabling the intents in the developer portal.
|
||||||
Yes, this is a new thing from Discord, as of October 2020. No, there's nothing we can do about it. Yes, we're aware it worked before.
|
Yes, this is a new thing from Discord, as of October 2020. No, there's nothing we can do about it. Yes, we're aware it worked before.
|
||||||
While waiting for your bot to be accepted, you can change the 'usePrivilegedIntents' inside your creds.yml to 'false', although this will break many of the ellie's features
|
While waiting for your bot to be accepted, you can change the 'usePrivilegedIntents' inside your creds.yml to 'false', although this will break many of the ellie's features
|
||||||
""");
|
""");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ namespace EllieBot.Db;
|
||||||
public abstract class EllieContext : DbContext
|
public abstract class EllieContext : DbContext
|
||||||
{
|
{
|
||||||
public DbSet<GuildConfig> GuildConfigs { get; set; }
|
public DbSet<GuildConfig> GuildConfigs { get; set; }
|
||||||
public DbSet<GreetSettings> GreetSettings { get; set; }
|
|
||||||
|
|
||||||
public DbSet<Quote> Quotes { get; set; }
|
public DbSet<Quote> Quotes { get; set; }
|
||||||
public DbSet<Reminder> Reminders { get; set; }
|
public DbSet<Reminder> Reminders { get; set; }
|
||||||
|
@ -283,10 +282,10 @@ public abstract class EllieContext : DbContext
|
||||||
var selfassignableRolesEntity = modelBuilder.Entity<SelfAssignedRole>();
|
var selfassignableRolesEntity = modelBuilder.Entity<SelfAssignedRole>();
|
||||||
|
|
||||||
selfassignableRolesEntity.HasIndex(s => new
|
selfassignableRolesEntity.HasIndex(s => new
|
||||||
{
|
{
|
||||||
s.GuildId,
|
s.GuildId,
|
||||||
s.RoleId
|
s.RoleId
|
||||||
})
|
})
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
selfassignableRolesEntity.Property(x => x.Group).HasDefaultValue(0);
|
selfassignableRolesEntity.Property(x => x.Group).HasDefaultValue(0);
|
||||||
|
@ -359,10 +358,10 @@ public abstract class EllieContext : DbContext
|
||||||
|
|
||||||
var xps = modelBuilder.Entity<UserXpStats>();
|
var xps = modelBuilder.Entity<UserXpStats>();
|
||||||
xps.HasIndex(x => new
|
xps.HasIndex(x => new
|
||||||
{
|
{
|
||||||
x.UserId,
|
x.UserId,
|
||||||
x.GuildId
|
x.GuildId
|
||||||
})
|
})
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
xps.HasIndex(x => x.UserId);
|
xps.HasIndex(x => x.UserId);
|
||||||
|
@ -408,9 +407,9 @@ public abstract class EllieContext : DbContext
|
||||||
.OnDelete(DeleteBehavior.SetNull);
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
ci.HasIndex(x => new
|
ci.HasIndex(x => new
|
||||||
{
|
{
|
||||||
x.Name
|
x.Name
|
||||||
})
|
})
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -529,10 +528,10 @@ public abstract class EllieContext : DbContext
|
||||||
.IsUnique(false);
|
.IsUnique(false);
|
||||||
|
|
||||||
rr2.HasIndex(x => new
|
rr2.HasIndex(x => new
|
||||||
{
|
{
|
||||||
x.MessageId,
|
x.MessageId,
|
||||||
x.Emote
|
x.Emote
|
||||||
})
|
})
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -607,11 +606,11 @@ public abstract class EllieContext : 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();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -636,10 +635,10 @@ public abstract class EllieContext : DbContext
|
||||||
#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
|
||||||
|
@ -679,29 +678,6 @@ public abstract class EllieContext : DbContext
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GreetSettings
|
|
||||||
|
|
||||||
modelBuilder
|
|
||||||
.Entity<GreetSettings>(gs => gs.HasIndex(x => new
|
|
||||||
{
|
|
||||||
x.GuildId,
|
|
||||||
x.GreetType
|
|
||||||
})
|
|
||||||
.IsUnique());
|
|
||||||
|
|
||||||
modelBuilder.Entity<GreetSettings>(gs =>
|
|
||||||
{
|
|
||||||
gs
|
|
||||||
.Property(x => x.IsEnabled)
|
|
||||||
.HasDefaultValue(false);
|
|
||||||
|
|
||||||
gs
|
|
||||||
.Property(x => x.AutoDeleteTimer)
|
|
||||||
.HasDefaultValue(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
|
@ -4,14 +4,14 @@ using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace EllieBot.Db;
|
namespace EllieBot.Db;
|
||||||
|
|
||||||
public sealed class EllieDbService : DbService
|
public sealed class EllieDbService : DbService
|
||||||
{
|
{
|
||||||
private readonly IBotCredsProvider _creds;
|
private readonly IBotCredsProvider _creds;
|
||||||
|
|
||||||
// these are props because creds can change at runtime
|
// these are props because creds can change at runtime
|
||||||
private string DbType => _creds.GetCreds().Db.Type.ToLowerInvariant().Trim();
|
private string DbType => _creds.GetCreds().Db.Type.ToLowerInvariant().Trim();
|
||||||
private string ConnString => _creds.GetCreds().Db.ConnectionString;
|
private string ConnString => _creds.GetCreds().Db.ConnectionString;
|
||||||
|
|
||||||
public EllieDbService(IBotCredsProvider creds)
|
public EllieDbService(IBotCredsProvider creds)
|
||||||
{
|
{
|
||||||
LinqToDBForEFTools.Initialize();
|
LinqToDBForEFTools.Initialize();
|
||||||
|
@ -26,13 +26,13 @@ public sealed class EllieDbService : DbService
|
||||||
var connString = ConnString;
|
var connString = ConnString;
|
||||||
|
|
||||||
await using var context = CreateRawDbContext(dbType, connString);
|
await using var context = CreateRawDbContext(dbType, connString);
|
||||||
|
|
||||||
// make sure sqlite db is in wal journal mode
|
// make sure sqlite db is in wal journal mode
|
||||||
if (context is SqliteContext)
|
if (context is SqliteContext)
|
||||||
{
|
{
|
||||||
await context.Database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL");
|
await context.Database.ExecuteSqlRawAsync("PRAGMA journal_mode=WAL");
|
||||||
}
|
}
|
||||||
|
|
||||||
await context.Database.MigrateAsync();
|
await context.Database.MigrateAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,13 +44,15 @@ public sealed class EllieDbService : DbService
|
||||||
case "postgres":
|
case "postgres":
|
||||||
case "pgsql":
|
case "pgsql":
|
||||||
return new PostgreSqlContext(connString);
|
return new PostgreSqlContext(connString);
|
||||||
|
case "mysql":
|
||||||
|
return new MysqlContext(connString);
|
||||||
case "sqlite":
|
case "sqlite":
|
||||||
return new SqliteContext(connString);
|
return new SqliteContext(connString);
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException($"The database provide type of '{dbType}' is not supported.");
|
throw new NotSupportedException($"The database provide type of '{dbType}' is not supported.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private EllieContext GetDbContextInternal()
|
private EllieContext GetDbContextInternal()
|
||||||
{
|
{
|
||||||
var dbType = DbType;
|
var dbType = DbType;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
using LinqToDB.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using EllieBot.Db.Models;
|
using EllieBot.Db.Models;
|
||||||
|
|
||||||
|
@ -33,8 +32,8 @@ public static class GuildConfigExtensions
|
||||||
{
|
{
|
||||||
var conf = ctx.GuildConfigsForId(guildId,
|
var conf = ctx.GuildConfigsForId(guildId,
|
||||||
set => set.Include(y => y.StreamRole)
|
set => set.Include(y => y.StreamRole)
|
||||||
.Include(y => y.StreamRole.Whitelist)
|
.Include(y => y.StreamRole.Whitelist)
|
||||||
.Include(y => y.StreamRole.Blacklist));
|
.Include(y => y.StreamRole.Blacklist));
|
||||||
|
|
||||||
if (conf.StreamRole is null)
|
if (conf.StreamRole is null)
|
||||||
conf.StreamRole = new();
|
conf.StreamRole = new();
|
||||||
|
@ -43,28 +42,19 @@ public static class GuildConfigExtensions
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IQueryable<GuildConfig> IncludeEverything(this DbSet<GuildConfig> configs)
|
private static IQueryable<GuildConfig> IncludeEverything(this DbSet<GuildConfig> configs)
|
||||||
=> configs
|
=> configs.AsQueryable()
|
||||||
.AsSplitQuery()
|
.AsSplitQuery()
|
||||||
.Include(gc => gc.CommandCooldowns)
|
.Include(gc => gc.CommandCooldowns)
|
||||||
.Include(gc => gc.FollowedStreams)
|
.Include(gc => gc.FollowedStreams)
|
||||||
.Include(gc => gc.StreamRole)
|
.Include(gc => gc.StreamRole)
|
||||||
.Include(gc => gc.DelMsgOnCmdChannels)
|
.Include(gc => gc.XpSettings)
|
||||||
.Include(gc => gc.XpSettings)
|
.ThenInclude(x => x.ExclusionList)
|
||||||
.ThenInclude(x => x.ExclusionList);
|
.Include(gc => gc.DelMsgOnCmdChannels);
|
||||||
|
|
||||||
public static async Task<GuildConfig[]> GetAllGuildConfigs(
|
public static IEnumerable<GuildConfig> GetAllGuildConfigs(
|
||||||
this DbSet<GuildConfig> configs,
|
this DbSet<GuildConfig> configs,
|
||||||
List<ulong> availableGuilds)
|
IReadOnlyList<ulong> availableGuilds)
|
||||||
{
|
=> configs.IncludeEverything().AsNoTracking().Where(x => availableGuilds.Contains(x.GuildId)).ToList();
|
||||||
var result = await configs
|
|
||||||
.AsQueryable()
|
|
||||||
.Include(x => x.CommandCooldowns)
|
|
||||||
.Where(x => availableGuilds.Contains(x.GuildId))
|
|
||||||
.AsNoTracking()
|
|
||||||
.ToArrayAsync();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets and creates if it doesn't exist a config for a guild.
|
/// Gets and creates if it doesn't exist a config for a guild.
|
||||||
|
@ -90,14 +80,13 @@ public static class GuildConfigExtensions
|
||||||
|
|
||||||
if (config is null)
|
if (config is null)
|
||||||
{
|
{
|
||||||
ctx.Set<GuildConfig>()
|
ctx.Set<GuildConfig>().Add(config = new()
|
||||||
.Add(config = new()
|
{
|
||||||
{
|
GuildId = guildId,
|
||||||
GuildId = guildId,
|
Permissions = Permissionv2.GetDefaultPermlist,
|
||||||
Permissions = Permissionv2.GetDefaultPermlist,
|
WarningsInitialized = true,
|
||||||
WarningsInitialized = true,
|
WarnPunishments = DefaultWarnPunishments
|
||||||
WarnPunishments = DefaultWarnPunishments
|
});
|
||||||
});
|
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,18 +122,18 @@ public static class GuildConfigExtensions
|
||||||
public static LogSetting LogSettingsFor(this DbContext ctx, ulong guildId)
|
public static LogSetting LogSettingsFor(this DbContext ctx, ulong guildId)
|
||||||
{
|
{
|
||||||
var logSetting = ctx.Set<LogSetting>()
|
var logSetting = ctx.Set<LogSetting>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Include(x => x.LogIgnores)
|
.Include(x => x.LogIgnores)
|
||||||
.Where(x => x.GuildId == guildId)
|
.Where(x => x.GuildId == guildId)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
if (logSetting is null)
|
if (logSetting is null)
|
||||||
{
|
{
|
||||||
ctx.Set<LogSetting>()
|
ctx.Set<LogSetting>()
|
||||||
.Add(logSetting = new()
|
.Add(logSetting = new()
|
||||||
{
|
{
|
||||||
GuildId = guildId
|
GuildId = guildId
|
||||||
});
|
});
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,20 +149,18 @@ public static class GuildConfigExtensions
|
||||||
|
|
||||||
public static GuildConfig GcWithPermissionsFor(this DbContext ctx, ulong guildId)
|
public static GuildConfig GcWithPermissionsFor(this DbContext ctx, ulong guildId)
|
||||||
{
|
{
|
||||||
var config = ctx.Set<GuildConfig>()
|
var config = ctx.Set<GuildConfig>().AsQueryable()
|
||||||
.AsQueryable()
|
.Where(gc => gc.GuildId == guildId)
|
||||||
.Where(gc => gc.GuildId == guildId)
|
.Include(gc => gc.Permissions)
|
||||||
.Include(gc => gc.Permissions)
|
.FirstOrDefault();
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (config is null) // if there is no guildconfig, create new one
|
if (config is null) // if there is no guildconfig, create new one
|
||||||
{
|
{
|
||||||
ctx.Set<GuildConfig>()
|
ctx.Set<GuildConfig>().Add(config = new()
|
||||||
.Add(config = new()
|
{
|
||||||
{
|
GuildId = guildId,
|
||||||
GuildId = guildId,
|
Permissions = Permissionv2.GetDefaultPermlist
|
||||||
Permissions = Permissionv2.GetDefaultPermlist
|
});
|
||||||
});
|
|
||||||
ctx.SaveChanges();
|
ctx.SaveChanges();
|
||||||
}
|
}
|
||||||
else if (config.Permissions is null || !config.Permissions.Any()) // if no perms, add default ones
|
else if (config.Permissions is null || !config.Permissions.Any()) // if no perms, add default ones
|
||||||
|
@ -190,21 +177,20 @@ public static class GuildConfigExtensions
|
||||||
|
|
||||||
public static IEnumerable<FollowedStream> GetFollowedStreams(this DbSet<GuildConfig> configs, List<ulong> included)
|
public static IEnumerable<FollowedStream> GetFollowedStreams(this DbSet<GuildConfig> configs, List<ulong> included)
|
||||||
=> configs.AsQueryable()
|
=> configs.AsQueryable()
|
||||||
.Where(gc => included.Contains(gc.GuildId))
|
.Where(gc => included.Contains(gc.GuildId))
|
||||||
.Include(gc => gc.FollowedStreams)
|
.Include(gc => gc.FollowedStreams)
|
||||||
.SelectMany(gc => gc.FollowedStreams)
|
.SelectMany(gc => gc.FollowedStreams)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
|
||||||
public static XpSettings XpSettingsFor(this DbContext ctx, ulong guildId)
|
public static XpSettings XpSettingsFor(this DbContext ctx, ulong guildId)
|
||||||
{
|
{
|
||||||
var gc = ctx.GuildConfigsForId(guildId,
|
var gc = ctx.GuildConfigsForId(guildId,
|
||||||
set => set.Include(x => x.XpSettings)
|
set => set.Include(x => x.XpSettings)
|
||||||
.ThenInclude(x => x.RoleRewards)
|
.ThenInclude(x => x.RoleRewards)
|
||||||
.Include(x => x.XpSettings)
|
.Include(x => x.XpSettings)
|
||||||
.ThenInclude(x => x.CurrencyRewards)
|
.ThenInclude(x => x.CurrencyRewards)
|
||||||
.Include(x => x.XpSettings)
|
.Include(x => x.XpSettings)
|
||||||
.ThenInclude(x => x.ExclusionList));
|
.ThenInclude(x => x.ExclusionList));
|
||||||
|
|
||||||
if (gc.XpSettings is null)
|
if (gc.XpSettings is null)
|
||||||
gc.XpSettings = new();
|
gc.XpSettings = new();
|
||||||
|
@ -214,15 +200,15 @@ public static class GuildConfigExtensions
|
||||||
|
|
||||||
public static IEnumerable<GeneratingChannel> GetGeneratingChannels(this DbSet<GuildConfig> configs)
|
public static IEnumerable<GeneratingChannel> GetGeneratingChannels(this DbSet<GuildConfig> configs)
|
||||||
=> configs.AsQueryable()
|
=> configs.AsQueryable()
|
||||||
.Include(x => x.GenerateCurrencyChannelIds)
|
.Include(x => x.GenerateCurrencyChannelIds)
|
||||||
.Where(x => x.GenerateCurrencyChannelIds.Any())
|
.Where(x => x.GenerateCurrencyChannelIds.Any())
|
||||||
.SelectMany(x => x.GenerateCurrencyChannelIds)
|
.SelectMany(x => x.GenerateCurrencyChannelIds)
|
||||||
.Select(x => new GeneratingChannel
|
.Select(x => new GeneratingChannel
|
||||||
{
|
{
|
||||||
ChannelId = x.ChannelId,
|
ChannelId = x.ChannelId,
|
||||||
GuildId = x.GuildConfig.GuildId
|
GuildId = x.GuildConfig.GuildId
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
public class GeneratingChannel
|
public class GeneratingChannel
|
||||||
{
|
{
|
||||||
|
|
53
src/EllieBot/Db/Extensions/QuoteExtensions.cs
Normal file
53
src/EllieBot/Db/Extensions/QuoteExtensions.cs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#nullable disable
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using EllieBot.Db.Models;
|
||||||
|
|
||||||
|
namespace EllieBot.Db;
|
||||||
|
|
||||||
|
public static class QuoteExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<Quote> GetForGuild(this DbSet<Quote> quotes, ulong guildId)
|
||||||
|
=> quotes.AsQueryable().Where(x => x.GuildId == guildId);
|
||||||
|
|
||||||
|
public static IReadOnlyCollection<Quote> GetGroup(
|
||||||
|
this DbSet<Quote> quotes,
|
||||||
|
ulong guildId,
|
||||||
|
int page,
|
||||||
|
OrderType order)
|
||||||
|
{
|
||||||
|
var q = quotes.AsQueryable().Where(x => x.GuildId == guildId);
|
||||||
|
if (order == OrderType.Keyword)
|
||||||
|
q = q.OrderBy(x => x.Keyword);
|
||||||
|
else
|
||||||
|
q = q.OrderBy(x => x.Id);
|
||||||
|
|
||||||
|
return q.Skip(15 * page).Take(15).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<Quote> GetRandomQuoteByKeywordAsync(
|
||||||
|
this DbSet<Quote> quotes,
|
||||||
|
ulong guildId,
|
||||||
|
string keyword)
|
||||||
|
{
|
||||||
|
return (await quotes.AsQueryable().Where(q => q.GuildId == guildId && q.Keyword == keyword).ToArrayAsync())
|
||||||
|
.RandomOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<Quote> SearchQuoteKeywordTextAsync(
|
||||||
|
this DbSet<Quote> quotes,
|
||||||
|
ulong guildId,
|
||||||
|
string keyword,
|
||||||
|
string text)
|
||||||
|
{
|
||||||
|
return (await quotes.AsQueryable()
|
||||||
|
.Where(q => q.GuildId == guildId
|
||||||
|
&& (keyword == null || q.Keyword == keyword)
|
||||||
|
&& (EF.Functions.Like(q.Text.ToUpper(), $"%{text.ToUpper()}%")
|
||||||
|
|| EF.Functions.Like(q.AuthorName, text)))
|
||||||
|
.ToArrayAsync())
|
||||||
|
.RandomOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveAllByKeyword(this DbSet<Quote> quotes, ulong guildId, string keyword)
|
||||||
|
=> quotes.RemoveRange(quotes.AsQueryable().Where(x => x.GuildId == guildId && x.Keyword.ToUpper() == keyword));
|
||||||
|
}
|
|
@ -26,6 +26,17 @@ public static class UserXpExtensions
|
||||||
return usr;
|
return usr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<IReadOnlyCollection<UserXpStats>> GetUsersFor(
|
||||||
|
this DbSet<UserXpStats> xps,
|
||||||
|
ulong guildId,
|
||||||
|
int page)
|
||||||
|
=> await xps.ToLinqToDBTable()
|
||||||
|
.Where(x => x.GuildId == guildId)
|
||||||
|
.OrderByDescending(x => x.Xp + x.AwardedXp)
|
||||||
|
.Skip(page * 9)
|
||||||
|
.Take(9)
|
||||||
|
.ToArrayAsyncLinqToDB();
|
||||||
|
|
||||||
public static async Task<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)
|
||||||
=> await xps.ToLinqToDBTable()
|
=> await xps.ToLinqToDBTable()
|
||||||
.Where(x => x.GuildId == guildId)
|
.Where(x => x.GuildId == guildId)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
namespace EllieBot.Db;
|
namespace EllieBot.Db;
|
||||||
|
|
||||||
public readonly struct LevelStats
|
public readonly struct LevelStats
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#nullable disable
|
#nullable disable
|
||||||
namespace EllieBot.Db.Models;
|
namespace EllieBot.Db.Models;
|
||||||
|
|
||||||
|
|
||||||
// FUTURE remove LastLevelUp from here and UserXpStats
|
// FUTURE remove LastLevelUp from here and UserXpStats
|
||||||
public class DiscordUser : DbEntity
|
public class DiscordUser : DbEntity
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,23 +13,21 @@ public class GuildConfig : DbEntity
|
||||||
|
|
||||||
public string AutoAssignRoleIds { get; set; }
|
public string AutoAssignRoleIds { get; set; }
|
||||||
|
|
||||||
// //greet stuff
|
//greet stuff
|
||||||
// public int AutoDeleteGreetMessagesTimer { get; set; } = 30;
|
public int AutoDeleteGreetMessagesTimer { get; set; } = 30;
|
||||||
// public int AutoDeleteByeMessagesTimer { get; set; } = 30;
|
public int AutoDeleteByeMessagesTimer { get; set; } = 30;
|
||||||
//
|
|
||||||
// public ulong GreetMessageChannelId { get; set; }
|
public ulong GreetMessageChannelId { get; set; }
|
||||||
// public ulong ByeMessageChannelId { get; set; }
|
public ulong ByeMessageChannelId { get; set; }
|
||||||
//
|
|
||||||
// public bool SendDmGreetMessage { get; set; }
|
public bool SendDmGreetMessage { get; set; }
|
||||||
// public string DmGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
|
public string DmGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
|
||||||
//
|
|
||||||
// public bool SendChannelGreetMessage { get; set; }
|
public bool SendChannelGreetMessage { get; set; }
|
||||||
// public string ChannelGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
|
public string ChannelGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
|
||||||
//
|
|
||||||
// public bool SendChannelByeMessage { get; set; }
|
public bool SendChannelByeMessage { get; set; }
|
||||||
// public string ChannelByeMessageText { get; set; } = "%user% has left!";
|
public string ChannelByeMessageText { get; set; } = "%user% has left!";
|
||||||
// public bool SendBoostMessage { get; set; }
|
|
||||||
// pulic int BoostMessageDeleteAfter { get; set; }
|
|
||||||
|
|
||||||
//self assignable roles
|
//self assignable roles
|
||||||
public bool ExclusiveSelfAssignedRoles { get; set; }
|
public bool ExclusiveSelfAssignedRoles { get; set; }
|
||||||
|
@ -100,6 +98,10 @@ public class GuildConfig : DbEntity
|
||||||
|
|
||||||
#region Boost Message
|
#region Boost Message
|
||||||
|
|
||||||
|
public bool SendBoostMessage { get; set; }
|
||||||
|
public string BoostMessage { get; set; } = "%user% just boosted this server!";
|
||||||
|
public ulong BoostMessageChannelId { get; set; }
|
||||||
|
public int BoostMessageDeleteAfter { get; set; }
|
||||||
public bool StickyRoles { get; set; }
|
public bool StickyRoles { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -8,4 +8,6 @@ public class UserXpStats : DbEntity
|
||||||
public long Xp { get; set; }
|
public long Xp { get; set; }
|
||||||
public long AwardedXp { get; set; }
|
public long AwardedXp { get; set; }
|
||||||
public XpNotificationLocation NotifyOnLevelUp { get; set; }
|
public XpNotificationLocation NotifyOnLevelUp { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum XpNotificationLocation { None, Dm, Channel }
|
|
@ -1,8 +0,0 @@
|
||||||
namespace EllieBot.Db.Models;
|
|
||||||
|
|
||||||
public enum XpNotificationLocation
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Dm,
|
|
||||||
Channel
|
|
||||||
}
|
|
38
src/EllieBot/Db/MysqlContext.cs
Normal file
38
src/EllieBot/Db/MysqlContext.cs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using EllieBot.Db.Models;
|
||||||
|
|
||||||
|
namespace EllieBot.Db;
|
||||||
|
|
||||||
|
public sealed class MysqlContext : EllieContext
|
||||||
|
{
|
||||||
|
private readonly string _connStr;
|
||||||
|
private readonly string _version;
|
||||||
|
|
||||||
|
protected override string CurrencyTransactionOtherIdDefaultValue
|
||||||
|
=> "NULL";
|
||||||
|
|
||||||
|
public MysqlContext(string connStr = "Server=localhost", string version = "8.0")
|
||||||
|
{
|
||||||
|
_connStr = connStr;
|
||||||
|
_version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
|
{
|
||||||
|
base.OnConfiguring(optionsBuilder);
|
||||||
|
optionsBuilder
|
||||||
|
.UseLowerCaseNamingConvention()
|
||||||
|
.UseMySql(_connStr, ServerVersion.Parse(_version));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
base.OnModelCreating(modelBuilder);
|
||||||
|
|
||||||
|
// mysql is case insensitive by default
|
||||||
|
// we can set binary collation to change that
|
||||||
|
modelBuilder.Entity<ClubInfo>()
|
||||||
|
.Property(x => x.Name)
|
||||||
|
.UseCollation("utf8mb4_bin");
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>true</ImplicitUsings>
|
<ImplicitUsings>true</ImplicitUsings>
|
||||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||||
<Version>5.1.14</Version>
|
<Version>5.1.6</Version>
|
||||||
|
|
||||||
<!-- Output/build -->
|
<!-- Output/build -->
|
||||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||||
|
@ -34,12 +34,13 @@
|
||||||
<PackageReference Include="Google.Apis.Urlshortener.v1" Version="1.41.1.138" />
|
<PackageReference Include="Google.Apis.Urlshortener.v1" Version="1.41.1.138" />
|
||||||
<PackageReference Include="Google.Apis.YouTube.v3" Version="1.68.0.3414" />
|
<PackageReference Include="Google.Apis.YouTube.v3" Version="1.68.0.3414" />
|
||||||
<PackageReference Include="Google.Apis.Customsearch.v1" Version="1.49.0.2084" />
|
<PackageReference Include="Google.Apis.Customsearch.v1" Version="1.49.0.2084" />
|
||||||
|
<!-- <PackageReference Include="Grpc.AspNetCore" Version="2.62.0" />-->
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.28.2" />
|
<PackageReference Include="Google.Protobuf" Version="3.26.1" />
|
||||||
<PackageReference Include="Grpc" Version="2.46.6" />
|
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.62.0" />
|
||||||
<PackageReference Include="Grpc.Net.Client" Version="2.62.0" />
|
<PackageReference Include="Grpc.Tools" Version="2.63.0">
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.66.0" PrivateAssets="All" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.5.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.5.0" />
|
||||||
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
|
@ -68,9 +69,9 @@
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Seq" Version="7.0.1" />
|
<PackageReference Include="Serilog.Sinks.Seq" Version="7.0.1" />
|
||||||
|
|
||||||
<PackageReference Include="SixLabors.Fonts" Version="2.0.4" />
|
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta17" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.9" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4" />
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta14" />
|
||||||
<PackageReference Include="SixLabors.Shapes" Version="1.0.0-beta0009" />
|
<PackageReference Include="SixLabors.Shapes" Version="1.0.0-beta0009" />
|
||||||
<PackageReference Include="StackExchange.Redis" Version="2.8.0" />
|
<PackageReference Include="StackExchange.Redis" Version="2.8.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="15.1.4" />
|
<PackageReference Include="YamlDotNet" Version="15.1.4" />
|
||||||
|
@ -80,7 +81,7 @@
|
||||||
|
|
||||||
|
|
||||||
<!-- Db-related packages -->
|
<!-- Db-related packages -->
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
@ -88,8 +89,9 @@
|
||||||
|
|
||||||
<PackageReference Include="linq2db.EntityFrameworkCore" Version="8.1.0" />
|
<PackageReference Include="linq2db.EntityFrameworkCore" Version="8.1.0" />
|
||||||
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.8" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.4" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
|
||||||
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||||
|
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
||||||
|
|
||||||
|
@ -102,7 +104,6 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\EllieBot.GrpcApiBase\EllieBot.GrpcApiBase.csproj" />
|
|
||||||
<ProjectReference Include="..\Ellie.Marmalade\Ellie.Marmalade.csproj" />
|
<ProjectReference Include="..\Ellie.Marmalade\Ellie.Marmalade.csproj" />
|
||||||
<ProjectReference Include="..\EllieBot.Voice\EllieBot.Voice.csproj" />
|
<ProjectReference Include="..\EllieBot.Voice\EllieBot.Voice.csproj" />
|
||||||
<ProjectReference Include="..\EllieBot.Generators\EllieBot.Generators.csproj" OutputItemType="Analyzer" />
|
<ProjectReference Include="..\EllieBot.Generators\EllieBot.Generators.csproj" OutputItemType="Analyzer" />
|
||||||
|
@ -113,6 +114,9 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Protobuf Include="..\EllieBot.Coordinator\Protos\coordinator.proto" GrpcServices="Client">
|
||||||
|
<Link>Protos\coordinator.proto</Link>
|
||||||
|
</Protobuf>
|
||||||
<None Update="data\**\*">
|
<None Update="data\**\*">
|
||||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
@ -126,13 +130,6 @@
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Protobuf Include="..\EllieBot.Coordinator\Protos\coordinator.proto">
|
|
||||||
<Link>_common\CoordinatorProtos\coordinator.proto</Link>
|
|
||||||
<!-- <GrpcServices>Client</GrpcServices>-->
|
|
||||||
</Protobuf>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'GlobalEllie' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'GlobalEllie' ">
|
||||||
<!-- Define trace doesn't seem to affect the build at all so I had to remove $(DefineConstants)-->
|
<!-- Define trace doesn't seem to affect the build at all so I had to remove $(DefineConstants)-->
|
||||||
|
|
|
@ -7,7 +7,16 @@ public static class MigrationQueries
|
||||||
{
|
{
|
||||||
public static void MigrateRero(MigrationBuilder migrationBuilder)
|
public static void MigrateRero(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
if (migrationBuilder.IsSqlite())
|
if (migrationBuilder.IsMySql())
|
||||||
|
{
|
||||||
|
migrationBuilder.Sql(
|
||||||
|
@"INSERT IGNORE into reactionroles(guildid, channelid, messageid, emote, roleid, `group`, levelreq, dateadded)
|
||||||
|
select guildid, channelid, messageid, emotename, roleid, exclusive, 0, reactionrolemessage.dateadded
|
||||||
|
from reactionrole
|
||||||
|
left join reactionrolemessage on reactionrolemessage.id = reactionrole.reactionrolemessageid
|
||||||
|
left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;");
|
||||||
|
}
|
||||||
|
else if (migrationBuilder.IsSqlite())
|
||||||
{
|
{
|
||||||
migrationBuilder.Sql(
|
migrationBuilder.Sql(
|
||||||
@"insert or ignore into reactionroles(guildid, channelid, messageid, emote, roleid, 'group', levelreq, dateadded)
|
@"insert or ignore into reactionroles(guildid, channelid, messageid, emote, roleid, 'group', levelreq, dateadded)
|
||||||
|
@ -18,8 +27,7 @@ left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;")
|
||||||
}
|
}
|
||||||
else if (migrationBuilder.IsNpgsql())
|
else if (migrationBuilder.IsNpgsql())
|
||||||
{
|
{
|
||||||
migrationBuilder.Sql(
|
migrationBuilder.Sql(@"insert into reactionroles(guildid, channelid, messageid, emote, roleid, ""group"", levelreq, dateadded)
|
||||||
@"insert into reactionroles(guildid, channelid, messageid, emote, roleid, ""group"", levelreq, dateadded)
|
|
||||||
select guildid, channelid, messageid, emotename, roleid, exclusive::int, 0, reactionrolemessage.dateadded
|
select guildid, channelid, messageid, emotename, roleid, exclusive::int, 0, reactionrolemessage.dateadded
|
||||||
from reactionrole
|
from reactionrole
|
||||||
left join reactionrolemessage on reactionrolemessage.id = reactionrole.reactionrolemessageid
|
left join reactionrolemessage on reactionrolemessage.id = reactionrole.reactionrolemessageid
|
||||||
|
@ -35,34 +43,15 @@ left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;")
|
||||||
public static void GuildConfigCleanup(MigrationBuilder builder)
|
public static void GuildConfigCleanup(MigrationBuilder builder)
|
||||||
{
|
{
|
||||||
builder.Sql($"""
|
builder.Sql($"""
|
||||||
DELETE FROM "DelMsgOnCmdChannel" WHERE "GuildConfigId" is NULL;
|
|
||||||
DELETE FROM "WarningPunishment" WHERE "GuildConfigId" NOT IN (SELECT "Id" from "GuildConfigs");
|
|
||||||
DELETE FROM "StreamRoleBlacklistedUser" WHERE "StreamRoleSettingsId" is NULL;
|
DELETE FROM "StreamRoleBlacklistedUser" WHERE "StreamRoleSettingsId" is NULL;
|
||||||
""");
|
""");
|
||||||
}
|
|
||||||
|
|
||||||
public static void GreetSettingsCopy(MigrationBuilder builder)
|
builder.Sql($"""
|
||||||
{
|
DELETE FROM "DelMsgOnCmdChannel" WHERE "GuildConfigId" is NULL;
|
||||||
|
""");
|
||||||
|
|
||||||
builder.Sql("""
|
builder.Sql("""
|
||||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
DELETE FROM "WarningPunishment" WHERE "GuildConfigId" NOT IN (SELECT "Id" from "GuildConfigs");
|
||||||
SELECT GuildId, 0, ChannelGreetMessageText, SendChannelGreetMessage, GreetMessageChannelId, AutoDeleteGreetMessagesTimer
|
|
||||||
FROM GuildConfigs
|
|
||||||
WHERE SendChannelGreetMessage = TRUE;
|
|
||||||
|
|
||||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
|
||||||
SELECT GuildId, 1, DmGreetMessageText, SendDmGreetMessage, GreetMessageChannelId, 0
|
|
||||||
FROM GuildConfigs
|
|
||||||
WHERE SendDmGreetMessage = TRUE;
|
|
||||||
|
|
||||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
|
||||||
SELECT GuildId, 2, ChannelByeMessageText, SendChannelByeMessage, ByeMessageChannelId, AutoDeleteByeMessagesTimer
|
|
||||||
FROM GuildConfigs
|
|
||||||
WHERE SendChannelByeMessage = TRUE;
|
|
||||||
|
|
||||||
INSERT INTO GreetSettings (GuildId, GreetType, MessageText, IsEnabled, ChannelId, AutoDeleteTimer)
|
|
||||||
SELECT GuildId, 3, BoostMessage, SendBoostMessage, BoostMessageChannelId, BoostMessageDeleteAfter
|
|
||||||
FROM GuildConfigs
|
|
||||||
WHERE SendBoostMessage = TRUE;
|
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
}
|
}
|
3425
src/EllieBot/Migrations/Mysql/20220409170652_mysql-init.Designer.cs
generated
Normal file
3425
src/EllieBot/Migrations/Mysql/20220409170652_mysql-init.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
2342
src/EllieBot/Migrations/Mysql/20220409170652_mysql-init.cs
Normal file
2342
src/EllieBot/Migrations/Mysql/20220409170652_mysql-init.cs
Normal file
File diff suppressed because it is too large
Load diff
3429
src/EllieBot/Migrations/Mysql/20220428044612_stondel.Designer.cs
generated
Normal file
3429
src/EllieBot/Migrations/Mysql/20220428044612_stondel.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
26
src/EllieBot/Migrations/Mysql/20220428044612_stondel.cs
Normal file
26
src/EllieBot/Migrations/Mysql/20220428044612_stondel.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class stondel : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "deletestreamonlinemessage",
|
||||||
|
table: "guildconfigs",
|
||||||
|
type: "tinyint(1)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "deletestreamonlinemessage",
|
||||||
|
table: "guildconfigs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3458
src/EllieBot/Migrations/Mysql/20220429044757_bank.Designer.cs
generated
Normal file
3458
src/EllieBot/Migrations/Mysql/20220429044757_bank.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
41
src/EllieBot/Migrations/Mysql/20220429044757_bank.cs
Normal file
41
src/EllieBot/Migrations/Mysql/20220429044757_bank.cs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class bank : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "bankusers",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
userid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
balance = table.Column<long>(type: "bigint", nullable: false),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_bankusers", x => x.id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_bankusers_userid",
|
||||||
|
table: "bankusers",
|
||||||
|
column: "userid",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "bankusers");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3411
src/EllieBot/Migrations/Mysql/20220504162509_new-rero.Designer.cs
generated
Normal file
3411
src/EllieBot/Migrations/Mysql/20220504162509_new-rero.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
120
src/EllieBot/Migrations/Mysql/20220504162509_new-rero.cs
Normal file
120
src/EllieBot/Migrations/Mysql/20220504162509_new-rero.cs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class newrero : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "reactionroles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
guildid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
channelid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
messageid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
emote = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
roleid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
group = table.Column<int>(type: "int", nullable: false),
|
||||||
|
levelreq = table.Column<int>(type: "int", nullable: false),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_reactionroles", x => x.id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_reactionroles_guildid",
|
||||||
|
table: "reactionroles",
|
||||||
|
column: "guildid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_reactionroles_messageid_emote",
|
||||||
|
table: "reactionroles",
|
||||||
|
columns: new[] { "messageid", "emote" },
|
||||||
|
unique: true);
|
||||||
|
|
||||||
|
MigrationQueries.MigrateRero(migrationBuilder);
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "reactionrole");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "reactionrolemessage");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "reactionroles");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "reactionrolemessage",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
guildconfigid = table.Column<int>(type: "int", nullable: false),
|
||||||
|
channelid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||||
|
exclusive = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
|
index = table.Column<int>(type: "int", nullable: false),
|
||||||
|
messageid = table.Column<ulong>(type: "bigint unsigned", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_reactionrolemessage", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_reactionrolemessage_guildconfigs_guildconfigid",
|
||||||
|
column: x => x.guildconfigid,
|
||||||
|
principalTable: "guildconfigs",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "reactionrole",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true),
|
||||||
|
emotename = table.Column<string>(type: "longtext", nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
reactionrolemessageid = table.Column<int>(type: "int", nullable: true),
|
||||||
|
roleid = table.Column<ulong>(type: "bigint unsigned", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_reactionrole", x => x.id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_reactionrole_reactionrolemessage_reactionrolemessageid",
|
||||||
|
column: x => x.reactionrolemessageid,
|
||||||
|
principalTable: "reactionrolemessage",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_reactionrole_reactionrolemessageid",
|
||||||
|
table: "reactionrole",
|
||||||
|
column: "reactionrolemessageid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_reactionrolemessage_guildconfigid",
|
||||||
|
table: "reactionrolemessage",
|
||||||
|
column: "guildconfigid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3481
src/EllieBot/Migrations/Mysql/20220614071410_patronage-system.Designer.cs
generated
Normal file
3481
src/EllieBot/Migrations/Mysql/20220614071410_patronage-system.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
175
src/EllieBot/Migrations/Mysql/20220614071410_patronage-system.cs
Normal file
175
src/EllieBot/Migrations/Mysql/20220614071410_patronage-system.cs
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class patronagesystem : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "patreonuserid",
|
||||||
|
table: "rewardedusers",
|
||||||
|
newName: "platformuserid");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "ix_rewardedusers_patreonuserid",
|
||||||
|
table: "rewardedusers",
|
||||||
|
newName: "ix_rewardedusers_platformuserid");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "xp",
|
||||||
|
table: "userxpstats",
|
||||||
|
type: "bigint",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "awardedxp",
|
||||||
|
table: "userxpstats",
|
||||||
|
type: "bigint",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "amountrewardedthismonth",
|
||||||
|
table: "rewardedusers",
|
||||||
|
type: "bigint",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<bool>(
|
||||||
|
name: "verboseerrors",
|
||||||
|
table: "guildconfigs",
|
||||||
|
type: "tinyint(1)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: true,
|
||||||
|
oldClrType: typeof(bool),
|
||||||
|
oldType: "tinyint(1)");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<long>(
|
||||||
|
name: "totalxp",
|
||||||
|
table: "discorduser",
|
||||||
|
type: "bigint",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0L,
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int",
|
||||||
|
oldDefaultValue: 0);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "patronquotas",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
userid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
featuretype = table.Column<int>(type: "int", nullable: false),
|
||||||
|
feature = table.Column<string>(type: "varchar(255)", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
hourlycount = table.Column<uint>(type: "int unsigned", nullable: false),
|
||||||
|
dailycount = table.Column<uint>(type: "int unsigned", nullable: false),
|
||||||
|
monthlycount = table.Column<uint>(type: "int unsigned", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_patronquotas", x => new { x.userid, x.featuretype, x.feature });
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "patrons",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
userid = table.Column<ulong>(type: "bigint unsigned", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
uniqueplatformuserid = table.Column<string>(type: "varchar(255)", nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
amountcents = table.Column<int>(type: "int", nullable: false),
|
||||||
|
lastcharge = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||||
|
validthru = table.Column<DateTime>(type: "datetime(6)", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_patrons", x => x.userid);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_patronquotas_userid",
|
||||||
|
table: "patronquotas",
|
||||||
|
column: "userid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_patrons_uniqueplatformuserid",
|
||||||
|
table: "patrons",
|
||||||
|
column: "uniqueplatformuserid",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "patronquotas");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "patrons");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "platformuserid",
|
||||||
|
table: "rewardedusers",
|
||||||
|
newName: "patreonuserid");
|
||||||
|
|
||||||
|
migrationBuilder.RenameIndex(
|
||||||
|
name: "ix_rewardedusers_platformuserid",
|
||||||
|
table: "rewardedusers",
|
||||||
|
newName: "ix_rewardedusers_patreonuserid");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "xp",
|
||||||
|
table: "userxpstats",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(long),
|
||||||
|
oldType: "bigint");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "awardedxp",
|
||||||
|
table: "userxpstats",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(long),
|
||||||
|
oldType: "bigint");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "amountrewardedthismonth",
|
||||||
|
table: "rewardedusers",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(long),
|
||||||
|
oldType: "bigint");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<bool>(
|
||||||
|
name: "verboseerrors",
|
||||||
|
table: "guildconfigs",
|
||||||
|
type: "tinyint(1)",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(bool),
|
||||||
|
oldType: "tinyint(1)",
|
||||||
|
oldDefaultValue: true);
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "totalxp",
|
||||||
|
table: "discorduser",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0,
|
||||||
|
oldClrType: typeof(long),
|
||||||
|
oldType: "bigint",
|
||||||
|
oldDefaultValue: 0L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3514
src/EllieBot/Migrations/Mysql/20220623090718_stondel-db-cache.Designer.cs
generated
Normal file
3514
src/EllieBot/Migrations/Mysql/20220623090718_stondel-db-cache.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,38 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class stondeldbcache : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "streamonlinemessages",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
channelid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
messageid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
type = table.Column<int>(type: "int", nullable: false),
|
||||||
|
name = table.Column<string>(type: "longtext", nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_streamonlinemessages", x => x.id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "streamonlinemessages");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3518
src/EllieBot/Migrations/Mysql/20220703194400_logwarns.Designer.cs
generated
Normal file
3518
src/EllieBot/Migrations/Mysql/20220703194400_logwarns.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
25
src/EllieBot/Migrations/Mysql/20220703194400_logwarns.cs
Normal file
25
src/EllieBot/Migrations/Mysql/20220703194400_logwarns.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class logwarns : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<ulong>(
|
||||||
|
name: "logwarnsid",
|
||||||
|
table: "logsettings",
|
||||||
|
type: "bigint unsigned",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "logwarnsid",
|
||||||
|
table: "logsettings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3556
src/EllieBot/Migrations/Mysql/20220725155953_xpitemshop.Designer.cs
generated
Normal file
3556
src/EllieBot/Migrations/Mysql/20220725155953_xpitemshop.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
44
src/EllieBot/Migrations/Mysql/20220725155953_xpitemshop.cs
Normal file
44
src/EllieBot/Migrations/Mysql/20220725155953_xpitemshop.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class xpitemshop : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "xpshopowneditem",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
userid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
itemtype = table.Column<int>(type: "int", nullable: false),
|
||||||
|
isusing = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||||
|
itemkey = table.Column<string>(type: "varchar(255)", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_xpshopowneditem", x => x.id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_xpshopowneditem_userid_itemtype_itemkey",
|
||||||
|
table: "xpshopowneditem",
|
||||||
|
columns: new[] { "userid", "itemtype", "itemkey" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "xpshopowneditem");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3560
src/EllieBot/Migrations/Mysql/20220727033931_linkonly-channels.Designer.cs
generated
Normal file
3560
src/EllieBot/Migrations/Mysql/20220727033931_linkonly-channels.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,26 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class linkonlychannels : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "type",
|
||||||
|
table: "imageonlychannels",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "type",
|
||||||
|
table: "imageonlychannels");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3542
src/EllieBot/Migrations/Mysql/20220808141855_remove-obsolete-xp-columns.Designer.cs
generated
Normal file
3542
src/EllieBot/Migrations/Mysql/20220808141855_remove-obsolete-xp-columns.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,48 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class removeobsoletexpcolumns : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "lastlevelup",
|
||||||
|
table: "userxpstats");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "lastlevelup",
|
||||||
|
table: "discorduser");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "lastxpgain",
|
||||||
|
table: "discorduser");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "lastlevelup",
|
||||||
|
table: "userxpstats",
|
||||||
|
type: "datetime(6)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "(UTC_TIMESTAMP)");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "lastlevelup",
|
||||||
|
table: "discorduser",
|
||||||
|
type: "datetime(6)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "(UTC_TIMESTAMP)");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "lastxpgain",
|
||||||
|
table: "discorduser",
|
||||||
|
type: "datetime(6)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "(UTC_TIMESTAMP - INTERVAL 1 year)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3546
src/EllieBot/Migrations/Mysql/20220831142722_banprune.Designer.cs
generated
Normal file
3546
src/EllieBot/Migrations/Mysql/20220831142722_banprune.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
25
src/EllieBot/Migrations/Mysql/20220831142722_banprune.cs
Normal file
25
src/EllieBot/Migrations/Mysql/20220831142722_banprune.cs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class banprune : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "prunedays",
|
||||||
|
table: "bantemplates",
|
||||||
|
type: "int",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "prunedays",
|
||||||
|
table: "bantemplates");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3550
src/EllieBot/Migrations/Mysql/20220913192520_shop-role-req.Designer.cs
generated
Normal file
3550
src/EllieBot/Migrations/Mysql/20220913192520_shop-role-req.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,25 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class shoprolereq : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<ulong>(
|
||||||
|
name: "rolerequirement",
|
||||||
|
table: "shopentry",
|
||||||
|
type: "bigint unsigned",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "rolerequirement",
|
||||||
|
table: "shopentry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3579
src/EllieBot/Migrations/Mysql/20220916194514_autopub.Designer.cs
generated
Normal file
3579
src/EllieBot/Migrations/Mysql/20220916194514_autopub.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
41
src/EllieBot/Migrations/Mysql/20220916194514_autopub.cs
Normal file
41
src/EllieBot/Migrations/Mysql/20220916194514_autopub.cs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class autopub : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "autopublishchannel",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
guildid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
channelid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_autopublishchannel", x => x.id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_autopublishchannel_guildid",
|
||||||
|
table: "autopublishchannel",
|
||||||
|
column: "guildid",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "autopublishchannel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3612
src/EllieBot/Migrations/Mysql/20221003175743_gambling-stats.Designer.cs
generated
Normal file
3612
src/EllieBot/Migrations/Mysql/20221003175743_gambling-stats.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,43 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class gamblingstats : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "gamblingstats",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
feature = table.Column<string>(type: "varchar(255)", nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
bet = table.Column<decimal>(type: "decimal(65,30)", nullable: false),
|
||||||
|
paidout = table.Column<decimal>(type: "decimal(65,30)", nullable: false),
|
||||||
|
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_gamblingstats", x => x.id);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_gamblingstats_feature",
|
||||||
|
table: "gamblingstats",
|
||||||
|
column: "feature",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "gamblingstats");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3616
src/EllieBot/Migrations/Mysql/20221021192758_toggle-global-expressions.Designer.cs
generated
Normal file
3616
src/EllieBot/Migrations/Mysql/20221021192758_toggle-global-expressions.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,26 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class toggleglobalexpressions : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "disableglobalexpressions",
|
||||||
|
table: "guildconfigs",
|
||||||
|
type: "tinyint(1)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "disableglobalexpressions",
|
||||||
|
table: "guildconfigs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3624
src/EllieBot/Migrations/Mysql/20221118195208_log-thread.Designer.cs
generated
Normal file
3624
src/EllieBot/Migrations/Mysql/20221118195208_log-thread.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
35
src/EllieBot/Migrations/Mysql/20221118195208_log-thread.cs
Normal file
35
src/EllieBot/Migrations/Mysql/20221118195208_log-thread.cs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class logthread : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<ulong>(
|
||||||
|
name: "threadcreatedid",
|
||||||
|
table: "logsettings",
|
||||||
|
type: "bigint unsigned",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<ulong>(
|
||||||
|
name: "threaddeletedid",
|
||||||
|
table: "logsettings",
|
||||||
|
type: "bigint unsigned",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "threadcreatedid",
|
||||||
|
table: "logsettings");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "threaddeletedid",
|
||||||
|
table: "logsettings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3628
src/EllieBot/Migrations/Mysql/20221122204432_feed-text.Designer.cs
generated
Normal file
3628
src/EllieBot/Migrations/Mysql/20221122204432_feed-text.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
26
src/EllieBot/Migrations/Mysql/20221122204432_feed-text.cs
Normal file
26
src/EllieBot/Migrations/Mysql/20221122204432_feed-text.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
public partial class feedtext : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "message",
|
||||||
|
table: "feedsub",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "message",
|
||||||
|
table: "feedsub");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3830
src/EllieBot/Migrations/Mysql/20240502233216_v5.Designer.cs
generated
Normal file
3830
src/EllieBot/Migrations/Mysql/20240502233216_v5.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
1614
src/EllieBot/Migrations/Mysql/20240502233216_v5.cs
Normal file
1614
src/EllieBot/Migrations/Mysql/20240502233216_v5.cs
Normal file
File diff suppressed because it is too large
Load diff
3819
src/EllieBot/Migrations/Mysql/20240518221440_guidlconfig-cleanup.Designer.cs
generated
Normal file
3819
src/EllieBot/Migrations/Mysql/20240518221440_guidlconfig-cleanup.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,702 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3784
src/EllieBot/Migrations/Mysql/20240611180516_remove-patron-limits.Designer.cs
generated
Normal file
3784
src/EllieBot/Migrations/Mysql/20240611180516_remove-patron-limits.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,44 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class removepatronlimits : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "patronquotas");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "patronquotas",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
userid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
|
||||||
|
featuretype = table.Column<int>(type: "int", nullable: false),
|
||||||
|
feature = table.Column<string>(type: "varchar(255)", nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||||
|
dailycount = table.Column<uint>(type: "int unsigned", nullable: false),
|
||||||
|
hourlycount = table.Column<uint>(type: "int unsigned", nullable: false),
|
||||||
|
monthlycount = table.Column<uint>(type: "int unsigned", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_patronquotas", x => new { x.userid, x.featuretype, x.feature });
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_patronquotas_userid",
|
||||||
|
table: "patronquotas",
|
||||||
|
column: "userid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
36
src/EllieBot/Migrations/Mysql/20240627033532_honeypot.cs
Normal file
36
src/EllieBot/Migrations/Mysql/20240627033532_honeypot.cs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace EllieBot.Migrations.Mysql
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class honeypot : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "honeypotchannels",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
guildid = table.Column<ulong>(type: "bigint unsigned", nullable: false)
|
||||||
|
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||||
|
channelid = table.Column<ulong>(type: "bigint unsigned", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_honeypotchannels", x => x.guildid);
|
||||||
|
})
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "honeypotchannels");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3800
src/EllieBot/Migrations/Mysql/MysqlContextModelSnapshot.cs
Normal file
3800
src/EllieBot/Migrations/Mysql/MysqlContextModelSnapshot.cs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,12 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
{
|
{
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
|
migrationBuilder.AddColumn<decimal>(
|
||||||
|
name: "rolerequirement",
|
||||||
|
table: "shopentry",
|
||||||
|
type: "numeric(20,0)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "autopublishchannel",
|
name: "autopublishchannel",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
|
@ -35,6 +41,10 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
{
|
{
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "autopublishchannel");
|
name: "autopublishchannel");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "rolerequirement",
|
||||||
|
table: "shopentry");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3795,4 +3795,4 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,199 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace EllieBot.Migrations.PostgreSql
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class greetsettings : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "greetsettings",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
id = table.Column<int>(type: "integer", nullable: false)
|
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy",
|
|
||||||
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
|
||||||
guildid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
|
|
||||||
greettype = table.Column<int>(type: "integer", nullable: false),
|
|
||||||
messagetext = table.Column<string>(type: "text", nullable: true),
|
|
||||||
isenabled = table.Column<bool>(type: "boolean", nullable: false, defaultValue: false),
|
|
||||||
channelid = table.Column<decimal>(type: "numeric(20,0)", nullable: true),
|
|
||||||
autodeletetimer = table.Column<int>(type: "integer", nullable: false, defaultValue: 0)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("pk_greetsettings", x => x.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "ix_greetsettings_guildid_greettype",
|
|
||||||
table: "greetsettings",
|
|
||||||
columns: new[] { "guildid", "greettype" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
MigrationQueries.GreetSettingsCopy(migrationBuilder);
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "autodeletebyemessagestimer",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "autodeletegreetmessagestimer",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "boostmessage",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "boostmessagechannelid",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "boostmessagedeleteafter",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "byemessagechannelid",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "channelbyemessagetext",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "channelgreetmessagetext",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "dmgreetmessagetext",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "greetmessagechannelid",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "sendboostmessage",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "sendchannelbyemessage",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "sendchannelgreetmessage",
|
|
||||||
table: "guildconfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "senddmgreetmessage",
|
|
||||||
table: "guildconfigs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "greetsettings");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "autodeletebyemessagestimer",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "integer",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "autodeletegreetmessagestimer",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "integer",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "boostmessage",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<decimal>(
|
|
||||||
name: "boostmessagechannelid",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "numeric(20,0)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0m);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "boostmessagedeleteafter",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "integer",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<decimal>(
|
|
||||||
name: "byemessagechannelid",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "numeric(20,0)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0m);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "channelbyemessagetext",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "channelgreetmessagetext",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "dmgreetmessagetext",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "text",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<decimal>(
|
|
||||||
name: "greetmessagechannelid",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "numeric(20,0)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0m);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "sendboostmessage",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "sendchannelbyemessage",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "sendchannelgreetmessage",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "senddmgreetmessage",
|
|
||||||
table: "guildconfigs",
|
|
||||||
type: "boolean",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,7 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "8.0.8")
|
.HasAnnotation("ProductVersion", "8.0.4")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
@ -1220,10 +1220,42 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("autoassignroleids");
|
.HasColumnName("autoassignroleids");
|
||||||
|
|
||||||
|
b.Property<int>("AutoDeleteByeMessagesTimer")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("autodeletebyemessagestimer");
|
||||||
|
|
||||||
|
b.Property<int>("AutoDeleteGreetMessagesTimer")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("autodeletegreetmessagestimer");
|
||||||
|
|
||||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages")
|
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("autodeleteselfassignedrolemessages");
|
.HasColumnName("autodeleteselfassignedrolemessages");
|
||||||
|
|
||||||
|
b.Property<string>("BoostMessage")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("boostmessage");
|
||||||
|
|
||||||
|
b.Property<decimal>("BoostMessageChannelId")
|
||||||
|
.HasColumnType("numeric(20,0)")
|
||||||
|
.HasColumnName("boostmessagechannelid");
|
||||||
|
|
||||||
|
b.Property<int>("BoostMessageDeleteAfter")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("boostmessagedeleteafter");
|
||||||
|
|
||||||
|
b.Property<decimal>("ByeMessageChannelId")
|
||||||
|
.HasColumnType("numeric(20,0)")
|
||||||
|
.HasColumnName("byemessagechannelid");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelByeMessageText")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("channelbyemessagetext");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelGreetMessageText")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("channelgreetmessagetext");
|
||||||
|
|
||||||
b.Property<bool>("CleverbotEnabled")
|
b.Property<bool>("CleverbotEnabled")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("cleverbotenabled");
|
.HasColumnName("cleverbotenabled");
|
||||||
|
@ -1244,6 +1276,10 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("disableglobalexpressions");
|
.HasColumnName("disableglobalexpressions");
|
||||||
|
|
||||||
|
b.Property<string>("DmGreetMessageText")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("dmgreetmessagetext");
|
||||||
|
|
||||||
b.Property<bool>("ExclusiveSelfAssignedRoles")
|
b.Property<bool>("ExclusiveSelfAssignedRoles")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("exclusiveselfassignedroles");
|
.HasColumnName("exclusiveselfassignedroles");
|
||||||
|
@ -1264,6 +1300,10 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
.HasColumnType("numeric(20,0)")
|
.HasColumnType("numeric(20,0)")
|
||||||
.HasColumnName("gamevoicechannel");
|
.HasColumnName("gamevoicechannel");
|
||||||
|
|
||||||
|
b.Property<decimal>("GreetMessageChannelId")
|
||||||
|
.HasColumnType("numeric(20,0)")
|
||||||
|
.HasColumnName("greetmessagechannelid");
|
||||||
|
|
||||||
b.Property<decimal>("GuildId")
|
b.Property<decimal>("GuildId")
|
||||||
.HasColumnType("numeric(20,0)")
|
.HasColumnType("numeric(20,0)")
|
||||||
.HasColumnName("guildid");
|
.HasColumnName("guildid");
|
||||||
|
@ -1288,6 +1328,22 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("prefix");
|
.HasColumnName("prefix");
|
||||||
|
|
||||||
|
b.Property<bool>("SendBoostMessage")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("sendboostmessage");
|
||||||
|
|
||||||
|
b.Property<bool>("SendChannelByeMessage")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("sendchannelbyemessage");
|
||||||
|
|
||||||
|
b.Property<bool>("SendChannelGreetMessage")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("sendchannelgreetmessage");
|
||||||
|
|
||||||
|
b.Property<bool>("SendDmGreetMessage")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("senddmgreetmessage");
|
||||||
|
|
||||||
b.Property<bool>("StickyRoles")
|
b.Property<bool>("StickyRoles")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("stickyroles");
|
.HasColumnName("stickyroles");
|
||||||
|
@ -3107,53 +3163,6 @@ namespace EllieBot.Migrations.PostgreSql
|
||||||
b.ToTable("xpshopowneditem", (string)null);
|
b.ToTable("xpshopowneditem", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Services.GreetSettings", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("id");
|
|
||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
|
||||||
|
|
||||||
b.Property<int>("AutoDeleteTimer")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasDefaultValue(0)
|
|
||||||
.HasColumnName("autodeletetimer");
|
|
||||||
|
|
||||||
b.Property<decimal?>("ChannelId")
|
|
||||||
.HasColumnType("numeric(20,0)")
|
|
||||||
.HasColumnName("channelid");
|
|
||||||
|
|
||||||
b.Property<int>("GreetType")
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("greettype");
|
|
||||||
|
|
||||||
b.Property<decimal>("GuildId")
|
|
||||||
.HasColumnType("numeric(20,0)")
|
|
||||||
.HasColumnName("guildid");
|
|
||||||
|
|
||||||
b.Property<bool>("IsEnabled")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasDefaultValue(false)
|
|
||||||
.HasColumnName("isenabled");
|
|
||||||
|
|
||||||
b.Property<string>("MessageText")
|
|
||||||
.HasColumnType("text")
|
|
||||||
.HasColumnName("messagetext");
|
|
||||||
|
|
||||||
b.HasKey("Id")
|
|
||||||
.HasName("pk_greetsettings");
|
|
||||||
|
|
||||||
b.HasIndex("GuildId", "GreetType")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("ix_greetsettings_guildid_greettype");
|
|
||||||
|
|
||||||
b.ToTable("greetsettings", (string)null);
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Db.Models.AntiAltSetting", b =>
|
modelBuilder.Entity("EllieBot.Db.Models.AntiAltSetting", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,197 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace EllieBot.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class greetsettings : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "GreetSettings",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
|
||||||
.Annotation("Sqlite:Autoincrement", true),
|
|
||||||
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
|
||||||
GreetType = table.Column<int>(type: "INTEGER", nullable: false),
|
|
||||||
MessageText = table.Column<string>(type: "TEXT", nullable: true),
|
|
||||||
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
|
|
||||||
ChannelId = table.Column<ulong>(type: "INTEGER", nullable: true),
|
|
||||||
AutoDeleteTimer = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 0)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_GreetSettings", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_GreetSettings_GuildId_GreetType",
|
|
||||||
table: "GreetSettings",
|
|
||||||
columns: new[] { "GuildId", "GreetType" },
|
|
||||||
unique: true);
|
|
||||||
|
|
||||||
MigrationQueries.GreetSettingsCopy(migrationBuilder);
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "AutoDeleteByeMessagesTimer",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "AutoDeleteGreetMessagesTimer",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "BoostMessage",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "BoostMessageChannelId",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "BoostMessageDeleteAfter",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ByeMessageChannelId",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ChannelByeMessageText",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ChannelGreetMessageText",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "DmGreetMessageText",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "GreetMessageChannelId",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "SendBoostMessage",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "SendChannelByeMessage",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "SendChannelGreetMessage",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "SendDmGreetMessage",
|
|
||||||
table: "GuildConfigs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "GreetSettings");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "AutoDeleteByeMessagesTimer",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "AutoDeleteGreetMessagesTimer",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "BoostMessage",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "TEXT",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<ulong>(
|
|
||||||
name: "BoostMessageChannelId",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0ul);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<int>(
|
|
||||||
name: "BoostMessageDeleteAfter",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<ulong>(
|
|
||||||
name: "ByeMessageChannelId",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0ul);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "ChannelByeMessageText",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "TEXT",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "ChannelGreetMessageText",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "TEXT",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<string>(
|
|
||||||
name: "DmGreetMessageText",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "TEXT",
|
|
||||||
nullable: true);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<ulong>(
|
|
||||||
name: "GreetMessageChannelId",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: 0ul);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "SendBoostMessage",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "SendChannelByeMessage",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "SendChannelGreetMessage",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<bool>(
|
|
||||||
name: "SendDmGreetMessage",
|
|
||||||
table: "GuildConfigs",
|
|
||||||
type: "INTEGER",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,7 +15,7 @@ namespace EllieBot.Migrations
|
||||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.8");
|
modelBuilder.HasAnnotation("ProductVersion", "8.0.4");
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Db.Models.AntiAltSetting", b =>
|
modelBuilder.Entity("EllieBot.Db.Models.AntiAltSetting", b =>
|
||||||
{
|
{
|
||||||
|
@ -907,9 +907,33 @@ namespace EllieBot.Migrations
|
||||||
b.Property<string>("AutoAssignRoleIds")
|
b.Property<string>("AutoAssignRoleIds")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("AutoDeleteByeMessagesTimer")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AutoDeleteGreetMessagesTimer")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages")
|
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("BoostMessage")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<ulong>("BoostMessageChannelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("BoostMessageDeleteAfter")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<ulong>("ByeMessageChannelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelByeMessageText")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("ChannelGreetMessageText")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<bool>("CleverbotEnabled")
|
b.Property<bool>("CleverbotEnabled")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
@ -925,6 +949,9 @@ namespace EllieBot.Migrations
|
||||||
b.Property<bool>("DisableGlobalExpressions")
|
b.Property<bool>("DisableGlobalExpressions")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("DmGreetMessageText")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
b.Property<bool>("ExclusiveSelfAssignedRoles")
|
b.Property<bool>("ExclusiveSelfAssignedRoles")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
@ -940,6 +967,9 @@ namespace EllieBot.Migrations
|
||||||
b.Property<ulong?>("GameVoiceChannel")
|
b.Property<ulong?>("GameVoiceChannel")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<ulong>("GreetMessageChannelId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<ulong>("GuildId")
|
b.Property<ulong>("GuildId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
@ -958,6 +988,18 @@ namespace EllieBot.Migrations
|
||||||
b.Property<string>("Prefix")
|
b.Property<string>("Prefix")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("SendBoostMessage")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("SendChannelByeMessage")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("SendChannelGreetMessage")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("SendDmGreetMessage")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<bool>("StickyRoles")
|
b.Property<bool>("StickyRoles")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
@ -2309,42 +2351,6 @@ namespace EllieBot.Migrations
|
||||||
b.ToTable("XpShopOwnedItem");
|
b.ToTable("XpShopOwnedItem");
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Services.GreetSettings", b =>
|
|
||||||
{
|
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<int>("AutoDeleteTimer")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER")
|
|
||||||
.HasDefaultValue(0);
|
|
||||||
|
|
||||||
b.Property<ulong?>("ChannelId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<int>("GreetType")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<ulong>("GuildId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<bool>("IsEnabled")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("INTEGER")
|
|
||||||
.HasDefaultValue(false);
|
|
||||||
|
|
||||||
b.Property<string>("MessageText")
|
|
||||||
.HasColumnType("TEXT");
|
|
||||||
|
|
||||||
b.HasKey("Id");
|
|
||||||
|
|
||||||
b.HasIndex("GuildId", "GreetType")
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
b.ToTable("GreetSettings");
|
|
||||||
});
|
|
||||||
|
|
||||||
modelBuilder.Entity("EllieBot.Db.Models.AntiAltSetting", b =>
|
modelBuilder.Entity("EllieBot.Db.Models.AntiAltSetting", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
b.HasOne("EllieBot.Db.Models.GuildConfig", null)
|
||||||
|
|
|
@ -36,8 +36,6 @@ public class AutoPublishService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
RetryMode = RetryMode.AlwaysFail
|
RetryMode = RetryMode.AlwaysFail
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo GUILDS
|
|
||||||
|
|
||||||
public async Task OnReadyAsync()
|
public async Task OnReadyAsync()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
using EllieBot.Modules.Administration.DangerousCommands;
|
namespace EllieBot.Modules.Administration.DangerousCommands;
|
||||||
|
|
||||||
namespace EllieBot.Modules.Administration;
|
public partial class Administration
|
||||||
|
|
||||||
public partial class Administration
|
|
||||||
{
|
{
|
||||||
[Group]
|
[Group]
|
||||||
public partial class CleanupCommands : CleanupModuleBase
|
public class CleanupCommands : CleanupModuleBase
|
||||||
{
|
{
|
||||||
private readonly ICleanupService _svc;
|
private readonly ICleanupService _svc;
|
||||||
private readonly IBotCredsProvider _creds;
|
|
||||||
|
|
||||||
public CleanupCommands(ICleanupService svc, IBotCredsProvider creds)
|
public CleanupCommands(ICleanupService svc)
|
||||||
{
|
=> _svc = svc;
|
||||||
_svc = svc;
|
|
||||||
_creds = creds;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
|
@ -43,32 +37,5 @@ public partial class Administration
|
||||||
|
|
||||||
await Response().Text("This guild's bot data will be saved.").SendAsync();
|
await Response().Text("This guild's bot data will be saved.").SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[OwnerOnly]
|
|
||||||
public async Task LeaveUnkeptServers(int startShardId, int shardMultiplier = 3000)
|
|
||||||
{
|
|
||||||
var keptGuildCount = await _svc.GetKeptGuildCount();
|
|
||||||
|
|
||||||
var response = await PromptUserConfirmAsync(new EmbedBuilder()
|
|
||||||
.WithDescription($"""
|
|
||||||
Do you want the bot to leave all unkept servers?
|
|
||||||
|
|
||||||
There are currently {keptGuildCount} kept servers.
|
|
||||||
|
|
||||||
**This is a highly destructive and irreversible action.**
|
|
||||||
"""));
|
|
||||||
|
|
||||||
if (!response)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var shardId = startShardId; shardId < _creds.GetCreds().TotalShards; shardId++)
|
|
||||||
{
|
|
||||||
await _svc.StartLeavingUnkeptServers(shardId);
|
|
||||||
await Task.Delay(shardMultiplier * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
await ctx.OkAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,12 +9,9 @@ namespace EllieBot.Modules.Administration.DangerousCommands;
|
||||||
|
|
||||||
public sealed class CleanupService : ICleanupService, IReadyExecutor, IEService
|
public sealed class CleanupService : ICleanupService, IReadyExecutor, IEService
|
||||||
{
|
{
|
||||||
private TypedKey<KeepReport> _cleanupReportKey = new("cleanup:report");
|
|
||||||
private TypedKey<bool> _cleanupTriggerKey = new("cleanup:trigger");
|
|
||||||
|
|
||||||
private TypedKey<int> _keepTriggerKey = new("keep:trigger");
|
|
||||||
|
|
||||||
private readonly IPubSub _pubSub;
|
private readonly IPubSub _pubSub;
|
||||||
|
private TypedKey<KeepReport> _keepReportKey = new("cleanup:report");
|
||||||
|
private TypedKey<bool> _keepTriggerKey = new("cleanup:trigger");
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private ConcurrentDictionary<int, ulong[]> guildIds = new();
|
private ConcurrentDictionary<int, ulong[]> guildIds = new();
|
||||||
private readonly IBotCredsProvider _creds;
|
private readonly IBotCredsProvider _creds;
|
||||||
|
@ -32,90 +29,11 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, IEService
|
||||||
_db = db;
|
_db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnReadyAsync()
|
|
||||||
{
|
|
||||||
await _pubSub.Sub(_cleanupTriggerKey, OnCleanupTrigger);
|
|
||||||
await _pubSub.Sub(_keepTriggerKey, InternalTriggerKeep);
|
|
||||||
|
|
||||||
_client.JoinedGuild += ClientOnJoinedGuild;
|
|
||||||
|
|
||||||
if (_client.ShardId == 0)
|
|
||||||
await _pubSub.Sub(_cleanupReportKey, OnKeepReport);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool keepTriggered = false;
|
|
||||||
|
|
||||||
private async ValueTask InternalTriggerKeep(int shardId)
|
|
||||||
{
|
|
||||||
if (_client.ShardId != shardId)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (keepTriggered)
|
|
||||||
return;
|
|
||||||
|
|
||||||
keepTriggered = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var allGuildIds = _client.Guilds.Select(x => x.Id).ToArray();
|
|
||||||
|
|
||||||
HashSet<ulong> dontDelete;
|
|
||||||
await using (var db = _db.GetDbContext())
|
|
||||||
{
|
|
||||||
await using var ctx = db.CreateLinqToDBContext();
|
|
||||||
var table = ctx.CreateTable<KeptGuilds>(tableOptions: TableOptions.CheckExistence);
|
|
||||||
|
|
||||||
var dontDeleteList = await table
|
|
||||||
.Where(x => allGuildIds.Contains(x.GuildId))
|
|
||||||
.Select(x => x.GuildId)
|
|
||||||
.ToListAsyncLinqToDB();
|
|
||||||
|
|
||||||
dontDelete = dontDeleteList.ToHashSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.Information("Leaving {RemainingCount} guilds, 1 every second. {DontDeleteCount} will remain",
|
|
||||||
allGuildIds.Length - dontDelete.Count,
|
|
||||||
dontDelete.Count);
|
|
||||||
|
|
||||||
foreach (var guildId in allGuildIds)
|
|
||||||
{
|
|
||||||
if (dontDelete.Contains(guildId))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
await Task.Delay(1016);
|
|
||||||
|
|
||||||
SocketGuild? guild = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
guild = _client.GetGuild(guildId);
|
|
||||||
|
|
||||||
if (guild is null)
|
|
||||||
{
|
|
||||||
Log.Warning("Unable to find guild {GuildId}", guildId);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
await guild.LeaveAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Warning("Unable to leave guild {GuildName} [{GuildId}]: {ErrorMessage}",
|
|
||||||
guild?.Name,
|
|
||||||
guildId,
|
|
||||||
ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
keepTriggered = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<KeepResult?> DeleteMissingGuildDataAsync()
|
public async Task<KeepResult?> DeleteMissingGuildDataAsync()
|
||||||
{
|
{
|
||||||
guildIds = new();
|
guildIds = new();
|
||||||
var totalShards = _creds.GetCreds().TotalShards;
|
var totalShards = _creds.GetCreds().TotalShards;
|
||||||
await _pubSub.Pub(_cleanupTriggerKey, true);
|
await _pubSub.Pub(_keepTriggerKey, true);
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
while (guildIds.Keys.Count < totalShards)
|
while (guildIds.Keys.Count < totalShards)
|
||||||
{
|
{
|
||||||
|
@ -217,7 +135,9 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, IEService
|
||||||
{
|
{
|
||||||
await using var db = _db.GetDbContext();
|
await using var db = _db.GetDbContext();
|
||||||
await using var ctx = db.CreateLinqToDBContext();
|
await using var ctx = db.CreateLinqToDBContext();
|
||||||
|
|
||||||
var table = ctx.CreateTable<KeptGuilds>(tableOptions: TableOptions.CheckExistence);
|
var table = ctx.CreateTable<KeptGuilds>(tableOptions: TableOptions.CheckExistence);
|
||||||
|
|
||||||
if (await table.AnyAsyncLinqToDB(x => x.GuildId == guildId))
|
if (await table.AnyAsyncLinqToDB(x => x.GuildId == guildId))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -229,31 +149,30 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, IEService
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> GetKeptGuildCount()
|
|
||||||
{
|
|
||||||
await using var db = _db.GetDbContext();
|
|
||||||
await using var ctx = db.CreateLinqToDBContext();
|
|
||||||
var table = ctx.CreateTable<KeptGuilds>(tableOptions: TableOptions.CheckExistence);
|
|
||||||
return await table.CountAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task StartLeavingUnkeptServers(int shardId)
|
|
||||||
=> await _pubSub.Pub(_keepTriggerKey, shardId);
|
|
||||||
|
|
||||||
private ValueTask OnKeepReport(KeepReport report)
|
private ValueTask OnKeepReport(KeepReport report)
|
||||||
{
|
{
|
||||||
guildIds[report.ShardId] = report.GuildIds;
|
guildIds[report.ShardId] = report.GuildIds;
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task OnReadyAsync()
|
||||||
|
{
|
||||||
|
await _pubSub.Sub(_keepTriggerKey, OnKeepTrigger);
|
||||||
|
|
||||||
|
_client.JoinedGuild += ClientOnJoinedGuild;
|
||||||
|
|
||||||
|
if (_client.ShardId == 0)
|
||||||
|
await _pubSub.Sub(_keepReportKey, OnKeepReport);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ClientOnJoinedGuild(SocketGuild arg)
|
private async Task ClientOnJoinedGuild(SocketGuild arg)
|
||||||
{
|
{
|
||||||
await KeepGuild(arg.Id);
|
await KeepGuild(arg.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueTask OnCleanupTrigger(bool arg)
|
private ValueTask OnKeepTrigger(bool arg)
|
||||||
{
|
{
|
||||||
_pubSub.Pub(_cleanupReportKey,
|
_pubSub.Pub(_keepReportKey,
|
||||||
new KeepReport()
|
new KeepReport()
|
||||||
{
|
{
|
||||||
ShardId = _client.ShardId,
|
ShardId = _client.ShardId,
|
||||||
|
|
|
@ -4,6 +4,4 @@ public interface ICleanupService
|
||||||
{
|
{
|
||||||
Task<KeepResult?> DeleteMissingGuildDataAsync();
|
Task<KeepResult?> DeleteMissingGuildDataAsync();
|
||||||
Task<bool> KeepGuild(ulong guildId);
|
Task<bool> KeepGuild(ulong guildId);
|
||||||
Task<int> GetKeptGuildCount();
|
|
||||||
Task StartLeavingUnkeptServers(int shardId);
|
|
||||||
}
|
}
|
|
@ -8,236 +8,236 @@ public partial class Administration
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
public Task Boost()
|
public async Task Boost()
|
||||||
=> Toggle(GreetType.Boost);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task BoostDel(int timer = 30)
|
|
||||||
=> SetDel(GreetType.Boost, timer);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task BoostMsg([Leftover] string? text = null)
|
|
||||||
=> SetMsg(GreetType.Boost, text);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task Greet()
|
|
||||||
=> Toggle(GreetType.Greet);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task GreetDel(int timer = 30)
|
|
||||||
=> SetDel(GreetType.Greet, timer);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task GreetMsg([Leftover] string? text = null)
|
|
||||||
=> SetMsg(GreetType.Greet, text);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task GreetDm()
|
|
||||||
=> Toggle(GreetType.GreetDm);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task GreetDmMsg([Leftover] string? text = null)
|
|
||||||
=> SetMsg(GreetType.GreetDm, text);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task Bye()
|
|
||||||
=> Toggle(GreetType.Bye);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task ByeDel(int timer = 30)
|
|
||||||
=> SetDel(GreetType.Bye, timer);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task ByeMsg([Leftover] string? text = null)
|
|
||||||
=> SetMsg(GreetType.Bye, text);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task GreetTest([Leftover] IGuildUser? user = null)
|
|
||||||
=> Test(GreetType.Greet, user);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
public Task GreetDmTest([Leftover] IGuildUser? user = null)
|
|
||||||
=> Test(GreetType.GreetDm, user);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
[Ratelimit(5)]
|
|
||||||
public Task ByeTest([Leftover] IGuildUser? user = null)
|
|
||||||
=> Test(GreetType.Bye, user);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[UserPerm(GuildPerm.ManageGuild)]
|
|
||||||
[Ratelimit(5)]
|
|
||||||
public Task BoostTest([Leftover] IGuildUser? user = null)
|
|
||||||
=> Test(GreetType.Boost, user);
|
|
||||||
|
|
||||||
|
|
||||||
public async Task Toggle(GreetType type)
|
|
||||||
{
|
{
|
||||||
var enabled = await _service.SetGreet(ctx.Guild.Id, ctx.Channel.Id, type);
|
var enabled = await _service.ToggleBoost(ctx.Guild.Id, ctx.Channel.Id);
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
await Response()
|
await Response().Confirm(strs.boost_on).SendAsync();
|
||||||
.Confirm(
|
|
||||||
type switch
|
|
||||||
{
|
|
||||||
GreetType.Boost => strs.boost_on,
|
|
||||||
GreetType.Greet => strs.greet_on,
|
|
||||||
GreetType.Bye => strs.bye_on,
|
|
||||||
GreetType.GreetDm => strs.greetdm_on,
|
|
||||||
_ => strs.error
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.SendAsync();
|
|
||||||
else
|
else
|
||||||
await Response()
|
await Response().Pending(strs.boost_off).SendAsync();
|
||||||
.Pending(
|
|
||||||
type switch
|
|
||||||
{
|
|
||||||
GreetType.Boost => strs.boost_off,
|
|
||||||
GreetType.Greet => strs.greet_off,
|
|
||||||
GreetType.Bye => strs.bye_off,
|
|
||||||
GreetType.GreetDm => strs.greetdm_off,
|
|
||||||
_ => strs.error
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.SendAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
public async Task SetDel(GreetType type, int timer)
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task BoostDel(int timer = 30)
|
||||||
{
|
{
|
||||||
if (timer is < 0 or > 600)
|
if (timer is < 0 or > 600)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await _service.SetDeleteTimer(ctx.Guild.Id, type, timer);
|
await _service.SetBoostDel(ctx.Guild.Id, timer);
|
||||||
|
|
||||||
if (timer > 0)
|
if (timer > 0)
|
||||||
await Response()
|
await Response().Confirm(strs.boostdel_on(timer)).SendAsync();
|
||||||
.Confirm(
|
|
||||||
type switch
|
|
||||||
{
|
|
||||||
GreetType.Boost => strs.boostdel_on(timer),
|
|
||||||
GreetType.Greet => strs.greetdel_on(timer),
|
|
||||||
GreetType.Bye => strs.byedel_on(timer),
|
|
||||||
_ => strs.error
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.SendAsync();
|
|
||||||
else
|
else
|
||||||
await Response()
|
await Response().Pending(strs.boostdel_off).SendAsync();
|
||||||
.Pending(
|
|
||||||
type switch
|
|
||||||
{
|
|
||||||
GreetType.Boost => strs.boostdel_off,
|
|
||||||
GreetType.Greet => strs.greetdel_off,
|
|
||||||
GreetType.Bye => strs.byedel_off,
|
|
||||||
_ => strs.error
|
|
||||||
})
|
|
||||||
.SendAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
public async Task SetMsg(GreetType type, string? text = null)
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task BoostMsg([Leftover] string? text = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
{
|
{
|
||||||
var conf = await _service.GetGreetSettingsAsync(ctx.Guild.Id, type);
|
var boostMessage = _service.GetBoostMessage(ctx.Guild.Id);
|
||||||
var msg = conf?.MessageText ?? GreetService.GetDefaultGreet(type);
|
await Response().Confirm(strs.boostmsg_cur(boostMessage?.SanitizeMentions())).SendAsync();
|
||||||
await Response()
|
|
||||||
.Confirm(
|
|
||||||
type switch
|
|
||||||
{
|
|
||||||
GreetType.Boost => strs.boostmsg_cur(msg),
|
|
||||||
GreetType.Greet => strs.greetmsg_cur(msg),
|
|
||||||
GreetType.Bye => strs.byemsg_cur(msg),
|
|
||||||
GreetType.GreetDm => strs.greetdmmsg_cur(msg),
|
|
||||||
_ => strs.error
|
|
||||||
})
|
|
||||||
.SendAsync();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isEnabled = await _service.SetMessage(ctx.Guild.Id, type, text);
|
var sendBoostEnabled = _service.SetBoostMessage(ctx.Guild.Id, ref text);
|
||||||
|
|
||||||
await Response()
|
await Response().Confirm(strs.boostmsg_new).SendAsync();
|
||||||
.Confirm(type switch
|
if (!sendBoostEnabled)
|
||||||
{
|
await Response().Pending(strs.boostmsg_enable($"`{prefix}boost`")).SendAsync();
|
||||||
GreetType.Boost => strs.boostmsg_new,
|
|
||||||
GreetType.Greet => strs.greetmsg_new,
|
|
||||||
GreetType.Bye => strs.byemsg_new,
|
|
||||||
GreetType.GreetDm => strs.greetdmmsg_new,
|
|
||||||
_ => strs.error
|
|
||||||
})
|
|
||||||
.SendAsync();
|
|
||||||
|
|
||||||
|
|
||||||
if (!isEnabled)
|
|
||||||
{
|
|
||||||
var cmdName = GetCmdName(type);
|
|
||||||
|
|
||||||
await Response().Pending(strs.boostmsg_enable($"`{prefix}{cmdName}`")).SendAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCmdName(GreetType type)
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task GreetDel(int timer = 30)
|
||||||
{
|
{
|
||||||
var cmdName = type switch
|
if (timer is < 0 or > 600)
|
||||||
{
|
return;
|
||||||
GreetType.Greet => "greet",
|
|
||||||
GreetType.Bye => "bye",
|
await _service.SetGreetDel(ctx.Guild.Id, timer);
|
||||||
GreetType.Boost => "boost",
|
|
||||||
GreetType.GreetDm => "greetdm",
|
if (timer > 0)
|
||||||
_ => "unknown_command"
|
await Response().Confirm(strs.greetdel_on(timer)).SendAsync();
|
||||||
};
|
else
|
||||||
return cmdName;
|
await Response().Pending(strs.greetdel_off).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Test(GreetType type, IGuildUser? user = null)
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task Greet()
|
||||||
|
{
|
||||||
|
var enabled = await _service.SetGreet(ctx.Guild.Id, ctx.Channel.Id);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
await Response().Confirm(strs.greet_on).SendAsync();
|
||||||
|
else
|
||||||
|
await Response().Pending(strs.greet_off).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task GreetMsg([Leftover] string? text = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
var greetMsg = _service.GetGreetMsg(ctx.Guild.Id);
|
||||||
|
await Response().Confirm(strs.greetmsg_cur(greetMsg?.SanitizeMentions())).SendAsync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sendGreetEnabled = _service.SetGreetMessage(ctx.Guild.Id, ref text);
|
||||||
|
|
||||||
|
await Response().Confirm(strs.greetmsg_new).SendAsync();
|
||||||
|
|
||||||
|
if (!sendGreetEnabled)
|
||||||
|
await Response().Pending(strs.greetmsg_enable($"`{prefix}greet`")).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task GreetDm()
|
||||||
|
{
|
||||||
|
var enabled = await _service.SetGreetDm(ctx.Guild.Id);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
await Response().Confirm(strs.greetdm_on).SendAsync();
|
||||||
|
else
|
||||||
|
await Response().Confirm(strs.greetdm_off).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task GreetDmMsg([Leftover] string? text = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
var dmGreetMsg = _service.GetDmGreetMsg(ctx.Guild.Id);
|
||||||
|
await Response().Confirm(strs.greetdmmsg_cur(dmGreetMsg?.SanitizeMentions())).SendAsync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sendGreetEnabled = _service.SetGreetDmMessage(ctx.Guild.Id, ref text);
|
||||||
|
|
||||||
|
await Response().Confirm(strs.greetdmmsg_new).SendAsync();
|
||||||
|
if (!sendGreetEnabled)
|
||||||
|
await Response().Pending(strs.greetdmmsg_enable($"`{prefix}greetdm`")).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task Bye()
|
||||||
|
{
|
||||||
|
var enabled = await _service.SetBye(ctx.Guild.Id, ctx.Channel.Id);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
await Response().Confirm(strs.bye_on).SendAsync();
|
||||||
|
else
|
||||||
|
await Response().Confirm(strs.bye_off).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task ByeMsg([Leftover] string? text = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
var byeMsg = _service.GetByeMessage(ctx.Guild.Id);
|
||||||
|
await Response().Confirm(strs.byemsg_cur(byeMsg?.SanitizeMentions())).SendAsync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sendByeEnabled = _service.SetByeMessage(ctx.Guild.Id, ref text);
|
||||||
|
|
||||||
|
await Response().Confirm(strs.byemsg_new).SendAsync();
|
||||||
|
if (!sendByeEnabled)
|
||||||
|
await Response().Pending(strs.byemsg_enable($"`{prefix}bye`")).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
public async Task ByeDel(int timer = 30)
|
||||||
|
{
|
||||||
|
await _service.SetByeDel(ctx.Guild.Id, timer);
|
||||||
|
|
||||||
|
if (timer > 0)
|
||||||
|
await Response().Confirm(strs.byedel_on(timer)).SendAsync();
|
||||||
|
else
|
||||||
|
await Response().Pending(strs.byedel_off).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
[Ratelimit(5)]
|
||||||
|
public async Task ByeTest([Leftover] IGuildUser? user = null)
|
||||||
{
|
{
|
||||||
user ??= (IGuildUser)ctx.User;
|
user ??= (IGuildUser)ctx.User;
|
||||||
|
|
||||||
await _service.Test(ctx.Guild.Id, type, (ITextChannel)ctx.Channel, user);
|
await _service.ByeTest((ITextChannel)ctx.Channel, user);
|
||||||
var conf = await _service.GetGreetSettingsAsync(ctx.Guild.Id, type);
|
var enabled = _service.GetByeEnabled(ctx.Guild.Id);
|
||||||
|
if (!enabled)
|
||||||
|
await Response().Pending(strs.byemsg_enable($"`{prefix}bye`")).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
var cmd = $"`{prefix}{GetCmdName(type)}`";
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
[Ratelimit(5)]
|
||||||
|
public async Task GreetTest([Leftover] IGuildUser? user = null)
|
||||||
|
{
|
||||||
|
user ??= (IGuildUser)ctx.User;
|
||||||
|
|
||||||
var str = type switch
|
await _service.GreetTest((ITextChannel)ctx.Channel, user);
|
||||||
{
|
var enabled = _service.GetGreetEnabled(ctx.Guild.Id);
|
||||||
GreetType.Greet => strs.boostmsg_enable(cmd),
|
if (!enabled)
|
||||||
GreetType.Bye => strs.greetmsg_enable(cmd),
|
await Response().Pending(strs.greetmsg_enable($"`{prefix}greet`")).SendAsync();
|
||||||
GreetType.Boost => strs.byemsg_enable(cmd),
|
}
|
||||||
GreetType.GreetDm => strs.greetdmmsg_enable(cmd),
|
|
||||||
_ => strs.error
|
[Cmd]
|
||||||
};
|
[RequireContext(ContextType.Guild)]
|
||||||
if (conf?.IsEnabled is not true)
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
await Response().Pending(str).SendAsync();
|
[Ratelimit(5)]
|
||||||
|
public async Task GreetDmTest([Leftover] IGuildUser? user = null)
|
||||||
|
{
|
||||||
|
user ??= (IGuildUser)ctx.User;
|
||||||
|
|
||||||
|
var success = await _service.GreetDmTest(user);
|
||||||
|
if (success)
|
||||||
|
await ctx.OkAsync();
|
||||||
|
else
|
||||||
|
await ctx.WarningAsync();
|
||||||
|
var enabled = _service.GetGreetDmEnabled(ctx.Guild.Id);
|
||||||
|
if (!enabled)
|
||||||
|
await Response().Pending(strs.greetdmmsg_enable($"`{prefix}greetdm`")).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cmd]
|
||||||
|
[RequireContext(ContextType.Guild)]
|
||||||
|
[UserPerm(GuildPerm.ManageGuild)]
|
||||||
|
[Ratelimit(5)]
|
||||||
|
public async Task BoostTest([Leftover] IGuildUser? user = null)
|
||||||
|
{
|
||||||
|
user ??= (IGuildUser)ctx.User;
|
||||||
|
|
||||||
|
await _service.BoostTest((ITextChannel)ctx.Channel, user);
|
||||||
|
var enabled = _service.GetBoostEnabled(ctx.Guild.Id);
|
||||||
|
if (!enabled)
|
||||||
|
await Response().Pending(strs.boostmsg_enable($"`{prefix}boost`")).SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
71
src/EllieBot/Modules/Administration/GreetBye/GreetGrouper.cs
Normal file
71
src/EllieBot/Modules/Administration/GreetBye/GreetGrouper.cs
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
namespace EllieBot.Services;
|
||||||
|
|
||||||
|
public class GreetGrouper<T>
|
||||||
|
{
|
||||||
|
private readonly Dictionary<ulong, HashSet<T>> _group;
|
||||||
|
private readonly object _locker = new();
|
||||||
|
|
||||||
|
public GreetGrouper()
|
||||||
|
=> _group = new();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a group, if group already exists, adds the specified user
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="guildId">Id of the server for which to create group for</param>
|
||||||
|
/// <param name="toAddIfExists">User to add if group already exists</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool CreateOrAdd(ulong guildId, T toAddIfExists)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
if (_group.TryGetValue(guildId, out var list))
|
||||||
|
{
|
||||||
|
list.Add(toAddIfExists);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_group[guildId] = new();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove the specified amount of items from the group. If all items are removed, group will be removed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="guildId">Id of the group</param>
|
||||||
|
/// <param name="count">Maximum number of items to retrieve</param>
|
||||||
|
/// <param name="items">Items retrieved</param>
|
||||||
|
/// <returns>Whether the group has no more items left and is deleted</returns>
|
||||||
|
public bool ClearGroup(ulong guildId, int count, out IReadOnlyCollection<T> items)
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
if (_group.TryGetValue(guildId, out var set))
|
||||||
|
{
|
||||||
|
// if we want more than there are, return everything
|
||||||
|
if (count >= set.Count)
|
||||||
|
{
|
||||||
|
items = set;
|
||||||
|
_group.Remove(guildId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are more in the group than what's needed
|
||||||
|
// take the requested number, remove them from the set
|
||||||
|
// and return them
|
||||||
|
var toReturn = set.TakeWhile(_ => count-- != 0).ToList();
|
||||||
|
foreach (var item in toReturn)
|
||||||
|
set.Remove(item);
|
||||||
|
|
||||||
|
items = toReturn;
|
||||||
|
// returning falsemeans group is not yet deleted
|
||||||
|
// because there are items left
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
items = Array.Empty<T>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,101 +1,63 @@
|
||||||
using LinqToDB;
|
|
||||||
using LinqToDB.EntityFrameworkCore;
|
|
||||||
using LinqToDB.Tools;
|
|
||||||
using EllieBot.Common.ModuleBehaviors;
|
using EllieBot.Common.ModuleBehaviors;
|
||||||
|
using EllieBot.Db.Models;
|
||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
|
|
||||||
namespace EllieBot.Services;
|
namespace EllieBot.Services;
|
||||||
|
|
||||||
public class GreetService : IEService, IReadyExecutor
|
public class GreetService : IEService, IReadyExecutor
|
||||||
{
|
{
|
||||||
|
public bool GroupGreets
|
||||||
|
=> _bss.Data.GroupGreets;
|
||||||
|
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
|
||||||
private ConcurrentDictionary<GreetType, ConcurrentHashSet<ulong>> _enabled = new();
|
private readonly ConcurrentDictionary<ulong, GreetSettings> _guildConfigsCache;
|
||||||
|
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
|
||||||
|
private readonly GreetGrouper<IGuildUser> _greets = new();
|
||||||
|
private readonly GreetGrouper<IUser> _byes = new();
|
||||||
|
private readonly BotConfigService _bss;
|
||||||
private readonly IReplacementService _repSvc;
|
private readonly IReplacementService _repSvc;
|
||||||
private readonly IBotCache _cache;
|
|
||||||
private readonly IMessageSenderService _sender;
|
private readonly IMessageSenderService _sender;
|
||||||
|
|
||||||
private readonly Channel<(GreetSettings, IUser, ITextChannel?)> _greetQueue =
|
|
||||||
Channel.CreateBounded<(GreetSettings, IUser, ITextChannel?)>(
|
|
||||||
new BoundedChannelOptions(60)
|
|
||||||
{
|
|
||||||
FullMode = BoundedChannelFullMode.DropOldest
|
|
||||||
});
|
|
||||||
|
|
||||||
public GreetService(
|
public GreetService(
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
|
IBot bot,
|
||||||
DbService db,
|
DbService db,
|
||||||
|
BotConfigService bss,
|
||||||
IMessageSenderService sender,
|
IMessageSenderService sender,
|
||||||
IReplacementService repSvc,
|
IReplacementService repSvc)
|
||||||
IBotCache cache
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_client = client;
|
_client = client;
|
||||||
|
_bss = bss;
|
||||||
_repSvc = repSvc;
|
_repSvc = repSvc;
|
||||||
_cache = cache;
|
|
||||||
_sender = sender;
|
_sender = sender;
|
||||||
|
|
||||||
|
_guildConfigsCache = new(bot.AllGuildConfigs.ToDictionary(g => g.GuildId, GreetSettings.Create));
|
||||||
foreach (var type in Enum.GetValues<GreetType>())
|
|
||||||
{
|
|
||||||
_enabled[type] = new();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task OnReadyAsync()
|
|
||||||
{
|
|
||||||
// cache all enabled guilds
|
|
||||||
await using (var uow = _db.GetDbContext())
|
|
||||||
{
|
|
||||||
var guilds = _client.Guilds.Select(x => x.Id).ToList();
|
|
||||||
var enabled = await uow.GetTable<GreetSettings>()
|
|
||||||
.Where(x => x.GuildId.In(guilds))
|
|
||||||
.Where(x => x.IsEnabled)
|
|
||||||
.Select(x => new
|
|
||||||
{
|
|
||||||
x.GuildId,
|
|
||||||
x.GreetType
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
foreach (var e in enabled)
|
|
||||||
{
|
|
||||||
_enabled[e.GreetType].Add(e.GuildId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_client.UserJoined += OnUserJoined;
|
_client.UserJoined += OnUserJoined;
|
||||||
_client.UserLeft += OnUserLeft;
|
_client.UserLeft += OnUserLeft;
|
||||||
|
|
||||||
|
bot.JoinedGuild += OnBotJoinedGuild;
|
||||||
_client.LeftGuild += OnClientLeftGuild;
|
_client.LeftGuild += OnClientLeftGuild;
|
||||||
|
|
||||||
_client.GuildMemberUpdated += ClientOnGuildMemberUpdated;
|
_client.GuildMemberUpdated += ClientOnGuildMemberUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnReadyAsync()
|
||||||
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
var (conf, user, compl) = await _greetDmQueue.Reader.ReadAsync();
|
||||||
{
|
var res = await GreetDmUserInternal(conf, user);
|
||||||
var (conf, user, ch) = await _greetQueue.Reader.ReadAsync();
|
compl.TrySetResult(res);
|
||||||
await GreetUsers(conf, ch, user);
|
await Task.Delay(2000);
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Greet Loop almost crashed. Please report this!");
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(2016);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task ClientOnGuildMemberUpdated(Cacheable<SocketGuildUser, ulong> optOldUser, SocketGuildUser newUser)
|
private Task ClientOnGuildMemberUpdated(Cacheable<SocketGuildUser, ulong> optOldUser, SocketGuildUser newUser)
|
||||||
{
|
{
|
||||||
if (!_enabled[GreetType.Boost].Contains(newUser.Guild.Id))
|
|
||||||
return Task.CompletedTask;
|
|
||||||
|
|
||||||
// if user is a new booster
|
// if user is a new booster
|
||||||
// or boosted again the same server
|
// or boosted again the same server
|
||||||
if ((optOldUser.Value is { PremiumSince: null } && newUser is { PremiumSince: not null })
|
if ((optOldUser.Value is { PremiumSince: null } && newUser is { PremiumSince: not null })
|
||||||
|
@ -103,74 +65,60 @@ public class GreetService : IEService, IReadyExecutor
|
||||||
&& newUser.PremiumSince is { } newDate
|
&& newUser.PremiumSince is { } newDate
|
||||||
&& newDate > oldDate))
|
&& newDate > oldDate))
|
||||||
{
|
{
|
||||||
_ = Task.Run(async () =>
|
var conf = GetOrAddSettingsForGuild(newUser.Guild.Id);
|
||||||
{
|
if (!conf.SendBoostMessage)
|
||||||
var conf = await GetGreetSettingsAsync(newUser.Guild.Id, GreetType.Boost);
|
return Task.CompletedTask;
|
||||||
|
|
||||||
if (conf is null || !conf.IsEnabled)
|
_ = Task.Run(TriggerBoostMessage(conf, newUser));
|
||||||
return;
|
|
||||||
|
|
||||||
ITextChannel? channel = null;
|
|
||||||
if (conf.ChannelId is { } cid)
|
|
||||||
channel = newUser.Guild.GetTextChannel(cid);
|
|
||||||
|
|
||||||
if (channel is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
await GreetUsers(conf, channel, newUser);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnClientLeftGuild(SocketGuild guild)
|
private Func<Task> TriggerBoostMessage(GreetSettings conf, SocketGuildUser user)
|
||||||
{
|
=> async () =>
|
||||||
foreach (var gt in Enum.GetValues<GreetType>())
|
|
||||||
{
|
{
|
||||||
_enabled[gt].TryRemove(guild.Id);
|
var channel = user.Guild.GetTextChannel(conf.BoostMessageChannelId);
|
||||||
|
if (channel is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await SendBoostMessage(conf, user, channel);
|
||||||
|
};
|
||||||
|
|
||||||
|
private async Task<bool> SendBoostMessage(GreetSettings conf, IGuildUser user, ITextChannel channel)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(conf.BoostMessage))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var toSend = SmartText.CreateFrom(conf.BoostMessage);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var newContent = await _repSvc.ReplaceAsync(toSend,
|
||||||
|
new(client: _client, guild: user.Guild, channel: channel, users: user));
|
||||||
|
var toDelete = await _sender.Response(channel).Text(newContent).Sanitize(false).SendAsync();
|
||||||
|
if (conf.BoostMessageDeleteAfter > 0)
|
||||||
|
toDelete.DeleteAfter(conf.BoostMessageDeleteAfter);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Error sending boost message");
|
||||||
}
|
}
|
||||||
|
|
||||||
await using var uow = _db.GetDbContext();
|
return false;
|
||||||
await uow.GetTable<GreetSettings>()
|
|
||||||
.Where(x => x.GuildId == guild.Id)
|
|
||||||
.DeleteAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task OnUserJoined(IGuildUser user)
|
private Task OnClientLeftGuild(SocketGuild arg)
|
||||||
{
|
{
|
||||||
_ = Task.Run(async () =>
|
_guildConfigsCache.TryRemove(arg.Id, out _);
|
||||||
{
|
return Task.CompletedTask;
|
||||||
try
|
}
|
||||||
{
|
|
||||||
if (_enabled[GreetType.Greet].Contains(user.GuildId))
|
|
||||||
{
|
|
||||||
var conf = await GetGreetSettingsAsync(user.GuildId, GreetType.Greet);
|
|
||||||
if (conf?.ChannelId is ulong cid)
|
|
||||||
{
|
|
||||||
var channel = await user.Guild.GetTextChannelAsync(cid);
|
|
||||||
if (channel is not null)
|
|
||||||
{
|
|
||||||
await _greetQueue.Writer.WriteAsync((conf, user, channel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private Task OnBotJoinedGuild(GuildConfig gc)
|
||||||
if (_enabled[GreetType.GreetDm].Contains(user.GuildId))
|
{
|
||||||
{
|
_guildConfigsCache[gc.GuildId] = GreetSettings.Create(gc);
|
||||||
var confDm = await GetGreetSettingsAsync(user.GuildId, GreetType.GreetDm);
|
|
||||||
if (confDm is not null)
|
|
||||||
{
|
|
||||||
await _greetQueue.Writer.WriteAsync((confDm, user, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error in GreetService.OnUserJoined. This should not happen. Please report it");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,27 +126,37 @@ public class GreetService : IEService, IReadyExecutor
|
||||||
{
|
{
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
if (!_enabled[GreetType.Bye].Contains(guild.Id))
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var conf = await GetGreetSettingsAsync(guild.Id, GreetType.Bye);
|
var conf = GetOrAddSettingsForGuild(guild.Id);
|
||||||
|
|
||||||
if (conf?.ChannelId is not { } cid)
|
if (!conf.SendChannelByeMessage)
|
||||||
return;
|
return;
|
||||||
|
var channel = guild.TextChannels.FirstOrDefault(c => c.Id == conf.ByeMessageChannelId);
|
||||||
|
|
||||||
var channel = guild.GetChannel(cid) as ITextChannel;
|
|
||||||
if (channel is null) //maybe warn the server owner that the channel is missing
|
if (channel is null) //maybe warn the server owner that the channel is missing
|
||||||
{
|
|
||||||
Log.Warning("Channel {ChannelId} in {GuildId} was not found. Bye message will be disabled",
|
|
||||||
conf.ChannelId,
|
|
||||||
conf.GuildId);
|
|
||||||
await SetGreet(guild.Id, null, GreetType.Bye, false);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
await _greetQueue.Writer.WriteAsync((conf, user, channel));
|
if (GroupGreets)
|
||||||
|
{
|
||||||
|
// if group is newly created, greet that user right away,
|
||||||
|
// but any user which joins in the next 5 seconds will
|
||||||
|
// be greeted in a group greet
|
||||||
|
if (_byes.CreateOrAdd(guild.Id, user))
|
||||||
|
{
|
||||||
|
// greet single user
|
||||||
|
await ByeUsers(conf, channel, new[] { user });
|
||||||
|
var groupClear = false;
|
||||||
|
while (!groupClear)
|
||||||
|
{
|
||||||
|
await Task.Delay(5000);
|
||||||
|
groupClear = _byes.ClearGroup(guild.Id, 5, out var toBye);
|
||||||
|
await ByeUsers(conf, channel, toBye);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
await ByeUsers(conf, channel, new[] { user });
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -208,63 +166,98 @@ public class GreetService : IEService, IReadyExecutor
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypedKey<GreetSettings?> GreetSettingsKey(ulong gid, GreetType type)
|
public string? GetDmGreetMsg(ulong id)
|
||||||
=> new($"greet_settings:{gid}:{type}");
|
|
||||||
|
|
||||||
public async Task<GreetSettings?> GetGreetSettingsAsync(ulong gid, GreetType type)
|
|
||||||
=> await _cache.GetOrAddAsync<GreetSettings?>(GreetSettingsKey(gid, type),
|
|
||||||
() => InternalGetGreetSettingsAsync(gid, type),
|
|
||||||
TimeSpan.FromSeconds(3));
|
|
||||||
|
|
||||||
private async Task<GreetSettings?> InternalGetGreetSettingsAsync(ulong gid, GreetType type)
|
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
var res = await uow.GetTable<GreetSettings>()
|
return uow.GuildConfigsForId(id, set => set).DmGreetMessageText;
|
||||||
.Where(x => x.GuildId == gid && x.GreetType == type)
|
|
||||||
.FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
if (res is not null)
|
|
||||||
res.MessageText ??= GetDefaultGreet(type);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GreetUsers(GreetSettings conf, ITextChannel? channel, IUser user)
|
public string? GetGreetMsg(ulong gid)
|
||||||
{
|
{
|
||||||
if (conf.GreetType == GreetType.GreetDm)
|
using var uow = _db.GetDbContext();
|
||||||
{
|
return uow.GuildConfigsForId(gid, set => set).ChannelGreetMessageText;
|
||||||
if (user is not IGuildUser gu)
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
await GreetDmUserInternal(conf, gu);
|
public string? GetBoostMessage(ulong gid)
|
||||||
return;
|
{
|
||||||
}
|
using var uow = _db.GetDbContext();
|
||||||
|
return uow.GuildConfigsForId(gid, set => set).BoostMessage;
|
||||||
|
}
|
||||||
|
|
||||||
if (channel is null)
|
public GreetSettings GetGreetSettings(ulong gid)
|
||||||
|
{
|
||||||
|
if (_guildConfigsCache.TryGetValue(gid, out var gs))
|
||||||
|
return gs;
|
||||||
|
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
return GreetSettings.Create(uow.GuildConfigsForId(gid, set => set));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task ByeUsers(GreetSettings conf, ITextChannel channel, IUser user)
|
||||||
|
=> ByeUsers(conf, channel, new[] { user });
|
||||||
|
|
||||||
|
private async Task ByeUsers(GreetSettings conf, ITextChannel channel, IReadOnlyCollection<IUser> users)
|
||||||
|
{
|
||||||
|
if (!users.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var repCtx = new ReplacementContext(client: _client,
|
var repCtx = new ReplacementContext(client: _client,
|
||||||
guild: channel.Guild,
|
guild: channel.Guild,
|
||||||
channel: channel,
|
channel: channel,
|
||||||
user: user);
|
users: users.ToArray());
|
||||||
|
|
||||||
var text = SmartText.CreateFrom(conf.MessageText);
|
var text = SmartText.CreateFrom(conf.ChannelByeMessageText);
|
||||||
text = await _repSvc.ReplaceAsync(text, repCtx);
|
text = await _repSvc.ReplaceAsync(text, repCtx);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var toDelete = await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
var toDelete = await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
||||||
if (conf.AutoDeleteTimer > 0)
|
if (conf.AutoDeleteByeMessagesTimer > 0)
|
||||||
toDelete.DeleteAfter(conf.AutoDeleteTimer);
|
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.DiscordCode is DiscordErrorCode.InsufficientPermissions
|
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions
|
||||||
or DiscordErrorCode.MissingPermissions
|
|| ex.DiscordCode == DiscordErrorCode.MissingPermissions
|
||||||
or DiscordErrorCode.UnknownChannel)
|
|| ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
||||||
{
|
{
|
||||||
Log.Warning(ex,
|
Log.Warning(ex,
|
||||||
"Missing permissions to send a {GreetType} message, it will be disabled on server: {GuildId}",
|
"Missing permissions to send a bye message, the bye message will be disabled on server: {GuildId}",
|
||||||
conf.GreetType,
|
|
||||||
channel.GuildId);
|
channel.GuildId);
|
||||||
await SetGreet(channel.GuildId, channel.Id, conf.GreetType, false);
|
await SetBye(channel.GuildId, channel.Id, false);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Warning(ex, "Error embeding bye message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task GreetUsers(GreetSettings conf, ITextChannel channel, IGuildUser user)
|
||||||
|
=> GreetUsers(conf, channel, new[] { user });
|
||||||
|
|
||||||
|
private async Task GreetUsers(GreetSettings conf, ITextChannel channel, IReadOnlyCollection<IGuildUser> users)
|
||||||
|
{
|
||||||
|
if (users.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var repCtx = new ReplacementContext(client: _client,
|
||||||
|
guild: channel.Guild,
|
||||||
|
channel: channel,
|
||||||
|
users: users.ToArray());
|
||||||
|
|
||||||
|
var text = SmartText.CreateFrom(conf.ChannelGreetMessageText);
|
||||||
|
text = await _repSvc.ReplaceAsync(text, repCtx);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var toDelete = await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
||||||
|
if (conf.AutoDeleteGreetMessagesTimer > 0)
|
||||||
|
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
|
||||||
|
}
|
||||||
|
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions
|
||||||
|
|| ex.DiscordCode == DiscordErrorCode.MissingPermissions
|
||||||
|
|| ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
||||||
|
{
|
||||||
|
Log.Warning(ex,
|
||||||
|
"Missing permissions to send a bye message, the greet message will be disabled on server: {GuildId}",
|
||||||
|
channel.GuildId);
|
||||||
|
await SetGreet(channel.GuildId, channel.Id, false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -272,12 +265,33 @@ public class GreetService : IEService, IReadyExecutor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly Channel<(GreetSettings, IGuildUser, TaskCompletionSource<bool>)> _greetDmQueue =
|
||||||
|
Channel.CreateBounded<(GreetSettings, IGuildUser, TaskCompletionSource<bool>)>(new BoundedChannelOptions(60)
|
||||||
|
{
|
||||||
|
// The limit of 60 users should be only hit when there's a raid. In that case
|
||||||
|
// probably the best thing to do is to drop newest (raiding) users
|
||||||
|
FullMode = BoundedChannelFullMode.DropNewest
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
private async Task<bool> GreetDmUser(GreetSettings conf, IGuildUser user)
|
||||||
|
{
|
||||||
|
var completionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
|
await _greetDmQueue.Writer.WriteAsync((conf, user, completionSource));
|
||||||
|
return await completionSource.Task;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<bool> GreetDmUserInternal(GreetSettings conf, IGuildUser user)
|
private async Task<bool> GreetDmUserInternal(GreetSettings conf, IGuildUser user)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var repCtx = new ReplacementContext(client: _client, guild: user.Guild, user: user);
|
// var rep = new ReplacementBuilder()
|
||||||
var smartText = SmartText.CreateFrom(conf.MessageText);
|
// .WithUser(user)
|
||||||
|
// .WithServer(_client, (SocketGuild)user.Guild)
|
||||||
|
// .Build();
|
||||||
|
|
||||||
|
var repCtx = new ReplacementContext(client: _client, guild: user.Guild, users: user);
|
||||||
|
var smartText = SmartText.CreateFrom(conf.DmGreetMessageText);
|
||||||
smartText = await _repSvc.ReplaceAsync(smartText, repCtx);
|
smartText = await _repSvc.ReplaceAsync(smartText, repCtx);
|
||||||
|
|
||||||
if (smartText is SmartPlainText pt)
|
if (smartText is SmartPlainText pt)
|
||||||
|
@ -327,9 +341,9 @@ public class GreetService : IEService, IReadyExecutor
|
||||||
{
|
{
|
||||||
// if there is less than 10 embeds, add an embed with footer only
|
// if there is less than 10 embeds, add an embed with footer only
|
||||||
seta.Embeds = seta.Embeds.Append(new SmartEmbedArrayElementText()
|
seta.Embeds = seta.Embeds.Append(new SmartEmbedArrayElementText()
|
||||||
{
|
{
|
||||||
Footer = CreateFooterSource(user)
|
Footer = CreateFooterSource(user)
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,9 +351,8 @@ public class GreetService : IEService, IReadyExecutor
|
||||||
|
|
||||||
await _sender.Response(user).Text(smartText).Sanitize(false).SendAsync();
|
await _sender.Response(user).Text(smartText).Sanitize(false).SendAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
Log.Error(ex, "Error sending greet dm");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,156 +366,303 @@ public class GreetService : IEService, IReadyExecutor
|
||||||
IconUrl = user.Guild.IconUrl
|
IconUrl = user.Guild.IconUrl
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private Task OnUserJoined(IGuildUser user)
|
||||||
public static string GetDefaultGreet(GreetType greetType)
|
{
|
||||||
=> greetType switch
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
GreetType.Boost => "%user.mention% has boosted the server!",
|
try
|
||||||
GreetType.Greet => "%user.mention% has joined the server!",
|
{
|
||||||
GreetType.Bye => "%user.name% has left the server!",
|
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||||
GreetType.GreetDm => "Welcome to the server %user.name%",
|
|
||||||
_ => "%user.name% did something new!"
|
|
||||||
};
|
|
||||||
|
|
||||||
public async Task<bool> SetGreet(
|
if (conf.SendChannelGreetMessage)
|
||||||
ulong guildId,
|
{
|
||||||
ulong? channelId,
|
var channel = await user.Guild.GetTextChannelAsync(conf.GreetMessageChannelId);
|
||||||
GreetType greetType,
|
if (channel is not null)
|
||||||
bool? value = null)
|
{
|
||||||
|
if (GroupGreets)
|
||||||
|
{
|
||||||
|
// if group is newly created, greet that user right away,
|
||||||
|
// but any user which joins in the next 5 seconds will
|
||||||
|
// be greeted in a group greet
|
||||||
|
if (_greets.CreateOrAdd(user.GuildId, user))
|
||||||
|
{
|
||||||
|
// greet single user
|
||||||
|
await GreetUsers(conf, channel, new[] { user });
|
||||||
|
var groupClear = false;
|
||||||
|
while (!groupClear)
|
||||||
|
{
|
||||||
|
await Task.Delay(5000);
|
||||||
|
groupClear = _greets.ClearGroup(user.GuildId, 5, out var toGreet);
|
||||||
|
await GreetUsers(conf, channel, toGreet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
await GreetUsers(conf, channel, new[] { user });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf.SendDmGreetMessage)
|
||||||
|
await GreetDmUser(conf, user);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? GetByeMessage(ulong gid)
|
||||||
|
{
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
return uow.GuildConfigsForId(gid, set => set).ChannelByeMessageText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GreetSettings GetOrAddSettingsForGuild(ulong guildId)
|
||||||
|
{
|
||||||
|
if (_guildConfigsCache.TryGetValue(guildId, out var settings))
|
||||||
|
return settings;
|
||||||
|
|
||||||
|
using (var uow = _db.GetDbContext())
|
||||||
|
{
|
||||||
|
var gc = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
settings = GreetSettings.Create(gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
_guildConfigsCache.TryAdd(guildId, settings);
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> SetGreet(ulong guildId, ulong channelId, bool? value = null)
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
var q = uow.GetTable<GreetSettings>();
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
var enabled = conf.SendChannelGreetMessage = value ?? !conf.SendChannelGreetMessage;
|
||||||
|
conf.GreetMessageChannelId = channelId;
|
||||||
|
|
||||||
if (value is null)
|
var toAdd = GreetSettings.Create(conf);
|
||||||
value = !_enabled[greetType].Contains(guildId);
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
if (value is { } v)
|
await uow.SaveChangesAsync();
|
||||||
{
|
return enabled;
|
||||||
await q
|
|
||||||
.InsertOrUpdateAsync(() => new()
|
|
||||||
{
|
|
||||||
GuildId = guildId,
|
|
||||||
GreetType = greetType,
|
|
||||||
IsEnabled = v,
|
|
||||||
ChannelId = channelId,
|
|
||||||
},
|
|
||||||
(old) => new()
|
|
||||||
{
|
|
||||||
IsEnabled = v,
|
|
||||||
ChannelId = channelId,
|
|
||||||
},
|
|
||||||
() => new()
|
|
||||||
{
|
|
||||||
GuildId = guildId,
|
|
||||||
GreetType = greetType,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value is true)
|
|
||||||
{
|
|
||||||
_enabled[greetType].Add(guildId);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_enabled[greetType].TryRemove(guildId);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SetGreetMessage(ulong guildId, ref string message)
|
||||||
public async Task<bool> SetMessage(ulong guildId, GreetType greetType, string? message)
|
|
||||||
{
|
{
|
||||||
await using (var uow = _db.GetDbContext())
|
message = message.SanitizeMentions();
|
||||||
{
|
|
||||||
await uow.GetTable<GreetSettings>()
|
|
||||||
.InsertOrUpdateAsync(() => new()
|
|
||||||
{
|
|
||||||
GuildId = guildId,
|
|
||||||
GreetType = greetType,
|
|
||||||
MessageText = message
|
|
||||||
},
|
|
||||||
x => new()
|
|
||||||
{
|
|
||||||
MessageText = message
|
|
||||||
},
|
|
||||||
() => new()
|
|
||||||
{
|
|
||||||
GuildId = guildId,
|
|
||||||
GreetType = greetType
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var conf = await GetGreetSettingsAsync(guildId, greetType);
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
throw new ArgumentNullException(nameof(message));
|
||||||
|
|
||||||
return conf?.IsEnabled ?? false;
|
using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
conf.ChannelGreetMessageText = message;
|
||||||
|
var greetMsgEnabled = conf.SendChannelGreetMessage;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache.AddOrUpdate(guildId, toAdd, (_, _) => toAdd);
|
||||||
|
|
||||||
|
uow.SaveChanges();
|
||||||
|
return greetMsgEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> SetDeleteTimer(ulong guildId, GreetType greetType, int timer)
|
public async Task<bool> SetGreetDm(ulong guildId, bool? value = null)
|
||||||
{
|
{
|
||||||
if (timer < 0 || timer > 3600)
|
await using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
var enabled = conf.SendDmGreetMessage = value ?? !conf.SendDmGreetMessage;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
|
await uow.SaveChangesAsync();
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetGreetDmMessage(ulong guildId, ref string? message)
|
||||||
|
{
|
||||||
|
message = message?.SanitizeMentions();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
throw new ArgumentNullException(nameof(message));
|
||||||
|
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
conf.DmGreetMessageText = message;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
|
uow.SaveChanges();
|
||||||
|
return conf.SendDmGreetMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> SetBye(ulong guildId, ulong channelId, bool? value = null)
|
||||||
|
{
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
var enabled = conf.SendChannelByeMessage = value ?? !conf.SendChannelByeMessage;
|
||||||
|
conf.ByeMessageChannelId = channelId;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
|
await uow.SaveChangesAsync();
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetByeMessage(ulong guildId, ref string? message)
|
||||||
|
{
|
||||||
|
message = message?.SanitizeMentions();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(message))
|
||||||
|
throw new ArgumentNullException(nameof(message));
|
||||||
|
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
conf.ChannelByeMessageText = message;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
|
uow.SaveChanges();
|
||||||
|
return conf.SendChannelByeMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetByeDel(ulong guildId, int timer)
|
||||||
|
{
|
||||||
|
if (timer is < 0 or > 600)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
conf.AutoDeleteByeMessagesTimer = timer;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
|
await uow.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetGreetDel(ulong guildId, int timer)
|
||||||
|
{
|
||||||
|
if (timer is < 0 or > 600)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
conf.AutoDeleteGreetMessagesTimer = timer;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
|
await uow.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetBoostMessage(ulong guildId, ref string message)
|
||||||
|
{
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
conf.BoostMessage = message;
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
|
uow.SaveChanges();
|
||||||
|
return conf.SendBoostMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetBoostDel(ulong guildId, int timer)
|
||||||
|
{
|
||||||
|
if (timer is < 0 or > 600)
|
||||||
throw new ArgumentOutOfRangeException(nameof(timer));
|
throw new ArgumentOutOfRangeException(nameof(timer));
|
||||||
|
|
||||||
await using (var uow = _db.GetDbContext())
|
await using var uow = _db.GetDbContext();
|
||||||
{
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
await uow.GetTable<GreetSettings>()
|
conf.BoostMessageDeleteAfter = timer;
|
||||||
.InsertOrUpdateAsync(() => new()
|
|
||||||
{
|
|
||||||
GuildId = guildId,
|
|
||||||
GreetType = greetType,
|
|
||||||
AutoDeleteTimer = timer,
|
|
||||||
},
|
|
||||||
x => new()
|
|
||||||
{
|
|
||||||
AutoDeleteTimer = timer
|
|
||||||
},
|
|
||||||
() => new()
|
|
||||||
{
|
|
||||||
GuildId = guildId,
|
|
||||||
GreetType = greetType
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var conf = await GetGreetSettingsAsync(guildId, greetType);
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
|
||||||
return conf?.IsEnabled ?? false;
|
await uow.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> ToggleBoost(ulong guildId, ulong channelId, bool? forceState = null)
|
||||||
public async Task<bool> Test(
|
|
||||||
ulong guildId,
|
|
||||||
GreetType type,
|
|
||||||
IMessageChannel channel,
|
|
||||||
IGuildUser user)
|
|
||||||
{
|
{
|
||||||
var conf = await GetGreetSettingsAsync(guildId, type);
|
await using var uow = _db.GetDbContext();
|
||||||
if (conf is null)
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
{
|
|
||||||
conf = new GreetSettings()
|
|
||||||
{
|
|
||||||
ChannelId = channel.Id,
|
|
||||||
GreetType = type,
|
|
||||||
IsEnabled = false,
|
|
||||||
GuildId = guildId,
|
|
||||||
AutoDeleteTimer = 30,
|
|
||||||
MessageText = GetDefaultGreet(type)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
await SendMessage(conf, channel, user);
|
if (forceState is not bool fs)
|
||||||
return true;
|
conf.SendBoostMessage = !conf.SendBoostMessage;
|
||||||
|
else
|
||||||
|
conf.SendBoostMessage = fs;
|
||||||
|
|
||||||
|
conf.BoostMessageChannelId = channelId;
|
||||||
|
await uow.SaveChangesAsync();
|
||||||
|
|
||||||
|
var toAdd = GreetSettings.Create(conf);
|
||||||
|
_guildConfigsCache[guildId] = toAdd;
|
||||||
|
return conf.SendBoostMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> SendMessage(GreetSettings conf, IMessageChannel channel, IGuildUser user)
|
#region Get Enabled Status
|
||||||
|
|
||||||
|
public bool GetGreetDmEnabled(ulong guildId)
|
||||||
{
|
{
|
||||||
if (conf.GreetType == GreetType.GreetDm)
|
using var uow = _db.GetDbContext();
|
||||||
{
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
await _greetQueue.Writer.WriteAsync((conf, user, null));
|
return conf.SendDmGreetMessage;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel is not ITextChannel ch)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
await GreetUsers(conf, ch, user);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool GetGreetEnabled(ulong guildId)
|
||||||
|
{
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
return conf.SendChannelGreetMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetByeEnabled(ulong guildId)
|
||||||
|
{
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
return conf.SendChannelByeMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetBoostEnabled(ulong guildId)
|
||||||
|
{
|
||||||
|
using var uow = _db.GetDbContext();
|
||||||
|
var conf = uow.GuildConfigsForId(guildId, set => set);
|
||||||
|
return conf.SendBoostMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Test Messages
|
||||||
|
|
||||||
|
public Task ByeTest(ITextChannel channel, IGuildUser user)
|
||||||
|
{
|
||||||
|
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||||
|
return ByeUsers(conf, channel, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task GreetTest(ITextChannel channel, IGuildUser user)
|
||||||
|
{
|
||||||
|
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||||
|
return GreetUsers(conf, channel, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> GreetDmTest(IGuildUser user)
|
||||||
|
{
|
||||||
|
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||||
|
return GreetDmUser(conf, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> BoostTest(ITextChannel channel, IGuildUser user)
|
||||||
|
{
|
||||||
|
var conf = GetOrAddSettingsForGuild(user.GuildId);
|
||||||
|
return SendBoostMessage(conf, user, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
|
@ -1,21 +1,45 @@
|
||||||
namespace EllieBot.Services;
|
using EllieBot.Db.Models;
|
||||||
|
|
||||||
public enum GreetType
|
namespace EllieBot.Services;
|
||||||
{
|
|
||||||
Greet,
|
|
||||||
GreetDm,
|
|
||||||
Bye,
|
|
||||||
Boost,
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GreetSettings
|
public class GreetSettings
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int AutoDeleteGreetMessagesTimer { get; set; }
|
||||||
|
public int AutoDeleteByeMessagesTimer { get; set; }
|
||||||
public ulong GuildId { get; set; }
|
|
||||||
public GreetType GreetType { get; set; }
|
public ulong GreetMessageChannelId { get; set; }
|
||||||
public string? MessageText { get; set; }
|
public ulong ByeMessageChannelId { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
public ulong? ChannelId { get; set; }
|
public bool SendDmGreetMessage { get; set; }
|
||||||
public int AutoDeleteTimer { get; set; }
|
public string? DmGreetMessageText { get; set; }
|
||||||
|
|
||||||
|
public bool SendChannelGreetMessage { get; set; }
|
||||||
|
public string? ChannelGreetMessageText { get; set; }
|
||||||
|
|
||||||
|
public bool SendChannelByeMessage { get; set; }
|
||||||
|
public string? ChannelByeMessageText { get; set; }
|
||||||
|
|
||||||
|
public bool SendBoostMessage { get; set; }
|
||||||
|
public string? BoostMessage { get; set; }
|
||||||
|
public int BoostMessageDeleteAfter { get; set; }
|
||||||
|
public ulong BoostMessageChannelId { get; set; }
|
||||||
|
|
||||||
|
public static GreetSettings Create(GuildConfig g)
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
AutoDeleteByeMessagesTimer = g.AutoDeleteByeMessagesTimer,
|
||||||
|
AutoDeleteGreetMessagesTimer = g.AutoDeleteGreetMessagesTimer,
|
||||||
|
GreetMessageChannelId = g.GreetMessageChannelId,
|
||||||
|
ByeMessageChannelId = g.ByeMessageChannelId,
|
||||||
|
SendDmGreetMessage = g.SendDmGreetMessage,
|
||||||
|
DmGreetMessageText = g.DmGreetMessageText,
|
||||||
|
SendChannelGreetMessage = g.SendChannelGreetMessage,
|
||||||
|
ChannelGreetMessageText = g.ChannelGreetMessageText,
|
||||||
|
SendChannelByeMessage = g.SendChannelByeMessage,
|
||||||
|
ChannelByeMessageText = g.ChannelByeMessageText,
|
||||||
|
SendBoostMessage = g.SendBoostMessage,
|
||||||
|
BoostMessage = g.BoostMessage,
|
||||||
|
BoostMessageDeleteAfter = g.BoostMessageDeleteAfter,
|
||||||
|
BoostMessageChannelId = g.BoostMessageChannelId
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -18,17 +18,11 @@ public partial class Administration
|
||||||
await Response().Confirm(strs.ropl_disabled).SendAsync();
|
await Response().Confirm(strs.ropl_disabled).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public Task AddPlaying([Leftover] string status)
|
public async Task AddPlaying(ActivityType t, [Leftover] string status)
|
||||||
=> AddPlaying(ActivityType.CustomStatus, status);
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[OwnerOnly]
|
|
||||||
public async Task AddPlaying(ActivityType statusType, [Leftover] string status)
|
|
||||||
{
|
{
|
||||||
await _service.AddPlaying(statusType, status);
|
await _service.AddPlaying(t, status);
|
||||||
|
|
||||||
await Response().Confirm(strs.ropl_added).SendAsync();
|
await Response().Confirm(strs.ropl_added).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public sealed class PlayingRotateService : IEService, IReadyExecutor
|
||||||
: rotatingStatuses[index++];
|
: rotatingStatuses[index++];
|
||||||
|
|
||||||
var statusText = await _repService.ReplaceAsync(playingStatus.Status, new (client: _client));
|
var statusText = await _repService.ReplaceAsync(playingStatus.Status, new (client: _client));
|
||||||
await _selfService.SetActivityAsync(statusText, (ActivityType)playingStatus.Type);
|
await _selfService.SetGameAsync(statusText, (ActivityType)playingStatus.Type);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class PruneService : IEService
|
||||||
using var cancelSource = new CancellationTokenSource();
|
using var cancelSource = new CancellationTokenSource();
|
||||||
if (!_pruningGuilds.TryAdd(channel.GuildId, cancelSource))
|
if (!_pruningGuilds.TryAdd(channel.GuildId, cancelSource))
|
||||||
return PruneResult.AlreadyRunning;
|
return PruneResult.AlreadyRunning;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!await _ps.LimitHitAsync(LimitedFeatureName.Prune, channel.Guild.OwnerId))
|
if (!await _ps.LimitHitAsync(LimitedFeatureName.Prune, channel.Guild.OwnerId))
|
||||||
|
|
|
@ -13,7 +13,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR
|
||||||
{
|
{
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly IBotCreds _creds;
|
private readonly IBotCredentials _creds;
|
||||||
|
|
||||||
private ConcurrentDictionary<ulong, List<ReactionRoleV2>> _cache;
|
private ConcurrentDictionary<ulong, List<ReactionRoleV2>> _cache;
|
||||||
private readonly object _cacheLock = new();
|
private readonly object _cacheLock = new();
|
||||||
|
@ -24,7 +24,7 @@ public sealed class ReactionRolesService : IReadyExecutor, IEService, IReactionR
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
IPatronageService ps,
|
IPatronageService ps,
|
||||||
DbService db,
|
DbService db,
|
||||||
IBotCreds creds)
|
IBotCredentials creds)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_client = client;
|
_client = client;
|
||||||
|
|
|
@ -9,13 +9,13 @@ namespace EllieBot.Modules.Administration;
|
||||||
public sealed class StickyRolesService : IEService, IReadyExecutor
|
public sealed class StickyRolesService : IEService, IReadyExecutor
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly IBotCreds _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private HashSet<ulong> _stickyRoles = new();
|
private HashSet<ulong> _stickyRoles = new();
|
||||||
|
|
||||||
public StickyRolesService(
|
public StickyRolesService(
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
IBotCreds creds,
|
IBotCredentials creds,
|
||||||
DbService db)
|
DbService db)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
|
|
|
@ -459,7 +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]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public async Task SetStatus([Leftover] SettableUserStatus status)
|
public async Task SetStatus([Leftover] SettableUserStatus status)
|
||||||
|
@ -491,25 +491,14 @@ public partial class Administration
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public async Task SetActivity(ActivityType? type, [Leftover] string game = null)
|
public async Task SetGame(ActivityType type, [Leftover] string game = null)
|
||||||
{
|
{
|
||||||
// var rep = new ReplacementBuilder().WithDefault(Context).Build();
|
// var rep = new ReplacementBuilder().WithDefault(Context).Build();
|
||||||
|
|
||||||
var repCtx = new ReplacementContext(ctx);
|
var repCtx = new ReplacementContext(ctx);
|
||||||
await _service.SetActivityAsync(game is null ? game : await repSvc.ReplaceAsync(game, repCtx), type);
|
await _service.SetGameAsync(game is null ? game : await repSvc.ReplaceAsync(game, repCtx), type);
|
||||||
|
|
||||||
await Response().Confirm(strs.set_activity).SendAsync();
|
await Response().Confirm(strs.set_game).SendAsync();
|
||||||
}
|
|
||||||
|
|
||||||
[Cmd]
|
|
||||||
[OwnerOnly]
|
|
||||||
public Task SetActivity([Leftover] string game = null)
|
|
||||||
=> SetActivity(null, game);
|
|
||||||
|
|
||||||
public class SetActivityOptions
|
|
||||||
{
|
|
||||||
public ActivityType? Type { get; set; }
|
|
||||||
public string Game { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@ -552,11 +541,11 @@ public partial class Administration
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var repCtx = new ReplacementContext(ctx);
|
var repCtx = new ReplacementContext(ctx);
|
||||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||||
await Response().Channel(ch).Text(text).SendAsync();
|
await Response().Channel(ch).Text(text).SendAsync();
|
||||||
|
|
||||||
await ctx.OkAsync();
|
await ctx.OkAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
private readonly IBotStrings _strings;
|
private readonly IBotStrings _strings;
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
|
||||||
private readonly IBotCreds _creds;
|
private readonly IBotCredentials _creds;
|
||||||
|
|
||||||
private ImmutableDictionary<ulong, IDMChannel> ownerChannels =
|
private ImmutableDictionary<ulong, IDMChannel> ownerChannels =
|
||||||
new Dictionary<ulong, IDMChannel>().ToImmutableDictionary();
|
new Dictionary<ulong, IDMChannel>().ToImmutableDictionary();
|
||||||
|
@ -36,7 +36,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
CommandHandler cmdHandler,
|
CommandHandler cmdHandler,
|
||||||
DbService db,
|
DbService db,
|
||||||
IBotStrings strings,
|
IBotStrings strings,
|
||||||
IBotCreds creds,
|
IBotCredentials creds,
|
||||||
IHttpClientFactory factory,
|
IHttpClientFactory factory,
|
||||||
BotConfigService bss,
|
BotConfigService bss,
|
||||||
IPubSub pubSub,
|
IPubSub pubSub,
|
||||||
|
@ -85,14 +85,13 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
|
|
||||||
autoCommands = uow.Set<AutoCommand>()
|
autoCommands = uow.Set<AutoCommand>().AsNoTracking()
|
||||||
.AsNoTracking()
|
.Where(x => x.Interval >= 5)
|
||||||
.Where(x => x.Interval >= 5)
|
.AsEnumerable()
|
||||||
.AsEnumerable()
|
.GroupBy(x => x.GuildId)
|
||||||
.GroupBy(x => x.GuildId)
|
.ToDictionary(x => x.Key,
|
||||||
.ToDictionary(x => x.Key,
|
y => y.ToDictionary(x => x.Id, TimerFromAutoCommand).ToConcurrent())
|
||||||
y => y.ToDictionary(x => x.Id, TimerFromAutoCommand).ToConcurrent())
|
.ToConcurrent();
|
||||||
.ToConcurrent();
|
|
||||||
|
|
||||||
var startupCommands = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0);
|
var startupCommands = uow.Set<AutoCommand>().AsNoTracking().Where(x => x.Interval == 0);
|
||||||
foreach (var cmd in startupCommands)
|
foreach (var cmd in startupCommands)
|
||||||
|
@ -171,18 +170,18 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
private async Task LoadOwnerChannels()
|
private async Task LoadOwnerChannels()
|
||||||
{
|
{
|
||||||
var channels = await _creds.OwnerIds.Select(id =>
|
var channels = await _creds.OwnerIds.Select(id =>
|
||||||
{
|
{
|
||||||
var user = _client.GetUser(id);
|
var user = _client.GetUser(id);
|
||||||
if (user is null)
|
if (user is null)
|
||||||
return Task.FromResult<IDMChannel>(null);
|
return Task.FromResult<IDMChannel>(null);
|
||||||
|
|
||||||
return user.CreateDMChannelAsync();
|
return user.CreateDMChannelAsync();
|
||||||
})
|
})
|
||||||
.WhenAll();
|
.WhenAll();
|
||||||
|
|
||||||
ownerChannels = channels.Where(x => x is not null)
|
ownerChannels = channels.Where(x => x is not null)
|
||||||
.ToDictionary(x => x.Recipient.Id, x => x)
|
.ToDictionary(x => x.Recipient.Id, x => x)
|
||||||
.ToImmutableDictionary();
|
.ToImmutableDictionary();
|
||||||
|
|
||||||
if (!ownerChannels.Any())
|
if (!ownerChannels.Any())
|
||||||
{
|
{
|
||||||
|
@ -401,10 +400,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (data.Type is { } activityType)
|
await _client.SetGameAsync(data.Name, data.Link, data.Type);
|
||||||
await _client.SetGameAsync(data.Name, data.Link, activityType);
|
|
||||||
else
|
|
||||||
await _client.SetCustomStatusAsync(data.Name);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -412,7 +408,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public Task SetActivityAsync(string game, ActivityType? type)
|
public Task SetGameAsync(string game, ActivityType type)
|
||||||
=> _pubSub.Pub(_activitySetKey,
|
=> _pubSub.Pub(_activitySetKey,
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
|
@ -434,10 +430,10 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
{
|
{
|
||||||
public string Name { get; init; }
|
public string Name { get; init; }
|
||||||
public string Link { get; init; }
|
public string Link { get; init; }
|
||||||
public ActivityType? Type { get; init; }
|
public ActivityType Type { get; init; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the specified <paramref name="users"/> to the database. If a database user with placeholder name
|
/// Adds the specified <paramref name="users"/> to the database. If a database user with placeholder name
|
||||||
/// and discriminator is present in <paramref name="users"/>, their name and discriminator get updated accordingly.
|
/// and discriminator is present in <paramref name="users"/>, their name and discriminator get updated accordingly.
|
||||||
|
@ -447,46 +443,41 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, IEService
|
||||||
/// <returns>A tuple with the amount of new users added and old users updated.</returns>
|
/// <returns>A tuple with the amount of new users added and old users updated.</returns>
|
||||||
public async Task<(long UsersAdded, long UsersUpdated)> RefreshUsersAsync(List<IUser> users)
|
public async Task<(long UsersAdded, long UsersUpdated)> RefreshUsersAsync(List<IUser> users)
|
||||||
{
|
{
|
||||||
await using var ctx = _db.GetDbContext();
|
await using var ctx = _db.GetDbContext();
|
||||||
var presentDbUsers = await ctx.GetTable<DiscordUser>()
|
var presentDbUsers = await ctx.GetTable<DiscordUser>()
|
||||||
.Select(x => new
|
.Select(x => new { x.UserId, x.Username, x.Discriminator })
|
||||||
{
|
.Where(x => users.Select(y => y.Id).Contains(x.UserId))
|
||||||
x.UserId,
|
.ToArrayAsyncEF();
|
||||||
x.Username,
|
|
||||||
x.Discriminator
|
|
||||||
})
|
|
||||||
.Where(x => users.Select(y => y.Id).Contains(x.UserId))
|
|
||||||
.ToArrayAsyncEF();
|
|
||||||
|
|
||||||
var usersToAdd = users
|
var usersToAdd = users
|
||||||
.Where(x => !presentDbUsers.Select(x => x.UserId).Contains(x.Id))
|
.Where(x => !presentDbUsers.Select(x => x.UserId).Contains(x.Id))
|
||||||
.Select(x => new DiscordUser()
|
.Select(x => new DiscordUser()
|
||||||
{
|
{
|
||||||
UserId = x.Id,
|
UserId = x.Id,
|
||||||
AvatarId = x.AvatarId,
|
AvatarId = x.AvatarId,
|
||||||
Username = x.Username,
|
Username = x.Username,
|
||||||
Discriminator = x.Discriminator
|
Discriminator = x.Discriminator
|
||||||
});
|
});
|
||||||
|
|
||||||
var added = (await ctx.BulkCopyAsync(usersToAdd)).RowsCopied;
|
var added = (await ctx.BulkCopyAsync(usersToAdd)).RowsCopied;
|
||||||
var toUpdateUserIds = presentDbUsers
|
var toUpdateUserIds = presentDbUsers
|
||||||
.Where(x => x.Username == "Unknown" && x.Discriminator == "????")
|
.Where(x => x.Username == "Unknown" && x.Discriminator == "????")
|
||||||
.Select(x => x.UserId)
|
.Select(x => x.UserId)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
foreach (var user in users.Where(x => toUpdateUserIds.Contains(x.Id)))
|
foreach (var user in users.Where(x => toUpdateUserIds.Contains(x.Id)))
|
||||||
{
|
{
|
||||||
await ctx.GetTable<DiscordUser>()
|
await ctx.GetTable<DiscordUser>()
|
||||||
.Where(x => x.UserId == user.Id)
|
.Where(x => x.UserId == user.Id)
|
||||||
.UpdateAsync(x => new DiscordUser()
|
.UpdateAsync(x => new DiscordUser()
|
||||||
{
|
{
|
||||||
Username = user.Username,
|
Username = user.Username,
|
||||||
Discriminator = user.Discriminator,
|
Discriminator = user.Discriminator,
|
||||||
|
|
||||||
// .award tends to set AvatarId and DateAdded to NULL, so account for that.
|
// .award tends to set AvatarId and DateAdded to NULL, so account for that.
|
||||||
AvatarId = user.AvatarId,
|
AvatarId = user.AvatarId,
|
||||||
DateAdded = x.DateAdded ?? DateTime.UtcNow
|
DateAdded = x.DateAdded ?? DateTime.UtcNow
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (added, toUpdateUserIds.Length);
|
return (added, toUpdateUserIds.Length);
|
||||||
|
|
|
@ -278,15 +278,15 @@ public partial class Administration
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
public Task WarnDelete(IGuildUser user, int index)
|
public Task WarnDelete(IGuildUser user, int index)
|
||||||
=> WarnDelete(user.Id, index);
|
=> WarnDelete(user.Id, index);
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPermission.Administrator)]
|
||||||
public async Task WarnDelete(ulong userId, int index)
|
public async Task WarnDelete(ulong userId, int index)
|
||||||
{
|
{
|
||||||
if (--index < 0)
|
if (--index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var warn = await _service.WarnDelete(userId, index);
|
var warn = await _service.WarnDelete(userId, index);
|
||||||
|
|
||||||
if (warn is null)
|
if (warn is null)
|
||||||
|
@ -294,7 +294,7 @@ public partial class Administration
|
||||||
await Response().Error(strs.warning_not_found).SendAsync();
|
await Response().Error(strs.warning_not_found).SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Response().Confirm(strs.warning_deleted(Format.Bold(index.ToString()))).SendAsync();
|
await Response().Confirm(strs.warning_deleted(Format.Bold(index.ToString()))).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ public partial class Administration
|
||||||
{
|
{
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var success = await _service.WarnClearAsync(ctx.Guild.Id, userId, index, ctx.User.ToString());
|
var success = await _service.WarnClearAsync(ctx.Guild.Id, userId, index, ctx.User.ToString());
|
||||||
var userStr = Format.Bold((ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString());
|
var userStr = Format.Bold((ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString());
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
|
|
|
@ -243,54 +243,43 @@ public class UserPunishService : IEService, IReadyExecutor
|
||||||
public async Task CheckAllWarnExpiresAsync()
|
public async Task CheckAllWarnExpiresAsync()
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
|
var cleared = await uow.Set<Warning>()
|
||||||
var toClear = await uow.GetTable<Warning>()
|
.Where(x => uow.Set<GuildConfig>()
|
||||||
.Where(x => uow.GetTable<GuildConfig>()
|
.Any(y => y.GuildId == x.GuildId
|
||||||
.Count(y => y.GuildId == x.GuildId
|
&& y.WarnExpireHours > 0
|
||||||
&& y.WarnExpireHours > 0
|
&& y.WarnExpireAction == WarnExpireAction.Clear)
|
||||||
&& y.WarnExpireAction == WarnExpireAction.Clear)
|
|
||||||
> 0
|
|
||||||
&& x.Forgiven == false
|
&& x.Forgiven == false
|
||||||
&& x.DateAdded
|
&& x.DateAdded
|
||||||
< DateTime.UtcNow.AddHours(-uow.GetTable<GuildConfig>()
|
< DateTime.UtcNow.AddHours(-uow.Set<GuildConfig>()
|
||||||
.Where(y => x.GuildId == y.GuildId)
|
.Where(y => x.GuildId == y.GuildId)
|
||||||
.Select(y => y.WarnExpireHours)
|
.Select(y => y.WarnExpireHours)
|
||||||
.First()))
|
.First()))
|
||||||
.Select(x => x.Id)
|
.UpdateAsync(_ => new()
|
||||||
.ToListAsyncLinqToDB();
|
{
|
||||||
|
Forgiven = true,
|
||||||
|
ForgivenBy = "expiry"
|
||||||
|
});
|
||||||
|
|
||||||
var cleared = await uow.GetTable<Warning>()
|
var deleted = await uow.Set<Warning>()
|
||||||
.Where(x => toClear.Contains(x.Id))
|
.Where(x => uow.Set<GuildConfig>()
|
||||||
.UpdateAsync(_ => new()
|
.Any(y => y.GuildId == x.GuildId
|
||||||
{
|
&& y.WarnExpireHours > 0
|
||||||
Forgiven = true,
|
&& y.WarnExpireAction == WarnExpireAction.Delete)
|
||||||
ForgivenBy = "expiry"
|
&& x.DateAdded
|
||||||
});
|
< DateTime.UtcNow.AddHours(-uow.Set<GuildConfig>()
|
||||||
|
.Where(y => x.GuildId == y.GuildId)
|
||||||
var toDelete = await uow.GetTable<Warning>()
|
.Select(y => y.WarnExpireHours)
|
||||||
.Where(x => uow.GetTable<GuildConfig>()
|
.First()))
|
||||||
.Count(y => y.GuildId == x.GuildId
|
.DeleteAsync();
|
||||||
&& y.WarnExpireHours > 0
|
|
||||||
&& y.WarnExpireAction == WarnExpireAction.Delete)
|
|
||||||
> 0
|
|
||||||
&& x.DateAdded
|
|
||||||
< DateTime.UtcNow.AddHours(-uow.GetTable<GuildConfig>()
|
|
||||||
.Where(y => x.GuildId == y.GuildId)
|
|
||||||
.Select(y => y.WarnExpireHours)
|
|
||||||
.First()))
|
|
||||||
.Select(x => x.Id)
|
|
||||||
.ToListAsyncLinqToDB();
|
|
||||||
|
|
||||||
var deleted = await uow.GetTable<Warning>()
|
|
||||||
.Where(x => toDelete.Contains(x.Id))
|
|
||||||
.DeleteAsync();
|
|
||||||
|
|
||||||
if (cleared > 0 || deleted > 0)
|
if (cleared > 0 || deleted > 0)
|
||||||
{
|
{
|
||||||
Log.Information("Cleared {ClearedWarnings} warnings and deleted {DeletedWarnings} warnings due to expiry",
|
Log.Information("Cleared {ClearedWarnings} warnings and deleted {DeletedWarnings} warnings due to expiry",
|
||||||
cleared,
|
cleared,
|
||||||
toDelete.Count);
|
deleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await uow.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CheckWarnExpiresAsync(ulong guildId)
|
public async Task CheckWarnExpiresAsync(ulong guildId)
|
||||||
|
@ -513,12 +502,12 @@ public class UserPunishService : IEService, IReadyExecutor
|
||||||
await ctx.Set<BanTemplate>()
|
await ctx.Set<BanTemplate>()
|
||||||
.ToLinqToDBTable()
|
.ToLinqToDBTable()
|
||||||
.InsertOrUpdateAsync(() => new()
|
.InsertOrUpdateAsync(() => new()
|
||||||
{
|
{
|
||||||
GuildId = guildId,
|
GuildId = guildId,
|
||||||
Text = null,
|
Text = null,
|
||||||
DateAdded = DateTime.UtcNow,
|
DateAdded = DateTime.UtcNow,
|
||||||
PruneDays = pruneDays
|
PruneDays = pruneDays
|
||||||
},
|
},
|
||||||
old => new()
|
old => new()
|
||||||
{
|
{
|
||||||
PruneDays = pruneDays
|
PruneDays = pruneDays
|
||||||
|
|
|
@ -6,6 +6,49 @@ namespace EllieBot.Modules.EllieExpressions;
|
||||||
|
|
||||||
public static class EllieExpressionExtensions
|
public static class EllieExpressionExtensions
|
||||||
{
|
{
|
||||||
|
private static string ResolveTriggerString(this string str, DiscordSocketClient client)
|
||||||
|
=> str.Replace("%bot.mention%", client.CurrentUser.Mention, StringComparison.Ordinal);
|
||||||
|
|
||||||
|
public static async Task<IUserMessage> Send(
|
||||||
|
this EllieExpression cr,
|
||||||
|
IUserMessage ctx,
|
||||||
|
IReplacementService repSvc,
|
||||||
|
DiscordSocketClient client,
|
||||||
|
IMessageSenderService sender)
|
||||||
|
{
|
||||||
|
var channel = cr.DmResponse ? await ctx.Author.CreateDMChannelAsync() : ctx.Channel;
|
||||||
|
|
||||||
|
var trigger = cr.Trigger.ResolveTriggerString(client);
|
||||||
|
var substringIndex = trigger.Length;
|
||||||
|
if (cr.ContainsAnywhere)
|
||||||
|
{
|
||||||
|
var pos = ctx.Content.AsSpan().GetWordPosition(trigger);
|
||||||
|
if (pos == WordPosition.Start)
|
||||||
|
substringIndex += 1;
|
||||||
|
else if (pos == WordPosition.End)
|
||||||
|
substringIndex = ctx.Content.Length;
|
||||||
|
else if (pos == WordPosition.Middle)
|
||||||
|
substringIndex += ctx.Content.IndexOf(trigger, StringComparison.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
var canMentionEveryone = (ctx.Author as IGuildUser)?.GuildPermissions.MentionEveryone ?? true;
|
||||||
|
|
||||||
|
var repCtx = new ReplacementContext(client: client,
|
||||||
|
guild: (ctx.Channel as ITextChannel)?.Guild as SocketGuild,
|
||||||
|
channel: ctx.Channel,
|
||||||
|
users: ctx.Author
|
||||||
|
)
|
||||||
|
.WithOverride("%target%",
|
||||||
|
() => canMentionEveryone
|
||||||
|
? ctx.Content[substringIndex..].Trim()
|
||||||
|
: ctx.Content[substringIndex..].Trim().SanitizeMentions(true));
|
||||||
|
|
||||||
|
var text = SmartText.CreateFrom(cr.Response);
|
||||||
|
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||||
|
|
||||||
|
return await sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static WordPosition GetWordPosition(this ReadOnlySpan<char> str, in ReadOnlySpan<char> word)
|
public static WordPosition GetWordPosition(this ReadOnlySpan<char> str, in ReadOnlySpan<char> word)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,10 +11,10 @@ public partial class EllieExpressions : EllieModule<EllieExpressionsService>
|
||||||
All
|
All
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IBotCreds _creds;
|
private readonly IBotCredentials _creds;
|
||||||
private readonly IHttpClientFactory _clientFactory;
|
private readonly IHttpClientFactory _clientFactory;
|
||||||
|
|
||||||
public EllieExpressions(IBotCreds creds, IHttpClientFactory clientFactory)
|
public EllieExpressions(IBotCredentials creds, IHttpClientFactory clientFactory)
|
||||||
{
|
{
|
||||||
_creds = creds;
|
_creds = creds;
|
||||||
_clientFactory = clientFactory;
|
_clientFactory = clientFactory;
|
||||||
|
@ -57,14 +57,14 @@ public partial class EllieExpressions : EllieModule<EllieExpressionsService>
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
public async Task ExprAddServer(string trigger, [Leftover] string response)
|
public async Task ExprAddServer(string key, [Leftover] string message)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(response) || string.IsNullOrWhiteSpace(trigger))
|
if (string.IsNullOrWhiteSpace(message) || string.IsNullOrWhiteSpace(key))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ExprAddInternalAsync(trigger, response);
|
await ExprAddInternalAsync(key, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -401,9 +401,10 @@ public partial class EllieExpressions : EllieModule<EllieExpressionsService>
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[Ratelimit(300)]
|
|
||||||
public async Task ExprsImport([Leftover] string input = null)
|
public async Task ExprsImport([Leftover] string input = null)
|
||||||
{
|
{
|
||||||
|
// todo cooldown on public bot for 1 day, limit 100
|
||||||
|
|
||||||
if (!AdminInGuildOrOwnerInDm())
|
if (!AdminInGuildOrOwnerInDm())
|
||||||
{
|
{
|
||||||
await Response().Error(strs.expr_insuff_perms).SendAsync();
|
await Response().Error(strs.expr_insuff_perms).SendAsync();
|
||||||
|
|
|
@ -249,54 +249,46 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (guild is not SocketGuild sg)
|
if (guild is SocketGuild sg)
|
||||||
return false;
|
|
||||||
|
|
||||||
var result = await _permChecker.CheckPermsAsync(
|
|
||||||
guild,
|
|
||||||
msg.Channel,
|
|
||||||
msg.Author,
|
|
||||||
"ACTUALEXPRESSIONS",
|
|
||||||
expr.Trigger
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!result.IsAllowed)
|
|
||||||
{
|
{
|
||||||
var cache = _pc.GetCacheFor(guild.Id);
|
var result = await _permChecker.CheckPermsAsync(
|
||||||
if (cache.Verbose)
|
guild,
|
||||||
|
msg.Channel,
|
||||||
|
msg.Author,
|
||||||
|
"ACTUALEXPRESSIONS",
|
||||||
|
expr.Trigger
|
||||||
|
);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cu = sg.CurrentUser;
|
var sentMsg = await expr.Send(msg, _repSvc, _client, _sender);
|
||||||
|
|
||||||
var channel = expr.DmResponse ? await msg.Author.CreateDMChannelAsync() : msg.Channel;
|
|
||||||
|
|
||||||
// have no perms to speak in that channel
|
|
||||||
if (channel is ITextChannel tc && !cu.GetPermissions(tc).SendMessages)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var sentMsg = await Send(expr, msg, channel);
|
|
||||||
|
|
||||||
var reactions = expr.GetReactions();
|
var reactions = expr.GetReactions();
|
||||||
foreach (var reaction in reactions)
|
foreach (var reaction in reactions)
|
||||||
|
@ -344,47 +336,6 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public string ResolveTriggerString(string str)
|
|
||||||
=> str.Replace("%bot.mention%", _client.CurrentUser.Mention, StringComparison.Ordinal);
|
|
||||||
|
|
||||||
public async Task<IUserMessage> Send(
|
|
||||||
EllieExpression cr,
|
|
||||||
IUserMessage ctx,
|
|
||||||
IMessageChannel channel
|
|
||||||
)
|
|
||||||
{
|
|
||||||
var trigger = ResolveTriggerString(cr.Trigger);
|
|
||||||
var substringIndex = trigger.Length;
|
|
||||||
if (cr.ContainsAnywhere)
|
|
||||||
{
|
|
||||||
var pos = ctx.Content.AsSpan().GetWordPosition(trigger);
|
|
||||||
if (pos == WordPosition.Start)
|
|
||||||
substringIndex += 1;
|
|
||||||
else if (pos == WordPosition.End)
|
|
||||||
substringIndex = ctx.Content.Length;
|
|
||||||
else if (pos == WordPosition.Middle)
|
|
||||||
substringIndex += ctx.Content.IndexOf(trigger, StringComparison.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
var canMentionEveryone = (ctx.Author as IGuildUser)?.GuildPermissions.MentionEveryone ?? true;
|
|
||||||
|
|
||||||
var repCtx = new ReplacementContext(client: _client,
|
|
||||||
guild: (ctx.Channel as ITextChannel)?.Guild as SocketGuild,
|
|
||||||
channel: ctx.Channel,
|
|
||||||
user: ctx.Author
|
|
||||||
)
|
|
||||||
.WithOverride("%target%",
|
|
||||||
() => canMentionEveryone
|
|
||||||
? ctx.Content[substringIndex..].Trim()
|
|
||||||
: ctx.Content[substringIndex..].Trim().SanitizeMentions(true));
|
|
||||||
|
|
||||||
var text = SmartText.CreateFrom(cr.Response);
|
|
||||||
text = await _repSvc.ReplaceAsync(text, repCtx);
|
|
||||||
|
|
||||||
return await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ResetExprReactions(ulong? maybeGuildId, int id)
|
public async Task ResetExprReactions(ulong? maybeGuildId, int id)
|
||||||
{
|
{
|
||||||
EllieExpression expr;
|
EllieExpression expr;
|
||||||
|
@ -838,7 +789,7 @@ public sealed class EllieExpressionsService : IExecOnMessage, IReadyExecutor
|
||||||
|
|
||||||
if (newguildExpressions.TryGetValue(guildId, out var exprs))
|
if (newguildExpressions.TryGetValue(guildId, out var exprs))
|
||||||
{
|
{
|
||||||
return (exprs.Where(x => x.Trigger.Contains(query) || x.Response.Contains(query))
|
return (exprs.Where(x => x.Trigger.Contains(query))
|
||||||
.Skip(page * 9)
|
.Skip(page * 9)
|
||||||
.Take(9)
|
.Take(9)
|
||||||
.ToArray(), exprs.Length);
|
.ToArray(), exprs.Length);
|
||||||
|
|
|
@ -73,7 +73,7 @@ public partial class Gambling
|
||||||
await Response().Error(strs.cant_dm).SendAsync();
|
await Response().Error(strs.cant_dm).SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public async Task BankBalance([Leftover] IUser user)
|
public async Task BankBalance([Leftover] IUser user)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue