Compare commits

..

16 Commits
5.0.0 ... 5.0.5

Author SHA1 Message Date
Kwoth
23c8dc00e8 dev: Upped version to 5.0.5 2024-05-11 08:02:59 +00:00
Kwoth
0da8190637 fix: repeat, greet, bye, boost messages can now once again mention anyone
fix: .say #channel fixed
2024-05-11 08:00:48 +00:00
Kwoth
d766295286 docs: Updated supported distros (thx cata) 2024-05-11 05:57:31 +00:00
Kwoth
21e3c64e01 Merge branch 'v5' of https://gitlab.com/kwoth/nadekobot into v5 2024-05-11 02:30:40 +00:00
Kwoth
9ddcd6d89e docs: Updated changelog 2024-05-11 02:05:56 +00:00
Kwoth
a154d5881c docs: Updated changelog 2024-05-10 15:36:12 +00:00
Kwoth
fb594e50fd fix: .h fixed, .xp fixed, pagination in .lb fixed 2024-05-10 15:29:04 +00:00
Kwoth
75c5a003bf fix: cleverbot:response should now be a valid module name 2024-05-10 09:53:20 +00:00
Kwoth
6f4cbddcad dev: Changed some namespaces. Pushing tags, Releasing 5.0.3 2024-05-10 05:56:02 +00:00
Kwoth
40528150f7 dev: Revert links back in the code, check for updates in the original nadekobot project 2024-05-10 04:58:25 +00:00
Kwoth
2b80823a1b docs: revert links back to kwoth/nadekobot as gitlab's organization thing is a ripoff 2024-05-10 04:56:26 +00:00
Kwoth
37ee769119 docs: Changed changelog version to 5.0.2 to avoid confusion 2024-05-10 02:56:14 +00:00
Kwoth
cfd39ebbd5 fix: windows exe shouldn't ask for .net to be installed anymore
fix: Version number is now correct
docs: Updated .net version name in the docs
2024-05-10 02:05:35 +00:00
Kwoth
0532b30f7f docs: updated docs to point to the new installer location 2024-05-09 14:17:25 +00:00
Kwoth
b92a38f49d docs: Changelog updated 2024-05-09 13:37:38 +00:00
Kwoth
81711c557a ci: give up on single file, try to fix docker, medusa builds 2024-05-09 13:30:02 +00:00
48 changed files with 278 additions and 227 deletions

View File

@@ -30,12 +30,12 @@ variables:
build:
stage: build
script:
- "dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true -o $LINUX_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r linux-arm64 --self-contained -p:PublishSingleFile=true -o $LINUX_ARM64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o $WIN_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r win-arm64 --self-contained -p:PublishSingleFile=true -o $WIN_ARM64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r osx-x64 --self-contained -p:PublishSingleFile=true -o $MACOS_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r osx-arm64 --self-contained -p:PublishSingleFile=true -o $MACOS_ARM64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r linux-x64 --self-contained -o $LINUX_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r linux-arm64 --self-contained -o $LINUX_ARM64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r win-x64 --self-contained -o $WIN_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r win-arm64 --self-contained -o $WIN_ARM64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r osx-x64 --self-contained -o $MACOS_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
- "dotnet publish -c Release -r osx-arm64 --self-contained -o $MACOS_ARM64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
artifacts:
paths:
- "$LINUX_X64_OUTPUT_DIR/"
@@ -81,7 +81,7 @@ release:
- if: $CI_COMMIT_TAG
script:
- |
release-cli create --name "NadekoBot v$CI_COMMIT_TAG" --description "## [Changelog](https://gitlab.com/nadeko/nadekobot/-/blob/v5/CHANGELOG.md#$(echo "$CI_COMMIT_TAG" | sed "s/\.//g")-$(date +%d%m%Y))" --tag-name $CI_COMMIT_TAG \
release-cli create --name "NadekoBot v$CI_COMMIT_TAG" --description "## [Changelog](https://gitlab.com/kwoth/nadekobot/-/blob/v5/CHANGELOG.md#$(echo "$CI_COMMIT_TAG" | sed "s/\.//g")-$(date +%d%m%Y))" --tag-name $CI_COMMIT_TAG \
--assets-link "{\"name\":\"${LINUX_X64_RELEASE}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${LINUX_X64_RELEASE}\"}" \
--assets-link "{\"name\":\"${LINUX_ARM64_RELEASE}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${LINUX_ARM64_RELEASE}\"}" \
--assets-link "{\"name\":\"${WIN_X64_RELEASE}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${WIN_X64_RELEASE}\"}" \
@@ -113,7 +113,7 @@ build-installer:
script:
- dotnet clean
- dotnet restore -f --no-cache -v n
- dotnet publish -c Release -p:PublishSingleFile=true --runtime win-x64 /p:Version=$CI_COMMIT_TAG src/NadekoBot
- dotnet publish -c Release --self-contained --runtime win-x64 /p:Version=$CI_COMMIT_TAG src/NadekoBot
- $env:NADEKOBOT_INSTALL_VERSION = $CI_COMMIT_TAG
- iscc.exe "/O+" ".\exe_builder.iss"
tags:
@@ -121,11 +121,12 @@ build-installer:
publish-medusa-package:
stage: publish-medusa-package
allow_failure: true
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_TAG
script:
- LAST_TAG=$(git describe --tags --abbrev=0)
- if [ $CI_COMMIT_TAG ];then MEDUSA_VERSION="$CI_COMMIT_TAG"; else MEDUSA_VERSION="$LAST_TAG+$CI_COMMIT_SHORT_SHA"; fi
- if [ $CI_COMMIT_TAG ];then MEDUSA_VERSION="$CI_COMMIT_TAG"; else MEDUSA_VERSION="$LAST_TAG-alpha$CI_COMMIT_SHORT_SHA"; fi
- cd src/Nadeko.Medusa/
- dotnet pack -c Release /p:Version=$MEDUSA_VERSION -o bin/Release/packed
- dotnet nuget push bin/Release/packed/ --source https://www.myget.org/F/nadeko/api/v2/package --api-key "$MYGET_API_KEY"

View File

@@ -2,7 +2,15 @@
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o
## [5.0.0]
## [5.0.5] - 11.05.2024
### Fixed
- `%server.members%` placeholder fixed
- `.say #channel <message>` should now be working properly again
- `.repeat`, `.greet`, `.bye` and `.boost` command can now once again mention anyone
## [5.0.4] - 10.05.2024
### Added
@@ -71,7 +79,7 @@ Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except da
- Removed log voice presence TTS
- Cleanup: Removed a lot of obsolete aliases from aliases.yml
## [4.3.22] - 23.04.2023
## [4.3.22] - 23.04.2024
### Added
- Added `.setbanner` command (thx cata)
@@ -80,7 +88,7 @@ Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except da
- Fixed pagination error due to a missing emoji
## [4.3.21] - 19.04.2023
## [4.3.21] - 19.04.2024
### Fixed
- Possible fix for a duplicate in `.h bank`

View File

@@ -27,7 +27,7 @@ RUN set -xe; \
useradd -m nadeko; \
apt-get update; \
apt-get install -y --no-install-recommends libopus0 libsodium23 libsqlite3-0 curl ffmpeg python3 sudo; \
update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1; \
update-alternatives --install /usr/local/bin/python python /usr/bin/python3.9 1; \
echo 'Defaults>nadeko env_keep+="ASPNETCORE_* DOTNET_* NadekoBot_* shard_id total_shards TZ"' > /etc/sudoers.d/nadeko; \
curl -Lo /usr/local/bin/yt-dlp https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp; \
chmod a+rx /usr/local/bin/yt-dlp; \

View File

@@ -1,6 +1,6 @@
# How to contribute
1. Make Merge Requests to the [**v5 branch**](https://gitlab.com/nadeko/nadekobot/tree/v5)
1. Make Merge Requests to the [**v5 branch**](https://gitlab.com/kwoth/nadekobot/tree/v5)
2. Keep a single Merge Request to a single feature
3. Fill out the MR template

View File

@@ -30,7 +30,7 @@ You can also donate to us through [PayPal][paypal] for one-time donations using
[![img][paypal-button]][paypal]
[gitlab]: https://gitlab.com/nadeko/nadekobot
[gitlab]: https://gitlab.com/kwoth/nadekobot
[discord-server]: https://discord.nadeko.bot/
[patreon]: https://www.patreon.com/nadekobot
[patreon-button]: ./assets/patreon.png

View File

@@ -14,7 +14,7 @@
version: "3.7"
services:
nadeko:
image: registry.gitlab.com/nadeko/nadekobot:latest
image: registry.gitlab.com/kwoth/nadekobot:latest
depends_on:
- redis
environment:

View File

@@ -15,12 +15,13 @@
##### Compatible operating systems:
- Ubuntu: 18.04, 20.04, 22.04, 22.10
- Mint: 19, 20, 21
- Debian: 10, 11
- CentOS: 7
- openSUSE 15
- ~~Fedora: 33, 34, 35~~ (Fedora is Pending Support)
- Ubuntu: 16.04, 18.04, 20.04, 21.04, 21.10, 22.04
- Mint: 19, 20
- Debian: 10, 11, 12
- RockyLinux: 8, 9
- AlmaLinux: 8, 9
- openSUSE Leap: 15.5, 15.6 & Tumbleweed
- Fedora: 38, 39, 40, 41, 42
## Linux From Source
@@ -28,7 +29,7 @@
Follow the following few steps only if you're migrating from v3. If not, skip to installation instructions.
Use the new installer script: `cd ~ && wget -N https://gitlab.com/Kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
Use the new installer script: `cd ~ && wget -N https://gitlab.com/kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
> - Install prerequisites (type `1` and press `enter`)
> - Download (type `2` and press `enter`)
> - Run (type `3` and press `enter`)
@@ -38,7 +39,7 @@ Use the new installer script: `cd ~ && wget -N https://gitlab.com/Kwoth/nadeko-
Open Terminal (if you're on an installation with a window manager) and navigate to the location where you want to install the bot (for example `cd ~`)
1. Download and run the **new** installer script `cd ~ && wget -N https://gitlab.com/Kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
1. Download and run the **new** installer script `cd ~ && wget -N https://gitlab.com/kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
2. Install prerequisites (type `1` and press enter)
3. Download the bot (type `2` and press enter)
4. Exit the installer (type `6` and press enter)
@@ -50,13 +51,13 @@ Open Terminal (if you're on an installation with a window manager) and navigate
- `CTRL` + `X`
- `Y`
- `Enter`
8. Run the installer script again `cd ~ && wget -N https://gitlab.com/Kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
8. Run the installer script again `cd ~ && wget -N https://gitlab.com/kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
9. Run the bot (type `3` and press enter)
##### Source Update Instructions
1. ⚠ Stop the bot ⚠
2. Update and run the **new** installer script `cd ~ && wget -N https://gitlab.com/Kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
2. Update and run the **new** installer script `cd ~ && wget -N https://gitlab.com/kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
3. Update the bot (type `2` and press enter)
4. Run the bot (type `3` and press enter)
5. 🎉
@@ -74,11 +75,11 @@ Open Terminal (if you're on an installation with a window manager) and navigate
3. Make sure your python is version 3+ with `python --version`
- if it's not, you can install python 3 and make it the default with: `sudo apt-get install python3.8 python-is-python3`
*You can use nadeko bash script [prerequisites installer](https://gitlab.com/Kwoth/nadeko-bash-installer/-/blob/v5/n-prereq.sh) as a reference*
*You can use nadeko bash script [prerequisites installer](https://gitlab.com/kwoth/nadeko-bash-installer/-/blob/v5/n-prereq.sh) as a reference*
##### Installation Instructions
1. Download the latest release from <https://gitlab.com/nadeko/nadekobot/-/releases>
1. Download the latest release from <https://gitlab.com/kwoth/nadekobot/-/releases>
- Look for the file called "X.XX.X-linux-x64-build.tar" (where X.XX.X is a series of numbers) and download it
2. Untar it
- ⚠ Make sure that you change X.XX.X to the same series of numbers as in step 1!
@@ -102,7 +103,7 @@ Open Terminal (if you're on an installation with a window manager) and navigate
##### Release Update Instructions
1. Stop the bot
2. Download the latest release from <https://gitlab.com/nadeko/nadekobot/-/releases>
2. Download the latest release from <https://gitlab.com/kwoth/nadekobot/-/releases>
- Look for the file called "x.x.x-linux-x64-build.tar" (where `X.X.X` is a version, for example 3.0.4) and download it
3. Untar it
- ⚠ Make sure that you change `X.X.X` to the same series of numbers as in step 2!

View File

@@ -31,7 +31,7 @@ sudo ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
##### Installation Instructions
1. Download and run the **new** installer script `cd ~ && wget -N https://gitlab.com/Kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
1. Download and run the **new** installer script `cd ~ && wget -N https://gitlab.com/kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
2. Install prerequisites (type `1` and press enter)
3. Download the bot (type `2` and press enter)
4. Exit the installer in order to set up your `creds.yml`
@@ -49,7 +49,7 @@ sudo ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
##### Update Instructions
1. ⚠ Stop the bot
2. Update and run the **new** installer script `cd ~ && wget -N https://gitlab.com/Kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
2. Update and run the **new** installer script `cd ~ && wget -N https://gitlab.com/kwoth/nadeko-bash-installer/-/raw/v5/linuxAIO.sh && bash linuxAIO.sh`
3. Update the bot (type `2` and press enter)
4. Run the bot (type `3` and press enter)
5. 🎉
@@ -60,7 +60,7 @@ sudo ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
##### Installation Instructions
1. Download the latest release from <https://gitlab.com/nadeko/nadekobot/-/releases>
1. Download the latest release from <https://gitlab.com/kwoth/nadekobot/-/releases>
- Look for the file called "X.XX.X-linux-x64-build.tar" (where X.XX.X is a series of numbers) and download it
2. Untar it
⚠ Make sure that you change X.XX.X to the same series of numbers as in step 1!
@@ -84,7 +84,7 @@ sudo ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
##### Update Instructions
1. Stop the bot
2. Download the latest release from <https://gitlab.com/nadeko/nadekobot/-/releases>
2. Download the latest release from <https://gitlab.com/kwoth/nadekobot/-/releases>
- Look for the file called "X.XX.X-linux-x64-build.tar" (where X.XX.X is a series of numbers) and download it
3. Untar it
⚠ Make sure that you change X.XX.X to the same series of numbers as in step 2!

View File

@@ -67,7 +67,7 @@ You can still install them manually:
##### Prerequisites
**Install these before proceeding or your bot will not work!**
- [.net 7](https://dotnet.microsoft.com/en-us/download) - needed to compile and run the bot
- [.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
@@ -75,7 +75,7 @@ You can still install them manually:
Open PowerShell (press windows button on your keyboard and type powershell, it should show up; alternatively, right click the start menu and select Windows PowerShell), and navigate to the location where you want to install the bot (for example `cd ~/Desktop/`)
1. `git clone https://gitlab.com/nadeko/nadekobot -b v5 --depth 1`
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`
@@ -93,8 +93,12 @@ Open PowerShell as described above and run the following commands:
- ⚠️ Make sure you don't have your database, credentials or any other nadekobot folder open in some application, this might prevent some of the steps from executing succesfully
2. Navigate to your bot's folder, example:
- `cd ~/Desktop/nadekobot`
3. Pull the new version
- `git pull`
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`

View File

@@ -36,6 +36,6 @@ If you're unsure whether something is an issue, ask in our support server first.
[macos-guide]: ./guides/osx-guide.md
[from-source-guide]: ./guides/from-source.md
[discord-server]: https://discord.nadeko.bot/
[gitlab]: https://gitlab.com/nadeko/nadekobot
[issues]: https://gitlab.com/nadeko/nadekobot/issues
[gitlab]: https://gitlab.com/kwoth/nadekobot
[issues]: https://gitlab.com/kwoth/nadekobot/issues
[donate]: ./donate.md

View File

@@ -8,7 +8,7 @@ Medusa system allows you to write independent medusae (known as "modules", "cogs
The system itself borrows some design from the current way Nadeko's Modules are written but mostly from never-released `Ayu.Commands` system which was designed to be used for a full Nadeko v3 rewrite.
The medusa base classes used for development are open source [here](https://gitlab.com/nadeko/nadekobot/-/tree/v5/src/Nadeko.Medusa) in case you need reference, as there is no generated documentation at the moment.
The medusa base classes used for development are open source [here](https://gitlab.com/kwoth/nadekobot/-/tree/v5/src/Nadeko.Medusa) in case you need reference, as there is no generated documentation at the moment.
### Term list
@@ -161,7 +161,7 @@ This section will guide you through how to create a simple custom medusa. You ca
</PackageReference>
<!-- Note: If you want to use NadekoBot services etc... You will have to manually clone
the https://gitlab.com/nadeko/nadekobot repo locally and reference the NadekoBot.csproj because there is no NadekoBot package atm.
the https://gitlab.com/kwoth/nadekobot repo locally and reference the NadekoBot.csproj because there is no NadekoBot package atm.
It is strongly recommended that you checkout a specific tag which matches your version of nadeko,
as there could be breaking changes even between minor versions of NadekoBot.
For example if you're running NadekoBot 4.1.0 locally for which you want to create a medusa for,

View File

@@ -97,7 +97,7 @@ public class GreetService : INService, IReadyExecutor
{
var newContent = await _repSvc.ReplaceAsync(toSend,
new(client: _client, guild: user.Guild, channel: channel, users: user));
var toDelete = await _sender.Response(channel).Text(newContent).SendAsync();
var toDelete = await _sender.Response(channel).Text(newContent).Sanitize(false).SendAsync();
if (conf.BoostMessageDeleteAfter > 0)
toDelete.DeleteAfter(conf.BoostMessageDeleteAfter);
@@ -217,7 +217,7 @@ public class GreetService : INService, IReadyExecutor
text = await _repSvc.ReplaceAsync(text, repCtx);
try
{
var toDelete = await _sender.Response(channel).Text(text).SendAsync();
var toDelete = await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
if (conf.AutoDeleteByeMessagesTimer > 0)
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
}
@@ -258,7 +258,7 @@ public class GreetService : INService, IReadyExecutor
text = await _repSvc.ReplaceAsync(text, repCtx);
try
{
var toDelete = await _sender.Response(channel).Text(text).SendAsync();
var toDelete = await _sender.Response(channel).Text(text).Sanitize(false).SendAsync();
if (conf.AutoDeleteGreetMessagesTimer > 0)
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
}
@@ -360,7 +360,7 @@ public class GreetService : INService, IReadyExecutor
}
}
await _sender.Response(user).Text(smartText).SendAsync();
await _sender.Response(user).Text(smartText).Sanitize(false).SendAsync();
}
catch
{
@@ -573,8 +573,6 @@ public class GreetService : INService, IReadyExecutor
public bool SetBoostMessage(ulong guildId, ref string message)
{
message = message.SanitizeMentions();
using var uow = _db.GetDbContext();
var conf = uow.GuildConfigsForId(guildId, set => set);
conf.BoostMessage = message;

View File

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

View File

@@ -19,7 +19,7 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor
private readonly IMessageSenderService _sender;
private const string RELEASES_URL = "https://gitlab.com/api/v4/projects/57687445/releases";
private const string RELEASES_URL = "https://gitlab.com/api/v4/projects/9321079/releases";
public CheckForUpdatesService(
BotConfigService bcs,
@@ -72,7 +72,7 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor
UpdateLastKnownVersion(latestVersion);
// pull changelog
var changelog = await http.GetStringAsync("https://gitlab.com/nadeko/nadekobot/-/raw/v5/CHANGELOG.md");
var changelog = await http.GetStringAsync("https://gitlab.com/kwoth/nadekobot/-/raw/v5/CHANGELOG.md");
var thisVersionChangelog = GetVersionChangelog(latestVersion, changelog);
@@ -95,7 +95,7 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor
.WithOkColor()
.WithAuthor($"NadekoBot v{latest} Released!")
.WithTitle("Changelog")
.WithUrl("https://gitlab.com/nadeko/nadekobot/-/blob/v5/CHANGELOG.md")
.WithUrl("https://gitlab.com/kwoth/nadekobot/-/blob/v5/CHANGELOG.md")
.WithDescription(thisVersionChangelog.TrimTo(4096))
.WithFooter(
"You may disable these messages by typing '.conf bot checkforupdates false'");

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public readonly struct FlipResult
{

View File

@@ -11,7 +11,7 @@ using NadekoBot.Services.Currency;
using System.Collections.Immutable;
using System.Globalization;
using System.Text;
using Nadeko.Econ.Gambling.Rps;
using NadekoBot.Modules.Gambling.Rps;
using NadekoBot.Common.TypeReaders;
using NadekoBot.Modules.Patronage;
@@ -776,7 +776,7 @@ public partial class Gambling : GamblingModule<GamblingService>
await using var uow = _db.GetDbContext();
var cleanRichest = await uow.Set<DiscordUser>()
.GetTopRichest(_client.CurrentUser.Id, 0, 10_000);
.GetTopRichest(_client.CurrentUser.Id, 0, 1000);
var sg = (SocketGuild)ctx.Guild!;
return cleanRichest.Where(x => sg.GetUser(x.UserId) is not null).ToList();
@@ -787,10 +787,14 @@ public partial class Gambling : GamblingModule<GamblingService>
return await uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, curPage);
}
}
var res = Response()
.Paginated();
await Response()
.Paginated()
.PageItems(GetTopRichest)
.TotalElements(900)
.PageSize(9)
.CurrentPage(page)
.Page((toSend, curPage) =>

View File

@@ -7,7 +7,7 @@ using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Nadeko.Econ.Gambling;
using NadekoBot.Modules.Gambling;
using NadekoBot.Common.TypeReaders;
using Color = SixLabors.ImageSharp.Color;
using Image = SixLabors.ImageSharp.Image;

View File

@@ -1,7 +1,7 @@
#nullable disable
using Nadeko.Econ.Gambling;
using Nadeko.Econ.Gambling.Betdraw;
using Nadeko.Econ.Gambling.Rps;
using NadekoBot.Modules.Gambling;
using NadekoBot.Modules.Gambling.Betdraw;
using NadekoBot.Modules.Gambling.Rps;
using OneOf;
namespace NadekoBot.Modules.Gambling;

View File

@@ -1,7 +1,7 @@
#nullable disable
using Nadeko.Econ.Gambling;
using Nadeko.Econ.Gambling.Betdraw;
using Nadeko.Econ.Gambling.Rps;
using NadekoBot.Modules.Gambling;
using NadekoBot.Modules.Gambling.Betdraw;
using NadekoBot.Modules.Gambling.Rps;
using NadekoBot.Modules.Gambling.Services;
using OneOf;

View File

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

View File

@@ -10,7 +10,7 @@ using JsonSerializer = System.Text.Json.JsonSerializer;
namespace NadekoBot.Modules.Help;
public sealed class Help : NadekoModule<HelpService>
public sealed partial class Help : NadekoModule<HelpService>
{
public const string PATREON_URL = "https://patreon.com/nadekobot";
public const string PAYPAL_URL = "https://paypal.me/Kwoth";
@@ -72,7 +72,7 @@ public sealed class Help : NadekoModule<HelpService>
return;
var topLevelModules = new List<ModuleInfo>();
foreach (var m in _cmds.Modules.GroupBy(x => x.GetTopLevelModule()).Select(x => x.Key))
foreach (var m in _cmds.Modules.GroupBy(x => x.GetTopLevelModule()).OrderBy(x => x.Key.Name).Select(x => x.Key))
{
var result = await _perms.CheckPermsAsync(ctx.Guild,
ctx.Channel,
@@ -80,6 +80,11 @@ public sealed class Help : NadekoModule<HelpService>
m.Name,
null);
#if GLOBAL_NADEKO
if (m.Preconditions.Any(x => x is NoPublicBotAttribute))
continue;
#endif
if (result.IsAllowed)
topLevelModules.Add(m);
}
@@ -87,6 +92,7 @@ public sealed class Help : NadekoModule<HelpService>
await Response()
.Paginated()
.Items(topLevelModules)
.PageSize(12)
.CurrentPage(page)
.AddFooter(false)
.Page((items, _) =>
@@ -99,13 +105,13 @@ public sealed class Help : NadekoModule<HelpService>
return embed;
}
items.OrderBy(module => module.Name)
.ToList()
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
GetModuleDescription(module.Name)
+ "\n"
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
true));
items
.ToList()
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
GetModuleDescription(module.Name)
+ "\n"
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
true));
return embed;
})
@@ -310,7 +316,7 @@ public sealed class Help : NadekoModule<HelpService>
{
string cmdName;
if (cmd.Aliases.Count > 1)
cmdName = Format.Code(prefix +cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
cmdName = Format.Code(prefix + cmd.Aliases[0]) + " | " + Format.Code(prefix + cmd.Aliases[1]);
else
cmdName = Format.Code(prefix + cmd.Aliases.First());
@@ -354,17 +360,16 @@ public sealed class Help : NadekoModule<HelpService>
public async Task H([Leftover] CommandInfo com = null)
{
var channel = ctx.Channel;
if (com is null)
{
var ch = channel is ITextChannel ? await ctx.User.CreateDMChannelAsync() : channel;
try
{
var ch = channel is ITextChannel ? await ctx.User.CreateDMChannelAsync() : channel;
var data = await GetHelpString();
if (data == default)
return;
await Response().Text(data).SendAsync();
await Response().Channel(ch).Text(data).SendAsync();
try
{
await ctx.OkAsync();
@@ -519,7 +524,7 @@ public sealed class Help : NadekoModule<HelpService>
=> smc.RespondConfirmAsync(_sender,
"""
- In case you don't want or cannot Donate to NadekoBot project, but you
- NadekoBot is a free and [open source](https://gitlab.com/nadeko/nadekobot) project which means you can run your own "selfhosted" instance on your computer.
- NadekoBot is a free and [open source](https://gitlab.com/kwoth/nadekobot) project which means you can run your own "selfhosted" instance on your computer.
*Keep in mind that running the bot on your computer means that the bot will be offline when you turn off your computer*

View File

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

View File

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

View File

@@ -269,7 +269,11 @@ public sealed class RepeaterService : IReadyExecutor, INService
var text = SmartText.CreateFrom(repeater.Message);
text = await _repSvc.ReplaceAsync(text, repCtx);
var newMsg = await _sender.Response(channel).Text(text).SendAsync();
var newMsg = await _sender.Response(channel)
.Text(text)
.Sanitize(false)
.SendAsync();
_ = newMsg.AddReactionAsync(new Emoji("🔄"));
if (_noRedundant.Contains(repeater.Id))

View File

@@ -85,6 +85,7 @@ public partial class Utility : NadekoModule
await Response()
.Text(message)
.Channel(channel)
.UserBasedMentions()
.SendAsync();
}

View File

@@ -1194,7 +1194,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
}
//avatar
if (stats.User.AvatarId is not null && template.User.Icon.Show)
if (template.User.Icon.Show)
{
try
{

View File

@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<Version>5.0.0</Version>
<Version>5.0.5</Version>
<!-- Output/build -->
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>

View File

@@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
namespace NadekoBot.Common;
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
[SuppressMessage("Style", "IDE0022:Use expression body for methods")]
public sealed class NoPublicBotAttribute : PreconditionAttribute
{
public override Task<PreconditionResult> CheckPermissionsAsync(

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling.Betdraw;
namespace NadekoBot.Modules.Gambling.Betdraw;
public enum BetdrawColorGuess
{

View File

@@ -1,4 +1,6 @@
namespace Nadeko.Econ.Gambling.Betdraw;
using Nadeko.Econ;
namespace NadekoBot.Modules.Gambling.Betdraw;
public sealed class BetdrawGame
{

View File

@@ -1,4 +1,6 @@
namespace Nadeko.Econ.Gambling.Betdraw;
using Nadeko.Econ;
namespace NadekoBot.Modules.Gambling.Betdraw;
public readonly struct BetdrawResult
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling.Betdraw;
namespace NadekoBot.Modules.Gambling.Betdraw;
public enum BetdrawResultType
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling.Betdraw;
namespace NadekoBot.Modules.Gambling.Betdraw;
public enum BetdrawValueGuess
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public sealed class BetflipGame
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public readonly struct BetflipResult
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public sealed class BetrollGame
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public readonly struct BetrollResult
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling.Rps;
namespace NadekoBot.Modules.Gambling.Rps;
public sealed class RpsGame
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
//here is a payout chart
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public readonly struct SlotResult
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public readonly struct LuLaResult
{

View File

@@ -1,4 +1,4 @@
namespace Nadeko.Econ.Gambling;
namespace NadekoBot.Modules.Gambling;
public sealed class LulaGame
{

View File

@@ -40,7 +40,7 @@ public sealed partial class ReplacementPatternStore
Register("%server.id%", static (IGuild g) => g.Id.ToString());
Register("%server.name%", static (IGuild g) => g.Name);
Register("%server.icon%", static (IGuild g) => g.IconUrl);
Register("%server.members%", static (IGuild g) => g.ApproximateMemberCount?.ToString() ?? "?");
Register("%server.members%", static async (IGuild g) => (g as SocketGuild)?.MemberCount.ToString() ?? "?");
Register("%server.boosters%", static (IGuild g) => g.PremiumSubscriptionCount.ToString());
Register("%server.boost_level%", static (IGuild g) => ((int)g.PremiumTier).ToString());
}

View File

@@ -25,7 +25,7 @@ public partial class ResponseBuilder
public async Task SendAsync(bool ephemeral = false)
{
var lastPage = (_paginationBuilder.TotalElements - 1)
var lastPage = (_paginationBuilder.Elems - 1)
/ _paginationBuilder.ItemsPerPage;
var items = (await _paginationBuilder.ItemsFunc(currentPage)).ToArray();

View File

@@ -357,9 +357,10 @@ public sealed partial class ResponseBuilder
fileName = name;
return this;
}
public PaginatedResponseBuilder Paginated()
=> new(this);
}
public class PaginatedResponseBuilder
@@ -396,7 +397,7 @@ public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilde
public Func<int, Task<SimpleInteractionBase>>? InteractionFunc { get; private set; }
public int TotalElements { get; private set; } = 1;
public int Elems { get; private set; } = 1;
public int ItemsPerPage { get; private set; } = 9;
public bool AddPaginatedFooter { get; private set; } = true;
public bool IsEphemeral { get; private set; }
@@ -411,10 +412,16 @@ public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilde
public SourcedPaginatedResponseBuilder<T> Items(IReadOnlyCollection<T> col)
{
items = col;
TotalElements = col.Count;
Elems = col.Count;
ItemsFunc = (i) => Task.FromResult(items.Skip(i * ItemsPerPage).Take(ItemsPerPage));
return this;
}
public SourcedPaginatedResponseBuilder<T> TotalElements(int i)
{
Elems = i;
return this;
}
public SourcedPaginatedResponseBuilder<T> PageItems(Func<int, Task<IEnumerable<T>>> func)
{

View File

@@ -113,7 +113,7 @@ public static class ServiceCollectionExtensions
typeof(IInputTransformer),
typeof(INService)
];
foreach (var svc in a.GetTypes()
.Where(type => type.IsClass && types.Any(t => type.IsAssignableTo(t)) && !type.HasAttribute<DIIgnoreAttribute>()
#if GLOBAL_NADEKO

View File

@@ -1,4 +1,6 @@
#nullable disable
using NadekoBot.Modules.Permissions;
namespace NadekoBot.Common.TypeReaders;
public sealed class ModuleTypeReader : NadekoTypeReader<ModuleInfo>
@@ -34,7 +36,7 @@ public sealed class ModuleOrExprTypeReader : NadekoTypeReader<ModuleOrExpr>
var module = _cmds.Modules.GroupBy(m => m.GetTopLevelModule())
.FirstOrDefault(m => m.Key.Name.ToUpperInvariant() == input)
?.Key;
if (module is null && input != "ACTUALEXPRESSIONS")
if (module is null && input != "ACTUALEXPRESSIONS" && input != CleverBotResponseStr.CLEVERBOT_RESPONSE)
return new(TypeReaderResult.FromError<ModuleOrExpr>(CommandError.ParseFailed, "No such module found."));
return new(TypeReaderResult.FromSuccess(new ModuleOrExpr

View File

@@ -10,7 +10,12 @@ public static class UserExtensions
// This method is only used for the xp card
public static Uri? RealAvatarUrl(this DiscordUser usr)
=> Uri.TryCreate(CDN.GetDefaultUserAvatarUrl(usr.UserId), UriKind.Absolute, out var uri)
{
if (!string.IsNullOrWhiteSpace(usr.AvatarId))
return new Uri(CDN.GetUserAvatarUrl(usr.UserId, usr.AvatarId, 128, ImageFormat.Png));
return Uri.TryCreate(CDN.GetDefaultUserAvatarUrl(usr.UserId), UriKind.Absolute, out var uri)
? uri
: null;
}
}