Compare commits

202 Commits
Author SHA1 Message Date
renovate-bot f2d3eddc82 Update docker/login-action digest to 4907a6d
CI / Package (pull_request) Successful in 42s
CI / Docker Build and Push (main) (pull_request) Has been skipped
CI / Docker Build and Push (release) (pull_request) Has been skipped
2026-05-13 04:02:30 +00:00
anthorob ad77cf630e update Maven dependencies
CI / Package (push) Successful in 1m7s
CI / Docker Build and Push (main) (push) Successful in 41s
CI / Docker Build and Push (release) (push) Has been skipped
2026-05-12 23:37:18 -04:00
anthorob 62fc2097c2 enable Maven cache in CI workflow
CI / Package (push) Successful in 2m0s
CI / Docker Build and Push (main) (push) Successful in 2m18s
CI / Docker Build and Push (release) (push) Has been skipped
2026-04-01 11:45:00 -04:00
anthorob b96e5b2880 Merge pull request 'chore(deps): pin dependencies' (#12) from renovate/pin-dependencies into main
CI / Package (push) Successful in 1m3s
CI / Docker Build and Push (main) (push) Successful in 2m17s
CI / Docker Build and Push (release) (push) Has been skipped
Reviewed-on: #12
2026-03-18 07:02:27 -04:00
renovate-bot b3bd6a45fe chore(deps): pin dependencies
CI / Package (pull_request) Successful in 2m7s
CI / Docker Build and Push (main) (pull_request) Has been skipped
CI / Docker Build and Push (release) (pull_request) Has been skipped
2026-03-18 10:56:02 +00:00
anthorob 83e618c6a3 fix workflow
CI / Package (push) Successful in 1m1s
CI / Docker Build and Push (main) (push) Successful in 41s
CI / Docker Build and Push (release) (push) Has been skipped
2026-03-18 06:46:21 -04:00
anthorob 078c540327 fix workflow
CI / Package (push) Successful in 1m6s
CI / Docker Build and Push (main) (push) Failing after 1m54s
CI / Docker Build and Push (release) (push) Has been skipped
2026-03-18 06:42:10 -04:00
anthorob e021a713b2 fix workflow
CI / Package (push) Failing after 1m14s
CI / Docker Build and Push (main) (push) Has been skipped
CI / Docker Build and Push (release) (push) Has been skipped
2026-03-18 06:38:29 -04:00
anthorob 91aaafeb40 fix workflow
CI / Docker Build and Push (main) (push) Has been cancelled
CI / Docker Build and Push (release) (push) Has been cancelled
CI / Package (push) Has been cancelled
2026-03-18 06:25:16 -04:00
anthorob 99457b40fc fix maven cache in workflow
CI / Package (push) Has been cancelled
CI / Docker Build and Push (main) (push) Has been cancelled
CI / Docker Build and Push (release) (push) Has been cancelled
2026-03-18 06:23:33 -04:00
anthorob 78a359ba09 fix maven cache in workflow
CI / Test (push) Has been cancelled
CI / Package (push) Has been cancelled
CI / Docker Build and Push (main) (push) Has been cancelled
CI / Docker Build and Push (release) (push) Has been cancelled
CI / Compile (push) Has been cancelled
2026-03-18 06:02:44 -04:00
anthorob 2a4dc09a9e switch to gitea worflow
CI / Test (push) Has been cancelled
CI / Package (push) Has been cancelled
CI / Docker Build and Push (main) (push) Has been cancelled
CI / Docker Build and Push (release) (push) Has been cancelled
CI / Compile (push) Has been cancelled
2026-03-18 05:38:47 -04:00
anthorob c442619531 remove harcoded html tag, parses next chunks to find track 2026-03-15 01:41:18 -04:00
anthorob d6fa27923b add compose override to gitignore 2026-03-09 05:07:53 -04:00
anthorob ec8cccf5e5 Merge branch 'renovate/pin-dependencies' into 'main'
chore(deps): pin dependencies

See merge request anthorob/netneutrality!116
2026-03-09 07:51:00 +00:00
Renovate Bot 7ca6215f47 chore(deps): pin dependencies 2026-03-09 07:49:18 +00:00
anthorob 82f6ea4f4d Merge branch '15-job-failed-8956' into 'main'
Resolve "Job Failed #8956"

Closes #15

See merge request anthorob/netneutrality!118
2026-03-09 07:30:25 +00:00
anthorob 1a0434ffed Resolve "Job Failed #8956" 2026-03-09 07:30:25 +00:00
anthorob 25a5df0743 improve ci 2026-03-09 03:06:16 -04:00
anthorob d8bd5ecfdb switch to ubuntu for runtime 2026-03-04 00:14:20 -05:00
anthorob 8101a02807 Merge branch '14-move-to-java-25-and-use-jdave' into 'main'
move to jdk 25

Closes #14

See merge request anthorob/netneutrality!115
2026-03-04 04:57:53 +00:00
anthorob d3da68f4d4 move to jdk 25 2026-03-04 04:57:53 +00:00
anthorob 03a1920ccb Merge branch 'renovate/mariadb-11' into 'main'
chore(deps): update mariadb:11 docker digest to 1cac849

See merge request anthorob/netneutrality!104
2025-12-19 09:32:56 +00:00
Renovate 4d753f3ddf chore(deps): update mariadb:11 docker digest to 1cac849 2025-12-19 09:32:56 +00:00
anthorob 71563abaf2 Merge branch 'renovate/net.dv8tion-jda-6.x' into 'main'
fix(deps): update dependency net.dv8tion:jda to v6

See merge request anthorob/netneutrality!97
2025-12-19 09:02:07 +00:00
Renovate 2c96f8ce85 fix(deps): update dependency net.dv8tion:jda to v6 2025-12-19 09:02:07 +00:00
anthorob cecd7baf3f Merge branch 'renovate/major-hibernate-orm' into 'main'
fix(deps): update hibernate orm to v7 (major)

See merge request anthorob/netneutrality!99
2025-11-22 07:36:00 +00:00
Renovate e35f739cf9 fix(deps): update hibernate orm to v7 (major) 2025-11-22 07:36:00 +00:00
anthorob f32968c0b5 Merge branch 'renovate/org.apache.maven.plugins-maven-jar-plugin-3.x' into 'main'
chore(deps): update dependency org.apache.maven.plugins:maven-jar-plugin to v3.5.0

See merge request anthorob/netneutrality!105
2025-11-22 06:58:20 +00:00
anthorob c13b731cd5 Merge branch 'renovate/org.gitlab4j-gitlab4j-api-6.x' into 'main'
fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.2.0

See merge request anthorob/netneutrality!100
2025-11-22 06:37:35 +00:00
Renovate Bot 4be5be2a47 chore(deps): update dependency org.apache.maven.plugins:maven-jar-plugin to v3.5.0 2025-11-15 09:04:20 +00:00
anthorob 3d0c4a169e Merge branch 'renovate/dev.lavalink.youtube-v2-1.x' into 'main'
fix(deps): update dependency dev.lavalink.youtube:v2 to v1.16.0

See merge request anthorob/netneutrality!93
2025-11-14 17:45:54 +00:00
Renovate e8c331fa63 fix(deps): update dependency dev.lavalink.youtube:v2 to v1.16.0 2025-11-14 17:45:54 +00:00
anthorob 303dc594b7 Merge branch 'renovate/quay.io-buildah-stable' into 'main'
chore(deps): update quay.io/buildah/stable docker digest to dd77a04

See merge request anthorob/netneutrality!102
2025-11-14 17:41:42 +00:00
Renovate Bot 3d9c25e637 chore(deps): update quay.io/buildah/stable docker digest to dd77a04 2025-11-14 16:34:27 +00:00
anthorob a4eb81d7de Merge branch 'renovate/pin-dependencies' into 'main'
chore(deps): pin ghcr.io/kikkia/yt-cipher docker tag to 4fbb0d9

See merge request anthorob/netneutrality!86
2025-11-12 12:18:32 +00:00
anthorob 9c34f3a4f4 Merge branch 'renovate/mariadb-11' into 'main'
chore(deps): update mariadb:11 docker digest to 404ebf2

See merge request anthorob/netneutrality!95
2025-11-12 12:15:49 +00:00
anthorob 7ef68cf968 Merge branch 'renovate/quay.io-buildah-stable' into 'main'
chore(deps): update quay.io/buildah/stable docker digest to 428cc6a

See merge request anthorob/netneutrality!87
2025-11-12 12:15:32 +00:00
anthorob 0224ba67fe Merge branch 'renovate/org.json-json-20250517.x' into 'main'
fix(deps): update dependency org.json:json to v20250517

See merge request anthorob/netneutrality!98
2025-11-12 12:15:11 +00:00
Renovate Bot 1c5afca21c fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.2.0 2025-11-11 17:04:10 +00:00
Renovate Bot 8c0062f31f chore(deps): update quay.io/buildah/stable docker digest to 428cc6a 2025-11-11 16:34:08 +00:00
Renovate Bot 2027ae296c fix(deps): update dependency org.json:json to v20250517 2025-11-11 04:04:20 +00:00
anthorob 3c50feb597 Merge branch 'renovate/com.mysql-mysql-connector-j-9.x' into 'main'
fix(deps): update dependency com.mysql:mysql-connector-j to v9.5.0

See merge request anthorob/netneutrality!90
2025-11-11 02:21:54 +00:00
anthorob c3f5807cea Merge branch 'renovate/okhttp-monorepo' into 'main'
fix(deps): update dependency com.squareup.okhttp3:okhttp-jvm to v5.3.0

See merge request anthorob/netneutrality!91
2025-11-11 02:21:18 +00:00
anthorob 6e8da65580 Merge branch 'renovate/hibernate-orm' into 'main'
fix(deps): update hibernate orm to v6.6.34.final

See merge request anthorob/netneutrality!89
2025-11-11 02:20:31 +00:00
anthorob 13b2f61261 Merge branch 'renovate/apache-commons' into 'main'
fix(deps): update dependency commons-io:commons-io to v2.21.0

See merge request anthorob/netneutrality!92
2025-11-11 02:20:02 +00:00
anthorob 6271e218cd Merge branch 'renovate/io.sentry-sentry-8.x' into 'main'
fix(deps): update dependency io.sentry:sentry to v8.25.0

See merge request anthorob/netneutrality!94
2025-11-11 02:19:19 +00:00
Renovate Bot 6f4977b466 chore(deps): update mariadb:11 docker digest to 404ebf2 2025-11-11 02:04:33 +00:00
anthorob f691fcd2ee Merge branch 'renovate/org.junit.jupiter-junit-jupiter-6.x' into 'main'
chore(deps): update dependency org.junit.jupiter:junit-jupiter to v6.0.1

See merge request anthorob/netneutrality!88
2025-11-11 02:02:48 +00:00
anthorob d03b02c9f9 Edit renovate.json 2025-11-11 01:28:49 +00:00
Renovate Bot db7be88f13 fix(deps): update dependency io.sentry:sentry to v8.25.0 2025-11-10 16:13:33 +00:00
Renovate Bot 2b3ca9ae18 fix(deps): update dependency commons-io:commons-io to v2.21.0 2025-11-10 16:04:33 +00:00
Renovate Bot d555a3144d fix(deps): update dependency com.squareup.okhttp3:okhttp-jvm to v5.3.0 2025-11-10 09:34:53 +00:00
Renovate Bot 60d50d99bc fix(deps): update dependency com.mysql:mysql-connector-j to v9.5.0 2025-11-10 09:34:49 +00:00
Renovate Bot a54f20e990 fix(deps): update hibernate orm to v6.6.34.final 2025-11-03 09:34:32 +00:00
Renovate Bot fac0aedc5e chore(deps): update dependency org.junit.jupiter:junit-jupiter to v6.0.1 2025-11-03 09:34:28 +00:00
Renovate Bot 0a693f4bc3 chore(deps): pin ghcr.io/kikkia/yt-cipher docker tag to 4fbb0d9 2025-11-03 09:34:25 +00:00
anthorob 8fa6de233e Merge branch 'command-processor-testing' into 'main'
Command processor testing

See merge request anthorob/netneutrality!85
2025-10-27 07:08:56 +00:00
anthorob 6fc3dc9577 Command processor testing 2025-10-27 07:08:56 +00:00
anthorob c19287d580 Merge branch 'renovate/dev.lavalink.youtube-v2-1.x' into 'main'
fix(deps): update dependency dev.lavalink.youtube:v2 to v1.15.0

See merge request anthorob/netneutrality!80
2025-10-26 15:43:39 +00:00
Renovate 3a678ae859 fix(deps): update dependency dev.lavalink.youtube:v2 to v1.15.0 2025-10-26 15:43:39 +00:00
anthorob 69e9ae982b Merge branch 'renovate/quay.io-buildah-stable' into 'main'
chore(deps): update quay.io/buildah/stable docker digest to 9fa1327

See merge request anthorob/netneutrality!73
2025-10-23 06:43:40 +00:00
anthorob 3a846ed846 Merge branch 'renovate/org.junit.jupiter-junit-jupiter-6.x' into 'main'
chore(deps): update dependency org.junit.jupiter:junit-jupiter to v6

See merge request anthorob/netneutrality!83
2025-10-23 06:43:18 +00:00
anthorob 7d6ad97951 Merge branch 'renovate/io.sentry-sentry-8.x' into 'main'
fix(deps): update dependency io.sentry:sentry to v8.24.0

See merge request anthorob/netneutrality!82
2025-10-23 06:39:37 +00:00
anthorob 450444f37b Merge branch 'renovate/net.fellbaum-jemoji-1.x' into 'main'
fix(deps): update dependency net.fellbaum:jemoji to v1.7.5

See merge request anthorob/netneutrality!70
2025-10-23 06:39:20 +00:00
anthorob b5bbbb7907 Merge branch 'renovate/log4j2-monorepo' into 'main'
fix(deps): update log4j2 monorepo to v2.25.2

See merge request anthorob/netneutrality!60
2025-10-23 06:39:07 +00:00
Renovate Bot f830f8468c chore(deps): update dependency org.junit.jupiter:junit-jupiter to v6 2025-10-23 06:24:53 +00:00
Renovate Bot 316e5f6b4a fix(deps): update log4j2 monorepo to v2.25.2 2025-10-23 06:24:50 +00:00
Renovate Bot 437cf3a460 fix(deps): update dependency io.sentry:sentry to v8.24.0 2025-10-23 06:24:47 +00:00
Renovate Bot 822c6297a5 fix(deps): update dependency net.fellbaum:jemoji to v1.7.5 2025-10-23 06:24:44 +00:00
anthorob d459b3b735 Merge branch 'renovate/major-okhttp-monorepo' into 'main'
fix(deps): update dependency com.squareup.okhttp3:okhttp to v5

See merge request anthorob/netneutrality!61
2025-10-22 21:47:31 +00:00
Renovate 6b2d64388d fix(deps): update dependency com.squareup.okhttp3:okhttp to v5 2025-10-22 21:47:31 +00:00
anthorob aad528c5c7 Merge branch 'renovate/flyway' into 'main'
fix(deps): update flyway to v11.14.1

See merge request anthorob/netneutrality!49
2025-10-22 21:27:32 +00:00
Renovate 47ced9d0f2 fix(deps): update flyway to v11.14.1 2025-10-22 21:27:32 +00:00
anthorob 86c94db9aa Merge branch 'renovate/apache-commons' into 'main'
fix(deps): update apache commons

See merge request anthorob/netneutrality!81
2025-10-22 21:26:37 +00:00
Renovate Bot 5171cee268 fix(deps): update apache commons 2025-10-22 20:56:33 +00:00
anthorob f345505578 Merge branch 'renovate/pin-dependencies' into 'main'
chore(deps): pin mariadb docker tag to ae61197

See merge request anthorob/netneutrality!79
2025-10-22 20:48:35 +00:00
anthorob 4f64254e60 Merge branch 'renovate/hibernate-orm' into 'main'
fix(deps): update hibernate orm

See merge request anthorob/netneutrality!71
2025-10-22 20:47:38 +00:00
anthorob 5678cf52d8 fix renovate 2025-10-22 16:29:49 -04:00
Renovate Bot c96e0d88b5 fix(deps): update hibernate orm 2025-10-22 20:23:00 +00:00
Renovate Bot 3791667aac chore(deps): update quay.io/buildah/stable docker digest to 9fa1327 2025-10-22 20:22:47 +00:00
Renovate Bot 813d0dde02 chore(deps): pin mariadb docker tag to ae61197 2025-10-22 20:22:46 +00:00
anthorob b78322e521 Merge branch 'scheduled-tasks' into 'main'
Implement scheduled tasks

See merge request anthorob/netneutrality!78
2025-10-22 20:11:03 +00:00
anthorob 78002d9299 Implement scheduled tasks 2025-10-22 20:11:03 +00:00
anthorob 78a149b546 Merge branch 'renovate/org.apache.maven.plugins-maven-shade-plugin-3.x' into 'main'
chore(deps): update dependency org.apache.maven.plugins:maven-shade-plugin to v3.6.1

See merge request anthorob/netneutrality!67
2025-10-05 08:27:01 +00:00
anthorob 178054dd23 Merge branch 'renovate/pin-dependencies' into 'main'
chore(deps): pin dependencies

See merge request anthorob/netneutrality!65
2025-10-05 08:22:15 +00:00
anthorob 9c09edc88d Merge branch 'renovate/org.apache.maven.plugins-maven-surefire-plugin-3.x' into 'main'
chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.4

See merge request anthorob/netneutrality!68
2025-10-05 07:52:25 +00:00
anthorob b5e8aa7bd0 Merge branch 'renovate/mockito-monorepo' into 'main'
chore(deps): update dependency org.mockito:mockito-core to v5.20.0

See merge request anthorob/netneutrality!72
2025-10-05 07:52:08 +00:00
anthorob 230aca1620 Merge branch 'renovate/com.google.code.gson-gson-2.x' into 'main'
fix(deps): update dependency com.google.code.gson:gson to v2.13.2

See merge request anthorob/netneutrality!69
2025-10-05 07:51:52 +00:00
Renovate Bot 508e3fb5da chore(deps): pin dependencies 2025-10-05 07:19:29 +00:00
Renovate Bot c195f1f56b chore(deps): update dependency org.mockito:mockito-core to v5.20.0 2025-10-04 14:56:28 +00:00
Renovate Bot 55f7314b05 fix(deps): update dependency com.google.code.gson:gson to v2.13.2 2025-10-03 14:13:49 +00:00
anthorob c3b9a36557 Merge branch 'renovate/maven-wrapper-3.x' into 'main'
chore(deps): update dependency maven-wrapper to v3.3.4

See merge request anthorob/netneutrality!66
2025-10-03 14:05:15 +00:00
Renovate Bot 4b45f802f7 chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.4 2025-10-03 13:48:47 +00:00
Renovate Bot 1b80d5aa5a chore(deps): update dependency org.apache.maven.plugins:maven-shade-plugin to v3.6.1 2025-10-03 13:48:46 +00:00
Renovate Bot 83ae5bf657 chore(deps): update dependency maven-wrapper to v3.3.4 2025-10-03 13:38:25 +00:00
anthorob e2a7aa79f6 Merge branch 'group-hibernate-renovate' into 'main'
Group Hibernate MR by Renovate

See merge request anthorob/netneutrality!64
2025-10-03 13:34:32 +00:00
anthorob e186c44185 Group Hibernate MR by Renovate 2025-10-03 13:34:32 +00:00
anthorob de96a679e6 Merge branch 'renovate/maven-3.x' into 'main'
chore(deps): update dependency maven to v3.9.11

See merge request anthorob/netneutrality!63
2025-10-02 14:48:12 +00:00
anthorob 9589f484ff Merge branch 'renovate/io.sentry-sentry-8.x' into 'main'
fix(deps): update dependency io.sentry:sentry to v8.22.0

See merge request anthorob/netneutrality!54
2025-10-02 14:43:28 +00:00
anthorob af7dec9c79 Merge branch 'renovate/org.gitlab4j-gitlab4j-api-6.x' into 'main'
fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.1.0

See merge request anthorob/netneutrality!51
2025-10-02 14:43:14 +00:00
Renovate a6123b9656 fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.1.0 2025-10-02 14:43:14 +00:00
anthorob e940da94e2 Merge branch 'renovate/org.junit.jupiter-junit-jupiter-5.x' into 'main'
chore(deps): update dependency org.junit.jupiter:junit-jupiter to v5.14.0

See merge request anthorob/netneutrality!59
2025-10-02 14:42:46 +00:00
Renovate Bot dad51621c5 fix(deps): update dependency io.sentry:sentry to v8.22.0 2025-09-30 08:24:16 +00:00
Renovate Bot 7003cfbd39 chore(deps): update dependency org.junit.jupiter:junit-jupiter to v5.14.0 2025-09-30 08:24:12 +00:00
Renovate Bot 0b057de598 chore(deps): update dependency maven to v3.9.11 2025-07-28 08:34:23 +00:00
anthorob ff70af988a Merge branch 'renovate/dev.arbjerg-lavaplayer-2.x' into 'main'
fix(deps): update dependency dev.arbjerg:lavaplayer to v2.2.4

See merge request anthorob/netneutrality!55
2025-07-26 01:12:59 +00:00
Renovate Bot f3c144d2b1 fix(deps): update dependency dev.arbjerg:lavaplayer to v2.2.4 2025-07-04 16:53:39 +00:00
anthorob 716c6e9d93 Merge branch 'renovate/org.junit.jupiter-junit-jupiter-5.x' into 'main'
chore(deps): update dependency org.junit.jupiter:junit-jupiter to v5.13.2

See merge request anthorob/netneutrality!57
2025-07-04 16:49:52 +00:00
anthorob 6172182ed5 Merge branch 'renovate/dev.lavalink.youtube-v2-1.x' into 'main'
fix(deps): update dependency dev.lavalink.youtube:v2 to v1.13.3

See merge request anthorob/netneutrality!53
2025-07-04 16:45:50 +00:00
Renovate fc4dd64dff fix(deps): update dependency dev.lavalink.youtube:v2 to v1.13.3 2025-07-04 16:45:50 +00:00
Renovate Bot c40430fa9b chore(deps): update dependency org.junit.jupiter:junit-jupiter to v5.13.2 2025-06-30 08:33:52 +00:00
anthorob 40a73fd62d Merge branch 'renovate/net.dv8tion-jda-5.x' into 'main'
fix(deps): update dependency net.dv8tion:jda to v5.6.1

See merge request anthorob/netneutrality!52
2025-06-22 00:32:47 +00:00
Renovate 39111235f7 fix(deps): update dependency net.dv8tion:jda to v5.6.1 2025-06-22 00:32:47 +00:00
anthorob aee731bebe Merge branch 'renovate/com.mysql-mysql-connector-j-9.x' into 'main'
fix(deps): update dependency com.mysql:mysql-connector-j to v9.3.0

See merge request anthorob/netneutrality!45
2025-06-09 14:57:49 +00:00
anthorob e50730298d Merge branch 'renovate/maven-3.x' into 'main'
chore(deps): update dependency maven to v3.9.10

See merge request anthorob/netneutrality!50
2025-06-09 14:53:16 +00:00
anthorob d26fea7b9c Merge branch 'renovate/eclipse-temurin-21.x' into 'main'
chore(deps): update eclipse-temurin docker tag to v21.0.7_6-jdk-alpine

See merge request anthorob/netneutrality!38
2025-06-09 14:52:04 +00:00
Renovate f6ba9233be chore(deps): update eclipse-temurin docker tag to v21.0.7_6-jdk-alpine 2025-06-09 14:52:04 +00:00
anthorob 1423b6105a Merge branch 'renovate/junit5-monorepo' into 'main'
chore(deps): update dependency org.junit.jupiter:junit-jupiter to v5.13.1

See merge request anthorob/netneutrality!48
2025-06-09 13:06:53 +00:00
anthorob eb765952e4 Merge branch 'renovate/io.sentry-sentry-8.x' into 'main'
fix(deps): update dependency io.sentry:sentry to v8.13.2

See merge request anthorob/netneutrality!46
2025-06-09 13:06:11 +00:00
anthorob 8e1154319b Merge branch 'renovate/org.hibernate.orm-hibernate-hikaricp-6.x' into 'main'
fix(deps): update dependency org.hibernate.orm:hibernate-hikaricp to v6.6.17.final

See merge request anthorob/netneutrality!27
2025-06-09 13:05:40 +00:00
anthorob a7f5508c41 Merge branch 'renovate/org.hibernate.orm-hibernate-core-6.x' into 'main'
fix(deps): update dependency org.hibernate.orm:hibernate-core to v6.6.17.final

See merge request anthorob/netneutrality!26
2025-06-09 13:05:23 +00:00
anthorob d2a14637f0 Merge branch 'renovate/net.fellbaum-jemoji-1.x' into 'main'
fix(deps): update dependency net.fellbaum:jemoji to v1.7.4

See merge request anthorob/netneutrality!34
2025-06-09 13:04:48 +00:00
anthorob 539cd723b2 Merge branch 'renovate/net.dv8tion-jda-5.x' into 'main'
fix(deps): update dependency net.dv8tion:jda to v5.5.1

See merge request anthorob/netneutrality!47
2025-06-09 13:00:07 +00:00
Renovate c95f461300 fix(deps): update dependency net.dv8tion:jda to v5.5.1 2025-06-09 13:00:07 +00:00
Renovate Bot 52fcd8434e chore(deps): update dependency org.junit.jupiter:junit-jupiter to v5.13.1 2025-06-09 08:33:52 +00:00
Renovate Bot 1d8b9eb873 chore(deps): update dependency maven to v3.9.10 2025-06-09 08:33:47 +00:00
Renovate Bot 91f8c2b6bb fix(deps): update dependency io.sentry:sentry to v8.13.2 2025-06-03 13:59:07 +00:00
Renovate Bot 60e6453354 fix(deps): update dependency com.mysql:mysql-connector-j to v9.3.0 2025-06-03 13:59:04 +00:00
Renovate Bot 0120932e59 fix(deps): update dependency org.hibernate.orm:hibernate-hikaricp to v6.6.17.final 2025-06-03 13:59:00 +00:00
Renovate Bot 56df16c3d5 fix(deps): update dependency org.hibernate.orm:hibernate-core to v6.6.17.final 2025-06-03 13:58:57 +00:00
Renovate Bot 251ac6e171 fix(deps): update dependency net.fellbaum:jemoji to v1.7.4 2025-06-03 13:58:54 +00:00
anthorob 194a19cec2 Merge branch 'renovate/org.gitlab4j-gitlab4j-api-6.x' into 'main'
fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.0.0-rc.10

See merge request anthorob/netneutrality!39
2025-06-03 13:55:57 +00:00
Renovate 069002a534 fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.0.0-rc.10 2025-06-03 13:55:57 +00:00
anthorob 7c960ddbdc Merge branch 'renovate/commons-io-commons-io-2.x' into 'main'
fix(deps): update dependency commons-io:commons-io to v2.19.0

See merge request anthorob/netneutrality!36
2025-05-22 15:57:56 +00:00
anthorob 13dabe4bda Merge branch 'renovate/com.google.code.gson-gson-2.x' into 'main'
fix(deps): update dependency com.google.code.gson:gson to v2.13.1

See merge request anthorob/netneutrality!35
2025-05-22 15:57:26 +00:00
anthorob 1d099ad67e Merge branch 'renovate/junit5-monorepo' into 'main'
fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.12.2

See merge request anthorob/netneutrality!28
2025-05-22 15:57:02 +00:00
anthorob acb11c3d9a Merge branch 'renovate/flyway' into 'main'
fix(deps): update flyway to v11.8.2

See merge request anthorob/netneutrality!30
2025-05-22 15:47:10 +00:00
Renovate 86f9c6bc77 fix(deps): update flyway to v11.8.2 2025-05-22 15:47:10 +00:00
anthorob 59106ea59e Merge branch 'renovate/io.sentry-sentry-8.x' into 'main'
fix(deps): update dependency io.sentry:sentry to v8.12.0

See merge request anthorob/netneutrality!29
2025-05-22 14:06:08 +00:00
Renovate Bot d04897d603 fix(deps): update dependency io.sentry:sentry to v8.12.0 2025-05-22 13:24:32 +00:00
Renovate Bot af8df43295 fix(deps): update dependency commons-io:commons-io to v2.19.0 2025-05-22 13:24:30 +00:00
Renovate Bot 9d9a973201 fix(deps): update dependency com.google.code.gson:gson to v2.13.1 2025-05-22 13:24:27 +00:00
Renovate Bot 5cc35c463e fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.12.2 2025-05-22 13:24:25 +00:00
anthorob 24053bf5a7 Merge branch '9-flyway-migrations' into 'master'
Resolve "Flyway migrations"

Closes #9

See merge request anthorob/netneutrality!43
2025-05-22 13:09:36 +00:00
anthorob 41d6de7219 Resolve "Flyway migrations" 2025-05-22 13:09:36 +00:00
anthorob fae59dd9bb Merge branch 'fix-music-player' into 'master'
Fix music player

See merge request anthorob/netneutrality!42
2025-05-21 16:30:43 +00:00
anthorob c055ac84c6 Fix music player 2025-05-21 16:30:43 +00:00
anthorob d88c1b380a Merge branch '13-bug-report-netneutrality-3h' into 'master'
Fix docker build issue

Closes #13

See merge request anthorob/netneutrality!41
2025-04-28 01:22:03 +00:00
anthorob 5b11e68f8a Fix docker build issue 2025-04-28 01:22:03 +00:00
anthorob 29be1c987a Merge branch '13-bug-report-netneutrality-3h' into 'master'
Fix NETNEUTRALITY-3H

Closes #13

See merge request anthorob/netneutrality!40
2025-04-28 01:14:12 +00:00
anthorob 070eeb986f Fix NETNEUTRALITY-3H 2025-04-28 01:14:12 +00:00
anthorob f9b385ec86 Merge branch 'renovate/net.dv8tion-jda-5.x' into 'master'
fix(deps): update dependency net.dv8tion:jda to v5.4.0

See merge request anthorob/netneutrality!37
2025-04-24 06:37:58 +00:00
Renovate 8e4a6841cc fix(deps): update dependency net.dv8tion:jda to v5.4.0 2025-04-24 06:37:58 +00:00
anthorob 0d735f3744 Merge branch 'renovate/net.dv8tion-jda-5.x' into 'master'
fix(deps): update dependency net.dv8tion:jda to v5.3.2

See merge request anthorob/netneutrality!33
2025-04-20 16:50:44 +00:00
Renovate 030d816caf fix(deps): update dependency net.dv8tion:jda to v5.3.2 2025-04-20 16:50:44 +00:00
anthorob 50e5e704b7 Merge branch 'renovate/net.dv8tion-jda-5.x' into 'master'
fix(deps): update dependency net.dv8tion:jda to v5.3.1

See merge request anthorob/netneutrality!32
2025-03-31 15:38:25 +00:00
Renovate ffd2f05509 fix(deps): update dependency net.dv8tion:jda to v5.3.1 2025-03-31 15:38:25 +00:00
anthorob 1efab2eb5b Merge branch '12-bug-report-netneutrality-3f' into 'master'
Resolve "Bug report: NETNEUTRALITY-3F"

Closes #12

See merge request anthorob/netneutrality!31
2025-03-26 18:25:25 +00:00
anthorob ef2cd9769e Resolve "Bug report: NETNEUTRALITY-3F" 2025-03-26 18:25:25 +00:00
anthorob c6666bbbc1 Merge branch 'renovate/eclipse-temurin-21.x' into 'master'
chore(deps): update eclipse-temurin docker tag to v21

See merge request anthorob/netneutrality!19
2025-03-16 13:23:14 +00:00
Renovate 85624a974d chore(deps): update eclipse-temurin docker tag to v21 2025-03-16 13:23:13 +00:00
anthorob a37e0b47ab Merge branch 'renovate/net.dv8tion-jda-5.x' into 'master'
fix(deps): update dependency net.dv8tion:jda to v5.3.0

See merge request anthorob/netneutrality!15
2025-03-12 01:20:06 +00:00
Renovate 143e96ec46 fix(deps): update dependency net.dv8tion:jda to v5.3.0 2025-03-12 01:20:06 +00:00
anthorob 19f889e885 Merge branch 'renovate/eclipse-temurin-17.x' into 'master'
chore(deps): update eclipse-temurin docker tag

See merge request anthorob/netneutrality!9
2025-03-11 15:13:48 +00:00
anthorob 864f92b766 Merge branch 'renovate/major-flyway' into 'master'
fix(deps): update flyway to v11 (major)

See merge request anthorob/netneutrality!25
2025-03-11 15:03:22 +00:00
Renovate 6d1af8094e fix(deps): update flyway to v11 (major) 2025-03-11 15:03:22 +00:00
Renovate Bot c145848c14 chore(deps): update eclipse-temurin docker tag 2025-03-11 10:01:18 +00:00
anthorob 119c997265 Merge branch 'renovate/org.gitlab4j-gitlab4j-api-6.x' into 'master'
fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.0.0-rc.9

See merge request anthorob/netneutrality!6
2025-03-11 10:00:02 +00:00
Renovate b9051a0f74 fix(deps): update dependency org.gitlab4j:gitlab4j-api to v6.0.0-rc.9 2025-03-11 10:00:02 +00:00
anthorob 649c1cc8ae Merge branch 'renovate/org.hibernate.orm-hibernate-core-6.x' into 'master'
fix(deps): update dependency org.hibernate.orm:hibernate-core to v6.6.10.final

See merge request anthorob/netneutrality!20
2025-03-11 09:43:37 +00:00
anthorob 2e45054ade Merge branch 'renovate/org.hibernate.orm-hibernate-hikaricp-6.x' into 'master'
fix(deps): update dependency org.hibernate.orm:hibernate-hikaricp to v6.6.10.final

See merge request anthorob/netneutrality!21
2025-03-11 09:43:24 +00:00
anthorob 65f17b67ec Merge branch 'renovate/io.sentry-sentry-8.x' into 'master'
fix(deps): update dependency io.sentry:sentry to v8

See merge request anthorob/netneutrality!23
2025-03-11 09:35:42 +00:00
anthorob 52eed29f27 Merge branch 'renovate/org.json-json-20250107.x' into 'master'
fix(deps): update dependency org.json:json to v20250107

See merge request anthorob/netneutrality!24
2025-03-11 06:47:06 +00:00
anthorob bf4d0d7f6a Merge branch 'renovate/flyway' into 'master'
fix(deps): update flyway to v10.22.0

See merge request anthorob/netneutrality!22
2025-03-11 06:46:53 +00:00
Renovate 35ee744673 fix(deps): update flyway to v10.22.0 2025-03-11 06:46:53 +00:00
Renovate Bot ac4b0b52df fix(deps): update dependency org.json:json to v20250107 2025-03-11 06:25:03 +00:00
Renovate Bot 04eb4d4c6e fix(deps): update dependency io.sentry:sentry to v8 2025-03-11 06:25:00 +00:00
Renovate Bot 6aa5261a03 fix(deps): update dependency org.hibernate.orm:hibernate-hikaricp to v6.6.10.final 2025-03-11 06:24:52 +00:00
Renovate Bot 464cbc5fd7 fix(deps): update dependency org.hibernate.orm:hibernate-core to v6.6.10.final 2025-03-11 06:24:47 +00:00
anthorob ecd4af7dc6 Merge branch 'renovate/log4j2-monorepo' into 'master'
fix(deps): update log4j2 monorepo to v2.24.3

See merge request anthorob/netneutrality!18
2025-03-11 06:22:49 +00:00
anthorob 6d312b664e Merge branch 'renovate/junit5-monorepo' into 'master'
fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.12.0

See merge request anthorob/netneutrality!17
2025-03-11 06:22:30 +00:00
anthorob d2207d4cac Merge branch 'renovate/org.apache.commons-commons-lang3-3.x' into 'master'
fix(deps): update dependency org.apache.commons:commons-lang3 to v3.17.0

See merge request anthorob/netneutrality!16
2025-03-11 06:22:16 +00:00
Renovate Bot 37d80f53ca fix(deps): update log4j2 monorepo to v2.24.3 2025-03-11 04:35:11 +00:00
Renovate Bot e6d0354334 fix(deps): update dependency org.junit.jupiter:junit-jupiter to v5.12.0 2025-03-11 04:35:08 +00:00
Renovate Bot a209eab8ff fix(deps): update dependency org.apache.commons:commons-lang3 to v3.17.0 2025-03-11 04:35:07 +00:00
anthorob c2b9f55408 Merge branch 'renovate/commons-codec-commons-codec-1.x' into 'master'
fix(deps): update dependency commons-codec:commons-codec to v1.18.0

See merge request anthorob/netneutrality!12
2025-03-11 04:31:35 +00:00
anthorob 3813ce3691 Merge branch 'renovate/commons-io-commons-io-2.x' into 'master'
fix(deps): update dependency commons-io:commons-io to v2.18.0

See merge request anthorob/netneutrality!13
2025-03-11 04:31:22 +00:00
anthorob 1eac4c96f2 Merge branch 'renovate/maven-wrapper-3.x' into 'master'
chore(deps): update dependency maven-wrapper to v3.3.2

See merge request anthorob/netneutrality!10
2025-03-11 04:31:10 +00:00
Renovate Bot b4d5ca75e6 fix(deps): update dependency commons-io:commons-io to v2.18.0 2025-03-11 04:25:22 +00:00
Renovate Bot 1be3167cb9 fix(deps): update dependency commons-codec:commons-codec to v1.18.0 2025-03-11 04:25:19 +00:00
Renovate Bot 61e96746be chore(deps): update dependency maven-wrapper to v3.3.2 2025-03-11 04:25:19 +00:00
anthorob dfd678757b Merge branch 'renovate/net.fellbaum-jemoji-1.x' into 'master'
fix(deps): update dependency net.fellbaum:jemoji to v1.7.1

See merge request anthorob/netneutrality!5
2025-03-11 04:23:23 +00:00
anthorob 093796211c Merge branch 'renovate/com.mysql-mysql-connector-j-9.x' into 'master'
fix(deps): update dependency com.mysql:mysql-connector-j to v9.2.0

See merge request anthorob/netneutrality!11
2025-03-11 04:19:41 +00:00
anthorob 178cca5b1b Merge branch 'renovate/dev.arbjerg-lavaplayer-2.x' into 'master'
fix(deps): update dependency dev.arbjerg:lavaplayer to v2.2.3

See merge request anthorob/netneutrality!4
2025-03-11 03:19:25 +00:00
anthorob 970806213d Merge branch 'renovate/maven-3.x' into 'master'
chore(deps): update dependency maven to v3.9.9

See merge request anthorob/netneutrality!8
2025-03-11 03:06:36 +00:00
Renovate Bot 0a069157b0 fix(deps): update dependency com.mysql:mysql-connector-j to v9.2.0 2025-03-10 08:33:44 +00:00
Renovate Bot ef7282f777 chore(deps): update dependency maven to v3.9.9 2025-03-10 07:33:22 +00:00
Renovate Bot eef8886a6d fix(deps): update dependency net.fellbaum:jemoji to v1.7.1 2025-03-09 20:22:30 +00:00
Renovate Bot 138385c895 fix(deps): update dependency dev.arbjerg:lavaplayer to v2.2.3 2025-03-09 20:22:29 +00:00
anthorob 4a14098ade Merge branch 'develop' into 'master'
Version 3.0

See merge request anthorob/netneutrality!3
2025-03-09 20:08:43 +00:00
anthorob 1242118b0d Version 3.0 2025-03-09 20:08:43 +00:00
135 changed files with 3168 additions and 1443 deletions

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
.git
.gitea
.idea
.mvn
src
classes
logs
target/*
!target/netneutrality.jar
*.iml
README.md
checkstyle.xml
mvnw
mvnw.cmd
pom.xml
+10 -3
View File
@@ -1,17 +1,24 @@
NETNEUTRALITY_TAG=latest
NETNEUTRALITY_BOT_ENV=dev
NETNEUTRALITY_BOT_TOKEN=
NETNEUTRALITY_BOT_PREFIX=$
NETNEUTRALITY_BOT_OWNER=
NETNEUTRALITY_BOT_INVITE=
NETNEUTRALITY_API_PORT=9000
MYSQL_HOST=127.0.0.1
MYSQL_USER=root
MYSQL_PASSWORD=
MYSQL_DATABASE=
MYSQL_PORT=3306
MYSQL_USER=java
MYSQL_PASSWORD=password
MYSQL_DATABASE=netneutrality
MYSQL_ROOT_PASSWORD=password
MARIADB_AUTO_UPGRADE=1
NETNEUTRALITY_PO_TOKEN=
NETNEUTRALITY_VISITOR_DATA=
NETNEUTRALITY_CIPHER_URL=http://localhost:8001
NETNEUTRALITY_CIPHER_PASSWORD=
NETNEUTRALITY_SENTRY_DSN=
GITLAB_HOST=
+125
View File
@@ -0,0 +1,125 @@
name: CI
on:
push:
branches:
- "main"
tags:
- '*'
pull_request:
branches:
- "main"
jobs:
package:
name: Package
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up JDK
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5
with:
distribution: 'temurin'
java-version: '25'
cache: 'maven'
- name: Build package
run: |
chmod +x ./mvnw
./mvnw --batch-mode --update-snapshots verify
- name: Upload test reports
if: always()
uses: actions/upload-artifact@c6a366c94c3e0affe28c06c8df20a878f24da3cf # v3
with:
name: junit-reports
path: |
**/target/*-reports/TEST-*.xml
if-no-files-found: ignore
- name: Upload Maven artifacts
uses: actions/upload-artifact@c6a366c94c3e0affe28c06c8df20a878f24da3cf # v3
with:
name: maven-artifacts
path: |
target/netneutrality.jar
startup.sh
if-no-files-found: error
docker-main:
name: Docker Build and Push (main)
runs-on: ubuntu-latest
needs: package
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Download build artifacts
uses: actions/download-artifact@a9bc5e6ef2cb54c177f32aa5726adaa15e7e2d59 # v3
with:
name: maven-artifacts
path: .
- name: Log in to registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push (main)
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
with:
context: .
file: ./Dockerfile
push: true
tags: "${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/netneutrality:main"
docker-release:
name: Docker Build and Push (release)
runs-on: ubuntu-latest
needs: package
if: ${{ startsWith(github.ref, 'refs/tags/') }}
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Download build artifacts
uses: actions/download-artifact@a9bc5e6ef2cb54c177f32aa5726adaa15e7e2d59 # v3
with:
name: maven-artifacts
path: .
- name: Compute release version
id: rel
shell: bash
run: |
# Strip leading 'v' if present (e.g., v1.2.3 -> 1.2.3)
ver="${GITHUB_REF_NAME#v}"
echo "version=$ver" >> "$GITHUB_OUTPUT"
- name: Log in to registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push (release + latest)
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7
with:
context: .
file: ./Dockerfile
push: true
tags: |
${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/netneutrality:${{ steps.rel.outputs.version }}
${{ secrets.REGISTRY_URL }}/${{ secrets.REGISTRY_USER }}/netneutrality:latest
+1
View File
@@ -45,3 +45,4 @@ target/
logs/
.env
docker-compose.override.yml
-54
View File
@@ -1,54 +0,0 @@
image: eclipse-temurin:17-jdk-alpine
variables:
MAVEN_OPTS: >-
-Dhttps.protocols=TLSv1.2
-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository
-Dorg.slf4j.simpleLogger.showDateTime=true
-Djava.awt.headless=true
MAVEN_CLI_OPTS: >-
--batch-mode
--errors
--fail-at-end
--show-version
--no-transfer-progress
-DinstallAtEnd=true
-DdeployAtEnd=true
cache:
key: "maven-$CI_COMMIT_REF_SLUG"
paths:
- .m2/repository
stages:
- compile
- test
- package
compile:
stage: compile
script:
- "chmod +x ./mvnw"
- "./mvnw $MAVEN_CLI_OPTS compile"
test:
stage: test
script:
- "chmod +x ./mvnw"
- "./mvnw $MAVEN_CLI_OPTS test"
artifacts:
when: always
reports:
junit:
- "**/target/*-reports/TEST-*.xml"
package:
stage: package
script:
- "chmod +x ./mvnw"
- "./mvnw $MAVEN_CLI_OPTS package -DskipTests=true"
artifacts:
name: "Maven artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
paths:
- "**/target"
+3 -18
View File
@@ -1,18 +1,3 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.15/apache-maven-3.9.15-bin.zip
+3 -14
View File
@@ -1,17 +1,6 @@
FROM eclipse-temurin:17-jdk-alpine AS build
FROM eclipse-temurin:25-jre@sha256:ff82c74a630c08b417502c4c18189e62074edbb28eb1f2d31b799ac138c01058
COPY .mvn/ .mvn
COPY mvnw pom.xml ./
COPY src ./src
RUN ["chmod", "+x", "./mvnw"]
RUN ./mvnw install
FROM eclipse-temurin:17-jre-alpine
RUN apk add netcat-openbsd
RUN apk add curl
RUN apt-get update && apt-get install -y --no-install-recommends netcat-openbsd curl && rm -rf /var/lib/apt/lists/*
WORKDIR /app
@@ -19,7 +8,7 @@ ARG API_PORT=9000
EXPOSE ${API_PORT}
COPY startup.sh ./
COPY --from=build /target/netneutrality-jar-with-dependencies.jar ./
COPY target/netneutrality.jar ./
RUN ["chmod", "+x", "./startup.sh"]
CMD ["./startup.sh"]
+11 -4
View File
@@ -1,17 +1,24 @@
NETNEUTRALITY_TAG=latest
NETNEUTRALITY_BOT_ENV=dev
NETNEUTRALITY_BOT_TOKEN=
NETNEUTRALITY_BOT_PREFIX=
NETNEUTRALITY_BOT_PREFIX=$
NETNEUTRALITY_BOT_OWNER=
NETNEUTRALITY_BOT_INVITE=
NETNEUTRALITY_API_PORT=9000
MYSQL_HOST=127.0.0.1
MYSQL_USER=root
MYSQL_PASSWORD=
MYSQL_DATABASE=
MYSQL_PORT=3306
MYSQL_USER=java
MYSQL_PASSWORD=password
MYSQL_DATABASE=netneutrality
MYSQL_ROOT_PASSWORD=password
MARIADB_AUTO_UPGRADE=1
NETNEUTRALITY_PO_TOKEN=
NETNEUTRALITY_VISITOR_DATA=
NETNEUTRALITY_CIPHER_URL=http://localhost:8001
NETNEUTRALITY_CIPHER_PASSWORD=
NETNEUTRALITY_SENTRY_DSN=
GITLAB_HOST=
+37
View File
@@ -0,0 +1,37 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="severity" value="warning"/>
<!-- Allows tab characters -->
<module name="FileTabCharacter">
<property name="eachLine" value="false"/>
</module>
<module name="TreeWalker">
<!-- Indentation with tabs -->
<module name="Indentation">
<property name="basicOffset" value="4"/>
<property name="tabWidth" value="4"/>
<property name="forceStrictCondition" value="false"/>
</module>
<!-- Common useful checks -->
<module name="EmptyBlock">
<property name="option" value="text"/>
</module>
<module name="NeedBraces"/>
<module name="AvoidStarImport"/>
<module name="UnusedImports"/>
<module name="EqualsHashCode"/>
<!-- Relaxed Javadoc rules -->
<module name="JavadocMethod">
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
</module>
</module>
</module>
-64
View File
@@ -1,64 +0,0 @@
services:
db:
image: mariadb:lts
container_name: db
restart: unless-stopped
volumes:
- netneutrality-db:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d
environment:
MYSQL_USER: 'java'
MYSQL_PASSWORD: 'password'
MYSQL_DATABASE: 'netneutrality'
MYSQL_ROOT_PASSWORD: 'password'
MARIADB_AUTO_UPGRADE: '1'
ports:
- "3306"
networks:
- internal
bot:
container_name: bot
build: ./
restart: unless-stopped
depends_on:
- db
volumes:
- ./logs:/app/logs
environment:
MYSQL_HOST: 'db'
MYSQL_USER: 'java'
MYSQL_PASSWORD: 'password'
MYSQL_DATABASE: 'netneutrality'
ports:
- "9000:9000"
networks:
- internal
webapp:
image: bot-webapp:dev
build: ../netneutrality-webapp
restart: always
depends_on:
- db
- bot
volumes:
- ./logs:/app/logs
environment:
DB_CONNECTION: 'mysql'
DB_HOST: 'db'
DB_PORT: '3306'
DB_DATABASE: 'netneutrality'
DB_USERNAME: 'java'
DB_PASSWORD: 'password'
BOT_URL: 'http://bot:9000'
ports:
- '8080:80'
networks:
- internal
volumes:
netneutrality-db:
networks:
internal:
+29 -27
View File
@@ -1,44 +1,46 @@
services:
db:
image: mariadb:lts
netneutrality-db:
image: mariadb:11@sha256:1cac8492bd78b1ec693238dc600be173397efd7b55eabc725abc281dc855b482
container_name: db
restart: unless-stopped
networks:
- netneutrality
volumes:
- netneutrality-db:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d
environment:
MYSQL_USER: 'java'
MYSQL_PASSWORD: 'password'
MYSQL_DATABASE: 'netneutrality'
MYSQL_ROOT_PASSWORD: 'password'
MARIADB_AUTO_UPGRADE: '1'
ports:
- "3306:3306"
networks:
- internal
- MYSQL_USER=${MYSQL_USER:-java}
- MYSQL_PASSWORD=${MYSQL_PASSWORD:-password}
- MYSQL_DATABASE=${MYSQL_DATABASE:-netneutrality}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-password}
- MARIADB_AUTO_UPGRADE=1
bot:
netneutrality-bot:
image: gitea.bobert.me/anthorob/netneutrality:${NETNEUTRALITY_TAG:-latest}
container_name: bot
build: ./
restart: unless-stopped
env_file: .env
networks:
- netneutrality
depends_on:
- db
- netneutrality-db
volumes:
- ./logs:/app/logs
environment:
MYSQL_HOST: 'db'
MYSQL_PORT: '3306'
MYSQL_USER: 'java'
MYSQL_PASSWORD: 'password'
MYSQL_DATABASE: 'netneutrality'
env_file: ".env"
ports:
- "9000:9000"
MYSQL_HOST: netneutrality-db
MYSQL_PORT: 3306
MYSQL_USER: java
MYSQL_PASSWORD: password
MYSQL_DATABASE: netneutrality
ejs-api:
image: ghcr.io/kikkia/yt-cipher:master@sha256:4fbb0d94cb4b9d2e5028986853825921d8c30975c0d948391fb9f4c7bf8520f6
container_name: ejs_signature_api
restart: unless-stopped
networks:
- internal
- netneutrality
# environment: # UNCOMMENT THIS LINE AND API_TOKEN TO ADD A PASSWORD
# - API_TOKEN=test
volumes:
netneutrality-db:
netneutrality-db: null
networks:
internal:
netneutrality: null
+42
View File
@@ -0,0 +1,42 @@
param (
[ValidateSet("migrate", "info", "validate", "clean", "baseline", "repair")]
[string]$Command = "info"
)
$envFile = ".env"
if (-not (Test-Path $envFile)) {
Write-Error ".env file not found in the current directory."
exit 1
}
Get-Content $envFile | ForEach-Object {
if ($_ -match "^\s*([A-Za-z_][A-Za-z0-9_]*)=(.*)$") {
$name = $matches[1]
$value = $matches[2]
[System.Environment]::SetEnvironmentVariable($name, $value)
}
}
$MYSQL_HOST = $env:MYSQL_HOST
$MYSQL_PORT = $env:MYSQL_PORT
$MYSQL_DATABASE = $env:MYSQL_DATABASE
if (-not $MYSQL_HOST -or -not $MYSQL_PORT -or -not $MYSQL_DATABASE) {
Write-Error "MYSQL_HOST, MYSQL_PORT, or MYSQL_DATABASE missing from .env"
exit 1
}
$env:FLYWAY_URL = "jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}"
$env:FLYWAY_USER = $env:MYSQL_USER
$env:FLYWAY_PASSWORD = $env:MYSQL_PASSWORD
Write-Host "Ensuring database '$MYSQL_DATABASE' exists..."
$mysqlCommand = "CREATE DATABASE IF NOT EXISTS $MYSQL_DATABASE CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
& mysql --host=$MYSQL_HOST --port=$MYSQL_PORT --user=$env:MYSQL_USER --password=$env:MYSQL_PASSWORD -e $mysqlCommand
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to create database or connect to MySQL. Check your credentials or server status."
exit 1
}
.\mvnw flyway:$Command
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
set -e
COMMAND=${1:-info}
ENV_FILE=".env"
if [[ ! -f "$ENV_FILE" ]]; then
echo ".env file not found in the current directory."
exit 1
fi
# Export variables from .env
export $(grep -E '^[A-Za-z_][A-Za-z0-9_]*=' "$ENV_FILE" | xargs)
if [[ -z "$MYSQL_HOST" || -z "$MYSQL_PORT" || -z "$MYSQL_DATABASE" ]]; then
echo "MYSQL_HOST, MYSQL_PORT, or MYSQL_DATABASE missing from .env"
exit 1
fi
export FLYWAY_URL="jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/${MYSQL_DATABASE}"
export FLYWAY_USER="$MYSQL_USER"
export FLYWAY_PASSWORD="$MYSQL_PASSWORD"
echo "Ensuring database '$MYSQL_DATABASE' exists..."
mysql -h"$MYSQL_HOST" -P"$MYSQL_PORT" -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" \
-e "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
if [[ $? -ne 0 ]]; then
echo "Failed to create database or connect to MySQL. Check your credentials or server status."
exit 1
fi
./mvnw flyway:"$COMMAND"
Vendored
+247 -260
View File
@@ -19,290 +19,277 @@
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.2.0
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
# Apache Maven Wrapper startup batch script, version 3.3.4
#
# Optional ENV vars
# -----------------
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
else
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
fi
fi
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=$(java-config --jre-home)
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink)
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
if $darwin ; then
javaHome="$(dirname "\"$javaExecutable\"")"
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
else
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
fi
javaHome="$(dirname "\"$javaExecutable\"")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
if [ -n "${JAVA_HOME-}" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
fi
fi
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
trim() {
# MWRAPPER-139:
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
# Needed for removing poorly interpreted newline sequences when running in more
# exotic environments such as mingw bash on Windows.
printf "%s" "${1}" | tr -d '[:space:]'
}
scriptDir="$(dirname "$0")"
scriptName="$(basename "$0")"
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl=$(trim "${value-}") ;;
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
esac
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
;;
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
elif command -v sha256sum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
else
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
fi
# Find the actual extracted directory name (handles snapshots where filename != directory name)
actualDistributionDir=""
# First try the expected directory name (for regular distributions)
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
actualDistributionDir="$distributionUrlNameMain"
fi
fi
# If not found, search for any directory with the Maven executable (for snapshots)
if [ -z "$actualDistributionDir" ]; then
# enable globbing to iterate over items
set +f
for dir in "$TMP_DOWNLOAD_DIR"/*; do
if [ -d "$dir" ]; then
if [ -f "$dir/bin/$MVN_CMD" ]; then
actualDistributionDir="$(basename "$dir")"
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=$(cd "$wdir/.." || exit 1; pwd)
fi
# end of workaround
done
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
# Remove \r in case we run on Windows within Git Bash
# and check out the repository with auto CRLF management
# enabled. Otherwise, we may read lines that are delimited with
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
# splitting rules.
tr -s '\r\n' ' ' < "$1"
fi
}
log() {
if [ "$MVNW_VERBOSE" = true ]; then
printf '%s\n' "$1"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
if [ -z "$BASE_DIR" ]; then
exit 1;
set -f
fi
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
log "$MAVEN_PROJECTBASEDIR"
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
if [ -r "$wrapperJarPath" ]; then
log "Found $wrapperJarPath"
else
log "Couldn't find $wrapperJarPath, downloading it ..."
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
fi
while IFS="=" read -r key value; do
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
safeValue=$(echo "$value" | tr -d '\r')
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
log "Downloading from: $wrapperUrl"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
fi
if command -v wget > /dev/null; then
log "Found wget ... using wget"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
log "Found curl ... using curl"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
fi
else
log "Falling back to using Java to download"
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=$(cygpath --path --windows "$javaSource")
javaClass=$(cygpath --path --windows "$javaClass")
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
log " - Compiling MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/javac" "$javaSource")
fi
if [ -e "$javaClass" ]; then
log " - Running MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
wrapperSha256Sum=""
while IFS="=" read -r key value; do
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
if [ -n "$wrapperSha256Sum" ]; then
wrapperSha256Result=false
if command -v sha256sum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
elif command -v shasum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
exit 1
fi
if [ $wrapperSha256Result = false ]; then
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
exit 1
fi
if [ -z "$actualDistributionDir" ]; then
verbose "Contents of $TMP_DOWNLOAD_DIR:"
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
die "Could not find Maven distribution directory in extracted archive"
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
clean || :
exec_maven "$@"
Vendored
+153 -169
View File
@@ -1,3 +1,4 @@
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@@ -18,188 +19,171 @@
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.2.0
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM Apache Maven Wrapper startup batch script, version 3.3.4
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
SET WRAPPER_SHA_256_SUM=""
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
)
IF NOT %WRAPPER_SHA_256_SUM%=="" (
powershell -Command "&{"^
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
" exit 1;"^
"}"^
"}"
if ERRORLEVEL 1 goto error
)
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
if ($env:MVNW_REPOURL) {
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
$MAVEN_M2_PATH = "$HOME/.m2"
if ($env:MAVEN_USER_HOME) {
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
}
:error
set ERROR_CODE=1
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
}
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
$MAVEN_WRAPPER_DISTS = $null
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
} else {
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
}
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
cmd /C exit /B %ERROR_CODE%
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# unzip and move
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
# Find the actual extracted directory name (handles snapshots where filename != directory name)
$actualDistributionDir = ""
# First try the expected directory name (for regular distributions)
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
$actualDistributionDir = $distributionUrlNameMain
}
# If not found, search for any directory with the Maven executable (for snapshots)
if (!$actualDistributionDir) {
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
if (Test-Path -Path $testPath -PathType Leaf) {
$actualDistributionDir = $_.Name
}
}
}
if (!$actualDistributionDir) {
Write-Error "Could not find Maven distribution directory in extracted archive"
}
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
+125 -47
View File
@@ -13,10 +13,11 @@
<properties>
<main.class>me.bobert.netneutrality.NetNeutrality</main.class>
<java.version>17</java.version>
<java.version>25</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
<mockito.version>5.23.0</mockito.version>
</properties>
<build>
@@ -28,52 +29,95 @@
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.5</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/mockito/mockito-core/${mockito.version}/mockito-core-${mockito.version}.jar"
</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>10.17.0</version>
<version>11.20.3</version>
<configuration>
<url>jdbc:mysql://localhost:3306/netneutrality</url>
<user>root</user>
<password></password>
<url>${env.FLYWAY_URL}</url>
<user>${env.FLYWAY_USER}</user>
<password>${env.FLYWAY_PASSWORD}</password>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<version>3.5.0</version>
<configuration>
<propertiesEncoding>UTF-8</propertiesEncoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.7.1</version>
<artifactId>maven-jar-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<archive>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>${main.class}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>netneutrality</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.2</version>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
<goal>shade</goal>
</goals>
<configuration>
<finalName>netneutrality</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${main.class}</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</transformer>
</transformers>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>checkstyle</id>
<phase>test</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<failOnViolation>true</failOnViolation>
<linkXRef>false</linkXRef>
<outputFile>target/checkstyle-result.xml</outputFile>
<outputFormat>xml</outputFormat>
</configuration>
</plugin>
</plugins>
</build>
@@ -100,71 +144,98 @@
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>5.1.2</version>
<version>6.4.1</version>
</dependency>
<dependency>
<groupId>dev.arbjerg</groupId>
<artifactId>lavaplayer</artifactId>
<version>2.2.2</version>
<version>2.2.6</version>
</dependency>
<dependency>
<groupId>dev.lavalink.youtube</groupId>
<artifactId>v2</artifactId>
<version>1.11.5</version>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>club.minnced</groupId>
<artifactId>jdave-api</artifactId>
<version>0.1.8</version>
</dependency>
<dependency>
<groupId>club.minnced</groupId>
<artifactId>jdave-native-linux-x86-64</artifactId>
<version>0.1.8</version>
</dependency>
<dependency>
<groupId>club.minnced</groupId>
<artifactId>jdave-native-win-x86-64</artifactId>
<version>0.1.8</version>
</dependency>
<dependency>
<groupId>club.minnced</groupId>
<artifactId>jdave-native-darwin</artifactId>
<version>0.1.8</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<artifactId>okhttp-jvm</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.5.2.Final</version>
<version>7.1.9.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-hikaricp</artifactId>
<version>6.5.2.Final</version>
<version>7.1.9.Final</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.0.0</version>
<version>9.7.0</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>10.17.0</version>
<version>11.20.3</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<version>10.17.0</version>
<version>11.20.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry</artifactId>
<version>7.12.1</version>
<version>8.41.0</version>
</dependency>
<dependency>
<groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-api</artifactId>
<version>6.0.0-rc.5</version>
<version>6.2.0</version>
</dependency>
<dependency>
<groupId>net.fellbaum</groupId>
<artifactId>jemoji</artifactId>
<version>1.7.0</version>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20240303</version>
<version>20250517</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.14.0</version>
</dependency>
<dependency>
@@ -176,41 +247,48 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.23.1</version>
<version>2.26.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.23.1</version>
<version>2.26.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.23.1</version>
<version>2.26.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.17.0</version>
<version>3.19.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.16.1</version>
<version>2.21.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.0</version>
<version>6.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
+31 -1
View File
@@ -1,6 +1,36 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"renovate/renovate-config"
"local>renovate/renovate-config",
"group:monorepos",
"group:flyway"
],
"packageRules": [
{
"matchPackageNames": [
"quay.io/buildah/stable"
],
"enabled": false
},
{
"matchPackageNames": [
"mariadb"
],
"automerge": false,
"dependencyDashboardApproval": true
},
{
"groupName": "hibernate orm",
"matchPackageNames": [
"org.hibernate.orm:**"
]
},
{
"groupName": "apache commons",
"matchPackageNames": [
"commons-**",
"org.apache.commons:**"
]
}
]
}
@@ -6,19 +6,22 @@ package me.bobert.netneutrality;
* https://discord.gg/qUa6zNFZsd
*/
import club.minnced.discord.jdave.interop.JDaveSessionFactory;
import io.sentry.Sentry;
import me.bobert.netneutrality.core.LogHandler;
import me.bobert.netneutrality.core.command.CommandManager;
import me.bobert.netneutrality.core.db.DatabaseMigration;
import me.bobert.netneutrality.core.db.SessionManager;
import me.bobert.netneutrality.core.tasks.TaskManager;
import me.bobert.netneutrality.core.thread.ScheduledTaskManager;
import me.bobert.netneutrality.core.thread.ThreadManager;
import me.bobert.netneutrality.hooks.EventsHandler;
import me.bobert.netneutrality.http.server.WebApi;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.thread.ShutdownThread;
import me.bobert.netneutrality.utils.Settings;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.audio.AudioModuleConfig;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.exceptions.InvalidTokenException;
import net.dv8tion.jda.api.requests.GatewayIntent;
@@ -33,7 +36,7 @@ public class NetNeutrality {
private static NetNeutrality instance;
private static JDA jda;
public static void main(String[] args) {
static void main() {
System.out.println("Starting NetNeutrality v" + VERSION);
String env = Settings.getInstance().get("NETNEUTRALITY_BOT_ENV", "dev");
@@ -52,6 +55,8 @@ public class NetNeutrality {
if ("dev".equals(env)) {
Configurator.setLevel("net.dv8tion.jda", Level.DEBUG);
Configurator.setLevel("dev.lavalink.youtube", Level.DEBUG);
Configurator.setLevel("com.sedmelluq.discord", Level.DEBUG);
}
instance = new NetNeutrality();
@@ -67,8 +72,8 @@ public class NetNeutrality {
throw new RuntimeException("No bot token provided, exiting.");
}
// DatabaseMigration.migrate();
SessionManager.getSessionFactory();
DatabaseMigration.migrate();
CommandManager.init();
MusicManager.initPlayerManager();
TaskManager.getInstance().init();
@@ -78,7 +83,7 @@ public class NetNeutrality {
new WebApi(Integer.parseInt(Settings.getInstance().get("NETNEUTRALITY_API_PORT", "9000")));
jda.getPresence().setActivity(Activity.watching("you"));
Runtime.getRuntime().addShutdownHook(new ShutdownThread(this));
Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
}
public static NetNeutrality getInstance() {
@@ -95,7 +100,13 @@ public class NetNeutrality {
try {
jda = JDABuilder
.createDefault(token)
.enableIntents(GatewayIntent.GUILD_MEMBERS, GatewayIntent.GUILD_MESSAGE_REACTIONS, GatewayIntent.GUILD_VOICE_STATES, GatewayIntent.MESSAGE_CONTENT)
.enableIntents(
GatewayIntent.GUILD_MEMBERS,
GatewayIntent.GUILD_MESSAGE_REACTIONS,
GatewayIntent.GUILD_VOICE_STATES,
GatewayIntent.MESSAGE_CONTENT)
.setAudioModuleConfig(
new AudioModuleConfig().withDaveSessionFactory(new JDaveSessionFactory()))
.setActivity(Activity.watching("me load..."))
.build();
jda.awaitReady();
@@ -107,6 +118,7 @@ public class NetNeutrality {
public void shutdown() {
System.out.println("[Net Neutrality] Shutting down...");
ScheduledTaskManager.cancelAll();
MusicManager.disconnectPlayers();
ThreadManager.shutdownExecutor();
disconnect();
@@ -5,10 +5,10 @@ package me.bobert.netneutrality.command.admin;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractAdminCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.AdminCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.db.entities.OBlacklist;
import me.bobert.netneutrality.db.service.BlacklistService;
@@ -18,7 +18,7 @@ import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import java.util.List;
public class BlacklistCommand extends AbstractAdminCommand {
public class BlacklistCommand extends AdminCommand {
@Override
public boolean isEnabled() {
@@ -5,10 +5,10 @@ package me.bobert.netneutrality.command.admin;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractAdminCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.AdminCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.tasks.TaskManager;
import me.bobert.netneutrality.tasks.emoji.EmojiReactionRoleTask;
@@ -24,7 +24,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
public class ReactionCommand extends AbstractAdminCommand {
public class ReactionCommand extends AdminCommand {
@Override
public boolean isEnabled() {
@@ -5,18 +5,22 @@ package me.bobert.netneutrality.command.basic;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.*;
import me.bobert.netneutrality.core.command.CommandCategory;
import me.bobert.netneutrality.core.command.CommandContainer;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandManager;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.AbstractCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.tasks.BuiltInTask;
import me.bobert.netneutrality.core.tasks.Task;
import me.bobert.netneutrality.tasks.help.BotInfo;
import me.bobert.netneutrality.tasks.help.CommandHelp;
import me.bobert.netneutrality.tasks.help.ReportBug;
import me.bobert.netneutrality.utils.MessageFunction;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.util.List;
@@ -61,9 +65,9 @@ public class HelpCommand extends AbstractCommand {
public CommandExecutionResult execute(CommandContext context) {
String command = context.getOption("command", null, CommandOption::getAsString);
if (command == null) {
Button commands = BuiltInTask.createButton(CommandHelp.class);
Button info = BuiltInTask.createButton(BotInfo.class);
Button reportbug = BuiltInTask.createButton(ReportBug.class);
Button commands = Task.createButton(CommandHelp.class);
Button info = Task.createButton(BotInfo.class);
Button reportbug = Task.createButton(ReportBug.class);
ActionRow row = ActionRow.of(commands, info, reportbug);
context.replyEphemeral("Thanks for using the Net Neutrality Bot! What do you need help with?", List.of(row));
return CommandExecutionResult.none();
@@ -5,10 +5,10 @@ package me.bobert.netneutrality.command.basic;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractCommand;
import me.bobert.netneutrality.core.command.CommandCategory;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.AbstractCommand;
import me.bobert.netneutrality.core.context.CommandContext;
public class PingCommand extends AbstractCommand {
@@ -5,10 +5,10 @@ package me.bobert.netneutrality.command.bot;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractAdminCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.AdminCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.db.GSettings;
import me.bobert.netneutrality.db.service.GuildService;
@@ -23,7 +23,7 @@ import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import java.util.Map;
public class ConfigureCommand extends AbstractAdminCommand {
public class ConfigureCommand extends AdminCommand {
@Override
public boolean isEnabled() {
@@ -6,11 +6,11 @@ package me.bobert.netneutrality.command.crypto;
*/
import me.bobert.netneutrality.core.LogHandler;
import me.bobert.netneutrality.core.command.AbstractCommand;
import me.bobert.netneutrality.core.command.CommandCategory;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.AbstractCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.http.WebModule;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@@ -5,11 +5,10 @@ package me.bobert.netneutrality.command.git;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.context.command.SlashCommandContext;
import me.bobert.netneutrality.core.command.AbstractCommand;
import me.bobert.netneutrality.core.command.CommandCategory;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.AbstractCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.http.WebModule;
import me.bobert.netneutrality.tasks.git.ReportIssueTask;
@@ -6,14 +6,14 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandCategory;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
public class BitconnectCommand extends AbstractMusicCommand {
public class BitconnectCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -6,14 +6,14 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
public class ClearQueueCommand extends AbstractMusicCommand {
public class ClearQueueCommand extends MusicCommand {
@Override
public boolean needAdmin() {
@@ -6,15 +6,15 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MessageFunction;
import me.bobert.netneutrality.utils.MusicUtils;
public class CurrentlyPlayingCommand extends AbstractMusicCommand {
public class CurrentlyPlayingCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -6,13 +6,13 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.utils.MusicUtils;
public class JoinCommand extends AbstractMusicCommand {
public class JoinCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -6,14 +6,14 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
public class LeaveCommand extends AbstractMusicCommand {
public class LeaveCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -6,15 +6,15 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import net.dv8tion.jda.api.interactions.commands.OptionType;
public class PlayCommand extends AbstractMusicCommand {
public class PlayCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -5,10 +5,10 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MessageFunction;
@@ -18,7 +18,7 @@ import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
public class QueueCommand extends AbstractMusicCommand {
public class QueueCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -4,14 +4,14 @@ package me.bobert.netneutrality.command.music;/*
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
public class ResumeCommand extends AbstractMusicCommand {
public class ResumeCommand extends MusicCommand {
@Override
public boolean isEnabled() {
return true;
@@ -6,14 +6,14 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
public class ShuffleCommand extends AbstractMusicCommand {
public class ShuffleCommand extends MusicCommand {
@Override
public boolean isEnabled() {
return true;
@@ -6,10 +6,10 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
@@ -17,7 +17,7 @@ import me.bobert.netneutrality.utils.UserFunction;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
public class SkipCommand extends AbstractMusicCommand {
public class SkipCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -6,15 +6,15 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
import me.bobert.netneutrality.utils.UserFunction;
public class StopCommand extends AbstractMusicCommand {
public class StopCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -5,15 +5,15 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MessageFunction;
import me.bobert.netneutrality.utils.MusicUtils;
public class ViewQueueCommand extends AbstractMusicCommand {
public class ViewQueueCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -6,10 +6,10 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.command.options.CommandOption;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
@@ -17,7 +17,7 @@ import me.bobert.netneutrality.utils.UserFunction;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
public class VolumeCommand extends AbstractMusicCommand {
public class VolumeCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -5,14 +5,14 @@ package me.bobert.netneutrality.command.music;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMusicCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.impl.MusicCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.music.MusicManager;
import me.bobert.netneutrality.utils.MusicUtils;
public class VoteSkipCommand extends AbstractMusicCommand {
public class VoteSkipCommand extends MusicCommand {
@Override
public boolean isEnabled() {
@@ -6,15 +6,15 @@ package me.bobert.netneutrality.command.react;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMessageMenuCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.impl.MessageMenuCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.tasks.TaskManager;
import me.bobert.netneutrality.tasks.emoji.EmojiReactionRoleTask;
import me.bobert.netneutrality.tasks.reaction.EmojiRoleFirstStep;
import net.dv8tion.jda.api.entities.Message;
public class CreateEmojiReaction extends AbstractMessageMenuCommand {
public class CreateEmojiReaction extends MessageMenuCommand {
@Override
public CommandExecutionResult execute(Message target, CommandContext context) {
EmojiReactionRoleTask task = TaskManager.getInstance().findTaskByPartialId(EmojiReactionRoleTask.class, target.getId()).orElse(null);
@@ -6,15 +6,15 @@ package me.bobert.netneutrality.command.react;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.AbstractMessageMenuCommand;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.impl.MessageMenuCommand;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.tasks.TaskManager;
import me.bobert.netneutrality.tasks.emoji.EmojiReactionRoleTask;
import me.bobert.netneutrality.tasks.reaction.EmojiRoleModify;
import net.dv8tion.jda.api.entities.Message;
public class ModifyEmojiReaction extends AbstractMessageMenuCommand {
public class ModifyEmojiReaction extends MessageMenuCommand {
@Override
public CommandExecutionResult execute(Message target, CommandContext context) {
@@ -6,12 +6,12 @@ package me.bobert.netneutrality.context;
*/
import me.bobert.netneutrality.core.context.AbstractContext;
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.events.Event;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import net.dv8tion.jda.api.utils.messages.MessageEditData;
@@ -97,7 +97,7 @@ public class AsyncContext extends AbstractContext {
}
@Override
public void reply(MessageCreateData messageCreateData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
public void reply(MessageCreateData messageCreateData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
if (hook != null) {
hook.sendMessage(messageCreateData).queue();
}
@@ -118,7 +118,7 @@ public class AsyncContext extends AbstractContext {
}
@Override
public void edit(MessageEditData messageEditData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
public void edit(MessageEditData messageEditData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
if (hook != null) {
hook.editOriginal(messageEditData).queue();
}
@@ -7,10 +7,10 @@ package me.bobert.netneutrality.context;
import me.bobert.netneutrality.core.context.AbstractContext;
import me.bobert.netneutrality.core.context.NoMessageContext;
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.events.Event;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import java.util.List;
@@ -43,7 +43,7 @@ public class MusicChannelContext extends AbstractContext implements NoMessageCon
}
@Override
public void reply(MessageCreateData messageCreateData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
public void reply(MessageCreateData messageCreateData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
if (getChannel().canTalk()) {
getChannel().sendMessage(messageCreateData).setComponents(components).queue(message -> consumer.accept(new AsyncContext(message)));
}
@@ -10,7 +10,10 @@ import me.bobert.netneutrality.core.command.options.MessageCommandOption;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.context.MessageContext;
import me.bobert.netneutrality.utils.Settings;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Mentions;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
@@ -55,6 +58,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
@Override
public List<CommandOption> parseOptions(String[] args, List<OptionData> commandOptions) {
List<CommandOption> options = new ArrayList<>();
int required = commandOptions.stream().filter(OptionData::isRequired).toList().size();
Mentions mentions = message.getMentions();
int roleMentionIndex = 0;
int userMentionIndex = 0;
@@ -71,13 +75,59 @@ public class MessageCommandContext extends CommandContext implements MessageCont
try {
switch (type) {
case STRING -> {
String str = args[index];
int currentOptionIndex = commandOptions.indexOf(data);
boolean nextOptionIsString = false;
if (currentOptionIndex + 1 < commandOptions.size()) {
OptionData nextOption = commandOptions.get(currentOptionIndex + 1);
nextOptionIsString = nextOption.getType() == OptionType.STRING;
}
if ((str.contains("<@") || str.contains("<#")) && str.contains(">")) {
invalidateContext(data, "expected a string at position " + (index + 1) + " but a role/user/channel was provided");
StringBuilder strBuilder = new StringBuilder();
if (!nextOptionIsString) {
while (index < args.length) {
String nextArg = args[index];
if ((nextArg.contains("<@") || nextArg.contains("<#") || nextArg.contains("<@&")) && nextArg.contains(">")) {
break;
}
if (nextArg.equalsIgnoreCase("true") || nextArg.equalsIgnoreCase("false")) {
break;
}
try {
Long.parseLong(nextArg);
break;
} catch (NumberFormatException ignored) {}
try {
Double.parseDouble(nextArg);
break;
} catch (NumberFormatException ignored) {}
if (!strBuilder.isEmpty()) {
strBuilder.append(" ");
}
strBuilder.append(nextArg);
index++;
}
// Update index to skip the concatenated strings
index = index - 1;
} else {
// Next option is also a string, so just take the current argument
if (index < args.length) {
strBuilder.append(args[index]);
}
}
if (strBuilder.isEmpty()) {
break;
}
String str = strBuilder.toString();
if (!choices.isEmpty()) {
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsString().equalsIgnoreCase(str)).toList();
if (matched.isEmpty()) {
@@ -116,8 +166,6 @@ public class MessageCommandContext extends CommandContext implements MessageCont
} else if (max != null && num > max.longValue()) {
value = max.longValue();
}
value = num;
}
case BOOLEAN -> {
String str = args[index];
@@ -129,7 +177,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
invalidateContext(data, "expected true or false");
}
case NUMBER -> {
double num = Long.parseLong(args[index]);
double num = Double.parseDouble(args[index]);
if (!choices.isEmpty()) {
List<Command.Choice> matched = choices.stream().filter(choice -> choice.getAsDouble() == num).toList();
if (matched.isEmpty()) {
@@ -206,7 +254,7 @@ public class MessageCommandContext extends CommandContext implements MessageCont
if (mentions.getChannels().size() > channelMentionIndex) {
GuildChannel channel = mentions.getChannels().get(channelMentionIndex++);
if (!requiredChannelTypes.contains(channel.getType())) {
if (!requiredChannelTypes.isEmpty() && !requiredChannelTypes.contains(channel.getType())) {
invalidateContext(data, "not a valid channel type at index " + (index + 1) +
" , valid types are: " + validTypes(requiredChannelTypes));
break;
@@ -222,7 +270,11 @@ public class MessageCommandContext extends CommandContext implements MessageCont
}
}
} catch (IndexOutOfBoundsException e) {
if (data.isRequired()) {
if (options.size() < required) {
invalidateContext(data, "missing required argument at index " + (index + 1));
}
if (data.isRequired() && index < required) {
// This should never happen because required options are validated before calling parseOptions()
throw new IllegalArgumentException("Required option " + data.getName() + " was not found at index " + index);
}
@@ -237,6 +289,13 @@ public class MessageCommandContext extends CommandContext implements MessageCont
index++;
}
// Check if there are leftover arguments that weren't consumed
if (index < args.length) {
if (options.size() >= required) {
invalidateContext(commandOptions.getLast(), "too many arguments");
}
}
return options;
}
@@ -8,11 +8,8 @@ package me.bobert.netneutrality.context.tasks;
import me.bobert.netneutrality.context.AsyncContext;
import me.bobert.netneutrality.core.context.NoMessageContext;
import me.bobert.netneutrality.core.context.TaskContext;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import java.util.List;
@@ -45,7 +42,7 @@ public class EmojiTaskContext extends TaskContext implements NoMessageContext {
}
@Override
public void reply(MessageCreateData messageCreateData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
public void reply(MessageCreateData messageCreateData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
if (getChannel() != null && getChannel().canTalk()) {
getChannel().sendMessage(messageCreateData).setComponents(components).queue(message -> consumer.accept(new AsyncContext(message)));
}
@@ -5,7 +5,6 @@ package me.bobert.netneutrality.core.command;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
@@ -5,35 +5,178 @@ package me.bobert.netneutrality.core.command;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.options.CommandOptions;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
public class CommandContainer {
public static final CommandContainer NULL_COMMAND = new CommandContainer(null);
private final Command command;
private CommandOptions commandOptions;
private CommandDataImpl commandData;
private List<OptionData> options;
private List<SubcommandData> subcommands;
private List<SubcommandGroupData> subcommandGroups;
public CommandContainer(Command command) {
this.command = command;
if (command != null) {
CommandOptionsBuilder commandOptionsBuilder = new CommandOptionsBuilder(command.getType(), command);
command.registerCommandOptions(commandOptionsBuilder);
initContainer(commandOptionsBuilder);
}
}
public Command getCommand() {
return command;
}
public CommandOptions getCommandOptions() {
return commandOptions;
public SlashCommandData getSlashCommandData() {
return commandData;
}
public void init() {
initOptions();
public List<OptionData> getOptions() {
return options;
}
private void initOptions() {
if (command != null) {
CommandOptionsBuilder commandOptionsBuilder = new CommandOptionsBuilder(command.getType(), command);
command.registerCommandOptions(commandOptionsBuilder);
commandOptions = commandOptionsBuilder.build();
public List<SubcommandData> getSubcommands() {
return subcommands;
}
public List<SubcommandGroupData> getSubcommandGroups() {
return subcommandGroups;
}
private void initContainer(CommandOptionsBuilder builder) {
this.commandData = builder.build();
this.options = commandData.getOptions();
this.subcommands = commandData.getSubcommands();
this.subcommandGroups = commandData.getSubcommandGroups();
}
public boolean isEmpty() {
return options.isEmpty() && subcommands.isEmpty() && subcommandGroups.isEmpty();
}
public String printUsage() {
StringBuilder usage = new StringBuilder();
if (!options.isEmpty()) {
usage.append("- Usage: /").append(command.getCommandName());
for (OptionData option : options) {
usage.append(" <").append(option.getName()).append(">");
}
usage.append(printOptions(options, null, false));
}
if (!subcommands.isEmpty()) {
for (SubcommandData subcommand : subcommands) {
usage.append("- Usage: /").append(command.getCommandName()).append(" ").append(subcommand.getName());
for (OptionData option : subcommand.getOptions()) {
usage.append(" <").append(option.getName()).append(">");
}
usage.append(" (").append(subcommand.getDescription()).append(")");
usage.append(printOptions(subcommand.getOptions(), null, false));
usage.append("\n");
}
}
if (!subcommandGroups.isEmpty()) {
for (SubcommandGroupData subcommandGroup : subcommandGroups) {
usage.append("- Subcommand: /").append(command.getCommandName())
.append(" ").append(subcommandGroup.getName())
.append(" (").append(subcommandGroup.getDescription()).append(")")
.append("\n");
for (SubcommandData subcommand : subcommandGroup.getSubcommands()) {
usage.append(" - Usage: /").append(command.getCommandName())
.append(" ").append(subcommandGroup.getName())
.append(" ").append(subcommand.getName());
for (OptionData option : subcommand.getOptions()) {
usage.append(" <").append(option.getName()).append(">");
}
usage.append(printOptions(subcommand.getOptions(), subcommand.getDescription(), true));
usage.append("\n");
}
}
}
if (!isEmpty()) {
usage.append("\n\n-# *: required argument");
}
return usage.toString();
}
private String printOptions(List<OptionData> options, String description, boolean group) {
StringBuilder usage = new StringBuilder();
if (description != null) {
usage.append(" (").append(description).append(")");
}
for (OptionData option : options) {
usage.append("\n");
if (group) {
usage.append(" ");
}
usage.append(" - ");
if (option.isRequired()) {
usage.append("*");
}
usage.append(option.getName()).append(": ").append(option.getDescription());
if (option.getMinValue() != null) {
usage.append(" [Min value: ").append(option.getMinValue().longValue()).append("]");
}
if (option.getMaxValue() != null) {
usage.append(" [Max value: ").append(option.getMaxValue().longValue()).append("]");
}
if (option.getMinLength() != null) {
usage.append(" [Min length: ").append(option.getMinLength().longValue()).append("]");
}
if (option.getMaxLength() != null) {
usage.append(" [Max length: ").append(option.getMaxLength().longValue()).append("]");
}
List<net.dv8tion.jda.api.interactions.commands.Command.Choice> choices = option.getChoices();
if (!choices.isEmpty()) {
StringJoiner joiner = new StringJoiner(", ");
for (net.dv8tion.jda.api.interactions.commands.Command.Choice choice : choices) {
joiner.add(choice.getAsString());
}
usage.append(" [Available choices: ").append(joiner).append("]");
}
Set<ChannelType> requiredChannelTypes = option.getChannelTypes();
if (!requiredChannelTypes.isEmpty()) {
StringJoiner joiner = new StringJoiner(", ");
for (ChannelType type : requiredChannelTypes) {
joiner.add(type.name());
}
usage.append(" [Required channel types: ").append(joiner).append("]");
}
}
return usage.toString();
}
}
@@ -5,16 +5,19 @@ package me.bobert.netneutrality.core.command;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.utils.ReflectionHelper;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.reflections.Reflections;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class CommandManager {
@@ -30,45 +33,32 @@ public class CommandManager {
logger.info("Loaded {} commands!", commands.size());
}
public static Command getCommand(String commandString) {
return getCommandContainer(commandString).getCommand();
}
public static CommandContainer getCommandContainer(String commandString) {
return commands.getOrDefault(commandString, CommandContainer.NULL_COMMAND);
}
public static void initCommands() {
Set<Class<? extends Command>> classes = new Reflections("me.bobert.netneutrality.command").getSubTypesOf(Command.class);
for (Class<? extends Command> s : classes) {
try {
if (Modifier.isAbstract(s.getModifiers())) {
continue;
}
Command command = s.getConstructor().newInstance();
ReflectionHelper.loadCommands(Command.class, command -> {
if (!command.isEnabled()) {
continue;
logger.info("Skipping command {} as it is disabled", command.getClass().getName());
return;
}
if (command.getCommandName() == null) {
throw new IllegalArgumentException("Command name is null");
logger.error("Failed to load command {}: Command name is null", command.getClass().getName());
return;
}
if (command.getDescription() == null && command.getType() == Command.Type.SLASH) {
throw new IllegalArgumentException("Command description is null");
logger.error("Failed to load command {}: Command description is null", command.getClass().getName());
return;
}
CommandContainer container = new CommandContainer(command);
container.init();
if (!commands.containsKey(command.getCommandName())) {
commands.put(command.getCommandName(), container);
}
} catch (Exception e) {
logger.error("Failed to load command {}: {}", s.getSimpleName(), e.getMessage());
}
}
});
}
public static void registerSlashCommands(JDA jda) {
@@ -83,9 +73,9 @@ public class CommandManager {
logger.debug("Registering slash command: {}", command.getCommandName());
try {
SlashCommandData data = container.getCommandOptions().getSlashCommandData();
SlashCommandData data = container.getSlashCommandData();
data.setDefaultPermissions(command.getSlashCommandPermission());
data.setGuildOnly(command.isGuildOnly());
data.setContexts(command.isGuildOnly() ? Set.of(InteractionContextType.GUILD) : Set.of(InteractionContextType.GUILD, InteractionContextType.BOT_DM));
slashCommands.add(data);
} catch (Exception e) {
@@ -1,30 +1,35 @@
package me.bobert.netneutrality.core.command.options;
package me.bobert.netneutrality.core.command;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.Command;
import net.dv8tion.jda.api.interactions.DiscordLocale;
import net.dv8tion.jda.api.interactions.IntegrationType;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.build.*;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction;
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationMap;
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
public class CommandOptionsBuilder implements SlashCommandData {
private final Command command;
private CommandDataImpl commandData;
public CommandOptionsBuilder(Command.Type type, Command command) {
this.command = command;
if (type == Command.Type.SLASH) {
commandData = (CommandDataImpl) Commands.slash(command.getCommandName(), command.getDescription());
@@ -39,8 +44,8 @@ public class CommandOptionsBuilder implements SlashCommandData {
}
}
public CommandOptions build() {
return new CommandOptions(command, commandData);
public CommandDataImpl build() {
return commandData;
}
@Override
@@ -69,8 +74,13 @@ public class CommandOptionsBuilder implements SlashCommandData {
}
@Override
public @Nonnull SlashCommandData setGuildOnly(boolean guildOnly) {
return commandData.setGuildOnly(guildOnly);
public @Nonnull SlashCommandData setContexts(@Nonnull Collection<InteractionContextType> contexts) {
return commandData.setContexts(contexts);
}
@Override
public @Nonnull SlashCommandData setIntegrationTypes(@Nonnull Collection<IntegrationType> integrationTypes) {
return commandData.setIntegrationTypes(integrationTypes);
}
@Override
@@ -99,8 +109,13 @@ public class CommandOptionsBuilder implements SlashCommandData {
}
@Override
public boolean isGuildOnly() {
return commandData.isGuildOnly();
public @Nonnull Set<InteractionContextType> getContexts() {
return commandData.getContexts();
}
@Override
public @Nonnull Set<IntegrationType> getIntegrationTypes() {
return commandData.getIntegrationTypes();
}
@Override
@@ -8,15 +8,12 @@ package me.bobert.netneutrality.core.command;
import io.sentry.Sentry;
import me.bobert.netneutrality.context.command.SlashCommandContext;
import me.bobert.netneutrality.core.LogHandler;
import me.bobert.netneutrality.core.command.options.CommandOptions;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.context.InteractionContext;
import me.bobert.netneutrality.core.tasks.Task;
import me.bobert.netneutrality.core.tasks.TaskManager;
import me.bobert.netneutrality.exceptions.CommandExecutionException;
import me.bobert.netneutrality.exceptions.GracefulContextError;
import me.bobert.netneutrality.utils.UserFunction;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
@@ -29,7 +26,10 @@ import java.util.List;
import java.util.Map;
import static java.util.function.Predicate.not;
import static me.bobert.netneutrality.core.command.CommandExecutionResult.Result.*;
import static me.bobert.netneutrality.core.command.CommandExecutionResult.Result.ERROR;
import static me.bobert.netneutrality.core.command.CommandExecutionResult.Result.NOACTION;
import static me.bobert.netneutrality.core.command.CommandExecutionResult.Result.TASK;
import static me.bobert.netneutrality.core.command.CommandExecutionResult.Result.WARN;
public class CommandProcessor {
@@ -64,7 +64,7 @@ public class CommandProcessor {
}
try {
logger.info("Context ID: {}", context.getId());
logger.debug("Context ID: {}", context.getId());
logger.info("Executing command {} on guild {}", command.getCommandName(), context.getGuild() == null ? "PrivateMessage" : context.getGuild().getId());
configureSentry(command);
@@ -73,7 +73,7 @@ public class CommandProcessor {
return;
}
if (command.getType() == Command.Type.SLASH && !checkUsage(container.getCommandOptions())) {
if (command.getType() == Command.Type.SLASH && !checkUsage(container)) {
return;
}
@@ -123,10 +123,10 @@ public class CommandProcessor {
}
}
private boolean checkUsage(CommandOptions commandOptions) {
List<SubcommandGroupData> groups = commandOptions.getSubcommandGroups();
List<SubcommandData> subcommands = commandOptions.getSubcommands();
List<OptionData> options = commandOptions.getOptions();
private boolean checkUsage(CommandContainer container) {
List<SubcommandGroupData> groups = container.getSubcommandGroups();
List<SubcommandData> subcommands = container.getSubcommands();
List<OptionData> options = container.getOptions();
String[] possibleCommands = Arrays.stream(context.getFullCommand().split(" ")).skip(1).toArray(String[]::new);
if (possibleCommands.length == 0) {
if (!groups.isEmpty()) {
@@ -203,22 +203,6 @@ public class CommandProcessor {
return false;
}
// check if last option is a string, if it is then combine all remaining strings into one
// ["@user", "you", "are", "banned"] becomes ["@user", "you are banned"]
if (!options.isEmpty() && arguments.size() > 1) {
OptionData last = options.get(options.size() - 1);
if (last.getType() == OptionType.STRING) {
List<String> lastArgs = arguments.stream().skip(options.size() - 1).toList();
arguments.removeAll(lastArgs);
arguments.add(String.join(" ", lastArgs));
}
}
if (arguments.size() > required + optional) {
context.reply(invalidUsage("too many arguments"));
return false;
}
context.setCurrentCommandOptions(arguments.toArray(String[]::new), options);
return true;
}
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.command;
package me.bobert.netneutrality.core.command.impl;
/*
* Copyright (c) anthorob
@@ -6,6 +6,7 @@ package me.bobert.netneutrality.core.command;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.Command;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
@@ -1,11 +1,13 @@
package me.bobert.netneutrality.core.command;
package me.bobert.netneutrality.core.command.impl;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
public abstract class AbstractAdminCommand extends AbstractCommand {
import me.bobert.netneutrality.core.command.CommandCategory;
public abstract class AdminCommand extends AbstractCommand {
@Override
public boolean needAdmin() {
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.command;
package me.bobert.netneutrality.core.command.impl;
/*
* Copyright (c) anthorob
@@ -7,11 +7,13 @@ package me.bobert.netneutrality.core.command;
*/
import me.bobert.netneutrality.context.command.MessageMenuContext;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandCategory;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import net.dv8tion.jda.api.entities.Message;
public abstract class AbstractMessageMenuCommand extends AbstractCommand {
public abstract class MessageMenuCommand extends AbstractCommand {
@Override
public String getDescription() {
return null;
@@ -1,10 +1,11 @@
package me.bobert.netneutrality.core.command;
package me.bobert.netneutrality.core.command.impl;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.CommandCategory;
import me.bobert.netneutrality.db.GSettings;
import me.bobert.netneutrality.db.service.GuildService;
import me.bobert.netneutrality.utils.UserFunction;
@@ -15,7 +16,7 @@ import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
public abstract class AbstractMusicCommand extends AbstractCommand {
public abstract class MusicCommand extends AbstractCommand {
@Override
public boolean needAdmin() {
@@ -63,8 +64,9 @@ public abstract class AbstractMusicCommand extends AbstractCommand {
@Override
public boolean canBeExecutedFrom(MessageChannel channel) {
if (channel instanceof GuildMessageChannel guildMessageChannel) {
if (channel.getType() != ChannelType.TEXT)
if (channel.getType() != ChannelType.TEXT) {
return false;
}
String channelDb = GuildService.get(guildMessageChannel.getGuild()).getGuildSettingService().getSetting(GSettings.MUSIC_CHANNEL);
if (channelDb != null && !channelDb.isEmpty()) {
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.command;
package me.bobert.netneutrality.core.command.impl;
/*
* Copyright (c) anthorob
@@ -7,11 +7,12 @@ package me.bobert.netneutrality.core.command;
*/
import me.bobert.netneutrality.context.command.UserMenuContext;
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
import me.bobert.netneutrality.core.command.CommandExecutionResult;
import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
import me.bobert.netneutrality.core.context.CommandContext;
import net.dv8tion.jda.api.entities.User;
public abstract class AbstractUserMenuCommand extends AbstractCommand {
public abstract class UserMenuCommand extends AbstractCommand {
@Override
public String getDescription() {
return null;
@@ -5,7 +5,11 @@ package me.bobert.netneutrality.core.command.options;
* https://discord.gg/qUa6zNFZsd
*/
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.IMentionable;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@@ -29,10 +33,8 @@ public interface CommandOption {
* <br>This is represented as an {@link Message.Attachment#isEphemeral() ephemeral} attachment which will only be hosted for up to 2 weeks.
* If you want a permanent reference, you must download it.
*
* @throws IllegalStateException
* If this option {@link #getType() type} is not {@link OptionType#ATTACHMENT}
*
* @return {@link net.dv8tion.jda.api.entities.Message.Attachment Attachment}
* @throws IllegalStateException If this option {@link #getType() type} is not {@link OptionType#ATTACHMENT}
*/
Message.Attachment getAsAttachment();
@@ -48,10 +50,8 @@ public interface CommandOption {
/**
* The boolean value.
*
* @throws IllegalStateException
* If this option is not of type {@link OptionType#BOOLEAN BOOLEAN}
*
* @return The boolean value
* @throws IllegalStateException If this option is not of type {@link OptionType#BOOLEAN BOOLEAN}
*/
boolean getAsBoolean();
@@ -59,12 +59,9 @@ public interface CommandOption {
* The long value for this option.
* <br>This will be the ID of any resolved entity such as {@link Role} or {@link Member}.
*
* @throws IllegalStateException
* If this option {@link #getType() type} cannot be converted to a long
* @throws NumberFormatException
* If this option is of type {@link OptionType#STRING STRING} and could not be parsed to a valid long value
*
* @return The long value
* @throws IllegalStateException If this option {@link #getType() type} cannot be converted to a long
* @throws NumberFormatException If this option is of type {@link OptionType#STRING STRING} and could not be parsed to a valid long value
*/
long getAsLong();
@@ -74,36 +71,27 @@ public interface CommandOption {
*
* <p><b>It is highly recommended to assert int values by using {@link OptionData#setRequiredRange(long, long)}</b>
*
* @throws IllegalStateException
* If this option {@link #getType() type} cannot be converted to a long
* @throws NumberFormatException
* If this option is of type {@link OptionType#STRING STRING} and could not be parsed to a valid long value
* @throws ArithmeticException
* If the provided integer value cannot fit into a 32bit signed int
*
* @return The int value
* @throws IllegalStateException If this option {@link #getType() type} cannot be converted to a long
* @throws NumberFormatException If this option is of type {@link OptionType#STRING STRING} and could not be parsed to a valid long value
* @throws ArithmeticException If the provided integer value cannot fit into a 32bit signed int
*/
int getAsInt();
/**
* The double value for this option.
*
* @throws IllegalStateException
* If this option {@link #getType() type} cannot be converted to a double
* @throws NumberFormatException
* If this option is of type {@link OptionType#STRING STRING} and could not be parsed to a valid double value
*
* @return The double value
* @throws IllegalStateException If this option {@link #getType() type} cannot be converted to a double
* @throws NumberFormatException If this option is of type {@link OptionType#STRING STRING} and could not be parsed to a valid double value
*/
double getAsDouble();
/**
* The resolved {@link IMentionable} instance for this option value.
*
* @throws IllegalStateException
* If the mentioned entity is not resolvable
*
* @return The resolved {@link IMentionable}
* @throws IllegalStateException If the mentioned entity is not resolvable
*/
IMentionable getAsMentionable();
@@ -111,42 +99,34 @@ public interface CommandOption {
* The resolved {@link Member} for this option value.
* <br>Note that {@link OptionType#USER OptionType.USER} can also accept users that are not members of a guild, in which case this will be null!
*
* @throws IllegalStateException
* If this option is not of type {@link OptionType#USER USER} or {@link OptionType#MENTIONABLE MENTIONABLE}
*
* @return The resolved {@link Member}, or null
* @throws IllegalStateException If this option is not of type {@link OptionType#USER USER} or {@link OptionType#MENTIONABLE MENTIONABLE}
*/
Member getAsMember();
/**
* The resolved {@link User} for this option value.
*
* @throws IllegalStateException
* If this option is not of type {@link OptionType#USER USER} or
* {@link OptionType#MENTIONABLE MENTIONABLE} without a resolved user
*
* @return The resolved {@link User}
* @throws IllegalStateException If this option is not of type {@link OptionType#USER USER} or
* {@link OptionType#MENTIONABLE MENTIONABLE} without a resolved user
*/
User getAsUser();
/**
* The resolved {@link Role} for this option value.
*
* @throws IllegalStateException
* If this option is not of type {@link OptionType#ROLE ROLE} or
* {@link OptionType#MENTIONABLE MENTIONABLE} without a resolved role
*
* @return The resolved {@link Role}
* @throws IllegalStateException If this option is not of type {@link OptionType#ROLE ROLE} or
* {@link OptionType#MENTIONABLE MENTIONABLE} without a resolved role
*/
Role getAsRole();
/**
* The {@link ChannelType} for the resolved channel.
*
* @throws IllegalStateException
* If this option is not of type {@link OptionType#CHANNEL CHANNEL}
*
* @return The {@link ChannelType}
* @throws IllegalStateException If this option is not of type {@link OptionType#CHANNEL CHANNEL}
*/
ChannelType getChannelType();
@@ -154,11 +134,9 @@ public interface CommandOption {
* The resolved {@link net.dv8tion.jda.api.entities.channel.middleman.GuildChannel} for this option value.
* <br>Note that {@link OptionType#CHANNEL OptionType.CHANNEL} can accept channels of any type!
*
* @throws IllegalStateException
* If this option is not of type {@link OptionType#CHANNEL CHANNEL}
* or could not be resolved for unexpected reasons
*
* @return The resolved {@link net.dv8tion.jda.api.entities.channel.middleman.GuildChannel}
* @throws IllegalStateException If this option is not of type {@link OptionType#CHANNEL CHANNEL}
* or could not be resolved for unexpected reasons
*/
GuildChannelUnion getAsChannel();
}
@@ -1,170 +0,0 @@
package me.bobert.netneutrality.core.command.options;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.command.Command;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;
public class CommandOptions {
private final Command command;
private final CommandDataImpl commandData;
private final List<OptionData> options;
private final List<SubcommandData> subcommands;
private final List<SubcommandGroupData> subcommandGroups;
public CommandOptions(Command command, CommandDataImpl commandData) {
this.command = command;
this.commandData = commandData;
this.options = commandData.getOptions();
this.subcommands = commandData.getSubcommands();
this.subcommandGroups = commandData.getSubcommandGroups();
}
public Command getCommand() {
return command;
}
public SlashCommandData getSlashCommandData() {
return commandData;
}
public List<OptionData> getOptions() {
return options;
}
public List<SubcommandData> getSubcommands() {
return subcommands;
}
public List<SubcommandGroupData> getSubcommandGroups() {
return subcommandGroups;
}
public boolean isEmpty() {
return options.isEmpty() && subcommands.isEmpty() && subcommandGroups.isEmpty();
}
public String printUsage() {
StringBuilder usage = new StringBuilder();
if (!options.isEmpty()) {
usage.append("- Usage: /").append(command.getCommandName());
for (OptionData option : options) {
usage.append(" <").append(option.getName()).append(">");
}
usage.append(printOptions(options, null, false));
}
if (!subcommands.isEmpty()) {
for (SubcommandData subcommand : subcommands) {
usage.append("- Usage: /").append(command.getCommandName()).append(" ").append(subcommand.getName());
for (OptionData option : subcommand.getOptions()) {
usage.append(" <").append(option.getName()).append(">");
}
usage.append(" (").append(subcommand.getDescription()).append(")");
usage.append(printOptions(subcommand.getOptions(), null, false));
usage.append("\n");
}
}
if (!subcommandGroups.isEmpty()) {
for (SubcommandGroupData subcommandGroup : subcommandGroups) {
usage.append("- Subcommand: /").append(command.getCommandName())
.append(" ").append(subcommandGroup.getName())
.append(" (").append(subcommandGroup.getDescription()).append(")")
.append("\n");
for (SubcommandData subcommand : subcommandGroup.getSubcommands()) {
usage.append(" - Usage: /").append(command.getCommandName())
.append(" ").append(subcommandGroup.getName())
.append(" ").append(subcommand.getName());
for (OptionData option : subcommand.getOptions()) {
usage.append(" <").append(option.getName()).append(">");
}
usage.append(printOptions(subcommand.getOptions(), subcommand.getDescription(), true));
usage.append("\n");
}
}
}
if (!isEmpty()) {
usage.append("\n\n-# *: required argument");
}
return usage.toString();
}
private String printOptions(List<OptionData> options, String description, boolean group) {
StringBuilder usage = new StringBuilder();
if (description != null) {
usage.append(" (").append(description).append(")");
}
for (OptionData option : options) {
usage.append("\n");
if (group) usage.append(" ");
usage.append(" - ");
if (option.isRequired()) {
usage.append("*");
}
usage.append(option.getName()).append(": ").append(option.getDescription());
if (option.getMinValue() != null) {
usage.append(" [Min value: ").append(option.getMinValue().longValue()).append("]");
}
if (option.getMaxValue() != null) {
usage.append(" [Max value: ").append(option.getMaxValue().longValue()).append("]");
}
if (option.getMinLength() != null) {
usage.append(" [Min length: ").append(option.getMinLength().longValue()).append("]");
}
if (option.getMaxLength() != null) {
usage.append(" [Max length: ").append(option.getMaxLength().longValue()).append("]");
}
List<net.dv8tion.jda.api.interactions.commands.Command.Choice> choices = option.getChoices();
if (!choices.isEmpty()) {
StringJoiner joiner = new StringJoiner(", ");
for (net.dv8tion.jda.api.interactions.commands.Command.Choice choice : choices) {
joiner.add(choice.getAsString());
}
usage.append(" [Available choices: ").append(joiner).append("]");
}
Set<ChannelType> requiredChannelTypes = option.getChannelTypes();
if (!requiredChannelTypes.isEmpty()) {
StringJoiner joiner = new StringJoiner(", ");
for (ChannelType type : requiredChannelTypes) {
joiner.add(type.name());
}
usage.append(" [Required channel types: ").append(joiner).append("]");
}
}
return usage.toString();
}
}
@@ -5,7 +5,11 @@ package me.bobert.netneutrality.core.command.options;
* https://discord.gg/qUa6zNFZsd
*/
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.IMentionable;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.interactions.commands.OptionType;
@@ -116,6 +120,10 @@ public class MessageCommandOption implements CommandOption {
@Override
public User getAsUser() {
if (value instanceof Member) {
return ((Member) value).getUser();
}
if (value instanceof User) {
return (User) value;
}
@@ -5,7 +5,11 @@ package me.bobert.netneutrality.core.command.options;
* https://discord.gg/qUa6zNFZsd
*/
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.IMentionable;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
@@ -6,7 +6,6 @@ package me.bobert.netneutrality.core.context;
*/
import io.sentry.Sentry;
import me.bobert.netneutrality.context.command.SlashCommandContext;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
@@ -17,7 +17,12 @@ import net.dv8tion.jda.api.interactions.commands.build.OptionData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -26,7 +31,7 @@ public abstract class CommandContext extends AbstractContext {
private Command command;
private SubcommandGroupData subcommandGroup;
private SubcommandData subcommand;
private final Map <OptionData, String> invalidOptions = new HashMap<>();
private final Map<OptionData, String> invalidOptions = new HashMap<>();
private final List<CommandOption> options;
public CommandContext(JDA jda, Guild guild, MessageChannel channel, Member member, User user) {
@@ -70,16 +75,20 @@ public abstract class CommandContext extends AbstractContext {
public <T> T getOption(String name, Supplier<? extends T> fallback, Function<? super CommandOption, ? extends T> resolver) {
Objects.requireNonNull(resolver, "resolver cannot be null");
CommandOption mapping = getOption(name);
if (mapping != null)
if (mapping != null) {
return resolver.apply(mapping);
}
return fallback == null ? null : fallback.get();
}
public <T> T getOption(String name, T fallback, Function<? super CommandOption, ? extends T> resolver) {
Objects.requireNonNull(resolver, "resolver cannot be null");
CommandOption mapping = getOption(name);
if (mapping != null)
if (mapping != null) {
return resolver.apply(mapping);
}
return fallback;
}
@@ -132,7 +141,4 @@ public abstract class CommandContext extends AbstractContext {
public abstract String parseCommandName();
public abstract String getFullCommand();
}
@@ -8,13 +8,17 @@ package me.bobert.netneutrality.core.context;
import me.bobert.netneutrality.context.AsyncContext;
import me.bobert.netneutrality.utils.ContextUtils;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.Event;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import net.dv8tion.jda.api.utils.messages.MessageEditData;
@@ -48,7 +52,7 @@ public interface Context {
void reply(Modal modal);
void reply(MessageCreateData messageCreateData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer);
void reply(MessageCreateData messageCreateData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer);
void defer(boolean ephemeral, Consumer<AsyncContext> consumer);
@@ -66,7 +70,7 @@ public interface Context {
reply(messageCreateData, false, List.of(), asyncMessage -> {});
}
default void reply(MessageCreateData messageCreateData, List<LayoutComponent> components) {
default void reply(MessageCreateData messageCreateData, List<MessageTopLevelComponent> components) {
reply(messageCreateData, false, components, asyncMessage -> {});
}
@@ -90,7 +94,7 @@ public interface Context {
reply(MessageCreateData.fromEmbeds(embeds));
}
default void edit(MessageEditData messageEditData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
default void edit(MessageEditData messageEditData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
if (isAcknowledged() && getInteractionHook() != null) {
getInteractionHook().editOriginal(messageEditData).setComponents(components).queue(message1 -> consumer.accept(new AsyncContext(message1)));
return;
@@ -99,7 +103,7 @@ public interface Context {
reply(MessageCreateData.fromEditData(messageEditData), ephemeral, components, consumer);
}
default void edit(MessageEditData messageEditData, List<LayoutComponent> components) {
default void edit(MessageEditData messageEditData, List<MessageTopLevelComponent> components) {
edit(messageEditData, false, components, asyncMessage -> {});
}
@@ -115,11 +119,11 @@ public interface Context {
edit(List.of(embed), List.of());
}
default void edit(List<MessageEmbed> embeds, List<LayoutComponent> components) {
default void edit(List<MessageEmbed> embeds, List<MessageTopLevelComponent> components) {
edit(MessageEditData.fromEmbeds(embeds), components);
}
default void edit(MessageEmbed embed, List<LayoutComponent> components) {
default void edit(MessageEmbed embed, List<MessageTopLevelComponent> components) {
edit(List.of(embed), components);
}
@@ -135,7 +139,7 @@ public interface Context {
defer(false, consumer);
}
default void replyEphemeral(MessageCreateData messageCreateData, List<LayoutComponent> components) {
default void replyEphemeral(MessageCreateData messageCreateData, List<MessageTopLevelComponent> components) {
reply(messageCreateData, true, components, asyncMessage -> {});
}
@@ -147,7 +151,11 @@ public interface Context {
replyEphemeralWithLimit(message);
}
default void replyEphemeral(String message, List<LayoutComponent> components) {
default void replyEphemeral(String message, MessageTopLevelComponent component) {
replyEphemeral(message, List.of(component));
}
default void replyEphemeral(String message, List<MessageTopLevelComponent> components) {
replyEphemeral(MessageCreateData.fromContent(message), components);
}
@@ -155,7 +163,7 @@ public interface Context {
replyEphemeral(MessageCreateData.fromEmbeds(embeds));
}
default void sendMessageInPrivate(MessageCreateData messageCreateData, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
default void sendMessageInPrivate(MessageCreateData messageCreateData, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
User user = getDiscordUser();
if (user != null) {
user.openPrivateChannel()
@@ -164,11 +172,11 @@ public interface Context {
}
}
default void sendMessageInPrivate(String message, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
default void sendMessageInPrivate(String message, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
sendMessageInPrivate(MessageCreateData.fromContent(message), components, consumer);
}
default void sendMessageInPrivate(MessageCreateData messageCreateData, List<LayoutComponent> components) {
default void sendMessageInPrivate(MessageCreateData messageCreateData, List<MessageTopLevelComponent> components) {
sendMessageInPrivate(messageCreateData, components, asyncContext -> {});
}
@@ -6,12 +6,12 @@ package me.bobert.netneutrality.core.context;
*/
import me.bobert.netneutrality.context.AsyncContext;
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
import net.dv8tion.jda.api.interactions.Interaction;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.callbacks.IModalCallback;
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import java.util.List;
@@ -58,7 +58,7 @@ public interface InteractionContext extends Context {
}
@Override
default void reply(MessageCreateData messageCreateData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
default void reply(MessageCreateData messageCreateData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
if (isAcknowledged()) {
getInteractionHook().sendMessage(messageCreateData).setEphemeral(ephemeral).setComponents(components).queue(message -> consumer.accept(new AsyncContext(message)));
return;
@@ -7,9 +7,9 @@ package me.bobert.netneutrality.core.context;
*/
import me.bobert.netneutrality.context.AsyncContext;
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
import java.util.List;
@@ -32,7 +32,7 @@ public interface MessageContext extends NoMessageContext {
}
@Override
default void reply(MessageCreateData messageCreateData, boolean ephemeral, List<LayoutComponent> components, Consumer<AsyncContext> consumer) {
default void reply(MessageCreateData messageCreateData, boolean ephemeral, List<MessageTopLevelComponent> components, Consumer<AsyncContext> consumer) {
if (ephemeral && getType() != ChannelType.PRIVATE) {
sendMessageInPrivate(messageCreateData, components);
return;
@@ -9,7 +9,7 @@ package me.bobert.netneutrality.core.context;
import me.bobert.netneutrality.context.AsyncContext;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.modals.Modal;
import net.dv8tion.jda.api.modals.Modal;
import java.util.function.Consumer;
@@ -9,6 +9,7 @@ import me.bobert.netneutrality.utils.Settings;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.output.MigrateResult;
public class DatabaseMigration {
private final static Logger logger = LogManager.getLogger(DatabaseMigration.class);
@@ -18,14 +19,17 @@ public class DatabaseMigration {
String dbUser = Settings.getInstance().get("MYSQL_USER", "root");
String dbPass = Settings.getInstance().get("MYSQL_PASSWORD", "");
String dbHost = Settings.getInstance().get("MYSQL_HOST", "localhost");
String dbPort = Settings.getInstance().get("MYSQL_PORT", "3306");
String dbUrl = String.format("jdbc:mysql://%s:%s/%s", dbHost, dbPort, dbName);
try {
logger.info("Running database migrations..");
Flyway flyway = Flyway.configure()
.dataSource(String.format("jdbc:mysql://%s:3306/%s", dbHost, dbName), dbUser, dbPass)
.baselineOnMigrate(true)
.dataSource(dbUrl, dbUser, dbPass)
.load();
flyway.migrate();
MigrateResult result = flyway.migrate();
logger.info("Database migrations finished successfully! (total: {})", result.migrationsExecuted);
} catch (Exception e) {
logger.error(e);
System.exit(1);
@@ -33,9 +33,10 @@ public class SessionManager {
String dbUser = Settings.getInstance().get("MYSQL_USER", "root");
String dbPass = Settings.getInstance().get("MYSQL_PASSWORD", "");
String dbHost = Settings.getInstance().get("MYSQL_HOST", "localhost");
logger.info(String.format("Connecting to database '%s' at %s:3306 with user '%s'", dbName, dbHost, dbUser));
String dbPort = Settings.getInstance().get("MYSQL_PORT", "3306");
logger.info("Connecting to database '{}' at {}:{} with user '{}'", dbName, dbHost, dbPort, dbUser);
settings.put(Environment.JAKARTA_JDBC_URL, String.format("jdbc:mysql://%s:3306/%s", dbHost, dbName));
settings.put(Environment.JAKARTA_JDBC_URL, String.format("jdbc:mysql://%s:%s/%s", dbHost, dbPort, dbName));
settings.put(Environment.JAKARTA_JDBC_USER, dbUser);
settings.put(Environment.JAKARTA_JDBC_PASSWORD, dbPass);
registryBuilder.applySettings(settings);
@@ -5,7 +5,7 @@ package me.bobert.netneutrality.core.tasks;
* https://discord.gg/qUa6zNFZsd
*/
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import me.bobert.netneutrality.core.context.TaskContext;
/**
* Represents a task that has a known ID and is loaded at runtime.
@@ -13,13 +13,5 @@ import net.dv8tion.jda.api.interactions.components.buttons.Button;
*/
public interface BuiltInTask extends Task {
static Button createButton(Class<? extends BuiltInTask> clazz) {
BuiltInTask builtInTask = TaskManager.getInstance().findBuiltInTaskByClass(clazz);
if (builtInTask == null) {
throw new IllegalArgumentException("Task class " + clazz.getName() + " was not registered by the task manager.");
}
return builtInTask.createButton();
}
void executeTask(TaskContext context);
}
@@ -0,0 +1,64 @@
package me.bobert.netneutrality.core.tasks;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import java.util.concurrent.TimeUnit;
public interface ScheduledTask {
class TimeFrame {
private final int interval;
private final TimeUnit unit;
private TimeFrame(int interval, TimeUnit unit) {
this.interval = interval;
this.unit = unit;
}
public static TimeFrame minutely() {
return new TimeFrame(1, TimeUnit.MINUTES);
}
public static TimeFrame minutely(int interval) {
return new TimeFrame(interval, TimeUnit.MINUTES);
}
public static TimeFrame hourly() {
return new TimeFrame(1, TimeUnit.HOURS);
}
public static TimeFrame hourly(int interval) {
return new TimeFrame(interval, TimeUnit.HOURS);
}
public static TimeFrame daily() {
return new TimeFrame(1, TimeUnit.DAYS);
}
public static TimeFrame daily(int interval) {
return new TimeFrame(interval, TimeUnit.DAYS);
}
public static TimeFrame custom(int interval, TimeUnit unit) {
return new TimeFrame(interval, unit);
}
public int getInterval() {
return interval;
}
public TimeUnit getUnit() {
return unit;
}
}
String getId();
TimeFrame getTimeFrame();
void run();
}
@@ -6,7 +6,7 @@ package me.bobert.netneutrality.core.tasks;
* https://discord.gg/qUa6zNFZsd
*/
public interface IStepTask {
public interface StepTask {
/**
* Defines the type of input expected for a step.
@@ -7,8 +7,9 @@ package me.bobert.netneutrality.core.tasks;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.context.TaskContext;
import me.bobert.netneutrality.core.tasks.trait.WithButton;
import me.bobert.netneutrality.core.tasks.trait.WithChildren;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.components.buttons.Button;
import java.time.OffsetDateTime;
@@ -20,6 +21,7 @@ public interface Task {
REMOVE_SELF,
REMOVE_SELF_AND_CHILDREN
}
/**
* This method should generate a unique ID to differentiate it from other tasks.
* <p>
@@ -44,6 +46,7 @@ public interface Task {
/**
* This is only used for debugging purpose.
*
* @return Name of the task
*/
String getName();
@@ -55,14 +58,13 @@ public interface Task {
/**
* When this returns true, the task will get removed by the cleanup thread.
*
* @return If the task is expired
*/
boolean isExpired();
OffsetDateTime getCreationTime();
Button createButton();
/**
* <p>This method is used to reply to the interaction that triggered this task.</p>
* <p>If the task is implementing {@link WithChildren}, the child tasks must be instanciated in this method.</p>
@@ -71,9 +73,20 @@ public interface Task {
/**
* Executes the task.
*
* @param context The context for this task.
*/
Lifecycle execute(TaskContext context);
void insert(CommandContext context);
static Button createButton(Class<? extends WithButton> clazz) {
WithButton withButton = TaskManager.getInstance().findButtonTaskByClass(clazz);
if (withButton == null) {
throw new IllegalArgumentException("Task " + clazz.getName() + " was not registered by the task manager.");
}
return withButton.createButton();
}
}
@@ -11,24 +11,24 @@ import me.bobert.netneutrality.core.context.InteractionContext;
import me.bobert.netneutrality.core.context.TaskContext;
import me.bobert.netneutrality.core.tasks.trait.Deletable;
import me.bobert.netneutrality.core.tasks.trait.NotAcknowledgeable;
import me.bobert.netneutrality.core.tasks.trait.WithButton;
import me.bobert.netneutrality.core.tasks.trait.WithChildren;
import me.bobert.netneutrality.core.tasks.trait.WithParent;
import me.bobert.netneutrality.core.thread.ThreadManager;
import me.bobert.netneutrality.core.thread.ScheduledTaskManager;
import me.bobert.netneutrality.db.service.TaskService;
import me.bobert.netneutrality.exceptions.GracefulContextError;
import me.bobert.netneutrality.exceptions.TaskExecutionException;
import me.bobert.netneutrality.thread.CleanupTaskThread;
import me.bobert.netneutrality.utils.ReflectionHelper;
import net.dv8tion.jda.api.interactions.InteractionHook;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.reflections.Reflections;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
@@ -58,13 +58,14 @@ public class TaskManager {
}
public void init() {
loadBuiltInTasks();
taskService.loadTasks();
logger.info("Initializing task manager...");
ThreadManager.getScheduledExecutor().scheduleWithFixedDelay(new CleanupTaskThread(), 1, 5, TimeUnit.MINUTES);
loadBuiltInTasks();
loadScheduledTasks();
taskService.loadTasks();
}
protected TaskService getTaskService() {
public TaskService getTaskService() {
return taskService;
}
@@ -97,7 +98,7 @@ public class TaskManager {
taskService.persistTask(persistableTask);
}
if (task instanceof IStepTask) {
if (task instanceof StepTask) {
pendingTasks.add(task);
} else {
tasks.put(id, task);
@@ -172,7 +173,7 @@ public class TaskManager {
}
}
logger.debug("Executing task: {}", taskId);
logger.info("Executing task: {}", taskId);
Task.Lifecycle status = task.execute(context);
handleTaskLifecycle(task, status);
@@ -201,7 +202,7 @@ public class TaskManager {
public <E extends Task> Optional<E> findTaskByPartialId(Class<E> clazz, String partialId) {
List<E> tasks = findTasksByPartialId(clazz, partialId);
return Optional.ofNullable(tasks.isEmpty() ? null : tasks.get(0));
return Optional.ofNullable(tasks.isEmpty() ? null : tasks.getFirst());
}
public <E extends Task> List<E> findTasksByPartialId(Class<E> clazz, String partialId) {
@@ -212,10 +213,10 @@ public class TaskManager {
.collect(Collectors.toList());
}
public BuiltInTask findBuiltInTaskByClass(Class<? extends BuiltInTask> clazz) {
public WithButton findButtonTaskByClass(Class<? extends WithButton> clazz) {
return tasks.values().stream()
.filter(clazz::isInstance)
.map(task -> (BuiltInTask) task)
.map(task -> (WithButton) task)
.findFirst()
.orElse(null);
}
@@ -233,22 +234,27 @@ public class TaskManager {
private void loadBuiltInTasks() {
logger.info("Loading built-in tasks...");
Set<Class<? extends BuiltInTask>> classes = new Reflections("me.bobert.netneutrality.tasks").getSubTypesOf(BuiltInTask.class);
for (Class<? extends BuiltInTask> s : classes) {
try {
if (Modifier.isAbstract(s.getModifiers())) {
continue;
ReflectionHelper.loadTasks(BuiltInTask.class, builtInTask -> {
if (builtInTask.isInsertable()) {
logger.info("Loaded task: {}", builtInTask.getClass().getName());
tasks.put(builtInTask.getId(), builtInTask);
}
});
}
BuiltInTask task = s.getConstructor().newInstance();
private void loadScheduledTasks() {
logger.info("Loading scheduled tasks...");
logger.info("Loaded task: {}", task);
tasks.put(task.getId(), task);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
logger.error("Failed to instantiate built-in task", e);
}
ReflectionHelper.loadTasks(ScheduledTask.class, scheduledTask -> {
String taskId = scheduledTask.getId();
if (taskId == null || taskId.trim().isEmpty()) {
logger.error("Cannot load scheduled task {}: task ID is null or empty", scheduledTask.getClass().getName());
return;
}
ScheduledTaskManager.schedule(scheduledTask);
});
}
private void deleteInteraction(Task task) {
@@ -267,7 +273,7 @@ public class TaskManager {
}
private void deleteInteraction(String taskId, Deletable deletable) {
logger.debug("Deleting interaction: {}", deletable);
logger.debug("Deleting interaction: {}", taskId);
CommandContext context = deletableTasksContext.get(taskId);
if (context != null) {
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.tasks;
package me.bobert.netneutrality.core.tasks.impl;
/*
* Copyright (c) anthorob
*
@@ -7,6 +7,7 @@ package me.bobert.netneutrality.core.tasks;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.context.TaskContext;
import me.bobert.netneutrality.core.tasks.BuiltInTask;
public abstract class AbstractBuiltInTask extends AbstractTask implements BuiltInTask {
@@ -35,6 +36,4 @@ public abstract class AbstractBuiltInTask extends AbstractTask implements BuiltI
executeTask(context);
return Lifecycle.BUILTIN;
}
public abstract void executeTask(TaskContext context);
}
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.tasks;
package me.bobert.netneutrality.core.tasks.impl;
/*
* Copyright (c) anthorob
*
@@ -6,6 +6,8 @@ package me.bobert.netneutrality.core.tasks;
*/
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.tasks.PersistableTask;
import me.bobert.netneutrality.core.tasks.TaskManager;
import org.json.JSONObject;
public abstract class AbstractPersistableTask extends AbstractTask implements PersistableTask {
@@ -9,13 +9,11 @@ package me.bobert.netneutrality.core.tasks.impl;
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.context.MessageContext;
import me.bobert.netneutrality.core.context.TaskContext;
import me.bobert.netneutrality.core.tasks.AbstractTask;
import me.bobert.netneutrality.core.tasks.IStepTask;
import me.bobert.netneutrality.core.tasks.StepTask;
import me.bobert.netneutrality.core.tasks.TaskManager;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.fellbaum.jemoji.Emoji;
import net.fellbaum.jemoji.EmojiManager;
@@ -27,7 +25,7 @@ import java.util.UUID;
* Represents a task that consists of multiple sequential steps. The task starts with an initial message (question)
* and expects a user response. Each step can lead to another step, forming a workflow.
*/
public abstract class StepTask extends AbstractTask implements IStepTask {
public abstract class AbstractStepTask extends AbstractTask implements StepTask {
private final Object stepLock = new Object();
private CommandContext commandContext;
private Guild guild;
@@ -110,11 +108,6 @@ public abstract class StepTask extends AbstractTask implements IStepTask {
return getCreationTime().plusMinutes(60).isBefore(OffsetDateTime.now());
}
@Override
public Button createButton() {
return null;
}
/**
* Validates the user input against the expected step type.
*
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.tasks;
package me.bobert.netneutrality.core.tasks.impl;
/*
* Copyright (c) anthorob
*
@@ -6,6 +6,8 @@ package me.bobert.netneutrality.core.tasks;
*/
import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.tasks.Task;
import me.bobert.netneutrality.core.tasks.TaskManager;
import java.time.OffsetDateTime;
import java.util.Objects;
@@ -29,8 +31,12 @@ public abstract class AbstractTask implements Task {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AbstractTask that = (AbstractTask) o;
return Objects.equals(getId(), that.getId());
@@ -5,49 +5,40 @@ package me.bobert.netneutrality.core.tasks.impl;
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.tasks.GenericRandomIdTask;
import me.bobert.netneutrality.core.tasks.Task;
import me.bobert.netneutrality.core.tasks.trait.WithChildren;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import me.bobert.netneutrality.core.tasks.trait.WithButton;
import net.dv8tion.jda.api.components.buttons.Button;
import net.dv8tion.jda.api.components.buttons.ButtonStyle;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import java.time.OffsetDateTime;
import java.util.List;
public abstract class ButtonTask extends GenericRandomIdTask {
public abstract class ButtonTask extends GenericRandomIdTask implements WithButton {
private final ButtonStyle buttonStyle;
private final String buttonLabel;
private Emoji emoji;
public ButtonTask(ButtonStyle buttonStyle, String buttonLabel) {
this.buttonStyle = buttonStyle;
this.buttonLabel = buttonLabel;
}
public Task setEmoji(Emoji emoji) {
this.emoji = emoji;
return this;
}
@Override
public Button createButton() {
if (buttonStyle == null || buttonLabel == null) {
return null;
}
return Button.of(buttonStyle, getId(), buttonLabel);
return Button.of(buttonStyle, getId(), buttonLabel, emoji);
}
@Override
public boolean isExpired() {
return getCreationTime().plusMinutes(15).isBefore(OffsetDateTime.now());
}
public ActionRow createActionRow(List<Task> tasks) {
ActionRow row = ActionRow.of(tasks.stream().map(Task::createButton).toList());
if (this instanceof WithChildren parent) {
parent.addChild(tasks);
}
return row;
}
public ActionRow createActionRow(Task... tasks) {
return createActionRow(List.of(tasks));
}
}
@@ -6,8 +6,6 @@ package me.bobert.netneutrality.core.tasks.impl;
*/
import me.bobert.netneutrality.context.tasks.EmojiTaskContext;
import me.bobert.netneutrality.core.tasks.AbstractPersistableTask;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -54,9 +52,4 @@ public abstract class EmojiTask extends AbstractPersistableTask {
public String getId() {
return String.format(EmojiTaskContext.ID, getGuildId(), getMessageId());
}
@Override
public Button createButton() {
return null;
}
}
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.tasks;
package me.bobert.netneutrality.core.tasks.impl;
/*
* Copyright (c) anthorob
@@ -6,8 +6,6 @@ package me.bobert.netneutrality.core.tasks;
* https://discord.gg/qUa6zNFZsd
*/
import net.dv8tion.jda.api.interactions.components.buttons.Button;
public abstract class GenericCustomIdTask extends AbstractTask {
private final String customId;
@@ -19,9 +17,4 @@ public abstract class GenericCustomIdTask extends AbstractTask {
public String getId() {
return customId;
}
@Override
public Button createButton() {
return null;
}
}
@@ -1,4 +1,4 @@
package me.bobert.netneutrality.core.tasks;
package me.bobert.netneutrality.core.tasks.impl;
/*
* Copyright (c) anthorob
@@ -6,11 +6,11 @@ package me.bobert.netneutrality.core.tasks.impl;
*/
import me.bobert.netneutrality.core.context.TaskContext;
import me.bobert.netneutrality.core.tasks.GenericRandomIdTask;
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Optional;
public abstract class ModalTask extends GenericRandomIdTask {
@@ -19,12 +19,12 @@ public abstract class ModalTask extends GenericRandomIdTask {
return getCreationTime().plusMinutes(5).isBefore(OffsetDateTime.now());
}
public ModalMapping getValue(String key, TaskContext context) {
public Optional<ModalMapping> getValue(String key, TaskContext context) {
List<?> mappings = (List<?>) context.getContextData("values");
return mappings.stream()
.filter(o -> o instanceof ModalMapping)
.map(o -> (ModalMapping) o)
.filter(mapping -> mapping.getId().equals(key))
.findFirst().orElse(null);
.filter(mapping -> mapping.getCustomId().equals(key))
.findFirst();
}
}
@@ -0,0 +1,31 @@
package me.bobert.netneutrality.core.tasks.trait;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.tasks.Task;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
import java.util.List;
public interface WithButton {
Button createButton();
default ActionRow createActionRow(List<Task> tasks) {
ActionRow row = ActionRow.of(tasks.stream().filter(task -> task instanceof WithButton).map(task -> (WithButton) task).map(WithButton::createButton).toList());
if (this instanceof WithChildren parent) {
parent.addChild(tasks);
}
return row;
}
default ActionRow createActionRow(Task... tasks) {
return createActionRow(List.of(tasks));
}
}
@@ -7,8 +7,8 @@ package me.bobert.netneutrality.core.thread;
*/
import me.bobert.netneutrality.exceptions.ExecutorException;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;
@@ -22,7 +22,7 @@ public class BaseThreadFactory implements ThreadFactory {
}
@Override
public Thread newThread(@NotNull Runnable r) {
public Thread newThread(@Nonnull Runnable r) {
Thread thread = new Thread(r);
thread.setName(name + "-" + threadId.getAndIncrement());
thread.setUncaughtExceptionHandler(new ExecutorException());
@@ -0,0 +1,64 @@
package me.bobert.netneutrality.core.thread;
/*
* Copyright (c) anthorob
*
* https://discord.gg/qUa6zNFZsd
*/
import me.bobert.netneutrality.core.LogHandler;
import me.bobert.netneutrality.core.tasks.ScheduledTask;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
public class ScheduledTaskManager {
private static final Logger logger = LogManager.getLogger(ScheduledTaskManager.class);
private static final ScheduledExecutorService executorService = ThreadManager.getScheduledExecutor();
private static final Map<String, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();
private ScheduledTaskManager() {}
public static void schedule(ScheduledTask task) {
String taskId = task.getId();
if (scheduledTasks.containsKey(taskId)) {
logger.warn("Task {} is already scheduled.", taskId);
return;
}
ScheduledTask.TimeFrame timeFrame = task.getTimeFrame();
Runnable runnable = () -> {
logger.info("Executing scheduled task: {}", taskId);
try {
task.run();
} catch (Exception e) {
logger.error("An exception was thrown while executing scheduled task {}", taskId);
LogHandler.log(e);
}
};
ScheduledFuture<?> future = executorService.scheduleWithFixedDelay(
runnable,
1,
timeFrame.getInterval(),
timeFrame.getUnit()
);
scheduledTasks.put(taskId, future);
logger.info("Successfully scheduled task: {} with interval {} {}",
taskId, timeFrame.getInterval(), timeFrame.getUnit());
}
public static void cancelAll() {
logger.info("Cancelling all {} scheduled tasks", scheduledTasks.size());
scheduledTasks.forEach((id, future) -> future.cancel(false));
scheduledTasks.clear();
}
}
@@ -6,7 +6,11 @@ package me.bobert.netneutrality.core.thread;
*/
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadManager {
@@ -38,11 +42,9 @@ public class ThreadManager {
ex.shutdown();
ex.awaitTermination(1, TimeUnit.SECONDS);
}
}
catch (InterruptedException e) {
} catch (InterruptedException e) {
System.err.println("[Executor] Running tasks interrupted");
}
finally {
} finally {
executors.forEach((name, ex) -> {
if (!ex.isTerminated()) {
System.err.println("[Executor: " + name + "] Forcing shutdown of running tasks..");
@@ -24,7 +24,7 @@ public interface Repository<O> {
default void save(O entity) {
Transaction transaction = null;
try(Session session = SessionManager.getSessionFactory().openSession()) {
try (Session session = SessionManager.getSessionFactory().openSession()) {
transaction = session.beginTransaction();
session.merge(entity);
transaction.commit();
@@ -6,7 +6,15 @@ package me.bobert.netneutrality.db.entities;
* https://discord.gg/qUa6zNFZsd
*/
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@Entity
@Table(name = "blacklist")
@@ -6,7 +6,11 @@ package me.bobert.netneutrality.db.entities;
* https://discord.gg/qUa6zNFZsd
*/
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.LinkedHashSet;
import java.util.Optional;
@@ -6,7 +6,18 @@ package me.bobert.netneutrality.db.entities;
* https://discord.gg/qUa6zNFZsd
*/
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.NamedQueries;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
@Entity
@Table(name = "guild_settings")
@@ -6,7 +6,16 @@ package me.bobert.netneutrality.db.entities;
* https://discord.gg/qUa6zNFZsd
*/
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.time.Instant;
@@ -6,7 +6,14 @@ package me.bobert.netneutrality.db.entities;
* https://discord.gg/qUa6zNFZsd
*/
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.Table;
@Entity
@Table(name = "logging")
@@ -46,8 +46,12 @@ public class OLoggingId implements Serializable {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
if (this == o) {
return true;
}
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) {
return false;
}
OLoggingId entity = (OLoggingId) o;
return Objects.equals(this.guildId, entity.guildId) &&
Objects.equals(this.channelId, entity.channelId);
@@ -5,7 +5,14 @@ package me.bobert.netneutrality.db.entities;
* https://discord.gg/qUa6zNFZsd
*/
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
@Entity
@Table(name = "tasks", uniqueConstraints = {@UniqueConstraint(columnNames = {"task_id"})})
@@ -6,7 +6,11 @@ package me.bobert.netneutrality.db.entities;
* https://discord.gg/qUa6zNFZsd
*/
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import org.hibernate.annotations.ColumnDefault;
import java.time.Instant;
@@ -92,7 +92,7 @@ public class BlacklistRepository implements Repository<OBlacklist> {
}
private OBlacklist getWordFromDb(String guildId, String word) {
try(Session session = SessionManager.getSessionFactory().openSession()) {
try (Session session = SessionManager.getSessionFactory().openSession()) {
Query<OBlacklist> query = session.createQuery("SELECT o FROM OBlacklist o WHERE upper(o.word) = upper(:word) AND o.guild.guildId = :guildId", OBlacklist.class);
query.setParameter("guildId", guildId);
query.setParameter("word", word);
@@ -30,7 +30,7 @@ public class GuildRepository implements Repository<OGuild> {
@Override
public OGuild findById(String id) {
try(Session session = SessionManager.getSessionFactory().openSession()) {
try (Session session = SessionManager.getSessionFactory().openSession()) {
Query<OGuild> query = session.createQuery("SELECT o FROM OGuild o WHERE o.guildId = :guildId", OGuild.class);
query.setParameter("guildId", id);
@@ -32,7 +32,7 @@ public class GuildSettingRepository implements Repository<OGuildSetting> {
@Override
public OGuildSetting findById(String id) {
try(Session session = SessionManager.getSessionFactory().openSession()) {
try (Session session = SessionManager.getSessionFactory().openSession()) {
Query<OGuildSetting> query = session.createQuery("SELECT o FROM OGuildSetting o WHERE o.id = :id", OGuildSetting.class);
query.setParameter("id", id);
@@ -35,7 +35,7 @@ public class MessageRepository implements Repository<OLogMessage> {
@Override
public OLogMessage findById(String id) {
try(Session session = SessionManager.getSessionFactory().openSession()) {
try (Session session = SessionManager.getSessionFactory().openSession()) {
Query<OLogMessage> query = session.createQuery("SELECT o FROM OLogMessage o WHERE o.messageId = :messageId", OLogMessage.class);
query.setParameter("messageId", id);
@@ -33,7 +33,7 @@ public class TaskRepository implements Repository<OTask> {
@Override
public OTask findById(String id) {
try(Session session = SessionManager.getSessionFactory().openSession()) {
try (Session session = SessionManager.getSessionFactory().openSession()) {
Query<OTask> query = session.createQuery("SELECT o FROM OTask o WHERE o.taskId = :taskId", OTask.class);
query.setParameter("taskId", id);
@@ -20,7 +20,6 @@ import me.bobert.netneutrality.core.context.CommandContext;
import me.bobert.netneutrality.core.context.Context;
import me.bobert.netneutrality.core.context.TaskContext;
import me.bobert.netneutrality.core.tasks.TaskManager;
import me.bobert.netneutrality.core.thread.ThreadManager;
import me.bobert.netneutrality.db.service.GuildService;
import me.bobert.netneutrality.utils.Settings;
import net.dv8tion.jda.api.entities.Message;
@@ -36,25 +35,27 @@ import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.EventListener;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
import java.util.function.Function;
public class EventsHandler implements EventListener {
private static final Map<Class<? extends Event>, Function<? extends Event, Context>> listeners = new ConcurrentHashMap<>();
private static final Logger logger = LoggerFactory.getLogger(EventsHandler.class);
private final ExecutorService executorService = ThreadManager.getExecutor("events-handler");
static {
addListener(MessageReceivedEvent.class, event -> {
if (event.getAuthor().isBot()) return null;
if (event.isWebhookMessage()) return null;
if (event.getAuthor().isBot()) {
return null;
}
if (event.isWebhookMessage()) {
return null;
}
Message message = event.getMessage();
String rawMessage = message.getContentDisplay().trim();
@@ -111,8 +112,8 @@ public class EventsHandler implements EventListener {
}
@Override
public void onEvent(@NotNull GenericEvent event) {
executorService.submit(() -> handleEvent((Event) event));
public void onEvent(@Nonnull GenericEvent event) {
handleEvent((Event) event);
}
@SuppressWarnings("unchecked")
Loaded 100 of 135 files, more files were not shown because too many files have changed in this diff. Show more