Compare commits

...

135 Commits

Author SHA1 Message Date
Kwoth
e40c9335c1 add: Added fishing skill stat
fix: fixed fishing spot calculation
change: patrons no longer have captchas on the public bot
docs: Upped version to 5.3.6
2025-01-20 00:48:37 +00:00
Kwoth
d921b6889d docs: Updated changelog, upped version to 5.3.5 2025-01-17 14:35:16 +00:00
Kwoth
aaef365bdc fix: .deletewaifus should now work 2025-01-17 13:14:21 +00:00
Kwoth
a01a646cbf fix: .sar rm will now accept role ids, in the role is deleted 2025-01-17 13:13:28 +00:00
Kwoth
5bee5e63d2 fix: fixed .fish description 2025-01-16 00:38:40 +00:00
Kwoth
815e318610 change: nerfed drops further as they're way too common 2025-01-14 19:39:42 +00:00
Kwoth
634c6c99ee fix: fixed spot calculation, reduced droprates 2025-01-14 03:55:32 +00:00
Kwoth
6b37b49439 Merge branch 'exit-code' into 'v5'
Exit with status code 0 on graceful shutdowns

See merge request Kwoth/nadekobot!334
2025-01-14 03:10:12 +00:00
Kaoticz
f42afa7eae Exit with status code 0 on graceful shutdowns 2025-01-14 03:10:12 +00:00
Kwoth
ccae1c59e9 docs: Updated changelog, upped version to 5.3.4 2025-01-14 03:05:43 +00:00
Kwoth
b0d8137a7a add: Added .fish command 2025-01-14 03:00:31 +00:00
Kwoth
e78a7d0efa change: adding a role to a sar group which already exists in another group will simply move it, instead of reporting success but not doing anything 2024-12-27 07:00:06 +00:00
Kwoth
1da19a51f6 fix: postgresql will skip the sar migration, users will have to re-do them 2024-12-26 17:55:25 +00:00
Kwoth
91eed9dbd8 fix: fixed iam with exclusive roles (in some cases?) being broken 2024-12-20 06:54:56 +00:00
Kwoth
7ba345b0fc docs: updated changelog, updated version 2024-12-15 13:18:51 +00:00
Kwoth
5d775c9589 Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-12-15 13:14:16 +00:00
Kwoth
2bd8ead10c Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-12-15 13:13:59 +00:00
Kwoth
1148ba3e6e Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-12-14 15:33:23 +00:00
Kwoth
5498bec8cc fix: .banner fixed, will now show guild banner if available, otherwise global banner, if available 2024-12-14 15:33:09 +00:00
Kwoth
9eed0c6be5 fix: .banner fixed, will now show guild banner if available, otherwise global banner, if available 2024-12-14 15:31:05 +00:00
Kwoth
acf6b7cf58 docs: updated changelog, updated version 2024-12-13 08:28:55 +00:00
Kwoth
8598419c5f fix: .dmcmd will now correctly block commands in dms, not globally
change: timely will no longer require guild context, as dmcmd .timely will do the same thing
2024-12-13 08:22:13 +00:00
Kwoth
758093eb32 fix: bannersize fixed, honeypot will now put 'Honeypot' as a ban reason 2024-12-12 08:56:45 +00:00
Kwoth
f44dd03f1a fix: .sclr will now correctly show the color without alpha prefixed 2024-12-11 23:06:01 +00:00
Kwoth
8ac5ec9f57 fix: .banner will now show a 'no banner' error, and will use image embed instead of thumbnail to show the banner. Only user server banners will be shown for now, global user banners will still not work. 2024-12-11 23:00:59 +00:00
Kwoth
5209ba802a change: winlb now has 9 items per page to look not broken 2024-12-11 17:21:25 +00:00
Kwoth
adfce6670c change: winlb now has a title 2024-12-11 17:13:59 +00:00
Kwoth
f8fbc71985 change: added role icon to .inrole, .winlb will now show userids when user can't be found 2024-12-10 14:16:24 +00:00
Kwoth
d4e2516a17 change: winlb embed fields are now inline to use less space 2024-12-10 11:24:02 +00:00
Kwoth
f62a67e2e6 docs: Updated commandlist 2024-12-10 07:20:47 +00:00
Kwoth
7895b5e702 fix: .translate will now use 2 embeds 2024-12-10 07:17:49 +00:00
Kwoth
28c8ccfb5f fix: .sar ex had an outdated description 2024-12-10 07:12:10 +00:00
Kwoth
79026e0c27 fix: .winlb looks better when there are no items 2024-12-09 17:31:23 +00:00
Kwoth
8b228b840a docs: slight docs improvement, added windows from source guide in the menu, separated it from the windows installer guide 2024-12-09 14:54:52 +00:00
Kwoth
f61c1a159d docs: fixed docs 2024-12-09 14:43:55 +00:00
Kwoth
2cdcdb2b23 dev: Fix tests 2024-12-07 16:54:18 +00:00
Kwoth
8d0a3ecb20 docs: Updated changelog.md 2024-12-07 16:51:02 +00:00
Kwoth
97f1405a94 add: added addrolereward and removerolereward events for .notify
add: added .notify with no params showing events with descriptions
add: .winlb
docs: updated docs
dev: updated discord.net, redid migrations
2024-12-07 16:46:06 +00:00
Kwoth
0622236523 add: Added .notify and migrations, added levelup and protection events for notify, removed xpnotify completely 2024-12-05 14:35:42 +00:00
Kwoth
0f240925e8 add: notify, minesweeper, migrations
dev: renames, refactors
change: remind optimized wait
2024-12-03 14:13:31 +00:00
Kwoth
d583e2b99a change: QUeueing a song after the queue is finished will restart the playback 2024-12-02 03:21:43 +00:00
Kwoth
2d72f6f498 add: Added .dmmod and .dmcmd to disable modules and commands in bot DMs 2024-12-02 02:20:33 +00:00
Kwoth
5143e42dff add: Added .xplevelset
remove: removed awardedxp from database.
change: .sclr show will now show hex
change: .awardxp will now add directly to user's real xp
2024-12-01 03:57:31 +00:00
Kwoth
790c36df8d fix: .setstream and .setactivity will now pause .ropl 2024-11-30 10:02:08 +00:00
Kwoth
15709bc8fb change: Finished giveaway will now reply to the giveaway message and ping a winner 2024-11-29 08:52:47 +00:00
Kwoth
f280f72227 fix: fixed giveaway load broken in the last patch 2024-11-29 08:50:55 +00:00
Kwoth
4069368beb change: added ending date for givaway as a timestamp tag
fixed: fixed an issue with flag translates
2024-11-28 08:55:53 +00:00
Kwoth
e036a2d3c9 fix: fixed .sclr again, again, and fixed .iamn 2024-11-27 03:26:57 +00:00
Kwoth
62a16f3faf fix: fixed .iam
fix: fixed .sclr not being respected on many different commands
change: .rps now also has the amount bet
2024-11-27 02:41:05 +00:00
Kwoth
231451f978 fix: fixed .sclr again 2024-11-27 01:28:17 +00:00
Kwoth
2bed4e7eac fix: Fixed many issues with 5.2.0 2024-11-27 01:23:38 +00:00
Kwoth
22eea3fa7b docs: updated changelog 2024-11-26 23:49:32 +00:00
Kwoth
8b1767078e fix: fixed sar migration 2024-11-26 23:31:27 +00:00
Kwoth
6654ccdad5 docs: updated commandlist 2024-11-26 20:56:49 +00:00
Kwoth
99827b0fa1 change: MessageXpCooldown is not in seconds 2024-11-26 19:58:20 +00:00
Kwoth
0451551ddf change: .gc will now remove previous plants with the same pw length from the channel and add them to itself. This is to avoid missed gcs. The amount text will be wrong however, as it will only show how much flowers spawned now. The user will get full amount of all gcs previously 2024-11-26 17:02:09 +00:00
Kwoth
75d0eb631d change: gambling commands now show amount bet. Slightly changed the layout. Updated some gambling strings
add: added .btr excl
2024-11-26 04:50:56 +00:00
Kwoth
96ce7e23bb Merge branch '520' into v5 2024-11-21 22:28:08 +00:00
Kwoth
aac475be62 fix: fixed time conversion 2024-11-21 19:02:22 +00:00
Kwoth
55fae53f6d fix: fixed time conversion 2024-11-21 19:00:36 +00:00
Kwoth
879f196f8b dev: new method in rotating service 2024-11-21 18:59:31 +00:00
Kwoth
796086538a .btr and .sclr added, cleanup 2024-11-20 17:16:41 +00:00
Kwoth
3178074828 fix: fixed .sinfo for guilds on other shards 2024-11-19 18:03:12 +00:00
Kwoth
0a9d53d380 change: sar rework, improved 2024-11-17 23:36:11 +00:00
Kwoth
d7fbf44d53 fix: re-added a missing extension method 2024-11-17 19:32:41 +00:00
Kwoth
cdd07d0559 fix: fixed accidental rename in previous patch 2024-11-17 19:17:04 +00:00
Kwoth
80a41c1f38 fix: fixed nullref in blacklist 2024-11-17 19:14:40 +00:00
Kwoth
1631394638 change: .bsreset price reduced 10x 2024-11-12 10:48:03 +00:00
Kwoth
7eb4895570 fix: fixed update usernames query 2024-11-12 01:09:06 +00:00
Kwoth
9b55028ba6 fix: fixed command description for betroll 2024-11-10 23:03:04 +00:00
Kwoth
53363d2840 fix: fixed newline missing in .timely 2024-11-10 22:31:48 +00:00
Kwoth
ca5a870bf8 docs: updated changelog 2024-11-10 16:08:26 +00:00
Kwoth
7f5e065c4d docs: updated commandlist, version upped to 5.1.20 2024-11-10 15:56:43 +00:00
Kwoth
86b214163a fix: typo 2024-11-10 12:28:06 +00:00
Kwoth
9dbb08d85f add: added .snipe command
add: added .gsreset and .bsreset commands
change: improved .timely rewards for patrons
dev: Improved how blacklist works under the hood
2024-11-08 18:24:50 +00:00
Kwoth
89ca56c77c fix: rich logging fix for userids, updated commandlist
add: added bot.date and changed bot.time placeholder. They use timestamp tags now.
fix: fixed double log on server leave
2024-11-07 05:38:22 +00:00
Kwoth
9e96679099 change: patreon reward bonuses increased slightly 2024-11-06 07:10:12 +00:00
Kwoth
1280d2b397 change: .divorce no longer has a cooldown
add: Added .waifuclaims / .claims command which lists your waifus (name, price and ids)
change: Timely now shows patreon multiplier bonus if there is any, (alongside boost)
2024-11-06 05:20:04 +00:00
Kwoth
c731127607 fix: missing example in commands 2024-11-05 09:40:01 +00:00
Kwoth
c15930306a fix: fix pipeline, missing aliases 2024-11-05 09:34:01 +00:00
Kwoth
701501d678 add: added .rakeback to get a part of the house edge back. Rakeback is accumulated by betting (not winning or losing in particular). All games have manually specified rakeback values
add: slot now has 1 more icon (wheat!), and multipliers have been modified to even out the gains
change: betroll is improved (around 2% better payout), as 66 is now a winning number, not a losing one
2024-11-05 08:24:21 +00:00
Kwoth
fa12fcea58 change: .race will now have 82-94% payout rate based on the number of players playign (1-12, x0.01 per player). Any player over 12 won't increase payout 2024-11-05 04:27:27 +00:00
Kwoth
274219c40b docs: Upped version to 5.1.19, updated changelog
fix: Fixed timely on different shards
2024-11-05 02:57:01 +00:00
Kwoth
96c9b47da2 add: timely now has an option in gambling whether to use no protection, captcha, or button.
fix: grpc api fix for dashy
2024-11-04 14:35:59 +00:00
Kwoth
b5d1469df1 Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-11-04 12:28:52 +00:00
Kwoth
d7747bd25a fix: timely fixes 2024-11-04 12:28:42 +00:00
Kwoth
7d162d1f04 fix: timely fixes 2024-11-04 12:28:01 +00:00
Kwoth
704d061d46 fix: fixed pipeline, added missing strings 2024-11-04 10:58:44 +00:00
Kwoth
c39c9061fd add: added timely boost bonus to gambling.yml
change: .betstats renamed to .gamblestats/.gs
add: added .betstats, .betstats <game> and .betstats <user> <game?> command which shows you your stats for gambling commands
2024-11-04 10:42:05 +00:00
Kwoth
619ddba4f8 fix: fixed pagination numbers in xplb and xpglb 2024-11-04 02:03:53 +00:00
Kwoth
3acef04b32 change: strikeout slightly thinner to make password easier to read on plants 2024-11-03 13:45:12 +00:00
Kwoth
83a1d959b1 fix: Added nordic and ugro finnic languages to flag translate 2024-11-03 12:05:51 +00:00
Kwoth
a1632722bc fix: fix timely 2024-11-03 09:32:43 +00:00
Kwoth
ee0a28afab fix: revert patron migration temporarily as ef core is bugging out hard 2024-11-03 08:39:37 +00:00
Kwoth
2b301c0aab fix: possible fix for patron table 2024-11-03 08:31:23 +00:00
Kwoth
b6b6b4e19e fix: Fixed UserId patron table error
fix: Added au and kz countries as en and kz languages respectively
fix: Strikeout is thinner now on plants
2024-11-03 08:24:00 +00:00
Kwoth
32fc8b6e03 docs: Upped version to 5.1.18, updated changelog 2024-11-03 03:44:33 +00:00
Kwoth
297e2fde0e change: timely 'password' is now a button 2024-11-03 03:41:34 +00:00
Kwoth
729f26caab button for timely 2024-11-03 02:48:39 +00:00
Kwoth
4b12e4e923 dev: Removed discrim from the database
add: .translateflags command
add: captcha to timely, configurable in .conf gambling
change: change bonuses for patreon rewards
fix: nunchi message color fix
2024-11-02 16:23:58 +00:00
Kwoth
12f4ce7f2a change: animal race will update more frequently, but animals will move slightly slower. Overall everything will be slightly faster 2024-11-01 04:53:20 +00:00
Kwoth
00944e08c3 fix: .ncs will now show an error if setting a pixel fails 2024-11-01 04:52:29 +00:00
Kwoth
569abd7194 api: work on server xp api 2024-10-31 11:48:31 +00:00
Kwoth
474a1db41d add: timely now has a 3 letter password by default. Configurable via .conf gamb 2024-10-31 11:48:09 +00:00
Kwoth
0f6255947e fix: fixed ubl pagination 2024-10-30 13:16:04 +00:00
Kwoth
f68f219a25 fix: ytdataapiv3 searches will no longer duplicate youtube urls 2024-10-30 07:02:13 +00:00
Kwoth
8f16b11d02 api: finance api implementation 2024-10-29 08:15:53 +00:00
Kwoth
df5eced904 change: Error sending greet dm will now be a warning
change: initial canvas price down to 3 from 10, 10 is way too expensive
2024-10-29 01:53:42 +00:00
Kwoth
1dcd158f43 fix: Bot will now not accept .aar Role if that Role is higher than or equal to bot's role. Previously bot would just fail silently, now there is a proper error message. 2024-10-28 21:42:05 +00:00
Kwoth
757c9b564d Updated changelog. Version upped to 5.1.16 2024-10-28 08:21:27 +00:00
Kwoth
07cef3eb5e Added .nc and related commands.
You can set pixel colors (and text) on a 500x350 canvas, pepega version of r/place
You use currency to set pixels.
see whole canvas: .nc
set pixel: .ncsp <pos> <color> <text?>
get pixel: .ncp <pos>
zoom: .ncz <pos> or .ncz x y
2024-10-28 08:17:23 +00:00
Kwoth
85c525e19b api: added command feed and shard update feed 2024-10-23 21:29:40 +00:00
Kwoth
477581f616 docs: Updated CHANGELOG, upped version to 5.1.15 2024-10-21 14:29:08 +00:00
Kwoth
ff30105816 fix: Fixed several features which weren't getting loaded on startup 2024-10-21 14:15:42 +00:00
Kwoth
49f04a594b fix: fixed expire settings not returned on api 2024-10-21 04:36:54 +00:00
Kwoth
716090a132 fix: fix migration incase there is invalid data 2024-10-21 04:08:33 +00:00
Kwoth
c835514c7b dev: split warn punishments into a separate table
api: Added warn endpoints
fix: Reminders should now be able to ping everyone if the user who created the reminder has that permission
2024-10-21 03:14:46 +00:00
Kwoth
b136e7ff0e fix: author name will be counted as content in embeds. Embeds will now be valid if they only have an author specified 2024-10-19 19:21:00 +00:00
Kwoth
9dd2997b0f dev: added botonguild api endpoint 2024-10-16 15:15:41 +00:00
Kwoth
fde5309ea4 dev: added quote api 2024-10-16 01:52:56 +00:00
Kwoth
a8e4173e9b fix: grpc api fix 2024-10-13 21:37:58 +00:00
Kwoth
74b4c4b64d change: cleanup command will now also clear greetsettings and autpublish channels
dev: Cleaned up some comments, changed grpc api
2024-10-10 16:01:49 +00:00
Kwoth
6cc5a160a2 fix: .greetmsg (and related commands) and .greettest (and other greet test commands) will now show the correct response string when the toggle is disabled 2024-10-07 20:02:43 +00:00
Kwoth
ca8e022db6 fix: .waifulb will no longer show #0000 discriminators, for real this time 2024-10-07 12:56:28 +00:00
Kwoth
cd8c14c607 change: Leaderboards will show 10 users per page 2024-10-07 09:07:32 +00:00
Kwoth
1340533c21 fix: fix cleanup migration 2024-10-06 14:17:26 +00:00
Kwoth
14d86b9042 fix: grpc api fix 2024-10-04 03:31:44 +00:00
Kwoth
3a504a954f add: Added options '-c' option for '.xpglb' which will show global xp leaderboard only with this server's users 2024-10-04 03:24:18 +00:00
Kwoth
822ce0b8de fix: Alias collision fixed, .qse will be quotesearch, .qs will remain queuesearch (music)
fix: Improved guild config cleanup migration by removing invalid Permissiosnv2 entries (thx Leon)
2024-10-04 02:00:46 +00:00
Kwoth
40490a4656 docs: Version upped to 5.1.14, updated CHANGELOG.md 2024-10-03 13:01:11 +00:00
Kwoth
0cf7909fef change: improved .xplb -c, it will now correctly work only on users who are still in the server, isntead of only top 1k
fix: Fixed medusa error on bot startup
2024-10-03 12:58:45 +00:00
Kwoth
de8d4b7d9e docs: Version upped to 5.1.13, updated CHANGELOG.md
fix: Fixed seq comment in creds
2024-10-03 12:05:16 +00:00
Kwoth
0123892038 fix: Grpc api will no longer start unless it's enabled in creds 2024-10-03 11:59:47 +00:00
Kwoth
d00e59567a fix: Fixed greet/bye messages showing wrong message in the wrong server sometimes
docs: Version upped to 5.1.12. Updated CHANGELOG.md
2024-10-03 11:31:28 +00:00
Kwoth
0aba2fdcaf fix: expressions will no longer cause exceptions if the bot doesn't have perms to write in the target channel
dev: Cleaned up expr code a little bit
2024-10-03 03:07:57 +00:00
332 changed files with 84368 additions and 3434 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
# Config
`.config` is the new `.bce`, it gives you a fast and easy way to edit most bot settings/values. Use `.h .config` for explanation.
`.config` gives you a fast and easy way to edit most bot settings/values. Use `.h .config` for explanation.
Use `.config` to see the list of editable config files
Use `.config <config-name>` to see the list of settable properties on that config

View File

@@ -1,27 +1,30 @@
## Creds Guide
This document aims to guide you through the process of creating a Discord account for your bot
(the Discord Bot application), and inviting that account into your Discord server.
This guide will show you how to create your own discord bot, invite it to your server, and copy it's credentials to your `creds.yml` in order to run your bot.
- Start by opening your creds.yml
- If you're on a windows installer version, click on the creds button next to your bot's RUN button.
- If you're on linux from source or windows from source version, open `nadekobot/output/creds.yml`. Please use visual studio code, notepad++ or another code editor. Usage of notepad is discouraged.
![Create a bot application and copy token to creds.yml file](https://cdn.nadeko.bot/tutorial/bot-creds-guide.gif)
- Go to [the Discord developer application page][DiscordApp].
- Log in with your Discord account.
- Click **New Application**.
- Fill out the `Name` field however you like.
- Go to the **Bot** tab on the left sidebar.
- Click on the `Add a Bot` button and confirm that you do want to add a bot to this app.
- **Optional:** Add bot's avatar and description.
- Copy your Token to `creds.yml` as shown above.
- Scroll down to the **`Privileged Gateway Intents`** section
- **Enable the following:**
1. Go to [the Discord developer application page][DiscordApp].
2. Log in with your Discord account.
3. Click **New Application**.
3. Fill out the `Name` field however you like, accept the terms, and confirm.
1. Go to the **Bot** tab on the left sidebar.
1. Click on the `Add a Bot` button and confirm that you do want to add a bot to this app.
1. **Optional:** Add bot's avatar and description.
1. Copy your Token to `creds.yml` as shown above.
1. Scroll down to the **`Privileged Gateway Intents`** section
- Enable the following:
- **PRESENCE INTENT**
- **SERVER MEMBERS INTENT**
- **MESSAGE CONTENT INTENT**
These are required for a number of features to function properly, and all should be on.
##### Getting Owner ID*(s)*:
##### Getting Owner ID
- Go to your Discord server and attempt to mention yourself, but put a backslash at the start
*(to make it slightly easier, add the backslash after the mention has been typed)*.

View File

@@ -7,10 +7,9 @@ Donations go a long way in helping us keep the project alive, and we appreciate
Donating to us also gives you the following benefits:
- A hoisted **Donators role** in our [Discord server][discord-server]
- A hoisted **Patron** role in [Nadeko Discord server][discord-server]
- Access to exclusive **#noticed** text and voice channels
- **1000 flowers** on the public bot per dollar donated (after fees)
- **Expressions** on the public bot for [Patreon pledges][patreon] of $5 or higher
- **3000 flowers** on the public bot per dollar donated (after fees)
## Patreon
@@ -26,7 +25,7 @@ You can set up a monthly pledge on [Patreon][patreon] and support the project's
You can also donate to us through [PayPal][paypal] for one-time donations using the button below, or by donating to `nadekodiscordbot@gmail.com`.
!!! Note
Mention your Discord tag (Username#1234) in the payment note to receive flower rewards.
Mention your Discord username or user id in the payment note to receive flower rewards.
[![img][paypal-button]][paypal]

View File

@@ -1,11 +1,11 @@
## Setting Up NadekoBot on Windows With the Updater
| Table of Contents|
| :---------------------------------------------------------------------------------------------------------------------------|
| [Prerequisites](#prerequisites) |
| [Setup](#setup) |
| [Starting the Bot](#starting-the-bot) |
| [Updating Nadeko](#updating-nadeko) |
| :-|
| [Prerequisites](#prerequisites) |
| [Setup](#setup) |
| [Starting the Bot](#starting-the-bot) |
| [Updating Nadeko](#updating-nadeko) |
| [Manually Installing the Prerequisites from the Updater](#music-prerequisites) |
*Note: If you want to make changes to Nadeko's source code, please follow the [From Source](#windows-from-source) guide instead.*
@@ -13,7 +13,6 @@
#### Prerequisites
- Windows 10 or later (64-bit)
- [Create a Discord Bot application and invite the bot to your server](../creds-guide.md)
**Optional**
@@ -29,8 +28,7 @@
![Create a new bot](https://i.imgur.com/JxtRk9e.png "Create a new bot")
- Click on **`DOWNLOAD`** at the lower right
![Bot Setup](https://i.imgur.com/HqAl36p.png "Bot Setup")
- **Note: Redis is optional. install Redis manually here: [Redis] Download and run the **`.msi`** file.**
- If you will use the music module, click on **`Install`** next to **`FFMPEG`** and **`Youtube-DLP`**.
- If you want to use the music module, click on **`Install`** next to **`FFMPEG`** and **`Youtube-DLP`**.
- If any dependencies fail to install, you can temporarily disable your Windows Defender/AV until you install them. If you don't want to, then read [the last section of this guide](#Manual-Prerequisite-Installation).
- When installation is finished, click on **`CREDS`** to the left of **`RUN`** at the lower right.
- Follow the guide on how to [Set up the creds.yml](../../creds-guide) file.
@@ -39,8 +37,6 @@
- Either click on **`RUN`** button in the updater or run the bot via its desktop shortcut.
### If you get a "No owner channels created..." message. Please follow the creds guide again [**HERE**](../../creds-guide).
#### Updating Nadeko
- Make sure Nadeko is closed and not running
@@ -52,71 +48,6 @@
- Launch the bot
- You've updated and are running again, easy as that!
#### Manual Prerequisite Installation
You can still install them manually:
- [Redis] (OPTIONAL) - Download and run the **`.msi`** file
- [ffmpeg-32bit] | [ffmpeg-64bit] - Download the **appropriate version** for your system (32 bit if you're running a 32 bit OS, or 64 if you're running a 64bit OS). Unzip it, and move `ffmpeg.exe` to a path that's in your PATH environment variable. If you don't know what that is, then just move the `ffmpeg.exe` file to NadekoBot/system
- [youtube-dlp] - Click to download the `yt-dlp.exe` file then put `yt-dlp.exe` in a path that's in your PATH environment variable. If you don't know what that is, then just move the `yt-dlp.exe` file to NadekoBot/system
## **⚠ IF YOU ARE FOLLOWING THE GUIDE ABOVE, IGNORE THIS SECTION ⚠**
### Windows From Source
##### Prerequisites
**Install these before proceeding or your bot will not work!**
- [.net 8](https://dotnet.microsoft.com/en-us/download) - needed to compile and run the bot
- [git](https://git-scm.com/downloads) - needed to clone the repository (you can also download the zip manually and extract it, but this guide assumes you're using git)
- [Redis] (OPTIONAL)- to cache things needed by some features and persist through restarts
##### Installation Instructions
Open PowerShell (press windows button on your keyboard and type powershell, it should show up; alternatively, right click the start menu and select Windows PowerShell), and navigate to the location where you want to install the bot (for example `cd ~/Desktop/`)
1. `git clone https://gitlab.com/kwoth/nadekobot -b v5 --depth 1`
2. `cd nadekobot`
3. `dotnet publish -c Release -o output/ src/NadekoBot/`
4. `cd output`
5. `cp creds_example.yml creds.yml`
6. Open `creds.yml` with your favorite text editor (Please don't use Notepad or WordPad. You can use Notepad++, VSCode, Atom, Sublime, or something similar)
7. [Enter your bot's token](#creds-guide)
8. Run the bot `dotnet NadekoBot.dll`
9. 🎉
##### Update Instructions
Open PowerShell as described above and run the following commands:
1. Stop the bot
- ⚠️ Make sure you don't have your database, credentials or any other nadekobot folder open in some application, this might prevent some of the steps from executing succesfully
2. Navigate to your bot's folder, example:
- `cd ~/Desktop/nadekobot`
3. Pull the new version, and make sure you're on the v5 branch
- *⚠️ the first 3 lines can be omitted if you're already on v5. If you're updating from v4, you must run them*
- `git remote set-branches origin '*'`
- `git fetch -v --depth=1`
- `git checkout v5`
- `git pull`
- ⚠️ If this fails, you may want to stash or remove your code changes if you don't know how to resolve merge conflicts
4. **Backup** old output in case your data is overwritten
- `cp -r -fo output/ output-old`
5. Build the bot again
- `dotnet publish -c Release -o output/ src/NadekoBot/`
6. Remove old strings and aliases to avoid overwriting the updated versions of those files
- ⚠ If you've modified said files, back them up instead
- `rm output-old/data/aliases.yml`
- `rm -r output-old/data/strings`
7. Copy old data
- `cp -Recurse .\output-old\data\ .\output\ -Force`
8. Copy creds.yml
- `cp output-old/creds.yml output/`
9. Run the bot
- `cd output`
- `dotnet NadekoBot.dll`
🎉 Enjoy
#### Music prerequisites
In order to use music commands, you need ffmpeg and yt-dlp installed.
@@ -131,4 +62,4 @@ In order to use music commands, you need ffmpeg and yt-dlp installed.
[Visual C++ 2017 (x64)]: https://aka.ms/vs/15/release/vc_redist.x64.exe
[ffmpeg-32bit]: https://cdn.nadeko.bot/dl/ffmpeg-32.zip
[ffmpeg-64bit]: https://cdn.nadeko.bot/dl/ffmpeg-64.zip
[youtube-dlp]: https://github.com/yt-dlp/yt-dlp/releases
[youtube-dlp]: https://github.com/yt-dlp/yt-dlp/releases

View File

@@ -0,0 +1,77 @@
## Setting Up NadekoBot on Windows from source
1. Prerequisites
- Windows 10 or later (64-bit)
- [.net 8 sdk](https://dotnet.microsoft.com/download/dotnet/8.0)
- If you want nadeko to play music: [Visual C++ 2010 (x86)] and [Visual C++ 2017 (x64)] (both are required, you may install them later)
- [git](https://git-scm.com/downloads) - needed to clone the repository (you can also download the zip manually and extract it, but this guide assumes you're using git)
- **Optional** Any code editor, for example [Visual Studio Code](https://code.visualstudio.com/Download)
- You'll need to at least modify creds.yml, notepad is inadequate
##### Installation Instructions
Open PowerShell (press windows button on your keyboard and type powershell, it should show up; alternatively, right click the start menu and select Windows PowerShell), and
0. Navigate to the location where you want to install the bot
- for example, type `cd ~/Desktop/` and press enter
1. `git clone https://gitlab.com/kwoth/nadekobot -b v5 --depth 1`
2. `cd nadekobot`
3. `dotnet publish -c Release -o output/ src/NadekoBot/`
4. `cd output`
5. `cp creds_example.yml creds.yml`
6. "You're done installing, you may now proceed to set up your bot's credentials by following the [#creds-guide]
- Once done, come back here and run the last command
8. Run the bot `dotnet NadekoBot.dll`
9. 🎉 Enjoy
##### Update Instructions
Open PowerShell as described above and run the following commands:
1. Stop the bot
- ⚠️ Make sure you don't have your database, credentials or any other nadekobot folder open in some application, this might prevent some of the steps from executing succesfully
2. Navigate to your bot's folder, example:
- `cd ~/Desktop/nadekobot`
3. Pull the new version, and make sure you're on the v5 branch
- *⚠️ If you're on v4, you must run these commands, if not, you may skip them.*
- `git remote set-branches origin '*'`
- `git fetch -v --depth=1`
- `git checkout v5`
- `git pull`
- ⚠️ If this fails, you may want to stash or remove your code changes if you don't know how to resolve merge conflicts
4. **Backup** old output in case your data is overwritten
- `cp -r -fo output/ output-old`
5. Build the bot again
- `dotnet publish -c Release -o output/ src/NadekoBot/`
6. Remove old strings and aliases to avoid overwriting the updated versions of those files
- ⚠ If you've modified said files, back them up instead
- `rm output-old/data/aliases.yml`
- `rm -r output-old/data/strings`
7. Copy old data, and new strings
- `cp -Recurse -Force .\output-old\data\ .\output\`
- `cp -Recurse -Force src/NadekoBot/data/strings/ output/data/`
8. Copy creds.yml
- `cp output-old/creds.yml output/`
9. Run the bot
- `cd output`
- `dotnet NadekoBot.dll`
🎉 Enjoy
#### Music prerequisites
In order to use music commands, you need ffmpeg and yt-dlp installed.
- [ffmpeg-32bit] | [ffmpeg-64bit] - Download the **appropriate version** for your system (32 bit if you're running a 32 bit OS, or 64 if you're running a 64bit OS). Unzip it, and move `ffmpeg.exe` to a path that's in your PATH environment variable. If you don't know what that is, just move the `ffmpeg.exe` file to `NadekoBot/output`.
- [youtube-dlp] - Click to download the `yt-dlp.exe` file, then move `yt-dlp.exe` to a path that's in your PATH environment variable. If you don't know what that is, just move the `yt-dlp.exe` file to `NadekoBot/system`.
[Updater]: https://dl.nadeko.bot/v3/
[Notepad++]: https://notepad-plus-plus.org/
[.net]: https://dotnet.microsoft.com/download/dotnet/8.0
[Redis]: https://github.com/MicrosoftArchive/redis/releases/download/win-3.0.504/Redis-x64-3.0.504.msi
[Visual C++ 2010 (x86)]: https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe
[Visual C++ 2017 (x64)]: https://aka.ms/vs/15/release/vc_redist.x64.exe
[ffmpeg-32bit]: https://cdn.nadeko.bot/dl/ffmpeg-32.zip
[ffmpeg-64bit]: https://cdn.nadeko.bot/dl/ffmpeg-64.zip
[youtube-dlp]: https://github.com/yt-dlp/yt-dlp/releases

View File

@@ -16,6 +16,7 @@ To self-host your own Nadeko, use the guides below:
- [:material-microsoft-windows: Windows guide][windows-guide]
- [:material-linux: Linux guide][linux-guide]
- [:material-apple: Mac OS guide][macos-guide]
- [:material-microsoft-windows: Windows (from source) guide][windows-source-guide]
In case you need any help, join our [Discord server][discord-server] where we may provide support.
@@ -32,6 +33,7 @@ If you're unsure whether something is an issue, ask in our support server first.
[invite]: https://invite.nadeko.bot/
[commands]: https://nadeko.bot/commands/
[windows-guide]: ./guides/windows-guide.md
[windows-source-guide]: ./guides/windows-source-guide.md
[linux-guide]: ./guides/linux-guide.md
[macos-guide]: ./guides/osx-guide.md
[from-source-guide]: ./guides/from-source.md

View File

@@ -75,6 +75,7 @@ nav:
- Windows Guide: guides/windows-guide.md
- Linux Guide: guides/linux-guide.md
- OSX Guide: guides/osx-guide.md
- Windows Guide (from source): guides/windows-source-guide.md
- Docker Guide (unsupported): guides/docker-guide.md
- Commands:
- Readme: commands-readme.md

View File

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

View File

@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Discord.Net.Core" Version="3.15.3" />
<PackageReference Include="Discord.Net.Core" Version="3.16.0" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="YamlDotNet" Version="15.1.4" />
</ItemGroup>

View File

@@ -12,13 +12,14 @@ namespace NadekoBot.Generators
{
public readonly record struct MethodPermData
{
public readonly string Name;
public readonly string Value;
public readonly ImmutableArray<(string Name, string Value)> MethodPerms;
public readonly ImmutableArray<string> NoAuthRequired;
public MethodPermData(string name, string value)
public MethodPermData(ImmutableArray<(string Name, string Value)> methodPerms,
ImmutableArray<string> noAuthRequired)
{
Name = name;
Value = value;
MethodPerms = methodPerms;
NoAuthRequired = noAuthRequired;
}
}
@@ -26,7 +27,7 @@ namespace NadekoBot.Generators
[Generator]
public class GrpcApiPermGenerator : IIncrementalGenerator
{
public const string Attribute =
public const string GRPC_API_PERM_ATTRIBUTE =
"""
namespace NadekoBot.GrpcApi;
@@ -37,13 +38,26 @@ namespace NadekoBot.Generators
public GrpcApiPermAttribute(GuildPerm value) => Value = value;
}
""";
public const string GRPC_NO_AUTH_REQUIRED_ATTRIBUTE =
"""
namespace NadekoBot.GrpcApi;
[System.AttributeUsage(System.AttributeTargets.Method)]
public class GrpcNoAuthRequiredAttribute : System.Attribute
{
}
""";
public void Initialize(IncrementalGeneratorInitializationContext context)
{
context.RegisterPostInitializationOutput(ctx => ctx.AddSource("GrpcApiPermAttribute.cs",
SourceText.From(Attribute, Encoding.UTF8)));
SourceText.From(GRPC_API_PERM_ATTRIBUTE, Encoding.UTF8)));
context.RegisterPostInitializationOutput(ctx => ctx.AddSource("GrpcNoAuthRequiredAttribute.cs",
SourceText.From(GRPC_NO_AUTH_REQUIRED_ATTRIBUTE, Encoding.UTF8)));
var enumsToGenerate = context.SyntaxProvider
var perms = context.SyntaxProvider
.ForAttributeWithMetadataName(
"NadekoBot.GrpcApi.GrpcApiPermAttribute",
predicate: static (s, _) => s is MethodDeclarationSyntax,
@@ -52,11 +66,24 @@ namespace NadekoBot.Generators
.Select(static (x, _) => x!.Value)
.Collect();
context.RegisterSourceOutput(enumsToGenerate,
var all = context.SyntaxProvider
.ForAttributeWithMetadataName(
"NadekoBot.GrpcApi.GrpcNoAuthRequiredAttribute",
predicate: static (s, _) => s is MethodDeclarationSyntax,
transform: static (ctx, _) => GetNoAuthMethodName(ctx.SemanticModel, ctx.TargetNode))
.Collect()
.Combine(perms)
.Select((x, _) => new MethodPermData(x.Right, x.Left));
context.RegisterSourceOutput(all,
static (spc, source) => Execute(source, spc));
}
private static MethodPermData? GetMethodSemanticTargets(SemanticModel model, SyntaxNode node)
private static string GetNoAuthMethodName(SemanticModel model, SyntaxNode node)
=> ((MethodDeclarationSyntax)node).Identifier.Text;
private static (string Name, string Value)? GetMethodSemanticTargets(SemanticModel model, SyntaxNode node)
{
var method = (MethodDeclarationSyntax)node;
@@ -64,20 +91,14 @@ namespace NadekoBot.Generators
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);
return (name, attr.ArgumentList?.Arguments[0].ToString() ?? "__missing_perm__");
}
private static void Execute(ImmutableArray<MethodPermData> fields, SourceProductionContext ctx)
private static void Execute(MethodPermData data, SourceProductionContext ctx)
{
using (var stringWriter = new StringWriter())
using (var sw = new IndentedTextWriter(stringWriter))
@@ -87,16 +108,17 @@ namespace NadekoBot.Generators
sw.WriteLine("namespace NadekoBot.GrpcApi;");
sw.WriteLine();
sw.WriteLine("public partial class PermsInterceptor");
sw.WriteLine("public partial class GrpcApiPermsInterceptor");
sw.WriteLine("{");
sw.Indent++;
sw.WriteLine("public static FrozenDictionary<string, GuildPerm> perms = new Dictionary<string, GuildPerm>()");
sw.WriteLine(
"private static FrozenDictionary<string, GuildPerm> _perms = new Dictionary<string, GuildPerm>()");
sw.WriteLine("{");
sw.Indent++;
foreach (var field in fields)
foreach (var field in data.MethodPerms)
{
sw.WriteLine("{{ \"{0}\", {1} }},", field.Name, field.Value);
}
@@ -104,6 +126,21 @@ namespace NadekoBot.Generators
sw.Indent--;
sw.WriteLine("}.ToFrozenDictionary();");
sw.WriteLine();
sw.WriteLine("private static FrozenSet<string> _noAuthRequired = new HashSet<string>()");
sw.WriteLine("{");
sw.Indent++;
foreach (var noauth in data.NoAuthRequired)
{
sw.WriteLine("{{ \"{0}\" }},", noauth);
}
sw.WriteLine("");
sw.Indent--;
sw.WriteLine("}.ToFrozenSet();");
sw.Indent--;
sw.WriteLine("}");

View File

@@ -0,0 +1,47 @@
syntax = "proto3";
option csharp_namespace = "NadekoBot.GrpcApi";
import "google/protobuf/empty.proto";
package ncanvas;
service GrpcNCanvas {
rpc GetCanvas(google.protobuf.Empty) returns (CanvasReply);
rpc GetPixel(GetPixelRequest) returns (GetPixelReply);
rpc SetPixel(SetPixelRequest) returns (SetPixelReply);
}
message CanvasReply {
repeated uint32 pixels = 1;
int32 width = 2;
int32 height = 3;
}
message GetPixelRequest {
int32 x = 1;
int32 y = 2;
}
message GetPixelReply {
string color = 1;
uint32 packedColor = 2;
int32 positionX = 3;
int32 positionY = 4;
int64 price = 5;
string text = 6;
string position = 7;
}
message SetPixelRequest {
string position = 1;
string color = 2;
string text = 3;
int64 price = 4;
}
message SetPixelReply {
string error = 1;
bool success = 2;
optional GetPixelReply pixel = 3;
}

View File

@@ -1,26 +0,0 @@
syntax = "proto3";
option csharp_namespace = "NadekoBot.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;
}

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
option csharp_namespace = "NadekoBot.GrpcApi";
import "google/protobuf/empty.proto";
import "google/protobuf/empty.proto";
package exprs;
@@ -10,6 +10,10 @@ service GrpcExprs {
rpc GetExprs(GetExprsRequest) returns (GetExprsReply);
rpc AddExpr(AddExprRequest) returns (AddExprReply);
rpc DeleteExpr(DeleteExprRequest) returns (google.protobuf.Empty);
rpc GetQuotes(GetQuotesRequest) returns (GetQuotesReply);
rpc AddQuote(AddQuoteRequest) returns (AddQuoteReply);
rpc DeleteQuote(DeleteQuoteRequest) returns (google.protobuf.Empty);
}
message DeleteExprRequest {
@@ -32,7 +36,7 @@ message ExprDto {
string id = 1;
string trigger = 2;
string response = 3;
bool ca = 4;
bool ad = 5;
bool dm = 6;
@@ -47,4 +51,39 @@ message AddExprRequest {
message AddExprReply {
string id = 1;
bool success = 2;
}
message GetQuotesRequest {
uint64 guildId = 1;
string query = 2;
int32 page = 3;
}
message GetQuotesReply {
repeated QuoteDto quotes = 1;
int32 totalCount = 2;
}
message QuoteDto {
string id = 1;
string trigger = 2;
string response = 3;
uint64 authorId = 4;
string authorName = 5;
}
message AddQuoteRequest {
uint64 guildId = 1;
QuoteDto quote = 2;
}
message AddQuoteReply {
string id = 1;
bool success = 2;
}
message DeleteQuoteRequest {
string id = 1;
uint64 guildId = 2;
}

View File

@@ -0,0 +1,60 @@
syntax = "proto3";
option csharp_namespace = "NadekoBot.GrpcApi";
import "google/protobuf/timestamp.proto";
package fin;
service GrpcFin {
rpc GetTransactions(GetTransactionsRequest) returns (GetTransactionsReply);
rpc GetHoldings(GetHoldingsRequest) returns (GetHoldingsReply);
rpc Withdraw(WithdrawRequest) returns (WithdrawReply);
rpc Deposit(DepositRequest) returns (DepositReply);
}
message GetTransactionsRequest {
int32 page = 1;
uint64 userId = 2;
}
message GetTransactionsReply {
repeated TransactionReply transactions = 1;
int32 total = 2;
}
message TransactionReply {
int64 amount = 1;
string note = 2;
string type = 3;
string extra = 4;
google.protobuf.Timestamp timestamp = 5;
string id = 6;
}
message GetHoldingsRequest {
uint64 userId = 1;
}
message GetHoldingsReply {
int64 cash = 1;
int64 bank = 2;
}
message WithdrawRequest {
uint64 userId = 1;
int64 amount = 2;
}
message WithdrawReply {
bool success = 1;
}
message DepositRequest {
uint64 userId = 1;
int64 amount = 2;
}
message DepositReply {
bool success = 1;
}

View File

@@ -5,20 +5,13 @@ option csharp_namespace = "NadekoBot.GrpcApi";
package greet;
service GrpcGreet {
rpc GetGreetSettings (GetGreetRequest) returns (GetGreetReply);
rpc GetGreetSettings (GetGreetRequest) returns (GrpcGreetSettings);
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 channelId = 1;
string message = 2;
bool isEnabled = 3;
GrpcGreetType type = 4;
@@ -26,6 +19,7 @@ message GrpcGreetSettings {
message GetGreetRequest {
uint64 guildId = 1;
GrpcGreetType type = 2;
}
message UpdateGreetRequest {
@@ -41,7 +35,7 @@ enum GrpcGreetType {
}
message UpdateGreetReply {
bool success = 1;
bool Success = 1;
}
message TestGreetRequest {

View File

@@ -3,43 +3,50 @@ syntax = "proto3";
option csharp_namespace = "NadekoBot.GrpcApi";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
package other;
service GrpcOther {
rpc GetGuilds(google.protobuf.Empty) returns (GetGuildsReply);
rpc BotOnGuild(BotOnGuildRequest) returns (BotOnGuildReply);
rpc GetTextChannels(GetTextChannelsRequest) returns (GetTextChannelsReply);
rpc GetRoles(GetRolesRequest) returns (GetRolesReply);
rpc GetCurrencyLb(GetLbRequest) returns (CurrencyLbReply);
rpc GetXpLb(GetLbRequest) returns (XpLbReply);
rpc GetWaifuLb(GetLbRequest) returns (WaifuLbReply);
rpc GetShardStatuses(google.protobuf.Empty) returns (GetShardStatusesReply);
rpc GetShardStats(google.protobuf.Empty) returns (stream ShardStatsReply);
rpc GetCommandFeed(google.protobuf.Empty) returns (stream CommandFeedEntry);
rpc GetServerInfo(ServerInfoRequest) returns (GetServerInfoReply);
}
message GetGuildsReply {
repeated GuildReply guilds = 1;
message CommandFeedEntry {
string command = 1;
}
message GuildReply {
uint64 id = 1;
string name = 2;
string iconUrl = 3;
message GetRolesRequest {
uint64 guildId = 1;
}
message GetShardStatusesReply {
repeated ShardStatusReply shards = 1;
message GetRolesReply {
repeated RoleReply roles = 1;
}
message ShardStatusReply {
message BotOnGuildRequest {
uint64 guildId = 1;
}
message BotOnGuildReply {
bool success = 1;
}
message ShardStatsReply {
int32 id = 1;
string status = 2;
int32 guildCount = 3;
google.protobuf.Timestamp lastUpdate = 4;
string uptime = 4;
int64 commands = 5;
}
message GetTextChannelsRequest{

View File

@@ -6,11 +6,17 @@ package warn;
service GrpcWarn {
rpc GetWarnSettings (WarnSettingsRequest) returns (WarnSettingsReply);
rpc SetWarnExpiry(SetWarnExpiryRequest) returns (SetWarnExpiryReply);
rpc AddWarnp (AddWarnpRequest) returns (AddWarnpReply);
rpc DeleteWarnp (DeleteWarnpRequest) returns (DeleteWarnpReply);
rpc GetLatestWarnings(GetLatestWarningsRequest) returns (GetLatestWarningsReply);
rpc GetUserWarnings(GetUserWarningsRequest) returns (GetUserWarningsReply);
rpc ClearWarning(ClearWarningRequest) returns (ClearWarningReply);
rpc SetWarnExpiry(SetWarnExpiryRequest) returns (SetWarnExpiryReply);
rpc ForgiveWarning(ForgiveWarningRequest) returns (ForgiveWarningReply);
rpc DeleteWarning(ForgiveWarningRequest) returns (ForgiveWarningReply);
}
message WarnSettingsRequest {
uint64 guildId = 1;
@@ -19,12 +25,14 @@ message WarnSettingsRequest {
message WarnPunishment {
int32 threshold = 1;
string action = 2;
int64 duration = 3;
int32 duration = 3;
string role = 4;
}
message WarnSettingsReply {
repeated WarnPunishment punishments = 1;
int32 expiryDays = 2;
bool deleteOnExpire = 3;
}
message AddWarnpRequest {
@@ -38,7 +46,7 @@ message AddWarnpReply {
message DeleteWarnpRequest {
uint64 guildId = 1;
int32 warnpIndex = 2;
int32 threshold = 2;
}
message DeleteWarnpReply {
@@ -47,37 +55,53 @@ message DeleteWarnpReply {
message GetUserWarningsRequest {
uint64 guildId = 1;
uint64 user_id = 2;
string user = 2;
int32 page = 3;
}
message GetUserWarningsReply {
repeated Warning warnings = 1;
int32 totalCount = 2;
}
message Warning {
int32 id = 1;
string id = 1;
string reason = 2;
int64 timestamp = 3;
int64 expiry_timestamp = 4;
bool cleared = 5;
string clearedBy = 6;
int64 weight = 4;
bool forgiven = 5;
string forgivenBy = 6;
string user = 7;
uint64 userId = 8;
string moderator = 9;
}
message ClearWarningRequest {
message ForgiveWarningRequest {
uint64 guildId = 1;
uint64 userId = 2;
optional int32 warnId = 3;
string warnId = 2;
string modName = 3;
}
message ClearWarningReply {
message ForgiveWarningReply {
bool success = 1;
}
message SetWarnExpiryRequest {
uint64 guildId = 1;
int32 expiryDays = 2;
bool deleteOnExpire = 3;
}
message SetWarnExpiryReply {
bool success = 1;
}
message GetLatestWarningsRequest {
uint64 guildId = 1;
int32 page = 2;
}
message GetLatestWarningsReply {
repeated Warning warnings = 1;
int32 totalCount = 2;
}

View File

@@ -0,0 +1,120 @@
syntax = "proto3";
option csharp_namespace = "NadekoBot.GrpcApi";
package xp;
service GrpcXp {
rpc GetXpLb(GetXpLbRequest) returns (GetXpLbReply);
rpc ResetUserXp(ResetUserXpRequest) returns (ResetUserXpReply);
rpc GetXpSettings(GetXpSettingsRequest) returns (GetXpSettingsReply);
rpc AddExclusion(AddExclusionRequest) returns (AddExclusionReply);
rpc DeleteExclusion(DeleteExclusionRequest) returns (DeleteExclusionReply);
rpc AddReward(AddRewardRequest) returns (AddRewardReply);
rpc DeleteReward(DeleteRewardRequest) returns (DeleteRewardReply);
rpc SetServerExclusion(SetServerExclusionRequest) returns (SetServerExclusionReply);
}
message SetServerExclusionRequest {
uint64 guildId = 1;
bool serverExcluded = 2;
}
message SetServerExclusionReply {
bool success = 1;
}
message GetXpLbRequest {
uint64 guildId = 1;
int32 page = 2;
}
message GetXpLbReply {
repeated XpLbUserReply users = 1;
int32 total = 2;
}
message XpLbUserReply {
uint64 userId = 1;
string username = 2;
int64 xp = 3;
int64 level = 4;
int64 levelPercent = 5;
string avatar = 6;
}
message ResetUserXpRequest {
uint64 guildId = 1;
uint64 userId = 2;
}
message ResetUserXpReply {
bool success = 1;
}
message GetXpSettingsReply {
repeated ExclItemReply exclusions = 1;
repeated RewItemReply rewards = 2;
bool serverExcluded = 3;
}
message GetXpSettingsRequest {
uint64 guildId = 1;
}
message ExclItemReply {
string type = 1;
uint64 id = 2;
string name = 3;
}
message RewItemReply {
int32 level = 1;
string type = 2;
string value = 3;
}
message AddExclusionRequest {
uint64 guildId = 1;
string type = 2;
uint64 id = 3;
}
message AddExclusionReply {
bool success = 1;
}
message DeleteExclusionRequest {
uint64 guildId = 1;
string type = 2;
uint64 id = 3;
}
message DeleteExclusionReply {
bool success = 1;
}
message AddRewardRequest {
uint64 guildId = 1;
int32 level = 2;
string type = 3;
string value = 4;
}
message AddRewardReply {
bool success = 1;
}
message DeleteRewardRequest {
uint64 guildId = 1;
int32 level = 2;
string type = 3;
}
message DeleteRewardReply {
bool success = 1;
}

View File

@@ -0,0 +1,88 @@
// using System;
// using System.Collections.Generic;
// using System.Diagnostics;
// using System.IO;
// using System.Linq;
// using Nadeko.Common;
// using NadekoBot.Modules.Games;
// using NUnit.Framework;
//
// namespace NadekoBot.Tests;
//
// public class FishTests
// {
// [Test]
// public void TestWeather()
// {
// var fs = new FishService(null, null);
//
// var rng = new Random();
//
// // output = @"ro+dD:bN0uVqV3ZOAv6r""EFeA'A]u]uSyz2Qd'r#0Vf:5zOX\VgSsF8LgRCL/uOW";
// while (true)
// {
// var output = "";
// for (var i = 0; i < 64; i++)
// {
// var c = (char)rng.Next(33, 123);
// output += c;
// }
//
// output = "";
// var weathers = new List<FishingWeather>();
// for (var i = 0; i < 1_000_000; i++)
// {
// var w = fs.GetWeather(DateTime.UtcNow.AddHours(6 * i), output);
// weathers.Add(w);
// }
//
// var vals = weathers.GroupBy(x => x)
// .ToDictionary(x => x.Key, x => x.Count());
//
// var str = weathers.Select(x => (int)x).Join("");
// var maxLength = MaxLength(str);
//
// if (maxLength < 12)
// {
// foreach (var v in vals)
// {
// Console.WriteLine($"{v.Key}: {v.Value}");
// }
//
// Console.WriteLine(output);
// Console.WriteLine(maxLength);
//
// File.WriteAllText("data.txt", weathers.Select(x => (int)x).Join(""));
//
// break;
// }
// }
// }
//
// // string with same characters
// static int MaxLength(String s)
// {
// int ans = 1, temp = 1;
//
// // Traverse the string
// for (int i = 1; i < s.Length; i++)
// {
// // If character is same as
// // previous increment temp value
// if (s[i] == s[i - 1])
// {
// ++temp;
// }
// else
// {
// ans = Math.Max(ans, temp);
// temp = 1;
// }
// }
//
// ans = Math.Max(ans, temp);
//
// // Return the required answer
// return ans;
// }
// }

View File

@@ -1,4 +1,5 @@
using Nadeko.Common;
using System;
using Nadeko.Common;
using NUnit.Framework;
namespace NadekoBot.Tests
@@ -120,5 +121,12 @@ namespace NadekoBot.Tests
num = new kwum(int.MaxValue);
Assert.AreEqual("3zzzzzz", num.ToString());
}
[Test]
public void TestPower()
{
var num = new kwum((int)Math.Pow(32, 2));
Assert.AreEqual("322", num.ToString());
}
}
}

View File

@@ -357,3 +357,4 @@ resharper_arrange_redundant_parentheses_highlighting = hint
# IDE0011: Add braces
dotnet_diagnostic.IDE0011.severity = warning
resharper_arrange_type_member_modifiers_highlighting = hint

View File

@@ -25,7 +25,7 @@ public sealed class Bot : IBot
public bool IsReady { get; private set; }
public int ShardId { get; set; }
private readonly IBotCredentials _creds;
private readonly IBotCreds _creds;
private readonly CommandService _commandService;
private readonly DbService _db;
@@ -42,6 +42,9 @@ public sealed class Bot : IBot
_credsProvider = new BotCredsProvider(totalShards, credPath);
_creds = _credsProvider.GetCreds();
LogSetup.SetupLogger(shardId, _creds);
Log.Information("Pid: {ProcessId}", Environment.ProcessId);
_db = new NadekoDbService(_credsProvider);
var messageCacheSize =
@@ -115,7 +118,7 @@ public sealed class Bot : IBot
// svcs.Components.Remove<IPlanner, Planner>();
// svcs.Components.Add<IPlanner, RemovablePlanner>();
svcs.AddSingleton<IBotCredentials>(_ => _credsProvider.GetCreds());
svcs.AddSingleton<IBotCreds>(_ => _credsProvider.GetCreds());
svcs.AddSingleton<DbService, DbService>(_db);
svcs.AddSingleton<IBotCredsProvider>(_credsProvider);
svcs.AddSingleton<DiscordSocketClient>(Client);
@@ -215,12 +218,12 @@ public sealed class Bot : IBot
catch (HttpException ex)
{
LoginErrorHandler.Handle(ex);
Helpers.ReadErrorAndExit(3);
Helpers.ReadErrorAndExit(101);
}
catch (Exception ex)
{
LoginErrorHandler.Handle(ex);
Helpers.ReadErrorAndExit(4);
Helpers.ReadErrorAndExit(5);
}
await clientReady.Task.ConfigureAwait(false);
@@ -272,7 +275,7 @@ public sealed class Bot : IBot
catch (Exception ex)
{
Log.Error(ex, "Error adding services");
Helpers.ReadErrorAndExit(9);
Helpers.ReadErrorAndExit(103);
}
Log.Information("Shard {ShardId} connected in {Elapsed:F2}s",

View File

@@ -25,7 +25,6 @@ public static class DiscordUserExtensions
{
UserId = userId,
Username = username,
Discriminator = discrim,
AvatarId = avatarId,
TotalXp = 0,
CurrencyAmount = 0
@@ -33,7 +32,6 @@ public static class DiscordUserExtensions
old => new()
{
Username = username,
Discriminator = discrim,
AvatarId = avatarId
},
() => new()
@@ -49,8 +47,7 @@ public static class DiscordUserExtensions
() => new()
{
UserId = userId,
Username = "Unknown",
Discriminator = "????",
Username = "??Unknown",
AvatarId = string.Empty,
TotalXp = 0,
CurrencyAmount = 0
@@ -87,14 +84,7 @@ public static class DiscordUserExtensions
> users.AsQueryable().Where(y => y.UserId == id).Select(y => y.TotalXp).FirstOrDefault())
.Count()
+ 1;
public static async Task<IReadOnlyCollection<DiscordUser>> GetUsersXpLeaderboardFor(this DbSet<DiscordUser> users, int page, int perPage)
=> await users.ToLinqToDBTable()
.OrderByDescending(x => x.TotalXp)
.Skip(page * perPage)
.Take(perPage)
.ToArrayAsyncLinqToDB();
public static Task<List<DiscordUser>> GetTopRichest(
this DbSet<DiscordUser> users,
ulong botId,

View File

@@ -57,8 +57,7 @@ public static class GuildConfigExtensions
List<ulong> availableGuilds)
{
var result = await configs
.AsQueryable()
.Include(x => x.CommandCooldowns)
.IncludeEverything()
.Where(x => availableGuilds.Contains(x.GuildId))
.AsNoTracking()
.ToArrayAsync();
@@ -96,7 +95,6 @@ public static class GuildConfigExtensions
GuildId = guildId,
Permissions = Permissionv2.GetDefaultPermlist,
WarningsInitialized = true,
WarnPunishments = DefaultWarnPunishments
});
ctx.SaveChanges();
}
@@ -104,7 +102,6 @@ public static class GuildConfigExtensions
if (!config.WarningsInitialized)
{
config.WarningsInitialized = true;
config.WarnPunishments = DefaultWarnPunishments;
}
return config;

View File

@@ -1,22 +0,0 @@
#nullable disable
using Microsoft.EntityFrameworkCore;
using NadekoBot.Db.Models;
namespace NadekoBot.Db;
public static class SelfAssignableRolesExtensions
{
public static bool DeleteByGuildAndRoleId(this DbSet<SelfAssignedRole> roles, ulong guildId, ulong roleId)
{
var role = roles.FirstOrDefault(s => s.GuildId == guildId && s.RoleId == roleId);
if (role is null)
return false;
roles.Remove(role);
return true;
}
public static IReadOnlyCollection<SelfAssignedRole> GetFromGuild(this DbSet<SelfAssignedRole> roles, ulong guildId)
=> roles.AsQueryable().Where(s => s.GuildId == guildId).ToArray();
}

View File

@@ -1,5 +1,4 @@
#nullable disable
using LinqToDB;
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Db.Models;
@@ -8,6 +7,9 @@ namespace NadekoBot.Db;
public static class UserXpExtensions
{
public static async Task<UserXpStats?> GetGuildUserXp(this ITable<UserXpStats> table, ulong guildId, ulong userId)
=> await table.FirstOrDefaultAsyncLinqToDB(x => x.GuildId == guildId && x.UserId == userId);
public static UserXpStats GetOrCreateUserXpStats(this DbContext ctx, ulong guildId, ulong userId)
{
var usr = ctx.Set<UserXpStats>().FirstOrDefault(x => x.UserId == userId && x.GuildId == guildId);
@@ -18,7 +20,6 @@ public static class UserXpExtensions
{
Xp = 0,
UserId = userId,
NotifyOnLevelUp = XpNotificationLocation.None,
GuildId = guildId
});
}
@@ -26,38 +27,24 @@ public static class UserXpExtensions
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)
=> await xps.ToLinqToDBTable()
.Where(x => x.GuildId == guildId)
.OrderByDescending(x => x.Xp + x.AwardedXp)
.OrderByDescending(x => x.Xp)
.Take(count)
.ToListAsyncLinqToDB();
public static async Task<int> GetUserGuildRanking(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
=> await xps.ToLinqToDBTable()
.Where(x => x.GuildId == guildId
&& x.Xp + x.AwardedXp
&& x.Xp
> xps.AsQueryable()
.Where(y => y.UserId == userId && y.GuildId == guildId)
.Select(y => y.Xp + y.AwardedXp)
.Select(y => y.Xp)
.FirstOrDefault())
.CountAsyncLinqToDB()
+ 1;
public static void ResetGuildUserXp(this DbSet<UserXpStats> xps, ulong userId, ulong guildId)
=> xps.Delete(x => x.UserId == userId && x.GuildId == guildId);
public static void ResetGuildXp(this DbSet<UserXpStats> xps, ulong guildId)
=> xps.Delete(x => x.GuildId == guildId);
@@ -65,6 +52,6 @@ public static class UserXpExtensions
=> await userXp
.Where(x => x.GuildId == guildId && x.UserId == userId)
.FirstOrDefaultAsyncLinqToDB() is UserXpStats uxs
? new(uxs.Xp + uxs.AwardedXp)
? new(uxs.Xp)
: new(0);
}

View File

@@ -4,38 +4,28 @@ namespace NadekoBot.Db;
public readonly struct LevelStats
{
public const int XP_REQUIRED_LVL_1 = 36;
public long Level { get; }
public long LevelXp { get; }
public long RequiredXp { get; }
public long TotalXp { get; }
public LevelStats(long xp)
public LevelStats(long totalXp)
{
if (xp < 0)
xp = 0;
if (totalXp < 0)
totalXp = 0;
TotalXp = xp;
const int baseXp = XP_REQUIRED_LVL_1;
var required = baseXp;
var totalXp = 0;
var lvl = 1;
while (true)
{
required = (int)(baseXp + (baseXp / 4.0 * (lvl - 1)));
if (required + totalXp > xp)
break;
totalXp += required;
lvl++;
}
Level = lvl - 1;
LevelXp = xp - totalXp;
RequiredXp = required;
TotalXp = totalXp;
Level = GetLevelByTotalXp(totalXp);
LevelXp = totalXp - GetTotalXpReqForLevel(Level);
RequiredXp = (9 * (Level + 1)) + 27;
}
public static LevelStats CreateForLevel(long level)
=> new(GetTotalXpReqForLevel(level));
public static long GetTotalXpReqForLevel(long level)
=> ((9 * level * level) + (63 * level)) / 2;
public static long GetLevelByTotalXp(long totalXp)
=> (long)((-7.0 / 2) + (1 / 6.0 * Math.Sqrt((8 * totalXp) + 441)));
}

View File

@@ -7,7 +7,7 @@ public class DiscordUser : DbEntity
{
public ulong UserId { get; set; }
public string Username { get; set; }
public string Discriminator { get; set; }
// public string Discriminator { get; set; }
public string AvatarId { get; set; }
public int? ClubId { get; set; }
@@ -27,9 +27,6 @@ public class DiscordUser : DbEntity
public override string ToString()
{
if (string.IsNullOrWhiteSpace(Discriminator) || Discriminator == "0000")
return Username;
return Username + "#" + Discriminator;
return Username;
}
}

View File

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

View File

@@ -9,7 +9,8 @@ public class FollowedStream : DbEntity
Picarto = 3,
Youtube = 4,
Facebook = 5,
Trovo = 6
Trovo = 6,
Kick = 7,
}
public ulong GuildId { get; set; }

View File

@@ -1,11 +0,0 @@
#nullable disable
namespace NadekoBot.Db.Models;
public class GroupName : DbEntity
{
public int GuildConfigId { get; set; }
public GuildConfig GuildConfig { get; set; }
public int Number { get; set; }
public string Name { get; set; }
}

View File

@@ -5,14 +5,15 @@ namespace NadekoBot.Db.Models;
public class GuildColors
{
[Key]
public int Id { get; set; }
public ulong GuildId { get; set; }
[Length(0, 9)]
[MaxLength(9)]
public string? OkColor { get; set; }
[Length(0, 9)]
[MaxLength(9)]
public string? ErrorColor { get; set; }
[Length(0, 9)]
[MaxLength(9)]
public string? PendingColor { get; set; }
}

View File

@@ -13,28 +13,11 @@ public class GuildConfig : DbEntity
public string AutoAssignRoleIds { get; set; }
// //greet stuff
// public int AutoDeleteGreetMessagesTimer { get; set; } = 30;
// public int AutoDeleteByeMessagesTimer { get; set; } = 30;
//
// public ulong GreetMessageChannelId { get; set; }
// public ulong ByeMessageChannelId { get; set; }
//
// public bool SendDmGreetMessage { get; set; }
// public string DmGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
//
// public bool SendChannelGreetMessage { get; set; }
// public string ChannelGreetMessageText { get; set; } = "Welcome to the %server% server, %user%!";
//
// public bool SendChannelByeMessage { get; set; }
// public string ChannelByeMessageText { get; set; } = "%user% has left!";
// public bool SendBoostMessage { get; set; }
// pulic int BoostMessageDeleteAfter { get; set; }
//self assignable roles
//todo FUTURE: DELETE, UNUSED
public bool ExclusiveSelfAssignedRoles { get; set; }
public bool AutoDeleteSelfAssignedRoleMessages { get; set; }
//stream notifications
public HashSet<FollowedStream> FollowedStreams { get; set; } = new();
@@ -53,31 +36,38 @@ public class GuildConfig : DbEntity
public HashSet<FilterChannelId> FilterInvitesChannelIds { get; set; } = new();
public HashSet<FilterLinksChannelId> FilterLinksChannelIds { get; set; } = new();
//public bool FilterLinks { get; set; }
//public HashSet<FilterLinksChannelId> FilterLinksChannels { get; set; } = new HashSet<FilterLinksChannelId>();
public bool FilterWords { get; set; }
public HashSet<FilteredWord> FilteredWords { get; set; } = new();
public HashSet<FilterWordsChannelId> FilterWordsChannelIds { get; set; } = new();
// mute
public HashSet<MutedUserId> MutedUsers { get; set; } = new();
public string MuteRoleName { get; set; }
// chatterbot
public bool CleverbotEnabled { get; set; }
// protection
public AntiRaidSetting AntiRaidSetting { get; set; }
public AntiSpamSetting AntiSpamSetting { get; set; }
public AntiAltSetting AntiAltSetting { get; set; }
// time
public string Locale { get; set; }
public string TimeZoneId { get; set; }
// timers
public HashSet<UnmuteTimer> UnmuteTimers { get; set; } = new();
public HashSet<UnbanTimer> UnbanTimer { get; set; } = new();
public HashSet<UnroleTimer> UnroleTimer { get; set; } = new();
// vcrole
public HashSet<VcRoleInfo> VcRoleInfos { get; set; }
// aliases
public HashSet<CommandAlias> CommandAliases { get; set; } = new();
public List<WarningPunishment> WarnPunishments { get; set; } = new();
public bool WarningsInitialized { get; set; }
public HashSet<SlowmodeIgnoredUser> SlowmodeIgnoredUsers { get; set; }
public HashSet<SlowmodeIgnoredRole> SlowmodeIgnoredRoles { get; set; }
@@ -92,15 +82,10 @@ public class GuildConfig : DbEntity
public List<FeedSub> FeedSubs { get; set; } = new();
public bool NotifyStreamOffline { get; set; }
public bool DeleteStreamOnlineMessage { get; set; }
public List<GroupName> SelfAssignableRoleGroupNames { get; set; }
public int WarnExpireHours { get; set; }
public WarnExpireAction WarnExpireAction { get; set; } = WarnExpireAction.Clear;
public bool DisableGlobalExpressions { get; set; } = false;
#region Boost Message
public bool StickyRoles { get; set; }
#endregion
}

View File

@@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations;
namespace NadekoBot.Db.Models;
public class NCPixel
{
[Key]
public int Id { get; set; }
public required int Position { get; init; }
public required long Price { get; init; }
public required ulong OwnerId { get; init; }
public required uint Color { get; init; }
[MaxLength(256)]
public required string Text { get; init; }
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations;
namespace NadekoBot.Db.Models;
public class Notify
{
[Key]
public int Id { get; set; }
public ulong GuildId { get; set; }
public ulong ChannelId { get; set; }
public NotifyType Type { get; set; }
[MaxLength(10_000)]
public string Message { get; set; } = string.Empty;
}
public enum NotifyType
{
LevelUp = 0,
Protection = 1, Prot = 1,
AddRoleReward = 2,
RemoveRoleReward = 3,
}

View File

@@ -0,0 +1,18 @@
using System.ComponentModel.DataAnnotations;
namespace NadekoBot.Db.Models;
public sealed class SarGroup
{
[Key]
public int Id { get; set; }
public int GroupNumber { get; set; }
public ulong GuildId { get; set; }
public ulong? RoleReq { get; set; }
public ICollection<Sar> Roles { get; set; } = [];
public bool IsExclusive { get; set; }
[MaxLength(100)]
public string? Name { get; set; }
}

View File

@@ -0,0 +1,27 @@
using System.ComponentModel.DataAnnotations;
namespace NadekoBot.Db.Models;
public sealed class ButtonRole
{
[Key]
public int Id { get; set; }
[MaxLength(200)]
public string ButtonId { get; set; } = string.Empty;
public ulong GuildId { get; set; }
public ulong ChannelId { get; set; }
public ulong MessageId { get; set; }
public int Position { get; set; }
public ulong RoleId { get; set; }
[MaxLength(100)]
public string Emote { get; set; } = string.Empty;
[MaxLength(50)]
public string Label { get; set; } = string.Empty;
public bool Exclusive { get; set; }
}

View File

@@ -3,6 +3,7 @@ namespace NadekoBot.Db.Models;
public class WarningPunishment : DbEntity
{
public ulong GuildId { get; set; }
public int Count { get; set; }
public PunishmentAction Punishment { get; set; }
public int Time { get; set; }

View File

@@ -1,11 +1,24 @@
#nullable disable
using System.ComponentModel.DataAnnotations;
namespace NadekoBot.Db.Models;
public class SelfAssignedRole : DbEntity
public sealed class Sar
{
[Key]
public int Id { get; set; }
public ulong GuildId { get; set; }
public ulong RoleId { get; set; }
public int Group { get; set; }
public int LevelRequirement { get; set; }
public int SarGroupId { get; set; }
public int LevelReq { get; set; }
}
public sealed class SarAutoDelete
{
[Key]
public int Id { get; set; }
public ulong GuildId { get; set; }
public bool IsEnabled { get; set; } = false;
}

View File

@@ -0,0 +1,12 @@
namespace NadekoBot.Db.Models;
public class TempRole
{
public int Id { get; set; }
public ulong GuildId { get; set; }
public bool Remove { get; set; }
public ulong RoleId { get; set; }
public ulong UserId { get; set; }
public DateTime ExpiresAt { get; set; }
}

View File

@@ -1,8 +1,12 @@
#nullable disable
using System.ComponentModel.DataAnnotations;
namespace NadekoBot.Db.Models;
public class PatronUser
{
// [Key]
// public int Id { get; set; }
public string UniquePlatformUserId { get; set; }
public ulong UserId { get; set; }
public int AmountCents { get; set; }

View File

@@ -6,6 +6,4 @@ public class UserXpStats : DbEntity
public ulong UserId { get; set; }
public ulong GuildId { get; set; }
public long Xp { get; set; }
public long AwardedXp { get; set; }
public XpNotificationLocation NotifyOnLevelUp { get; set; }
}

View File

@@ -1,4 +1,4 @@
namespace NadekoBot.Db.Models;
namespace NadekoBot.Db.Models;
public enum XpNotificationLocation
{

View File

@@ -2,6 +2,7 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using NadekoBot.Db.Models;
using NadekoBot.Modules.Administration.Services;
// ReSharper disable UnusedAutoPropertyAccessor.Global
@@ -14,7 +15,6 @@ public abstract class NadekoContext : DbContext
public DbSet<Quote> Quotes { get; set; }
public DbSet<Reminder> Reminders { get; set; }
public DbSet<SelfAssignedRole> SelfAssignableRoles { get; set; }
public DbSet<MusicPlaylist> MusicPlaylists { get; set; }
public DbSet<NadekoExpression> Expressions { get; set; }
public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; }
@@ -62,7 +62,7 @@ public abstract class NadekoContext : DbContext
public DbSet<ArchivedTodoListModel> TodosArchive { get; set; }
public DbSet<HoneypotChannel> HoneyPotChannels { get; set; }
// todo add guild colors
// public DbSet<GuildColors> GuildColors { get; set; }
@@ -74,6 +74,136 @@ public abstract class NadekoContext : DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// load all entities from current assembly
modelBuilder.ApplyConfigurationsFromAssembly(typeof(NadekoContext).Assembly);
#region Notify
modelBuilder.Entity<Notify>(e =>
{
e.HasAlternateKey(x => new
{
x.GuildId,
Event = x.Type
});
});
#endregion
#region TempRoles
modelBuilder.Entity<TempRole>(e =>
{
e.HasAlternateKey(x => new
{
x.GuildId,
x.UserId,
x.RoleId
});
e.HasIndex(x => x.ExpiresAt);
});
#endregion
#region GuildColors
modelBuilder.Entity<GuildColors>()
.HasIndex(x => x.GuildId)
.IsUnique(true);
#endregion
#region Button Roles
modelBuilder.Entity<ButtonRole>(br =>
{
br.HasIndex(x => x.GuildId)
.IsUnique(false);
br.HasAlternateKey(x => new
{
x.RoleId,
x.MessageId,
});
});
#endregion
#region New Sar
modelBuilder.Entity<SarGroup>(sg =>
{
sg.HasAlternateKey(x => new
{
x.GuildId,
x.GroupNumber
});
sg.HasMany(x => x.Roles)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<Sar>()
.HasAlternateKey(x => new
{
x.GuildId,
x.RoleId
});
modelBuilder.Entity<SarAutoDelete>()
.HasIndex(x => x.GuildId)
.IsUnique();
#endregion
#region Rakeback
modelBuilder.Entity<Rakeback>()
.HasKey(x => x.UserId);
#endregion
#region UserBetStats
modelBuilder.Entity<UserBetStats>(ubs =>
{
ubs.HasIndex(x => new
{
x.UserId,
x.Game
})
.IsUnique();
ubs.HasIndex(x => x.MaxWin)
.IsUnique(false);
});
#endregion
#region Flag Translate
modelBuilder.Entity<FlagTranslateChannel>()
.HasIndex(x => new
{
x.GuildId,
x.ChannelId
})
.IsUnique();
#endregion
#region NCanvas
modelBuilder.Entity<NCPixel>()
.HasAlternateKey(x => x.Position);
modelBuilder.Entity<NCPixel>()
.HasIndex(x => x.OwnerId);
#endregion
#region QUOTES
var quoteEntity = modelBuilder.Entity<Quote>();
@@ -195,11 +325,6 @@ public abstract class NadekoContext : DbContext
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.WarnPunishments)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.SlowmodeIgnoredRoles)
.WithOne()
@@ -257,11 +382,6 @@ public abstract class NadekoContext : DbContext
.HasForeignKey(x => x.GuildConfigId)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<GuildConfig>()
.HasMany(x => x.SelfAssignableRoleGroupNames)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<FeedSub>()
.HasAlternateKey(x => new
{
@@ -277,19 +397,16 @@ public abstract class NadekoContext : DbContext
#endregion
#region WarningPunishments
#region Self Assignable Roles
var selfassignableRolesEntity = modelBuilder.Entity<SelfAssignedRole>();
selfassignableRolesEntity.HasIndex(s => new
{
s.GuildId,
s.RoleId
})
.IsUnique();
selfassignableRolesEntity.Property(x => x.Group).HasDefaultValue(0);
var warnpunishmentEntity = modelBuilder.Entity<WarningPunishment>(b =>
{
b.HasAlternateKey(x => new
{
x.GuildId,
x.Count
});
});
#endregion
@@ -339,6 +456,7 @@ public abstract class NadekoContext : DbContext
du.HasIndex(x => x.TotalXp);
du.HasIndex(x => x.CurrencyAmount);
du.HasIndex(x => x.UserId);
du.HasIndex(x => x.Username);
});
#endregion
@@ -368,7 +486,6 @@ public abstract class NadekoContext : DbContext
xps.HasIndex(x => x.UserId);
xps.HasIndex(x => x.GuildId);
xps.HasIndex(x => x.Xp);
xps.HasIndex(x => x.AwardedXp);
#endregion
@@ -474,23 +591,6 @@ public abstract class NadekoContext : DbContext
#endregion
#region GroupName
modelBuilder.Entity<GroupName>()
.HasIndex(x => new
{
x.GuildConfigId,
x.Number
})
.IsUnique();
modelBuilder.Entity<GroupName>()
.HasOne(x => x.GuildConfig)
.WithMany(x => x.SelfAssignableRoleGroupNames)
.IsRequired();
#endregion
#region BanTemplate
modelBuilder.Entity<BanTemplate>().HasIndex(x => x.GuildId).IsUnique();
@@ -695,7 +795,7 @@ public abstract class NadekoContext : DbContext
gs
.Property(x => x.IsEnabled)
.HasDefaultValue(false);
gs
.Property(x => x.AutoDeleteTimer)
.HasDefaultValue(0);

View File

@@ -5,6 +5,54 @@ namespace NadekoBot.Migrations;
public static class MigrationQueries
{
public static void MergeAwardedXp(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("""
UPDATE UserXpStats
SET Xp = AwardedXp + Xp,
AwardedXp = 0
WHERE AwardedXp > 0;
""");
}
public static void MigrateSar(MigrationBuilder migrationBuilder)
{
if (migrationBuilder.IsNpgsql())
return;
migrationBuilder.Sql("""
INSERT INTO GroupName (Number, GuildConfigId)
SELECT DISTINCT "Group", GC.Id
FROM SelfAssignableRoles as SAR
INNER JOIN GuildConfigs as GC
ON SAR.GuildId = GC.GuildId
WHERE SAR.GuildId not in (SELECT GuildConfigs.GuildId from GroupName LEFT JOIN GuildConfigs ON GroupName.GuildConfigId = GuildConfigs.Id);
INSERT INTO SarGroup (Id, GroupNumber, Name, IsExclusive, GuildId)
SELECT GN.Id, GN.Number, GN.Name, GC.ExclusiveSelfAssignedRoles, GC.GuildId
FROM GroupName as GN
INNER JOIN GuildConfigs as GC ON GN.GuildConfigId = GC.Id;
INSERT INTO Sar (GuildId, RoleId, SarGroupId, LevelReq)
SELECT SAR.GuildId, SAR.RoleId, (SELECT Id FROM SarGroup WHERE SG.Number = SarGroup.GroupNumber AND SG.GuildId = SarGroup.GuildId), MIN(SAR.LevelRequirement)
FROM SelfAssignableRoles as SAR
INNER JOIN (SELECT GuildId, gn.Number FROM GroupName as gn
INNER JOIN GuildConfigs as gc ON gn.GuildConfigId =gc.Id
) as SG
ON SG.GuildId = SAR.GuildId
WHERE SG.Number IN (SELECT GroupNumber FROM SarGroup WHERE Sar.GuildId = SarGroup.GuildId)
GROUP BY SAR.GuildId, SAR.RoleId;
INSERT INTO SarAutoDelete (GuildId, IsEnabled)
SELECT GuildId, AutoDeleteSelfAssignedRoleMessages FROM GuildConfigs WHERE AutoDeleteSelfAssignedRoleMessages = TRUE;
""");
}
public static void UpdateUsernames(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("UPDATE DiscordUser SET Username = '??' || Username WHERE Discriminator = '????';");
}
public static void MigrateRero(MigrationBuilder migrationBuilder)
{
if (migrationBuilder.IsSqlite())
@@ -38,6 +86,7 @@ left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;")
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 "Permissions" WHERE "GuildConfigId" NOT IN (SELECT "Id" from "GuildConfigs");
""");
}
@@ -65,4 +114,20 @@ left join guildconfigs on reactionrolemessage.guildconfigid = guildconfigs.id;")
WHERE SendBoostMessage = TRUE;
""");
}
public static void AddGuildIdsToWarningPunishment(MigrationBuilder builder)
{
builder.Sql("""
DELETE FROM WarningPunishment WHERE GuildConfigId IS NULL OR GuildConfigId NOT IN (SELECT Id FROM GuildConfigs);
UPDATE WarningPunishment
SET GuildId = (SELECT GuildId FROM GuildConfigs WHERE Id = GuildConfigId);
DELETE FROM WarningPunishment as wp
WHERE (wp.Count, wp.GuildConfigId) in (
SELECT wp2.Count, wp2.GuildConfigId FROM WarningPunishment as wp2
GROUP BY wp2.Count, wp2.GuildConfigId
HAVING COUNT(id) > 1
);
""");
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class warnsplit : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<decimal>(
name: "guildid",
table: "warningpunishment",
type: "numeric(20,0)",
nullable: false,
defaultValue: 0m);
MigrationQueries.AddGuildIdsToWarningPunishment(migrationBuilder);
migrationBuilder.DropForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment");
migrationBuilder.DropIndex(
name: "ix_warningpunishment_guildconfigid",
table: "warningpunishment");
migrationBuilder.DropColumn(
name: "guildconfigid",
table: "warningpunishment");
migrationBuilder.AddUniqueConstraint(
name: "ak_warningpunishment_guildid_count",
table: "warningpunishment",
columns: new[] { "guildid", "count" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropUniqueConstraint(
name: "ak_warningpunishment_guildid_count",
table: "warningpunishment");
migrationBuilder.DropColumn(
name: "guildid",
table: "warningpunishment");
migrationBuilder.AddColumn<int>(
name: "guildconfigid",
table: "warningpunishment",
type: "integer",
nullable: true);
migrationBuilder.CreateIndex(
name: "ix_warningpunishment_guildconfigid",
table: "warningpunishment",
column: "guildconfigid");
migrationBuilder.AddForeignKey(
name: "fk_warningpunishment_guildconfigs_guildconfigid",
table: "warningpunishment",
column: "guildconfigid",
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class ncanvas : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ncpixel",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
position = table.Column<int>(type: "integer", nullable: false),
price = table.Column<long>(type: "bigint", nullable: false),
ownerid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
color = table.Column<long>(type: "bigint", nullable: false),
text = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_ncpixel", x => x.id);
table.UniqueConstraint("ak_ncpixel_position", x => x.position);
});
migrationBuilder.CreateIndex(
name: "ix_discorduser_username",
table: "discorduser",
column: "username");
migrationBuilder.CreateIndex(
name: "ix_ncpixel_ownerid",
table: "ncpixel",
column: "ownerid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ncpixel");
migrationBuilder.DropIndex(
name: "ix_discorduser_username",
table: "discorduser");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class nodiscrimandflagtranslate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "discriminator",
table: "discorduser");
migrationBuilder.CreateTable(
name: "flagtranslatechannel",
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),
channelid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
dateadded = table.Column<DateTime>(type: "timestamp without time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_flagtranslatechannel", x => x.id);
});
migrationBuilder.CreateIndex(
name: "ix_flagtranslatechannel_guildid_channelid",
table: "flagtranslatechannel",
columns: new[] { "guildid", "channelid" },
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "flagtranslatechannel");
migrationBuilder.AddColumn<string>(
name: "discriminator",
table: "discorduser",
type: "text",
nullable: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class betstats : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "userbetstats",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
game = table.Column<int>(type: "integer", nullable: false),
wincount = table.Column<long>(type: "bigint", nullable: false),
losecount = table.Column<long>(type: "bigint", nullable: false),
totalbet = table.Column<decimal>(type: "numeric", nullable: false),
paidout = table.Column<decimal>(type: "numeric", nullable: false),
maxwin = table.Column<long>(type: "bigint", nullable: false),
maxbet = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_userbetstats", x => x.id);
});
migrationBuilder.CreateIndex(
name: "ix_userbetstats_userid_game",
table: "userbetstats",
columns: new[] { "userid", "game" },
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "userbetstats");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class rakeback : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "rakeback",
columns: table => new
{
userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
amount = table.Column<decimal>(type: "numeric", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_rakeback", x => x.userid);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "rakeback");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,170 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class sarrework : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "sarautodelete",
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),
isenabled = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_sarautodelete", x => x.id);
});
migrationBuilder.CreateTable(
name: "sargroup",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy",
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
groupnumber = table.Column<int>(type: "integer", nullable: false),
guildid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
rolereq = table.Column<decimal>(type: "numeric(20,0)", nullable: true),
isexclusive = table.Column<bool>(type: "boolean", nullable: false),
name = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_sargroup", x => x.id);
table.UniqueConstraint("ak_sargroup_guildid_groupnumber",
x => new
{
x.guildid,
x.groupnumber
});
});
migrationBuilder.CreateTable(
name: "sar",
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),
roleid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
sargroupid = table.Column<int>(type: "integer", nullable: false),
levelreq = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_sar", x => x.id);
table.UniqueConstraint("ak_sar_guildid_roleid",
x => new
{
x.guildid,
x.roleid
});
table.ForeignKey(
name: "fk_sar_sargroup_sargroupid",
column: x => x.sargroupid,
principalTable: "sargroup",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "ix_sar_sargroupid",
table: "sar",
column: "sargroupid");
migrationBuilder.CreateIndex(
name: "ix_sarautodelete_guildid",
table: "sarautodelete",
column: "guildid",
unique: true);
MigrationQueries.MigrateSar(migrationBuilder);
migrationBuilder.DropTable(
name: "groupname");
migrationBuilder.DropTable(
name: "selfassignableroles");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "sar");
migrationBuilder.DropTable(
name: "sarautodelete");
migrationBuilder.DropTable(
name: "sargroup");
migrationBuilder.CreateTable(
name: "groupname",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy",
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
guildconfigid = table.Column<int>(type: "integer", nullable: false),
dateadded = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
name = table.Column<string>(type: "text", nullable: true),
number = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_groupname", x => x.id);
table.ForeignKey(
name: "fk_groupname_guildconfigs_guildconfigid",
column: x => x.guildconfigid,
principalTable: "guildconfigs",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "selfassignableroles",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy",
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
dateadded = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
group = table.Column<int>(type: "integer", nullable: false, defaultValue: 0),
guildid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
levelrequirement = table.Column<int>(type: "integer", nullable: false),
roleid = table.Column<decimal>(type: "numeric(20,0)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_selfassignableroles", x => x.id);
});
migrationBuilder.CreateIndex(
name: "ix_groupname_guildconfigid_number",
table: "groupname",
columns: new[] { "guildconfigid", "number" },
unique: true);
migrationBuilder.CreateIndex(
name: "ix_selfassignableroles_guildid_roleid",
table: "selfassignableroles",
columns: new[] { "guildid", "roleid" },
unique: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class btnroles_guildcolors : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "buttonrole",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
buttonid = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
guildid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
channelid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
messageid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
position = table.Column<int>(type: "integer", nullable: false),
roleid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
emote = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
label = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
exclusive = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_buttonrole", x => x.id);
table.UniqueConstraint("ak_buttonrole_roleid_messageid", x => new { x.roleid, x.messageid });
});
migrationBuilder.CreateTable(
name: "guildcolors",
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),
okcolor = table.Column<string>(type: "character varying(9)", maxLength: 9, nullable: true),
errorcolor = table.Column<string>(type: "character varying(9)", maxLength: 9, nullable: true),
pendingcolor = table.Column<string>(type: "character varying(9)", maxLength: 9, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_guildcolors", x => x.id);
});
migrationBuilder.CreateIndex(
name: "ix_buttonrole_guildid",
table: "buttonrole",
column: "guildid");
migrationBuilder.CreateIndex(
name: "ix_guildcolors_guildid",
table: "guildcolors",
column: "guildid",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "buttonrole");
migrationBuilder.DropTable(
name: "guildcolors");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,108 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class awardedxptemprolenotify : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "ix_userxpstats_awardedxp",
table: "userxpstats");
MigrationQueries.MergeAwardedXp(migrationBuilder);
migrationBuilder.DropColumn(
name: "awardedxp",
table: "userxpstats");
migrationBuilder.DropColumn(
name: "notifyonlevelup",
table: "userxpstats");
migrationBuilder.CreateTable(
name: "notify",
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),
channelid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
type = table.Column<int>(type: "integer", nullable: false),
message = table.Column<string>(type: "character varying(10000)", maxLength: 10000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_notify", x => x.id);
table.UniqueConstraint("ak_notify_guildid_type", x => new { x.guildid, x.type });
});
migrationBuilder.CreateTable(
name: "temprole",
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),
remove = table.Column<bool>(type: "boolean", nullable: false),
roleid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
expiresat = table.Column<DateTime>(type: "timestamp without time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_temprole", x => x.id);
table.UniqueConstraint("ak_temprole_guildid_userid_roleid", x => new { x.guildid, x.userid, x.roleid });
});
migrationBuilder.CreateIndex(
name: "ix_userbetstats_maxwin",
table: "userbetstats",
column: "maxwin");
migrationBuilder.CreateIndex(
name: "ix_temprole_expiresat",
table: "temprole",
column: "expiresat");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "notify");
migrationBuilder.DropTable(
name: "temprole");
migrationBuilder.DropIndex(
name: "ix_userbetstats_maxwin",
table: "userbetstats");
migrationBuilder.AddColumn<long>(
name: "awardedxp",
table: "userxpstats",
type: "bigint",
nullable: false,
defaultValue: 0L);
migrationBuilder.AddColumn<int>(
name: "notifyonlevelup",
table: "userxpstats",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "ix_userxpstats_awardedxp",
table: "userxpstats",
column: "awardedxp");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class fishes : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "fishcatch",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
fishid = table.Column<int>(type: "integer", nullable: false),
count = table.Column<int>(type: "integer", nullable: false),
maxstars = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_fishcatch", x => x.id);
table.UniqueConstraint("ak_fishcatch_userid_fishid", x => new { x.userid, x.fishid });
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "fishcatch");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Migrations.PostgreSql
{
/// <inheritdoc />
public partial class fishskill : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "userfishstats",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
skill = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_userfishstats", x => x.id);
});
migrationBuilder.CreateIndex(
name: "ix_userfishstats_userid",
table: "userfishstats",
column: "userid",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "userfishstats");
}
}
}

View File

@@ -451,6 +451,69 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("blacklist", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ButtonRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ButtonId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("character varying(200)")
.HasColumnName("buttonid");
b.Property<decimal>("ChannelId")
.HasColumnType("numeric(20,0)")
.HasColumnName("channelid");
b.Property<string>("Emote")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("emote");
b.Property<bool>("Exclusive")
.HasColumnType("boolean")
.HasColumnName("exclusive");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<string>("Label")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("label");
b.Property<decimal>("MessageId")
.HasColumnType("numeric(20,0)")
.HasColumnName("messageid");
b.Property<int>("Position")
.HasColumnType("integer")
.HasColumnName("position");
b.Property<decimal>("RoleId")
.HasColumnType("numeric(20,0)")
.HasColumnName("roleid");
b.HasKey("Id")
.HasName("pk_buttonrole");
b.HasAlternateKey("RoleId", "MessageId")
.HasName("ak_buttonrole_roleid_messageid");
b.HasIndex("GuildId")
.HasDatabaseName("ix_buttonrole_guildid");
b.ToTable("buttonrole", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
{
b.Property<int>("ClubId")
@@ -751,10 +814,6 @@ namespace NadekoBot.Migrations.PostgreSql
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
b.Property<string>("Discriminator")
.HasColumnType("text")
.HasColumnName("discriminator");
b.Property<bool>("IsClubAdmin")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
@@ -799,6 +858,9 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasIndex("UserId")
.HasDatabaseName("ix_discorduser_userid");
b.HasIndex("Username")
.HasDatabaseName("ix_discorduser_username");
b.ToTable("discorduser", (string)null);
});
@@ -995,6 +1057,37 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("filteredword", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.FlagTranslateChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("ChannelId")
.HasColumnType("numeric(20,0)")
.HasColumnName("channelid");
b.Property<DateTime?>("DateAdded")
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.HasKey("Id")
.HasName("pk_flagtranslatechannel");
b.HasIndex("GuildId", "ChannelId")
.IsUnique()
.HasDatabaseName("ix_flagtranslatechannel_guildid_channelid");
b.ToTable("flagtranslatechannel", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
{
b.Property<int>("Id")
@@ -1172,7 +1265,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("giveawayuser", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.GroupName", b =>
modelBuilder.Entity("NadekoBot.Db.Models.GuildColors", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
@@ -1181,30 +1274,33 @@ namespace NadekoBot.Migrations.PostgreSql
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime?>("DateAdded")
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
b.Property<string>("ErrorColor")
.HasMaxLength(9)
.HasColumnType("character varying(9)")
.HasColumnName("errorcolor");
b.Property<int>("GuildConfigId")
.HasColumnType("integer")
.HasColumnName("guildconfigid");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("OkColor")
.HasMaxLength(9)
.HasColumnType("character varying(9)")
.HasColumnName("okcolor");
b.Property<int>("Number")
.HasColumnType("integer")
.HasColumnName("number");
b.Property<string>("PendingColor")
.HasMaxLength(9)
.HasColumnType("character varying(9)")
.HasColumnName("pendingcolor");
b.HasKey("Id")
.HasName("pk_groupname");
.HasName("pk_guildcolors");
b.HasIndex("GuildConfigId", "Number")
b.HasIndex("GuildId")
.IsUnique()
.HasDatabaseName("ix_groupname_guildconfigid_number");
.HasDatabaseName("ix_guildcolors_guildid");
b.ToTable("groupname", (string)null);
b.ToTable("guildcolors", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.GuildConfig", b =>
@@ -1627,6 +1723,49 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("muteduserid", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.NCPixel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<long>("Color")
.HasColumnType("bigint")
.HasColumnName("color");
b.Property<decimal>("OwnerId")
.HasColumnType("numeric(20,0)")
.HasColumnName("ownerid");
b.Property<int>("Position")
.HasColumnType("integer")
.HasColumnName("position");
b.Property<long>("Price")
.HasColumnType("bigint")
.HasColumnName("price");
b.Property<string>("Text")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)")
.HasColumnName("text");
b.HasKey("Id")
.HasName("pk_ncpixel");
b.HasAlternateKey("Position")
.HasName("ak_ncpixel_position");
b.HasIndex("OwnerId")
.HasDatabaseName("ix_ncpixel_ownerid");
b.ToTable("ncpixel", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.NadekoExpression", b =>
{
b.Property<int>("Id")
@@ -1678,6 +1817,42 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("expressions", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.Notify", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("ChannelId")
.HasColumnType("numeric(20,0)")
.HasColumnName("channelid");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<string>("Message")
.IsRequired()
.HasMaxLength(10000)
.HasColumnType("character varying(10000)")
.HasColumnName("message");
b.Property<int>("Type")
.HasColumnType("integer")
.HasColumnName("type");
b.HasKey("Id")
.HasName("pk_notify");
b.HasAlternateKey("GuildId", "Type")
.HasName("ak_notify_guildid_type");
b.ToTable("notify", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.PatronUser", b =>
{
b.Property<decimal>("UserId")
@@ -2127,7 +2302,7 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("rotatingstatus", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.SelfAssignedRole", b =>
modelBuilder.Entity("NadekoBot.Db.Models.Sar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
@@ -2136,36 +2311,98 @@ namespace NadekoBot.Migrations.PostgreSql
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime?>("DateAdded")
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
b.Property<int>("Group")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasDefaultValue(0)
.HasColumnName("group");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<int>("LevelRequirement")
b.Property<int>("LevelReq")
.HasColumnType("integer")
.HasColumnName("levelrequirement");
.HasColumnName("levelreq");
b.Property<decimal>("RoleId")
.HasColumnType("numeric(20,0)")
.HasColumnName("roleid");
b.Property<int>("SarGroupId")
.HasColumnType("integer")
.HasColumnName("sargroupid");
b.HasKey("Id")
.HasName("pk_selfassignableroles");
.HasName("pk_sar");
b.HasIndex("GuildId", "RoleId")
b.HasAlternateKey("GuildId", "RoleId")
.HasName("ak_sar_guildid_roleid");
b.HasIndex("SarGroupId")
.HasDatabaseName("ix_sar_sargroupid");
b.ToTable("sar", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.SarAutoDelete", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<bool>("IsEnabled")
.HasColumnType("boolean")
.HasColumnName("isenabled");
b.HasKey("Id")
.HasName("pk_sarautodelete");
b.HasIndex("GuildId")
.IsUnique()
.HasDatabaseName("ix_selfassignableroles_guildid_roleid");
.HasDatabaseName("ix_sarautodelete_guildid");
b.ToTable("selfassignableroles", (string)null);
b.ToTable("sarautodelete", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.SarGroup", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("GroupNumber")
.HasColumnType("integer")
.HasColumnName("groupnumber");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<bool>("IsExclusive")
.HasColumnType("boolean")
.HasColumnName("isexclusive");
b.Property<string>("Name")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("name");
b.Property<decimal?>("RoleReq")
.HasColumnType("numeric(20,0)")
.HasColumnName("rolereq");
b.HasKey("Id")
.HasName("pk_sargroup");
b.HasAlternateKey("GuildId", "GroupNumber")
.HasName("ak_sargroup_guildid_groupnumber");
b.ToTable("sargroup", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ShopEntry", b =>
@@ -2501,6 +2738,47 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("streamrolewhitelisteduser", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.TempRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("ExpiresAt")
.HasColumnType("timestamp without time zone")
.HasColumnName("expiresat");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<bool>("Remove")
.HasColumnType("boolean")
.HasColumnName("remove");
b.Property<decimal>("RoleId")
.HasColumnType("numeric(20,0)")
.HasColumnName("roleid");
b.Property<decimal>("UserId")
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
b.HasKey("Id")
.HasName("pk_temprole");
b.HasAlternateKey("GuildId", "UserId", "RoleId")
.HasName("ak_temprole_guildid_userid_roleid");
b.HasIndex("ExpiresAt")
.HasDatabaseName("ix_temprole_expiresat");
b.ToTable("temprole", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.Property<int>("Id")
@@ -2657,10 +2935,6 @@ namespace NadekoBot.Migrations.PostgreSql
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<long>("AwardedXp")
.HasColumnType("bigint")
.HasColumnName("awardedxp");
b.Property<DateTime?>("DateAdded")
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
@@ -2669,10 +2943,6 @@ namespace NadekoBot.Migrations.PostgreSql
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<int>("NotifyOnLevelUp")
.HasColumnType("integer")
.HasColumnName("notifyonlevelup");
b.Property<decimal>("UserId")
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
@@ -2684,9 +2954,6 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasKey("Id")
.HasName("pk_userxpstats");
b.HasIndex("AwardedXp")
.HasDatabaseName("ix_userxpstats_awardedxp");
b.HasIndex("GuildId")
.HasDatabaseName("ix_userxpstats_guildid");
@@ -2938,9 +3205,9 @@ namespace NadekoBot.Migrations.PostgreSql
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
b.Property<int?>("GuildConfigId")
.HasColumnType("integer")
.HasColumnName("guildconfigid");
b.Property<decimal>("GuildId")
.HasColumnType("numeric(20,0)")
.HasColumnName("guildid");
b.Property<int>("Punishment")
.HasColumnType("integer")
@@ -2957,8 +3224,8 @@ namespace NadekoBot.Migrations.PostgreSql
b.HasKey("Id")
.HasName("pk_warningpunishment");
b.HasIndex("GuildConfigId")
.HasDatabaseName("ix_warningpunishment_guildconfigid");
b.HasAlternateKey("GuildId", "Count")
.HasName("ak_warningpunishment_guildid_count");
b.ToTable("warningpunishment", (string)null);
});
@@ -3107,6 +3374,67 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("xpshopowneditem", (string)null);
});
modelBuilder.Entity("NadekoBot.Modules.Games.FishCatch", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("integer")
.HasColumnName("count");
b.Property<int>("FishId")
.HasColumnType("integer")
.HasColumnName("fishid");
b.Property<int>("MaxStars")
.HasColumnType("integer")
.HasColumnName("maxstars");
b.Property<decimal>("UserId")
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
b.HasKey("Id")
.HasName("pk_fishcatch");
b.HasAlternateKey("UserId", "FishId")
.HasName("ak_fishcatch_userid_fishid");
b.ToTable("fishcatch", (string)null);
});
modelBuilder.Entity("NadekoBot.Modules.Games.UserFishStats", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Skill")
.HasColumnType("integer")
.HasColumnName("skill");
b.Property<decimal>("UserId")
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
b.HasKey("Id")
.HasName("pk_userfishstats");
b.HasIndex("UserId")
.IsUnique()
.HasDatabaseName("ix_userfishstats_userid");
b.ToTable("userfishstats", (string)null);
});
modelBuilder.Entity("NadekoBot.Services.GreetSettings", b =>
{
b.Property<int>("Id")
@@ -3154,6 +3482,77 @@ namespace NadekoBot.Migrations.PostgreSql
b.ToTable("greetsettings", (string)null);
});
modelBuilder.Entity("NadekoBot.Services.Rakeback", b =>
{
b.Property<decimal>("UserId")
.ValueGeneratedOnAdd()
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
b.Property<decimal>("Amount")
.HasColumnType("numeric")
.HasColumnName("amount");
b.HasKey("UserId")
.HasName("pk_rakeback");
b.ToTable("rakeback", (string)null);
});
modelBuilder.Entity("NadekoBot.Services.UserBetStats", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Game")
.HasColumnType("integer")
.HasColumnName("game");
b.Property<long>("LoseCount")
.HasColumnType("bigint")
.HasColumnName("losecount");
b.Property<long>("MaxBet")
.HasColumnType("bigint")
.HasColumnName("maxbet");
b.Property<long>("MaxWin")
.HasColumnType("bigint")
.HasColumnName("maxwin");
b.Property<decimal>("PaidOut")
.HasColumnType("numeric")
.HasColumnName("paidout");
b.Property<decimal>("TotalBet")
.HasColumnType("numeric")
.HasColumnName("totalbet");
b.Property<decimal>("UserId")
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
b.Property<long>("WinCount")
.HasColumnType("bigint")
.HasColumnName("wincount");
b.HasKey("Id")
.HasName("pk_userbetstats");
b.HasIndex("MaxWin")
.HasDatabaseName("ix_userbetstats_maxwin");
b.HasIndex("UserId", "Game")
.IsUnique()
.HasDatabaseName("ix_userbetstats_userid_game");
b.ToTable("userbetstats", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.AntiAltSetting", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
@@ -3386,18 +3785,6 @@ namespace NadekoBot.Migrations.PostgreSql
.HasConstraintName("fk_giveawayuser_giveawaymodel_giveawayid");
});
modelBuilder.Entity("NadekoBot.Db.Models.GroupName", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig")
.WithMany("SelfAssignableRoleGroupNames")
.HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_groupname_guildconfigs_guildconfigid");
b.Navigation("GuildConfig");
});
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredLogItem", b =>
{
b.HasOne("NadekoBot.Db.Models.LogSetting", "LogSetting")
@@ -3437,6 +3824,16 @@ namespace NadekoBot.Migrations.PostgreSql
.HasConstraintName("fk_playlistsong_musicplaylists_musicplaylistid");
});
modelBuilder.Entity("NadekoBot.Db.Models.Sar", b =>
{
b.HasOne("NadekoBot.Db.Models.SarGroup", null)
.WithMany("Roles")
.HasForeignKey("SarGroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_sar_sargroup_sargroupid");
});
modelBuilder.Entity("NadekoBot.Db.Models.ShopEntry", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
@@ -3616,15 +4013,6 @@ namespace NadekoBot.Migrations.PostgreSql
b.Navigation("User");
});
modelBuilder.Entity("NadekoBot.Db.Models.WarningPunishment", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("WarnPunishments")
.HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_warningpunishment_guildconfigs_guildconfigid");
});
modelBuilder.Entity("NadekoBot.Db.Models.XpCurrencyReward", b =>
{
b.HasOne("NadekoBot.Db.Models.XpSettings", "XpSettings")
@@ -3722,8 +4110,6 @@ namespace NadekoBot.Migrations.PostgreSql
b.Navigation("Permissions");
b.Navigation("SelfAssignableRoleGroupNames");
b.Navigation("ShopEntries");
b.Navigation("SlowmodeIgnoredRoles");
@@ -3740,8 +4126,6 @@ namespace NadekoBot.Migrations.PostgreSql
b.Navigation("VcRoleInfos");
b.Navigation("WarnPunishments");
b.Navigation("XpSettings");
});
@@ -3755,6 +4139,11 @@ namespace NadekoBot.Migrations.PostgreSql
b.Navigation("Songs");
});
modelBuilder.Entity("NadekoBot.Db.Models.SarGroup", b =>
{
b.Navigation("Roles");
});
modelBuilder.Entity("NadekoBot.Db.Models.ShopEntry", b =>
{
b.Navigation("Items");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class warnsplit : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<ulong>(
name: "GuildId",
table: "WarningPunishment",
type: "INTEGER",
nullable: false,
defaultValue: 0ul);
MigrationQueries.AddGuildIdsToWarningPunishment(migrationBuilder);
migrationBuilder.DropForeignKey(
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
table: "WarningPunishment");
migrationBuilder.DropIndex(
name: "IX_WarningPunishment_GuildConfigId",
table: "WarningPunishment");
migrationBuilder.DropColumn(
name: "GuildConfigId",
table: "WarningPunishment");
migrationBuilder.AddUniqueConstraint(
name: "AK_WarningPunishment_GuildId_Count",
table: "WarningPunishment",
columns: new[] { "GuildId", "Count" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropUniqueConstraint(
name: "AK_WarningPunishment_GuildId_Count",
table: "WarningPunishment");
migrationBuilder.DropColumn(
name: "GuildId",
table: "WarningPunishment");
migrationBuilder.AddColumn<int>(
name: "GuildConfigId",
table: "WarningPunishment",
type: "INTEGER",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_WarningPunishment_GuildConfigId",
table: "WarningPunishment",
column: "GuildConfigId");
migrationBuilder.AddForeignKey(
name: "FK_WarningPunishment_GuildConfigs_GuildConfigId",
table: "WarningPunishment",
column: "GuildConfigId",
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class ncanvas : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "NCPixel",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Position = table.Column<int>(type: "INTEGER", nullable: false),
Price = table.Column<long>(type: "INTEGER", nullable: false),
OwnerId = table.Column<ulong>(type: "INTEGER", nullable: false),
Color = table.Column<uint>(type: "INTEGER", nullable: false),
Text = table.Column<string>(type: "TEXT", maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_NCPixel", x => x.Id);
table.UniqueConstraint("AK_NCPixel_Position", x => x.Position);
});
migrationBuilder.CreateIndex(
name: "IX_DiscordUser_Username",
table: "DiscordUser",
column: "Username");
migrationBuilder.CreateIndex(
name: "IX_NCPixel_OwnerId",
table: "NCPixel",
column: "OwnerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "NCPixel");
migrationBuilder.DropIndex(
name: "IX_DiscordUser_Username",
table: "DiscordUser");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class nodiscrimandflagtranslate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Discriminator",
table: "DiscordUser");
migrationBuilder.CreateTable(
name: "FlagTranslateChannel",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
ChannelId = table.Column<ulong>(type: "INTEGER", nullable: false),
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_FlagTranslateChannel", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_FlagTranslateChannel_GuildId_ChannelId",
table: "FlagTranslateChannel",
columns: new[] { "GuildId", "ChannelId" },
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "FlagTranslateChannel");
migrationBuilder.AddColumn<string>(
name: "Discriminator",
table: "DiscordUser",
type: "TEXT",
nullable: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class betstats : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "UserBetStats",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
Game = table.Column<int>(type: "INTEGER", nullable: false),
WinCount = table.Column<long>(type: "INTEGER", nullable: false),
LoseCount = table.Column<long>(type: "INTEGER", nullable: false),
TotalBet = table.Column<decimal>(type: "TEXT", nullable: false),
PaidOut = table.Column<decimal>(type: "TEXT", nullable: false),
MaxWin = table.Column<long>(type: "INTEGER", nullable: false),
MaxBet = table.Column<long>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserBetStats", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_UserBetStats_UserId_Game",
table: "UserBetStats",
columns: new[] { "UserId", "Game" },
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserBetStats");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class rakeback : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Rakeback",
columns: table => new
{
UserId = table.Column<ulong>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Amount = table.Column<decimal>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Rakeback", x => x.UserId);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Rakeback");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,163 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class sarrework : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "SarAutoDelete",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
IsEnabled = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SarAutoDelete", x => x.Id);
});
migrationBuilder.CreateTable(
name: "SarGroup",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GroupNumber = table.Column<int>(type: "INTEGER", nullable: false),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
RoleReq = table.Column<ulong>(type: "INTEGER", nullable: true),
IsExclusive = table.Column<bool>(type: "INTEGER", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_SarGroup", x => x.Id);
table.UniqueConstraint("AK_SarGroup_GuildId_GroupNumber",
x => new
{
x.GuildId,
x.GroupNumber
});
});
migrationBuilder.CreateTable(
name: "Sar",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
RoleId = table.Column<ulong>(type: "INTEGER", nullable: false),
SarGroupId = table.Column<int>(type: "INTEGER", nullable: false),
LevelReq = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Sar", x => x.Id);
table.UniqueConstraint("AK_Sar_GuildId_RoleId",
x => new
{
x.GuildId,
x.RoleId
});
table.ForeignKey(
name: "FK_Sar_SarGroup_SarGroupId",
column: x => x.SarGroupId,
principalTable: "SarGroup",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Sar_SarGroupId",
table: "Sar",
column: "SarGroupId");
migrationBuilder.CreateIndex(
name: "IX_SarAutoDelete_GuildId",
table: "SarAutoDelete",
column: "GuildId",
unique: true);
MigrationQueries.MigrateSar(migrationBuilder);
migrationBuilder.DropTable(
name: "GroupName");
migrationBuilder.DropTable(
name: "SelfAssignableRoles");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Sar");
migrationBuilder.DropTable(
name: "SarAutoDelete");
migrationBuilder.DropTable(
name: "SarGroup");
migrationBuilder.CreateTable(
name: "GroupName",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildConfigId = table.Column<int>(type: "INTEGER", nullable: false),
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: true),
Name = table.Column<string>(type: "TEXT", nullable: true),
Number = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_GroupName", x => x.Id);
table.ForeignKey(
name: "FK_GroupName_GuildConfigs_GuildConfigId",
column: x => x.GuildConfigId,
principalTable: "GuildConfigs",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "SelfAssignableRoles",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: true),
Group = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 0),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
LevelRequirement = table.Column<int>(type: "INTEGER", nullable: false),
RoleId = table.Column<ulong>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_SelfAssignableRoles", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_GroupName_GuildConfigId_Number",
table: "GroupName",
columns: new[] { "GuildConfigId", "Number" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_SelfAssignableRoles_GuildId_RoleId",
table: "SelfAssignableRoles",
columns: new[] { "GuildId", "RoleId" },
unique: true);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,73 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class btnroles_guildcolors : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ButtonRole",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
ButtonId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
ChannelId = table.Column<ulong>(type: "INTEGER", nullable: false),
MessageId = table.Column<ulong>(type: "INTEGER", nullable: false),
Position = table.Column<int>(type: "INTEGER", nullable: false),
RoleId = table.Column<ulong>(type: "INTEGER", nullable: false),
Emote = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Label = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
Exclusive = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ButtonRole", x => x.Id);
table.UniqueConstraint("AK_ButtonRole_RoleId_MessageId", x => new { x.RoleId, x.MessageId });
});
migrationBuilder.CreateTable(
name: "GuildColors",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
OkColor = table.Column<string>(type: "TEXT", maxLength: 9, nullable: true),
ErrorColor = table.Column<string>(type: "TEXT", maxLength: 9, nullable: true),
PendingColor = table.Column<string>(type: "TEXT", maxLength: 9, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_GuildColors", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_ButtonRole_GuildId",
table: "ButtonRole",
column: "GuildId");
migrationBuilder.CreateIndex(
name: "IX_GuildColors_GuildId",
table: "GuildColors",
column: "GuildId",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ButtonRole");
migrationBuilder.DropTable(
name: "GuildColors");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,106 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class awardedxptemprolenotify : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_UserXpStats_AwardedXp",
table: "UserXpStats");
MigrationQueries.MergeAwardedXp(migrationBuilder);
migrationBuilder.DropColumn(
name: "AwardedXp",
table: "UserXpStats");
migrationBuilder.DropColumn(
name: "NotifyOnLevelUp",
table: "UserXpStats");
migrationBuilder.CreateTable(
name: "Notify",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
ChannelId = table.Column<ulong>(type: "INTEGER", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false),
Message = table.Column<string>(type: "TEXT", maxLength: 10000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Notify", x => x.Id);
table.UniqueConstraint("AK_Notify_GuildId_Type", x => new { x.GuildId, x.Type });
});
migrationBuilder.CreateTable(
name: "TempRole",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
Remove = table.Column<bool>(type: "INTEGER", nullable: false),
RoleId = table.Column<ulong>(type: "INTEGER", nullable: false),
UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
ExpiresAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TempRole", x => x.Id);
table.UniqueConstraint("AK_TempRole_GuildId_UserId_RoleId", x => new { x.GuildId, x.UserId, x.RoleId });
});
migrationBuilder.CreateIndex(
name: "IX_UserBetStats_MaxWin",
table: "UserBetStats",
column: "MaxWin");
migrationBuilder.CreateIndex(
name: "IX_TempRole_ExpiresAt",
table: "TempRole",
column: "ExpiresAt");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Notify");
migrationBuilder.DropTable(
name: "TempRole");
migrationBuilder.DropIndex(
name: "IX_UserBetStats_MaxWin",
table: "UserBetStats");
migrationBuilder.AddColumn<long>(
name: "AwardedXp",
table: "UserXpStats",
type: "INTEGER",
nullable: false,
defaultValue: 0L);
migrationBuilder.AddColumn<int>(
name: "NotifyOnLevelUp",
table: "UserXpStats",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "IX_UserXpStats_AwardedXp",
table: "UserXpStats",
column: "AwardedXp");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class fishes : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "FishCatch",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
FishId = table.Column<int>(type: "INTEGER", nullable: false),
Count = table.Column<int>(type: "INTEGER", nullable: false),
MaxStars = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_FishCatch", x => x.Id);
table.UniqueConstraint("AK_FishCatch_UserId_FishId", x => new { x.UserId, x.FishId });
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "FishCatch");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Migrations
{
/// <inheritdoc />
public partial class fishskill : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "UserFishStats",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
Skill = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserFishStats", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_UserFishStats_UserId",
table: "UserFishStats",
column: "UserId",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "UserFishStats");
}
}
}

View File

@@ -335,6 +335,54 @@ namespace NadekoBot.Migrations
b.ToTable("Blacklist");
});
modelBuilder.Entity("NadekoBot.Db.Models.ButtonRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ButtonId")
.IsRequired()
.HasMaxLength(200)
.HasColumnType("TEXT");
b.Property<ulong>("ChannelId")
.HasColumnType("INTEGER");
b.Property<string>("Emote")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<bool>("Exclusive")
.HasColumnType("INTEGER");
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<string>("Label")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("TEXT");
b.Property<ulong>("MessageId")
.HasColumnType("INTEGER");
b.Property<int>("Position")
.HasColumnType("INTEGER");
b.Property<ulong>("RoleId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasAlternateKey("RoleId", "MessageId");
b.HasIndex("GuildId");
b.ToTable("ButtonRole");
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
{
b.Property<int>("ClubId")
@@ -560,9 +608,6 @@ namespace NadekoBot.Migrations
b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT");
b.Property<string>("Discriminator")
.HasColumnType("TEXT");
b.Property<bool>("IsClubAdmin")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
@@ -596,6 +641,8 @@ namespace NadekoBot.Migrations
b.HasIndex("UserId");
b.HasIndex("Username");
b.ToTable("DiscordUser");
});
@@ -741,6 +788,29 @@ namespace NadekoBot.Migrations
b.ToTable("FilteredWord");
});
modelBuilder.Entity("NadekoBot.Db.Models.FlagTranslateChannel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ulong>("ChannelId")
.HasColumnType("INTEGER");
b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT");
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("GuildId", "ChannelId")
.IsUnique();
b.ToTable("FlagTranslateChannel");
});
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
{
b.Property<int>("Id")
@@ -872,30 +942,33 @@ namespace NadekoBot.Migrations
b.ToTable("GiveawayUser");
});
modelBuilder.Entity("NadekoBot.Db.Models.GroupName", b =>
modelBuilder.Entity("NadekoBot.Db.Models.GuildColors", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime?>("DateAdded")
b.Property<string>("ErrorColor")
.HasMaxLength(9)
.HasColumnType("TEXT");
b.Property<int>("GuildConfigId")
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<string>("Name")
b.Property<string>("OkColor")
.HasMaxLength(9)
.HasColumnType("TEXT");
b.Property<int>("Number")
.HasColumnType("INTEGER");
b.Property<string>("PendingColor")
.HasMaxLength(9)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("GuildConfigId", "Number")
b.HasIndex("GuildId")
.IsUnique();
b.ToTable("GroupName");
b.ToTable("GuildColors");
});
modelBuilder.Entity("NadekoBot.Db.Models.GuildConfig", b =>
@@ -1213,6 +1286,38 @@ namespace NadekoBot.Migrations
b.ToTable("MutedUserId");
});
modelBuilder.Entity("NadekoBot.Db.Models.NCPixel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<uint>("Color")
.HasColumnType("INTEGER");
b.Property<ulong>("OwnerId")
.HasColumnType("INTEGER");
b.Property<int>("Position")
.HasColumnType("INTEGER");
b.Property<long>("Price")
.HasColumnType("INTEGER");
b.Property<string>("Text")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasAlternateKey("Position");
b.HasIndex("OwnerId");
b.ToTable("NCPixel");
});
modelBuilder.Entity("NadekoBot.Db.Models.NadekoExpression", b =>
{
b.Property<int>("Id")
@@ -1251,6 +1356,33 @@ namespace NadekoBot.Migrations
b.ToTable("Expressions");
});
modelBuilder.Entity("NadekoBot.Db.Models.Notify", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ulong>("ChannelId")
.HasColumnType("INTEGER");
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<string>("Message")
.IsRequired()
.HasMaxLength(10000)
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasAlternateKey("GuildId", "Type");
b.ToTable("Notify");
});
modelBuilder.Entity("NadekoBot.Db.Models.PatronUser", b =>
{
b.Property<ulong>("UserId")
@@ -1586,35 +1718,80 @@ namespace NadekoBot.Migrations
b.ToTable("RotatingStatus");
});
modelBuilder.Entity("NadekoBot.Db.Models.SelfAssignedRole", b =>
modelBuilder.Entity("NadekoBot.Db.Models.Sar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT");
b.Property<int>("Group")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(0);
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<int>("LevelRequirement")
b.Property<int>("LevelReq")
.HasColumnType("INTEGER");
b.Property<ulong>("RoleId")
.HasColumnType("INTEGER");
b.Property<int>("SarGroupId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("GuildId", "RoleId")
b.HasAlternateKey("GuildId", "RoleId");
b.HasIndex("SarGroupId");
b.ToTable("Sar");
});
modelBuilder.Entity("NadekoBot.Db.Models.SarAutoDelete", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<bool>("IsEnabled")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("GuildId")
.IsUnique();
b.ToTable("SelfAssignableRoles");
b.ToTable("SarAutoDelete");
});
modelBuilder.Entity("NadekoBot.Db.Models.SarGroup", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("GroupNumber")
.HasColumnType("INTEGER");
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<bool>("IsExclusive")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.HasMaxLength(100)
.HasColumnType("TEXT");
b.Property<ulong?>("RoleReq")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasAlternateKey("GuildId", "GroupNumber");
b.ToTable("SarGroup");
});
modelBuilder.Entity("NadekoBot.Db.Models.ShopEntry", b =>
@@ -1863,6 +2040,36 @@ namespace NadekoBot.Migrations
b.ToTable("StreamRoleWhitelistedUser");
});
modelBuilder.Entity("NadekoBot.Db.Models.TempRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("ExpiresAt")
.HasColumnType("TEXT");
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<bool>("Remove")
.HasColumnType("INTEGER");
b.Property<ulong>("RoleId")
.HasColumnType("INTEGER");
b.Property<ulong>("UserId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasAlternateKey("GuildId", "UserId", "RoleId");
b.HasIndex("ExpiresAt");
b.ToTable("TempRole");
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.Property<int>("Id")
@@ -1977,18 +2184,12 @@ namespace NadekoBot.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<long>("AwardedXp")
.HasColumnType("INTEGER");
b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT");
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<int>("NotifyOnLevelUp")
.HasColumnType("INTEGER");
b.Property<ulong>("UserId")
.HasColumnType("INTEGER");
@@ -1997,8 +2198,6 @@ namespace NadekoBot.Migrations
b.HasKey("Id");
b.HasIndex("AwardedXp");
b.HasIndex("GuildId");
b.HasIndex("UserId");
@@ -2183,7 +2382,7 @@ namespace NadekoBot.Migrations
b.Property<DateTime?>("DateAdded")
.HasColumnType("TEXT");
b.Property<int?>("GuildConfigId")
b.Property<ulong>("GuildId")
.HasColumnType("INTEGER");
b.Property<int>("Punishment")
@@ -2197,7 +2396,7 @@ namespace NadekoBot.Migrations
b.HasKey("Id");
b.HasIndex("GuildConfigId");
b.HasAlternateKey("GuildId", "Count");
b.ToTable("WarningPunishment");
});
@@ -2309,6 +2508,51 @@ namespace NadekoBot.Migrations
b.ToTable("XpShopOwnedItem");
});
modelBuilder.Entity("NadekoBot.Modules.Games.FishCatch", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("Count")
.HasColumnType("INTEGER");
b.Property<int>("FishId")
.HasColumnType("INTEGER");
b.Property<int>("MaxStars")
.HasColumnType("INTEGER");
b.Property<ulong>("UserId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasAlternateKey("UserId", "FishId");
b.ToTable("FishCatch");
});
modelBuilder.Entity("NadekoBot.Modules.Games.UserFishStats", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("Skill")
.HasColumnType("INTEGER");
b.Property<ulong>("UserId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("UserId")
.IsUnique();
b.ToTable("UserFishStats");
});
modelBuilder.Entity("NadekoBot.Services.GreetSettings", b =>
{
b.Property<int>("Id")
@@ -2345,6 +2589,60 @@ namespace NadekoBot.Migrations
b.ToTable("GreetSettings");
});
modelBuilder.Entity("NadekoBot.Services.Rakeback", b =>
{
b.Property<ulong>("UserId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<decimal>("Amount")
.HasColumnType("TEXT");
b.HasKey("UserId");
b.ToTable("Rakeback");
});
modelBuilder.Entity("NadekoBot.Services.UserBetStats", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("Game")
.HasColumnType("INTEGER");
b.Property<long>("LoseCount")
.HasColumnType("INTEGER");
b.Property<long>("MaxBet")
.HasColumnType("INTEGER");
b.Property<long>("MaxWin")
.HasColumnType("INTEGER");
b.Property<decimal>("PaidOut")
.HasColumnType("TEXT");
b.Property<decimal>("TotalBet")
.HasColumnType("TEXT");
b.Property<ulong>("UserId")
.HasColumnType("INTEGER");
b.Property<long>("WinCount")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("MaxWin");
b.HasIndex("UserId", "Game")
.IsUnique();
b.ToTable("UserBetStats");
});
modelBuilder.Entity("NadekoBot.Db.Models.AntiAltSetting", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
@@ -2554,17 +2852,6 @@ namespace NadekoBot.Migrations
.IsRequired();
});
modelBuilder.Entity("NadekoBot.Db.Models.GroupName", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", "GuildConfig")
.WithMany("SelfAssignableRoleGroupNames")
.HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("GuildConfig");
});
modelBuilder.Entity("NadekoBot.Db.Models.IgnoredLogItem", b =>
{
b.HasOne("NadekoBot.Db.Models.LogSetting", "LogSetting")
@@ -2600,6 +2887,15 @@ namespace NadekoBot.Migrations
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("NadekoBot.Db.Models.Sar", b =>
{
b.HasOne("NadekoBot.Db.Models.SarGroup", null)
.WithMany("Roles")
.HasForeignKey("SarGroupId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("NadekoBot.Db.Models.ShopEntry", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
@@ -2760,14 +3056,6 @@ namespace NadekoBot.Migrations
b.Navigation("User");
});
modelBuilder.Entity("NadekoBot.Db.Models.WarningPunishment", b =>
{
b.HasOne("NadekoBot.Db.Models.GuildConfig", null)
.WithMany("WarnPunishments")
.HasForeignKey("GuildConfigId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("NadekoBot.Db.Models.XpCurrencyReward", b =>
{
b.HasOne("NadekoBot.Db.Models.XpSettings", "XpSettings")
@@ -2862,8 +3150,6 @@ namespace NadekoBot.Migrations
b.Navigation("Permissions");
b.Navigation("SelfAssignableRoleGroupNames");
b.Navigation("ShopEntries");
b.Navigation("SlowmodeIgnoredRoles");
@@ -2880,8 +3166,6 @@ namespace NadekoBot.Migrations
b.Navigation("VcRoleInfos");
b.Navigation("WarnPunishments");
b.Navigation("XpSettings");
});
@@ -2895,6 +3179,11 @@ namespace NadekoBot.Migrations
b.Navigation("Songs");
});
modelBuilder.Entity("NadekoBot.Db.Models.SarGroup", b =>
{
b.Navigation("Roles");
});
modelBuilder.Entity("NadekoBot.Db.Models.ShopEntry", b =>
{
b.Navigation("Items");

View File

@@ -46,7 +46,7 @@ public partial class Administration : NadekoModule<AdministrationService>
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
[BotPerm(GuildPerm.ManageGuild)]
public async Task ImageOnlyChannel(StoopidTime time = null)
public async Task ImageOnlyChannel(ParsedTimespan timespan = null)
{
var newValue = await _somethingOnly.ToggleImageOnlyChannelAsync(ctx.Guild.Id, ctx.Channel.Id);
if (newValue)
@@ -59,7 +59,7 @@ public partial class Administration : NadekoModule<AdministrationService>
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.Administrator)]
[BotPerm(GuildPerm.ManageGuild)]
public async Task LinkOnlyChannel(StoopidTime time = null)
public async Task LinkOnlyChannel(ParsedTimespan timespan = null)
{
var newValue = await _somethingOnly.ToggleLinkOnlyChannelAsync(ctx.Guild.Id, ctx.Channel.Id);
if (newValue)
@@ -72,10 +72,10 @@ public partial class Administration : NadekoModule<AdministrationService>
[RequireContext(ContextType.Guild)]
[UserPerm(ChannelPerm.ManageChannels)]
[BotPerm(ChannelPerm.ManageChannels)]
public async Task Slowmode(StoopidTime time = null)
public async Task Slowmode(ParsedTimespan timespan = null)
{
var seconds = (int?)time?.Time.TotalSeconds ?? 0;
if (time is not null && (time.Time < TimeSpan.FromSeconds(0) || time.Time > TimeSpan.FromHours(6)))
var seconds = (int?)timespan?.Time.TotalSeconds ?? 0;
if (timespan is not null && (timespan.Time < TimeSpan.FromSeconds(0) || timespan.Time > TimeSpan.FromHours(6)))
return;
await ((ITextChannel)ctx.Channel).ModifyAsync(tcp =>
@@ -96,7 +96,7 @@ public partial class Administration : NadekoModule<AdministrationService>
var guild = (SocketGuild)ctx.Guild;
var (enabled, channels) = _service.GetDelMsgOnCmdData(ctx.Guild.Id);
var embed = _sender.CreateEmbed()
var embed = CreateEmbed()
.WithOkColor()
.WithTitle(GetText(strs.server_delmsgoncmd))
.WithDescription(enabled ? "✅" : "❌");
@@ -298,18 +298,18 @@ public partial class Administration : NadekoModule<AdministrationService>
[RequireContext(ContextType.Guild)]
[UserPerm(ChannelPerm.ManageMessages)]
[BotPerm(ChannelPerm.ManageMessages)]
public Task Delete(ulong messageId, StoopidTime time = null)
=> Delete((ITextChannel)ctx.Channel, messageId, time);
public Task Delete(ulong messageId, ParsedTimespan timespan = null)
=> Delete((ITextChannel)ctx.Channel, messageId, timespan);
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task Delete(ITextChannel channel, ulong messageId, StoopidTime time = null)
=> await InternalMessageAction(channel, messageId, time, msg => msg.DeleteAsync());
public async Task Delete(ITextChannel channel, ulong messageId, ParsedTimespan timespan = null)
=> await InternalMessageAction(channel, messageId, timespan, msg => msg.DeleteAsync());
private async Task InternalMessageAction(
ITextChannel channel,
ulong messageId,
StoopidTime time,
ParsedTimespan timespan,
Func<IMessage, Task> func)
{
var userPerms = ((SocketGuildUser)ctx.User).GetPermissions(channel);
@@ -334,13 +334,13 @@ public partial class Administration : NadekoModule<AdministrationService>
return;
}
if (time is null)
if (timespan is null)
await msg.DeleteAsync();
else if (time.Time <= TimeSpan.FromDays(7))
else if (timespan.Time <= TimeSpan.FromDays(7))
{
_ = Task.Run(async () =>
{
await Task.Delay(time.Time);
await Task.Delay(timespan.Time);
await msg.DeleteAsync();
});
}

View File

@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore;
using NadekoBot.Db.Models;
using NadekoBot.Modules.Administration._common.results;
namespace NadekoBot.Modules.Administration.Services;
namespace NadekoBot.Modules.Administration;
public class AdministrationService : INService
{

View File

@@ -24,6 +24,13 @@ public partial class Administration
await Response().Error(strs.hierarchy).SendAsync();
return;
}
// the user can't aar the role which is greater or equal to the bot's highest role
if (role.Position >= ((SocketGuild)ctx.Guild).CurrentUser.GetRoles().Max(x => x.Position))
{
await Response().Error(strs.hierarchy).SendAsync();
return;
}
var roles = await _service.ToggleAarAsync(ctx.Guild.Id, role.Id);
if (roles.Count == 0)

View File

@@ -1,4 +1,3 @@
#nullable disable
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using NadekoBot.Common.ModuleBehaviors;
@@ -11,53 +10,63 @@ public class AutoPublishService : IExecNoCommand, IReadyExecutor, INService
private readonly DbService _db;
private readonly DiscordSocketClient _client;
private readonly IBotCredsProvider _creds;
private ConcurrentDictionary<ulong, ulong> _enabled;
private ConcurrentDictionary<ulong, ulong> _enabled = new();
public AutoPublishService(DbService db, DiscordSocketClient client, IBotCredsProvider creds)
{
_db = db;
_client = client;
_creds = creds;
}
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
}
public async Task ExecOnNoCommandAsync(IGuild? guild, IUserMessage msg)
{
if (guild is null)
return;
if (msg.Channel.GetChannelType() != ChannelType.News)
return;
if (!_enabled.TryGetValue(guild.Id, out var cid) || cid != msg.Channel.Id)
return;
await msg.CrosspostAsync(new RequestOptions()
{
RetryMode = RetryMode.AlwaysFail
});
}
// todo GUILDS
public async Task OnReadyAsync()
{
var creds = _creds.GetCreds();
await using var ctx = _db.GetDbContext();
var items = await ctx.GetTable<AutoPublishChannel>()
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId, creds.TotalShards, _client.ShardId))
.ToListAsyncLinqToDB();
.Where(x => Linq2DbExpressions.GuildOnShard(x.GuildId, creds.TotalShards, _client.ShardId))
.ToListAsyncLinqToDB();
_enabled = items
.ToDictionary(x => x.GuildId, x => x.ChannelId)
.ToConcurrent();
.ToDictionary(x => x.GuildId, x => x.ChannelId)
.ToConcurrent();
_client.LeftGuild += ClientOnLeftGuild;
}
private async Task ClientOnLeftGuild(SocketGuild guild)
{
await using var ctx = _db.GetDbContext();
_enabled.TryRemove(guild.Id, out _);
await ctx.GetTable<AutoPublishChannel>()
.Where(x => x.GuildId == guild.Id)
.DeleteAsync();
}
public async Task<bool> ToggleAutoPublish(ulong guildId, ulong channelId)
{
await using var ctx = _db.GetDbContext();
var deleted = await ctx.GetTable<AutoPublishChannel>()
.DeleteAsync(x => x.GuildId == guildId && x.ChannelId == channelId);
.DeleteAsync(x => x.GuildId == guildId && x.ChannelId == channelId);
if (deleted != 0)
{
@@ -66,22 +75,22 @@ public class AutoPublishService : IExecNoCommand, IReadyExecutor, INService
}
await ctx.GetTable<AutoPublishChannel>()
.InsertOrUpdateAsync(() => new()
{
GuildId = guildId,
ChannelId = channelId,
DateAdded = DateTime.UtcNow,
},
old => new()
{
ChannelId = channelId,
DateAdded = DateTime.UtcNow,
},
() => new()
{
GuildId = guildId
});
.InsertOrUpdateAsync(() => new()
{
GuildId = guildId,
ChannelId = channelId,
DateAdded = DateTime.UtcNow,
},
old => new()
{
ChannelId = channelId,
DateAdded = DateTime.UtcNow,
},
() => new()
{
GuildId = guildId
});
_enabled[guildId] = channelId;
return true;

View File

@@ -136,7 +136,7 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, INService
await using var linqCtx = ctx.CreateLinqToDBContext();
await using var tempTable = linqCtx.CreateTempTable<CleanupId>();
foreach (var chunk in allIds.Chunk(20000))
foreach (var chunk in allIds.Chunk(10000))
{
await tempTable.BulkCopyAsync(chunk.Select(x => new CleanupId()
{
@@ -187,13 +187,6 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, INService
.Contains(x.GuildId))
.DeleteAsync();
// delete ignored users
await ctx.GetTable<DiscordPermOverride>()
.Where(x => x.GuildId != null
&& !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId.Value))
.DeleteAsync();
// delete perm overrides
await ctx.GetTable<DiscordPermOverride>()
.Where(x => x.GuildId != null
@@ -206,7 +199,67 @@ public sealed class CleanupService : ICleanupService, IReadyExecutor, INService
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete autopublish channels
await ctx.GetTable<AutoPublishChannel>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete greet settings
await ctx.GetTable<GreetSettings>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete sar
await ctx.GetTable<SarGroup>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete warnings
await ctx.GetTable<Warning>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete warn punishments
await ctx.GetTable<WarningPunishment>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete sticky roles
await ctx.GetTable<StickyRole>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete at channels
await ctx.GetTable<AutoTranslateChannel>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete ban templates
await ctx.GetTable<BanTemplate>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
// delete reminders
await ctx.GetTable<Reminder>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.ServerId))
.DeleteAsync();
// delete button roles
await ctx.GetTable<ButtonRole>()
.Where(x => !tempTable.Select(x => x.GuildId)
.Contains(x.GuildId))
.DeleteAsync();
return new()
{
GuildCount = guildIds.Keys.Count,

View File

@@ -42,9 +42,9 @@ public partial class Administration
.Page((items, _) =>
{
if (!items.Any())
return _sender.CreateEmbed().WithErrorColor().WithFooter(sql).WithDescription("-");
return CreateEmbed().WithErrorColor().WithFooter(sql).WithDescription("-");
return _sender.CreateEmbed()
return CreateEmbed()
.WithOkColor()
.WithFooter(sql)
.WithTitle(string.Join(" ║ ", result.ColumnNames))
@@ -99,7 +99,7 @@ public partial class Administration
{
try
{
var embed = _sender.CreateEmbed()
var embed = CreateEmbed()
.WithTitle(GetText(strs.sql_confirm_exec))
.WithDescription(Format.Code(sql));
@@ -119,7 +119,7 @@ public partial class Administration
[OwnerOnly]
public async Task PurgeUser(ulong userId)
{
var embed = _sender.CreateEmbed()
var embed = CreateEmbed()
.WithDescription(GetText(strs.purge_user_confirm(Format.Bold(userId.ToString()))));
if (!await PromptUserConfirmAsync(embed))
@@ -138,8 +138,7 @@ public partial class Administration
[OwnerOnly]
public Task DeleteXp()
=> ConfirmActionInternalAsync("Delete Xp", () => _xcs.DeleteXp());
[Cmd]
[OwnerOnly]
public Task DeleteWaifus()

View File

@@ -200,9 +200,7 @@ public partial class Administration
if (!isEnabled)
{
var cmdName = GetCmdName(type);
await Response().Pending(strs.boostmsg_enable($"`{prefix}{cmdName}`")).SendAsync();
await SendGreetEnableHint(type);
}
}
@@ -226,19 +224,24 @@ public partial class Administration
await _service.Test(ctx.Guild.Id, type, (ITextChannel)ctx.Channel, user);
var conf = await _service.GetGreetSettingsAsync(ctx.Guild.Id, type);
if (conf?.IsEnabled is not true)
await SendGreetEnableHint(type);
}
private async Task SendGreetEnableHint(GreetType type)
{
var cmd = $"`{prefix}{GetCmdName(type)}`";
var str = type switch
{
GreetType.Greet => strs.boostmsg_enable(cmd),
GreetType.Bye => strs.greetmsg_enable(cmd),
GreetType.Boost => strs.byemsg_enable(cmd),
GreetType.Greet => strs.greetmsg_enable(cmd),
GreetType.Bye => strs.byemsg_enable(cmd),
GreetType.Boost => strs.boostmsg_enable(cmd),
GreetType.GreetDm => strs.greetdmmsg_enable(cmd),
_ => strs.error
};
if (conf?.IsEnabled is not true)
await Response().Pending(str).SendAsync();
await Response().Pending(str).SendAsync();
}
}
}

View File

@@ -208,11 +208,11 @@ public class GreetService : INService, IReadyExecutor
return Task.CompletedTask;
}
private TypedKey<GreetSettings?> GreetSettingsKey(GreetType type)
=> new($"greet_settings:{type}");
private TypedKey<GreetSettings?> GreetSettingsKey(ulong gid, GreetType type)
=> new($"greet_settings:{gid}:{type}");
public async Task<GreetSettings?> GetGreetSettingsAsync(ulong gid, GreetType type)
=> await _cache.GetOrAddAsync<GreetSettings?>(GreetSettingsKey(type),
=> await _cache.GetOrAddAsync<GreetSettings?>(GreetSettingsKey(gid, type),
() => InternalGetGreetSettingsAsync(gid, type),
TimeSpan.FromSeconds(3));
@@ -339,7 +339,7 @@ public class GreetService : INService, IReadyExecutor
}
catch (Exception ex)
{
Log.Error(ex, "Error sending greet dm");
Log.Warning(ex, "Unable to send Greet DM. Probably the user has closed DMs");
return false;
}

View File

@@ -71,7 +71,7 @@ public sealed class HoneyPotService : IHoneyPotService, IReadyExecutor, IExecNoC
try
{
Log.Information("Honeypot caught user {User} [{UserId}]", user, user.Id);
await user.BanAsync(pruneDays: 1);
await user.BanAsync(pruneDays: 1, reason: "Honeypot");
await user.Guild.RemoveBanAsync(user.Id);
}
catch (Exception e)

View File

@@ -123,7 +123,7 @@ public partial class Administration
[Cmd]
public async Task LanguagesList()
=> await Response().Embed(_sender.CreateEmbed()
=> await Response().Embed(CreateEmbed()
.WithOkColor()
.WithTitle(GetText(strs.lang_list))
.WithDescription(string.Join("\n",

View File

@@ -72,18 +72,18 @@ public partial class Administration
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageRoles | GuildPerm.MuteMembers)]
[Priority(1)]
public async Task Mute(StoopidTime time, IGuildUser user, [Leftover] string reason = "")
public async Task Mute(ParsedTimespan timespan, IGuildUser user, [Leftover] string reason = "")
{
if (time.Time < TimeSpan.FromMinutes(1) || time.Time > TimeSpan.FromDays(49))
if (timespan.Time < TimeSpan.FromMinutes(1) || timespan.Time > TimeSpan.FromDays(49))
return;
try
{
if (!await VerifyMutePermissions((IGuildUser)ctx.User, user))
return;
await _service.TimedMute(user, ctx.User, time.Time, reason: reason);
await _service.TimedMute(user, ctx.User, timespan.Time, reason: reason);
await Response().Confirm(strs.user_muted_time(Format.Bold(user.ToString()),
(int)time.Time.TotalMinutes)).SendAsync();
(int)timespan.Time.TotalMinutes)).SendAsync();
}
catch (Exception ex)
{
@@ -133,18 +133,18 @@ public partial class Administration
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageRoles)]
[Priority(1)]
public async Task ChatMute(StoopidTime time, IGuildUser user, [Leftover] string reason = "")
public async Task ChatMute(ParsedTimespan timespan, IGuildUser user, [Leftover] string reason = "")
{
if (time.Time < TimeSpan.FromMinutes(1) || time.Time > TimeSpan.FromDays(49))
if (timespan.Time < TimeSpan.FromMinutes(1) || timespan.Time > TimeSpan.FromDays(49))
return;
try
{
if (!await VerifyMutePermissions((IGuildUser)ctx.User, user))
return;
await _service.TimedMute(user, ctx.User, time.Time, MuteType.Chat, reason);
await _service.TimedMute(user, ctx.User, timespan.Time, MuteType.Chat, reason);
await Response().Confirm(strs.user_chat_mute_time(Format.Bold(user.ToString()),
(int)time.Time.TotalMinutes)).SendAsync();
(int)timespan.Time.TotalMinutes)).SendAsync();
}
catch (Exception ex)
{
@@ -193,18 +193,18 @@ public partial class Administration
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.MuteMembers)]
[Priority(1)]
public async Task VoiceMute(StoopidTime time, IGuildUser user, [Leftover] string reason = "")
public async Task VoiceMute(ParsedTimespan timespan, IGuildUser user, [Leftover] string reason = "")
{
if (time.Time < TimeSpan.FromMinutes(1) || time.Time > TimeSpan.FromDays(49))
if (timespan.Time < TimeSpan.FromMinutes(1) || timespan.Time > TimeSpan.FromDays(49))
return;
try
{
if (!await VerifyMutePermissions((IGuildUser)ctx.User, user))
return;
await _service.TimedMute(user, ctx.User, time.Time, MuteType.Voice, reason);
await _service.TimedMute(user, ctx.User, timespan.Time, MuteType.Voice, reason);
await Response().Confirm(strs.user_voice_mute_time(Format.Bold(user.ToString()),
(int)time.Time.TotalMinutes)).SendAsync();
(int)timespan.Time.TotalMinutes)).SendAsync();
}
catch
{

View File

@@ -122,7 +122,7 @@ public class MuteService : INService
return;
_ = Task.Run(() => _sender.Response(user)
.Embed(_sender.CreateEmbed()
.Embed(_sender.CreateEmbed(user?.GuildId)
.WithDescription($"You've been muted in {user.Guild} server")
.AddField("Mute Type", type.ToString())
.AddField("Moderator", mod.ToString())
@@ -140,7 +140,7 @@ public class MuteService : INService
return;
_ = Task.Run(() => _sender.Response(user)
.Embed(_sender.CreateEmbed()
.Embed(_sender.CreateEmbed(user.GuildId)
.WithDescription($"You've been unmuted in {user.Guild} server")
.AddField("Unmute Type", type.ToString())
.AddField("Moderator", mod.ToString())

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