Compare commits

..

223 Commits

Author SHA1 Message Date
8262e81e69 Fixes part 1
There's definitely more to do here, I am dead inside
2023-04-05 20:46:24 -05:00
a48596de8a Fixes bug that caused /list to not display properly 2023-04-05 19:34:17 -06:00
39b9147484 Minor adjustments 2023-04-05 18:13:40 -06:00
5ba81de118 ChatManager now uses ChatRenderer properly 2023-04-05 17:39:52 -06:00
4b3c31f0e9 Git you fucking piece of shit 2023-04-05 16:25:14 -06:00
48aabaa878 Merge remote-tracking branch 'refs/remotes/origin/RELEASE-2023.03' into RELEASE-2023.03 2023-04-05 16:17:38 -06:00
3070ff893e Bugfixes and better admin chat system 2023-04-05 16:13:05 -06:00
b29a176fa9 minor fixing 2023-04-05 16:38:31 -05:00
d1569cb3c0 Luck Perms is actually based but also not based 2023-04-05 15:59:20 -05:00
cb818c0056 Removes the WorldGuardBridge
It was unused after Paul rewrote the rainbow trail.
2023-04-05 13:59:01 -06:00
51c807d318 Bugfixes, begin working on LP tracks 2023-04-05 10:54:39 -06:00
5422ad6ac7 Fucking shit 2023-04-04 20:40:26 -06:00
773805101b Convert tags automatically when loading them in to avoid errors 2023-04-04 20:25:17 -06:00
f474ce99fd Added inheritance to the groups when created by TFM. 2023-04-04 17:42:05 -05:00
dbb289db66 Squashed commit of the following:
commit cc48f93556
Merge: 71127c31 dd373fc9
Author: Paul Reilly <pawereus@gmail.com>
Date:   Fri Mar 31 21:15:34 2023 -0500

    Merge branch 'main' into development

commit dd373fc9aa
Merge: edb3dbfd 41331e71
Author: Paldiu <pawereus@gmail.com>
Date:   Fri Mar 31 18:25:42 2023 -0500

    Merge pull request #307 from AtlasMediaGroup/RELEASE-2022.06.1

    Release 2022.06.1

commit 41331e719d
Author: Video <videogamesm12@gmail.com>
Date:   Wed Mar 8 19:58:14 2023 -0700

    Updates version to 2022.06.1

commit 72c83ba84a
Merge: edb3dbfd 3deaaafb
Author: Video <videogamesm12@gmail.com>
Date:   Wed Mar 8 19:53:51 2023 -0700

    Merge pull request #306 from AtlasMediaGroup/critical-exploit-fix

    Patches critical exploit in the command blocker

commit 3deaaafb88
Author: Video <videogamesm12@gmail.com>
Date:   Wed Mar 8 19:52:30 2023 -0700

    Patches critical exploit
2023-03-31 21:33:08 -05:00
f53ba1bd76 Lots of fixes and cool shit
- Fixes bug that caused login messages to not show properly
- Fixes bug that caused names to now show properly in tab
- Adds the ability for commands to be ignored if plugins that they require aren't present
- Fixes bug that caused the admin list to fail to load properly
- Fixes bug that caused tags to not show properly
- Login messages now use MiniMessage
2023-03-30 23:14:57 -06:00
74408b85bf Fix autoclosing on resultsets 2023-03-30 22:46:45 -05:00
c26e05c392 Fix discrepancies. 2023-03-30 21:21:50 -05:00
ee39e6f534 Now buildable. 2023-03-30 20:36:00 -05:00
8a58782d99 LuckPerms Integration (2/2) 2023-03-30 15:26:35 -05:00
cc244fc4f7 LuckPerms Integration (1.5/2) 2023-03-29 22:00:35 -05:00
65540b7f3a LuckPerms Integration (1/2)
This is part 1 of 2 of the luckperms integration for our switch to permissions.
2023-03-29 00:46:32 -05:00
f91c21cc81 Merge branch 'RELEASE-2023.03' of https://github.com/AtlasMediaGroup/TotalFreedomMod into RELEASE-2023.03 2023-03-27 23:27:22 -06:00
6c983f6b97 I was on a development roll and now I need to sleep
- Removes commands /aec, /attributelist, /reactionbar, /playtime, /settotalvotes, /status
- Removes unused activity log functionality
- Migrates many more commands to use MiniMessage
- Merges /disguisetoggle with /toggle
- Reimplements explosive arrows in a much better way
2023-03-27 23:23:34 -06:00
1e97273e01 Fixed commas breaking notes. 2023-03-27 21:02:30 -05:00
922a2bcc76 Change trailer from blocks to particles. 2023-03-27 20:35:16 -05:00
34269bde09 Please read the commit description for a full changelog
- Reimplements the clownfish toggle in a much better way
- Completely rewrites the plugin's chat formatting system
- Tags now use MiniMessage instead of color codes. New tags are automatically converted.
- /adminchat now uses MiniMessage for its messages
- /autoclear and /autotp now use MiniMessage for their messages
- /banip now uses MiniMessage for its messages
- /bird now uses MiniMessage for its messages (and also now shows a rainbow message)
- /blockcmd now uses MiniMessage for its messages
- /clownfish now uses MiniMessage for its messages
- /notes now uses MiniMessage for its messages
- /op now uses MiniMessage for its messages
- /plc now uses MiniMessage for its messages
- Fixes bug in /stop where the stop message was not showing properly
- Condenses /tagrainbow into /tag and integrates /tag gradient into /tag set using MiniMessage
- /toggle now uses MiniMessage for its messages
- /tossmob now uses MiniMessage for its messages
- /unban, /unbanip, and /unbanname now use MiniMessage for its messages
- /unblockcmd now uses MiniMessage for its messages
- /uncage now uses MiniMessage for its messages
- /undisguiseall now uses MiniMessage for its messages
- /unlinkdiscord now uses MiniMessage for its messages
- /unmute now uses MiniMessage for its messages
- /vanish now uses MiniMessage for its messages
- /vote now partially uses MiniMessage for its messages
- /warn now uses MiniMessage for its messages
- Deprecates FreedomCommand.msg(String) for now
2023-03-27 18:42:43 -06:00
922fa4a34f Whoops lol 2023-03-26 21:59:17 -06:00
ccf572315f Read the commit description
- Admin chat formats now use MiniMessage
- Tab header and footers now use MiniMessage
- Certain titles from the plugin now use MiniMessage
- More commands now use MiniMessage
2023-03-26 21:56:38 -06:00
733f668145 Read the commit details for more information
- Removes several old unused commands
- Begins implementing MiniMessage into several commands
2023-03-26 19:49:31 -06:00
2cd107c317 Even more commands use Adventure now. Includes a bugfix for /creative. 2023-03-26 17:13:05 -06:00
e4782a3542 Changes several commands to use Adventure 2023-03-26 16:28:12 -06:00
77d65e80f8 Removes useless fucking command 2023-03-26 15:28:22 -06:00
3644ba33a5 This is interferring with testing and is pointless 2023-03-26 12:32:28 -06:00
f25d69c5fa Fixer upper 2023-03-17 22:10:32 -05:00
9dbe30aaa7 i can't think but this may be right 2023-03-16 13:19:37 -05:00
1a28facc56 Made some adjustments; still more to do. 2023-03-11 18:36:15 -06:00
e82a90c0dc [SHOP] Reverts previous bugfix. There's clearly something else going on that I didn't pick up on 2023-03-11 02:58:23 -07:00
f8e09665f5 [SHOP] Fixes bug where not having the Shop enabled would cause an error to be thrown then the server is shutting down 2023-03-11 02:55:51 -07:00
a5135ef641 [DISCORD] Lots and lots of bugfixes
- Fixes bug where sending any messages through Discord would result in errors about roles
- Fixes bug where attempting to send any messages to Discord just didn't work
- Discord integration now shows main chat messages in color
2023-03-11 02:38:33 -07:00
071d19c5e0 [COMMONS] Fixes minor bug that caused /tpr to teleport you partially into the ground
Alco wouldn't stop annoying me about this.
2023-03-11 01:08:27 -07:00
2e7756ed0f [COMMONS] Bugfixes, cleanup, and a much-needed clownfish tweak
- Fixes bug that caused non-shop items (like the mob tosser) to not work if the Shop plugin is not already installed
- Finally makes the fucking clownfish something that can be turned down in the sound settings by having it play the sound at the Player sound category
2023-03-11 00:55:02 -07:00
5332dc88cd My life sucks
- Fixes mistake that caused the shop plugin to not enable properly
- Fixes issue that caused the Discord integration to block the main thread when it shouldn't
- Removes old legacy code that still relied on JDA
- Fixes issue that caused slash commands to fail to register properly
2023-03-11 00:27:43 -07:00
631b691518 General corrections
- Removes JDA as a dependency as we do not use that shit
- Fixes fuck-up on my end where I didn't think Paul used the libraries part of spigot.yml but he actually did
2023-03-10 23:52:24 -07:00
982a991fb0 Video man enters the scene
- Fixes multiple issues that were preventing the project from building
- Fixes an issue that was causing project build class files to be included in git commits
2023-03-10 23:41:06 -07:00
adbad1ad9b Update TFD4J.java
Forgot to init the bot LMFAO!!! RETARD.
2023-03-10 20:17:38 -06:00
cbd3caaab3 Another fix 2023-03-10 19:27:20 -06:00
49696f0c30 Minor fix 2023-03-10 19:25:18 -06:00
3a96c853d2 Cyclic Dependency Patch
- Fixed cyclic dependencies
- Added a TFShoppe class for effective plugin initialization
- Registered discord commands, did not before
- Added SLF4J loggers for module logging.
2023-03-10 19:21:03 -06:00
b5804c7eb1 Attempt to fix maven compiler issues 2023-03-09 09:41:13 -06:00
f9ecebd5c9 Fix Minor Discrepancy 2023-03-09 09:36:59 -06:00
3a6e7921cc Merge branch 'development' into RELEASE-2023.03 2023-03-09 09:13:44 -06:00
b7ea1b8b3e 2023.03 update 2 / 2
I think we're done!!!
2023-03-09 03:50:47 -06:00
2265783afb Part 1 / 2
Only thing left is to fix all the code issues from moving out the discord and shop implementations.
2023-03-09 01:42:18 -06:00
71127c3152 Add configuration option for disabling books (#275)
FS-458

Co-authored-by: Video <videogamesm12@gmail.com>
Co-authored-by: Paldiu <pawereus@gmail.com>
2023-02-20 23:39:40 +00:00
f53696aa9e dissc 2023-02-16 20:28:38 -06:00
ea60be4c48 Implemenn
ababa stuff
2023-02-16 18:33:25 -06:00
3bd177ea6f Bump actions/setup-java from 3.6.0 to 3.9.0 (#291)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3.6.0 to 3.9.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3.6.0...v3.9.0)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
2023-01-07 20:21:19 +00:00
1c0b768e4f Add logging to ro command - FS-233 (#282)
* Add logging to ro command - FS-233

* Create a variable for API instead of calling method every time

Co-authored-by: Paldiu <pawereus@gmail.com>
Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
2023-01-07 18:31:11 +00:00
67b0656e61 Merge pull request #285 from AtlasMediaGroup/fs24
Resolves many issues in FS-24 and cleans up code
2023-01-06 20:37:26 -06:00
b3e1a8b528 Aggressive debloat
- Removes unused Logviewer functionality
- Removes several unused bits of code from FPlayer
- Changes the build configuration to not shade in org.apache.commons:commons-lang3, commons-io.commons-io,
  jetbrains.annotation, and org.javassist:javassist, opting instead to load them in on runtime using a
  little-known Spigot trick
2022-11-21 07:09:59 -07:00
99a5897d44 Go fuck yourself Codacy
Codacy complained about me forgetting a "default" case in my rewrite of /moblimiter, so I have to do this shit.
2022-11-20 23:02:00 -07:00
9064f4b1f2 A few more changes
- Cleans up /potion a tiny bit
- Rewrites part of /moblimiter
- Resolves FS-346 by cleaning up /setlever
- Modernizes /opall a bit
- Changes more components to use Adventure
2022-11-20 22:57:31 -07:00
2698cbf46d Too much shit to list in the commit name
- Removes ancient unused code
- General code cleanup in some places
- Rewrites a few components to use Adventure (testing needed)
- Rewrites a few commands to use more modern Java features like Streams
- Fixes oversight where vanishing still worked by names and not UUIDs
- Removes unused Pterodactyl integration
- Removes AutoEject's IP range banning functionality
- Does some minor cleanup to HTTPD's list & players modules
- Fixes ages-old bug in the AntiSpam that caused it to falsely mute players
2022-11-17 01:34:45 -07:00
d3b4feaec9 Merge branch 'development' into fs24 2022-11-16 03:04:35 -07:00
c9adb0c5a8 Codacy is incredibly picky and I hope it burns in hell 2022-11-16 03:01:51 -07:00
cb642eba08 Completely rewrites the Block Inspector, fixes bug in BukkitTelnetBridge caused when Essentials is not installed 2022-11-15 21:32:21 -07:00
fa85b8e160 Merge pull request #284 from AtlasMediaGroup/FS-454
FS-454 - Add expiry to indefinite bans
2022-11-14 17:12:17 -06:00
69a06167a1 Resolves FS-464
Banners had a cap in them to mitigate the effects of chunk bans back in like 2019. This removes that ancient broken cap.
2022-11-14 11:41:38 -07:00
550ff492ee Resolves FS-339 by aggressively rewriting /list and removing ancient unused code 2022-11-14 10:54:59 -07:00
88914632f5 Resolves FS-321 by aggressively rewriting /plugincontrol 2022-11-14 00:38:42 -07:00
47445933f3 Resolves FS-320 and fixes FS-471 2022-11-13 23:20:46 -07:00
94d6f0a872 Attempts to resolve FS-311 and mitigates FS-396 2022-11-13 20:53:50 -07:00
3d67c83ea4 Resolves FS-322 2022-11-13 07:01:30 -07:00
22161b2e90 Resolves FS-331 2022-11-13 06:55:17 -07:00
b1f08c3b7f God fucking dammit 2022-11-13 06:49:32 -07:00
466745d51f Resolves FS-348 2022-11-13 06:46:48 -07:00
98921b975f Resolves FS-340 and improves some surrounding code a bit 2022-11-13 06:44:56 -07:00
35d53ece4e Resolves FS-338 2022-11-13 06:40:36 -07:00
33146fa161 Resolves FS-337 2022-11-13 06:35:44 -07:00
d7fddc3765 Resolves FS-333 2022-11-13 06:31:45 -07:00
0db765af43 Merge branch 'development' into FS-454 2022-11-13 13:31:33 +00:00
f4cb736c17 Resolves FS-325 2022-11-13 06:28:53 -07:00
3763e0728d Resolves FS-341 2022-11-13 06:25:56 -07:00
af18299613 Resolves FS-318 by rewriting the /mute command
This has the fortunate side-effect of also fixing several bugs present in the original command.
2022-11-13 06:19:10 -07:00
f0d6549eec Resolves FS-316 by aggressively rewriting /blockedit
Disclaimer: I did this whilst sleep deprvied.
I didn't know how the fuck NPath is calculated so to play it safe I aggressively rewrote the command. I also took the opportunity to make some of the command's messages more consistent with eachother (using restrict/restore instead of block/unblock).
2022-11-13 04:49:58 -07:00
3b61ba408f Fixes FS-314 2022-11-04 22:58:36 -06:00
af710edc88 Fixes FS-323 by rewriting ride modes to make sense 2022-11-04 22:26:19 -06:00
459a11e638 Fixes FS-349 2022-11-04 21:32:23 -06:00
2e41414358 Fixes FS-343 2022-11-04 21:30:28 -06:00
a3d7fe19a0 Bump codacy/codacy-analysis-cli-action from 4.1.0 to 4.2.0 (#269)
Bumps [codacy/codacy-analysis-cli-action](https://github.com/codacy/codacy-analysis-cli-action) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/codacy/codacy-analysis-cli-action/releases)
- [Commits](https://github.com/codacy/codacy-analysis-cli-action/compare/v4.1.0...v4.2.0)

---
updated-dependencies:
- dependency-name: codacy/codacy-analysis-cli-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
2022-11-03 12:20:56 +00:00
7f4000aff9 Remove indefinite wording for bans with expiry 2022-10-29 22:09:58 +11:00
d2884f007b Remove ParseException from IConfig 2022-10-29 21:36:05 +11:00
58b1890183 Add expiry to indefinite bans 2022-10-29 21:33:00 +11:00
8317b1f881 Remove unused imports, variables and other minor oversights in the Discord bridge (#280)
* Fix player names not being deformatted

* Remove unused imports and variables

* Rectify usage of deprecated methods

* Clarify comment

* Update JDA plugin warning repository URL

* Fix possible NPEs

Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
2022-10-28 13:46:16 +01:00
706e9540ce Remove Broken Downstream Merge Action (#281)
This never worked, let's just remove it.
2022-10-28 13:25:59 +01:00
ac00d36dc6 Bump actions/setup-java from 3.5.1 to 3.6.0 (#279)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3.5.1 to 3.6.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3.5.1...v3.6.0)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-25 00:32:07 +01:00
a2133369d2 Merge pull request #276 from AtlasMediaGroup/FS-460-remove-sit-command-from-tfm
[FS-460] Remove /sit command
2022-10-17 11:32:36 -06:00
48728c9524 Merge branch 'development' into FS-460-remove-sit-command-from-tfm 2022-10-17 09:51:09 -06:00
d343bbc3d7 Merge pull request #268 from AtlasMediaGroup/FS-452-not-fucked
Removes /nh and code associated with it
2022-10-16 20:14:26 -06:00
2c357d1d49 Remove /sit command
FS-460
2022-10-13 19:53:04 +01:00
5246639608 Merge branch 'development' into FS-452-not-fucked 2022-10-12 21:37:18 +01:00
7fb4a477dc Removes TFGuilds integration (#264)
TFGuilds was shitcanned the other day (good riddence), so there's no point in bridging it anymore.

Co-authored-by: Allink <44676012+allinkdev@users.noreply.github.com>
Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
2022-10-12 21:36:49 +01:00
612499ff0a Merge pull request #274 from AtlasMediaGroup/main
Merge Main --> Development for 2022.06 Release.
2022-10-12 17:41:40 +01:00
edb3dbfdbe Merge pull request #273 from AtlasMediaGroup/RELEASE-2022.06
Release 2022.06
2022-10-12 17:37:09 +01:00
a332ecfbea Merge pull request #272 from AtlasMediaGroup/fix-interact-blocking
Remove guard clause causing unintended side effects in interact blocker
2022-10-12 11:29:00 -05:00
7f78549f9d Merge branch 'development' into fix-interact-blocking 2022-10-09 15:15:57 -05:00
fd6f8a2d17 Merge branch 'main' into RELEASE-2022.06 2022-10-08 15:08:52 +01:00
21c84d76d3 Bump actions/setup-java from 3.3.0 to 3.5.1 (#271)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 3.3.0 to 3.5.1.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v3.3.0...v3.5.1)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-08 15:06:56 +01:00
88f53c05b9 Remove guard clause causing unintended side effects 2022-10-05 12:31:05 +01:00
51cc527697 Removes /nh and code associated with it (except this time its based on the right branch) 2022-09-14 19:24:58 -06:00
ae5038ef0f Uplifts pom version to release 2022-09-13 21:54:42 -06:00
ec5aa0304e Uplifts version 2022-09-12 21:42:04 -06:00
ebafc1c669 Hopefully fixing it this time (#119)
This is proving to be more of a PITA than I had expected.
2022-09-12 22:54:44 +01:00
9f8dafb075 Merge pull request #257 from AtlasMediaGroup/update-squash
Update squash
2022-09-12 22:53:58 +01:00
1eaaf5fcdb Fixes bug where the whitelist wasn't working 2022-09-11 22:10:57 -06:00
42458084d7 Untitled bugfix 2022-09-11 16:47:12 -06:00
0cd2886e40 Fixes oversight where not having Essentials installed causes Discord reporting to fail 2022-09-11 16:14:31 -06:00
575568cb05 Fixes severe bug where changes to player data wouldn't save 2022-09-11 15:33:05 -06:00
26be5d0f44 Fixes bug where adminchat messages were duplicated when sent from in-game
Yet another bug discovered during testing before the release was to be cut
2022-09-11 12:47:58 -06:00
7a724c2f13 Fixes bug that prevented /saconfig add from working properly
This popped up during testing right before RC2 was intended to be cut.
2022-09-11 12:12:36 -06:00
9e1aa5d34e Uplifts version to 2022.06-RC2 2022-09-11 11:36:21 -06:00
4564ad0449 Fix SAConfig NPE (originally by Allink) 2022-09-11 11:34:16 -06:00
1ddeb4b621 Merge pull request #263 from AtlasMediaGroup/FS-450
Fixes several bugs caused by potential issues in TFM's admin loading system (FS-450)
2022-09-11 11:30:37 -06:00
a8665a15d4 Merge pull request #262 from AtlasMediaGroup/FS-449
Stabilization Part 4 - The Lost Episode (Remastered) [FS-449]
2022-09-11 11:30:21 -06:00
c0f3712c8d Fixes several bugs caused by any potential issues in TFM's admin loading system 2022-09-11 06:35:32 -06:00
0dd7bc06eb FS-449 2022-09-11 06:04:01 -06:00
4d98108a46 Remove uptime command (#250)
Codacy is struggling for no reason, merging anyway.
2022-09-11 12:31:52 +01:00
02b2810488 Merge remote-tracking branch 'origin/dependabot/maven/development/org.junit.jupiter-junit-jupiter-5.9.0' into megabranch 2022-08-18 23:47:37 +01:00
7e110e8ac6 Merge remote-tracking branch 'origin/dependabot/maven/development/org.javassist-javassist-3.29.1-GA' into megabranch 2022-08-18 23:47:34 +01:00
6d3f365878 Merge remote-tracking branch 'origin/dependabot/maven/development/net.essentialsx-EssentialsX-2.19.6' into megabranch 2022-08-18 23:47:25 +01:00
05bb64ce85 Bump EssentialsX from 2.19.4 to 2.19.6
Bumps [EssentialsX](https://github.com/EssentialsX/Essentials) from 2.19.4 to 2.19.6.
- [Release notes](https://github.com/EssentialsX/Essentials/releases)
- [Commits](https://github.com/EssentialsX/Essentials/compare/2.19.4...2.19.6)

---
updated-dependencies:
- dependency-name: net.essentialsx:EssentialsX
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-15 01:45:49 +00:00
b05238c51f Bump javassist from 3.29.0-GA to 3.29.1-GA
Bumps [javassist](https://github.com/jboss-javassist/javassist) from 3.29.0-GA to 3.29.1-GA.
- [Release notes](https://github.com/jboss-javassist/javassist/releases)
- [Changelog](https://github.com/jboss-javassist/javassist/blob/master/Changes.md)
- [Commits](https://github.com/jboss-javassist/javassist/commits)

---
updated-dependencies:
- dependency-name: org.javassist:javassist
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-12 01:27:24 +00:00
7bda4beab0 Bump worldedit-bukkit from 7.2.10 to 7.2.12
Bumps worldedit-bukkit from 7.2.10 to 7.2.12.

---
updated-dependencies:
- dependency-name: com.sk89q.worldedit:worldedit-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-08 01:42:07 +00:00
97544977b0 Bump junit-jupiter from 5.8.2 to 5.9.0
Bumps [junit-jupiter](https://github.com/junit-team/junit5) from 5.8.2 to 5.9.0.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.8.2...r5.9.0)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-27 01:34:57 +00:00
073356be49 Properly patch Game Master Blocks (#245)
* Break cancelled blocks on interact

* Cancel master blocks

* Add Scissors maven repository

* Remove Scissors repo (it is already included in the AMG repo)

* Remove unused import & add TODO for the 1.19 port
2022-07-16 23:03:23 +01:00
c472c5d5ce Merge pull request #243 from AtlasMediaGroup/beds
Fix beds exploding in the Nether & End dimensions with explosions off
2022-06-20 07:25:27 -05:00
cb401577a4 Fix beds exploding in the Nether & End dimensions with explosions off 2022-06-20 02:46:09 +01:00
9d3165694a Update version 2022-06-17 16:04:55 -05:00
cffb5d9326 Bump codacy/codacy-analysis-cli-action from 4.0.2 to 4.1.0 (#242)
Bumps [codacy/codacy-analysis-cli-action](https://github.com/codacy/codacy-analysis-cli-action) from 4.0.2 to 4.1.0.
- [Release notes](https://github.com/codacy/codacy-analysis-cli-action/releases)
- [Commits](https://github.com/codacy/codacy-analysis-cli-action/compare/4.0.2...v4.1.0)

---
updated-dependencies:
- dependency-name: codacy/codacy-analysis-cli-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-16 12:33:31 +01:00
4e8df0938f Merge pull request #240 from AtlasMediaGroup/add-devs
Add developers and improve code readability
2022-06-08 18:11:49 -05:00
511f172d84 Add developers and improve code readability 2022-06-08 17:57:22 -05:00
bfa8b2a752 Merge pull request #239 from AtlasMediaGroup/FS-222
Unvanish, remove commandspy & set fuckoff radius to 0 for removed admins
2022-06-05 18:47:21 -05:00
594b1f5605 Merge branch 'development' into FS-222 2022-06-05 18:42:51 -05:00
b9ca4f52a2 Merge pull request #238 from AtlasMediaGroup/properly-update
Update rest of dependencies
2022-06-05 18:41:34 -05:00
d298e923b8 Merge pull request #227 from allinkdev/FS-222
Merge allinkdev:FS-222 into AtlasMediaGroup:FS-222
2022-06-06 00:37:29 +01:00
d0d97c0681 Merge branch 'development' into properly-update 2022-06-05 18:36:50 -05:00
2540c7c589 Merge pull request #237 from AtlasMediaGroup/discord
Re-implement most-used commands from the old python bot & other improvements
2022-06-05 18:35:35 -05:00
6bc91fc779 Merge pull request #236 from allinkdev/properly-update
Merge allinkdev:properly-update into AtlasMediaGroup:properly-update
2022-06-06 00:35:22 +01:00
9a54ef66d1 Merge pull request #231 from allinkdev/discord
Merge allinkdev:discord into AtlasMediaGroup:discord branch
2022-06-06 00:31:13 +01:00
722ef5f99a Merge branch 'development' into discord 2022-06-05 23:11:39 +01:00
6bf6eeec91 Merge branch 'development' into properly-update 2022-06-05 22:53:56 +01:00
9df30a9556 Merge branch 'development' into FS-222 2022-06-05 22:52:30 +01:00
83bb892056 Merge pull request #233 from AtlasMediaGroup/fix-readme
Update README to fix badge
2022-06-05 16:51:23 -05:00
62ff195ec5 Merge branch 'development' into fix-readme 2022-06-05 22:48:25 +01:00
495fe79d94 Properly update 2022-06-05 22:44:38 +01:00
422b41dc8d Merge branch 'development' into FS-222 2022-06-05 22:41:02 +01:00
f44a1c7e69 Merge branch 'development' into discord 2022-06-05 22:40:48 +01:00
9f8dd91457 Merge pull request #235 from AtlasMediaGroup/update-deps
Update all dependencies, confirmed working
2022-06-05 16:30:08 -05:00
ee45256764 Update all dependencies, confirmed working 2022-06-05 16:09:23 -05:00
f6faf3b8bc Merge pull request #166 from AtlasMediaGroup/dependabot/maven/development/org.jetbrains-annotations-23.0.0
Bump annotations from 22.0.0 to 23.0.0
2022-06-05 15:38:43 -05:00
8210dafcd3 Bump annotations from 22.0.0 to 23.0.0
Bumps [annotations](https://github.com/JetBrains/java-annotations) from 22.0.0 to 23.0.0.
- [Release notes](https://github.com/JetBrains/java-annotations/releases)
- [Changelog](https://github.com/JetBrains/java-annotations/blob/master/CHANGELOG.md)
- [Commits](https://github.com/JetBrains/java-annotations/compare/22.0.0...23.0.0)

---
updated-dependencies:
- dependency-name: org.jetbrains:annotations
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-05 20:04:42 +00:00
4eb8174aa9 Merge pull request #164 from AtlasMediaGroup/dependabot/maven/development/org.reflections-reflections-0.10.2
Bump reflections from 0.9.12 to 0.10.2
2022-06-05 15:02:37 -05:00
ab309032e5 Update README to fix badge 2022-06-05 14:22:46 -05:00
0db661600f Merge remote-tracking branch 'origin/development' into discord 2022-06-05 20:21:58 +01:00
d94b184703 Bump reflections from 0.9.12 to 0.10.2
Bumps [reflections](https://github.com/ronmamo/reflections) from 0.9.12 to 0.10.2.
- [Release notes](https://github.com/ronmamo/reflections/releases)
- [Commits](https://github.com/ronmamo/reflections/compare/0.9.12...0.10.2)

---
updated-dependencies:
- dependency-name: org.reflections:reflections
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-05 19:18:11 +00:00
c07473ef6d Merge pull request #216 from AtlasMediaGroup/dependabot/maven/development/com.sk89q.worldedit-worldedit-bukkit-7.2.10
Bump worldedit-bukkit from 7.2.8 to 7.2.10
2022-06-05 14:15:46 -05:00
d7261627ff Bump worldedit-bukkit from 7.2.8 to 7.2.10
Bumps worldedit-bukkit from 7.2.8 to 7.2.10.

---
updated-dependencies:
- dependency-name: com.sk89q.worldedit:worldedit-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-05 18:39:30 +00:00
6ac7090fef Merge pull request #213 from AtlasMediaGroup/dependabot/maven/development/org.apache.maven.plugins-maven-compiler-plugin-3.10.1
Bump maven-compiler-plugin from 3.8.1 to 3.10.1
2022-06-05 13:37:09 -05:00
611ee619a0 Merge branch 'development' into FS-222 2022-06-05 18:18:55 +01:00
9d2555cd03 Bump maven-compiler-plugin from 3.8.1 to 3.10.1
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.8.1 to 3.10.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.8.1...maven-compiler-plugin-3.10.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-05 15:31:57 +00:00
3c4b4140ce Bump actions/checkout from 2 to 3 (#202)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-05 16:29:29 +01:00
0f2d596b7a Bump actions/setup-java from 2.3.0 to 3.3.0 (#228)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 2.3.0 to 3.3.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v2.3.0...v3.3.0)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-05 13:43:26 +01:00
dcdaecf9b0 Bump aormsby/Fork-Sync-With-Upstream-action from 2.1 to 3.3 (#230)
Bumps [aormsby/Fork-Sync-With-Upstream-action](https://github.com/aormsby/Fork-Sync-With-Upstream-action) from 2.1 to 3.3.
- [Release notes](https://github.com/aormsby/Fork-Sync-With-Upstream-action/releases)
- [Commits](https://github.com/aormsby/Fork-Sync-With-Upstream-action/compare/v2.1...v3.3)

---
updated-dependencies:
- dependency-name: aormsby/Fork-Sync-With-Upstream-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-05 13:15:26 +01:00
b4b10a3020 A single space 2022-06-05 12:14:49 +01:00
fb259ca9b7 Merge branch 'development' into FS-222 2022-06-05 00:18:55 +01:00
52a39aa992 Bump github/codeql-action from 1 to 2 (#225)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-05 00:15:42 +01:00
b4e7251e3b Merge pull request #232 from AtlasMediaGroup/main
Merge from main into development
2022-06-04 15:06:28 +01:00
0f1fbf9481 Merge pull request #198 from AtlasMediaGroup/RELEASE-2022.02
Release 2022.02
2022-06-04 15:04:16 +01:00
73eb3226ee allow spawn eggs to do SOMETHING (#219)
* allow spawn eggs to do SOMETHING

they now spawn a mob despite the mob having zero nbt from the spawn egg. "it's better than nothing" as one might say.

* mushroom cow moment

* formatting/style + remove extra change

* 💀

💀

* 💀 💀 💀

💀 💀 💀 💀 💀

Co-authored-by: Paldiu <pawereus@gmail.com>
Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
2022-06-04 14:59:35 +01:00
8edc87034f Merge branch 'development' into FS-222 2022-06-03 19:21:07 +01:00
68bcabe5c2 fix httpd log spam (#223)
fix httpd log spam with invalid url encoded strings (lol)

Co-authored-by: Paldiu <pawereus@gmail.com>
Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
2022-06-03 18:27:37 +01:00
ecc92589e9 Bump codacy/codacy-analysis-cli-action from 4.0.0 to 4.0.2 (#209)
Bumps [codacy/codacy-analysis-cli-action](https://github.com/codacy/codacy-analysis-cli-action) from 4.0.0 to 4.0.2.
- [Release notes](https://github.com/codacy/codacy-analysis-cli-action/releases)
- [Commits](https://github.com/codacy/codacy-analysis-cli-action/compare/4.0.0...4.0.2)

---
updated-dependencies:
- dependency-name: codacy/codacy-analysis-cli-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-03 15:04:13 +01:00
bf41d08580 Mention the user who completes the report so we can have their current Discord name (includes their current name & tag in-case they delete their account) 2022-05-26 22:13:57 +01:00
0fc20b6c56 Merge branch 'development' into FS-222 2022-05-26 10:11:01 -05:00
9c91166319 Allow players to report offline players & allow admins to mark reports as completed, deleting them and sending them to an archive channel 2022-05-26 16:10:00 +01:00
09a220e0a2 VPS -> Host 2022-05-25 20:18:01 +01:00
ad9dd42edb Remove unused import 2022-05-25 19:55:25 +01:00
c9f5db0141 Add Discord commands like the old bot 2022-05-25 19:44:45 +01:00
47c30c3283 Add plural to Displayables 2022-05-25 19:41:58 +01:00
6c426644f6 Add uptime & memory related functions to FUtil 2022-05-25 18:49:53 +01:00
72bab1e2ed Add mean averaging to FUtil 2022-05-25 18:41:35 +01:00
1726050d65 Clean up DiscordToMinecraftListener 2022-05-25 17:18:49 +01:00
0fc5b01b29 Clean up message sanitization and properly strip section signs from nicks/messages 2022-05-25 17:15:04 +01:00
dfd90af017 Merge pull request #224 from AtlasMediaGroup/dependabot/maven/development/org.apache.maven.plugins-maven-antrun-plugin-3.1.0
Bump maven-antrun-plugin from 3.0.0 to 3.1.0
2022-05-24 20:47:32 -05:00
5af45a2154 Do the disabling in the admin class, so it works with commands like doom & also disable potion spy 2022-05-03 09:44:36 +01:00
54df28022f Remove offline vanished players & check if the player is online before attempting to get the FPlayer 2022-05-03 09:23:37 +01:00
0326171e85 Unvanish, remove commandspy & set fuckoff radius to 0 for removed admins 2022-05-03 08:58:42 +01:00
d13ecea947 Merge branch 'RELEASE-2022.02' of https://github.com/AtlasMediaGroup/TotalFreedomMod into RELEASE-2022.02 2022-05-01 09:55:58 -05:00
7ec053c867 Adjusted version
Removed "-RELEASE"
2022-05-01 09:55:47 -05:00
1dcc05e7f5 Merge pull request #195 from AtlasMediaGroup/Wild1145-patch-3
Update SECURITY.md
2022-05-01 15:45:16 +01:00
c913b7ae74 Set Maven Shade version to 3.3.0 2022-05-01 09:41:53 -05:00
951f3c91d9 2022.02-RELEASE Versioning
- Changed the version to 2022.02-RELEASE
- Changed the API version to 1.17
2022-05-01 09:31:20 -05:00
b573871c14 Bump maven-antrun-plugin from 3.0.0 to 3.1.0
Bumps [maven-antrun-plugin](https://github.com/apache/maven-antrun-plugin) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/apache/maven-antrun-plugin/releases)
- [Commits](https://github.com/apache/maven-antrun-plugin/compare/maven-antrun-plugin-3.0.0...maven-antrun-plugin-3.1.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-antrun-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-01 11:42:11 +00:00
78654eb5e8 Merge pull request #222 from AtlasMediaGroup/stabilization
Stabilization
2022-05-01 05:39:48 -06:00
adbe125283 increments version 2022-04-20 17:03:13 -06:00
e6a20e1757 fix httpd log spam
fix httpd log spam with invalid url encoded strings (lol)
2022-04-17 14:58:58 -07:00
d71d8edf53 Merge branch 'development' into stabilization 2022-04-15 08:09:05 -06:00
6af9f240f4 Stage 3 of IP -> UUID migration: completely removing the verification system 2022-04-15 07:52:06 -06:00
05745c4210 Stage 2 of IP -> UUID migration: changing the admin list to use UUIDs 2022-04-15 07:09:23 -06:00
98388d0d23 Stage 1 of IP -> UUID migration: changing player data to use UUIDs instead 2022-04-15 06:27:32 -06:00
1da87eeb37 Merge pull request #217 from AtlasMediaGroup/dependabot/maven/development/net.coreprotect-coreprotect-21.2
Bump coreprotect from 20.4 to 21.2
2022-04-15 05:44:33 -06:00
b656925e4f Fixes two bugs related to commands
- Fixes commands not showing up in their own dedicated section in /help
- Fixes duplicate/disorganized commands in the HTTPD help page by overhauling it
2022-04-15 05:28:32 -06:00
d4f44e988c Additional future-proofing 2022-04-15 05:08:11 -06:00
c39c632a67 Removes useless code 2022-04-15 05:03:41 -06:00
733f002a87 Bump to RC02 and fix Netbeans compile issue. 2022-03-27 19:49:16 +01:00
adcccb10e5 Removes dependency on NMS 2022-03-25 14:45:32 -06:00
3fdc0c05bb Bump coreprotect from 20.4 to 21.2
Bumps coreprotect from 20.4 to 21.2.

---
updated-dependencies:
- dependency-name: net.coreprotect:coreprotect
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-22 01:56:59 +00:00
2551d184ca Merge pull request #211 from AtlasMediaGroup/RELEASE-2022.02
Release 2022.02
2022-03-11 18:09:21 -06:00
f9eabf27d5 Merge pull request #205 from AtlasMediaGroup/fs-442
FS-442
2022-03-06 16:15:53 -07:00
76ce98621a Corrected now that we're targeting the 2022.02 relase. 2022-03-06 14:42:45 +00:00
bc0495a68f Update SECURITY.md
Fixes to update the documentation based on actively supported versions.
2022-03-06 14:39:41 +00:00
846154a723 will this work 2022-03-06 14:37:45 +00:00
398 changed files with 8978 additions and 13433 deletions

View File

@ -21,11 +21,11 @@ jobs:
steps: steps:
# Checkout the repository to the GitHub Actions runner # Checkout the repository to the GitHub Actions runner
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI - name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@4.0.0 uses: codacy/codacy-analysis-cli-action@v4.2.0
with: with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations # You can also omit the token and run the tools that support default configurations
@ -41,6 +41,6 @@ jobs:
# Upload the SARIF file generated in the previous step # Upload the SARIF file generated in the previous step
- name: Upload SARIF results file - name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v1 uses: github/codeql-action/upload-sarif@v2
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View File

@ -35,10 +35,10 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Setup Java JDK - name: Setup Java JDK
uses: actions/setup-java@v2.3.0 uses: actions/setup-java@v3.9.0
with: with:
# The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x). Early access versions can be specified in the form of e.g. 14-ea, 14.0.0-ea, or 14.0.0-ea.28 # The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x). Early access versions can be specified in the form of e.g. 14-ea, 14.0.0-ea, or 14.0.0-ea.28
java-version: 17 java-version: 17
@ -46,7 +46,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v1 uses: github/codeql-action/init@v2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -57,7 +57,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v1 uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@ -71,4 +71,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1 uses: github/codeql-action/analyze@v2

View File

@ -1,43 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: Downstream Branch Updates
on:
schedule:
- cron: '20 7 * * *'
# scheduled at 07:00 every Monday and Thursday
workflow_dispatch: # click the button on Github repo!
jobs:
sync_with_upstream:
runs-on: ubuntu-latest
name: Sync main with upstream latest
steps:
# Step 1: run a standard checkout action, provided by github
- name: Checkout main
uses: actions/checkout@v2
with:
ref: main
# submodules: 'recursive' ### may be needed in your situation
# Step 2: run this sync action - specify the upstream repo, upstream branch to sync with, and target sync branch
- name: Pull (Fast-Forward) upstream changes
id: sync
uses: aormsby/Fork-Sync-With-Upstream-action@v2.1
with:
upstream_repository: AtlasMediaGroup/TotalFreedomMod
upstream_branch: main
target_branch: development
git_pull_args: --ff-only # optional arg use, defaults to simple 'pull'
# Step 3: Display a message if 'sync' step had new commits (simple test)
- name: Check for new commits
if: steps.sync.outputs.has_new_commits
run: echo "There were new commits."
# Step 4: Print a helpful timestamp for your records (not required, just nice)
- name: Timestamp
run: date

View File

@ -9,11 +9,11 @@ jobs:
steps: steps:
# Checkout the code # Checkout the code
- uses: actions/checkout@v1 - uses: actions/checkout@v3
# Java 16 Builds # Java 16 Builds
- name: Set up JDK 17 - name: Set up JDK 17
uses: actions/setup-java@v2.3.0 uses: actions/setup-java@v3.9.0
with: with:
java-version: 17 java-version: 17
distribution: 'adopt' distribution: 'adopt'

2
.gitignore vendored
View File

@ -29,7 +29,7 @@ manifest.mf
*.iml *.iml
# Maven excludes # Maven excludes
/target target/
# OS generated files # OS generated files
.DS_Store .DS_Store

View File

@ -1,4 +1,4 @@
# TotalFreedomMod [![Maven-Build](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/maven.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/maven.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/29c0f964da304666bd654bc7b1d556db)](https://www.codacy.com/gh/AtlasMediaGroup/TotalFreedomMod/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AtlasMediaGroup/TotalFreedomMod&utm_campaign=Badge_Grade) [![CodeQL](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml) # TotalFreedomMod [![Maven-Build](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/java17-maven.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/java17-maven.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/29c0f964da304666bd654bc7b1d556db)](https://www.codacy.com/gh/AtlasMediaGroup/TotalFreedomMod/dashboard?utm_source=github.com&utm_medium=referral&utm_content=AtlasMediaGroup/TotalFreedomMod&utm_campaign=Badge_Grade) [![CodeQL](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/AtlasMediaGroup/TotalFreedomMod/actions/workflows/codeql-analysis.yml)
TotalFreedomMod is a CraftBukkit server plugin designed primarily to support the [Official TotalFreedom Minecraft Server](https://totalfreedom.me/). However, you are more than welcome to adapt the source for your own server. TotalFreedomMod is a CraftBukkit server plugin designed primarily to support the [Official TotalFreedom Minecraft Server](https://totalfreedom.me/). However, you are more than welcome to adapt the source for your own server.

View File

@ -9,16 +9,16 @@ In terms of plugin releases, our support matrix is as follows:
### Actively Supported ### Actively Supported
These versions are currently actively supported by our team, and you should expect security patches where appropriate for these versions. These versions are currently actively supported by our team, and you should expect security patches where appropriate for these versions.
| Version | Supported | Support End: | | Version | Supported | Support End: |
| ------------------- | ------------------ | ------------------------------ | | ------------------- | ---------- | ------------------------------ |
| 2021.09 | :white_check_mark: | No Earlier than December 2021 | | 2022.02 | | No Earlier than May 2022 |
### Legacy Supported ### Legacy Supported
These versions are no longer under active development, however we will look to release critical secuirty patches where appropriate. These versions are no longer under active development, however we will look to release critical secuirty patches where appropriate.
| Version | Supported | Support End: | | Version | Supported | Support End: |
| ------------------- | ------------------ | ------------ | | ------------------- | ---------- | ------------ |
| 2021.06 | :white_check_mark: | October 2021 | | 2021.09 | ⚠️ | April 2022 |
### No Longer Supported ### No Longer Supported
@ -26,8 +26,9 @@ These versions are no longer supported at all. It is strongly advised to update
| Version | Supported | Support Ended: | | Version | Supported | Support Ended: |
| ------------------- | ------------------ | ------------------- | | ------------------- | ------------------ | ------------------- |
| 2021.05 | :white_check_mark: | September 2021 | | 2021.06 | :x: | October 2021 |
| 2021.04 | :white_check_mark: | July 2021 | | 2021.05 | :x: | September 2021 |
| 2021.04 | :x: | July 2021 |
| 2021.02 | :x: | 6 June 2021 | | 2021.02 | :x: | 6 June 2021 |
| 2020.11 | :x: | 3 May 2021 | | 2020.11 | :x: | 3 May 2021 |
| 6.0.x (Pre-Release) | :x: | December 2020 | | 6.0.x (Pre-Release) | :x: | December 2020 |

250
commons/pom.xml Normal file
View File

@ -0,0 +1,250 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>me.totalfreedom</groupId>
<artifactId>TotalFreedomMod</artifactId>
<version>2023.03</version>
</parent>
<artifactId>commons</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.luckperms</groupId>
<artifactId>api</artifactId>
<version>5.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.inject</artifactId>
<version>0.3.5</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<!-- Filter resources for build.properties -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<!-- Compiler -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<outputFileName>TotalFreedomMod.jar</outputFileName>
<compilerVersion>17</compilerVersion>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<!-- Git describe -->
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>4.9.10</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
</execution>
<execution>
<id>validate-the-git-infos</id>
<goals>
<goal>validateRevision</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<prefix>git</prefix>
<dateFormat>yyyy-MM-dd HH:mm:ss</dateFormat>
<verbose>false</verbose>
<format>properties</format>
<failOnNoGitDirectory>false</failOnNoGitDirectory>
<failOnUnableToExtractRepoInfo>false</failOnUnableToExtractRepoInfo>
<includeOnlyProperties>
<includeOnlyProperty>git.commit.id.abbrev</includeOnlyProperty>
</includeOnlyProperties>
<gitDescribe>
<skip>false</skip>
<always>false</always>
<abbrev>7</abbrev>
<dirty>-dirty</dirty>
<match>*</match>
</gitDescribe>
</configuration>
</plugin>
<!-- Antrun -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>default-cli</id>
<phase>initialize</phase>
<configuration>
<target>
<propertyfile file="${project.basedir}/src/main/resources/build.properties"
comment="Build information. Edit this to your liking.">
<entry key="buildAuthor" default="unknown"/>
<entry key="buildNumber" default="0"/>
<entry key="buildCodeName" value="${tfm.build.codename}"/>
<entry key="buildVersion" value="${project.version}"/>
<entry key="buildDate" value="${timestamp}"/>
<!--suppress UnresolvedMavenProperty -->
<entry key="buildHead" value="${git.commit.id.abbrev}"/>
</propertyfile>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Properties -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${project.basedir}/src/main/resources/build.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<!-- Buildnumber -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<buildNumberPropertyName>maven.buildnumber</buildNumberPropertyName>
<buildNumberPropertiesFileLocation>${project.basedir}/src/main/resources/build.properties
</buildNumberPropertiesFileLocation>
<format>{0,number,#}</format>
<items>
<item>buildNumber</item>
</items>
</configuration>
</plugin>
<!-- Shade -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<relocations>
<relocation>
<pattern>io.papermc.lib</pattern>
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib
</shadedPattern> <!-- Replace this -->
</relocation>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>me.totalfreedom.totalfreedommod</shadedPattern>
</relocation>
</relocations>
<artifactSet>
<includes>
<include>org.reflections:reflections</include>
<include>io.papermc:paperlib</include>
<include>org.bstats:bstats-bukkit</include>
<include>org.bstats:bstats-base</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -2,8 +2,8 @@ package me.totalfreedom.totalfreedommod;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.util.FUtil; import net.kyori.adventure.text.Component;
import org.bukkit.ChatColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -35,10 +35,10 @@ public class AntiNuke extends FreedomService
if (fPlayer.incrementAndGetBlockDestroyCount() > ConfigEntry.NUKE_MONITOR_COUNT_BREAK.getInteger()) if (fPlayer.incrementAndGetBlockDestroyCount() > ConfigEntry.NUKE_MONITOR_COUNT_BREAK.getInteger())
{ {
FUtil.bcastMsg(player.getName() + " is breaking blocks too fast!", ChatColor.RED); server.broadcast(Component.text(player.getName()).append(Component.text(" is breaking blocks too fast!"))
//plugin.ae.autoEject(player, "You are breaking blocks too fast. Nukers are not permitted on this server."); .color(NamedTextColor.RED));
player.kickPlayer(ChatColor.RED + "You are breaking blocks too fast. Nukers are not permitted on this server."); player.kick(Component.text("You are breaking blocks too fast. Nukers are not permitted on this server.",
NamedTextColor.RED));
fPlayer.resetBlockDestroyCount(); fPlayer.resetBlockDestroyCount();
event.setCancelled(true); event.setCancelled(true);
@ -58,10 +58,9 @@ public class AntiNuke extends FreedomService
if (fPlayer.incrementAndGetBlockPlaceCount() > ConfigEntry.NUKE_MONITOR_COUNT_PLACE.getInteger()) if (fPlayer.incrementAndGetBlockPlaceCount() > ConfigEntry.NUKE_MONITOR_COUNT_PLACE.getInteger())
{ {
FUtil.bcastMsg(player.getName() + " is placing blocks too fast!", ChatColor.RED); server.broadcast(Component.text(player.getName()).append(Component.text(" is placing blocks too fast!"))
//plugin.ae.autoEject(player, "You are placing blocks too fast."); .color(NamedTextColor.RED));
player.kickPlayer(ChatColor.RED + "You are placing blocks too fast."); player.kick(Component.text("You are placing blocks too fast.", NamedTextColor.RED));
fPlayer.resetBlockPlaceCount(); fPlayer.resetBlockPlaceCount();
event.setCancelled(true); event.setCancelled(true);

View File

@ -2,60 +2,48 @@ package me.totalfreedom.totalfreedommod;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.util.FSync; import net.kyori.adventure.text.Component;
import me.totalfreedom.totalfreedommod.util.FUtil; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class AntiSpam extends FreedomService public class AntiSpam extends FreedomService
{ {
private ScheduledThreadPoolExecutor cycle;
public static final int MSG_PER_CYCLE = 8; public static final int MSG_PER_CYCLE = 8;
public static final int TICKS_PER_CYCLE = 2 * 10;
// //
public BukkitTask cycleTask = null;
private Map<Player, Integer> muteCounts = new HashMap<>(); private Map<Player, Integer> muteCounts = new HashMap<>();
@Override @Override
public void onStart() public void onStart()
{ {
new BukkitRunnable() cycle = new ScheduledThreadPoolExecutor(1);
{ cycle.scheduleAtFixedRate(this::cycle, 0, 1, TimeUnit.SECONDS);
@Override
public void run()
{
cycle();
}
}.runTaskTimer(plugin, TICKS_PER_CYCLE, TICKS_PER_CYCLE);
} }
@Override @Override
public void onStop() public void onStop()
{ {
FUtil.cancel(cycleTask); cycle.shutdownNow();
} }
private void cycle() private void cycle()
{ {
for (Player player : server.getOnlinePlayers()) server.getOnlinePlayers().stream().map(player -> plugin.pl.getPlayer(player)).forEach(fPlayer ->
{ {
final FPlayer playerdata = plugin.pl.getPlayer(player);
// TODO: Move each to their own section // TODO: Move each to their own section
playerdata.resetMsgCount(); fPlayer.resetMsgCount();
playerdata.resetBlockDestroyCount(); fPlayer.resetBlockDestroyCount();
playerdata.resetBlockPlaceCount(); fPlayer.resetBlockPlaceCount();
} });
} }
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
@ -81,17 +69,16 @@ public class AntiSpam extends FreedomService
int time = count * minutes; int time = count * minutes;
playerdata.setMuted(true, time); playerdata.setMuted(true, time);
FSync.bcastMsg(String.format("%s has automatically been muted for %d minutes for spamming chat.", server.broadcast(Component.text(player.getName()).append(Component.text(" has been automatically muted for "))
player.getName(), .append(Component.text(time)).append(Component.text(" minutes for spamming chat."))
time), .color(NamedTextColor.RED));
ChatColor.RED);
playerdata.resetMsgCount(); playerdata.resetMsgCount();
event.setCancelled(true); event.setCancelled(true);
} }
else if (playerdata.incrementAndGetMsgCount() > MSG_PER_CYCLE / 2) else if (playerdata.incrementAndGetMsgCount() > MSG_PER_CYCLE / 2)
{ {
FUtil.playerMsg(player, "Please refrain from spamming chat.", ChatColor.GRAY); player.sendMessage(Component.text("Please refrain from spamming chat.", NamedTextColor.GRAY));
event.setCancelled(true); event.setCancelled(true);
} }
@ -100,14 +87,12 @@ public class AntiSpam extends FreedomService
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event)
{ {
String command = event.getMessage();
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final FPlayer fPlayer = plugin.pl.getPlayer(player); final FPlayer fPlayer = plugin.pl.getPlayer(player);
fPlayer.setLastCommand(command);
if (fPlayer.allCommandsBlocked()) if (fPlayer.allCommandsBlocked())
{ {
FUtil.playerMsg(player, "Your commands have been blocked by an admin.", ChatColor.RED); player.sendMessage(Component.text("Your commands have been blocked by an admin.", NamedTextColor.RED));
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
@ -119,7 +104,9 @@ public class AntiSpam extends FreedomService
if (fPlayer.incrementAndGetMsgCount() > MSG_PER_CYCLE) if (fPlayer.incrementAndGetMsgCount() > MSG_PER_CYCLE)
{ {
FUtil.bcastMsg(player.getName() + " was automatically kicked for spamming commands.", ChatColor.RED); server.broadcast(Component.text(player.getName())
.append(Component.text(" was automatically kicked for spamming commands."))
.color(NamedTextColor.RED));
plugin.ae.autoEject(player, "Kicked for spamming commands."); plugin.ae.autoEject(player, "Kicked for spamming commands.");
fPlayer.resetMsgCount(); fPlayer.resetMsgCount();

View File

@ -91,7 +91,7 @@ public class AutoEject extends FreedomService
} }
case STRIKE_THREE: case STRIKE_THREE:
{ {
plugin.bm.addBan(Ban.forPlayerFuzzy(player, Bukkit.getConsoleSender(), null, kickMessage)); plugin.bm.addBan(Ban.forPlayer(player, Bukkit.getConsoleSender(), null, kickMessage));
FUtil.bcastMsg(ChatColor.RED + player.getName() + " has been banned."); FUtil.bcastMsg(ChatColor.RED + player.getName() + " has been banned.");

View File

@ -2,7 +2,6 @@ package me.totalfreedom.totalfreedommod;
import me.totalfreedom.totalfreedommod.banning.IndefiniteBanList; import me.totalfreedom.totalfreedommod.banning.IndefiniteBanList;
import me.totalfreedom.totalfreedommod.config.YamlConfig; import me.totalfreedom.totalfreedommod.config.YamlConfig;
import me.totalfreedom.totalfreedommod.permissions.PermissionConfig;
import me.totalfreedom.totalfreedommod.punishments.PunishmentList; import me.totalfreedom.totalfreedommod.punishments.PunishmentList;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
@ -32,7 +31,6 @@ public class BackupManager extends FreedomService
{ {
createBackups(TotalFreedomMod.CONFIG_FILENAME, true); createBackups(TotalFreedomMod.CONFIG_FILENAME, true);
createBackups(IndefiniteBanList.CONFIG_FILENAME); createBackups(IndefiniteBanList.CONFIG_FILENAME);
createBackups(PermissionConfig.PERMISSIONS_FILENAME, true);
createBackups(PunishmentList.CONFIG_FILENAME); createBackups(PunishmentList.CONFIG_FILENAME);
createBackups("database.db"); createBackups("database.db");
} }

View File

@ -0,0 +1,229 @@
package me.totalfreedom.totalfreedommod;
import com.google.common.base.Strings;
import io.papermc.paper.event.player.AsyncChatEvent;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.api.event.AdminChatEvent;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.Displayable;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.Arrays;
public class ChatManager extends FreedomService
{
@Override
public void onStart()
{
}
@Override
public void onStop()
{
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerChat(AsyncChatEvent event)
{
// Important information for later down the line
String steamrolled = FUtil.steamroll(event.originalMessage());
Player player = event.getPlayer();
FPlayer fPlayer = plugin.pl.getPlayer(player);
// Chat is disabled
if (!ConfigEntry.TOGGLE_CHAT.getBoolean() && !plugin.al.isAdmin(player))
{
event.getPlayer().sendMessage(FUtil.miniMessage("<red>The chat is currently disabled."));
event.setCancelled(true);
return;
}
// Locked up
else if (fPlayer.isLockedUp())
{
event.getPlayer().sendMessage(FUtil.miniMessage("<red>You are locked up and thus can't talk."));
event.setCancelled(true);
return;
}
// Admin chat is enabled
else if (fPlayer.inAdminChat())
{
adminChat(player, steamrolled, true);
event.setCancelled(true);
return;
}
// The event was already cancelled elsewhere or the player was muted
else if (event.isCancelled() || fPlayer.isMuted())
{
return;
}
// Splitter
Component splitter = Component.text("»", NamedTextColor.DARK_GRAY);
// Message
TextComponent.Builder message = Component.text();
// Truncate the message if it's too long
if (steamrolled.length() > 256)
{
steamrolled = steamrolled.substring(0, 256);
}
// Did this because sonarlint was complaining about doing the unboxing in the if statement.
// Something about returning null because it was boxed... I'm not sure.
boolean unboxed = ConfigEntry.FOURCHAN_ENABLED.getBoolean();
// Chat colorization
// -- 4chan mode --
if (steamrolled.startsWith("> ") && unboxed)
{
message.append(Component.text(steamrolled, NamedTextColor.GREEN));
}
// -- Legacy chat colors --
else if (FUtil.containsChatColor(steamrolled))
{
message.append(FUtil.colorizeAsComponent(steamrolled.replace("&k", "")));
}
// -- MiniMessage --
else
{
message.append(FUtil.miniMessage(steamrolled));
}
// This simply filters out shit like &k in a simple but stupid way.
Component filtered = FUtil.miniMessage(FUtil.miniMessage(message.build()));
// Pinging
String steamrolledFiltered = FUtil.steamroll(filtered);
Arrays.stream(steamrolledFiltered.split(" ")).filter(string -> string.startsWith("@")).forEach(possiblePlayer ->
{
Player potential = server.getPlayer(possiblePlayer.replace("@", ""));
// Ping only that particular player
if (potential != null)
{
ping(potential);
}
// Ping everyone (if the person pinging is an admin)
else if (possiblePlayer.equalsIgnoreCase("@everyone") && plugin.al.isAdmin(player))
{
server.getOnlinePlayers().forEach(this::ping);
}
});
event.message(filtered);
event.renderer((source, displayName, msg, viewer) -> FUtil.miniMessage("<tag><nickname> <splitter> <message>",
Placeholder.component("tag", plugin.pl.getPlayer(source).getTag().append(Component.space())),
Placeholder.component("nickname", displayName),
Placeholder.component("splitter", splitter),
Placeholder.component("message", msg)));
}
@EventHandler
public void onAdminChat(AdminChatEvent event)
{
Displayable display = event.getDisplayable();
String flatAbv = FUtil.miniMessage(display.getAbbr());
Component defaultFormat = FUtil.miniMessage("<prefix><dark_gray>[<aqua>ADMIN<dark_gray>] <dark_red><name> <dark_gray>[<rankcolor><rank></rankcolor>]</dark_gray><white>: <gold><message>",
Placeholder.component("prefix", event.getPrefix()),
Placeholder.component("name", event.getName()),
Placeholder.unparsed("rank", flatAbv),
TagResolver.resolver("rankcolor", Tag.styling(getColor(display))),
Placeholder.component("message", event.getMessage()));
plugin.getComponentLogger().info(defaultFormat);
;
server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player ->
{
Admin admin = plugin.al.getAdmin(player);
if (!Strings.isNullOrEmpty(admin.getAcFormat()))
{
String format = admin.getAcFormat();
player.sendMessage(FUtil.miniMessage(format,
Placeholder.component("prefix", event.getPrefix()),
Placeholder.component("name", event.getName()),
Placeholder.unparsed("rank", flatAbv),
TagResolver.resolver("rankcolor", Tag.styling(getColor(display))),
Placeholder.component("message", event.getMessage())));
}
else
{
player.sendMessage(defaultFormat);
}
});
}
public TextColor getColor(Displayable display)
{
return display.getColor();
}
public void adminChat(Component name, Displayable displayable, Component message, boolean async)
{
AdminChatEvent event = new AdminChatEvent(name, displayable, message, async);
event.callEvent();
}
public void adminChat(Key key, Component prefix, Component name, Displayable displayable, Component message, boolean async)
{
AdminChatEvent event = new AdminChatEvent(key, prefix, name, displayable, message, async);
event.callEvent();
}
public void adminChat(CommandSender sender, String message)
{
adminChat(sender, message, false);
}
public void adminChat(CommandSender sender, String message, boolean async)
{
Displayable display = plugin.rm.getDisplay(sender);
adminChat(Component.text(sender.getName()), display, Component.text(message), async);
}
public void reportAction(Player reporter, String reportedName, String report)
{
messageAllAdmins("<red>[REPORTS]</red> <gold><reporter> has reported <reported> for <reason>.",
Placeholder.unparsed("reporter", reporter.getName()),
Placeholder.unparsed("reported", reportedName),
Placeholder.unparsed("reason", report));
}
public void messageAllAdmins(String message, TagResolver... placeholders)
{
Component parsed = FUtil.miniMessage(message, placeholders);
plugin.getComponentLogger().info(parsed);
server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)).forEach(player ->
player.sendMessage(parsed));
}
public void broadcastSplit(String forAdmins, String forOperators, TagResolver... placeholders)
{
messageAllAdmins(forAdmins, placeholders);
server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
player.sendMessage(FUtil.miniMessage(forOperators, placeholders)));
}
public void ping(Player player)
{
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, SoundCategory.MASTER, 1337F, 0.9F);
}
}

View File

@ -0,0 +1,29 @@
package me.totalfreedom.totalfreedommod;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
public class CommandSpy extends FreedomService
{
@Override
public void onStart()
{
}
@Override
public void onStop()
{
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event)
{
server.getOnlinePlayers().stream().filter(player -> plugin.al.isAdmin(player)
&& plugin.al.getAdmin(player).getCommandSpy() && player != event.getPlayer()).forEach(player ->
player.sendMessage(Component.text(event.getPlayer().getName()).append(Component.text(": "))
.append(Component.text(event.getMessage())).color(NamedTextColor.GRAY)));
}
}

View File

@ -11,7 +11,7 @@ public abstract class FreedomService implements Listener
protected final Server server; protected final Server server;
protected final Logger logger; protected final Logger logger;
public FreedomService() protected FreedomService()
{ {
plugin = TotalFreedomMod.getPlugin(); plugin = TotalFreedomMod.getPlugin();
server = plugin.getServer(); server = plugin.getServer();

View File

@ -614,7 +614,7 @@ public class FrontDoor extends FreedomService
{ {
for (Player player : Bukkit.getOnlinePlayers()) for (Player player : Bukkit.getOnlinePlayers())
{ {
plugin.pl.getPlayer(player).setTag("[" + ChatColor.BLUE + "Total" + ChatColor.GOLD + "Freedom" + ChatColor.WHITE + "]"); plugin.pl.getPlayer(player).setTag(FUtil.miniMessage("[" + ChatColor.BLUE + "Total" + ChatColor.GOLD + "Freedom" + ChatColor.WHITE + "]"));
} }
break; break;
} }

View File

@ -1,15 +1,22 @@
package me.totalfreedom.totalfreedommod; package me.totalfreedom.totalfreedommod;
import com.google.common.base.Strings;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.player.PlayerData; import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.util.FConverter;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FSync; import me.totalfreedom.totalfreedommod.util.FSync;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -30,7 +37,6 @@ public class LoginProcess extends FreedomService
private static boolean lockdownEnabled = false; private static boolean lockdownEnabled = false;
public List<String> TELEPORT_ON_JOIN = new ArrayList<>(); public List<String> TELEPORT_ON_JOIN = new ArrayList<>();
public List<String> CLEAR_ON_JOIN = new ArrayList<>(); public List<String> CLEAR_ON_JOIN = new ArrayList<>();
public List<String> CLOWNFISH_TOGGLE = new ArrayList<>();
public static boolean isLockdownEnabled() public static boolean isLockdownEnabled()
{ {
@ -58,13 +64,13 @@ public class LoginProcess extends FreedomService
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent event) public void onPlayerPreLogin(AsyncPlayerPreLoginEvent event)
{ {
final String ip = event.getAddress().getHostAddress().trim(); final Admin entry = plugin.al.getEntryByUuid(event.getUniqueId());
final boolean isAdmin = plugin.al.getEntryByIp(ip) != null; final boolean isAdmin = entry != null && entry.isActive();
// Check if the player is already online // Check if the player is already online
for (Player onlinePlayer : server.getOnlinePlayers()) for (Player onlinePlayer : server.getOnlinePlayers())
{ {
if (!onlinePlayer.getName().equalsIgnoreCase(event.getName())) if (!onlinePlayer.getUniqueId().equals(event.getUniqueId()))
{ {
continue; continue;
} }
@ -86,7 +92,7 @@ public class LoginProcess extends FreedomService
{ {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final String username = player.getName(); final String username = player.getName();
final String ip = event.getAddress().getHostAddress().trim(); final UUID uuid = player.getUniqueId();
// Check username length // Check username length
if (username.length() < MIN_USERNAME_LENGTH || username.length() > MAX_USERNAME_LENGTH) if (username.length() < MIN_USERNAME_LENGTH || username.length() > MAX_USERNAME_LENGTH)
@ -120,7 +126,8 @@ public class LoginProcess extends FreedomService
} }
// Validation below this point // Validation below this point
if (plugin.al.getEntryByIp(ip) != null) // Check if player is admin final Admin entry = plugin.al.getEntryByUuid(uuid);
if (entry != null && entry.isActive()) // Check if player is admin
{ {
// Force-allow log in // Force-allow log in
event.allow(); event.allow();
@ -175,12 +182,9 @@ public class LoginProcess extends FreedomService
} }
// Whitelist // Whitelist
if (plugin.si.isWhitelisted()) if (server.hasWhitelist() && !player.isWhitelisted())
{ {
if (!plugin.si.getWhitelisted().contains(username.toLowerCase())) event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not whitelisted on this server.");
{
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not whitelisted on this server.");
}
} }
} }
@ -199,29 +203,25 @@ public class LoginProcess extends FreedomService
@Override @Override
public void run() public void run()
{ {
for (String line : ConfigEntry.FIRST_JOIN_INFO.getStringList()) ConfigEntry.FIRST_JOIN_INFO.getStringList().forEach(line -> FUtil.playerMsgCooler(player, line));
{
player.sendMessage(FUtil.colorize(line));
}
} }
}.runTaskLater(plugin, 20); }.runTaskLater(plugin, 20);
} }
player.sendTitle(FUtil.colorize(ConfigEntry.SERVER_LOGIN_TITLE.getString()), FUtil.colorize(ConfigEntry.SERVER_LOGIN_SUBTITLE.getString()), 20, 100, 60); FUtil.playerTitle(player, ConfigEntry.SERVER_LOGIN_TITLE.getString(), ConfigEntry.SERVER_LOGIN_SUBTITLE.getString());
player.setOp(true);
if (TELEPORT_ON_JOIN.contains(player.getName()) || ConfigEntry.AUTO_TP.getBoolean()) if (TELEPORT_ON_JOIN.contains(player.getName()) || ConfigEntry.AUTO_TP.getBoolean())
{ {
int x = FUtil.randomInteger(-10000, 10000); int x = FUtil.randomInteger(-10000, 10000);
int z = FUtil.randomInteger(-10000, 10000); int z = FUtil.randomInteger(-10000, 10000);
int y = player.getWorld().getHighestBlockYAt(x, z); int y = player.getWorld().getHighestBlockYAt(x, z) + 1;
Location location = new Location(player.getLocation().getWorld(), x, y, z); Location location = new Location(player.getLocation().getWorld(), x, y, z);
PaperLib.teleportAsync(player, location); PaperLib.teleportAsync(player, location);
player.sendMessage(ChatColor.AQUA + "You have been teleported to a random location automatically."); FUtil.playerMsgCooler(player, "<aqua>You have been automatically teleported to a random location.");
return; return;
} }
if (!playerData.hasVerification() && !playerData.getIps().contains(FUtil.getIp(player))) if (!playerData.getIps().contains(FUtil.getIp(player)))
{ {
playerData.addIp(FUtil.getIp(player)); playerData.addIp(FUtil.getIp(player));
plugin.pl.save(playerData); plugin.pl.save(playerData);
@ -230,35 +230,47 @@ public class LoginProcess extends FreedomService
if (CLEAR_ON_JOIN.contains(player.getName()) || ConfigEntry.AUTO_CLEAR.getBoolean()) if (CLEAR_ON_JOIN.contains(player.getName()) || ConfigEntry.AUTO_CLEAR.getBoolean())
{ {
player.getInventory().clear(); player.getInventory().clear();
player.sendMessage(ChatColor.AQUA + "Your inventory has been cleared automatically."); FUtil.playerMsgCooler(player, "<aqua>Your inventory has been automatically cleared.");
return; return;
} }
if (!ConfigEntry.SERVER_TABLIST_HEADER.getString().isEmpty()) if (!ConfigEntry.SERVER_TABLIST_HEADER.getString().isEmpty())
{ {
player.setPlayerListHeader(FUtil.colorize(ConfigEntry.SERVER_TABLIST_HEADER.getString()).replace("\\n", "\n")); player.sendPlayerListHeader(FUtil.miniMessage(ConfigEntry.SERVER_TABLIST_HEADER.getString()));
} }
if (!ConfigEntry.SERVER_TABLIST_FOOTER.getString().isEmpty()) if (!ConfigEntry.SERVER_TABLIST_FOOTER.getString().isEmpty())
{ {
player.setPlayerListFooter(FUtil.colorize(ConfigEntry.SERVER_TABLIST_FOOTER.getString()).replace("\\n", "\n")); player.sendPlayerListFooter(FUtil.miniMessage(ConfigEntry.SERVER_TABLIST_FOOTER.getString()));
} }
if (!plugin.al.isAdmin(player)) if (!plugin.al.isAdmin(player))
{ {
String tag = playerData.getTag(); Component tag = playerData.getTag();
if (tag != null) if (tag != null)
{ {
fPlayer.setTag(FUtil.colorize(tag)); fPlayer.setTag(tag);
} }
int noteCount = playerData.getNotes().size(); int noteCount = playerData.getNotes().size();
if (noteCount != 0) if (noteCount != 0)
{ {
String noteMessage = "This player has " + noteCount + " admin note" + (noteCount > 1 ? "s" : "") + "."; plugin.cm.messageAllAdmins("<gold>This player has <yellow><count> <gold>admin note<plural>.",
FLog.info(noteMessage); Placeholder.unparsed("count", String.valueOf(noteCount)), Placeholder.unparsed("plural", noteCount > 1 ? "s" : ""));
plugin.al.messageAllAdmins(ChatColor.GOLD + noteMessage); plugin.cm.messageAllAdmins("<gold>Do <yellow>/notes <player> list<gold> to view them.",
plugin.al.messageAllAdmins(ChatColor.GOLD + "Do " + ChatColor.YELLOW + "/notes " + player.getName() + " list" + ChatColor.GOLD + " to view them."); Placeholder.unparsed("player", player.getName()));
}
}
else
{
Admin admin = plugin.al.getAdmin(player);
String format = admin.getAcFormat();
if (!Strings.isNullOrEmpty(format) && FConverter.needsConversion(admin.getAcFormat()))
{
player.sendMessage(FUtil.miniMessage("<green>Converting your admin chat format..."));
admin.setAcFormat(FConverter.convertAdminChatFormat(format));
plugin.al.save(admin);
} }
} }
@ -269,14 +281,14 @@ public class LoginProcess extends FreedomService
{ {
if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean()) if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
{ {
player.sendMessage(ChatColor.RED + "Server is currently closed to non-admins."); FUtil.playerMsgCooler(player, "<red>Server is currently closed to non-admins.");
} }
if (lockdownEnabled) if (lockdownEnabled)
{ {
FUtil.playerMsg(player, "Warning: Server is currenty in lockdown-mode, new players will not be able to join!", ChatColor.RED); FUtil.playerMsgCooler(player, "<red>Warning: Server is currenty in lockdown-mode, new players will not be able to join!");
} }
} }
}.runTaskLater(plugin, 20L); }.runTaskLater(plugin, 20L);
} }
} }

View File

@ -1,11 +1,12 @@
package me.totalfreedom.totalfreedommod; package me.totalfreedom.totalfreedommod;
import java.util.ArrayList; import io.papermc.paper.event.player.AsyncChatEvent;
import java.util.List;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FSync; import me.totalfreedom.totalfreedommod.util.FSync;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -13,13 +14,9 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
public class Muter extends FreedomService public class Muter extends FreedomService
{ {
public final List<String> MUTED_PLAYERS = new ArrayList<>();
@Override @Override
public void onStart() public void onStart()
{ {
@ -31,7 +28,7 @@ public class Muter extends FreedomService
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onAsyncPlayerChatEvent(AsyncPlayerChatEvent event) public void onAsyncPlayerChatEvent(AsyncChatEvent event)
{ {
Player player = event.getPlayer(); Player player = event.getPlayer();
@ -45,11 +42,10 @@ public class Muter extends FreedomService
if (plugin.al.isAdminSync(player)) if (plugin.al.isAdminSync(player))
{ {
fPlayer.setMuted(false); fPlayer.setMuted(false);
MUTED_PLAYERS.remove(player.getName());
return; return;
} }
FSync.playerMsg(event.getPlayer(), ChatColor.RED + "You are muted."); player.sendMessage(Component.text("You are muted.", NamedTextColor.RED));
event.setCancelled(true); event.setCancelled(true);
} }
@ -87,7 +83,7 @@ public class Muter extends FreedomService
if (ConfigEntry.MUTED_BLOCKED_COMMANDS.getStringList().contains(cmdName)) if (ConfigEntry.MUTED_BLOCKED_COMMANDS.getStringList().contains(cmdName))
{ {
player.sendMessage(ChatColor.RED + "That command is blocked while you are muted."); player.sendMessage(Component.text("That command is blocked while you are muted.", NamedTextColor.RED));
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
@ -98,16 +94,4 @@ public class Muter extends FreedomService
FLog.info(String.format("[PREPROCESS_COMMAND] %s(%s): %s", player.getName(), ChatColor.stripColor(player.getDisplayName()), message), true); FLog.info(String.format("[PREPROCESS_COMMAND] %s(%s): %s", player.getName(), ChatColor.stripColor(player.getDisplayName()), message), true);
} }
} }
@EventHandler(priority = EventPriority.LOW)
public void onPlayerJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
FPlayer playerdata = plugin.pl.getPlayer(player);
if (MUTED_PLAYERS.contains(player.getName()))
{
playerdata.setMuted(true);
}
}
} }

View File

@ -1,14 +1,21 @@
package me.totalfreedom.totalfreedommod; package me.totalfreedom.totalfreedommod;
import com.google.gson.Gson;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.server.ServerListPingEvent; import org.bukkit.event.server.ServerListPingEvent;
import java.io.InputStreamReader;
public class ServerPing extends FreedomService public class ServerPing extends FreedomService
{ {
private final Gson gson = new Gson();
private final VersionMeta meta = gson.fromJson(new InputStreamReader(Bukkit.class.getClassLoader().getResourceAsStream("version.json")),VersionMeta.class);
@Override @Override
public void onStart() public void onStart()
{ {
@ -26,51 +33,39 @@ public class ServerPing extends FreedomService
if (plugin.bm.isIpBanned(ip)) if (plugin.bm.isIpBanned(ip))
{ {
event.setMotd(FUtil.colorize(ConfigEntry.SERVER_BAN_MOTD.getString())); event.motd(FUtil.miniMessage(ConfigEntry.SERVER_BAN_MOTD.getString()));
return; return;
} }
if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean()) if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
{ {
event.setMotd(FUtil.colorize(ConfigEntry.SERVER_ADMINMODE_MOTD.getString())); event.motd(FUtil.miniMessage(ConfigEntry.SERVER_ADMINMODE_MOTD.getString()));
return; return;
} }
if (LoginProcess.isLockdownEnabled()) if (LoginProcess.isLockdownEnabled())
{ {
event.setMotd(FUtil.colorize(ConfigEntry.SERVER_LOCKDOWN_MOTD.getString())); event.motd(FUtil.miniMessage(ConfigEntry.SERVER_LOCKDOWN_MOTD.getString()));
return; return;
} }
if (Bukkit.hasWhitelist()) if (Bukkit.hasWhitelist())
{ {
event.setMotd(FUtil.colorize(ConfigEntry.SERVER_WHITELIST_MOTD.getString())); event.motd(FUtil.miniMessage(ConfigEntry.SERVER_WHITELIST_MOTD.getString()));
return; return;
} }
if (Bukkit.getOnlinePlayers().size() >= Bukkit.getMaxPlayers()) if (Bukkit.getOnlinePlayers().size() >= Bukkit.getMaxPlayers())
{ {
event.setMotd(FUtil.colorize(ConfigEntry.SERVER_FULL_MOTD.getString())); event.motd(FUtil.miniMessage(ConfigEntry.SERVER_FULL_MOTD.getString()));
return; return;
} }
String baseMotd = ConfigEntry.SERVER_MOTD.getString().replace("%mcversion%", plugin.si.getVersion()); event.motd(FUtil.miniMessage(ConfigEntry.SERVER_MOTD.getString(), Placeholder.unparsed("version", meta.id)));
baseMotd = baseMotd.replace("\\n", "\n"); }
baseMotd = FUtil.colorize(baseMotd);
if (!ConfigEntry.SERVER_COLORFUL_MOTD.getBoolean()) private static class VersionMeta
{ {
event.setMotd(baseMotd); private String id;
return;
}
// Colorful MOTD
final StringBuilder motd = new StringBuilder();
for (String word : baseMotd.split(" "))
{
motd.append(FUtil.randomChatColor()).append(word).append(" ");
}
event.setMotd(motd.toString().trim());
} }
} }

View File

@ -1,46 +1,23 @@
package me.totalfreedom.totalfreedommod; package me.totalfreedom.totalfreedommod;
import java.io.File;
import java.io.InputStream;
import java.util.Properties;
import me.totalfreedom.totalfreedommod.admin.ActivityLog;
import me.totalfreedom.totalfreedommod.admin.AdminList; import me.totalfreedom.totalfreedommod.admin.AdminList;
import me.totalfreedom.totalfreedommod.api.Aggregator;
import me.totalfreedom.totalfreedommod.api.ShoppeCommons;
import me.totalfreedom.totalfreedommod.api.TFD4JCommons;
import me.totalfreedom.totalfreedommod.banning.BanManager; import me.totalfreedom.totalfreedommod.banning.BanManager;
import me.totalfreedom.totalfreedommod.banning.IndefiniteBanList; import me.totalfreedom.totalfreedommod.banning.IndefiniteBanList;
import me.totalfreedom.totalfreedommod.blocking.BlockBlocker; import me.totalfreedom.totalfreedommod.blocking.*;
import me.totalfreedom.totalfreedommod.blocking.EditBlocker;
import me.totalfreedom.totalfreedommod.blocking.EventBlocker;
import me.totalfreedom.totalfreedommod.blocking.InteractBlocker;
import me.totalfreedom.totalfreedommod.blocking.MobBlocker;
import me.totalfreedom.totalfreedommod.blocking.PVPBlocker;
import me.totalfreedom.totalfreedommod.blocking.PotionBlocker;
import me.totalfreedom.totalfreedommod.blocking.SignBlocker;
import me.totalfreedom.totalfreedommod.blocking.command.CommandBlocker; import me.totalfreedom.totalfreedommod.blocking.command.CommandBlocker;
import me.totalfreedom.totalfreedommod.bridge.BukkitTelnetBridge; import me.totalfreedom.totalfreedommod.bridge.*;
import me.totalfreedom.totalfreedommod.bridge.CoreProtectBridge;
import me.totalfreedom.totalfreedommod.bridge.EssentialsBridge;
import me.totalfreedom.totalfreedommod.bridge.LibsDisguisesBridge;
import me.totalfreedom.totalfreedommod.bridge.TFGuildsBridge;
import me.totalfreedom.totalfreedommod.bridge.WorldEditBridge;
import me.totalfreedom.totalfreedommod.bridge.WorldGuardBridge;
import me.totalfreedom.totalfreedommod.caging.Cager; import me.totalfreedom.totalfreedommod.caging.Cager;
import me.totalfreedom.totalfreedommod.command.CommandLoader; import me.totalfreedom.totalfreedommod.command.CommandLoader;
import me.totalfreedom.totalfreedommod.config.MainConfig; import me.totalfreedom.totalfreedommod.config.MainConfig;
import me.totalfreedom.totalfreedommod.discord.Discord;
import me.totalfreedom.totalfreedommod.freeze.Freezer; import me.totalfreedom.totalfreedommod.freeze.Freezer;
import me.totalfreedom.totalfreedommod.fun.ItemFun; import me.totalfreedom.totalfreedommod.fun.*;
import me.totalfreedom.totalfreedommod.fun.Jumppads;
import me.totalfreedom.totalfreedommod.fun.Landminer;
import me.totalfreedom.totalfreedommod.fun.MP44;
import me.totalfreedom.totalfreedommod.fun.Trailer;
import me.totalfreedom.totalfreedommod.httpd.HTTPDaemon; import me.totalfreedom.totalfreedommod.httpd.HTTPDaemon;
import me.totalfreedom.totalfreedommod.permissions.PermissionConfig;
import me.totalfreedom.totalfreedommod.permissions.PermissionManager;
import me.totalfreedom.totalfreedommod.player.PlayerList; import me.totalfreedom.totalfreedommod.player.PlayerList;
import me.totalfreedom.totalfreedommod.punishments.PunishmentList; import me.totalfreedom.totalfreedommod.punishments.PunishmentList;
import me.totalfreedom.totalfreedommod.rank.RankManager; import me.totalfreedom.totalfreedommod.rank.RankManager;
import me.totalfreedom.totalfreedommod.shop.Shop;
import me.totalfreedom.totalfreedommod.shop.Votifier;
import me.totalfreedom.totalfreedommod.sql.SQLite; import me.totalfreedom.totalfreedommod.sql.SQLite;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
@ -54,7 +31,10 @@ import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spigotmc.SpigotConfig;
import java.io.File;
import java.io.InputStream;
import java.util.Properties;
public class TotalFreedomMod extends JavaPlugin public class TotalFreedomMod extends JavaPlugin
{ {
@ -67,18 +47,14 @@ public class TotalFreedomMod extends JavaPlugin
private static TotalFreedomMod plugin; private static TotalFreedomMod plugin;
// //
public MainConfig config; public MainConfig config;
public PermissionConfig permissions;
// //
// Service Handler // Service Handler
public FreedomServiceHandler fsh; public FreedomServiceHandler fsh;
// Command Loader // Command Loader
public CommandLoader cl; public CommandLoader cl;
// Services // Services
public ServerInterface si;
public WorldManager wm; public WorldManager wm;
public LogViewer lv;
public AdminList al; public AdminList al;
public ActivityLog acl;
public RankManager rm; public RankManager rm;
public CommandBlocker cb; public CommandBlocker cb;
public EventBlocker eb; public EventBlocker eb;
@ -90,16 +66,15 @@ public class TotalFreedomMod extends JavaPlugin
public AntiNuke nu; public AntiNuke nu;
public AntiSpam as; public AntiSpam as;
public PlayerList pl; public PlayerList pl;
public Shop sh; public ShoppeCommons sh;
public Votifier vo;
public SQLite sql; public SQLite sql;
public Announcer an; public Announcer an;
public ChatManager cm; public ChatManager cm;
public Discord dc; public TFD4JCommons dc;
public Aggregator ag;
public PunishmentList pul; public PunishmentList pul;
public BanManager bm; public BanManager bm;
public IndefiniteBanList im; public IndefiniteBanList im;
public PermissionManager pem;
public GameRuleHandler gr; public GameRuleHandler gr;
public CommandSpy cs; public CommandSpy cs;
public Cager ca; public Cager ca;
@ -121,20 +96,16 @@ public class TotalFreedomMod extends JavaPlugin
public Trailer tr; public Trailer tr;
public HTTPDaemon hd; public HTTPDaemon hd;
public WorldRestrictions wr; public WorldRestrictions wr;
public SignBlocker snp;
public EntityWiper ew; public EntityWiper ew;
public Sitter st;
public VanishHandler vh; public VanishHandler vh;
public Pterodactyl ptero;
// //
// Bridges // Bridges
public BukkitTelnetBridge btb; public BukkitTelnetBridge btb;
public EssentialsBridge esb; public EssentialsBridge esb;
public LibsDisguisesBridge ldb; public LibsDisguisesBridge ldb;
public CoreProtectBridge cpb; public CoreProtectBridge cpb;
public TFGuildsBridge tfg;
public WorldEditBridge web; public WorldEditBridge web;
public WorldGuardBridge wgb; public LuckPermsBridge lpb;
public static TotalFreedomMod getPlugin() public static TotalFreedomMod getPlugin()
{ {
@ -147,7 +118,7 @@ public class TotalFreedomMod extends JavaPlugin
{ {
if (plugin.getName().equalsIgnoreCase(pluginName)) if (plugin.getName().equalsIgnoreCase(pluginName))
{ {
return (TotalFreedomMod)plugin; return (TotalFreedomMod) plugin;
} }
} }
return null; return null;
@ -176,9 +147,6 @@ public class TotalFreedomMod extends JavaPlugin
final MethodTimer timer = new MethodTimer(); final MethodTimer timer = new MethodTimer();
timer.start(); timer.start();
// Warn if we're running on a wrong version
ServerInterface.warnVersion();
// Delete unused files // Delete unused files
FUtil.deleteCoreDumps(); FUtil.deleteCoreDumps();
FUtil.deleteFolder(new File("./_deleteme")); FUtil.deleteFolder(new File("./_deleteme"));
@ -198,9 +166,6 @@ public class TotalFreedomMod extends JavaPlugin
BackupManager backups = new BackupManager(); BackupManager backups = new BackupManager();
backups.createAllBackups(); backups.createAllBackups();
permissions = new PermissionConfig();
permissions.load();
mv = new MovementValidator(); mv = new MovementValidator();
sp = new ServerPing(); sp = new ServerPing();
@ -211,13 +176,10 @@ public class TotalFreedomMod extends JavaPlugin
FLog.info("Started " + fsh.getServiceAmount() + " services."); FLog.info("Started " + fsh.getServiceAmount() + " services.");
timer.update(); timer.update();
FLog.info("Version " + pluginVersion + " for " + ServerInterface.COMPILE_NMS_VERSION + " enabled in " + timer.getTotal() + "ms"); FLog.info("Version " + pluginVersion + " enabled in " + timer.getTotal() + "ms");
// Metrics @ https://bstats.org/plugin/bukkit/TotalFreedomMod/2966 // Metrics @ https://bstats.org/plugin/bukkit/TotalFreedomMod/2966
new Metrics(this, 2966); new Metrics(this, 2966);
// little workaround to stop spigot from autorestarting - causing AMP to detach from process.
SpigotConfig.config.set("settings.restart-on-crash", false);
} }
@Override @Override
@ -237,6 +199,22 @@ public class TotalFreedomMod extends JavaPlugin
return new CleanroomChunkGenerator(id); return new CleanroomChunkGenerator(id);
} }
public void registerDiscord()
{
if (Bukkit.getPluginManager().isPluginEnabled("TFD4J"))
{
dc = ag.getDiscordContext().getValue();
}
}
public void registerShoppe()
{
if (Bukkit.getPluginManager().isPluginEnabled("TF-Shoppe"))
{
sh = ag.getShoppeContext().getValue();
}
}
public static class BuildProperties public static class BuildProperties
{ {
public String author; public String author;
@ -251,6 +229,7 @@ public class TotalFreedomMod extends JavaPlugin
try try
{ {
final Properties props; final Properties props;
final String unknown = "unknown";
try (InputStream in = plugin.getResource("build.properties")) try (InputStream in = plugin.getResource("build.properties"))
{ {
@ -258,15 +237,13 @@ public class TotalFreedomMod extends JavaPlugin
props.load(in); props.load(in);
} }
author = props.getProperty("buildAuthor", "unknown"); author = props.getProperty("buildAuthor", unknown);
codename = props.getProperty("buildCodeName", "unknown"); codename = props.getProperty("buildCodeName", unknown);
version = props.getProperty("buildVersion", pluginVersion); version = props.getProperty("buildVersion", pluginVersion);
number = props.getProperty("buildNumber", "1"); number = props.getProperty("buildNumber", "1");
date = props.getProperty("buildDate", "unknown"); date = props.getProperty("buildDate", unknown);
// Need to do this or it will display ${git.commit.id.abbrev} head = props.getProperty("buildHead", unknown).replace("${git.commit.id.abbrev}", unknown);
head = props.getProperty("buildHead", "unknown").replace("${git.commit.id.abbrev}", "unknown"); } catch (Exception ex)
}
catch (Exception ex)
{ {
FLog.severe("Could not load build properties! Did you compile with NetBeans/Maven?"); FLog.severe("Could not load build properties! Did you compile with NetBeans/Maven?");
FLog.severe(ex); FLog.severe(ex);
@ -296,12 +273,9 @@ public class TotalFreedomMod extends JavaPlugin
private void initServices() private void initServices()
{ {
// Start services // Start services
si = new ServerInterface();
wm = new WorldManager(); wm = new WorldManager();
lv = new LogViewer();
sql = new SQLite(); sql = new SQLite();
al = new AdminList(); al = new AdminList();
acl = new ActivityLog();
rm = new RankManager(); rm = new RankManager();
cb = new CommandBlocker(); cb = new CommandBlocker();
eb = new EventBlocker(); eb = new EventBlocker();
@ -314,21 +288,18 @@ public class TotalFreedomMod extends JavaPlugin
as = new AntiSpam(); as = new AntiSpam();
wr = new WorldRestrictions(); wr = new WorldRestrictions();
pl = new PlayerList(); pl = new PlayerList();
sh = new Shop(); ag = new Aggregator();
vo = new Votifier();
an = new Announcer(); an = new Announcer();
cm = new ChatManager(); cm = new ChatManager();
dc = new Discord();
pul = new PunishmentList(); pul = new PunishmentList();
bm = new BanManager(); bm = new BanManager();
im = new IndefiniteBanList(); im = new IndefiniteBanList();
pem = new PermissionManager();
gr = new GameRuleHandler(); gr = new GameRuleHandler();
snp = new SignBlocker();
ew = new EntityWiper(); ew = new EntityWiper();
st = new Sitter();
vh = new VanishHandler(); vh = new VanishHandler();
ptero = new Pterodactyl();
} }
private void initAdminUtils() private void initAdminUtils()
@ -354,9 +325,8 @@ public class TotalFreedomMod extends JavaPlugin
cpb = new CoreProtectBridge(); cpb = new CoreProtectBridge();
esb = new EssentialsBridge(); esb = new EssentialsBridge();
ldb = new LibsDisguisesBridge(); ldb = new LibsDisguisesBridge();
tfg = new TFGuildsBridge();
web = new WorldEditBridge(); web = new WorldEditBridge();
wgb = new WorldGuardBridge(); lpb = new LuckPermsBridge();
} }
private void initFun() private void initFun()

View File

@ -0,0 +1,70 @@
package me.totalfreedom.totalfreedommod;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
public class VanishHandler extends FreedomService
{
@Override
public void onStart()
{
}
@Override
public void onStop()
{
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
server.getOnlinePlayers().stream().filter(pl -> !plugin.al.isAdmin(player)
&& plugin.al.isVanished(pl.getUniqueId())).forEach(pl -> player.hidePlayer(plugin, pl));
server.getOnlinePlayers().stream().filter(pl -> !plugin.al.isAdmin(pl)
&& plugin.al.isVanished(player.getUniqueId())).forEach(pl -> pl.hidePlayer(plugin, player));
if (plugin.al.isVanished(player.getUniqueId()))
{
plugin.esb.setVanished(player.getName(), true);
plugin.cm.messageAllAdmins("<yellow><player> has joined silently.", Placeholder.unparsed("player", player.getName()));
event.joinMessage(null);
new BukkitRunnable()
{
@Override
public void run()
{
if (plugin.al.isVanished(player.getUniqueId()))
{
player.sendActionBar(FUtil.miniMessage("<gold>You are hidden from other players."));
}
else
{
this.cancel();
}
}
}.runTaskTimer(plugin, 0L, 4L);
}
}
@EventHandler
public void onPlayerLeave(PlayerQuitEvent event)
{
Player player = event.getPlayer();
if (plugin.al.isVanished(player.getUniqueId()))
{
event.quitMessage(null);
plugin.cm.messageAllAdmins("<yellow><player> has left silently.", Placeholder.unparsed("player", player.getName()));
}
}
}

View File

@ -1,38 +1,34 @@
package me.totalfreedom.totalfreedommod.admin; package me.totalfreedom.totalfreedommod.admin;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import me.totalfreedom.totalfreedommod.LogViewer.LogsRegistrationMode;
import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
public class Admin public class Admin
{ {
private final List<String> ips = new ArrayList<>(); private final List<String> ips = new ArrayList<>();
private String name; private UUID uuid;
private boolean active = true; private boolean active = true;
private Rank rank = Rank.ADMIN; private DisplayableGroup rank = GroupProvider.ADMIN.getGroup();
private Date lastLogin = new Date(); private Date lastLogin = new Date();
private Boolean commandSpy = false; private Boolean commandSpy = false;
private Boolean potionSpy = false; private Boolean potionSpy = false;
private String acFormat = null; private String acFormat = null;
private String pteroID = null;
public Admin(Player player) public Admin(Player player)
{ {
this.name = player.getName(); uuid = player.getUniqueId();
this.ips.add(FUtil.getIp(player)); this.ips.add(FUtil.getIp(player));
} }
@ -40,18 +36,16 @@ public class Admin
{ {
try try
{ {
this.name = resultSet.getString("username"); this.uuid = UUID.fromString(resultSet.getString("uuid"));
this.active = resultSet.getBoolean("active"); this.active = resultSet.getBoolean("active");
this.rank = Rank.findRank(resultSet.getString("rank")); this.rank = GroupProvider.fromArgument(resultSet.getString("rank")).getGroup();
this.ips.clear(); this.ips.clear();
this.ips.addAll(FUtil.stringToList(resultSet.getString("ips"))); this.ips.addAll(FUtil.stringToList(resultSet.getString("ips")));
this.lastLogin = new Date(resultSet.getLong("last_login")); this.lastLogin = new Date(resultSet.getLong("last_login"));
this.commandSpy = resultSet.getBoolean("command_spy"); this.commandSpy = resultSet.getBoolean("command_spy");
this.potionSpy = resultSet.getBoolean("potion_spy"); this.potionSpy = resultSet.getBoolean("potion_spy");
this.acFormat = resultSet.getString("ac_format"); this.acFormat = resultSet.getString("ac_format");
this.pteroID = resultSet.getString("ptero_id"); } catch (SQLException e)
}
catch (SQLException e)
{ {
FLog.severe("Failed to load admin: " + e.getMessage()); FLog.severe("Failed to load admin: " + e.getMessage());
} }
@ -62,33 +56,30 @@ public class Admin
{ {
final StringBuilder output = new StringBuilder(); final StringBuilder output = new StringBuilder();
output.append("Admin: ").append(name).append("\n") output.append("Admin: ").append(getName() != null ? getName() : getUuid().toString()).append("\n")
.append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n") .append("- IPs: ").append(StringUtils.join(ips, ", ")).append("\n")
.append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n") .append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n")
.append("- Rank: ").append(rank.getName()).append("\n") .append("- Rank: ").append(rank.getName()).append("\n")
.append("- Is Active: ").append(active).append("\n") .append("- Is Active: ").append(active).append("\n")
.append("- Potion Spy: ").append(potionSpy).append("\n") .append("- Potion Spy: ").append(potionSpy).append("\n")
.append("- Admin Chat Format: ").append(acFormat).append("\n") .append("- Admin Chat Format: ").append(acFormat).append("\n");
.append("- Pterodactyl ID: ").append(pteroID).append("\n");
return output.toString(); return output.toString();
} }
public Map<String, Object> toSQLStorable() public Map<String, Object> toSQLStorable()
{ {
Map<String, Object> map = new HashMap<String, Object>() HashMap<String, Object> map = new HashMap<>();
{{ map.put("uuid", uuid.toString());
put("username", name); map.put("active", active);
put("active", active); map.put("rank", rank.toString());
put("rank", rank.toString()); map.put("ips", FUtil.listToString(ips));
put("ips", FUtil.listToString(ips)); map.put("last_login", lastLogin.getTime());
put("last_login", lastLogin.getTime()); map.put("command_spy", commandSpy);
put("command_spy", commandSpy); map.put("potion_spy", potionSpy);
put("potion_spy", potionSpy); map.put("ac_format", acFormat);
put("ac_format", acFormat); return map;
put("ptero_id", pteroID);
}};
return map;
} }
// Util IP methods // Util IP methods
@ -120,20 +111,20 @@ public class Admin
public boolean isValid() public boolean isValid()
{ {
return name != null return uuid != null
&& rank != null && rank != null
&& !ips.isEmpty() && !ips.isEmpty()
&& lastLogin != null; && lastLogin != null;
} }
public String getName() public UUID getUuid()
{ {
return name; return uuid;
} }
public void setName(String name) public String getName()
{ {
this.name = name; return Bukkit.getOfflinePlayer(uuid).getName();
} }
public boolean isActive() public boolean isActive()
@ -156,24 +147,55 @@ public class Admin
if (!active) if (!active)
{ {
if (getRank().isAtLeast(Rank.ADMIN)) setActiveSplitWorkToReduceComplexity(plugin);
{
if (plugin.btb != null)
{
plugin.btb.killTelnetSessions(getName());
}
}
plugin.lv.updateLogsRegistration(null, getName(), LogsRegistrationMode.DELETE);
} }
} }
public Rank getRank() private void setActiveSplitWorkToReduceComplexity(TotalFreedomMod plugin)
{
if (getRank().isAtLeast(GroupProvider.ADMIN.getGroup()))
{
if (plugin.btb != null)
{
plugin.btb.killTelnetSessions(getName());
}
// Ensure admins don't have admin functionality when removed (FS-222)
AdminList.vanished.remove(getUuid());
if (plugin.esb != null)
{
plugin.esb.setVanished(getName(), false);
}
setCommandSpy(false);
setPotionSpy(false);
Server server = Bukkit.getServer();
Player player = server.getPlayer(getUuid());
if (player != null)
{
// Update chats
FPlayer freedomPlayer = plugin.pl.getPlayer(player);
freedomPlayer.removeAdminFunctionality();
// Disable vanish
for (Player player1 : server.getOnlinePlayers())
{
player1.showPlayer(plugin, player);
}
}
}
}
public DisplayableGroup getRank()
{ {
return rank; return rank;
} }
public void setRank(Rank rank) public void setRank(DisplayableGroup rank)
{ {
this.rank = rank; this.rank = rank;
} }
@ -222,14 +244,4 @@ public class Admin
{ {
this.acFormat = acFormat; this.acFormat = acFormat;
} }
public String getPteroID()
{
return pteroID;
}
public void setPteroID(String pteroID)
{
this.pteroID = pteroID;
}
} }

View File

@ -2,38 +2,31 @@ package me.totalfreedom.totalfreedommod.admin;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.Bukkit; import net.kyori.adventure.text.Component;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class AdminList extends FreedomService public class AdminList extends FreedomService
{ {
public static final List<String> vanished = new ArrayList<>(); public static final List<UUID> vanished = new ArrayList<>();
public final Map<String, List<String>> verifiedNoAdmin = Maps.newHashMap();
private final Set<Admin> allAdmins = Sets.newHashSet(); // Includes disabled admins private final Set<Admin> allAdmins = Sets.newHashSet(); // Includes disabled admins
// Only active admins below // Only active admins below
private final Set<Admin> activeAdmins = Sets.newHashSet(); private final Set<Admin> activeAdmins = Sets.newHashSet();
private final Map<UUID, Admin> uuidTable = Maps.newHashMap();
private final Map<String, Admin> nameTable = Maps.newHashMap(); private final Map<String, Admin> nameTable = Maps.newHashMap();
private final Map<String, Admin> ipTable = Maps.newHashMap(); private final Map<String, Admin> ipTable = Maps.newHashMap();
public static List<String> getVanished()
{
return vanished;
}
@Override @Override
public void onStart() public void onStart()
{ {
@ -44,6 +37,7 @@ public class AdminList extends FreedomService
@Override @Override
public void onStop() public void onStop()
{ {
// This does nothing. This comment is here to prevent SonarLint from complaining.
} }
public void load() public void load()
@ -52,34 +46,37 @@ public class AdminList extends FreedomService
try try
{ {
ResultSet adminSet = plugin.sql.getAdminList(); ResultSet adminSet = plugin.sql.getAdminList();
while (adminSet.next())
{ {
while (adminSet.next()) tryAddAdmin(adminSet);
{
Admin admin = new Admin(adminSet);
allAdmins.add(admin);
}
} }
} } catch (SQLException e)
catch (SQLException e)
{ {
FLog.severe("Failed to load admin list: " + e.getMessage()); FLog.severe("Failed to load admin list: " + e.getMessage());
} }
updateTables(); updateTables();
FLog.info("Loaded " + allAdmins.size() + " admins (" + nameTable.size() + " active, " + ipTable.size() + " IPs)"); FLog.info("Loaded " + allAdmins.size() + " admins (" + uuidTable.size() + " active, " + ipTable.size() + " IPs)");
} }
public void messageAllAdmins(String message) private void tryAddAdmin(ResultSet adminSet) throws SQLException
{ {
for (Player player : server.getOnlinePlayers()) try
{ {
if (isAdmin(player)) Admin admin = new Admin(adminSet);
{ allAdmins.add(admin);
player.sendMessage(message); } catch (Throwable ex)
} {
FLog.warning("An error occurred whilst reading the admin entry at row #" + adminSet.getRow());
FLog.warning(ex);
} }
} }
public void messageAllAdmins(Component message)
{
server.getOnlinePlayers().stream().filter(this::isAdmin).forEach(player -> player.sendMessage(message));
}
public void potionSpyMessage(String message) public void potionSpyMessage(String message)
{ {
for (Player player : server.getOnlinePlayers()) for (Player player : server.getOnlinePlayers())
@ -97,16 +94,6 @@ public class AdminList extends FreedomService
return isAdmin(sender); return isAdmin(sender);
} }
public List<String> getActiveAdminNames()
{
List<String> names = new ArrayList();
for (Admin admin : activeAdmins)
{
names.add(admin.getName());
}
return names;
}
public boolean isAdmin(CommandSender sender) public boolean isAdmin(CommandSender sender)
{ {
if (!(sender instanceof Player)) if (!(sender instanceof Player))
@ -114,12 +101,18 @@ public class AdminList extends FreedomService
return true; return true;
} }
Admin admin = getAdmin((Player)sender); Admin admin = getAdmin((Player) sender);
return admin != null && admin.isActive(); return admin != null && admin.isActive();
} }
// Cast to OfflinePlayer
public boolean isAdmin(Player player) public boolean isAdmin(Player player)
{
return isAdmin((OfflinePlayer) player);
}
public boolean isAdmin(OfflinePlayer player)
{ {
if (player == null) if (player == null)
{ {
@ -139,55 +132,29 @@ public class AdminList extends FreedomService
return false; return false;
} }
return admin.getRank().ordinal() >= Rank.SENIOR_ADMIN.ordinal(); return admin.getRank().getLuckPermsGroup().getWeight().orElse(0)
>= GroupProvider.SENIOR_ADMIN.getGroup().getLuckPermsGroup().getWeight().orElse(1);
// We don't want this to return true if there's no group weight available.
} }
public Admin getAdmin(CommandSender sender) public Admin getAdmin(CommandSender sender)
{ {
if (sender instanceof Player) if (sender instanceof Player player)
{ {
return getAdmin((Player)sender); return getAdmin(player);
} }
return getEntryByName(sender.getName()); return getEntryByName(sender.getName());
} }
public Admin getAdmin(Player player) public Admin getAdmin(OfflinePlayer player)
{ {
// Find admin return getEntryByUuid(player.getUniqueId());
String ip = FUtil.getIp(player); }
Admin admin = getEntryByName(player.getName());
// Admin by name public Admin getEntryByUuid(UUID uuid)
if (admin != null) {
{ return uuidTable.get(uuid);
// Check if we're in online mode,
// Or the players IP is in the admin entry
if (Bukkit.getOnlineMode() || admin.getIps().contains(ip))
{
if (!admin.getIps().contains(ip))
{
// Add the new IP if we have to
admin.addIp(ip);
save(admin);
updateTables();
}
return admin;
}
}
// Admin by ip
admin = getEntryByIp(ip);
if (admin != null)
{
// Set the new username
String oldName = admin.getName();
admin.setName(player.getName());
plugin.sql.updateAdminName(oldName, admin.getName());
updateTables();
}
return null;
} }
public Admin getEntryByName(String name) public Admin getEntryByName(String name)
@ -200,23 +167,10 @@ public class AdminList extends FreedomService
return ipTable.get(ip); return ipTable.get(ip);
} }
public Admin getEntryByIpFuzzy(String needleIp) // To cast against OfflinePlayer
public Admin getAdmin(Player player)
{ {
final Admin directAdmin = getEntryByIp(needleIp); return getAdmin((OfflinePlayer) player);
if (directAdmin != null)
{
return directAdmin;
}
for (String ip : ipTable.keySet())
{
if (FUtil.fuzzyIpMatch(needleIp, ip, 3))
{
return ipTable.get(ip);
}
}
return null;
} }
public void updateLastLogin(Player player) public void updateLastLogin(Player player)
@ -228,37 +182,15 @@ public class AdminList extends FreedomService
} }
admin.setLastLogin(new Date()); admin.setLastLogin(new Date());
admin.setName(player.getName());
save(admin); save(admin);
} }
public boolean isAdminImpostor(Player player) public void addAdmin(Admin admin)
{
return getEntryByName(player.getName()) != null && !isAdmin(player) && !isVerifiedAdmin(player);
}
public boolean isVerifiedAdmin(Player player)
{
return verifiedNoAdmin.containsKey(player.getName()) && verifiedNoAdmin.get(player.getName()).contains(FUtil.getIp(player));
}
public boolean isIdentityMatched(Player player)
{
if (Bukkit.getOnlineMode())
{
return true;
}
Admin admin = getAdmin(player);
return admin != null && admin.getName().equalsIgnoreCase(player.getName());
}
public boolean addAdmin(Admin admin)
{ {
if (!admin.isValid()) if (!admin.isValid())
{ {
FLog.warning("Could not add admin: " + admin.getName() + ". Admin is missing details!"); FLog.warning("Could not add admin: " + admin.getName() + ". Admin is missing details!");
return false; return;
} }
// Store admin, update views // Store admin, update views
@ -267,18 +199,13 @@ public class AdminList extends FreedomService
// Save admin // Save admin
plugin.sql.addAdmin(admin); plugin.sql.addAdmin(admin);
return true;
} }
public boolean removeAdmin(Admin admin) public boolean removeAdmin(Admin admin)
{ {
if (admin.getRank().isAtLeast(Rank.ADMIN)) if (admin.getRank().isAtLeast(GroupProvider.ADMIN.getGroup()) && (plugin.btb != null))
{ {
if (plugin.btb != null) plugin.btb.killTelnetSessions(admin.getName());
{
plugin.btb.killTelnetSessions(admin.getName());
}
} }
// Remove admin, update views // Remove admin, update views
@ -297,6 +224,7 @@ public class AdminList extends FreedomService
public void updateTables() public void updateTables()
{ {
activeAdmins.clear(); activeAdmins.clear();
uuidTable.clear();
nameTable.clear(); nameTable.clear();
ipTable.clear(); ipTable.clear();
@ -308,13 +236,16 @@ public class AdminList extends FreedomService
} }
activeAdmins.add(admin); activeAdmins.add(admin);
nameTable.put(admin.getName().toLowerCase(), admin); uuidTable.put(admin.getUuid(), admin);
if (admin.getName() != null)
{
nameTable.put(admin.getName().toLowerCase(), admin);
}
for (String ip : admin.getIps()) for (String ip : admin.getIps())
{ {
ipTable.put(ip, admin); ipTable.put(ip, admin);
} }
} }
} }
@ -332,7 +263,7 @@ public class AdminList extends FreedomService
{ {
try try
{ {
ResultSet currentSave = plugin.sql.getAdminByName(admin.getName()); ResultSet currentSave = plugin.sql.getAdminByUuid(admin.getUuid());
for (Map.Entry<String, Object> entry : admin.toSQLStorable().entrySet()) for (Map.Entry<String, Object> entry : admin.toSQLStorable().entrySet())
{ {
Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue()); Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue());
@ -341,8 +272,7 @@ public class AdminList extends FreedomService
plugin.sql.setAdminValue(admin, entry.getKey(), entry.getValue()); plugin.sql.setAdminValue(admin, entry.getKey(), entry.getValue());
} }
} }
} } catch (SQLException e)
catch (SQLException e)
{ {
FLog.severe("Failed to save admin: " + e.getMessage()); FLog.severe("Failed to save admin: " + e.getMessage());
} }
@ -350,36 +280,30 @@ public class AdminList extends FreedomService
public void deactivateOldEntries(boolean verbose) public void deactivateOldEntries(boolean verbose)
{ {
for (Admin admin : allAdmins) allAdmins.stream()
{ .filter(admin -> admin.isActive() && !admin.getRank().isAtLeast(GroupProvider.SENIOR_ADMIN.getGroup()))
if (!admin.isActive() || admin.getRank().isAtLeast(Rank.SENIOR_ADMIN)) .forEach(admin ->
{ {
continue; final Date lastLogin = admin.getLastLogin();
} final long lastLoginHours = TimeUnit.HOURS.convert(new Date().getTime() - lastLogin.getTime(), TimeUnit.MILLISECONDS);
if (lastLoginHours < ConfigEntry.ADMINLIST_CLEAN_THESHOLD_HOURS.getInteger())
final Date lastLogin = admin.getLastLogin(); {
final long lastLoginHours = TimeUnit.HOURS.convert(new Date().getTime() - lastLogin.getTime(), TimeUnit.MILLISECONDS); return;
}
if (lastLoginHours < ConfigEntry.ADMINLIST_CLEAN_THESHOLD_HOURS.getInteger()) if (verbose)
{ {
continue; FUtil.adminAction("TotalFreedomMod", "Deactivating admin " + admin.getName() + ", inactive for " + lastLoginHours + " hours", true);
} }
admin.setActive(false);
if (verbose) save(admin);
{ });
FUtil.adminAction("TotalFreedomMod", "Deactivating admin " + admin.getName() + ", inactive for " + lastLoginHours + " hours", true);
}
admin.setActive(false);
save(admin);
}
updateTables(); updateTables();
} }
public boolean isVanished(String player) public boolean isVanished(UUID uuid)
{ {
return vanished.contains(player); return vanished.contains(uuid);
} }
public Set<Admin> getAllAdmins() public Set<Admin> getAllAdmins()
@ -401,9 +325,4 @@ public class AdminList extends FreedomService
{ {
return ipTable; return ipTable;
} }
public Map<String, List<String>> getVerifiedNoAdmin()
{
return verifiedNoAdmin;
}
} }

View File

@ -0,0 +1,27 @@
package me.totalfreedom.totalfreedommod.api;
public class Aggregator
{
private Context<TFD4JCommons> discord;
private Context<ShoppeCommons> shoppe;
public Context<TFD4JCommons> getDiscordContext()
{
return discord;
}
public void setDiscordContext(Context<TFD4JCommons> discord)
{
this.discord = discord;
}
public Context<ShoppeCommons> getShoppeContext()
{
return shoppe;
}
public void setShoppeContext(Context<ShoppeCommons> shoppe)
{
this.shoppe = shoppe;
}
}

View File

@ -0,0 +1,16 @@
package me.totalfreedom.totalfreedommod.api;
public class Context<T>
{
private final T value;
public Context(T value)
{
this.value = value;
}
public T getValue()
{
return value;
}
}

View File

@ -0,0 +1,7 @@
package me.totalfreedom.totalfreedommod.api;
@FunctionalInterface
public interface Interpolator
{
double[] interpolate(double from, double to, int max);
}

View File

@ -1,4 +1,4 @@
package me.totalfreedom.totalfreedommod.shop; package me.totalfreedom.totalfreedommod.api;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;

View File

@ -0,0 +1,55 @@
package me.totalfreedom.totalfreedommod.api;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
public interface ShoppeCommons
{
int getCoinsPerReactionWin();
void startReactionTimer();
void forceStartReaction();
void startReaction();
void endReaction(String winner);
String getShopPrefix();
String getShopTitle();
Inventory generateShopGUI(PlayerData playerData);
Inventory generateLoginMessageGUI(Player player);
boolean isRealItem(PlayerData data, ShopItem shopItem, PlayerInventory inventory, ItemStack realItem);
boolean isRealItem(PlayerData data, ShopItem shopItem, ItemStack givenItem, ItemStack realItem);
ItemStack getLightningRod();
ItemStack getGrapplingHook();
ItemStack getFireBall();
ItemStack getRideablePearl();
ItemStack getStackingPotato();
ItemStack getClownFish();
boolean canAfford(int price, int coins);
int amountNeeded(int price, int coins);
ItemStack shopGUIItem(ShopItem item, PlayerData data);
ShopItem getShopItem(int slot);
String getReactionString();
}

View File

@ -0,0 +1,33 @@
package me.totalfreedom.totalfreedommod.api;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.player.PlayerData;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.Map;
public interface TFD4JCommons
{
void messageAdminChatChannel(String message);
void clearQueue();
void messageChatChannel(String message, boolean system);
boolean syncRoles(Admin admin, String id);
String getCode(PlayerData playerData);
String generateCode(int size);
Map<String, PlayerData> getLinkCodes();
String formatBotTag();
boolean sendReportOffline(Player reporter, OfflinePlayer reported, String reason);
boolean sendReport(Player reporter, Player reported, String reason);
boolean isEnabled();
}

View File

@ -0,0 +1,74 @@
package me.totalfreedom.totalfreedommod.api.event;
import me.totalfreedom.totalfreedommod.rank.Displayable;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class AdminChatEvent extends Event
{
private static HandlerList handlerList = new HandlerList();
//--
private Key identifier;
private Component prefix = Component.empty();
private Component name;
private Displayable displayable;
private Component message;
public AdminChatEvent(Key identifier, Component prefix, Component name, Displayable rank, Component message, boolean async)
{
super(async);
this.identifier = identifier;
this.prefix = prefix;
this.name = name;
this.displayable = rank;
this.message = message;
}
public AdminChatEvent(Component name, Displayable rank, Component message, boolean async)
{
super(async);
this.identifier = Key.key("tfm", "default");
this.name = name;
this.displayable = rank;
this.message = message;
}
public static HandlerList getHandlerList()
{
return handlerList;
}
@Override
public @NotNull HandlerList getHandlers()
{
return handlerList;
}
public Key getIdentifier()
{
return identifier;
}
public Component getPrefix()
{
return prefix;
}
public Component getName()
{
return name;
}
public Displayable getDisplayable()
{
return displayable;
}
public Component getMessage()
{
return message;
}
}

View File

@ -121,17 +121,6 @@ public class Ban
reason); reason);
} }
public static Ban forPlayerFuzzy(Player player, CommandSender by, Date expiry, String reason)
{
return new Ban(player.getName(),
player.getUniqueId(),
FUtil.getFuzzyIp(FUtil.getIp(player)),
by.getName(),
Date.from(Instant.now()),
expiry,
reason);
}
public static SimpleDateFormat getDateFormat() public static SimpleDateFormat getDateFormat()
{ {
return DATE_FORMAT; return DATE_FORMAT;

View File

@ -1,6 +1,5 @@
package me.totalfreedom.totalfreedommod.banning; package me.totalfreedom.totalfreedommod.banning;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -14,7 +13,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -30,8 +28,6 @@ public class BanManager extends FreedomService
private final Map<String, Ban> nameBans = Maps.newHashMap(); private final Map<String, Ban> nameBans = Maps.newHashMap();
private final Map<UUID, Ban> uuidBans = Maps.newHashMap(); private final Map<UUID, Ban> uuidBans = Maps.newHashMap();
private final Map<String, Ban> ipBans = Maps.newHashMap(); private final Map<String, Ban> ipBans = Maps.newHashMap();
private final List<String> unbannableUsernames = Lists.newArrayList();
// //
@Override @Override
@ -70,16 +66,12 @@ public class BanManager extends FreedomService
updateViews(); updateViews();
FLog.info("Loaded " + ipBans.size() + " IP bans and " + nameBans.size() + " username bans."); FLog.info("Loaded " + ipBans.size() + " IP bans and " + nameBans.size() + " username bans.");
// Load unbannable usernames
unbannableUsernames.clear();
unbannableUsernames.addAll(ConfigEntry.FAMOUS_PLAYERS.getStringList());
FLog.info("Loaded " + unbannableUsernames.size() + " unbannable usernames.");
} }
@Override @Override
public void onStop() public void onStop()
{ {
// This does nothing. This comment is here to prevent SonarLint from complaining.
} }
public Set<Ban> getAllBans() public Set<Ban> getAllBans()

View File

@ -1,10 +1,14 @@
package me.totalfreedom.totalfreedommod.banning; package me.totalfreedom.totalfreedommod.banning;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import me.totalfreedom.totalfreedommod.config.IConfig; import me.totalfreedom.totalfreedommod.config.IConfig;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
public class IndefiniteBan implements IConfig public class IndefiniteBan implements IConfig
@ -13,15 +17,13 @@ public class IndefiniteBan implements IConfig
private String username = null; private String username = null;
private UUID uuid = null; private UUID uuid = null;
private String reason = null; private String reason = null;
private Date expiry = null;
public IndefiniteBan()
{
}
@Override @Override
public void loadFrom(ConfigurationSection cs) public void loadFrom(ConfigurationSection cs)
{ {
this.username = cs.getName(); this.username = cs.getName();
try try
{ {
String strUUID = cs.getString("uuid", null); String strUUID = cs.getString("uuid", null);
@ -35,9 +37,20 @@ public class IndefiniteBan implements IConfig
{ {
FLog.warning("Failed to load indefinite banned UUID for " + this.username + ". Make sure the UUID is in the correct format with dashes."); FLog.warning("Failed to load indefinite banned UUID for " + this.username + ". Make sure the UUID is in the correct format with dashes.");
} }
this.ips.clear(); this.ips.clear();
this.ips.addAll(cs.getStringList("ips")); this.ips.addAll(cs.getStringList("ips"));
this.reason = cs.getString("reason", null); this.reason = cs.getString("reason", null);
String date = cs.getString("expiry", null);
try
{
this.expiry = date != null ? new SimpleDateFormat("yyyy-MM-dd").parse(date) : null;
}
catch (ParseException ex)
{
FLog.warning("Failed to load indefinite banned expiry for " + this.username + ". Make sure the expiry is in the correct format (yyyy-MM-dd).");
}
} }
@Override @Override
@ -86,4 +99,24 @@ public class IndefiniteBan implements IConfig
{ {
this.reason = reason; this.reason = reason;
} }
public Date getExpiry()
{
return expiry;
}
public void setExpiry(Date date)
{
this.expiry = date;
}
public boolean hasExpiry()
{
return this.expiry != null;
}
public boolean isExpired()
{
return hasExpiry() && expiry.before(new Date(FUtil.getUnixTime()));
}
} }

View File

@ -2,6 +2,8 @@ package me.totalfreedom.totalfreedommod.banning;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
@ -19,30 +21,24 @@ public class IndefiniteBanList extends FreedomService
{ {
public static final String CONFIG_FILENAME = "indefinitebans.yml"; public static final String CONFIG_FILENAME = "indefinitebans.yml";
private YamlConfig config;
private final Set<IndefiniteBan> indefBans = Sets.newHashSet(); private final Set<IndefiniteBan> indefBans = Sets.newHashSet();
private int nameBanCount = 0; private int nameBanCount = 0;
private int uuidBanCount = 0; private int uuidBanCount = 0;
private int ipBanCount = 0; private int ipBanCount = 0;
public static String getConfigFilename() private final SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy, zzzz");
{
return CONFIG_FILENAME;
}
@Override @Override
public void onStart() public void onStart()
{ {
indefBans.clear(); indefBans.clear();
final YamlConfig config = new YamlConfig(plugin, CONFIG_FILENAME, true); config = new YamlConfig(plugin, CONFIG_FILENAME, true);
config.load(); config.load();
for (String name : config.getKeys(false)) for (String name : config.getKeys(false))
@ -64,10 +60,18 @@ public class IndefiniteBanList extends FreedomService
continue; continue;
} }
if (indefBan.isExpired())
{
FLog.info("Removing " + name + " from indefinite ban list as the entry has expired!");
config.set(name, null);
continue;
}
indefBans.add(indefBan); indefBans.add(indefBan);
} }
updateCount(); updateCount();
config.save();
FLog.info("Loaded " + nameBanCount + " indefinite name bans, " + uuidBanCount + " UUID bans, and " + ipBanCount + " ip bans"); FLog.info("Loaded " + nameBanCount + " indefinite name bans, " + uuidBanCount + " UUID bans, and " + ipBanCount + " ip bans");
} }
@ -75,6 +79,7 @@ public class IndefiniteBanList extends FreedomService
@Override @Override
public void onStop() public void onStop()
{ {
// This does nothing. This comment is here to prevent SonarLint from complaining.
} }
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
@ -109,14 +114,34 @@ public class IndefiniteBanList extends FreedomService
} }
} }
onPlayerLoginSplitWorkToReduceComplexity(event, ban, bannedBy);
}
private void onPlayerLoginSplitWorkToReduceComplexity(PlayerLoginEvent event, IndefiniteBan ban, String bannedBy) {
if (ban != null) if (ban != null)
{ {
String kickMessage = ChatColor.RED + "Your " + bannedBy + " is indefinitely banned from this server."; if (ban.isExpired())
{
config.set(ban.getUsername(), null);
config.save();
return;
}
String kickMessage = ChatColor.RED + "Your " + bannedBy + " is "
+ (ban.hasExpiry() ? "" : "indefinitely ")
+ "banned from this server.";
String reason = ban.getReason(); String reason = ban.getReason();
if (!Strings.isNullOrEmpty(reason)) if (!Strings.isNullOrEmpty(reason))
{ {
kickMessage += "\nReason: " + ChatColor.GOLD + reason; kickMessage += "\nReason: " + ChatColor.GOLD + reason;
} }
Date expiry = ban.getExpiry();
if (expiry != null)
{
kickMessage += ChatColor.RED + "\nExpiry: " + ChatColor.GOLD + dateFormat.format(expiry);
}
String appealURL = ConfigEntry.SERVER_INDEFBAN_URL.getString(); String appealURL = ConfigEntry.SERVER_INDEFBAN_URL.getString();
if (!Strings.isNullOrEmpty(appealURL)) if (!Strings.isNullOrEmpty(appealURL))
{ {
@ -125,7 +150,6 @@ public class IndefiniteBanList extends FreedomService
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, kickMessage); event.disallow(PlayerLoginEvent.Result.KICK_OTHER, kickMessage);
} }
} }
private void updateCount() private void updateCount()
{ {
nameBanCount = 0; nameBanCount = 0;

View File

@ -1,14 +1,10 @@
package me.totalfreedom.totalfreedommod.blocking; package me.totalfreedom.totalfreedommod.blocking;
import java.util.List;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.Groups;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Banner;
import org.bukkit.block.Skull; import org.bukkit.block.Skull;
import org.bukkit.block.banner.Pattern;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -30,6 +26,7 @@ public class BlockBlocker extends FreedomService
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
// TODO: Remove deprecated method. Complexity is also O(35) which is very bad.
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
public void onBlockPlace(BlockPlaceEvent event) public void onBlockPlace(BlockPlaceEvent event)
{ {
@ -71,7 +68,7 @@ public class BlockBlocker extends FreedomService
} }
case STRUCTURE_BLOCK: case STRUCTURE_BLOCK:
{ {
if (!ConfigEntry.ALLOW_STRUCTURE_BLOCKS.getBoolean()) if (!ConfigEntry.ALLOW_MASTERBLOCKS.getBoolean())
{ {
player.sendMessage(ChatColor.GRAY + "Structure blocks are disabled."); player.sendMessage(ChatColor.GRAY + "Structure blocks are disabled.");
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
@ -81,7 +78,7 @@ public class BlockBlocker extends FreedomService
} }
case JIGSAW: case JIGSAW:
{ {
if (!ConfigEntry.ALLOW_JIGSAWS.getBoolean()) if (!ConfigEntry.ALLOW_MASTERBLOCKS.getBoolean())
{ {
player.sendMessage(ChatColor.GRAY + "Jigsaws are disabled."); player.sendMessage(ChatColor.GRAY + "Jigsaws are disabled.");
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1)); player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
@ -89,6 +86,16 @@ public class BlockBlocker extends FreedomService
} }
break; break;
} }
case REPEATING_COMMAND_BLOCK:
case CHAIN_COMMAND_BLOCK:
case COMMAND_BLOCK:
if (!ConfigEntry.ALLOW_MASTERBLOCKS.getBoolean())
{
player.sendMessage(ChatColor.GRAY + "Command blocks are disabled.");
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), new ItemStack(Material.COOKIE, 1));
event.setCancelled(true);
}
break;
case GRINDSTONE: case GRINDSTONE:
{ {
if (!ConfigEntry.ALLOW_GRINDSTONES.getBoolean()) if (!ConfigEntry.ALLOW_GRINDSTONES.getBoolean())
@ -177,17 +184,5 @@ public class BlockBlocker extends FreedomService
break; break;
} }
} }
if (Groups.BANNERS.contains(event.getBlockPlaced().getType()))
{
Banner banner = (Banner)event.getBlockPlaced().getState();
List<Pattern> patterns = banner.getPatterns();
if (patterns.size() >= 2)
{
banner.setPatterns(patterns.subList(0, 2));
player.sendMessage(ChatColor.GRAY + "Your banner had too many patterns on it, so some were removed.");
}
}
} }
} }

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import me.totalfreedom.scissors.event.block.MasterBlockFireEvent;
import io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
@ -18,15 +20,7 @@ import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Tameable; import org.bukkit.entity.Tameable;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.*;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockGrowEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
@ -115,6 +109,28 @@ public class EventBlocker extends FreedomService
event.setRadius(ConfigEntry.EXPLOSIVE_RADIUS.getDouble().floatValue()); event.setRadius(ConfigEntry.EXPLOSIVE_RADIUS.getDouble().floatValue());
} }
@EventHandler(priority = EventPriority.HIGH)
public void onBlockExplode(BlockExplodeEvent event)
{
if (!ConfigEntry.ALLOW_EXPLOSIONS.getBoolean())
{
event.setCancelled(true);
return;
}
event.setYield(ConfigEntry.EXPLOSIVE_RADIUS.getDouble().floatValue());
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onMasterBlockFire(MasterBlockFireEvent event)
{
if (!ConfigEntry.ALLOW_MASTERBLOCKS.getBoolean())
{
event.setCancelled(true);
event.getAt().getBlock().setType(Material.CAKE);
}
}
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)
public void onEntityCombust(EntityCombustEvent event) public void onEntityCombust(EntityCombustEvent event)
{ {
@ -146,12 +162,9 @@ public class EventBlocker extends FreedomService
if (ConfigEntry.ENABLE_PET_PROTECT.getBoolean()) if (ConfigEntry.ENABLE_PET_PROTECT.getBoolean())
{ {
Entity entity = event.getEntity(); Entity entity = event.getEntity();
if (entity instanceof Tameable) if (entity instanceof Tameable tameable && tameable.isTamed())
{ {
if (((Tameable)entity).isTamed()) event.setCancelled(true);
{
event.setCancelled(true);
}
} }
} }
} }
@ -265,4 +278,10 @@ public class EventBlocker extends FreedomService
FUtil.fixCommandVoid(event.getEntity()); FUtil.fixCommandVoid(event.getEntity());
event.setDeathMessage(event.getDeathMessage()); event.setDeathMessage(event.getDeathMessage());
} }
@EventHandler
public void onSignInteract(PlayerSignCommandPreprocessEvent event)
{
event.setCancelled(true);
}
} }

View File

@ -5,6 +5,8 @@ import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.Groups; import me.totalfreedom.totalfreedommod.util.Groups;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -64,24 +66,42 @@ public class InteractBlocker extends FreedomService
} }
} }
// TODO: Current cognitive complexity is O(24). This is too high.
private void handleRightClick(PlayerInteractEvent event) private void handleRightClick(PlayerInteractEvent event)
{ {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final Block clickedBlock = event.getClickedBlock();
if (event.getClickedBlock() != null) if (clickedBlock != null && clickedBlock.getType() == Material.RESPAWN_ANCHOR && !ConfigEntry.ALLOW_RESPAWN_ANCHORS.getBoolean())
{ {
if (event.getClickedBlock().getType().equals(Material.STRUCTURE_BLOCK) || event.getClickedBlock().getType().equals(Material.JIGSAW) || event.getClickedBlock().getType().equals(Material.RESPAWN_ANCHOR)) event.setCancelled(true);
{ return;
event.setCancelled(true);
event.getPlayer().closeInventory();
}
} }
if (Groups.SPAWN_EGGS.contains(event.getMaterial())) if (Groups.SPAWN_EGGS.contains(event.getMaterial()))
{ {
player.getInventory().clear(player.getInventory().getHeldItemSlot());
player.sendMessage(ChatColor.GRAY + "Spawn eggs are currently disabled.");
event.setCancelled(true); event.setCancelled(true);
EntityType eggType = null;
try
{
Material mat = event.getMaterial();
if (mat == Material.MOOSHROOM_SPAWN_EGG)
{
eggType = EntityType.MUSHROOM_COW;
}
else
{
eggType = EntityType.valueOf(mat.name().substring(0, mat.name().length() - 10));
}
}
catch (IllegalArgumentException ignored)
{
//
}
if (eggType != null && clickedBlock != null)
{
clickedBlock.getWorld().spawnEntity(clickedBlock.getLocation().add(event.getBlockFace().getDirection()).add(0.5, 0.5, 0.5), eggType);
}
return; return;
} }
@ -152,6 +172,11 @@ public class InteractBlocker extends FreedomService
} }
case WRITTEN_BOOK: case WRITTEN_BOOK:
{ {
if (ConfigEntry.ALLOW_BOOKS.getBoolean())
{
break;
}
player.getInventory().clear(player.getInventory().getHeldItemSlot()); player.getInventory().clear(player.getInventory().getHeldItemSlot());
player.sendMessage(ChatColor.GRAY + "Books are currently disabled."); player.sendMessage(ChatColor.GRAY + "Books are currently disabled.");
event.setCancelled(true); event.setCancelled(true);

View File

@ -54,6 +54,7 @@ public class MobBlocker extends FreedomService
} }
} }
// TODO: Complexity for this method is too high [O(23)]. This needs to be fixed.
@EventHandler(priority = EventPriority.NORMAL) @EventHandler(priority = EventPriority.NORMAL)
public void onCreatureSpawn(CreatureSpawnEvent event) public void onCreatureSpawn(CreatureSpawnEvent event)
{ {

View File

@ -24,6 +24,7 @@ public class PVPBlocker extends FreedomService
{ {
} }
// TODO: Complexity is O(26). This needs to be reduced.
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) public void onEntityDamageByEntity(EntityDamageByEntityEvent event)
{ {
@ -70,7 +71,7 @@ public class PVPBlocker extends FreedomService
} }
} }
if (player != null & !plugin.al.isAdmin(player)) if (player != null && !plugin.al.isAdmin(player))
{ {
if (player.getGameMode() == GameMode.CREATIVE) if (player.getGameMode() == GameMode.CREATIVE)
{ {

View File

@ -24,7 +24,7 @@ import org.bukkit.plugin.SimplePluginManager;
public class CommandBlocker extends FreedomService public class CommandBlocker extends FreedomService
{ {
private final Pattern whitespacePattern = Pattern.compile("^/?( +)(.*)?");
private final Pattern flagPattern = Pattern.compile("(:([0-9]){5,})"); private final Pattern flagPattern = Pattern.compile("(:([0-9]){5,})");
// //
private final Map<String, CommandBlockerEntry> entryList = Maps.newHashMap(); private final Map<String, CommandBlockerEntry> entryList = Maps.newHashMap();
@ -60,7 +60,7 @@ public class CommandBlocker extends FreedomService
entryList.clear(); entryList.clear();
} }
public void load() public void load() // TODO: Complexity is 21. Need to fix this.
{ {
entryList.clear(); entryList.clear();
unknownCommands.clear(); unknownCommands.clear();
@ -147,6 +147,7 @@ public class CommandBlocker extends FreedomService
return isCommandBlocked(command, sender, false); return isCommandBlocked(command, sender, false);
} }
// TODO: Complexity is 22. Need to fix this. Complexity can be no more than O(15).
public boolean isCommandBlocked(String command, CommandSender sender, boolean doAction) public boolean isCommandBlocked(String command, CommandSender sender, boolean doAction)
{ {
if (command == null || command.isEmpty()) if (command == null || command.isEmpty())
@ -156,6 +157,14 @@ public class CommandBlocker extends FreedomService
// Format // Format
command = command.toLowerCase().trim(); command = command.toLowerCase().trim();
// Whitespaces
Matcher whitespaceMatcher = whitespacePattern.matcher(command);
if (whitespaceMatcher.matches() && whitespaceMatcher.groupCount() == 2)
{
command = whitespaceMatcher.group(2);
}
command = command.startsWith("/") ? command.substring(1) : command; command = command.startsWith("/") ? command.substring(1) : command;
// Check for plugin specific commands // Check for plugin specific commands
@ -203,12 +212,9 @@ public class CommandBlocker extends FreedomService
} }
// Validate sub command // Validate sub command
if (entry.getSubCommand() != null) if (entry.getSubCommand() != null && (subCommand == null || !subCommand.startsWith(entry.getSubCommand())))
{ {
if (subCommand == null || !subCommand.startsWith(entry.getSubCommand())) return false;
{
return false;
}
} }
if (entry.getRank().hasPermission(sender)) if (entry.getRank().hasPermission(sender))

View File

@ -2,10 +2,10 @@ package me.totalfreedom.totalfreedommod.blocking.command;
import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.spigotmc.SpigotConfig;
public class CommandBlockerEntry public class CommandBlockerEntry
{ {
@ -45,7 +45,7 @@ public class CommandBlockerEntry
} }
if (action == CommandBlockerAction.BLOCK_UNKNOWN) if (action == CommandBlockerAction.BLOCK_UNKNOWN)
{ {
sender.sendMessage(SpigotConfig.unknownCommandMessage); sender.sendMessage(Bukkit.spigot().getSpigotConfig().getString("messages.unknown-command"));
return; return;
} }
FUtil.playerMsg(sender, FUtil.colorize(message)); FUtil.playerMsg(sender, FUtil.colorize(message));

View File

@ -2,7 +2,7 @@ package me.totalfreedom.totalfreedommod.blocking.command;
import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public enum CommandBlockerRank public enum CommandBlockerRank
@ -25,7 +25,7 @@ public enum CommandBlockerRank
Admin admin = TotalFreedomMod.getPlugin().al.getAdmin(sender); Admin admin = TotalFreedomMod.getPlugin().al.getAdmin(sender);
if (admin != null) if (admin != null)
{ {
if (admin.getRank() == Rank.SENIOR_ADMIN) if (admin.getRank() == GroupProvider.SENIOR_ADMIN.getGroup())
{ {
return SENIOR_ADMIN; return SENIOR_ADMIN;
} }

View File

@ -1,8 +1,5 @@
package me.totalfreedom.totalfreedommod.bridge; package me.totalfreedom.totalfreedommod.bridge;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import me.totalfreedom.bukkittelnet.BukkitTelnet; import me.totalfreedom.bukkittelnet.BukkitTelnet;
import me.totalfreedom.bukkittelnet.api.TelnetCommandEvent; import me.totalfreedom.bukkittelnet.api.TelnetCommandEvent;
import me.totalfreedom.bukkittelnet.api.TelnetPreLoginEvent; import me.totalfreedom.bukkittelnet.api.TelnetPreLoginEvent;
@ -10,13 +7,18 @@ import me.totalfreedom.bukkittelnet.api.TelnetRequestDataTagsEvent;
import me.totalfreedom.bukkittelnet.session.ClientSession; import me.totalfreedom.bukkittelnet.session.ClientSession;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Deprecated
public class BukkitTelnetBridge extends FreedomService public class BukkitTelnetBridge extends FreedomService
{ {
@ -42,9 +44,9 @@ public class BukkitTelnetBridge extends FreedomService
return; return;
} }
final Admin admin = plugin.al.getEntryByIpFuzzy(ip); final Admin admin = plugin.al.getEntryByIp(ip);
if (admin == null || !admin.isActive() || !admin.getRank().hasConsoleVariant()) if (admin == null || !admin.isActive())
{ {
return; return;
} }
@ -80,8 +82,8 @@ public class BukkitTelnetBridge extends FreedomService
boolean active = admin.isActive(); boolean active = admin.isActive();
isAdmin = active; isAdmin = active;
isSeniorAdmin = active && admin.getRank() == Rank.SENIOR_ADMIN; isSeniorAdmin = active && admin.getRank().equals(GroupProvider.SENIOR_ADMIN.getGroup());
isTelnetAdmin = active && (isSeniorAdmin || admin.getRank() == Rank.ADMIN); isTelnetAdmin = active && (isSeniorAdmin || admin.getRank().equals(GroupProvider.ADMIN.getGroup()));
} }
playerTags.put("tfm.admin.isAdmin", isAdmin); playerTags.put("tfm.admin.isAdmin", isAdmin);
@ -90,7 +92,10 @@ public class BukkitTelnetBridge extends FreedomService
playerTags.put("tfm.playerdata.getTag", plugin.pl.getPlayer(player).getTag()); playerTags.put("tfm.playerdata.getTag", plugin.pl.getPlayer(player).getTag());
playerTags.put("tfm.essentialsBridge.getNickname", plugin.esb.getNickname(player.getName())); if (server.getPluginManager().isPluginEnabled("Essentials"))
{
playerTags.put("tfm.essentialsBridge.getNickname", plugin.esb.getNickname(player.getName()));
}
} }
} }
@ -101,15 +106,11 @@ public class BukkitTelnetBridge extends FreedomService
try try
{ {
final Plugin bukkitTelnet = server.getPluginManager().getPlugin("BukkitTelnet"); final Plugin bukkitTelnet = server.getPluginManager().getPlugin("BukkitTelnet");
if (bukkitTelnet != null) if (bukkitTelnet instanceof BukkitTelnet)
{ {
if (bukkitTelnet instanceof BukkitTelnet) bukkitTelnetPlugin = (BukkitTelnet) bukkitTelnet;
{
bukkitTelnetPlugin = (BukkitTelnet)bukkitTelnet;
}
} }
} } catch (Exception ex)
catch (Exception ex)
{ {
FLog.severe(ex); FLog.severe(ex);
} }
@ -159,8 +160,7 @@ public class BukkitTelnetBridge extends FreedomService
{ {
telnet.appender.removeSession(session); telnet.appender.removeSession(session);
session.syncTerminateSession(); session.syncTerminateSession();
} } catch (Exception ex)
catch (Exception ex)
{ {
FLog.severe("Error removing single telnet session: " + ex.getMessage()); FLog.severe("Error removing single telnet session: " + ex.getMessage());
} }
@ -168,8 +168,7 @@ public class BukkitTelnetBridge extends FreedomService
FLog.info(sessionsToRemove.size() + " telnet session(s) removed."); FLog.info(sessionsToRemove.size() + " telnet session(s) removed.");
} }
} } catch (Exception ex)
catch (Exception ex)
{ {
FLog.severe("Error removing telnet sessions: " + ex.getMessage()); FLog.severe("Error removing telnet sessions: " + ex.getMessage());
} }

View File

@ -0,0 +1,339 @@
package me.totalfreedom.totalfreedommod.bridge;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.coreprotect.CoreProtect;
import net.coreprotect.CoreProtectAPI;
import net.coreprotect.utility.Util;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
public class CoreProtectBridge extends FreedomService
{
//-- Block Inspector --//
private static final Component name = Component.text("Block Inspector").color(TextColor.color(0x30ade4));
private static final Component header = Component.text("---- ").append(name)
.append(Component.text(" ---- ")).colorIfAbsent(NamedTextColor.WHITE);
private static final Component prefix = name.append(Component.text(" - ").color(NamedTextColor.WHITE))
.colorIfAbsent(NamedTextColor.WHITE);
//--
private final HashMap<UUID, Long> cooldownMap = new HashMap<>();
private HashMap<UUID, FUtil.PaginationList<CoreProtectAPI.ParseResult>> historyMap;
//---------------------//
private CoreProtectAPI coreProtectAPI = null;
public static Long getSecondsLeft(long prevTime, int timeAdd)
{
return prevTime / 1000L + timeAdd - System.currentTimeMillis() / 1000L;
}
@Override
public void onStart()
{
if (isEnabled())
{
historyMap = new HashMap<>();
}
}
@Override
public void onStop()
{
}
public CoreProtect getCoreProtect()
{
CoreProtect coreProtect = null;
try
{
final Plugin coreProtectPlugin = server.getPluginManager().getPlugin("CoreProtect");
assert coreProtectPlugin != null;
if (coreProtectPlugin instanceof CoreProtect)
{
coreProtect = (CoreProtect)coreProtectPlugin;
}
}
catch (Exception ex)
{
FLog.severe(ex);
}
return coreProtect;
}
public CoreProtectAPI getCoreProtectAPI()
{
if (coreProtectAPI == null)
{
try
{
final CoreProtect coreProtect = getCoreProtect();
coreProtectAPI = coreProtect.getAPI();
// Check if the plugin or api is not enabled, if so, return null
if (!coreProtect.isEnabled() || !coreProtectAPI.isEnabled())
{
return null;
}
}
catch (Exception ex)
{
FLog.severe(ex);
}
}
return coreProtectAPI;
}
public boolean isEnabled()
{
if (!server.getPluginManager().isPluginEnabled("CoreProtect"))
{
return false;
}
final CoreProtect coreProtect = getCoreProtect();
return coreProtect != null && coreProtect.isEnabled();
}
// Rollback the specified player's edits that were in the last 24 hours.
public void rollback(final String name)
{
if (!isEnabled())
{
return;
}
final CoreProtectAPI coreProtect = getCoreProtectAPI();
new BukkitRunnable()
{
@Override
public void run()
{
coreProtect.performRollback(86400, Collections.singletonList(name), null, null, null, null, 0, null);
}
}.runTaskAsynchronously(plugin);
}
// Reverts a rollback for the specified player's edits that were in the last 24 hours.
public void restore(final String name)
{
if (!isEnabled())
{
return;
}
final CoreProtectAPI coreProtect = getCoreProtectAPI();
new BukkitRunnable()
{
@Override
public void run()
{
coreProtect.performRestore(86400, Collections.singletonList(name), null, null, null, null, 0, null);
}
}.runTaskAsynchronously(plugin);
}
public boolean hasHistory(Player player)
{
return historyMap.containsKey(player.getUniqueId());
}
public FUtil.PaginationList<CoreProtectAPI.ParseResult> getHistoryForPlayer(Player player)
{
return historyMap.get(player.getUniqueId());
}
// TODO: Complexity is O(19). This should be reduced.
public void showPageToPlayer(Player player, FUtil.PaginationList<CoreProtectAPI.ParseResult> results, int pageNum)
{
if (player == null || !player.isOnline())
{
return;
}
List<CoreProtectAPI.ParseResult> page = results.getPage(pageNum);
if (page == null || page.isEmpty())
{
player.sendMessage(prefix.append(Component.text("No results were found.", NamedTextColor.WHITE)));
}
else
{
// This shouldn't change at all in any of the other entries, so this should be safe
Component location = Component.text(String.format("(%s, %s, %s)", results.get(0).getX(),
results.get(0).getY(), results.get(0).getZ()));
final long time = System.currentTimeMillis() / 1000;
player.sendMessage(header.append(location.color(NamedTextColor.GRAY).decorate(TextDecoration.ITALIC)));
page.forEach(entry ->
{
TextComponent.Builder line = Component.text();
// Time
line.append(Component.text(Util.getTimeSince(entry.getTime(), time, false))
.color(NamedTextColor.GRAY));
// Action
Component action = Component.text(" interacted with ");
Component symbol = Component.text(" - ", NamedTextColor.WHITE);
switch (entry.getActionId())
{
case 0 ->
{
action = Component.text(" broke ");
symbol = Component.text(" - ", NamedTextColor.RED);
}
case 1 ->
{
action = Component.text(" placed ");
symbol = Component.text(" + ", NamedTextColor.GREEN);
}
case 2 -> action = Component.text(" clicked ");
default ->
{
// Do nothing (shuts Codacy up)
}
}
// Symbol, player, action, block
line.append(symbol).append(Component.text(entry.getPlayer()).color(TextColor.color(0x30ade4)))
.append(action.color(NamedTextColor.WHITE)).append(
Component.text(entry.getBlockData().getMaterial().name().toLowerCase())
.color(TextColor.color(0x30ade4)));
// Rolled back?
if (entry.isRolledBack())
{
line.decorate(TextDecoration.STRIKETHROUGH);
}
player.sendMessage(line.append(Component.text(".", NamedTextColor.WHITE)).build());
});
if (results.getPageCount() > 1)
{
player.sendMessage(Component.text("-----", NamedTextColor.WHITE));
// Page indicator
TextComponent.Builder indicator = Component.text();
// <-
if (pageNum > 1)
{
indicator.append(Component.text("", NamedTextColor.WHITE).clickEvent(
ClickEvent.runCommand("/ins history " + (pageNum - 1))));
}
// Page <current>/<total>
indicator.append(Component.text("Page ", TextColor.color(0x30ade4)).append(Component.text(pageNum + "/"
+ results.getPageCount(), NamedTextColor.WHITE)));
// ->
if (pageNum < results.getPageCount())
{
indicator.append(Component.text("", NamedTextColor.WHITE).clickEvent(
ClickEvent.runCommand("/ins history " + (pageNum + 1))));
}
// | Use /ins history <page> for advanced navigation
indicator.append(Component.text(" | ", NamedTextColor.GRAY).append(Component.text("Use ", NamedTextColor.WHITE)
.append(Component.text("/ins history <page>", TextColor.color(0x30ade4))
.clickEvent(ClickEvent.suggestCommand("/ins history ")))
.append(Component.text(" for advanced navigation", NamedTextColor.WHITE))));
player.sendMessage(indicator.build());
}
}
}
public CompletableFuture<FUtil.PaginationList<CoreProtectAPI.ParseResult>> lookupForPlayer(Block block, Player player)
{
cooldownMap.put(player.getUniqueId(), System.currentTimeMillis());
CoreProtectAPI api = getCoreProtectAPI();
return CompletableFuture.supplyAsync(() ->
{
historyMap.remove(player.getUniqueId());
FUtil.PaginationList<CoreProtectAPI.ParseResult> pages = new FUtil.PaginationList<>(10);
api.blockLookup(block, -1).forEach(stringArray -> pages.add(api.parseResult(stringArray)));
historyMap.put(player.getUniqueId(), pages);
return pages;
});
}
@EventHandler(priority = EventPriority.MONITOR)
public void onInteract(PlayerInteractEvent event)
{
// The inspector only works if we have CoreProtect installed
if (!isEnabled())
{
return;
}
Player player = event.getPlayer();
if ((event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)
&& plugin.pl.getData(player.getUniqueId()).hasInspection())
{
event.setCancelled(true);
Block block = event.getClickedBlock();
Optional<Long> cooldown = Optional.ofNullable(cooldownMap.get(player.getUniqueId()));
if (cooldown.isPresent() && getSecondsLeft(cooldown.get(), 3) > 0L)
{
player.sendMessage(prefix.append(Component.text("You need to wait ")
.append(Component.text(getSecondsLeft(cooldown.get(), 3)))
.append(Component.text(" seconds before you can make another query."))
.color(NamedTextColor.WHITE)));
return;
}
// Time to do a look-up.
if (block != null)
{
/* This is a hack to make it so that when you right-click, the coordinates that get used depend on
* what's in your hand. Non-blocks use the block you clicked directly, but blocks use wherever the
* block was supposed to be placed. */
ItemStack hand = player.getInventory().getItemInMainHand();
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && hand.getType().isBlock() && hand.getType() != Material.AIR)
{
block = block.getRelative(event.getBlockFace()).getState().getBlock();
}
lookupForPlayer(block, player).thenAccept(results ->
{
if (results.isEmpty())
{
player.sendMessage(prefix.append(Component.text("No results were found.").color(NamedTextColor.WHITE)));
}
else
{
showPageToPlayer(player, results, 1);
}
});
}
}
}
}

View File

@ -4,7 +4,7 @@ import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User; import com.earth2me.essentials.User;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
@ -28,11 +28,13 @@ public class EssentialsBridge extends FreedomService
@Override @Override
public void onStart() public void onStart()
{ {
// This is completely useless, but it's here to make sure the service is loaded.
} }
@Override @Override
public void onStop() public void onStop()
{ {
essentialsPlugin = null;
} }
public Essentials getEssentialsPlugin() public Essentials getEssentialsPlugin()
@ -43,9 +45,9 @@ public class EssentialsBridge extends FreedomService
{ {
final Plugin essentials = server.getPluginManager().getPlugin("Essentials"); final Plugin essentials = server.getPluginManager().getPlugin("Essentials");
assert essentials != null; assert essentials != null;
if (essentials instanceof Essentials) if (essentials instanceof Essentials e)
{ {
essentialsPlugin = (Essentials)essentials; essentialsPlugin = e;
} }
} }
catch (Exception ex) catch (Exception ex)
@ -114,8 +116,7 @@ public class EssentialsBridge extends FreedomService
User user = getEssentialsUser(username); User user = getEssentialsUser(username);
if (user != null) if (user != null)
{ {
Long l = FUtil.getField(user, "lastActivity"); return user.getLastOnlineActivity();
return (l != null) ? l : 0L;
} }
} }
catch (Exception ex) catch (Exception ex)
@ -155,9 +156,9 @@ public class EssentialsBridge extends FreedomService
if (inventoryHolder instanceof HumanEntity) if (inventoryHolder instanceof HumanEntity)
{ {
Player invOwner = (Player)inventoryHolder; Player invOwner = (Player)inventoryHolder;
Rank recieverRank = plugin.rm.getRank(player); DisplayableGroup recieverRank = plugin.rm.getRank(player);
Rank playerRank = plugin.rm.getRank(invOwner); DisplayableGroup playerRank = plugin.rm.getRank(invOwner);
if (playerRank.ordinal() >= recieverRank.ordinal() || !invOwner.isOnline()) if (playerRank.getWeight() >= recieverRank.getWeight() || !invOwner.isOnline())
{ {
event.setCancelled(true); event.setCancelled(true);
refreshPlayer = player; refreshPlayer = player;
@ -205,13 +206,6 @@ public class EssentialsBridge extends FreedomService
} }
} }
// TODO: Actually use this for something or remove it.
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
}
public boolean isEnabled() public boolean isEnabled()
{ {
final Essentials ess = getEssentialsPlugin(); final Essentials ess = getEssentialsPlugin();

View File

@ -5,12 +5,13 @@ import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
public class LibsDisguisesBridge extends FreedomService public class LibsDisguisesBridge extends FreedomService
{ {
private LibsDisguises libsDisguisesPlugin = null; private static LibsDisguises libsDisguisesPlugin = null;
@Override @Override
public void onStart() public void onStart()
@ -22,22 +23,18 @@ public class LibsDisguisesBridge extends FreedomService
{ {
} }
public LibsDisguises getLibsDisguisesPlugin() public static LibsDisguises getLibsDisguisesPlugin()
{ {
if (libsDisguisesPlugin == null) if (libsDisguisesPlugin == null)
{ {
try try
{ {
final Plugin libsDisguises = server.getPluginManager().getPlugin("LibsDisguises"); final Plugin libsDisguises = Bukkit.getServer().getPluginManager().getPlugin("LibsDisguises");
if (libsDisguises != null) if (libsDisguises instanceof LibsDisguises)
{ {
if (libsDisguises instanceof LibsDisguises) libsDisguisesPlugin = (LibsDisguises) libsDisguises;
{
libsDisguisesPlugin = (LibsDisguises)libsDisguises;
}
} }
} } catch (Exception ex)
catch (Exception ex)
{ {
FLog.severe(ex); FLog.severe(ex);
} }
@ -68,8 +65,7 @@ public class LibsDisguisesBridge extends FreedomService
DisguiseAPI.undisguiseToAll(player); DisguiseAPI.undisguiseToAll(player);
} }
} }
} } catch (Exception ex)
catch (Exception ex)
{ {
FLog.severe(ex); FLog.severe(ex);
} }
@ -80,7 +76,7 @@ public class LibsDisguisesBridge extends FreedomService
return !BlockedDisguises.disabled; return !BlockedDisguises.disabled;
} }
public void setDisguisesEnabled(boolean state) public static void setDisguisesEnabled(boolean state)
{ {
final LibsDisguises libsDisguises = getLibsDisguisesPlugin(); final LibsDisguises libsDisguises = getLibsDisguisesPlugin();

View File

@ -0,0 +1,59 @@
package me.totalfreedom.totalfreedommod.bridge;
import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.track.TrackManager;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.UnknownDependencyException;
public class LuckPermsBridge
{
private final LuckPerms luckPerms;
public LuckPermsBridge()
{
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager()
.getRegistration(LuckPerms.class);
if (provider == null) throw new UnknownDependencyException("LuckPerms must be present!");
this.luckPerms = provider.getProvider();
setupTracks();
}
public LuckPerms getAPI()
{
return luckPerms;
}
public void setupTracks()
{
TrackManager trackManager = getAPI().getTrackManager();
if (!trackManager.isLoaded("fakeOp"))
{
trackManager.createAndLoadTrack("fakeOp").whenComplete((track, exception) ->
{
track.appendGroup(GroupProvider.NON_OP.getGroup().getLuckPermsGroup());
track.appendGroup(GroupProvider.OP.getGroup().getLuckPermsGroup());
});
}
if (!trackManager.isLoaded("admin"))
{
trackManager.createAndLoadTrack("admin").whenComplete((track, exception) ->
{
track.appendGroup(GroupProvider.ADMIN.getGroup().getLuckPermsGroup());
track.appendGroup(GroupProvider.SENIOR_ADMIN.getGroup().getLuckPermsGroup());
});
}
if (!trackManager.isLoaded("builder"))
{
trackManager.createAndLoadTrack("builder").whenComplete((track, exception) ->
track.appendGroup(GroupProvider.MASTER_BUILDER.getGroup().getLuckPermsGroup()));
}
}
}

View File

@ -48,52 +48,6 @@ public class WorldEditBridge extends FreedomService
return worldeditPlugin; return worldeditPlugin;
} }
public void undo(Player player, int count)
{
try
{
LocalSession session = getPlayerSession(player);
if (session != null)
{
final BukkitPlayer bukkitPlayer = getBukkitPlayer(player);
if (bukkitPlayer != null)
{
for (int i = 0; i < count; i++)
{
session.undo(session.getBlockBag(bukkitPlayer), bukkitPlayer);
}
}
}
}
catch (Exception ex)
{
FLog.severe(ex);
}
}
public void redo(Player player, int count)
{
try
{
LocalSession session = getPlayerSession(player);
if (session != null)
{
final BukkitPlayer bukkitPlayer = getBukkitPlayer(player);
if (bukkitPlayer != null)
{
for (int i = 0; i < count; i++)
{
session.redo(session.getBlockBag(bukkitPlayer), bukkitPlayer);
}
}
}
}
catch (Exception ex)
{
FLog.severe(ex);
}
}
public void setLimit(Player player, int limit) public void setLimit(Player player, int limit)
{ {
try try
@ -153,23 +107,4 @@ public class WorldEditBridge extends FreedomService
return null; return null;
} }
} }
private BukkitPlayer getBukkitPlayer(Player player)
{
final WorldEditPlugin wep = getWorldEditPlugin();
if (wep == null)
{
return null;
}
try
{
return wep.wrapPlayer(player);
}
catch (Exception ex)
{
FLog.severe(ex);
return null;
}
}
} }

View File

@ -124,7 +124,7 @@ public class CageData
this.location = location; this.location = location;
this.outerMaterial = outer; this.outerMaterial = outer;
this.innerMaterial = inner; this.innerMaterial = inner;
input = null; input = null; // TODO: Remove static variable declaration in a non-static block.
buildHistory(location); buildHistory(location);
regenerate(); regenerate();
@ -141,7 +141,7 @@ public class CageData
this.location = location; this.location = location;
this.outerMaterial = outer; this.outerMaterial = outer;
this.innerMaterial = inner; this.innerMaterial = inner;
CageData.input = input; CageData.input = input; // TODO: Remove static variable declaration in a non-static block.
buildHistory(location); buildHistory(location);
regenerate(); regenerate();

View File

@ -0,0 +1,10 @@
package me.totalfreedom.totalfreedommod.command;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface CommandDependencies
{
String[] value();
}

View File

@ -63,10 +63,25 @@ public class CommandLoader extends FreedomService
Set<Class<? extends FreedomCommand>> commandClasses = commandDir.getSubTypesOf(FreedomCommand.class); Set<Class<? extends FreedomCommand>> commandClasses = commandDir.getSubTypesOf(FreedomCommand.class);
commandLoading:
for (Class<? extends FreedomCommand> commandClass : commandClasses) for (Class<? extends FreedomCommand> commandClass : commandClasses)
{ {
try try
{ {
if (commandClass.isAnnotationPresent(CommandDependencies.class))
{
String[] dependencies = commandClass.getAnnotation(CommandDependencies.class).value();
for (String plugin : dependencies)
{
if (!server.getPluginManager().isPluginEnabled(plugin))
{
FLog.warning("Not loading command due to missing dependency (" + plugin + "): /" + commandClass.getSimpleName().replace("Command_", ""));
continue commandLoading;
}
}
}
add(commandClass.newInstance()); add(commandClass.newInstance());
} }
catch (InstantiationException | IllegalAccessException | ExceptionInInitializerError ex) catch (InstantiationException | IllegalAccessException | ExceptionInInitializerError ex)

View File

@ -2,13 +2,12 @@ package me.totalfreedom.totalfreedommod.command;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import me.totalfreedom.totalfreedommod.rank.Rank;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface CommandPermissions public @interface CommandPermissions
{ {
Rank level() default Rank.NON_OP; String permission() default "default";
SourceType source() default SourceType.BOTH; SourceType source() default SourceType.BOTH;

View File

@ -1,13 +1,13 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.Rank; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "adminchat", source = SourceType.BOTH)
@CommandParameters(description = "Talk privately with other admins on the server.", usage = "/<command> [message]", aliases = "o,sc,ac,staffchat") @CommandParameters(description = "Talk privately with other admins on the server.", usage = "/<command> [message]", aliases = "o,sc,ac,staffchat")
public class Command_adminchat extends FreedomCommand public class Command_adminchat extends FreedomCommand
{ {
@ -19,15 +19,14 @@ public class Command_adminchat extends FreedomCommand
{ {
if (senderIsConsole) if (senderIsConsole)
{ {
msg("You must be in-game to toggle admin chat, it cannot be toggled via CONSOLE or Telnet."); msgNew("<red>You must be in-game to toggle admin chat, it cannot be toggled via CONSOLE or Telnet.");
return true; return true;
} }
FPlayer userinfo = plugin.pl.getPlayer(playerSender); FPlayer userinfo = plugin.pl.getPlayer(playerSender);
userinfo.setAdminChat(!userinfo.inAdminChat()); userinfo.setAdminChat(!userinfo.inAdminChat());
msg("Admin chat turned " + (userinfo.inAdminChat() ? "on" : "off") + "."); msgNew("Admin chat turned <status>.", Placeholder.unparsed("status", userinfo.inAdminChat() ? "on" : "off"));
} } else
else
{ {
plugin.cm.adminChat(sender, StringUtils.join(args, " ")); plugin.cm.adminChat(sender, StringUtils.join(args, " "));
} }

View File

@ -2,15 +2,11 @@ package me.totalfreedom.totalfreedommod.command;
import java.util.List; import java.util.List;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) @CommandPermissions(permission = "admininfo", source = SourceType.BOTH)
@CommandParameters(description = "Information on how to apply for admin.", usage = "/<command>", aliases = "si,ai,staffinfo") @CommandParameters(description = "Information on how to apply for admin.", usage = "/<command>", aliases = "si,ai,staffinfo")
public class Command_admininfo extends FreedomCommand public class Command_admininfo extends FreedomCommand
{ {
@ -22,12 +18,13 @@ public class Command_admininfo extends FreedomCommand
if (adminInfo.isEmpty()) if (adminInfo.isEmpty())
{ {
msg("The admin information section of the config.yml file has not been configured.", ChatColor.RED); msgNew("<red>The admin information section of the config.yml file has not been configured.");
} }
else else
{ {
msg(FUtil.colorize(StringUtils.join(adminInfo, "\n"))); adminInfo.forEach(this::msgNew);
} }
return true; return true;
} }
} }

View File

@ -4,13 +4,13 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "adminmode", source = SourceType.BOTH)
@CommandParameters(description = "Denies joining of operators and only allows admins to join.", usage = "/<command> [on | off]", aliases = "staffmode") @CommandParameters(description = "Denies joining of operators and only allows admins to join.", usage = "/<command> [on | off]", aliases = "staffmode")
public class Command_adminmode extends FreedomCommand public class Command_adminmode extends FreedomCommand
{ {
@ -33,13 +33,8 @@ public class Command_adminmode extends FreedomCommand
{ {
ConfigEntry.ADMIN_ONLY_MODE.setBoolean(true); ConfigEntry.ADMIN_ONLY_MODE.setBoolean(true);
FUtil.adminAction(sender.getName(), "Closing the server to non-admins", true); FUtil.adminAction(sender.getName(), "Closing the server to non-admins", true);
for (Player player : server.getOnlinePlayers()) server.getOnlinePlayers().stream().filter(player -> !isAdmin(player)).forEach(player ->
{ player.kick(Component.text("The server is now closed to non-admins.")));
if (!isAdmin(player))
{
player.kickPlayer("Server is now closed to non-admins.");
}
}
return true; return true;
} }

View File

@ -4,15 +4,15 @@ import io.papermc.lib.PaperLib;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.world.WorldTime; import me.totalfreedom.totalfreedommod.world.WorldTime;
import me.totalfreedom.totalfreedommod.world.WorldWeather; import me.totalfreedom.totalfreedommod.world.WorldWeather;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) @CommandPermissions(permission = "adminworld", source = SourceType.BOTH)
@CommandParameters(description = "Allows for admins to configure time, and weather of the AdminWorld, and allows for admins and ops to go to the AdminWorld.", @CommandParameters(description = "Allows for admins to configure time, and weather of the AdminWorld, and allows for admins and ops to go to the AdminWorld.",
usage = "/<command> [time <morning | noon | evening | night> | weather <off | rain | storm>]", usage = "/<command> [time <morning | noon | evening | night> | weather <off | rain | storm>]",
aliases = "sw,aw,staffworld") aliases = "sw,aw,staffworld")
@ -49,7 +49,7 @@ public class Command_adminworld extends FreedomCommand
{ {
switch (commandMode) switch (commandMode)
{ {
case TELEPORT: case TELEPORT ->
{ {
if (!(sender instanceof Player) || playerSender == null) if (!(sender instanceof Player) || playerSender == null)
{ {
@ -60,24 +60,21 @@ public class Command_adminworld extends FreedomCommand
try try
{ {
adminWorld = plugin.wm.adminworld.getWorld(); adminWorld = plugin.wm.adminworld.getWorld();
} } catch (Exception ignored)
catch (Exception ignored)
{ {
} }
if (adminWorld == null || playerSender.getWorld() == adminWorld) if (adminWorld == null || playerSender.getWorld() == adminWorld)
{ {
msg("Going to the main world."); msgNew("Going to the main world.");
PaperLib.teleportAsync(playerSender, server.getWorlds().get(0).getSpawnLocation()); PaperLib.teleportAsync(playerSender, server.getWorlds().get(0).getSpawnLocation());
} } else
else
{ {
msg("Going to the AdminWorld."); msgNew("Going to the AdminWorld.");
plugin.wm.adminworld.sendToWorld(playerSender); plugin.wm.adminworld.sendToWorld(playerSender);
} }
break;
} }
case TIME: case TIME ->
{ {
assertCommandPerms(sender, playerSender); assertCommandPerms(sender, playerSender);
@ -87,21 +84,18 @@ public class Command_adminworld extends FreedomCommand
if (timeOfDay != null) if (timeOfDay != null)
{ {
plugin.wm.adminworld.setTimeOfDay(timeOfDay); plugin.wm.adminworld.setTimeOfDay(timeOfDay);
msg("AdminWorld time set to: " + timeOfDay.name()); msgNew("AdminWorld time set to: <time>", Placeholder.unparsed("time", timeOfDay.name()));
} } else
else
{ {
msg("Invalid time of day. Can be: sunrise, noon, sunset, midnight"); msgNew("<red>Invalid time of day. Can be: sunrise, noon, sunset, midnight");
} }
} } else
else
{ {
return false; return false;
} }
break;
} }
case WEATHER: case WEATHER ->
{ {
assertCommandPerms(sender, playerSender); assertCommandPerms(sender, playerSender);
@ -111,21 +105,18 @@ public class Command_adminworld extends FreedomCommand
if (weatherMode != null) if (weatherMode != null)
{ {
plugin.wm.adminworld.setWeatherMode(weatherMode); plugin.wm.adminworld.setWeatherMode(weatherMode);
msg("AdminWorld weather set to: " + weatherMode.name()); msgNew("AdminWorld weather set to <mode>.", Placeholder.unparsed("mode", weatherMode.name()));
} } else
else
{ {
msg("Invalid weather mode. Can be: off, rain, storm"); msgNew("<red>Invalid weather mode. Can be: off, rain, storm");
} }
} } else
else
{ {
return false; return false;
} }
break;
} }
default: default ->
{ {
return false; return false;
} }
@ -137,7 +128,7 @@ public class Command_adminworld extends FreedomCommand
{ {
return noPerms(); return noPerms();
} }
msg(ex.getMessage()); msgNew("<red>" + ex.getMessage());
return true; return true;
} }
@ -147,7 +138,7 @@ public class Command_adminworld extends FreedomCommand
// TODO: Redo this properly // TODO: Redo this properly
private void assertCommandPerms(CommandSender sender, Player playerSender) throws PermissionDeniedException private void assertCommandPerms(CommandSender sender, Player playerSender) throws PermissionDeniedException
{ {
if (!(sender instanceof Player) || playerSender == null || !isAdmin(sender)) if (!(sender instanceof Player) || playerSender == null || !sender.hasPermission("tfm.adminworld.manage"))
{ {
throw new PermissionDeniedException(); throw new PermissionDeniedException();
} }

View File

@ -1,12 +1,11 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "announce", source = SourceType.BOTH)
@CommandParameters(description = "Make an announcement anonymously to operators.", usage = "/<command> <message>") @CommandParameters(description = "Make an announcement anonymously to operators.", usage = "/<command> <message>")
public class Command_announce extends FreedomCommand public class Command_announce extends FreedomCommand
{ {

View File

@ -1,11 +1,11 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "autoclear", source = SourceType.BOTH)
@CommandParameters(description = "Toggle whether or not a player has their inventory automatically cleared when they join", usage = "/<command> <player>") @CommandParameters(description = "Toggle whether or not a player has their inventory automatically cleared when they join", usage = "/<command> <player>")
public class Command_autoclear extends FreedomCommand public class Command_autoclear extends FreedomCommand
{ {
@ -29,7 +29,8 @@ public class Command_autoclear extends FreedomCommand
plugin.lp.CLEAR_ON_JOIN.add(args[0]); plugin.lp.CLEAR_ON_JOIN.add(args[0]);
} }
msg(args[0] + " will " + (enabled ? "no longer" : "now") + " have their inventory cleared when they join."); msgNew("<player> will <status> have their inventory cleared when they join.",
Placeholder.unparsed("player", args[0]), Placeholder.unparsed("status", enabled ? "no longer" : "now"));
return true; return true;
} }

View File

@ -1,11 +1,11 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "autotp", source = SourceType.BOTH)
@CommandParameters(description = "Toggle whether or not a player is automatically teleported when they join", usage = "/<command> <player>") @CommandParameters(description = "Toggle whether or not a player is automatically teleported when they join", usage = "/<command> <player>")
public class Command_autotp extends FreedomCommand public class Command_autotp extends FreedomCommand
{ {
@ -29,8 +29,8 @@ public class Command_autotp extends FreedomCommand
plugin.lp.TELEPORT_ON_JOIN.add(args[0]); plugin.lp.TELEPORT_ON_JOIN.add(args[0]);
} }
msg(args[0] + " will " + (enabled ? "no longer" : "now") + " be automatically teleported when they join."); msgNew("<player> will <status> be automatically teleported when they join.",
Placeholder.unparsed("player", args[0]), Placeholder.unparsed("status", enabled ? "no longer" : "now"));
return true; return true;
} }
} }

View File

@ -7,11 +7,10 @@ import me.totalfreedom.totalfreedommod.banning.Ban;
import me.totalfreedom.totalfreedommod.player.PlayerData; import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.punishments.Punishment; import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType; import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
@ -19,7 +18,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH, blockHostConsole = true) @CommandPermissions(permission = "ban", source = SourceType.BOTH, blockHostConsole = true)
@CommandParameters(description = "Bans the specified player.", usage = "/<command> <username> [reason] [-nrb | -q]", aliases = "gtfo") @CommandParameters(description = "Bans the specified player.", usage = "/<command> <username> [reason] [-nrb | -q]", aliases = "gtfo")
public class Command_ban extends FreedomCommand public class Command_ban extends FreedomCommand
{ {
@ -118,7 +117,7 @@ public class Command_ban extends FreedomCommand
} }
else else
{ {
msg("Banned " + player.getName() + " quietly."); msgNew("Banned <player> quietly.", Placeholder.unparsed("player", player.getName()));
} }
// Kill player // Kill player
player.setHealth(0.0); player.setHealth(0.0);
@ -160,7 +159,9 @@ public class Command_ban extends FreedomCommand
{ {
bcast.append(" - Reason: ").append(ChatColor.YELLOW).append(reason); bcast.append(" - Reason: ").append(ChatColor.YELLOW).append(reason);
} }
msg(sender, ChatColor.GRAY + username + " has been banned and IP is: " + ip); msgNew("<name> has been banned and their IP is <ip>.",
Placeholder.unparsed("name", username),
Placeholder.unparsed("ip", ip));
FUtil.adminAction(sender.getName(), bcast.toString(), true); FUtil.adminAction(sender.getName(), bcast.toString(), true);
} }
@ -168,13 +169,9 @@ public class Command_ban extends FreedomCommand
if (player != null) if (player != null)
{ {
player.kickPlayer(ban.bakeKickMessage()); player.kickPlayer(ban.bakeKickMessage());
for (Player p : Bukkit.getOnlinePlayers())
{ server.getOnlinePlayers().stream().filter(pl -> FUtil.getIp(pl).equalsIgnoreCase(ip)).forEach(pl ->
if (FUtil.getIp(p).equals(FUtil.getIp(player))) player.kickPlayer(ban.bakeKickMessage()));
{
p.kickPlayer(ChatColor.RED + "You've been kicked because someone on your IP has been banned.");
}
}
} }
// Log ban // Log ban

View File

@ -1,17 +1,15 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.banning.Ban; import me.totalfreedom.totalfreedommod.banning.Ban;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH, blockHostConsole = true) @CommandPermissions(permission = "banip", source = SourceType.BOTH, blockHostConsole = true)
@CommandParameters(description = "Bans the specified ip.", usage = "/<command> <ip> [reason] [-q]") @CommandParameters(description = "Bans the specified ip.", usage = "/<command> <ip> [reason] [-q]")
public class Command_banip extends FreedomCommand public class Command_banip extends FreedomCommand
{ {
@ -32,13 +30,13 @@ public class Command_banip extends FreedomCommand
if (FUtil.isValidIPv4(ip)) if (FUtil.isValidIPv4(ip))
{ {
msg(ip + " is not a valid IP address", ChatColor.RED); msgNew("<red><ip> is not a valid IP address.", Placeholder.unparsed("ip", ip));
return true; return true;
} }
if (plugin.bm.getByIp(ip) != null) if (plugin.bm.getByIp(ip) != null)
{ {
msg("The IP " + ip + " is already banned", ChatColor.RED); msgNew("<red>The IP <ip> is already banned.", Placeholder.unparsed("ip", ip));
return true; return true;
} }
@ -61,20 +59,13 @@ public class Command_banip extends FreedomCommand
plugin.bm.addBan(ban); plugin.bm.addBan(ban);
// Kick player and handle others on IP // Kick player and handle others on IP
for (Player player : server.getOnlinePlayers()) server.getOnlinePlayers().stream().filter(player -> FUtil.getIp(player).equalsIgnoreCase(ip)).forEach(player ->
{ player.kickPlayer(ban.bakeKickMessage()));
if (FUtil.getIp(player).equals(ip))
{
player.kickPlayer(ban.bakeKickMessage());
}
if (!silent) // Broadcasts the message
{ if (!silent)
// Broadcast {
FLog.info(ChatColor.RED + sender.getName() + " - Banned the IP " + ip); plugin.cm.broadcastSplit("<red><sender> - Banned the IP <ip>", "<red><sender> - Banned an IP", Placeholder.unparsed("ip", ip));
String message = sender.getName() + " - Banned " + (plugin.al.isAdmin(player) ? "the IP " + ip : "an IP");
msg(player, message, ChatColor.RED);
}
} }
return true; return true;

View File

@ -0,0 +1,43 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.List;
@CommandPermissions(permission = "banlist", source = SourceType.BOTH)
@CommandParameters(description = "Shows all banned player names. Admins may optionally use 'purge' to clear the list.", usage = "/<command> [purge]")
public class Command_banlist extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length > 0)
{
if (args[0].equalsIgnoreCase("purge"))
{
checkPermission("tfm.banlist.purge");
FUtil.adminAction(sender.getName(), "Purging the ban list", true);
msgNew("<green>Purged <amount> player bans.", Placeholder.unparsed("amount", String.valueOf(plugin.bm.purge())));
return true;
}
return false;
}
msgNew("<total> player bans (<usernames> usernames, <ips> IPs)",
Placeholder.unparsed("total", String.valueOf(plugin.bm.getAllBans().size())),
Placeholder.unparsed("usernames", String.valueOf(plugin.bm.getUsernameBans())),
Placeholder.unparsed("ips", String.valueOf(plugin.bm.getIpBans().size())));
return true;
}
@Override
protected List<String> getTabCompleteOptions(CommandSender sender, Command command, String alias, String[] args)
{
return args.length == 1 && sender.hasPermission("tfm.banlist.purge") ? Collections.singletonList("purge") : Collections.emptyList();
}
}

View File

@ -1,16 +1,15 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.banning.Ban; import me.totalfreedom.totalfreedommod.banning.Ban;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH, blockHostConsole = true) @CommandPermissions(permission = "banname", source = SourceType.BOTH, blockHostConsole = true)
@CommandParameters(description = "Bans the specified name.", usage = "/<command> <name> [reason] [-q]") @CommandParameters(description = "Bans the specified name.", usage = "/<command> <name> [reason] [-q]")
public class Command_banname extends FreedomCommand public class Command_banname extends FreedomCommand
{ {
@ -31,7 +30,7 @@ public class Command_banname extends FreedomCommand
if (plugin.bm.getByUsername(name) != null) if (plugin.bm.getByUsername(name) != null)
{ {
msg("The name " + name + " is already banned", ChatColor.RED); msgNew("<red>The name <name> is already banned.", Placeholder.unparsed("name", name));
return true; return true;
} }

View File

@ -3,14 +3,13 @@ package me.totalfreedom.totalfreedommod.command;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.SplittableRandom; import java.util.SplittableRandom;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) @CommandPermissions(permission = "bird", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Spawns a random type of fish at your location.", usage = "/<command>") @CommandParameters(description = "Spawns a random type of fish at your location.", usage = "/<command>")
public class Command_bird extends FreedomCommand public class Command_bird extends FreedomCommand
{ {
@ -20,7 +19,7 @@ public class Command_bird extends FreedomCommand
{ {
Location location = playerSender.getTargetBlock(null, 15).getLocation().add(0, 1, 0); Location location = playerSender.getTargetBlock(null, 15).getLocation().add(0, 1, 0);
playerSender.getWorld().spawnEntity(location, getRandomFish()); playerSender.getWorld().spawnEntity(location, getRandomFish());
msg(":goodbird:"); msgNew("<rainbow>:goodbird:");
return true; return true;
} }

View File

@ -3,14 +3,13 @@ package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment; import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType; import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "blockcmd", source = SourceType.BOTH)
@CommandParameters(description = "Block all commands for everyone on the server, or a specific player.", usage = "/<command> <-a | purge | <player>>", aliases = "blockcommands,blockcommand,bc,bcmd") @CommandParameters(description = "Block all commands for everyone on the server, or a specific player.", usage = "/<command> <-a | purge | <player>>", aliases = "blockcommands,blockcommand,bc,bcmd")
public class Command_blockcmd extends FreedomCommand public class Command_blockcmd extends FreedomCommand
{ {
@ -36,7 +35,8 @@ public class Command_blockcmd extends FreedomCommand
playerdata.setCommandsBlocked(false); playerdata.setCommandsBlocked(false);
} }
} }
msg("Unblocked commands for " + counter + " players.");
msgNew("Unblocked commands for <count> players.", Placeholder.unparsed("count", String.valueOf(counter)));
return true; return true;
} }
@ -53,10 +53,10 @@ public class Command_blockcmd extends FreedomCommand
counter += 1; counter += 1;
plugin.pl.getPlayer(player).setCommandsBlocked(true); plugin.pl.getPlayer(player).setCommandsBlocked(true);
msg(player, "Your commands have been blocked by an admin.", ChatColor.RED); msgNew(player, "<red>Your commands have been blocked by an admin.");
} }
msg("Blocked commands for " + counter + " players."); msgNew("Blocked commands for <count> players.", Placeholder.unparsed("count", String.valueOf(counter)));
return true; return true;
} }
@ -64,13 +64,13 @@ public class Command_blockcmd extends FreedomCommand
if (player == null) if (player == null)
{ {
msg(FreedomCommand.PLAYER_NOT_FOUND); msg(PLAYER_NOT_FOUND);
return true; return true;
} }
if (isAdmin(player)) if (isAdmin(player))
{ {
msg(player.getName() + " is an admin, and cannot have their commands blocked."); msgNew("<player> is an admin, and cannot have their commands blocked.", Placeholder.unparsed("player", player.getName()));
return true; return true;
} }
@ -79,13 +79,13 @@ public class Command_blockcmd extends FreedomCommand
{ {
FUtil.adminAction(sender.getName(), "Blocking all commands for " + player.getName(), true); FUtil.adminAction(sender.getName(), "Blocking all commands for " + player.getName(), true);
playerdata.setCommandsBlocked(true); playerdata.setCommandsBlocked(true);
msg("Blocked commands for " + player.getName() + "."); msgNew("Blocked commands for <player>.", Placeholder.unparsed("player", player.getName()));
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.BLOCKCMD, null)); plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.BLOCKCMD, null));
} }
else else
{ {
msg("That players commands are already blocked.", ChatColor.RED); msgNew("<red>That player's commands are already blocked.");
} }
return true; return true;
} }

View File

@ -0,0 +1,113 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.Optional;
@CommandPermissions(permission = "blockedit", source = SourceType.BOTH)
@CommandParameters(description = "Restricts/restores block modification abilities for everyone on the server or a certain player.", usage = "/<command> [<player> [reason] | list | purge | all]")
public class Command_blockedit extends FreedomCommand
{
@Override
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, String[] args, final boolean senderIsConsole)
{
if (args.length > 0)
{
switch (args[0].toLowerCase())
{
case "list" ->
{
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
plugin.pl.getPlayer(player).isEditBlocked()).sorted().toList();
boolean plural = list.size() != 1;
msgNew("There <grammar> <count> player<plural> online with restricted block modification abilities: <players>",
Placeholder.unparsed("grammar", plural ? "are" : "is"),
Placeholder.unparsed("count", String.valueOf(list.size())),
Placeholder.unparsed("plural", plural ? "s" : ""),
Placeholder.unparsed("colon", list.size() > 0 ? ":" : "."),
Placeholder.unparsed("players", FUtil.listToString(list.stream().map(HumanEntity::getName).toList())));
}
case "purge" ->
{
FUtil.adminAction(sender.getName(), "Restoring block modification abilities for all players", true);
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
plugin.pl.getPlayer(player).isEditBlocked()).toList();
list.forEach(player ->
{
plugin.pl.getPlayer(player).setEditBlocked(false);
msgNew(player, "<green>Your block modification abilities have been restored.");
});
msgNew("Restored block modification abilities for <count> player<plural>.",
Placeholder.unparsed("count", String.valueOf(list.size())),
Placeholder.unparsed("plural", list.size() != 1 ? "s" : ""));
}
case "all", "-a" ->
{
FUtil.adminAction(sender.getName(), "Restricting block modification abilities for all non-admins", true);
List<? extends Player> list = server.getOnlinePlayers().stream().filter(player ->
!plugin.al.isAdmin(player)).toList();
list.forEach(player ->
{
plugin.pl.getPlayer(player).setEditBlocked(true);
msgNew(player, "<red>Your block modification abilities have been restricted.");
});
msgNew("Restricted block modification abilities for <count> player<plural>.",
Placeholder.unparsed("count", String.valueOf(list.size())),
Placeholder.unparsed("plural", list.size() != 1 ? "s" : ""));
}
default -> Optional.ofNullable(getPlayer(args[0])).ifPresentOrElse(player ->
{
FPlayer fPlayer = plugin.pl.getPlayer(player);
if (fPlayer.isEditBlocked())
{
FUtil.adminAction(sender.getName(), "Restoring block modification abilities for " + player.getName(), true);
fPlayer.setEditBlocked(false);
msgNew("Restored block modification abilities for <player>.", Placeholder.unparsed("player", player.getName()));
msgNew(player, "<green>Your block modification abilities have been restored.");
}
else
{
if (plugin.al.isAdmin(player))
{
msgNew("<red><player> is an admin, and as such cannot have their block modification abilities restricted.", Placeholder.unparsed("player", player.getName()));
}
else
{
FUtil.adminAction(sender.getName(), "Restricting block modification abilities for " + player.getName(), true);
fPlayer.setEditBlocked(true);
msgNew("Restricted block modification abilities for <player>.", Placeholder.unparsed("player", player.getName()));
msgNew(player, "<red>Your block modification abilities have been restricted.");
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player),
sender.getName(), PunishmentType.BLOCKEDIT, null));
}
}
}, () -> msg(PLAYER_NOT_FOUND));
}
return true;
}
else
{
return false;
}
}
}

View File

@ -0,0 +1,111 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
@CommandPermissions(permission = "blockpvp", source = SourceType.BOTH)
@CommandParameters(description = "Toggle PVP mode for everyone or a certain player.", usage = "/<command> [<player> | list | purge | all]", aliases = "pvpblock,pvpmode")
public class Command_blockpvp extends FreedomCommand
{
@Override
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, String[] args, final boolean senderIsConsole)
{
if (args.length == 0)
{
return false;
}
switch (args[0].toLowerCase())
{
// List
case "list" ->
{
List<String> restricted = server.getOnlinePlayers().stream().filter(player ->
plugin.pl.getPlayer(player).isPvpBlocked()).map(Player::getName).toList();
if (restricted.isEmpty())
{
msgNew("Nobody currently has their PVP abilities restricted.");
}
else
{
msgNew("PVP abilities are restricted for these player(s): <players>",
Placeholder.unparsed("players", FUtil.listToString(restricted)));
}
return true;
}
// Purge
case "purge" ->
{
FUtil.adminAction(sender.getName(), "Restoring PVP abilities for all players", true);
List<? extends Player> affected = server.getOnlinePlayers().stream().filter(player -> plugin.pl.getPlayer(player).isPvpBlocked()).toList();
affected.forEach(player ->
{
msgNew(player, "<green>Your PVP abilities have been restored.");
plugin.pl.getPlayer(player).setPvpBlocked(false);
});
msgNew("Restored PVP abilities for <count> players.", Placeholder.unparsed("count", String.valueOf(affected.size())));
}
// All
case "all" ->
{
FUtil.adminAction(sender.getName(), "Restricting PVP capabilities for all non-admins", true);
List<? extends Player> affected = server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).toList();
affected.forEach(player ->
{
msgNew(player, "<red>Your PVP abilities have been restricted.");
plugin.pl.getPlayer(player).setPvpBlocked(true);
});
msgNew("Restricted PVP abilities for <count> players.", Placeholder.unparsed("count", String.valueOf(affected.size())));
}
// Specific players
default ->
{
final Player p = getPlayer(args[0]);
if (p == null)
{
msg(PLAYER_NOT_FOUND);
return true;
}
final FPlayer pd = plugin.pl.getPlayer(p);
if (pd.isPvpBlocked())
{
FUtil.adminAction(sender.getName(), "Restoring PVP capabilities for " + p.getName(), true);
pd.setPvpBlocked(false);
msgNew("Enabled the ability to PVP for <player>.", Placeholder.unparsed("player", p.getName()));
msgNew(p, "<green>Your PVP abilities have been restored.");
}
else
{
if (plugin.al.isAdmin(p))
{
msgNew("<red><player> is an admin, and cannot have their PVP disabled.", Placeholder.unparsed("player", p.getName()));
return true;
}
FUtil.adminAction(sender.getName(), "Restricting PVP for " + p.getName(), true);
pd.setPvpBlocked(true);
plugin.pul.logPunishment(new Punishment(p.getName(), FUtil.getIp(p), sender.getName(), PunishmentType.BLOCKPVP, null));
msgNew(p, "<red>Your PVP abilities have been restricted.");
msgNew("Restricted PVP abilities for <player>. ", Placeholder.unparsed("player", p.getName()));
}
}
}
return true;
}
}

View File

@ -1,14 +1,13 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "blockredstone", source = SourceType.BOTH)
@CommandParameters(description = "Blocks redstone on the server.", usage = "/<command>", aliases = "bre") @CommandParameters(description = "Blocks redstone on the server.", usage = "/<command>", aliases = "bre")
public class Command_blockredstone extends FreedomCommand public class Command_blockredstone extends FreedomCommand
{ {

View File

@ -7,9 +7,7 @@ import java.util.List;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment; import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType; import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -17,11 +15,11 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "cage", source = SourceType.BOTH)
@CommandParameters(description = "Place a cage around someone with certain blocks, or someone's player head.", usage = "/<command> <purge | <partialname> [head | block] [playername | blockname]") @CommandParameters(description = "Place a cage around someone with certain blocks, or someone's player head.", usage = "/<command> <purge | <partialname> [head | block] [playername | blockname]")
public class Command_cage extends FreedomCommand public class Command_cage extends FreedomCommand
{ {
@Override
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole) public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
{ {
if (args.length == 0) if (args.length == 0)
@ -33,11 +31,8 @@ public class Command_cage extends FreedomCommand
if (args[0].equalsIgnoreCase("purge")) if (args[0].equalsIgnoreCase("purge"))
{ {
FUtil.adminAction(sender.getName(), "Uncaging all players", true); FUtil.adminAction(sender.getName(), "Uncaging all players", true);
for (Player player : server.getOnlinePlayers()) server.getOnlinePlayers().stream().map(player -> plugin.pl.getPlayer(player)).forEach(fPlayer ->
{ fPlayer.getCageData().setCaged(false));
final FPlayer fPlayer = plugin.pl.getPlayer(player);
fPlayer.getCageData().setCaged(false);
}
return true; return true;
} }
@ -51,7 +46,7 @@ public class Command_cage extends FreedomCommand
final FPlayer fPlayer = plugin.pl.getPlayer(player); final FPlayer fPlayer = plugin.pl.getPlayer(player);
if (fPlayer.getCageData().isCaged()) if (fPlayer.getCageData().isCaged())
{ {
msg("That player is already caged.", ChatColor.RED); msgNew("<red>That player is already caged.");
return true; return true;
} }
@ -62,7 +57,7 @@ public class Command_cage extends FreedomCommand
final String s = args[1]; final String s = args[1];
switch (s) switch (s)
{ {
case "head": case "head" ->
{ {
outerMaterial = Material.PLAYER_HEAD; outerMaterial = Material.PLAYER_HEAD;
if (args.length >= 3) if (args.length >= 3)
@ -73,9 +68,8 @@ public class Command_cage extends FreedomCommand
{ {
outerMaterial = Material.SKELETON_SKULL; outerMaterial = Material.SKELETON_SKULL;
} }
break;
} }
case "block": case "block" ->
{ {
if (args.length >= 3) if (args.length >= 3)
{ {
@ -85,11 +79,10 @@ public class Command_cage extends FreedomCommand
if (Material.matchMaterial(args[2]) != null && Material.matchMaterial(args[2]).isBlock()) if (Material.matchMaterial(args[2]) != null && Material.matchMaterial(args[2]).isBlock())
{ {
outerMaterial = Material.matchMaterial(args[2]); outerMaterial = Material.matchMaterial(args[2]);
break;
} }
else else
{ {
msg("Invalid block!", ChatColor.RED); msgNew("<red>Invalid block!");
return true; return true;
} }
} }
@ -98,7 +91,7 @@ public class Command_cage extends FreedomCommand
return false; return false;
} }
} }
default: default ->
{ {
return false; return false;
} }
@ -156,7 +149,7 @@ public class Command_cage extends FreedomCommand
{ {
if (args[1].equals("block")) if (args[1].equals("block"))
{ {
return FUtil.getAllMaterialNames(); return Arrays.stream(Material.values()).map(Enum::name).toList();
} }
else if (args[1].equals("head")) else if (args[1].equals("head"))
{ {

View File

@ -1,8 +1,6 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -10,39 +8,20 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "cake", source = SourceType.BOTH)
@CommandParameters(description = "For the people that are still alive - gives a cake to everyone on the server.", usage = "/<command>") @CommandParameters(description = "For the people that are still alive - gives a cake to everyone on the server.", usage = "/<command>")
public class Command_cake extends FreedomCommand public class Command_cake extends FreedomCommand
{ {
public static final String CAKE_LYRICS = "But there's no sense crying over every mistake. You just keep on trying till you run out of cake.";
@Override @Override
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole) public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
{ {
final StringBuilder output = new StringBuilder();
for (final String word : CAKE_LYRICS.split(" "))
{
output.append(FUtil.randomChatColor()).append(word).append(" ");
}
final ItemStack heldItem = new ItemStack(Material.CAKE); final ItemStack heldItem = new ItemStack(Material.CAKE);
final ItemMeta heldItemMeta = heldItem.getItemMeta(); final ItemMeta heldItemMeta = heldItem.getItemMeta();
assert heldItemMeta != null; assert heldItemMeta != null;
heldItemMeta.setDisplayName(ChatColor.WHITE + "The " + ChatColor.DARK_GRAY + "Lie"); heldItemMeta.displayName(FUtil.miniMessage("<white>The <dark_gray>Lie"));
heldItem.setItemMeta(heldItemMeta); heldItem.setItemMeta(heldItemMeta);
server.getOnlinePlayers().forEach(player -> player.getInventory().addItem(heldItem));
for (Player player : server.getOnlinePlayers()) server.broadcast(FUtil.miniMessage("<rainbow>But there's no sense crying over every mistake. You just keep on trying till you run out of cake."));
{
final int firstEmpty = player.getInventory().firstEmpty();
if (firstEmpty >= 0)
{
player.getInventory().setItem(firstEmpty, heldItem);
}
}
FUtil.bcastMsg(output.toString());
return true; return true;
} }
} }

View File

@ -1,29 +1,26 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "cleanchat", source = SourceType.BOTH)
@CommandParameters(description = "Clears the chat.", usage = "/<command>", aliases = "cc") @CommandParameters(description = "Clears the chat.", usage = "/<command>", aliases = "cc")
public class Command_cleanchat extends FreedomCommand public class Command_cleanchat extends FreedomCommand
{ {
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
for (Player player : server.getOnlinePlayers()) server.getOnlinePlayers().stream().filter(player -> !plugin.al.isAdmin(player)).forEach(player ->
{ {
if (!plugin.al.isAdmin(player)) for (int i = 0; i < 100; i++)
{ {
for (int i = 0; i < 100; i++) msg(player, Component.space());
{
msg(player, "");
}
} }
} });
FUtil.adminAction(sender.getName(), "Cleared chat", true); FUtil.adminAction(sender.getName(), "Cleared chat", true);
return true; return true;
} }

View File

@ -1,20 +1,26 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.ONLY_CONSOLE) @CommandDependencies({"TFD4J"})
@CommandParameters(description = "Clear the discord message queue.", usage = "/<command>") @CommandPermissions(permission = "cleardiscordqueue", source = SourceType.ONLY_CONSOLE)
@CommandParameters(description = "Clear the Discord message queue.", usage = "/<command>")
public class Command_cleardiscordqueue extends FreedomCommand public class Command_cleardiscordqueue extends FreedomCommand
{ {
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
if (plugin.dc == null)
{
msgNew("<red>Discord is not enabled.");
return true;
}
plugin.dc.clearQueue(); plugin.dc.clearQueue();
msg("Cleared the discord message queue."); msgNew("<green>Cleared the Discord message queue.");
return true; return true;
} }
} }

View File

@ -0,0 +1,41 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.api.ShopItem;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandDependencies({"TF-Shoppe"})
@CommandPermissions(permission = "clownfish", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Obtain a clown fish", usage = "/<command>")
public class Command_clownfish extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (plugin.sh == null)
{
msgNew("<red>Shop is currently disabled.");
return true;
}
if (plugin.pl.getData(playerSender).hasItem(ShopItem.CLOWN_FISH))
{
playerSender.getInventory().addItem(plugin.sh.getClownFish());
msgNew("<green>You have been given a <name>.", Placeholder.unparsed("name", ShopItem.CLOWN_FISH.getName()));
}
else if (plugin.pl.getPlayer(playerSender).isClownfishDisabled())
{
msgNew("<red>An admin has disabled your ability to use the <name>. Guess you were the clown after all.",
Placeholder.unparsed("name", ShopItem.CLOWN_FISH.getName()));
}
else
{
msgNew("<red>You don't own a <name>! Purchase one from the shop.", Placeholder.unparsed("name", ShopItem.CLOWN_FISH.getName()));
}
return true;
}
}

View File

@ -1,12 +1,12 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.rank.Rank; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.ONLY_IN_GAME) @CommandPermissions(permission = "cmdspy", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Spy on commands", usage = "/<command>", aliases = "commandspy") @CommandParameters(description = "Spy on commands", usage = "/<command>", aliases = "commandspy")
public class Command_cmdspy extends FreedomCommand public class Command_cmdspy extends FreedomCommand
{ {
@ -16,7 +16,7 @@ public class Command_cmdspy extends FreedomCommand
{ {
Admin admin = plugin.al.getAdmin(playerSender); Admin admin = plugin.al.getAdmin(playerSender);
admin.setCommandSpy(!admin.getCommandSpy()); admin.setCommandSpy(!admin.getCommandSpy());
msg("CommandSpy " + (admin.getCommandSpy() ? "enabled." : "disabled.")); msgNew("CommandSpy <status>.", Placeholder.unparsed("status", admin.getCommandSpy() ? "enabled." : "disabled."));
plugin.al.save(admin); plugin.al.save(admin);
plugin.al.updateTables(); plugin.al.updateTables();
return true; return true;

View File

@ -2,9 +2,8 @@ package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.PlayerData; import me.totalfreedom.totalfreedommod.player.PlayerData;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -12,41 +11,42 @@ import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@CommandPermissions(level = Rank.OP, source = SourceType.BOTH) @CommandDependencies({"TF-Shoppe"})
@CommandPermissions(permission = "coins", source = SourceType.BOTH)
@CommandParameters(description = "Shows the amount of coins you or another player has. Also allows you to give coins to other players.", usage = "/<command> [player] | pay <player> <amount>") @CommandParameters(description = "Shows the amount of coins you or another player has. Also allows you to give coins to other players.", usage = "/<command> [player] | pay <player> <amount>")
public class Command_coins extends FreedomCommand public class Command_coins extends FreedomCommand
{ {
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
if (!ConfigEntry.SHOP_ENABLED.getBoolean()) if (plugin.sh == null || !ConfigEntry.SHOP_ENABLED.getBoolean())
{ {
msg("The shop is currently disabled!", ChatColor.RED); msgNew("<red>The shop is currently disabled!");
return true; return true;
} }
final String prefix = FUtil.colorize(ConfigEntry.SHOP_PREFIX.getString() + " ");
switch (args.length) switch (args.length)
{ {
// Mode for seeing how many coins the sender has (doesn't work from console) // Mode for seeing how many coins the sender has (doesn't work from console)
case 0: case 0 ->
{ {
if (senderIsConsole) if (senderIsConsole)
{ {
msg("When used from the console, you must define a target player."); msgNew("When used from the console, you must define a target player.");
} }
else else
{ {
PlayerData playerData = getData(playerSender); PlayerData playerData = getData(playerSender);
msg(prefix + ChatColor.GREEN + "You have " + ChatColor.RED + playerData.getCoins() + ChatColor.GREEN msgNew("<green>You have <gold><coins></gold> coin<plural>.",
+ " coins."); Placeholder.unparsed("coins", String.valueOf(playerData.getCoins())),
Placeholder.unparsed("plural", playerData.getCoins() > 1 ? "s" : ""));
} }
return true; return true;
} }
// Mode for seeing how many coins a player has. // Mode for seeing how many coins a player has.
case 1: case 1 ->
{ {
Player target = getPlayer(args[0]); Player target = getPlayer(args[0]);
@ -57,13 +57,17 @@ public class Command_coins extends FreedomCommand
else else
{ {
PlayerData playerData = getData(target); PlayerData playerData = getData(target);
msg(prefix + ChatColor.GREEN + target.getName() + " has " + ChatColor.RED + playerData.getCoins() + ChatColor.GREEN + " coins."); msgNew("<green><gold><player></gold> has <gold><coins></gold> coin<plural>.",
Placeholder.unparsed("player", target.getName()),
Placeholder.unparsed("coins", String.valueOf(playerData.getCoins())),
Placeholder.unparsed("plural", playerData.getCoins() > 1 ? "s" : ""));
} }
return true; return true;
} }
// Mode for paying another player coins // Mode for paying another player coins
case 3: case 3 ->
{ {
if (args[0].equalsIgnoreCase("pay")) if (args[0].equalsIgnoreCase("pay"))
{ {
@ -82,14 +86,14 @@ public class Command_coins extends FreedomCommand
} }
catch (NumberFormatException ex) catch (NumberFormatException ex)
{ {
msg("Invalid number: " + args[2], ChatColor.RED); msgNew("<red>Invalid number: <num>", Placeholder.unparsed("num", args[2]));
return true; return true;
} }
// Prevents players from performing transactions they can't afford to do. // Prevents players from performing transactions they can't afford to do.
if (senderData.getCoins() < coinsToTransfer) if (senderData.getCoins() < coinsToTransfer)
{ {
msg("You don't have enough coins to perform this transaction.", ChatColor.RED); msgNew("<red>You don't have enough coins to perform this transaction.");
return true; return true;
} }
@ -103,22 +107,27 @@ public class Command_coins extends FreedomCommand
playerData.setCoins(playerData.getCoins() + coinsToTransfer); playerData.setCoins(playerData.getCoins() + coinsToTransfer);
senderData.setCoins(senderData.getCoins() - coinsToTransfer); senderData.setCoins(senderData.getCoins() - coinsToTransfer);
msg(target, sender.getName() boolean plural = coinsToTransfer > 1;
+ ChatColor.GREEN + " has given you "
+ ChatColor.GOLD + coinsToTransfer
+ ChatColor.GREEN + " coin" + (coinsToTransfer > 1 ? "s" : "") + "!", ChatColor.GOLD);
msg("You have given " msgNew(target, "<green><gold><sender></gold> has given you <gold><coins></gold> coin<plural>!",
+ ChatColor.GOLD + coinsToTransfer Placeholder.unparsed("sender", sender.getName()),
+ ChatColor.GREEN + " coin" + (coinsToTransfer > 1 ? "s" : "") Placeholder.unparsed("coins", String.valueOf(coinsToTransfer)),
+ " to " + ChatColor.GOLD + target.getName() + ChatColor.GREEN + ".", ChatColor.GREEN); Placeholder.unparsed("plural", plural ? "s" : ""));
msgNew("<green>You have given <gold><coins></gold> coin<plural> to <gold><player></gold>.",
Placeholder.unparsed("player", target.getName()),
Placeholder.unparsed("coins", String.valueOf(coinsToTransfer)),
Placeholder.unparsed("plural", plural ? "s" : ""));
plugin.pl.save(playerData);
plugin.pl.save(senderData);
} }
return true; return true;
} }
return true;
} }
default ->
default:
{ {
return false; return false;
} }

View File

@ -1,18 +1,17 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.ONLY_CONSOLE) @CommandPermissions(permission = "consolesay", source = SourceType.ONLY_CONSOLE)
@CommandParameters(description = "Telnet/Console command - Send a chat message with chat formatting over telnet.", usage = "/<command> <message>", aliases = "csay") @CommandParameters(description = "Telnet/Console command - Send a chat message with chat formatting over telnet.", usage = "/<command> <message>", aliases = "csay")
public class Command_consolesay extends FreedomCommand public class Command_consolesay extends FreedomCommand
{ {
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
@ -21,9 +20,16 @@ public class Command_consolesay extends FreedomCommand
return false; return false;
} }
String message = StringUtils.join(args, " "); server.broadcast(FUtil.miniMessage("<gray>[CONSOLE] <red><sender> <dark_gray>» <white><message>",
FUtil.bcastMsg(String.format("§7[CONSOLE] §c%s §8\u00BB §f%s", sender.getName(), StringUtils.join(args, " "))); Placeholder.unparsed("sender", sender.getName()),
plugin.dc.messageChatChannel("[CONSOLE] " + sender.getName() + " \u00BB " + ChatColor.stripColor(message)); Placeholder.unparsed("message", StringUtils.join(args, " "))));
if (plugin.dc != null)
{
String message = StringUtils.join(args, " ");
plugin.dc.messageChatChannel("[CONSOLE] " + sender.getName() + " \u00BB " + ChatColor.stripColor(message), true);
}
return true; return true;
} }
} }

View File

@ -0,0 +1,34 @@
package me.totalfreedom.totalfreedommod.command;
import java.util.Collections;
import java.util.Random;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@CommandPermissions(permission = "cookie", source = SourceType.BOTH)
@CommandParameters(description = "For those who have no friends - gives a cookie to everyone on the server.", usage = "/<command>")
public class Command_cookie extends FreedomCommand
{
private static final Random RANDOM = new Random();
@Override
public boolean run(CommandSender sender, Player sender_p, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
final ItemStack heldItem = new ItemStack(Material.COOKIE);
final ItemMeta heldItemMeta = heldItem.getItemMeta();
assert heldItemMeta != null;
heldItemMeta.displayName(FUtil.miniMessage("<rainbow>Cookie"));
heldItemMeta.lore(Collections.singletonList(FUtil.miniMessage("<rainbow>But, you can have a cookie anyways,\nsince you are sad you are have no friends.")));
heldItem.setItemMeta(heldItemMeta);
server.getOnlinePlayers().forEach(player -> player.getInventory().addItem(heldItem));
server.broadcast(FUtil.miniMessage("<rainbow:" + RANDOM.nextInt() + ">Imagine that you have zero cookies and you split them evenly among zero friends. How many cookies does each person get? See? It doesn't make sense. And Cookie Monster is sad that there are no cookies, and you are sad that you have no friends."));
return true;
}
}

View File

@ -1,7 +1,6 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import java.util.SplittableRandom; import java.util.SplittableRandom;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -9,7 +8,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) @CommandPermissions(permission = "deafen", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Makes random sounds.", usage = "/<command>") @CommandParameters(description = "Makes random sounds.", usage = "/<command>")
public class Command_deafen extends FreedomCommand public class Command_deafen extends FreedomCommand
{ {

View File

@ -1,9 +1,9 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import net.kyori.adventure.text.Component;
import me.totalfreedom.totalfreedommod.rank.Rank; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.ChatColor; import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -11,24 +11,23 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) @CommandPermissions(permission = "debugstick", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Get a stick of happiness.", usage = "/<command>") @CommandParameters(description = "Get a stick of happiness.", usage = "/<command>")
public class Command_debugstick extends FreedomCommand public class Command_debugstick extends FreedomCommand
{ {
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
ItemStack itemStack = new ItemStack(Material.DEBUG_STICK); ItemStack itemStack = new ItemStack(Material.DEBUG_STICK);
ItemMeta itemMeta = itemStack.getItemMeta(); ItemMeta itemMeta = itemStack.getItemMeta();
assert itemMeta != null; assert itemMeta != null;
itemMeta.setDisplayName(ChatColor.GOLD.toString() + ChatColor.BOLD.toString() + "Stick of Happiness"); itemMeta.displayName(Component.text("Stick of Happiness", NamedTextColor.GOLD).decorate(TextDecoration.BOLD));
List<String> lore = Arrays.asList( itemMeta.lore(Arrays.asList(
ChatColor.RED + "This is the most powerful stick in the game.", Component.text("This is the most powerful stick in the game.", NamedTextColor.RED),
ChatColor.DARK_BLUE + "You can left click to select what you want to change.", Component.text("You can left click to select what you want to change.", NamedTextColor.DARK_BLUE),
ChatColor.DARK_GREEN + "And then you can right click to change it!", Component.text("And then you can right click to change it!", NamedTextColor.DARK_GREEN),
ChatColor.DARK_PURPLE + "Isn't technology amazing?"); Component.text("Isn't technology amazing?", NamedTextColor.DARK_PURPLE)
itemMeta.setLore(lore); ));
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
playerSender.getInventory().addItem(itemStack); playerSender.getInventory().addItem(itemStack);
return true; return true;

View File

@ -1,12 +1,11 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH) @CommandPermissions(permission = "denick", source = SourceType.BOTH)
@CommandParameters(description = "Essentials Interface Command - Remove the nickname of all players on the server.", usage = "/<command>") @CommandParameters(description = "Essentials Interface Command - Remove the nickname of all players on the server.", usage = "/<command>")
public class Command_denick extends FreedomCommand public class Command_denick extends FreedomCommand
{ {
@ -16,17 +15,12 @@ public class Command_denick extends FreedomCommand
{ {
if (!plugin.esb.isEnabled()) if (!plugin.esb.isEnabled())
{ {
msg("Essentials is not enabled on this server."); msgNew("<red>Essentials is not enabled on this server.");
return true; return true;
} }
FUtil.adminAction(sender.getName(), "Removing all nicknames", false); FUtil.adminAction(sender.getName(), "Removing all nicknames", false);
server.getOnlinePlayers().forEach(player -> plugin.esb.setNickname(player.getName(), null));
for (Player player : server.getOnlinePlayers())
{
plugin.esb.setNickname(player.getName(), null);
}
return true; return true;
} }
} }

View File

@ -0,0 +1,62 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.rank.HierarchyProvider;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.luckperms.api.model.user.User;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.concurrent.atomic.AtomicBoolean;
@CommandPermissions(permission = "deop", source = SourceType.BOTH)
@CommandParameters(description = "Deop a player", usage = "/<command> <partialname>")
public class Command_deop extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (args.length < 1)
{
return false;
}
boolean silent = false;
if (args.length == 2)
{
silent = args[1].equalsIgnoreCase("-s");
}
Player player = Bukkit.getServer().getPlayer(args[0]);
if (player == null || plugin.al.isVanished(player.getUniqueId()))
{
msg(sender, PLAYER_NOT_FOUND);
return true;
}
AtomicBoolean atomicBoolean = new AtomicBoolean(silent);
User user = GroupProvider.getUser(player);
HierarchyProvider.OP.getHierarchy().demoteUser(user).whenComplete((result, throwable) ->
{
if (throwable != null)
{
FLog.severe("Error while demoting " + player.getName() + " to OP: " + throwable.getMessage());
return;
}
msg(player, YOU_ARE_NOT_OP);
plugin.rm.updateDisplay(player);
if (!atomicBoolean.get())
{
FUtil.adminAction(sender.getName(), "De-opping " + player.getName(), false);
}
});
return true;
}
}

View File

@ -0,0 +1,37 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.rank.HierarchyProvider;
import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import net.luckperms.api.model.user.User;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandPermissions(permission = "deop.all", source = SourceType.BOTH, blockHostConsole = true)
@CommandParameters(description = "Deop everyone on the server.", usage = "/<command>")
public class Command_deopall extends FreedomCommand
{
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
FUtil.adminAction(sender.getName(), "De-opping all players on the server", true);
server.getOnlinePlayers().forEach(player ->
{
User user = GroupProvider.getUser(player);
HierarchyProvider.OP.getHierarchy().demoteUser(user).whenComplete((result, ex) -> {
if (ex != null) {
FLog.severe("Failed to demote " + player.getName() + " to default rank");
}
msg(player, YOU_ARE_NOT_OP);
plugin.rm.updateDisplay(player);
});
});
return true;
}
}

View File

@ -2,8 +2,8 @@ package me.totalfreedom.totalfreedommod.command;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -15,7 +15,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) @CommandPermissions(permission = "dispfill", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Fill nearby dispensers with a set of items of your choice.", usage = "/<command> <radius> <comma,separated,items>") @CommandParameters(description = "Fill nearby dispensers with a set of items of your choice.", usage = "/<command> <radius> <comma,separated,items>")
public class Command_dispfill extends FreedomCommand public class Command_dispfill extends FreedomCommand
{ {
@ -43,7 +43,7 @@ public class Command_dispfill extends FreedomCommand
} }
catch (NumberFormatException ex) catch (NumberFormatException ex)
{ {
msg("Invalid radius."); msgNew("<red>Invalid radius: <amount>", Placeholder.unparsed("amount", args[0]));
return true; return true;
} }
@ -60,7 +60,7 @@ public class Command_dispfill extends FreedomCommand
} }
else else
{ {
msg("Skipping invalid item: " + searchItem); msgNew("Skipping invalid item: <item>", Placeholder.unparsed("item", searchItem));
} }
} }
@ -76,21 +76,23 @@ public class Command_dispfill extends FreedomCommand
for (int zOffset = -radius; zOffset <= radius; zOffset++) for (int zOffset = -radius; zOffset <= radius; zOffset++)
{ {
final Block targetBlock = centerBlock.getRelative(xOffset, yOffset, zOffset); final Block targetBlock = centerBlock.getRelative(xOffset, yOffset, zOffset);
if (targetBlock.getLocation().distanceSquared(centerLocation) < (radius * radius)) if (targetBlock.getLocation().distanceSquared(centerLocation) < (radius * radius) && targetBlock.getType().equals(Material.DISPENSER))
{ {
if (targetBlock.getType().equals(Material.DISPENSER)) msgNew("Filling dispenser @ <location>", Placeholder.unparsed("location", FUtil.formatLocation(targetBlock.getLocation())));
if (plugin.cpb.isEnabled())
{ {
msg("Filling dispenser @ " + FUtil.formatLocation(targetBlock.getLocation()));
plugin.cpb.getCoreProtectAPI().logContainerTransaction(sender.getName(), targetBlock.getLocation()); plugin.cpb.getCoreProtectAPI().logContainerTransaction(sender.getName(), targetBlock.getLocation());
setDispenserContents(targetBlock, itemsArray);
affected++;
} }
setDispenserContents(targetBlock, itemsArray);
affected++;
} }
} }
} }
} }
msg("Done. " + affected + " dispenser(s) filled."); msgNew("Done. <amount> dispenser(s) filled.", Placeholder.unparsed("amount", String.valueOf(affected)));
} }
else else
{ {

View File

@ -3,11 +3,10 @@ package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.banning.Ban; import me.totalfreedom.totalfreedommod.banning.Ban;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.discord.Discord;
import me.totalfreedom.totalfreedommod.punishments.Punishment; import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType; import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -18,7 +17,7 @@ import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@CommandPermissions(level = Rank.SENIOR_ADMIN, source = SourceType.ONLY_CONSOLE, blockHostConsole = true) @CommandPermissions(permission = "doom", source = SourceType.ONLY_CONSOLE, blockHostConsole = true)
@CommandParameters(description = "Sends the specified player to their doom.", usage = "/<command> <playername> [reason]") @CommandParameters(description = "Sends the specified player to their doom.", usage = "/<command> <playername> [reason]")
public class Command_doom extends FreedomCommand public class Command_doom extends FreedomCommand
{ {
@ -52,10 +51,9 @@ public class Command_doom extends FreedomCommand
admin.setActive(false); admin.setActive(false);
plugin.al.save(admin); plugin.al.save(admin);
plugin.al.updateTables(); plugin.al.updateTables();
plugin.ptero.updateAccountStatus(admin); if (plugin.dc != null && plugin.dc.isEnabled() && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean())
if (plugin.dc.enabled && ConfigEntry.DISCORD_ROLE_SYNC.getBoolean())
{ {
Discord.syncRoles(admin, plugin.pl.getData(admin.getName()).getDiscordID()); plugin.dc.syncRoles(admin, plugin.pl.getData(admin.getName()).getDiscordID());
} }
} }
@ -119,7 +117,10 @@ public class Command_doom extends FreedomCommand
{ {
// message // message
FUtil.adminAction(sender.getName(), "Banning " + player.getName(), true); FUtil.adminAction(sender.getName(), "Banning " + player.getName(), true);
msg(sender, player.getName() + " has been banned and IP is: " + ip);
msgNew("<name> has been banned and their IP is <ip>.",
Placeholder.unparsed("name", player.getName()),
Placeholder.unparsed("ip", ip));
// generate explosion // generate explosion
player.getWorld().createExplosion(player.getLocation(), 0F, false); player.getWorld().createExplosion(player.getLocation(), 0F, false);

View File

@ -1,12 +1,11 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME) @CommandPermissions(permission = "eject", source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Eject any entities that are riding you.", usage = "/<command>") @CommandParameters(description = "Eject any entities that are riding you.", usage = "/<command>")
public class Command_eject extends FreedomCommand public class Command_eject extends FreedomCommand
{ {
@ -38,11 +37,13 @@ public class Command_eject extends FreedomCommand
if (count != 0) if (count != 0)
{ {
msg(count + " entit" + (count == 1 ? "y was" : "ies were") + " ejected.", ChatColor.GREEN); msgNew("<green><count> entit<grammar> ejected.",
Placeholder.unparsed("count", String.valueOf(count)),
Placeholder.unparsed("grammar", count == 1 ? "y was" : "ies were"));
} }
else else
{ {
msg("Nothing was ejected.", ChatColor.GREEN); msgNew("<green>Nothing was ejected.");
} }
return true; return true;

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