mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
Compare commits
162 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
81711c557a | ||
|
57895ac751 | ||
|
73cceb3aa6 | ||
|
08e7784fbd | ||
|
0174862106 | ||
|
3803ecd35d | ||
|
6ad0f13096 | ||
|
e070ca3b87 | ||
|
6caea8e9e7 | ||
|
d30fa44f3c | ||
|
b1e554d09f | ||
|
4e559d2606 | ||
|
4f0692db59 | ||
|
bbc277f4b9 | ||
|
b3a847e395 | ||
|
8f0b44252d | ||
|
577d62a1c1 | ||
|
3e71d9f1ba | ||
|
03c5124122 | ||
|
8e589660ac | ||
|
64ef775bee | ||
|
6a7ab79446 | ||
|
ea0b51d474 | ||
|
7637de8fed | ||
|
6327e242ca | ||
|
96ad5516d3 | ||
|
7d916a5513 | ||
|
4fc0cded15 | ||
|
48e51784da | ||
|
3ef05f8aa7 | ||
|
fc4858830c | ||
|
a25adefc65 | ||
|
daa2177559 | ||
|
d28c7b500d | ||
|
4bab94b329 | ||
|
e963ffeaab | ||
|
ddeded9a70 | ||
|
4a378b9663 | ||
|
812b865add | ||
|
e0819f760c | ||
|
6c9c8bf63e | ||
|
bca845d76a | ||
|
6c305860bc | ||
|
863929bb0f | ||
|
eee4e64d80 | ||
|
236a8aa9ac | ||
|
eca4a14cb6 | ||
|
6bc8e4b7d2 | ||
|
b34f383649 | ||
|
006fa1a9fe | ||
|
a04a427af2 | ||
|
e1d027eaf5 | ||
|
49563ea6d4 | ||
|
59b9742c19 | ||
|
f491e3d37d | ||
|
1f11e4f227 | ||
|
08d8da25cd | ||
|
74690c73d6 | ||
|
1aebca14e1 | ||
|
5060d606cf | ||
|
23b3ad5837 | ||
|
7297318538 | ||
|
c9fb0a8b03 | ||
|
18619b4d3a | ||
|
ef06388335 | ||
|
cc060da1a7 | ||
|
d1db54498b | ||
|
eef5b3f948 | ||
|
1c41fbfce2 | ||
|
d86b5b2b6c | ||
|
2d3ff83c7c | ||
|
043ad98473 | ||
|
127a46a9b8 | ||
|
a7e1e8a982 | ||
|
b0ac35b82e | ||
|
367135be6a | ||
|
f69f8548b0 | ||
|
45b654eab1 | ||
|
449dbafff7 | ||
|
afba004d85 | ||
|
d71021eb11 | ||
|
ef4d38bc87 | ||
|
96851c7c2d | ||
|
41ae182373 | ||
|
9bf5a5a3cd | ||
|
bab23c25a5 | ||
|
0ba8555f56 | ||
|
340c5b2268 | ||
|
77e8c66b73 | ||
|
9d9f8f7f98 | ||
|
bc77783820 | ||
|
a28be0d343 | ||
|
94c08b0b9e | ||
|
77358a563d | ||
|
82a48b101b | ||
|
6ebe321de9 | ||
|
f67a2e9922 | ||
|
b4fec10ee6 | ||
|
42b9a01550 | ||
|
5f94b20015 | ||
|
9d4d94cbc1 | ||
|
f35b1a9219 | ||
|
9332c8a24c | ||
|
201aa45c6b | ||
|
97ae7b5a5b | ||
|
59544a107c | ||
|
e158ba5b35 | ||
|
f4b9c1c0e6 | ||
|
cdf9adc8a4 | ||
|
9b09f223d9 | ||
|
2caf406254 | ||
|
3c3d082112 | ||
|
2d548b55de | ||
|
dfbe1721f3 | ||
|
17ef3caefd | ||
|
f4b21a9445 | ||
|
2d3399b7e6 | ||
|
22e8b62df2 | ||
|
8f62a46016 | ||
|
842a8a2f71 | ||
|
be1d14d095 | ||
|
ce5e04b398 | ||
|
775487ad47 | ||
|
41e4936f52 | ||
|
d831a116d9 | ||
|
8f43b44677 | ||
|
93df4f3bf3 | ||
|
073b832065 | ||
|
a01e580e03 | ||
|
6124e2fab5 | ||
|
4dd31d6a0b | ||
|
e8706d4006 | ||
|
b34cd534c3 | ||
|
ec2b7b3ad6 | ||
|
4bc3147697 | ||
|
2c63b1cce7 | ||
|
069f8fab9d | ||
|
1f1b01995e | ||
|
140cc43c98 | ||
|
26b7149435 | ||
|
b354ee7269 | ||
|
b829ca0109 | ||
|
308ba36b2e | ||
|
01f70f0a24 | ||
|
09171fb10a | ||
|
db2328cdaf | ||
|
7a60868632 | ||
|
0af8048938 | ||
|
1ad0bc33af | ||
|
8c8e9f7770 | ||
|
e91646594f | ||
|
ff066b6473 | ||
|
2353488c70 | ||
|
3ab4460597 | ||
|
1efda23c3d | ||
|
307003e6fe | ||
|
6827c195ad | ||
|
affaaf2fab | ||
|
f0ac087fdb | ||
|
63a9ae2dac | ||
|
0fe4f14d96 | ||
|
30d7ff958b |
@@ -3,19 +3,9 @@
|
||||
|
||||
# Don't ignore nugetconfig
|
||||
!./NuGet.Config
|
||||
|
||||
# Don't ignore src projects
|
||||
!src/Nadeko.Econ/**
|
||||
!src/Nadeko.Common/**
|
||||
# Use Nadeko.Medusa project
|
||||
!src/Nadeko.Medusa/**
|
||||
# Use NadekoBot project
|
||||
!src/NadekoBot/**
|
||||
# Use NadekoBot.Coordinator project
|
||||
!src/NadekoBot.Coordinator/**
|
||||
# Use Generators project
|
||||
!src/NadekoBot.Generators/**
|
||||
# Use Ayu stuff
|
||||
!src/ayu/**
|
||||
!src/**
|
||||
!docker-entrypoint.sh
|
||||
|
||||
# ignore bin and obj folders in projects
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,8 +3,7 @@
|
||||
src/NadekoBot/data/last_known_version.txt
|
||||
|
||||
# medusa stuff
|
||||
!src/NadekoBot/data/medusae/medusa.yml
|
||||
src/NadekoBot/data/medusae/**
|
||||
src/NadekoBot/data/medusae/
|
||||
|
||||
# other
|
||||
|
||||
|
@@ -1,12 +1,11 @@
|
||||
image: mcr.microsoft.com/dotnet/sdk:6.0
|
||||
image: mcr.microsoft.com/dotnet/sdk:8.0
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- build-installer
|
||||
- upload-builds
|
||||
- release
|
||||
- publish-windows
|
||||
- upload-windows-updater-release
|
||||
- publish-medusa-package
|
||||
|
||||
variables:
|
||||
@@ -14,8 +13,16 @@ variables:
|
||||
tests: "NadekoBot.Tests"
|
||||
LINUX_X64_OUTPUT_DIR: "nadekobot-linux-x64"
|
||||
LINUX_X64_RELEASE: "$CI_COMMIT_TAG-linux-x64-build.tar"
|
||||
LINUX_ARM64_OUTPUT_DIR: "nadekobot-linux-arm64"
|
||||
LINUX_ARM64_RELEASE: "$CI_COMMIT_TAG-linux-arm64-build.tar"
|
||||
MACOS_X64_OUTPUT_DIR: "nadekobot-osx-x64"
|
||||
MACOS_X64_RELEASE: "$CI_COMMIT_TAG-osx-x64-build.tar"
|
||||
MACOS_ARM64_OUTPUT_DIR: "nadekobot-osx-arm64"
|
||||
MACOS_ARM64_RELEASE: "$CI_COMMIT_TAG-osx-arm64-build.tar"
|
||||
WIN_X64_OUTPUT_DIR: "nadekobot-windows-x64"
|
||||
WIN_X64_RELEASE: "$CI_COMMIT_TAG-windows-x64-build.zip"
|
||||
WIN_ARM64_OUTPUT_DIR: "nadekobot-windows-arm64"
|
||||
WIN_ARM64_RELEASE: "$CI_COMMIT_TAG-windows-arm64-build.zip"
|
||||
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/NadekoBot-build/${CI_COMMIT_TAG}"
|
||||
INSTALLER_OUTPUT_DIR: "nadeko-installers/${CI_COMMIT_TAG}"
|
||||
INSTALLER_FILE_NAME: "nadeko-setup-${CI_COMMIT_TAG}.exe"
|
||||
@@ -23,12 +30,20 @@ variables:
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- "dotnet publish -c Release -r linux-x64 --self-contained -o $LINUX_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
|
||||
- "dotnet publish -c Release -r win7-x64 --self-contained -o $WIN_X64_OUTPUT_DIR src/NadekoBot/NadekoBot.csproj"
|
||||
- "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"
|
||||
artifacts:
|
||||
paths:
|
||||
- "$LINUX_X64_OUTPUT_DIR/"
|
||||
- "$LINUX_ARM64_OUTPUT_DIR/"
|
||||
- "$WIN_X64_OUTPUT_DIR/"
|
||||
- "$WIN_ARM64_OUTPUT_DIR/"
|
||||
- "$MACOS_X64_OUTPUT_DIR/"
|
||||
- "$MACOS_ARM64_OUTPUT_DIR/"
|
||||
|
||||
upload-builds:
|
||||
stage: upload-builds
|
||||
@@ -38,11 +53,26 @@ upload-builds:
|
||||
script:
|
||||
- apk add --no-cache curl tar zip
|
||||
- "tar cvf $LINUX_X64_RELEASE $LINUX_X64_OUTPUT_DIR/*"
|
||||
- "tar cvf $LINUX_ARM64_RELEASE $LINUX_ARM64_OUTPUT_DIR/*"
|
||||
- "tar cvf $MACOS_X64_RELEASE $MACOS_X64_OUTPUT_DIR/*"
|
||||
- "tar cvf $MACOS_ARM64_RELEASE $MACOS_ARM64_OUTPUT_DIR/*"
|
||||
- "zip -r $WIN_X64_RELEASE $WIN_X64_OUTPUT_DIR/*"
|
||||
- "zip -r $WIN_ARM64_RELEASE $WIN_ARM64_OUTPUT_DIR/*"
|
||||
- "mv $INSTALLER_OUTPUT_DIR/$INSTALLER_FILE_NAME $INSTALLER_FILE_NAME"
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $LINUX_X64_RELEASE $PACKAGE_REGISTRY_URL/$LINUX_X64_RELEASE
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $LINUX_ARM64_RELEASE $PACKAGE_REGISTRY_URL/$LINUX_ARM64_RELEASE
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $WIN_X64_RELEASE $PACKAGE_REGISTRY_URL/$WIN_X64_RELEASE
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $WIN_ARM64_RELEASE $PACKAGE_REGISTRY_URL/$WIN_ARM64_RELEASE
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $MACOS_X64_RELEASE $PACKAGE_REGISTRY_URL/$MACOS_X64_RELEASE
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $MACOS_ARM64_RELEASE $PACKAGE_REGISTRY_URL/$MACOS_ARM64_RELEASE
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $INSTALLER_FILE_NAME $PACKAGE_REGISTRY_URL/$INSTALLER_FILE_NAME
|
||||
|
||||
release:
|
||||
stage: release
|
||||
@@ -51,9 +81,14 @@ release:
|
||||
- if: $CI_COMMIT_TAG
|
||||
script:
|
||||
- |
|
||||
release-cli create --name "NadekoBot v$CI_COMMIT_TAG" --description "## [Changelog](https://gitlab.com/Kwoth/nadekobot/-/blob/v4/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/nadeko/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\":\"${WIN_X64_RELEASE}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${WIN_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}\"}" \
|
||||
--assets-link "{\"name\":\"${WIN_ARM64_RELEASE}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${WIN_ARM64_RELEASE}\"}" \
|
||||
--assets-link "{\"name\":\"${MACOS_X64_RELEASE}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${MACOS_X64_RELEASE}\"}" \
|
||||
--assets-link "{\"name\":\"${MACOS_ARM64_RELEASE}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${MACOS_ARM64_RELEASE}\"}" \
|
||||
--assets-link "{\"name\":\"${INSTALLER_FILE_NAME}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${INSTALLER_FILE_NAME}\"}"
|
||||
|
||||
test:
|
||||
stage: test
|
||||
@@ -63,14 +98,14 @@ test:
|
||||
- "cd $tests_path"
|
||||
- "dotnet test"
|
||||
|
||||
publish-windows:
|
||||
stage: publish-windows
|
||||
build-installer:
|
||||
stage: build-installer
|
||||
rules:
|
||||
- if: "$CI_COMMIT_TAG"
|
||||
image: scottyhardy/docker-wine
|
||||
before_script:
|
||||
- choco install dotnet-6.0-runtime --version=6.0.4 -y
|
||||
- choco install dotnet-6.0-sdk --version=6.0.202 -y
|
||||
- choco install dotnet-runtime --version=8.0.4 -y
|
||||
- choco install dotnet-sdk --version=8.0.204 -y
|
||||
- choco install innosetup -y
|
||||
artifacts:
|
||||
paths:
|
||||
@@ -78,33 +113,20 @@ publish-windows:
|
||||
script:
|
||||
- dotnet clean
|
||||
- dotnet restore -f --no-cache -v n
|
||||
- dotnet publish -c Release --runtime win7-x64 /p:Version=$CI_COMMIT_TAG src/NadekoBot
|
||||
- dotnet publish -c Release --runtime win-x64 /p:Version=$CI_COMMIT_TAG src/NadekoBot
|
||||
- $env:NADEKOBOT_INSTALL_VERSION = $CI_COMMIT_TAG
|
||||
- iscc.exe "/O+" ".\exe_builder.iss"
|
||||
tags:
|
||||
- windows
|
||||
|
||||
upload-windows-updater-release:
|
||||
stage: upload-windows-updater-release
|
||||
rules:
|
||||
- if: "$CI_COMMIT_TAG"
|
||||
image:
|
||||
name: amazon/aws-cli
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- sed -i "s/_INSTALLER_FILE_NAME_/$INSTALLER_FILE_NAME/g" releases-v3.json
|
||||
- sed -i "s/_VERSION_/$CI_COMMIT_TAG/g" releases-v3.json
|
||||
- aws --version
|
||||
- aws --endpoint-url $AWS_SERVICE_URL s3api put-object --bucket "$AWS_BUCKET_NAME" --key "dl/bot/$INSTALLER_FILE_NAME" --acl public-read --body "$INSTALLER_OUTPUT_DIR/$INSTALLER_FILE_NAME"
|
||||
- aws --endpoint-url $AWS_SERVICE_URL s3api put-object --bucket "$AWS_BUCKET_NAME" --key "dl/bot/releases-v3.json" --acl public-read --body "releases-v3.json"
|
||||
- saas-windows-medium-amd64
|
||||
|
||||
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"
|
||||
|
19
.readthedocs.yaml
Normal file
19
.readthedocs.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
# Read the Docs configuration file for MkDocs projects
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.12"
|
||||
|
||||
mkdocs:
|
||||
configuration: mkdocs.yml
|
||||
|
||||
# Optionally declare the Python requirements required to build your docs
|
||||
python:
|
||||
install:
|
||||
- requirements: mkdocs-requirements.txt
|
151
CHANGELOG.md
151
CHANGELOG.md
@@ -1,6 +1,155 @@
|
||||
# Changelog
|
||||
|
||||
Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o
|
||||
Mostly based on [keepachangelog](https://keepachangelog.com/en/1.0.0/) except date format. a-c-f-r-o
|
||||
|
||||
## [5.0.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Added `.shopadd command` You can now sell commands in the shop. The command will execute as if you were the one running it when someone buys it
|
||||
- type `.h .shopadd` for more info
|
||||
- Added `.stickyroles` Users leaving the server will have their roles saved to the database and reapplied if they rejoin within 30 days.
|
||||
- Giveaway commands
|
||||
- `.ga start <duration> <text>` starts the giveway with the specified duration and message (prize). You may have up to 5 giveaways on the server at once
|
||||
- `.ga end <id>` prematurely ends the giveaway and selects a winner
|
||||
- `.ga cancel <id>` cancels the giveaway and doesn't select a winner
|
||||
- `.ga list` lists active giveaways on the current server
|
||||
- `.ga reroll <id>` rerolls the winner on the completed giveaway. This only works for 24 hours after the giveaway has ended, or until the bot restarts.
|
||||
- Users can join the giveaway by adding a :tada: reaction
|
||||
- Added Todo Commands
|
||||
- `.todo add <name>` - adds a new todo
|
||||
- `.todo delete <id>` - deletes a todo item
|
||||
- `.todo done <id>` - completes a todo (marks it with a checkmark)
|
||||
- `.todo list` - lists all todos
|
||||
- `.todo edit <id> <new message>` - edits a todo item message
|
||||
- `.todo show <id>` - Shows the text of the specified todo item
|
||||
- In addition to that, there are also Todo archive commands
|
||||
- `.todo archive add <name>` - adds all current todos (completed and not completed) to the archived list, your current todo list will become cleared
|
||||
- `.todo archive list` - lists all your archived todo lists
|
||||
- `.todo archive show <id>` - shows the todo items from one of your archived lists
|
||||
- `.todo archive delete <id>` - deletes and archived todo list
|
||||
- Added `.queufairplay` / `.qfp` (music feature) re-added but it works differently
|
||||
- Once you run it, it will reorganize currently queued songs so that they're in a fair order.
|
||||
- Added `.clubrename` command to uh rename your club
|
||||
- For self-hosters:
|
||||
- Added `.sqlselectcsv` which will return results in a csv file instead of an embed.
|
||||
- You can set whether nadeko ignores other bots in `bot.yml`
|
||||
- You can set shop sale cut in `gambling.yml`
|
||||
- Added a page parameter to `.feedlist`
|
||||
- Added seconds/sec/s to `.convert` command
|
||||
- Added `.prunecancel` to cancel an active prune
|
||||
- Added progress reporting when using `.prune`.
|
||||
- Added audit log reason for `.setrole` and some other features
|
||||
|
||||
### Changed
|
||||
|
||||
- Users who have manage messages perm in the channel will now be excluded from link and invite filtering (`.sfi` and `.sfl`)
|
||||
- `.send` command should work consistently and correctly now. You can have targets from other shards too. The usage has been changed. refer to `.h .send` for more info
|
||||
- `.serverinfo` no longer takes a server name. It only takes an id or no arguments
|
||||
- You can now target a different channel with .repeat
|
||||
- `.cmds <module name>`, `.cmds <group name` and `.mdls` looks better
|
||||
- The bot will now send a discord Reply to every command
|
||||
- `.queuesearch` / `.qs` will now show the results with respective video thumbnails
|
||||
- A lot of code cleanup (still a lot to be done) and Quality of Life improvements
|
||||
- `.inrole` will now show mentions primarily, and use a spoiler to show usernames
|
||||
|
||||
### Fixed
|
||||
|
||||
- `.feed` should now correctly accept (and show) the message which can be passed as the third parameter
|
||||
- `.say` will now correctly report errors if the user or the bot don't have sufficent perms to send a message in the targeted channel
|
||||
- Fixed `.invitelist` not paginating correctly
|
||||
- `.serverinfo` will now correctly work for other shards
|
||||
- `.send` will now correctly work for other shards
|
||||
- `.translate` command will no longer fail if the user capitalizes the language name
|
||||
- Fixed xp card user avatar not showing for some users
|
||||
|
||||
### Removed
|
||||
|
||||
- `.poll` commands removed as discord added polls
|
||||
- `.scpl` and other music soundcloud commands have been removed as soundcloud isn't issuing new api tokens for years now
|
||||
- Removed a lot of useless and nsfw commands
|
||||
- Removed log voice presence TTS
|
||||
- Cleanup: Removed a lot of obsolete aliases from aliases.yml
|
||||
|
||||
## [4.3.22] - 23.04.2023
|
||||
|
||||
### Added
|
||||
- Added `.setbanner` command (thx cata)
|
||||
|
||||
### Fixed
|
||||
- Fixed pagination error due to a missing emoji
|
||||
|
||||
|
||||
## [4.3.21] - 19.04.2023
|
||||
|
||||
### Fixed
|
||||
- Possible fix for a duplicate in `.h bank`
|
||||
- Fixed `.stock` command
|
||||
- Fixed `.clubapply` and `.clubaccept`
|
||||
- Removed some redundant discriminators
|
||||
|
||||
## [4.3.20] - 20.01.2024
|
||||
|
||||
### Fixed
|
||||
- Fixed `.config searches followedStreams.maxCount` not working
|
||||
|
||||
## [4.3.19] - 20.01.2024
|
||||
|
||||
### Added
|
||||
- Added `followedStreams.maxCount` to `searches.yml` which lets bot owners change the default of 10 per server
|
||||
|
||||
### Changed
|
||||
- Improvements to GPT ChatterBot (thx alexandra)
|
||||
- Add a personality prompt to tweak the way chatgpt bot behaves
|
||||
- Added Chat history support to chatgpt ChatterBot
|
||||
- Chatgpt token usage now correctly calculated
|
||||
- More chatgpt configs in `games.yml`
|
||||
|
||||
## [4.3.18] - 26.12.2023
|
||||
|
||||
### Added
|
||||
|
||||
- Added `.cacheusers` command (thx Kotz)
|
||||
- Added `.clubreject` which lets you reject club applications
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated discord lib, there should be less console errors now
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `icon_url` when using `.showembed`
|
||||
- Fixed `.quoteshow` not showing sometimes (thx Cata)
|
||||
- Notifications will no longer be sent if dms are off when using `.give`
|
||||
- Users should no longer be able to apply to clubs while in a club already (especially not to the same club they're already in)
|
||||
|
||||
### Removed
|
||||
|
||||
- `.revimg` and `.revav` as google removed reverse image search
|
||||
|
||||
## [4.3.17] - 06.09.2023
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix to waifu gifts being character limited
|
||||
- Fixes UserUpdated and UserPresence not correctly ignoring users that are logignored
|
||||
- Added Trim() to activity names since apparently some activities have trailing spaces.
|
||||
|
||||
## [4.3.16] - 24.05.2023
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed missing events from `.logevents`
|
||||
- Fixed `.log` thread deleted and thread created events not working properly
|
||||
|
||||
## [4.3.15] - 21.05.2023
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed -w 0 in trivia
|
||||
- Fixed `.rps` amount field in the response
|
||||
- Fixed `.showembed` output
|
||||
- Fixed bank award's incorrect output message
|
||||
|
||||
## [4.3.14] - 02.04.2023
|
||||
|
||||
|
17
Dockerfile
17
Dockerfile
@@ -1,13 +1,11 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||
WORKDIR /source
|
||||
|
||||
COPY src/Nadeko.Medusa/*.csproj src/Nadeko.Medusa/
|
||||
COPY src/Nadeko.Econ/*.csproj src/Nadeko.Econ/
|
||||
COPY src/Nadeko.Common/*.csproj src/Nadeko.Common/
|
||||
COPY src/NadekoBot/*.csproj src/NadekoBot/
|
||||
COPY src/NadekoBot.Coordinator/*.csproj src/NadekoBot.Coordinator/
|
||||
COPY src/NadekoBot.Generators/*.csproj src/NadekoBot.Generators/
|
||||
COPY src/ayu/Ayu.Discord.Voice/*.csproj src/ayu/Ayu.Discord.Voice/
|
||||
COPY src/NadekoBot.Voice/*.csproj src/NadekoBot.Voice/
|
||||
COPY NuGet.Config ./
|
||||
RUN dotnet restore src/NadekoBot/
|
||||
|
||||
@@ -22,18 +20,17 @@ RUN set -xe; \
|
||||
chmod +x /app/NadekoBot
|
||||
|
||||
# final stage/image
|
||||
FROM mcr.microsoft.com/dotnet/runtime:6.0
|
||||
FROM mcr.microsoft.com/dotnet/runtime:8.0
|
||||
WORKDIR /app
|
||||
|
||||
RUN set -xe; \
|
||||
useradd -m nadeko; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends libopus0 libsodium23 libsqlite3-0 curl ffmpeg python3 python3-pip sudo; \
|
||||
update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1; \
|
||||
apt-get install -y --no-install-recommends libopus0 libsodium23 libsqlite3-0 curl ffmpeg python3 sudo; \
|
||||
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; \
|
||||
pip3 install --no-cache-dir --upgrade youtube-dl; \
|
||||
apt-get purge -y python3-pip; \
|
||||
chmod +x /usr/local/bin/youtube-dl; \
|
||||
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; \
|
||||
apt-get autoremove -y; \
|
||||
apt-get autoclean -y
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Copyright 2021 Kwoth
|
||||
Copyright 2023 Kwoth
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
@@ -13,27 +13,23 @@ ProjectSection(SolutionItems) = preProject
|
||||
.gitlab-ci.yml = .gitlab-ci.yml
|
||||
Dockerfile = Dockerfile
|
||||
NuGet.Config = NuGet.Config
|
||||
migrate.ps1 = migrate.ps1
|
||||
remove-migration.ps1 = remove-migration.ps1
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NadekoBot", "src\NadekoBot\NadekoBot.csproj", "{45EC1473-C678-4857-A544-07DFE0D0B478}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ayu", "ayu", "{6058FEDF-A318-4CD4-8F04-A7E8E7EC8874}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ayu.Discord.Voice", "src\ayu\Ayu.Discord.Voice\Ayu.Discord.Voice.csproj", "{2F4CF6D6-0C2F-4944-B204-9508CDA53195}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot.Voice", "src\NadekoBot.Voice\NadekoBot.Voice.csproj", "{2F4CF6D6-0C2F-4944-B204-9508CDA53195}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot.Tests", "src\NadekoBot.Tests\NadekoBot.Tests.csproj", "{DB448DD4-C97F-40E9-8BD3-F605FF1FF833}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot.Coordinator", "src\NadekoBot.Coordinator\NadekoBot.Coordinator.csproj", "{AE9B7F8C-81D7-4401-83A3-643B38258374}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot.Generators", "src\NadekoBot.Generators\NadekoBot.Generators.csproj", "{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot.VotesApi", "src\NadekoBot.VotesApi\NadekoBot.VotesApi.csproj", "{3BC82CFE-BEE7-451F-986B-17EDD1570C4F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nadeko.Medusa", "src\Nadeko.Medusa\Nadeko.Medusa.csproj", "{E685977E-31A4-46F4-A5D7-4E3E39E82E43}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nadeko.Common", "src\Nadeko.Common\Nadeko.Common.csproj", "{A6022F5F-A764-4D3F-847B-36F0391FF659}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nadeko.Econ", "src\Nadeko.Econ\Nadeko.Econ.csproj", "{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot.Generators", "src\NadekoBot.Generators\NadekoBot.Generators.csproj", "{92770AF3-83EE-49F1-A0BB-79124D19A13D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -66,12 +62,6 @@ Global
|
||||
{AE9B7F8C-81D7-4401-83A3-643B38258374}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AE9B7F8C-81D7-4401-83A3-643B38258374}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AE9B7F8C-81D7-4401-83A3-643B38258374}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3BC82CFE-BEE7-451F-986B-17EDD1570C4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3BC82CFE-BEE7-451F-986B-17EDD1570C4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3BC82CFE-BEE7-451F-986B-17EDD1570C4F}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
@@ -84,33 +74,24 @@ Global
|
||||
{E685977E-31A4-46F4-A5D7-4E3E39E82E43}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E685977E-31A4-46F4-A5D7-4E3E39E82E43}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E685977E-31A4-46F4-A5D7-4E3E39E82E43}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A6022F5F-A764-4D3F-847B-36F0391FF659}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6022F5F-A764-4D3F-847B-36F0391FF659}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6022F5F-A764-4D3F-847B-36F0391FF659}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6022F5F-A764-4D3F-847B-36F0391FF659}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6022F5F-A764-4D3F-847B-36F0391FF659}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6022F5F-A764-4D3F-847B-36F0391FF659}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{92770AF3-83EE-49F1-A0BB-79124D19A13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{92770AF3-83EE-49F1-A0BB-79124D19A13D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{92770AF3-83EE-49F1-A0BB-79124D19A13D}.GlobalNadeko|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{92770AF3-83EE-49F1-A0BB-79124D19A13D}.GlobalNadeko|Any CPU.Build.0 = Debug|Any CPU
|
||||
{92770AF3-83EE-49F1-A0BB-79124D19A13D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{92770AF3-83EE-49F1-A0BB-79124D19A13D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{45EC1473-C678-4857-A544-07DFE0D0B478} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{6058FEDF-A318-4CD4-8F04-A7E8E7EC8874} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{2F4CF6D6-0C2F-4944-B204-9508CDA53195} = {6058FEDF-A318-4CD4-8F04-A7E8E7EC8874}
|
||||
{DB448DD4-C97F-40E9-8BD3-F605FF1FF833} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{AE9B7F8C-81D7-4401-83A3-643B38258374} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{3BC3BDF8-1A0B-45EB-AB2B-C0891D4D37B8} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{3BC82CFE-BEE7-451F-986B-17EDD1570C4F} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{E685977E-31A4-46F4-A5D7-4E3E39E82E43} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{A6022F5F-A764-4D3F-847B-36F0391FF659} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{4F4FBF7C-74F0-4AE4-B451-9E60BDCA9C37} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{92770AF3-83EE-49F1-A0BB-79124D19A13D} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
{2F4CF6D6-0C2F-4944-B204-9508CDA53195} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5F3F555C-855F-4BE8-B526-D062D3E8ACA4}
|
||||
|
@@ -5,5 +5,5 @@
|
||||
[](https://nadeko.bot/commands)
|
||||
|
||||
### Useful links
|
||||
- [Self hosting Guides and Docs](https://nadekobot.readthedocs.io/en/v4)
|
||||
- [Self hosting Guides and Docs](https://nadekobot.readthedocs.io/en/latest)
|
||||
- [Discord support server](https://discord.nadeko.bot)
|
||||
|
23
docker-compose.yml
Normal file
23
docker-compose.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
nadeko:
|
||||
image: insert-image-name-here:latest
|
||||
depends_on:
|
||||
- redis
|
||||
environment:
|
||||
TZ: Europe/Paris
|
||||
NadekoBot_RedisOptions: redis,name=nadeko
|
||||
#NadekoBot_ShardRunCommand: dotnet
|
||||
#NadekoBot_ShardRunArguments: /app/NadekoBot.dll {0} {1}
|
||||
volumes:
|
||||
- /srv/nadeko/conf:/app/conf:ro
|
||||
- /srv/nadeko/data:/app/data
|
||||
|
||||
redis:
|
||||
image: redis:4-alpine
|
||||
sysctls:
|
||||
- net.core.somaxconn=511
|
||||
command: redis-server --maxmemory 32M --maxmemory-policy volatile-lru
|
||||
volumes:
|
||||
- /srv/nadeko/redis-data:/data
|
@@ -1,6 +1,6 @@
|
||||
# How to contribute
|
||||
|
||||
1. Make Merge Requests to the [**v4 branch**](https://gitlab.com/Kwoth/nadekobot/tree/v4)
|
||||
1. Make Merge Requests to the [**v5 branch**](https://gitlab.com/nadeko/nadekobot/tree/v5)
|
||||
2. Keep a single Merge Request to a single feature
|
||||
3. Fill out the MR template
|
||||
|
||||
|
@@ -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/Kwoth/nadekobot
|
||||
[gitlab]: https://gitlab.com/nadeko/nadekobot
|
||||
[discord-server]: https://discord.nadeko.bot/
|
||||
[patreon]: https://www.patreon.com/nadekobot
|
||||
[patreon-button]: ./assets/patreon.png
|
||||
|
@@ -14,7 +14,7 @@
|
||||
version: "3.7"
|
||||
services:
|
||||
nadeko:
|
||||
image: registry.gitlab.com/kwoth/nadekobot:latest
|
||||
image: registry.gitlab.com/nadeko/nadekobot:latest
|
||||
depends_on:
|
||||
- redis
|
||||
environment:
|
||||
|
@@ -1,4 +1,4 @@
|
||||
w# Setting up NadekoBot on Linux
|
||||
# Setting up NadekoBot on Linux
|
||||
|
||||
| Table of Contents |
|
||||
| :-------------------------------------------------- |
|
||||
@@ -13,27 +13,22 @@ w# Setting up NadekoBot on Linux
|
||||
|
||||
#### Operating System Compatibility
|
||||
|
||||
It is recommended that you use **Ubuntu 20.04**, as there have been nearly no problems with it. Also, **32-bit systems are incompatible**.
|
||||
|
||||
|
||||
### Ubuntu 22.04 is ruled as incompatible so double check which ubuntu version you are using.
|
||||
|
||||
##### Compatible operating systems:
|
||||
|
||||
- Ubuntu: 16.04, 18.04, 20.04
|
||||
- Mint: 19, 20
|
||||
- Ubuntu: 18.04, 20.04, 22.04, 22.10
|
||||
- Mint: 19, 20, 21
|
||||
- Debian: 10, 11
|
||||
- CentOS: 7
|
||||
- openSUSE
|
||||
- Fedora: 33, 34, 35
|
||||
- openSUSE 15
|
||||
- ~~Fedora: 33, 34, 35~~ (Fedora is Pending Support)
|
||||
|
||||
## Linux From Source
|
||||
|
||||
##### Migration from v3 -> v4
|
||||
##### Migration from v3 -> v5
|
||||
|
||||
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/v4/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`)
|
||||
@@ -43,7 +38,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/v4/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)
|
||||
@@ -55,13 +50,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/v4/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/v4/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. 🎉
|
||||
@@ -79,11 +74,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/v4/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/Kwoth/nadekobot/-/releases>
|
||||
1. Download the latest release from <https://gitlab.com/nadeko/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!
|
||||
@@ -107,7 +102,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/Kwoth/nadekobot/-/releases>
|
||||
2. Download the latest release from <https://gitlab.com/nadeko/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!
|
||||
@@ -180,8 +175,8 @@ Choose:
|
||||
[1] to Run NadekoBot with Auto Restart on "die" command without updating.
|
||||
[2] to Run with Auto Updating on restart after using "die" command.
|
||||
```
|
||||
- Run `1` to update the bot upon restart. (This is done using the `.die` command)
|
||||
- Run `2` to restart the bot without updating. (This is also done using the `.die` command)
|
||||
- Run `1` to restart the bot without updating. (This is done using the `.die` command)
|
||||
- Run `2` to update the bot upon restart. (This is also done using the `.die` command)
|
||||
|
||||
5. That's it! to detatch the tmux session:
|
||||
- Press `Ctrl` + `B`
|
||||
|
@@ -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/v4/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/v4/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/Kwoth/nadekobot/-/releases>
|
||||
1. Download the latest release from <https://gitlab.com/nadeko/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/Kwoth/nadekobot/-/releases>
|
||||
2. Download the latest release from <https://gitlab.com/nadeko/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!
|
||||
|
@@ -10,11 +10,9 @@
|
||||
|
||||
*Note: If you want to make changes to Nadeko's source code, please follow the [From Source](#windows-from-source) guide instead.*
|
||||
|
||||
*If you have Windows 7 or a 32-bit system, please refer to the [From Source](#windows-from-source)) guide.*
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- Windows 8 or later (64-bit)
|
||||
- Windows 10 or later (64-bit)
|
||||
- [Create a Discord Bot application and invite the bot to your server](../creds-guide.md)
|
||||
|
||||
**Optional**
|
||||
@@ -31,10 +29,8 @@
|
||||

|
||||
- Click on **`DOWNLOAD`** at the lower right
|
||||

|
||||
- Click on **`Install`** next to **`Redis`**.
|
||||
- **(Note: Redis is optional unless you are are using the bot on 2000+ servers)**
|
||||
- Note: If Redis fails to install, install Redis manually here: [Redis Installer](https://github.com/MicrosoftArchive/redis/releases/tag/win-3.0.504) Download and run the **`.msi`** file.
|
||||
- If you will use the music module, click on **`Install`** next to **`FFMPEG`** and **`Youtube-DL`**.
|
||||
- **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 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.
|
||||
@@ -60,9 +56,9 @@
|
||||
|
||||
You can still install them manually:
|
||||
|
||||
- [Redis Installer](https://github.com/MicrosoftArchive/redis/releases/tag/win-3.0.504) - Download and run the **`.msi`** file
|
||||
- [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-dl] - Click to download the file. Then put `youtube-dl.exe` in a path that's in your PATH environment variable. If you don't know what that is, then just move the `youtube-dl.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 ⚠**
|
||||
|
||||
@@ -71,15 +67,15 @@ You can still install them manually:
|
||||
##### Prerequisites
|
||||
|
||||
**Install these before proceeding or your bot will not work!**
|
||||
- [.net 6](https://dotnet.microsoft.com/download/dotnet/6.0) - needed to compile and run the bot
|
||||
- [.net 7](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](https://github.com/MicrosoftArchive/redis/releases/download/win-3.0.504/Redis-x64-3.0.504.msi) - to cache things needed by some features and persist through restarts
|
||||
- [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 v4 --depth 1`
|
||||
1. `git clone https://gitlab.com/nadeko/nadekobot -b v5 --depth 1`
|
||||
2. `cd nadekobot`
|
||||
3. `dotnet publish -c Release -o output/ src/NadekoBot/`
|
||||
4. `cd output`
|
||||
@@ -119,11 +115,11 @@ Open PowerShell as described above and run the following commands:
|
||||
🎉 Enjoy
|
||||
|
||||
#### Music prerequisites
|
||||
In order to use music commands, you need ffmpeg and youtube-dl installed.
|
||||
In order to use music commands, you need ffmpeg and 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-dl] - Click to download the file, then move `youtube-dl.exe` to a path that's in your PATH environment variable. If you don't know what that is, just move the `youtube-dl.exe` file to `NadekoBot/system`.
|
||||
- [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/
|
||||
[Updater]: https://dl.nadeko.bot/v3/
|
||||
[Notepad++]: https://notepad-plus-plus.org/
|
||||
[.net]: https://dotnet.microsoft.com/download/dotnet/5.0
|
||||
[Redis]: https://github.com/MicrosoftArchive/redis/releases/download/win-3.0.504/Redis-x64-3.0.504.msi
|
||||
@@ -131,4 +127,4 @@ In order to use music commands, you need ffmpeg and youtube-dl 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-dl]: https://yt-dl.org/downloads/latest/youtube-dl.exe
|
||||
[youtube-dlp]: https://github.com/yt-dlp/yt-dlp/releases
|
||||
|
@@ -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/Kwoth/nadekobot
|
||||
[issues]: https://gitlab.com/Kwoth/nadekobot/issues
|
||||
[gitlab]: https://gitlab.com/nadeko/nadekobot
|
||||
[issues]: https://gitlab.com/nadeko/nadekobot/issues
|
||||
[donate]: ./donate.md
|
||||
|
@@ -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/Kwoth/nadekobot/-/tree/v4/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/nadeko/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 gitlab.com/kwoth/nadekobot repo locally and reference the NadekoBot.csproj because there is no NadekoBot package atm.
|
||||
the https://gitlab.com/nadeko/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,
|
||||
|
@@ -8,7 +8,7 @@ Permissions are very handy at setting who can use what commands in a server. All
|
||||
|
||||
Several commands still require that you have the correct permissions on Discord to be able to use them, so for users to be able to use commands like `.kick` and `.voicemute`, they need **Kick** and **Mute Members** server permissions, respectively.
|
||||
|
||||
With the permissions system it possible to restrict who can skip the current song, pick NadekoFlowers or use the NSFW module.
|
||||
With the permissions system it possible to restrict who can skip the current song.
|
||||
|
||||
## First Time Setup
|
||||
|
||||
@@ -64,15 +64,6 @@ To allow users to only see the current song and have a DJ role for queuing follo
|
||||
4. `.rm Music enable DJ`
|
||||
- Enables all music commands only for the DJ role
|
||||
|
||||
#### How do I create a NSFW role?
|
||||
|
||||
Say you want to only enable NSFW commands for a specific role, just do the following two steps.
|
||||
|
||||
1. `.sm NSFW disable`
|
||||
- Disables the NSFW module from being used
|
||||
2. `.rm NSFW enable Lewd`
|
||||
- Enables usage of the NSFW module for the Lewd role
|
||||
|
||||
#### How do I disable Expressions from triggering?
|
||||
|
||||
If you don't want server or global Expressions, just block the module that controls their usage:
|
||||
|
@@ -38,7 +38,7 @@ Some features have their own specific placeholders which are noted in that featu
|
||||
- `%channel.name%` - Channel name
|
||||
- `%channel.id%` - Channel ID
|
||||
- `%channel.created%` - Channel creation date
|
||||
- `%channel.nsfw%` - Returns either `True` or `False`, depending on if the channel is designated as NSFW using discord
|
||||
- `%channel.nsfw%` - Returns either `True` or `False`, depending on if the channel is designated as age-restricted in discord
|
||||
- `%channel.topic%` - Channel topic
|
||||
|
||||
### User placeholders
|
||||
@@ -68,11 +68,6 @@ Some features have their own specific placeholders which are noted in that featu
|
||||
- `%ban.reason%` - Reason for the ban, if provided
|
||||
- `%ban.duration%` - Duration of the ban in the form Days.Hours:Minutes (6.05:04)
|
||||
|
||||
### Bot stats placeholders
|
||||
|
||||
- `%servers%` - Server count bot has joined
|
||||
- `%users%` - Combined user count on servers the bot has joined
|
||||
|
||||
### Shard stats placeholders
|
||||
|
||||
- `%shard.servercount%` - Server count on current shard
|
||||
@@ -89,6 +84,5 @@ Some features have their own specific placeholders which are noted in that featu
|
||||
|
||||
- `%rngX-Y%` - Returns a random number between X and Y
|
||||
- `%target%` - Returns anything the user has written after the trigger (only works on Expressions)
|
||||
- `%img:stuff%` - Returns an `imgur.com` search for "stuff" (only works on Expressions)
|
||||
|
||||

|
||||
|
@@ -1,7 +1,7 @@
|
||||
#define sysfolder "system"
|
||||
#define version GetEnv("NADEKOBOT_INSTALL_VERSION")
|
||||
#define target "win7-x64"
|
||||
#define platform "net6.0"
|
||||
#define target "win-x64"
|
||||
#define platform "net8.0"
|
||||
|
||||
[Setup]
|
||||
AppName = {param:botname|NadekoBot}
|
||||
|
10
migrate.ps1
Normal file
10
migrate.ps1
Normal file
@@ -0,0 +1,10 @@
|
||||
if ($args.Length -eq 0) {
|
||||
Write-Host "Please provide a migration name." -ForegroundColor Red
|
||||
}
|
||||
else {
|
||||
$migrationName = $args[0]
|
||||
dotnet ef migrations add $migrationName -c SqliteContext -p src/NadekoBot/NadekoBot.csproj
|
||||
dotnet ef migrations add $migrationName -c PostgreSqlContext -p src/NadekoBot/NadekoBot.csproj
|
||||
dotnet ef migrations add $migrationName -c MysqlContext -p src/NadekoBot/NadekoBot.csproj
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
site_name: 'NadekoBot'
|
||||
site_url: 'https://nadeko.bot'
|
||||
repo_url: 'https://gitlab.com/kwoth/nadekobot'
|
||||
repo_url: 'https://gitlab.com/nadeko/nadekobot'
|
||||
site_author: 'Kwoth'
|
||||
|
||||
theme:
|
||||
|
63
release.ps1
63
release.ps1
@@ -1,63 +0,0 @@
|
||||
function Get-Changelog($lastTag)
|
||||
{
|
||||
if(!$lastTag)
|
||||
{
|
||||
$lastTag = git describe --tags --abbrev=0
|
||||
}
|
||||
|
||||
$tag = "$lastTag..HEAD"
|
||||
|
||||
$clArr = (git log $tag --oneline)
|
||||
[array]::Reverse($clArr)
|
||||
$changelog = $clArr | where { "$_" -notlike "*(POEditor.com)*" -and "$_" -notlike "*Merge branch*" -and "$_" -notlike "*Merge pull request*" -and "$_" -notlike "^-*" -and "$_" -notlike "*Merge remote tracking*" }
|
||||
$changelog = [string]::join([Environment]::NewLine, $changelog)
|
||||
|
||||
$cl2 = $clArr | where { "$_" -like "*Merge pull request*" }
|
||||
$changelog = "## Changes$nl$changelog"
|
||||
if ($null -ne $cl2) {
|
||||
$cl2 = [string]::join([Environment]::NewLine, $cl2)
|
||||
$changelog = $changelog + "$nl ## Pull Requests Merged$nl$cl2"
|
||||
}
|
||||
|
||||
return $changelog
|
||||
}
|
||||
|
||||
function Build-Installer($versionNumber)
|
||||
{
|
||||
$env:NADEKOBOT_INSTALL_VERSION = $versionNumber
|
||||
|
||||
dotnet clean
|
||||
# rm -r -fo "src\NadekoBot\bin"
|
||||
dotnet publish -c Release --runtime win7-x64 /p:Version=$versionNumber src/NadekoBot
|
||||
# .\rcedit-x64.exe "src\NadekoBot\bin\Release\netcoreapp2.1\win7-x64\nadekobot.exe" --set-icon "src\NadekoBot\bin\Release\netcoreapp2.1\win7-x64\nadeko_icon.ico"
|
||||
|
||||
& "iscc.exe" "/O+" ".\exe_builder.iss"
|
||||
|
||||
Write-ReleaseFile($versionNumber)
|
||||
# $path = [Environment]::GetFolderPath('MyDocuments') + "\_projekti\new_installer\$versionNumber\";
|
||||
# $binPath = $path + "nadeko-setup-$versionNumber.exe";
|
||||
# Copy-Item -Path $path -Destination $dest -Force -ErrorAction Stop
|
||||
|
||||
# return $path
|
||||
}
|
||||
|
||||
function Write-ReleaseFile($versionNumber) {
|
||||
$changelog = ""
|
||||
# pull the changes if they exist
|
||||
# git pull
|
||||
# attempt to build teh installer
|
||||
# $path = Build-Installer $versionNumber
|
||||
|
||||
# get changelog before tagging
|
||||
$changelog = Get-Changelog
|
||||
# tag the release
|
||||
# & (git tag, $tag)
|
||||
|
||||
# print out the changelog to the console
|
||||
# Write-Host $changelog
|
||||
|
||||
$jsonReleaseFile = "[{""VersionName"": ""$versionNumber"", ""DownloadLink"": ""https://cdn.nadeko.bot/dl/bot/nadeko-setup-$versionNumber.exe"", ""Changelog"": """"}]"
|
||||
|
||||
$releaseJsonOutPath = [Environment]::GetFolderPath('MyDocuments') + "\_projekti\nadeko-installers\$versionNumber\"
|
||||
New-Item -Path $releaseJsonOutPath -Value $jsonReleaseFile -Name "releases.json" -Force
|
||||
}
|
@@ -1 +0,0 @@
|
||||
[{ "VersionName":"_VERSION_", "DownloadLink":"https://cdn.nadeko.bot/dl/bot/_INSTALLER_FILE_NAME_" }]
|
4
remove-migration.ps1
Normal file
4
remove-migration.ps1
Normal file
@@ -0,0 +1,4 @@
|
||||
dotnet ef migrations remove -c SqliteContext -f
|
||||
dotnet ef migrations remove -c PostgreSqlContext -f
|
||||
dotnet ef migrations remove -c MysqlContext -f
|
||||
|
@@ -1 +0,0 @@
|
||||
global using NonBlocking;
|
@@ -1,14 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NonBlocking" Version="2.1.0" />
|
||||
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -1,19 +0,0 @@
|
||||
namespace Nadeko.Common;
|
||||
|
||||
public readonly struct ShmartBankAmount
|
||||
{
|
||||
public long Amount { get; }
|
||||
public ShmartBankAmount(long amount)
|
||||
{
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
public static implicit operator ShmartBankAmount(long num)
|
||||
=> new(num);
|
||||
|
||||
public static implicit operator long(ShmartBankAmount num)
|
||||
=> num.Amount;
|
||||
|
||||
public static implicit operator ShmartBankAmount(int num)
|
||||
=> new(num);
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
namespace Nadeko.Common;
|
||||
|
||||
public readonly struct ShmartNumber : IEquatable<ShmartNumber>
|
||||
{
|
||||
public long Value { get; }
|
||||
|
||||
public ShmartNumber(long val)
|
||||
{
|
||||
Value = val;
|
||||
}
|
||||
|
||||
public static implicit operator ShmartNumber(long num)
|
||||
=> new(num);
|
||||
|
||||
public static implicit operator long(ShmartNumber num)
|
||||
=> num.Value;
|
||||
|
||||
public static implicit operator ShmartNumber(int num)
|
||||
=> new(num);
|
||||
|
||||
public override string ToString()
|
||||
=> Value.ToString();
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
=> obj is ShmartNumber sn && Equals(sn);
|
||||
|
||||
public bool Equals(ShmartNumber other)
|
||||
=> other.Value == Value;
|
||||
|
||||
public override int GetHashCode()
|
||||
=> Value.GetHashCode();
|
||||
|
||||
public static bool operator ==(ShmartNumber left, ShmartNumber right)
|
||||
=> left.Equals(right);
|
||||
|
||||
public static bool operator !=(ShmartNumber left, ShmartNumber right)
|
||||
=> !(left == right);
|
||||
}
|
@@ -1 +0,0 @@
|
||||
global using Nadeko.Common;
|
@@ -1,13 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nadeko.Common\Nadeko.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Overridden to implement custom checks which commands have to pass in order to be executed.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Used as a marker class for bot_perm and user_perm Attributes
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class bot_owner_onlyAttribute : MedusaPermAttribute
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using Discord;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public sealed class bot_permAttribute : MedusaPermAttribute
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Marks a method as a snek command
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Marks services in command arguments for injection.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Marks the parameter to take
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the priority of a command in case there are multiple commands with the same name but different parameters.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Marks the class as a service which can be used within the same Medusa
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using Discord;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public sealed class user_permAttribute : MedusaPermAttribute
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using Discord;
|
||||
using NadekoBot;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Commands which take this class as a first parameter can be executed in both DMs and Servers
|
||||
@@ -40,13 +40,4 @@ public abstract class AnyContext
|
||||
/// <param name="args">Arguments (if any) to format in</param>
|
||||
/// <returns>A formatted localized string</returns>
|
||||
public abstract string GetText(string key, object[]? args = null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a context-aware <see cref="IEmbedBuilder"/> instance
|
||||
/// (future feature for guild-based embed colors)
|
||||
/// Any code dealing with embeds should use it for future-proofness
|
||||
/// instead of manually creating embedbuilder instances
|
||||
/// </summary>
|
||||
/// <returns>A context-aware <see cref="IEmbedBuilder"/> instance </returns>
|
||||
public abstract IEmbedBuilder Embed();
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
using Discord;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Commands which take this type as the first parameter can only be executed in DMs
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using Discord;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Commands which take this type as a first parameter can only be executed in a server
|
||||
|
@@ -1,14 +0,0 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
public static class EmbedBuilderExtensions
|
||||
{
|
||||
public static IEmbedBuilder WithOkColor(this IEmbedBuilder eb)
|
||||
=> eb.WithColor(EmbedColor.Ok);
|
||||
|
||||
public static IEmbedBuilder WithPendingColor(this IEmbedBuilder eb)
|
||||
=> eb.WithColor(EmbedColor.Pending);
|
||||
|
||||
public static IEmbedBuilder WithErrorColor(this IEmbedBuilder eb)
|
||||
=> eb.WithColor(EmbedColor.Error);
|
||||
|
||||
}
|
@@ -1,11 +1,10 @@
|
||||
using Discord;
|
||||
using Nadeko.Snake;
|
||||
|
||||
namespace NadekoBot;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
public static class MedusaExtensions
|
||||
{
|
||||
public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, IEmbedBuilder embed, string msg = "")
|
||||
public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, EmbedBuilder embed, string msg = "")
|
||||
=> ch.SendMessageAsync(msg,
|
||||
embed: embed.Build(),
|
||||
options: new()
|
||||
@@ -13,25 +12,21 @@ public static class MedusaExtensions
|
||||
RetryMode = RetryMode.Retry502
|
||||
});
|
||||
|
||||
// unlocalized
|
||||
public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, AnyContext ctx, string msg)
|
||||
=> ch.EmbedAsync(ctx.Embed().WithOkColor().WithDescription(msg));
|
||||
|
||||
public static Task<IUserMessage> SendPendingAsync(this IMessageChannel ch, AnyContext ctx, string msg)
|
||||
=> ch.EmbedAsync(ctx.Embed().WithPendingColor().WithDescription(msg));
|
||||
|
||||
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, AnyContext ctx, string msg)
|
||||
=> ch.EmbedAsync(ctx.Embed().WithErrorColor().WithDescription(msg));
|
||||
|
||||
// unlocalized
|
||||
public static Task<IUserMessage> SendConfirmAsync(this AnyContext ctx, string msg)
|
||||
=> ctx.Channel.SendConfirmAsync(ctx, msg);
|
||||
=> ctx.Channel.EmbedAsync(new EmbedBuilder()
|
||||
.WithColor(0, 200, 0)
|
||||
.WithDescription(msg));
|
||||
|
||||
public static Task<IUserMessage> SendPendingAsync(this AnyContext ctx, string msg)
|
||||
=> ctx.Channel.SendPendingAsync(ctx, msg);
|
||||
=> ctx.Channel.EmbedAsync(new EmbedBuilder()
|
||||
.WithColor(200, 200, 0)
|
||||
.WithDescription(msg));
|
||||
|
||||
public static Task<IUserMessage> SendErrorAsync(this AnyContext ctx, string msg)
|
||||
=> ctx.Channel.SendErrorAsync(ctx, msg);
|
||||
=> ctx.Channel.EmbedAsync(new EmbedBuilder()
|
||||
.WithColor(200, 0, 0)
|
||||
.WithDescription(msg));
|
||||
|
||||
// localized
|
||||
public static Task ConfirmAsync(this AnyContext ctx)
|
||||
|
@@ -1,18 +0,0 @@
|
||||
using Discord;
|
||||
|
||||
namespace NadekoBot;
|
||||
|
||||
public interface IEmbedBuilder
|
||||
{
|
||||
IEmbedBuilder WithDescription(string? desc);
|
||||
IEmbedBuilder WithTitle(string? title);
|
||||
IEmbedBuilder AddField(string title, object value, bool isInline = false);
|
||||
IEmbedBuilder WithFooter(string text, string? iconUrl = null);
|
||||
IEmbedBuilder WithAuthor(string name, string? iconUrl = null, string? url = null);
|
||||
IEmbedBuilder WithColor(EmbedColor color);
|
||||
IEmbedBuilder WithDiscordColor(Color color);
|
||||
Embed Build();
|
||||
IEmbedBuilder WithUrl(string url);
|
||||
IEmbedBuilder WithImageUrl(string url);
|
||||
IEmbedBuilder WithThumbnailUrl(string url);
|
||||
}
|
@@ -1,23 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<EnablePreviewFeatures>true</EnablePreviewFeatures>
|
||||
<RootNamespace>Nadeko.Snake</RootNamespace>
|
||||
|
||||
<Authors>The NadekoBot Team</Authors>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net.Core" Version="3.104.0" />
|
||||
<PackageReference Include="Serilog" Version="2.11.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="11.2.1" />
|
||||
<PackageReference Include="Discord.Net.Core" Version="3.204.0" />
|
||||
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||
<PackageReference Include="YamlDotNet" Version="15.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Version)' == '' ">
|
||||
<Version>5.0.0</Version>
|
||||
<Version>9.0.0</Version>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Overridden to implement parsers for custom types
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
public readonly struct ParseResult<T>
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using Discord;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// The base class which will be loaded as a module into NadekoBot
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
public readonly struct CommandStrings
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Defines methods to retrieve and reload medusa strings
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Implemented by classes which provide localized strings in their own ways
|
||||
|
@@ -1,4 +1,4 @@
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
public class LocalMedusaStringsProvider : IMedusaStringsProvider
|
||||
{
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using System.Globalization;
|
||||
using Serilog;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
public class MedusaStrings : IMedusaStrings
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
using Serilog;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace Nadeko.Snake;
|
||||
namespace NadekoBot.Medusa;
|
||||
|
||||
/// <summary>
|
||||
/// Loads strings from the shortcut or localizable path
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<NoWarn>CS8981</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -9,11 +10,11 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="2.47.0" />
|
||||
<PackageReference Include="Serilog" Version="2.11.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="2.62.0" />
|
||||
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="11.2.1" />
|
||||
<PackageReference Include="YamlDotNet" Version="15.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -6,8 +6,6 @@ using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Cloneable
|
||||
@@ -23,54 +21,60 @@ namespace Cloneable
|
||||
private const string CLONE_ATTRIBUTE_STRING = "CloneAttribute";
|
||||
private const string IGNORE_CLONE_ATTRIBUTE_STRING = "IgnoreCloneAttribute";
|
||||
|
||||
private const string CLONEABLE_ATTRIBUTE_TEXT = @"// <AutoGenerated/>
|
||||
private const string CLONEABLE_ATTRIBUTE_TEXT = $$"""
|
||||
// <AutoGenerated/>
|
||||
using System;
|
||||
|
||||
namespace " + CLONEABLE_NAMESPACE + @"
|
||||
namespace {{CLONEABLE_NAMESPACE}}
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class " + CLONEABLE_ATTRIBUTE_STRING + @" : Attribute
|
||||
internal sealed class {{CLONEABLE_ATTRIBUTE_STRING}} : Attribute
|
||||
{
|
||||
public " + CLONEABLE_ATTRIBUTE_STRING + @"()
|
||||
public {{CLONEABLE_ATTRIBUTE_STRING}}()
|
||||
{
|
||||
}
|
||||
|
||||
public bool " + EXPLICIT_DECLARATION_KEY_STRING + @" { get; set; }
|
||||
public bool {{EXPLICIT_DECLARATION_KEY_STRING}} { get; set; }
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
private const string CLONE_PROPERTY_ATTRIBUTE_TEXT = @"// <AutoGenerated/>
|
||||
""";
|
||||
|
||||
private const string CLONE_PROPERTY_ATTRIBUTE_TEXT = $$"""
|
||||
// <AutoGenerated/>
|
||||
using System;
|
||||
|
||||
namespace " + CLONEABLE_NAMESPACE + @"
|
||||
namespace {{CLONEABLE_NAMESPACE}}
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class " + CLONE_ATTRIBUTE_STRING + @" : Attribute
|
||||
internal sealed class {{CLONE_ATTRIBUTE_STRING}} : Attribute
|
||||
{
|
||||
public " + CLONE_ATTRIBUTE_STRING + @"()
|
||||
public {{CLONE_ATTRIBUTE_STRING}}()
|
||||
{
|
||||
}
|
||||
|
||||
public bool " + PREVENT_DEEP_COPY_KEY_STRING + @" { get; set; }
|
||||
public bool {{PREVENT_DEEP_COPY_KEY_STRING}} { get; set; }
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
private const string IGNORE_CLONE_PROPERTY_ATTRIBUTE_TEXT = @"// <AutoGenerated/>
|
||||
""";
|
||||
|
||||
private const string IGNORE_CLONE_PROPERTY_ATTRIBUTE_TEXT = $$"""
|
||||
// <AutoGenerated/>
|
||||
using System;
|
||||
|
||||
namespace " + CLONEABLE_NAMESPACE + @"
|
||||
namespace {{CLONEABLE_NAMESPACE}}
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class " + IGNORE_CLONE_ATTRIBUTE_STRING + @" : Attribute
|
||||
internal sealed class {{IGNORE_CLONE_ATTRIBUTE_STRING}} : Attribute
|
||||
{
|
||||
public " + IGNORE_CLONE_ATTRIBUTE_STRING + @"()
|
||||
public {{IGNORE_CLONE_ATTRIBUTE_STRING}}()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
""";
|
||||
|
||||
private INamedTypeSymbol? _cloneableAttribute;
|
||||
private INamedTypeSymbol? _ignoreCloneAttribute;
|
||||
|
@@ -1,8 +1,7 @@
|
||||
// Code temporarily yeeted from
|
||||
// https://github.com/mostmand/Cloneable/blob/master/Cloneable/CloneableGenerator.cs
|
||||
// because of NRT issue
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Cloneable
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// Code temporarily yeeted from
|
||||
// https://github.com/mostmand/Cloneable/blob/master/Cloneable/CloneableGenerator.cs
|
||||
// because of NRT issue
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
|
@@ -1,336 +0,0 @@
|
||||
// #nullable enable
|
||||
// using System;
|
||||
// using System.CodeDom.Compiler;
|
||||
// using System.Collections.Generic;
|
||||
// using System.Collections.Immutable;
|
||||
// using System.Collections.ObjectModel;
|
||||
// using System.Diagnostics;
|
||||
// using System.IO;
|
||||
// using System.Linq;
|
||||
// using System.Text;
|
||||
// using System.Threading;
|
||||
// using Microsoft.CodeAnalysis;
|
||||
// using Microsoft.CodeAnalysis.CSharp;
|
||||
// using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
// using Microsoft.CodeAnalysis.Text;
|
||||
//
|
||||
// namespace NadekoBot.Generators.Command;
|
||||
//
|
||||
// [Generator]
|
||||
// public class CommandAttributesGenerator : IIncrementalGenerator
|
||||
// {
|
||||
// public const string ATTRIBUTE = @"// <AutoGenerated />
|
||||
//
|
||||
// namespace NadekoBot.Common;
|
||||
//
|
||||
// [System.AttributeUsage(System.AttributeTargets.Method)]
|
||||
// public class CmdAttribute : System.Attribute
|
||||
// {
|
||||
//
|
||||
// }";
|
||||
//
|
||||
// public class MethodModel
|
||||
// {
|
||||
// public string? Namespace { get; }
|
||||
// public IReadOnlyCollection<string> Classes { get; }
|
||||
// public string ReturnType { get; }
|
||||
// public string MethodName { get; }
|
||||
// public IEnumerable<string> Params { get; }
|
||||
//
|
||||
// public MethodModel(string? ns, IReadOnlyCollection<string> classes, string returnType, string methodName, IEnumerable<string> @params)
|
||||
// {
|
||||
// Namespace = ns;
|
||||
// Classes = classes;
|
||||
// ReturnType = returnType;
|
||||
// MethodName = methodName;
|
||||
// Params = @params;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public class FileModel
|
||||
// {
|
||||
// public string? Namespace { get; }
|
||||
// public IReadOnlyCollection<string> ClassHierarchy { get; }
|
||||
// public IReadOnlyCollection<MethodModel> Methods { get; }
|
||||
//
|
||||
// public FileModel(string? ns, IReadOnlyCollection<string> classHierarchy, IReadOnlyCollection<MethodModel> methods)
|
||||
// {
|
||||
// Namespace = ns;
|
||||
// ClassHierarchy = classHierarchy;
|
||||
// Methods = methods;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
// {
|
||||
// // #if DEBUG
|
||||
// // if (!Debugger.IsAttached)
|
||||
// // Debugger.Launch();
|
||||
// // // SpinWait.SpinUntil(() => Debugger.IsAttached);
|
||||
// // #endif
|
||||
// context.RegisterPostInitializationOutput(static ctx => ctx.AddSource(
|
||||
// "CmdAttribute.g.cs",
|
||||
// SourceText.From(ATTRIBUTE, Encoding.UTF8)));
|
||||
//
|
||||
// var methods = context.SyntaxProvider
|
||||
// .CreateSyntaxProvider(
|
||||
// static (node, _) => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 },
|
||||
// static (ctx, cancel) => Transform(ctx, cancel))
|
||||
// .Where(static m => m is not null)
|
||||
// .Where(static m => m?.ChildTokens().Any(static x => x.IsKind(SyntaxKind.PublicKeyword)) ?? false);
|
||||
//
|
||||
// var compilationMethods = context.CompilationProvider.Combine(methods.Collect());
|
||||
//
|
||||
// context.RegisterSourceOutput(compilationMethods,
|
||||
// static (ctx, tuple) => RegisterAction(in ctx, tuple.Left, in tuple.Right));
|
||||
// }
|
||||
//
|
||||
// private static void RegisterAction(in SourceProductionContext ctx,
|
||||
// Compilation comp,
|
||||
// in ImmutableArray<MethodDeclarationSyntax?> methods)
|
||||
// {
|
||||
// if (methods is { IsDefaultOrEmpty: true })
|
||||
// return;
|
||||
//
|
||||
// var models = GetModels(comp, methods, ctx.CancellationToken);
|
||||
//
|
||||
// foreach (var model in models)
|
||||
// {
|
||||
// var name = $"{model.Namespace}.{string.Join(".", model.ClassHierarchy)}.g.cs";
|
||||
// try
|
||||
// {
|
||||
// var source = GetSourceText(model);
|
||||
// ctx.AddSource(name, SourceText.From(source, Encoding.UTF8));
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Error writing source file {name}\n" + ex);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static string GetSourceText(FileModel model)
|
||||
// {
|
||||
// using var sw = new StringWriter();
|
||||
// using var tw = new IndentedTextWriter(sw);
|
||||
//
|
||||
// tw.WriteLine("// <AutoGenerated />");
|
||||
// tw.WriteLine("#pragma warning disable CS1066");
|
||||
//
|
||||
// if (model.Namespace is not null)
|
||||
// {
|
||||
// tw.WriteLine($"namespace {model.Namespace};");
|
||||
// tw.WriteLine();
|
||||
// }
|
||||
//
|
||||
// foreach (var className in model.ClassHierarchy)
|
||||
// {
|
||||
// tw.WriteLine($"public partial class {className}");
|
||||
// tw.WriteLine("{");
|
||||
// tw.Indent ++;
|
||||
// }
|
||||
//
|
||||
// foreach (var method in model.Methods)
|
||||
// {
|
||||
// tw.WriteLine("[NadekoCommand]");
|
||||
// tw.WriteLine("[NadekoDescription]");
|
||||
// tw.WriteLine("[Aliases]");
|
||||
// tw.WriteLine($"public partial {method.ReturnType} {method.MethodName}({string.Join(", ", method.Params)});");
|
||||
// }
|
||||
//
|
||||
// foreach (var _ in model.ClassHierarchy)
|
||||
// {
|
||||
// tw.Indent --;
|
||||
// tw.WriteLine("}");
|
||||
// }
|
||||
//
|
||||
// tw.Flush();
|
||||
// return sw.ToString();
|
||||
// }
|
||||
//
|
||||
// private static IReadOnlyCollection<FileModel> GetModels(Compilation compilation,
|
||||
// in ImmutableArray<MethodDeclarationSyntax?> inputMethods,
|
||||
// CancellationToken cancel)
|
||||
// {
|
||||
// var models = new List<FileModel>();
|
||||
//
|
||||
// var methods = inputMethods
|
||||
// .Where(static x => x is not null)
|
||||
// .Distinct();
|
||||
//
|
||||
// var methodModels = methods
|
||||
// .Select(x => MethodDeclarationToMethodModel(compilation, x!))
|
||||
// .Where(static x => x is not null)
|
||||
// .Cast<MethodModel>();
|
||||
//
|
||||
// var groups = methodModels
|
||||
// .GroupBy(static x => $"{x.Namespace}.{string.Join(".", x.Classes)}");
|
||||
//
|
||||
// foreach (var group in groups)
|
||||
// {
|
||||
// if (cancel.IsCancellationRequested)
|
||||
// return new Collection<FileModel>();
|
||||
//
|
||||
// if (group is null)
|
||||
// continue;
|
||||
//
|
||||
// var elems = group.ToList();
|
||||
// if (elems.Count is 0)
|
||||
// continue;
|
||||
//
|
||||
// var model = new FileModel(
|
||||
// methods: elems,
|
||||
// ns: elems[0].Namespace,
|
||||
// classHierarchy: elems![0].Classes
|
||||
// );
|
||||
//
|
||||
// models.Add(model);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return models;
|
||||
// }
|
||||
//
|
||||
// private static MethodModel? MethodDeclarationToMethodModel(Compilation comp, MethodDeclarationSyntax decl)
|
||||
// {
|
||||
// // SpinWait.SpinUntil(static () => Debugger.IsAttached);
|
||||
//
|
||||
// SemanticModel semanticModel;
|
||||
// try
|
||||
// {
|
||||
// semanticModel = comp.GetSemanticModel(decl.SyntaxTree);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// // for some reason this method can throw "Not part of this compilation" argument exception
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// var methodModel = new MethodModel(
|
||||
// @params: decl.ParameterList.Parameters
|
||||
// .Where(p => p.Type is not null)
|
||||
// .Select(p =>
|
||||
// {
|
||||
// var prefix = p.Modifiers.Any(static x => x.IsKind(SyntaxKind.ParamsKeyword))
|
||||
// ? "params "
|
||||
// : string.Empty;
|
||||
//
|
||||
// var type = semanticModel
|
||||
// .GetTypeInfo(p.Type!)
|
||||
// .Type
|
||||
// ?.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
//
|
||||
//
|
||||
// var name = p.Identifier.Text;
|
||||
//
|
||||
// var suffix = string.Empty;
|
||||
// if (p.Default is not null)
|
||||
// {
|
||||
// if (p.Default.Value is LiteralExpressionSyntax)
|
||||
// {
|
||||
// suffix = " = " + p.Default.Value;
|
||||
// }
|
||||
// else if (p.Default.Value is MemberAccessExpressionSyntax maes)
|
||||
// {
|
||||
// var maesSemModel = comp.GetSemanticModel(maes.SyntaxTree);
|
||||
// var sym = maesSemModel.GetSymbolInfo(maes.Name);
|
||||
// if (sym.Symbol is null)
|
||||
// {
|
||||
// suffix = " = " + p.Default.Value;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// suffix = " = " + sym.Symbol.ToDisplayString();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return $"{prefix}{type} {name}{suffix}";
|
||||
// })
|
||||
// .ToList(),
|
||||
// methodName: decl.Identifier.Text,
|
||||
// returnType: decl.ReturnType.ToString(),
|
||||
// ns: GetNamespace(decl),
|
||||
// classes: GetClasses(decl)
|
||||
// );
|
||||
//
|
||||
// return methodModel;
|
||||
// }
|
||||
//
|
||||
// //https://github.com/andrewlock/NetEscapades.EnumGenerators/blob/main/src/NetEscapades.EnumGenerators/EnumGenerator.cs
|
||||
// static string? GetNamespace(MethodDeclarationSyntax declarationSyntax)
|
||||
// {
|
||||
// // determine the namespace the class is declared in, if any
|
||||
// string? nameSpace = null;
|
||||
// var parentOfInterest = declarationSyntax.Parent;
|
||||
// while (parentOfInterest is not null)
|
||||
// {
|
||||
// parentOfInterest = parentOfInterest.Parent;
|
||||
//
|
||||
// if (parentOfInterest is BaseNamespaceDeclarationSyntax ns)
|
||||
// {
|
||||
// nameSpace = ns.Name.ToString();
|
||||
// while (true)
|
||||
// {
|
||||
// if (ns.Parent is not NamespaceDeclarationSyntax parent)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// ns = parent;
|
||||
// nameSpace = $"{ns.Name}.{nameSpace}";
|
||||
// }
|
||||
//
|
||||
// return nameSpace;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// return nameSpace;
|
||||
// }
|
||||
//
|
||||
// static IReadOnlyCollection<string> GetClasses(MethodDeclarationSyntax declarationSyntax)
|
||||
// {
|
||||
// // determine the namespace the class is declared in, if any
|
||||
// var classes = new LinkedList<string>();
|
||||
// var parentOfInterest = declarationSyntax.Parent;
|
||||
// while (parentOfInterest is not null)
|
||||
// {
|
||||
// if (parentOfInterest is ClassDeclarationSyntax cds)
|
||||
// {
|
||||
// classes.AddFirst(cds.Identifier.ToString());
|
||||
// }
|
||||
//
|
||||
// parentOfInterest = parentOfInterest.Parent;
|
||||
// }
|
||||
//
|
||||
// Debug.WriteLine($"Method {declarationSyntax.Identifier.Text} has {classes.Count} classes");
|
||||
//
|
||||
// return classes;
|
||||
// }
|
||||
//
|
||||
// private static MethodDeclarationSyntax? Transform(GeneratorSyntaxContext ctx, CancellationToken cancel)
|
||||
// {
|
||||
// var methodDecl = ctx.Node as MethodDeclarationSyntax;
|
||||
// if (methodDecl is null)
|
||||
// return default;
|
||||
//
|
||||
// foreach (var attListSyntax in methodDecl.AttributeLists)
|
||||
// {
|
||||
// foreach (var attSyntax in attListSyntax.Attributes)
|
||||
// {
|
||||
// if (cancel.IsCancellationRequested)
|
||||
// return default;
|
||||
//
|
||||
// var symbol = ctx.SemanticModel.GetSymbolInfo(attSyntax).Symbol;
|
||||
// if (symbol is not IMethodSymbol attSymbol)
|
||||
// continue;
|
||||
//
|
||||
// if (attSymbol.ContainingType.ToDisplayString() == "NadekoBot.Common.CmdAttribute")
|
||||
// return methodDecl;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return default;
|
||||
// }
|
||||
// }
|
@@ -1,10 +1,6 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Newtonsoft.Json;
|
||||
@@ -26,24 +22,23 @@ namespace NadekoBot.Generators
|
||||
[Generator]
|
||||
public class LocalizedStringsGenerator : ISourceGenerator
|
||||
{
|
||||
private const string LOC_STR_SOURCE = @"namespace NadekoBot
|
||||
{
|
||||
public readonly struct LocStr
|
||||
{
|
||||
public readonly string Key;
|
||||
public readonly object[] Params;
|
||||
|
||||
public LocStr(string key, params object[] data)
|
||||
{
|
||||
Key = key;
|
||||
Params = data;
|
||||
}
|
||||
}
|
||||
}";
|
||||
// private const string LOC_STR_SOURCE = @"namespace NadekoBot
|
||||
// {
|
||||
// public readonly struct LocStr
|
||||
// {
|
||||
// public readonly string Key;
|
||||
// public readonly object[] Params;
|
||||
//
|
||||
// public LocStr(string key, params object[] data)
|
||||
// {
|
||||
// Key = key;
|
||||
// Params = data;
|
||||
// }
|
||||
// }
|
||||
// }";
|
||||
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
@@ -55,6 +50,7 @@ namespace NadekoBot.Generators
|
||||
using (var stringWriter = new StringWriter())
|
||||
using (var sw = new IndentedTextWriter(stringWriter))
|
||||
{
|
||||
sw.WriteLine("#pragma warning disable CS8981");
|
||||
sw.WriteLine("namespace NadekoBot;");
|
||||
sw.WriteLine();
|
||||
|
||||
@@ -106,7 +102,7 @@ namespace NadekoBot.Generators
|
||||
context.AddSource("strs.g.cs", stringWriter.ToString());
|
||||
}
|
||||
|
||||
context.AddSource("LocStr.g.cs", LOC_STR_SOURCE);
|
||||
// context.AddSource("LocStr.g.cs", LOC_STR_SOURCE);
|
||||
}
|
||||
|
||||
private List<TranslationPair> GetFields(string? dataText)
|
||||
|
@@ -5,12 +5,13 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<IsRoslynComponent>true</IsRoslynComponent>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" PrivateAssets="all" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" PrivateAssets="all" GeneratePathProperty="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -23,3 +24,4 @@
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
|
@@ -3,9 +3,9 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Common.Attributes;
|
||||
using NadekoBot.Services;
|
||||
using NadekoBot.Modules;
|
||||
|
||||
namespace NadekoBot.Tests
|
||||
{
|
||||
@@ -99,31 +99,33 @@ namespace NadekoBot.Tests
|
||||
Assert.Warn("There are some unused entries in data/aliases.yml");
|
||||
}
|
||||
|
||||
// [Test]
|
||||
// public void NoObsoleteCommandStrings()
|
||||
// {
|
||||
// var stringsSource = new LocalFileStringsSource(responsesPath, commandsPath);
|
||||
//
|
||||
// var culture = new CultureInfo("en-US");
|
||||
//
|
||||
// var isSuccess = true;
|
||||
// var allCommandNames = CommandNameLoadHelper.LoadCommandNames(aliasesPath);
|
||||
// var enUsCommandNames = allCommandNames
|
||||
// .Select(x => x.Value[0]) // first alias is command name
|
||||
// .ToHashSet();
|
||||
// foreach (var entry in stringsSource.GetCommandStrings()[culture.Name])
|
||||
// {
|
||||
// // key is command name which should be specified in aliases[0] of any method name
|
||||
// var cmdName = entry.Key;
|
||||
//
|
||||
// if (!enUsCommandNames.Contains(cmdName))
|
||||
// {
|
||||
// TestContext.Out.WriteLine($"'{cmdName}' It's either obsolete or missing an alias entry.");
|
||||
// isSuccess = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Assert.IsTrue(isSuccess);
|
||||
// }
|
||||
[Test]
|
||||
public void NoObsoleteCommandStrings()
|
||||
{
|
||||
var stringsSource = new LocalFileStringsSource(responsesPath, commandsPath);
|
||||
|
||||
var culture = new CultureInfo("en-US");
|
||||
|
||||
var methodNames = GetCommandMethodNames()
|
||||
.ToHashSet();
|
||||
|
||||
var isSuccess = true;
|
||||
// var allCommandNames = CommandNameLoadHelper.LoadCommandStrings(commandsPath));
|
||||
foreach (var entry in stringsSource.GetCommandStrings()[culture.Name])
|
||||
{
|
||||
var cmdName = entry.Key;
|
||||
|
||||
if (!methodNames.Contains(cmdName))
|
||||
{
|
||||
TestContext.Out.WriteLine($"'{cmdName}' from commands.en-US.yml doesn't have a matching command method.");
|
||||
isSuccess = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(isSuccess)
|
||||
Assert.IsTrue(isSuccess);
|
||||
else
|
||||
Assert.Warn("There are some unused command strings in data/strings/commands.en-US.yml");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Nadeko.Common;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
using Nadeko.Common;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Db.Models;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using Nadeko.Common;
|
||||
using NadekoBot.Common;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace NadekoBot.Tests
|
||||
|
@@ -1,9 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<EnablePreviewFeatures>True</EnablePreviewFeatures>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -13,9 +11,8 @@
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nadeko.Common\Nadeko.Common.csproj" />
|
||||
<ProjectReference Include="..\Nadeko.Econ\Nadeko.Econ.csproj" />
|
||||
<ProjectReference Include="..\NadekoBot\NadekoBot.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using NadekoBot.Common;
|
||||
using Nadeko.Common;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Internal;
|
||||
|
||||
|
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ayu.Discord.Voice
|
||||
namespace NadekoBot.Voice
|
||||
{
|
||||
internal static unsafe class LibOpus
|
||||
{
|
||||
public const string OPUS = "opus";
|
||||
public const string OPUS = "data/lib/opus";
|
||||
|
||||
[DllImport(OPUS, EntryPoint = "opus_encoder_create", CallingConvention = CallingConvention.Cdecl)]
|
||||
internal static extern IntPtr CreateEncoder(int Fs, int channels, int application, out OpusError error);
|
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ayu.Discord.Voice
|
||||
namespace NadekoBot.Voice
|
||||
{
|
||||
internal static unsafe class Sodium
|
||||
{
|
||||
private const string SODIUM = "libsodium";
|
||||
private const string SODIUM = "data/lib/libsodium";
|
||||
|
||||
[DllImport(SODIUM, EntryPoint = "crypto_secretbox_easy", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern int SecretBoxEasy(byte* output, byte* input, long inputLength, byte* nonce, byte* secret);
|
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ayu.Discord.Voice.Models
|
||||
namespace NadekoBot.Voice.Models
|
||||
{
|
||||
public sealed class SelectProtocol
|
||||
{
|
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ayu.Discord.Voice.Models
|
||||
namespace NadekoBot.Voice.Models
|
||||
{
|
||||
public sealed class VoiceHello
|
||||
{
|
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ayu.Discord.Voice.Models
|
||||
namespace NadekoBot.Voice.Models
|
||||
{
|
||||
public sealed class VoiceIdentify
|
||||
{
|
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ayu.Discord.Voice.Models
|
||||
namespace NadekoBot.Voice.Models
|
||||
{
|
||||
public sealed class VoiceReady
|
||||
{
|
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ayu.Discord.Voice.Models
|
||||
namespace NadekoBot.Voice.Models
|
||||
{
|
||||
public sealed class VoiceResume
|
||||
{
|
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ayu.Discord.Voice.Models
|
||||
namespace NadekoBot.Voice.Models
|
||||
{
|
||||
public sealed class VoiceSessionDescription
|
||||
{
|
@@ -1,7 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Ayu.Discord.Voice.Models
|
||||
namespace NadekoBot.Voice.Models
|
||||
{
|
||||
public sealed class VoiceSpeaking
|
||||
{
|
@@ -5,10 +5,11 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<NoWarn>CS8632</NoWarn>
|
||||
<Version>1.0.2</Version>
|
||||
<RootNamespace>NadekoBot.Voice</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Serilog" Version="2.11.0" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="6.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Serilog" Version="3.1.1" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -4,7 +4,7 @@ using System.Buffers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ayu.Discord.Voice
|
||||
namespace NadekoBot.Voice
|
||||
{
|
||||
public sealed class PoopyBufferImmortalized : ISongBuffer
|
||||
{
|
@@ -4,7 +4,7 @@ using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ayu.Discord.Voice
|
||||
namespace NadekoBot.Voice
|
||||
{
|
||||
public interface ISongBuffer : IDisposable
|
||||
{
|
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Buffers;
|
||||
|
||||
namespace Ayu.Discord.Voice
|
||||
namespace NadekoBot.Voice
|
||||
{
|
||||
public sealed class VoiceClient : IDisposable
|
||||
{
|
@@ -1,4 +1,4 @@
|
||||
using Ayu.Discord.Voice.Models;
|
||||
using NadekoBot.Voice.Models;
|
||||
using Discord.Models.Gateway;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Serilog;
|
||||
@@ -12,7 +12,7 @@ using System.Threading.Tasks;
|
||||
using Ayu.Discord.Gateway;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Ayu.Discord.Voice
|
||||
namespace NadekoBot.Voice
|
||||
{
|
||||
public class VoiceGateway
|
||||
{
|
@@ -20,9 +20,8 @@ namespace NadekoBot.VotesApi
|
||||
public AuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock,
|
||||
IConfiguration conf)
|
||||
: base(options, logger, encoder, clock)
|
||||
: base(options, logger, encoder)
|
||||
=> _conf = conf;
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
|
@@ -1,13 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MorseCode.ITask" Version="2.0.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -357,3 +357,4 @@ resharper_arrange_redundant_parentheses_highlighting = hint
|
||||
|
||||
# IDE0011: Add braces
|
||||
dotnet_diagnostic.IDE0011.severity = warning
|
||||
|
||||
|
@@ -1,28 +1,26 @@
|
||||
#nullable disable
|
||||
using DryIoc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NadekoBot.Common.Configs;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Utility;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Db.Models;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using RunMode = Discord.Commands.RunMode;
|
||||
|
||||
namespace NadekoBot;
|
||||
|
||||
public sealed class Bot
|
||||
public sealed class Bot : IBot
|
||||
{
|
||||
public event Func<GuildConfig, Task> JoinedGuild = delegate { return Task.CompletedTask; };
|
||||
|
||||
public DiscordSocketClient Client { get; }
|
||||
public ImmutableArray<GuildConfig> AllGuildConfigs { get; private set; }
|
||||
public IReadOnlyCollection<GuildConfig> AllGuildConfigs { get; private set; }
|
||||
|
||||
private IServiceProvider Services { get; set; }
|
||||
private IContainer Services { get; set; }
|
||||
|
||||
public string Mention { get; private set; }
|
||||
public bool IsReady { get; private set; }
|
||||
public int ShardId { get; set; }
|
||||
|
||||
@@ -31,18 +29,19 @@ public sealed class Bot
|
||||
private readonly DbService _db;
|
||||
|
||||
private readonly IBotCredsProvider _credsProvider;
|
||||
|
||||
private readonly Assembly[] _loadedAssemblies;
|
||||
// private readonly InteractionService _interactionService;
|
||||
|
||||
public Bot(int shardId, int? totalShards, string credPath = null)
|
||||
{
|
||||
if (shardId < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(shardId));
|
||||
ArgumentOutOfRangeException.ThrowIfLessThan(shardId, 0);
|
||||
|
||||
ShardId = shardId;
|
||||
_credsProvider = new BotCredsProvider(totalShards, credPath);
|
||||
_creds = _credsProvider.GetCreds();
|
||||
|
||||
_db = new(_credsProvider);
|
||||
_db = new NadekoDbService(_credsProvider);
|
||||
|
||||
var messageCacheSize =
|
||||
#if GLOBAL_NADEKO
|
||||
@@ -81,10 +80,14 @@ public sealed class Bot
|
||||
// _interactionService = new(Client.Rest);
|
||||
|
||||
Client.Log += Client_Log;
|
||||
_loadedAssemblies = new[]
|
||||
{
|
||||
typeof(Bot).Assembly, // bot
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public List<ulong> GetCurrentGuildIds()
|
||||
public IReadOnlyList<ulong> GetCurrentGuildIds()
|
||||
=> Client.Guilds.Select(x => x.Id).ToList();
|
||||
|
||||
private void AddServices()
|
||||
@@ -96,120 +99,89 @@ public sealed class Bot
|
||||
using (var uow = _db.GetDbContext())
|
||||
{
|
||||
uow.EnsureUserCreated(bot.Id, bot.Username, bot.Discriminator, bot.AvatarId);
|
||||
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
||||
AllGuildConfigs = uow.Set<GuildConfig>().GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
||||
}
|
||||
|
||||
var svcs = new ServiceCollection().AddTransient(_ => _credsProvider.GetCreds()) // bot creds
|
||||
.AddSingleton(_credsProvider)
|
||||
.AddSingleton(_db) // database
|
||||
.AddSingleton(Client) // discord socket client
|
||||
.AddSingleton(_commandService)
|
||||
// .AddSingleton(_interactionService)
|
||||
.AddSingleton(this)
|
||||
.AddSingleton<ISeria, JsonSeria>()
|
||||
.AddSingleton<IConfigSeria, YamlSeria>()
|
||||
.AddConfigServices()
|
||||
.AddConfigMigrators()
|
||||
.AddMemoryCache()
|
||||
// music
|
||||
.AddMusic()
|
||||
// cache
|
||||
.AddCache(_creds);
|
||||
// var svcs = new StandardKernel(new NinjectSettings()
|
||||
// {
|
||||
// // ThrowOnGetServiceNotFound = true,
|
||||
// ActivationCacheDisabled = true,
|
||||
// });
|
||||
|
||||
var svcs = new Container();
|
||||
|
||||
// this is required in order for medusa unloading to work
|
||||
// svcs.Components.Remove<IPlanner, Planner>();
|
||||
// svcs.Components.Add<IPlanner, RemovablePlanner>();
|
||||
|
||||
svcs.AddSingleton<IBotCredentials, IBotCredentials>(_ => _credsProvider.GetCreds());
|
||||
svcs.AddSingleton<DbService, DbService>(_db);
|
||||
svcs.AddSingleton<IBotCredsProvider>(_credsProvider);
|
||||
svcs.AddSingleton<DiscordSocketClient>(Client);
|
||||
svcs.AddSingleton<CommandService>(_commandService);
|
||||
svcs.AddSingleton<Bot>(this);
|
||||
svcs.AddSingleton<IBot>(this);
|
||||
|
||||
svcs.AddSingleton<ISeria, JsonSeria>();
|
||||
svcs.AddSingleton<IConfigSeria, YamlSeria>();
|
||||
svcs.AddSingleton<IMemoryCache, MemoryCache>(new MemoryCache(new MemoryCacheOptions()));
|
||||
svcs.AddSingleton<IBehaviorHandler, BehaviorHandler>();
|
||||
svcs.AddSingleton<ILocalization, Localization>();
|
||||
|
||||
|
||||
svcs.AddHttpClient();
|
||||
svcs.AddHttpClient("memelist")
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
|
||||
foreach (var a in _loadedAssemblies)
|
||||
{
|
||||
AllowAutoRedirect = false
|
||||
});
|
||||
svcs.AddConfigServices(a)
|
||||
.AddLifetimeServices(a);
|
||||
}
|
||||
|
||||
svcs.AddHttpClient("google:search")
|
||||
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler()
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
|
||||
});
|
||||
svcs.AddMusic()
|
||||
.AddCache(_creds)
|
||||
.AddHttpClients();
|
||||
|
||||
if (Environment.GetEnvironmentVariable("NADEKOBOT_IS_COORDINATED") != "1")
|
||||
{
|
||||
svcs.AddSingleton<ICoordinator, SingleProcessCoordinator>();
|
||||
}
|
||||
else
|
||||
{
|
||||
svcs.AddSingleton<RemoteGrpcCoordinator>()
|
||||
.AddSingleton<ICoordinator>(x => x.GetRequiredService<RemoteGrpcCoordinator>())
|
||||
.AddSingleton<IReadyExecutor>(x => x.GetRequiredService<RemoteGrpcCoordinator>());
|
||||
svcs.AddSingleton<RemoteGrpcCoordinator>();
|
||||
svcs.AddSingleton<ICoordinator>(_ => svcs.GetRequiredService<RemoteGrpcCoordinator>());
|
||||
svcs.AddSingleton<IReadyExecutor>(_ => svcs.GetRequiredService<RemoteGrpcCoordinator>());
|
||||
}
|
||||
|
||||
svcs.Scan(scan => scan.FromAssemblyOf<IReadyExecutor>()
|
||||
.AddClasses(classes => classes.AssignableToAny(
|
||||
// services
|
||||
typeof(INService),
|
||||
|
||||
// behaviours
|
||||
typeof(IExecOnMessage),
|
||||
typeof(IInputTransformer),
|
||||
typeof(IExecPreCommand),
|
||||
typeof(IExecPostCommand),
|
||||
typeof(IExecNoCommand))
|
||||
.WithoutAttribute<DontAddToIocContainerAttribute>()
|
||||
#if GLOBAL_NADEKO
|
||||
.WithoutAttribute<NoPublicBotAttribute>()
|
||||
#endif
|
||||
)
|
||||
.AsSelfWithInterfaces()
|
||||
.WithSingletonLifetime());
|
||||
svcs.AddSingleton<IServiceProvider>(svcs);
|
||||
|
||||
//initialize Services
|
||||
Services = svcs.BuildServiceProvider();
|
||||
Services = svcs;
|
||||
Services.GetRequiredService<IBehaviorHandler>().Initialize();
|
||||
Services.GetRequiredService<CurrencyRewardService>();
|
||||
|
||||
if (Client.ShardId == 0)
|
||||
ApplyConfigMigrations();
|
||||
|
||||
_ = LoadTypeReaders(typeof(Bot).Assembly);
|
||||
foreach (var a in _loadedAssemblies)
|
||||
{
|
||||
LoadTypeReaders(a);
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
Log.Information("All services loaded in {ServiceLoadTime:F2}s", sw.Elapsed.TotalSeconds);
|
||||
}
|
||||
|
||||
private void ApplyConfigMigrations()
|
||||
private void LoadTypeReaders(Assembly assembly)
|
||||
{
|
||||
// execute all migrators
|
||||
var migrators = Services.GetServices<IConfigMigrator>();
|
||||
foreach (var migrator in migrators)
|
||||
migrator.EnsureMigrated();
|
||||
}
|
||||
|
||||
private IEnumerable<object> LoadTypeReaders(Assembly assembly)
|
||||
{
|
||||
Type[] allTypes;
|
||||
try
|
||||
{
|
||||
allTypes = assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
Log.Warning(ex.LoaderExceptions[0], "Error getting types");
|
||||
return Enumerable.Empty<object>();
|
||||
}
|
||||
|
||||
var filteredTypes = allTypes.Where(x => x.IsSubclassOf(typeof(TypeReader))
|
||||
var filteredTypes = assembly.GetExportedTypes()
|
||||
.Where(x => x.IsSubclassOf(typeof(TypeReader))
|
||||
&& x.BaseType?.GetGenericArguments().Length > 0
|
||||
&& !x.IsAbstract);
|
||||
|
||||
var toReturn = new List<object>();
|
||||
foreach (var ft in filteredTypes)
|
||||
{
|
||||
var x = (TypeReader)ActivatorUtilities.CreateInstance(Services, ft);
|
||||
var baseType = ft.BaseType;
|
||||
if (baseType is null)
|
||||
continue;
|
||||
var typeArgs = baseType.GetGenericArguments();
|
||||
_commandService.AddTypeReader(typeArgs[0], x);
|
||||
toReturn.Add(x);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
var typeReader = (TypeReader)ActivatorUtilities.CreateInstance(Services, ft);
|
||||
var typeArgs = baseType.GetGenericArguments();
|
||||
_commandService.AddTypeReader(typeArgs[0], typeReader);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoginAsync(string token)
|
||||
@@ -291,7 +263,6 @@ public sealed class Bot
|
||||
|
||||
await LoginAsync(_creds.Token);
|
||||
|
||||
Mention = Client.CurrentUser.Mention;
|
||||
Log.Information("Shard {ShardId} loading services...", Client.ShardId);
|
||||
try
|
||||
{
|
||||
@@ -310,7 +281,11 @@ public sealed class Bot
|
||||
// start handling messages received in commandhandler
|
||||
await commandHandler.StartHandling();
|
||||
|
||||
await _commandService.AddModulesAsync(typeof(Bot).Assembly, Services);
|
||||
foreach (var a in _loadedAssemblies)
|
||||
{
|
||||
await _commandService.AddModulesAsync(a, Services);
|
||||
}
|
||||
|
||||
// await _interactionService.AddModulesAsync(typeof(Bot).Assembly, Services);
|
||||
IsReady = true;
|
||||
|
||||
@@ -364,7 +339,7 @@ public sealed class Bot
|
||||
|
||||
if (arg.Exception is { InnerException: WebSocketClosedException { CloseCode: 4014 } })
|
||||
{
|
||||
Log.Error(@"
|
||||
Log.Error("""
|
||||
Login failed.
|
||||
|
||||
*** Please enable privileged intents ***
|
||||
@@ -383,7 +358,8 @@ Read this only if your bot is in 100 or more servers:
|
||||
|
||||
You'll need to apply to use the intents with Discord, but for small selfhosts, all that is required is enabling the intents in the developer portal.
|
||||
Yes, this is a new thing from Discord, as of October 2020. No, there's nothing we can do about it. Yes, we're aware it worked before.
|
||||
While waiting for your bot to be accepted, you can change the 'usePrivilegedIntents' inside your creds.yml to 'false', although this will break many of the nadeko's features");
|
||||
While waiting for your bot to be accepted, you can change the 'usePrivilegedIntents' inside your creds.yml to 'false', although this will break many of the nadeko's features
|
||||
""");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
@@ -1,10 +0,0 @@
|
||||
namespace NadekoBot.Common.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public sealed class NadekoOptionsAttribute : Attribute
|
||||
{
|
||||
public Type OptionType { get; set; }
|
||||
|
||||
public NadekoOptionsAttribute(Type t)
|
||||
=> OptionType = t;
|
||||
}
|
@@ -1,185 +0,0 @@
|
||||
#nullable disable
|
||||
using Cloneable;
|
||||
using NadekoBot.Common.Yml;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System.Globalization;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace NadekoBot.Common.Configs;
|
||||
|
||||
[Cloneable]
|
||||
public sealed partial class BotConfig : ICloneable<BotConfig>
|
||||
{
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
public int Version { get; set; } = 5;
|
||||
|
||||
[Comment(@"Most commands, when executed, have a small colored line
|
||||
next to the response. The color depends whether the command
|
||||
is completed, errored or in progress (pending)
|
||||
Color settings below are for the color of those lines.
|
||||
To get color's hex, you can go here https://htmlcolorcodes.com/
|
||||
and copy the hex code fo your selected color (marked as #)")]
|
||||
public ColorConfig Color { get; set; }
|
||||
|
||||
[Comment("Default bot language. It has to be in the list of supported languages (.langli)")]
|
||||
public CultureInfo DefaultLocale { get; set; }
|
||||
|
||||
[Comment(@"Style in which executed commands will show up in the console.
|
||||
Allowed values: Simple, Normal, None")]
|
||||
public ConsoleOutputType ConsoleOutputType { get; set; }
|
||||
|
||||
[Comment(@"Whether the bot will check for new releases every hour")]
|
||||
public bool CheckForUpdates { get; set; } = true;
|
||||
|
||||
[Comment(@"Do you want any messages sent by users in Bot's DM to be forwarded to the owner(s)?")]
|
||||
public bool ForwardMessages { get; set; }
|
||||
|
||||
[Comment(
|
||||
@"Do you want the message to be forwarded only to the first owner specified in the list of owners (in creds.yml),
|
||||
or all owners? (this might cause the bot to lag if there's a lot of owners specified)")]
|
||||
public bool ForwardToAllOwners { get; set; }
|
||||
|
||||
[Comment(@"Any messages sent by users in Bot's DM to be forwarded to the specified channel.
|
||||
This option will only work when ForwardToAllOwners is set to false")]
|
||||
public ulong? ForwardToChannel { get; set; }
|
||||
|
||||
[Comment(@"When a user DMs the bot with a message which is not a command
|
||||
they will receive this message. Leave empty for no response. The string which will be sent whenever someone DMs the bot.
|
||||
Supports embeds. How it looks: https://puu.sh/B0BLV.png")]
|
||||
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
||||
public string DmHelpText { get; set; }
|
||||
|
||||
[Comment(@"Only users who send a DM to the bot containing one of the specified words will get a DmHelpText response.
|
||||
Case insensitive.
|
||||
Leave empty to reply with DmHelpText to every DM.")]
|
||||
public List<string> DmHelpTextKeywords { get; set; }
|
||||
|
||||
[Comment(@"This is the response for the .h command")]
|
||||
[YamlMember(ScalarStyle = ScalarStyle.Literal)]
|
||||
public string HelpText { get; set; }
|
||||
|
||||
[Comment(@"List of modules and commands completely blocked on the bot")]
|
||||
public BlockedConfig Blocked { get; set; }
|
||||
|
||||
[Comment(@"Which string will be used to recognize the commands")]
|
||||
public string Prefix { get; set; }
|
||||
|
||||
[Comment(@"Toggles whether your bot will group greet/bye messages into a single message every 5 seconds.
|
||||
1st user who joins will get greeted immediately
|
||||
If more users join within the next 5 seconds, they will be greeted in groups of 5.
|
||||
This will cause %user.mention% and other placeholders to be replaced with multiple users.
|
||||
Keep in mind this might break some of your embeds - for example if you have %user.avatar% in the thumbnail,
|
||||
it will become invalid, as it will resolve to a list of avatars of grouped users.
|
||||
note: This setting is primarily used if you're afraid of raids, or you're running medium/large bots where some
|
||||
servers might get hundreds of people join at once. This is used to prevent the bot from getting ratelimited,
|
||||
and (slightly) reduce the greet spam in those servers.")]
|
||||
public bool GroupGreets { get; set; }
|
||||
|
||||
[Comment(@"Whether the bot will rotate through all specified statuses.
|
||||
This setting can be changed via .ropl command.
|
||||
See RotatingStatuses submodule in Administration.")]
|
||||
public bool RotateStatuses { get; set; }
|
||||
|
||||
public BotConfig()
|
||||
{
|
||||
var color = new ColorConfig();
|
||||
Color = color;
|
||||
DefaultLocale = new("en-US");
|
||||
ConsoleOutputType = ConsoleOutputType.Normal;
|
||||
ForwardMessages = false;
|
||||
ForwardToAllOwners = false;
|
||||
DmHelpText = @"{""description"": ""Type `%prefix%h` for help.""}";
|
||||
HelpText = @"{
|
||||
""title"": ""To invite me to your server, use this link"",
|
||||
""description"": ""https://discordapp.com/oauth2/authorize?client_id={0}&scope=bot&permissions=66186303"",
|
||||
""color"": 53380,
|
||||
""thumbnail"": ""https://i.imgur.com/nKYyqMK.png"",
|
||||
""fields"": [
|
||||
{
|
||||
""name"": ""Useful help commands"",
|
||||
""value"": ""`%bot.prefix%modules` Lists all bot modules.
|
||||
`%prefix%h CommandName` Shows some help about a specific command.
|
||||
`%prefix%commands ModuleName` Lists all commands in a module."",
|
||||
""inline"": false
|
||||
},
|
||||
{
|
||||
""name"": ""List of all Commands"",
|
||||
""value"": ""https://nadeko.bot/commands"",
|
||||
""inline"": false
|
||||
},
|
||||
{
|
||||
""name"": ""Nadeko Support Server"",
|
||||
""value"": ""https://discord.nadeko.bot/ "",
|
||||
""inline"": true
|
||||
}
|
||||
]
|
||||
}";
|
||||
var blocked = new BlockedConfig();
|
||||
Blocked = blocked;
|
||||
Prefix = ".";
|
||||
RotateStatuses = false;
|
||||
GroupGreets = false;
|
||||
DmHelpTextKeywords = new()
|
||||
{
|
||||
"help",
|
||||
"commands",
|
||||
"cmds",
|
||||
"module",
|
||||
"can you do"
|
||||
};
|
||||
}
|
||||
|
||||
// [Comment(@"Whether the prefix will be a suffix, or prefix.
|
||||
// For example, if your prefix is ! you will run a command called 'cash' by typing either
|
||||
// '!cash @Someone' if your prefixIsSuffix: false or
|
||||
// 'cash @Someone!' if your prefixIsSuffix: true")]
|
||||
// public bool PrefixIsSuffix { get; set; }
|
||||
|
||||
// public string Prefixed(string text) => PrefixIsSuffix
|
||||
// ? text + Prefix
|
||||
// : Prefix + text;
|
||||
|
||||
public string Prefixed(string text)
|
||||
=> Prefix + text;
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public sealed partial class BlockedConfig
|
||||
{
|
||||
public HashSet<string> Commands { get; set; }
|
||||
public HashSet<string> Modules { get; set; }
|
||||
|
||||
public BlockedConfig()
|
||||
{
|
||||
Modules = new();
|
||||
Commands = new();
|
||||
}
|
||||
}
|
||||
|
||||
[Cloneable]
|
||||
public partial class ColorConfig
|
||||
{
|
||||
[Comment(@"Color used for embed responses when command successfully executes")]
|
||||
public Rgba32 Ok { get; set; }
|
||||
|
||||
[Comment(@"Color used for embed responses when command has an error")]
|
||||
public Rgba32 Error { get; set; }
|
||||
|
||||
[Comment(@"Color used for embed responses while command is doing work or is in progress")]
|
||||
public Rgba32 Pending { get; set; }
|
||||
|
||||
public ColorConfig()
|
||||
{
|
||||
Ok = Rgba32.ParseHex("00e584");
|
||||
Error = Rgba32.ParseHex("ee281f");
|
||||
Pending = Rgba32.ParseHex("faa61a");
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConsoleOutputType
|
||||
{
|
||||
Normal = 0,
|
||||
Simple = 1,
|
||||
None = 2
|
||||
}
|
@@ -1,240 +0,0 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Common.Yml;
|
||||
|
||||
namespace NadekoBot.Common;
|
||||
|
||||
public sealed class Creds : IBotCredentials
|
||||
{
|
||||
[Comment(@"DO NOT CHANGE")]
|
||||
public int Version { get; set; }
|
||||
|
||||
[Comment(@"Bot token. Do not share with anyone ever -> https://discordapp.com/developers/applications/")]
|
||||
public string Token { get; set; }
|
||||
|
||||
[Comment(@"List of Ids of the users who have bot owner permissions
|
||||
**DO NOT ADD PEOPLE YOU DON'T TRUST**")]
|
||||
public ICollection<ulong> OwnerIds { get; set; }
|
||||
|
||||
[Comment("Keep this on 'true' unless you're sure your bot shouldn't use privileged intents or you're waiting to be accepted")]
|
||||
public bool UsePrivilegedIntents { get; set; }
|
||||
|
||||
[Comment(@"The number of shards that the bot will be running on.
|
||||
Leave at 1 if you don't know what you're doing.
|
||||
|
||||
note: If you are planning to have more than one shard, then you must change botCache to 'redis'.
|
||||
Also, in that case you should be using NadekoBot.Coordinator to start the bot, and it will correctly override this value.")]
|
||||
public int TotalShards { get; set; }
|
||||
|
||||
[Comment(
|
||||
@"Login to https://console.cloud.google.com, create a new project, go to APIs & Services -> Library -> YouTube Data API and enable it.
|
||||
Then, go to APIs and Services -> Credentials and click Create credentials -> API key.
|
||||
Used only for Youtube Data Api (at the moment).")]
|
||||
public string GoogleApiKey { get; set; }
|
||||
|
||||
[Comment(
|
||||
@"Create a new custom search here https://programmablesearchengine.google.com/cse/create/new
|
||||
Enable SafeSearch
|
||||
Remove all Sites to Search
|
||||
Enable Search the entire web
|
||||
Copy the 'Search Engine ID' to the SearchId field
|
||||
|
||||
Do all steps again but enable image search for the ImageSearchId")]
|
||||
public GoogleApiConfig Google { get; set; }
|
||||
|
||||
[Comment(@"Settings for voting system for discordbots. Meant for use on global Nadeko.")]
|
||||
public VotesSettings Votes { get; set; }
|
||||
|
||||
[Comment(@"Patreon auto reward system settings.
|
||||
go to https://www.patreon.com/portal -> my clients -> create client")]
|
||||
public PatreonSettings Patreon { get; set; }
|
||||
|
||||
[Comment(@"Api key for sending stats to DiscordBotList.")]
|
||||
public string BotListToken { get; set; }
|
||||
|
||||
[Comment(@"Official cleverbot api key.")]
|
||||
public string CleverbotApiKey { get; set; }
|
||||
|
||||
[Comment(@"Official GPT-3 api key.")]
|
||||
public string Gpt3ApiKey { get; set; }
|
||||
|
||||
[Comment(@"Which cache implementation should bot use.
|
||||
'memory' - Cache will be in memory of the bot's process itself. Only use this on bots with a single shard. When the bot is restarted the cache is reset.
|
||||
'redis' - Uses redis (which needs to be separately downloaded and installed). The cache will persist through bot restarts. You can configure connection string in creds.yml")]
|
||||
public BotCacheImplemenation BotCache { get; set; }
|
||||
|
||||
[Comment(@"Redis connection string. Don't change if you don't know what you're doing.
|
||||
Only used if botCache is set to 'redis'")]
|
||||
public string RedisOptions { get; set; }
|
||||
|
||||
[Comment(@"Database options. Don't change if you don't know what you're doing. Leave null for default values")]
|
||||
public DbOptions Db { get; set; }
|
||||
|
||||
[Comment(@"Address and port of the coordinator endpoint. Leave empty for default.
|
||||
Change only if you've changed the coordinator address or port.")]
|
||||
public string CoordinatorUrl { get; set; }
|
||||
|
||||
[Comment(
|
||||
@"Api key obtained on https://rapidapi.com (go to MyApps -> Add New App -> Enter Name -> Application key)")]
|
||||
public string RapidApiKey { get; set; }
|
||||
|
||||
[Comment(@"https://locationiq.com api key (register and you will receive the token in the email).
|
||||
Used only for .time command.")]
|
||||
public string LocationIqApiKey { get; set; }
|
||||
|
||||
[Comment(@"https://timezonedb.com api key (register and you will receive the token in the email).
|
||||
Used only for .time command")]
|
||||
public string TimezoneDbApiKey { get; set; }
|
||||
|
||||
[Comment(@"https://pro.coinmarketcap.com/account/ api key. There is a free plan for personal use.
|
||||
Used for cryptocurrency related commands.")]
|
||||
public string CoinmarketcapApiKey { get; set; }
|
||||
|
||||
// [Comment(@"https://polygon.io/dashboard/api-keys api key. Free plan allows for 5 queries per minute.
|
||||
// Used for stocks related commands.")]
|
||||
// public string PolygonIoApiKey { get; set; }
|
||||
|
||||
[Comment(@"Api key used for Osu related commands. Obtain this key at https://osu.ppy.sh/p/api")]
|
||||
public string OsuApiKey { get; set; }
|
||||
|
||||
[Comment(@"Optional Trovo client id.
|
||||
You should use this if Trovo stream notifications stopped working or you're getting ratelimit errors.")]
|
||||
public string TrovoClientId { get; set; }
|
||||
|
||||
[Comment(@"Obtain by creating an application at https://dev.twitch.tv/console/apps")]
|
||||
public string TwitchClientId { get; set; }
|
||||
|
||||
[Comment(@"Obtain by creating an application at https://dev.twitch.tv/console/apps")]
|
||||
public string TwitchClientSecret { get; set; }
|
||||
|
||||
[Comment(@"Command and args which will be used to restart the bot.
|
||||
Only used if bot is executed directly (NOT through the coordinator)
|
||||
placeholders:
|
||||
{0} -> shard id
|
||||
{1} -> total shards
|
||||
Linux default
|
||||
cmd: dotnet
|
||||
args: ""NadekoBot.dll -- {0}""
|
||||
Windows default
|
||||
cmd: NadekoBot.exe
|
||||
args: ""{0}""")]
|
||||
public RestartConfig RestartCommand { get; set; }
|
||||
|
||||
public Creds()
|
||||
{
|
||||
Version = 7;
|
||||
Token = string.Empty;
|
||||
UsePrivilegedIntents = true;
|
||||
OwnerIds = new List<ulong>();
|
||||
TotalShards = 1;
|
||||
GoogleApiKey = string.Empty;
|
||||
Votes = new(string.Empty, string.Empty, string.Empty, string.Empty);
|
||||
Patreon = new(string.Empty, string.Empty, string.Empty, string.Empty);
|
||||
BotListToken = string.Empty;
|
||||
CleverbotApiKey = string.Empty;
|
||||
Gpt3ApiKey = string.Empty;
|
||||
BotCache = BotCacheImplemenation.Memory;
|
||||
RedisOptions = "localhost:6379,syncTimeout=30000,responseTimeout=30000,allowAdmin=true,password=";
|
||||
Db = new()
|
||||
{
|
||||
Type = "sqlite",
|
||||
ConnectionString = "Data Source=data/NadekoBot.db"
|
||||
};
|
||||
|
||||
CoordinatorUrl = "http://localhost:3442";
|
||||
|
||||
RestartCommand = new();
|
||||
Google = new();
|
||||
}
|
||||
|
||||
|
||||
public class DbOptions
|
||||
{
|
||||
[Comment(@"Database type. ""sqlite"", ""mysql"" and ""postgresql"" are supported.
|
||||
Default is ""sqlite""")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[Comment(@"Database connection string.
|
||||
You MUST change this if you're not using ""sqlite"" type.
|
||||
Default is ""Data Source=data/NadekoBot.db""
|
||||
Example for mysql: ""Server=localhost;Port=3306;Uid=root;Pwd=my_super_secret_mysql_password;Database=nadeko""
|
||||
Example for postgresql: ""Server=localhost;Port=5432;User Id=postgres;Password=my_super_secret_postgres_password;Database=nadeko;""")]
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
|
||||
public sealed record PatreonSettings
|
||||
{
|
||||
public string ClientId { get; set; }
|
||||
public string AccessToken { get; set; }
|
||||
public string RefreshToken { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
|
||||
[Comment(
|
||||
@"Campaign ID of your patreon page. Go to your patreon page (make sure you're logged in) and type ""prompt('Campaign ID', window.patreon.bootstrap.creator.data.id);"" in the console. (ctrl + shift + i)")]
|
||||
public string CampaignId { get; set; }
|
||||
|
||||
public PatreonSettings(
|
||||
string accessToken,
|
||||
string refreshToken,
|
||||
string clientSecret,
|
||||
string campaignId)
|
||||
{
|
||||
AccessToken = accessToken;
|
||||
RefreshToken = refreshToken;
|
||||
ClientSecret = clientSecret;
|
||||
CampaignId = campaignId;
|
||||
}
|
||||
|
||||
public PatreonSettings()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed record VotesSettings
|
||||
{
|
||||
[Comment(@"top.gg votes service url
|
||||
This is the url of your instance of the NadekoBot.Votes api
|
||||
Example: https://votes.my.cool.bot.com")]
|
||||
public string TopggServiceUrl { get; set; }
|
||||
|
||||
[Comment(@"Authorization header value sent to the TopGG service url with each request
|
||||
This should be equivalent to the TopggKey in your NadekoBot.Votes api appsettings.json file")]
|
||||
public string TopggKey { get; set; }
|
||||
|
||||
[Comment(@"discords.com votes service url
|
||||
This is the url of your instance of the NadekoBot.Votes api
|
||||
Example: https://votes.my.cool.bot.com")]
|
||||
public string DiscordsServiceUrl { get; set; }
|
||||
|
||||
[Comment(@"Authorization header value sent to the Discords service url with each request
|
||||
This should be equivalent to the DiscordsKey in your NadekoBot.Votes api appsettings.json file")]
|
||||
public string DiscordsKey { get; set; }
|
||||
|
||||
public VotesSettings()
|
||||
{
|
||||
}
|
||||
|
||||
public VotesSettings(
|
||||
string topggServiceUrl,
|
||||
string topggKey,
|
||||
string discordsServiceUrl,
|
||||
string discordsKey)
|
||||
{
|
||||
TopggServiceUrl = topggServiceUrl;
|
||||
TopggKey = topggKey;
|
||||
DiscordsServiceUrl = discordsServiceUrl;
|
||||
DiscordsKey = discordsKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GoogleApiConfig
|
||||
{
|
||||
public string SearchId { get; init; }
|
||||
public string ImageSearchId { get; init; }
|
||||
}
|
||||
|
||||
public enum BotCacheImplemenation
|
||||
{
|
||||
Memory,
|
||||
Redis
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
namespace NadekoBot;
|
||||
|
||||
public class SimpleInteraction<T>
|
||||
{
|
||||
public ButtonBuilder Button { get; }
|
||||
private readonly Func<SocketMessageComponent, T, Task> _onClick;
|
||||
private readonly T? _state;
|
||||
|
||||
public SimpleInteraction(ButtonBuilder button, Func<SocketMessageComponent, T?, Task> onClick, T? state = default)
|
||||
{
|
||||
Button = button;
|
||||
_onClick = onClick;
|
||||
_state = state;
|
||||
}
|
||||
|
||||
public async Task TriggerAsync(SocketMessageComponent smc)
|
||||
{
|
||||
await _onClick(smc, _state!);
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
|
||||
namespace Nadeko.Medusa;
|
||||
|
||||
public sealed class MedusaAssemblyLoadContext : AssemblyLoadContext
|
||||
{
|
||||
private readonly AssemblyDependencyResolver _depResolver;
|
||||
|
||||
public MedusaAssemblyLoadContext(string pluginPath) : base(isCollectible: true)
|
||||
{
|
||||
_depResolver = new(pluginPath);
|
||||
}
|
||||
|
||||
protected override Assembly? Load(AssemblyName assemblyName)
|
||||
{
|
||||
var assemblyPath = _depResolver.ResolveAssemblyToPath(assemblyName);
|
||||
if (assemblyPath != null)
|
||||
{
|
||||
return LoadFromAssemblyPath(assemblyPath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
|
||||
{
|
||||
var libraryPath = _depResolver.ResolveUnmanagedDllToPath(unmanagedDllName);
|
||||
if (libraryPath != null)
|
||||
{
|
||||
return LoadUnmanagedDllFromPath(libraryPath);
|
||||
}
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Nadeko.Medusa;
|
||||
|
||||
public class MedusaServiceProvider : IServiceProvider
|
||||
{
|
||||
private readonly IServiceProvider _nadekoServices;
|
||||
private readonly IServiceProvider _medusaServices;
|
||||
|
||||
public MedusaServiceProvider(IServiceProvider nadekoServices, IServiceProvider medusaServices)
|
||||
{
|
||||
_nadekoServices = nadekoServices;
|
||||
_medusaServices = medusaServices;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public object? GetService(Type serviceType)
|
||||
{
|
||||
if (!serviceType.Assembly.IsCollectible)
|
||||
return _nadekoServices.GetService(serviceType);
|
||||
|
||||
return _medusaServices.GetService(serviceType);
|
||||
}
|
||||
}
|
@@ -1,164 +0,0 @@
|
||||
#nullable disable
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace NadekoBot.Common;
|
||||
|
||||
public class ReplacementBuilder
|
||||
{
|
||||
private static readonly Regex _rngRegex = new("%rng(?:(?<from>(?:-)?\\d+)-(?<to>(?:-)?\\d+))?%",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
private readonly ConcurrentDictionary<Regex, Func<Match, string>> _regex = new();
|
||||
|
||||
private readonly ConcurrentDictionary<string, Func<string>> _reps = new();
|
||||
|
||||
public ReplacementBuilder()
|
||||
=> WithRngRegex();
|
||||
|
||||
public ReplacementBuilder WithDefault(
|
||||
IUser usr,
|
||||
IMessageChannel ch,
|
||||
SocketGuild g,
|
||||
DiscordSocketClient client)
|
||||
=> WithUser(usr).WithChannel(ch).WithServer(client, g).WithClient(client);
|
||||
|
||||
public ReplacementBuilder WithDefault(ICommandContext ctx)
|
||||
=> WithDefault(ctx.User, ctx.Channel, ctx.Guild as SocketGuild, (DiscordSocketClient)ctx.Client);
|
||||
|
||||
public ReplacementBuilder WithMention(DiscordSocketClient client)
|
||||
{
|
||||
_reps.TryAdd("%bot.mention%", () => client.CurrentUser.Mention);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithClient(DiscordSocketClient client)
|
||||
{
|
||||
WithMention(client);
|
||||
|
||||
_reps.TryAdd("%bot.status%", () => client.Status.ToString());
|
||||
_reps.TryAdd("%bot.latency%", () => client.Latency.ToString());
|
||||
_reps.TryAdd("%bot.name%", () => client.CurrentUser.Username);
|
||||
_reps.TryAdd("%bot.fullname%", () => client.CurrentUser.ToString());
|
||||
_reps.TryAdd("%bot.time%",
|
||||
() => DateTime.Now.ToString("HH:mm " + TimeZoneInfo.Local.StandardName.GetInitials()));
|
||||
_reps.TryAdd("%bot.discrim%", () => client.CurrentUser.Discriminator);
|
||||
_reps.TryAdd("%bot.id%", () => client.CurrentUser.Id.ToString());
|
||||
_reps.TryAdd("%bot.avatar%", () => client.CurrentUser.RealAvatarUrl().ToString());
|
||||
|
||||
WithStats(client);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithServer(DiscordSocketClient client, SocketGuild g)
|
||||
{
|
||||
_reps.TryAdd("%server%", () => g is null ? "DM" : g.Name);
|
||||
_reps.TryAdd("%server.id%", () => g is null ? "DM" : g.Id.ToString());
|
||||
_reps.TryAdd("%server.name%", () => g is null ? "DM" : g.Name);
|
||||
_reps.TryAdd("%server.icon%", () => g is null ? null : g.IconUrl);
|
||||
_reps.TryAdd("%server.members%", () => g is { } sg ? sg.MemberCount.ToString() : "?");
|
||||
_reps.TryAdd("%server.boosters%", () => g.PremiumSubscriptionCount.ToString());
|
||||
_reps.TryAdd("%server.boost_level%", () => ((int)g.PremiumTier).ToString());
|
||||
_reps.TryAdd("%server.time%",
|
||||
() =>
|
||||
{
|
||||
var to = TimeZoneInfo.Local;
|
||||
if (g is not null)
|
||||
{
|
||||
if (GuildTimezoneService.AllServices.TryGetValue(client.CurrentUser.Id, out var tz))
|
||||
to = tz.GetTimeZoneOrDefault(g.Id) ?? TimeZoneInfo.Local;
|
||||
}
|
||||
|
||||
return TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Utc, to).ToString("HH:mm ")
|
||||
+ to.StandardName.GetInitials();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithChannel(IMessageChannel ch)
|
||||
{
|
||||
_reps.TryAdd("%channel%", () => ch.Name);
|
||||
_reps.TryAdd("%channel.mention%", () => (ch as ITextChannel)?.Mention ?? "#" + ch.Name);
|
||||
_reps.TryAdd("%channel.name%", () => ch.Name);
|
||||
_reps.TryAdd("%channel.id%", () => ch.Id.ToString());
|
||||
_reps.TryAdd("%channel.created%", () => ch.CreatedAt.ToString("HH:mm dd.MM.yyyy"));
|
||||
_reps.TryAdd("%channel.nsfw%", () => (ch as ITextChannel)?.IsNsfw.ToString() ?? "-");
|
||||
_reps.TryAdd("%channel.topic%", () => (ch as ITextChannel)?.Topic ?? "-");
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithUser(IUser user)
|
||||
{
|
||||
WithManyUsers(new[] { user });
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithManyUsers(IEnumerable<IUser> users)
|
||||
{
|
||||
_reps.TryAdd("%user%", () => string.Join(" ", users.Select(user => user.Mention)));
|
||||
_reps.TryAdd("%user.mention%", () => string.Join(" ", users.Select(user => user.Mention)));
|
||||
_reps.TryAdd("%user.fullname%", () => string.Join(" ", users.Select(user => user.ToString())));
|
||||
_reps.TryAdd("%user.name%", () => string.Join(" ", users.Select(user => user.Username)));
|
||||
_reps.TryAdd("%user.discrim%", () => string.Join(" ", users.Select(user => user.Discriminator)));
|
||||
_reps.TryAdd("%user.avatar%", () => string.Join(" ", users.Select(user => user.RealAvatarUrl().ToString())));
|
||||
_reps.TryAdd("%user.id%", () => string.Join(" ", users.Select(user => user.Id.ToString())));
|
||||
_reps.TryAdd("%user.created_time%",
|
||||
() => string.Join(" ", users.Select(user => user.CreatedAt.ToString("HH:mm"))));
|
||||
_reps.TryAdd("%user.created_date%",
|
||||
() => string.Join(" ", users.Select(user => user.CreatedAt.ToString("dd.MM.yyyy"))));
|
||||
_reps.TryAdd("%user.joined_time%",
|
||||
() => string.Join(" ", users.Select(user => (user as IGuildUser)?.JoinedAt?.ToString("HH:mm") ?? "-")));
|
||||
_reps.TryAdd("%user.joined_date%",
|
||||
() => string.Join(" ",
|
||||
users.Select(user => (user as IGuildUser)?.JoinedAt?.ToString("dd.MM.yyyy") ?? "-")));
|
||||
return this;
|
||||
}
|
||||
|
||||
private ReplacementBuilder WithStats(DiscordSocketClient c)
|
||||
{
|
||||
_reps.TryAdd("%shard.servercount%", () => c.Guilds.Count.ToString());
|
||||
_reps.TryAdd("%shard.usercount%", () => c.Guilds.Sum(g => g.MemberCount).ToString());
|
||||
_reps.TryAdd("%shard.id%", () => c.ShardId.ToString());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithRngRegex()
|
||||
{
|
||||
var rng = new NadekoRandom();
|
||||
_regex.TryAdd(_rngRegex,
|
||||
match =>
|
||||
{
|
||||
if (!int.TryParse(match.Groups["from"].ToString(), out var from))
|
||||
from = 0;
|
||||
if (!int.TryParse(match.Groups["to"].ToString(), out var to))
|
||||
to = 0;
|
||||
|
||||
if (from == 0 && to == 0)
|
||||
return rng.Next(0, 11).ToString();
|
||||
|
||||
if (from >= to)
|
||||
return string.Empty;
|
||||
|
||||
return rng.Next(from, to + 1).ToString();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementBuilder WithOverride(string key, Func<string> output)
|
||||
{
|
||||
_reps.AddOrUpdate(key, output, delegate { return output; });
|
||||
return this;
|
||||
}
|
||||
|
||||
public Replacer Build()
|
||||
=> new(_reps.Select(x => (x.Key, x.Value)).ToArray(), _regex.Select(x => (x.Key, x.Value)).ToArray());
|
||||
|
||||
public ReplacementBuilder WithProviders(IEnumerable<IPlaceholderProvider> phProviders)
|
||||
{
|
||||
foreach (var provider in phProviders)
|
||||
foreach (var ovr in provider.GetPlaceholders())
|
||||
_reps.TryAdd(ovr.Name, ovr.Func);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
@@ -1,94 +0,0 @@
|
||||
#nullable disable
|
||||
using System.Text.RegularExpressions;
|
||||
using Nadeko.Common;
|
||||
|
||||
namespace NadekoBot.Common;
|
||||
|
||||
public class Replacer
|
||||
{
|
||||
private readonly IEnumerable<(Regex Regex, Func<Match, string> Replacement)> _regex;
|
||||
private readonly IEnumerable<(string Key, Func<string> Text)> _replacements;
|
||||
|
||||
public Replacer(IEnumerable<(string, Func<string>)> replacements, IEnumerable<(Regex, Func<Match, string>)> regex)
|
||||
{
|
||||
_replacements = replacements;
|
||||
_regex = regex;
|
||||
}
|
||||
|
||||
public string Replace(string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return input;
|
||||
|
||||
foreach (var (key, text) in _replacements)
|
||||
{
|
||||
if (input.Contains(key))
|
||||
input = input.Replace(key, text(), StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
foreach (var item in _regex)
|
||||
input = item.Regex.Replace(input, m => item.Replacement(m));
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
public SmartText Replace(SmartText data)
|
||||
=> data switch
|
||||
{
|
||||
SmartEmbedText embedData => Replace(embedData) with
|
||||
{
|
||||
PlainText = Replace(embedData.PlainText),
|
||||
Color = embedData.Color
|
||||
},
|
||||
SmartPlainText plain => Replace(plain),
|
||||
SmartEmbedTextArray arr => Replace(arr),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(data), "Unsupported argument type")
|
||||
};
|
||||
|
||||
private SmartEmbedTextArray Replace(SmartEmbedTextArray embedArr)
|
||||
=> new()
|
||||
{
|
||||
Embeds = embedArr.Embeds.Map(e => Replace(e) with
|
||||
{
|
||||
Color = e.Color
|
||||
}),
|
||||
Content = Replace(embedArr.Content)
|
||||
};
|
||||
|
||||
private SmartPlainText Replace(SmartPlainText plain)
|
||||
=> Replace(plain.Text);
|
||||
|
||||
private T Replace<T>(T embedData) where T: SmartEmbedTextBase, new()
|
||||
{
|
||||
var newEmbedData = new T
|
||||
{
|
||||
Description = Replace(embedData.Description),
|
||||
Title = Replace(embedData.Title),
|
||||
Thumbnail = Replace(embedData.Thumbnail),
|
||||
Image = Replace(embedData.Image),
|
||||
Url = Replace(embedData.Url),
|
||||
Author = embedData.Author is null
|
||||
? null
|
||||
: new()
|
||||
{
|
||||
Name = Replace(embedData.Author.Name),
|
||||
IconUrl = Replace(embedData.Author.IconUrl)
|
||||
},
|
||||
Fields = embedData.Fields?.Map(f => new SmartTextEmbedField
|
||||
{
|
||||
Name = Replace(f.Name),
|
||||
Value = Replace(f.Value),
|
||||
Inline = f.Inline
|
||||
}),
|
||||
Footer = embedData.Footer is null
|
||||
? null
|
||||
: new()
|
||||
{
|
||||
Text = Replace(embedData.Footer.Text),
|
||||
IconUrl = Replace(embedData.Footer.IconUrl)
|
||||
}
|
||||
};
|
||||
|
||||
return newEmbedData;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user