Compare commits

..
182 Commits
Author SHA1 Message Date
RoinujNosde 776acbebbe refactor: added PermissionsManager field to ChatHandler 2022-12-04 12:30:29 -03:00
RoinujNosde aa70a7653e feat(chat): adds permissions to use colors and formats 2022-12-03 21:47:08 -03:00
RoinujNosde 046aa1d96d fix: sets duplicate names to something unique 2022-11-30 20:01:40 -03:00
WolfBot e44775e994 chore(master): release 2.18.2-SNAPSHOT (#339) 2022-11-29 19:54:00 -03:00
WolfBot 43da5bd1f1 chore(master): release 2.18.1 (#335) 2022-11-29 19:53:16 -03:00
Minat0_ 8fa465da38 fix: missing getHandlerList on HomeRegroupEvent (#338) 2022-11-29 14:48:31 -03:00
RoinujNosde 56c7908c33 fix(bungee): error deserializing clan banners 2022-11-23 20:14:14 -03:00
RoinujNosde fc81e76521 fix: added check for clan_member on land commands 2022-11-18 19:21:01 -03:00
RoinujNosde f7fe5c4ad4 refactor: ignore unknown subchannels 2022-11-08 20:19:57 -03:00
RoinujNosde 8f4f763c37 refactor: added debug messages to BungeeManager 2022-11-04 23:15:09 -03:00
RoinujNosde 7a37382264 fix: default ranks were getting re-added on config load 2022-11-03 20:37:29 -03:00
RoinujNosde 7f9d133051 fix: channel auto creation setting not respected on join/link 2022-11-02 14:55:00 -03:00
RoinujNosde 26ba9f7329 fix: attempt at fixing NPE on getAllClanPlayers 2022-11-01 21:43:31 -03:00
Minat0_ d8cb61b0fc fix: money was not given back when channel creation failed (#336) 2022-10-31 18:39:26 -03:00
Minat0_ 3f1b06dcf9 fix: wrong path of discord economy section (#334) 2022-10-31 17:14:10 -03:00
WolfBot b043eb0742 chore(master): release 2.18.1-SNAPSHOT (#331) 2022-10-14 18:15:11 -03:00
github-actions[bot]andWolfBot 7691a4b719 chore(master): release 2.18.0 (#318)
Co-authored-by: WolfBot <112733600+bot-wolf@users.noreply.github.com>
2022-10-14 18:13:47 -03:00
Edson Passos 87ece22036 feat(lang): new crowdin updates (#319) 2022-10-14 18:10:47 -03:00
RoinujNosde f7e7ec6624 fix: removes duplicate /clan from help 2022-10-03 19:59:02 -03:00
RoinujNosde 25197cdd72 feat: add help-size config 2022-09-30 18:43:00 -03:00
Edson Passos 30a501c063 fix: ConfigurationSerializableAdapter NPE 2022-09-27 10:22:47 -03:00
RoinujNosde f14c425488 fix: NPE while purging data 2022-09-24 19:43:14 -03:00
Edson Passos cc2e32984d ci: added modrinth action 2022-09-20 20:07:56 -03:00
Edson Passos 2c9b0f98fe feat: Improves Bungee support (#327) 2022-09-17 11:22:11 -03:00
Edson Passos f484bc16c6 fix: set useSSL to false 2022-08-30 08:30:42 -03:00
RoinujNosde 37f0ecff50 fix: supports '.' and '*' as username prefix by default 2022-08-28 12:33:01 -03:00
Minat0_ c8969f2196 chore: update dependency version at README.md (#329) 2022-08-28 12:03:20 -03:00
Edson Passos b9c3cfd640 ci: adds name to job 2022-08-24 22:02:56 -03:00
RoinujNosde a440834347 feat: adds starter-ranks
A list of ranks, defined in the config, which are added to new clans
2022-08-16 19:09:10 -03:00
RoinujNosde 1adec0b89d fix: changes size of some frames for better visualization on Bedrock 2022-08-15 20:27:53 -03:00
RoinujNosde d56a0a979a feat: adds permission to bypass the teleport delay
Node: simpleclans.vip.teleport-delay
2022-08-15 20:18:53 -03:00
RoinujNosde af07988103 fix: getPastClans() preserves the insertion order 2022-08-15 19:37:17 -03:00
Edson Passos 96a13d8d6c fix: updates join date when joining a clan (#326) 2022-08-15 11:33:14 -03:00
Edson Passos 2a1ad5b5c8 fix: removes rank and join date on disband 2022-08-15 10:28:50 -03:00
RoinujNosde 1311423a17 refactor: changed members list to <ClanPlayer> 2022-08-01 19:38:50 -03:00
RoinujNosde 59e9c4caed refactor: changed clanPlayers map to <UUID, ClanPlayer> 2022-08-01 19:17:00 -03:00
RoinujNosde 4ab53d1613 perf: improved UUID lookup performance 2022-07-11 22:55:13 -03:00
RoinujNosde 2ea744443f feat: added method for registering protection providers 2022-06-27 18:58:05 -03:00
Edson Passos 8bd8bb6466 ci: disable fork on release-please 2022-06-24 19:29:58 -03:00
Minat0_ e7f756f306 fix: NPE while sending a message to spies (#322) 2022-06-24 19:27:34 -03:00
Edson Passos b7961acd5c ci: use fork on release-please 2022-06-12 15:12:43 -03:00
RoinujNosde c47289c5bf fix: NPE while collecting fees
ClanPlayer#toPlayer() returns null when the player is not connected
2022-06-12 15:10:32 -03:00
Edson Passos 7769060f4d ci: updated release-please token
This fixes actions listening to "release" not running
2022-06-10 19:35:52 -03:00
RoinujNosde a859928622 fix: NoClassDefFoundError in WorldGuard6Provider 2022-06-09 23:38:55 -03:00
RoinujNosde becb88b763 feat: adds PlayerHomeClearEvent
and fires PlayerHomeSetEvent when the mod command is used
2022-06-09 14:15:14 -03:00
RoinujNosde 711f81f3da ci: update java version
here we go again
2022-06-08 21:41:15 -03:00
RoinujNosde 7fae6f8b8a ci: added missing required input 2022-06-08 21:36:57 -03:00
RoinujNosde 62a8d304f4 ci: adds snapshots repository and udpated setup-jdk 2022-06-08 21:32:22 -03:00
Edson Passos fe8668abb0 Merge pull request #317 from RoinujNosde/release-please--branches--master
chore(master): release 2.17.1-SNAPSHOT
2022-06-08 21:04:55 -03:00
github-actions[bot] 36f5739f06 chore(master): release 2.17.1-SNAPSHOT 2022-06-09 00:01:26 +00:00
RoinujNosde f7465941b2 ci: updated crowdin.yml and publish actions 2022-06-08 21:00:08 -03:00
Edson Passos 2aa5b9aad3 bump version... 2022-06-08 20:20:55 -03:00
Edson Passos 51f82ba988 New Crowdin updates (#316) 2022-06-08 19:57:45 -03:00
Edson Passos 327bcf3980 v2.17.0 2022-06-08 19:45:19 -03:00
Edson Passos 5c3bb558cf feat(lang): new Crowdin updates (#295) 2022-06-08 19:27:22 -03:00
RoinujNosde c726e2bb3c feature: adds coordinates to Land 2022-06-07 14:27:17 -03:00
Edson Passos af6c72eda9 fix: war end via request 2022-06-05 12:53:56 -03:00
RoinujNosde d48c17f1f9 feature: adds permission FEE_BYPASS to ranks
removes simpleclans.member.bypass-fee
2022-05-31 19:14:00 -03:00
RoinujNosde 93eef5c727 fix: catches exceptions when creating Discord channels 2022-05-22 22:01:01 -03:00
RoinujNosde 714aa10701 fix: adds groups (Vault) to the global storage, instead of per world 2022-05-20 19:53:50 -03:00
Minat0_ b2d271b23b fix: don't confuse auto-group-groupname and auto-groups 2022-05-18 17:54:57 +03:00
RoinujNosde 7dad746269 fix: possibly improves performance of ClanPlayer lookup 2022-05-17 20:28:30 -03:00
RoinujNosde 37399cd50b fix: refactored ConfirmationPrompts 2022-05-10 20:03:09 -03:00
RoinujNosde 132eac98e2 fix: doesn't try saving Players with duplicate names 2022-05-09 20:21:15 -03:00
RoinujNosde ba68e8f70a fix: doesn't try saving Players with null names 2022-05-08 18:48:25 -03:00
RoinujNosde 0d3542b4aa Merge remote-tracking branch 'origin/dev' into dev 2022-05-08 17:40:28 -03:00
RoinujNosde 94eed8710c fix!: removed PlotSquared3Provider
Maven repo is down
2022-05-08 17:40:06 -03:00
RoinujNosde 0d3d4981c0 fix: removed PlotSquared3Provider
Maven repo is down
2022-05-08 17:35:56 -03:00
Minat0_ 73fa75fccc fix!: Log "API" when player is offline (#310) 2022-05-08 16:44:17 -03:00
RoinujNosde a855b51617 fix: pending invites could bypass the max members limit 2022-05-03 20:32:39 -03:00
RoinujNosde 83e7ad4ae1 fix: duplicate usernames logic 2022-05-02 21:24:18 -03:00
RoinujNosde 05cddb7e7f feature: adds ClanPlayerTeleportEvent 2022-04-08 14:23:05 -03:00
RoinujNosde 8d1ed8cf41 fix: refactored DBCore, added caller's stack trace to db exceptions 2022-04-05 20:00:33 -03:00
RoinujNosde f8862299f2 fix: optimizes player lookup by using Bukkit#getOfflinePlayers #306 2022-04-02 20:35:09 -03:00
RoinujNosde 1de339addc fix: parsing placeholders that return new placeholders 2022-03-30 19:23:39 -03:00
RoinujNosde e929b58cd7 fix: player not removed from Discord channel on kick #305 2022-03-17 18:55:42 -03:00
RoinujNosde 237755b5d5 fix: remove colors from logged chat messages 2022-03-13 20:02:47 -03:00
RoinujNosde c648343cdc fix: stop setting player locale on insert
The player has not set a language yet
2022-03-13 00:02:19 -03:00
RoinujNosde f34b9273cc fix: setting server's default language as the player's 2022-03-12 23:44:00 -03:00
Minat0_andRoinujNosde d07bc160e6 fix: Strips only Spy and Discord chats (#304)
Co-authored-by: RoinujNosde <edsonpassosjr@outlook.com>
2022-03-12 23:24:31 -03:00
RoinujNosde 6f1f919977 fix: NoSuchFieldException on PlayerHeadCacheTask 2022-03-11 18:13:11 -03:00
Edson Passos 12a5aa92bb fix: disallows 'k' format in tags by default 2022-03-08 12:11:28 -03:00
RoinujNosde 5d7ad0808d fix: checks for valid alphabet even for players with bypass permission 2022-03-06 10:58:02 -03:00
RoinujNosde ac0e2f2116 fix: checks for spaces in tag when ACCEPT_OTHER_ALPHABETS_LETTERS is enabled 2022-03-06 10:57:10 -03:00
Edson Passos 2d553234a3 Update maven.yml 2022-03-06 01:03:38 -03:00
RoinujNosde e4588fe1ef fix: error parsing username regex 2022-03-05 22:29:09 -03:00
RoinujNosde 4221cc2fa1 fix: teleporting to highest block if home is set on a slab #301 2022-03-05 22:18:49 -03:00
RoinujNosde 5db69775a3 feature: adds username regex to config 2022-03-04 20:40:40 -03:00
Minat0_ 88f61a150f Lack of permissions when auto-create is false (#300)
* fix: Lack of permissions when auto-create is false
2022-03-03 20:06:23 -03:00
Edson Passos f0df4435be Bump version 2022-03-02 15:09:53 -03:00
Minat0_andEdson Passos 05c0f734b5 Disband command requires confirmation (#299)
* build: Add maven dependency plugin

* feature: Disband command requires confirmation

* fix: Don't create clans (event) if auto-creation is false

* Updates env variable for testing purpose

* Makes confirm and decline methods abstract

* Testing dependency plugin config

Co-authored-by: Edson Passos <edsonpassosjr@outlook.com>
2022-03-02 17:03:49 +03:00
Edson Passos 4f0b721d49 Updates SCMessage with ChatEvent changes #298 2022-03-02 07:57:11 -03:00
RoinujNosde 3ebb041a3f Merge remote-tracking branch 'origin/dev' into dev 2022-02-26 22:13:47 -03:00
RoinujNosde 3b8dc4992d fix: first time players marked as "not played before" 2022-02-26 22:13:28 -03:00
Edson Passos 16be0c12a0 Fixes line breaks in changelog 2022-02-24 22:36:27 -03:00
Edson Passos 18c7c41ac4 Updated badges and repo info 2022-02-24 22:26:21 -03:00
Edson Passos cb201eb4b8 Update publish_reposilite.yml 2022-02-24 22:01:47 -03:00
Edson Passos 7a8ac9509b Bump version 2022-02-24 21:45:33 -03:00
Edson Passos 587bd9b445 Merge pull request #296 from RoinujNosde/dev
2.16.2
2022-02-24 21:42:42 -03:00
Edson Passos 6419e16eb0 Merge branch 'master' into dev 2022-02-24 21:38:59 -03:00
RoinujNosde 59d2bfc5f8 fix: middle-click actions stopped working on 1.18 #294 2022-02-24 20:37:52 -03:00
Edson Passos e452441380 Adds 1.18 to curseforge supported versions 2022-02-24 19:00:52 -03:00
Edson Passos 4d8fc0f0e5 Updates distributionManagement 2022-02-24 16:01:42 -03:00
Edson Passos 6bbb12e901 Create publish_reposilite.yml 2022-02-24 13:07:10 -03:00
RoinujNosde 002939f2df fix: bad usage of > in javadocs 2022-02-20 15:53:02 -03:00
RoinujNosde 6f27da4bdb fix: bad usage of > in javadocs 2022-02-20 15:48:58 -03:00
RoinujNosde 268f4752d6 feature: adds javadoc plugin 2022-02-20 15:32:15 -03:00
RoinujNosde 204858dee7 fix: uses - instead of space as commit hash separator 2022-02-20 14:18:27 -03:00
RoinujNosde a0ced58a02 feature: adds commit hash to version 2022-02-20 14:15:08 -03:00
RoinujNosde b8cbf831b3 fix: sc_players.name unique constraint not being respected in some cases 2022-02-19 22:59:45 -03:00
RoinujNosde d6ec0c3a3d fix: removes duplicate methods getHealthString and getHungerString 2022-02-19 22:10:51 -03:00
RoinujNosde bf3fc03f93 fix: checks if player name is null before processing death 2022-02-19 21:58:54 -03:00
Edson Passos 52348096a0 Merge pull request #293 from RoinujNosde/l10n_dev
New Crowdin updates
2022-02-18 11:06:29 -03:00
Edson Passos 00a48b24dd New translations messages.properties (Lithuanian) 2022-02-18 11:04:44 -03:00
Edson Passos c9aae0d781 Adds Lithuanian translation (#292)
* New translations messages.properties (Russian)

* New translations messages.properties (Norwegian)

* New translations messages.properties (Lithuanian)
2022-02-18 09:35:12 -03:00
Edson Passos d0bba163a0 New Crowdin updates (#284) 2022-02-18 09:31:32 -03:00
Edson Passos cd0e75483a Merge pull request #290 from Tomut0/dev
Some fixes on messages.properties
2022-02-16 09:40:08 -03:00
Edson Passos 2c365c5d54 Updates insufficient balance message 2022-02-16 09:38:53 -03:00
Minat0_ 9704562353 fix: Fixes "your.clan.doesnt.have.minimum.linked.player" message key 2022-02-16 11:51:43 +03:00
Minat0_ 836fc9d6a0 fix: Returns needed money as argument of "not.sufficient.money" key 2022-02-15 19:54:43 +03:00
Minat0_ cd01b0cd47 fix: Added missing message when player creates a discord channel 2022-02-15 19:54:43 +03:00
Minat0_ d797ab0908 feature: Leaders can create discord channel (#288)
* fix: CNFE on ChatManager#getDiscordHook

* Makes possible to turn off automatic discord channels creation
2022-02-14 22:32:42 -03:00
RoinujNosde fd58f4abda feature: chat listener priority can be changed via config #286 2022-02-03 18:52:34 -03:00
RoinujNosde 6653c6f8c0 feature: staffers can bypass the teleport timer 2022-02-02 19:09:45 -03:00
RoinujNosde 4dee178403 fix: removed PlotSquared5Provider 2022-02-02 18:55:01 -03:00
RoinujNosde 908451c65c feature: %rel_simpleclans_color% is configurable 2022-01-31 19:08:17 -03:00
RoinujNosde d468bd0df2 fix: temporarily removed PlotSquared5Provider as its maven repo is unavailable 2022-01-30 15:26:07 -03:00
RoinujNosde 3779585645 fix: incompatibility with UltimateChat's latest version
Added missing enum ConfigField.TAG_SEPARATOR_char (deprecated)
2022-01-30 14:36:15 -03:00
RoinujNosde c346fdf967 fix: removes player's own name from kick completion #263 2022-01-29 22:36:18 -03:00
Minat0_ 240a782774 Fixes missing clanTag argument at exception 2022-01-30 02:02:47 +03:00
Edson PassosandMinat0_ dce26a784f 2.16.1 (#283)
Adds Landlord 4 support
Fixes bug on create land event
Fixes a bug where JDA was loaded earlier than SC's DiscordHook
Fixes resetKdr not resetting ally kills
LanguageChooser now uses _ instead of -
Adds %clean-tag% placeholder for chat messages
Fixes bb settings
Fixes Vault groups getting removed only on join
Probably adds support for older GriefPrevention versions
Possibly fixes bug on home item on ClanDetailsFrame (staff)
Fixes unban command not saving changes
Strips colors from chat messages
Adds missing language keys
Fixes disallowed tags setting
Adds feature to limit past clans
Hides the player's own clan from some completions
Adds placeholder for bank bb messages
Adds bb commands for staff
Fixes player' permission was not deleted after kicking from the clan
Place command now supports offline players
Fixes not kicking a member if there is at least one leader
Adds sender to DisbandClanEvent
Fixes opening double chests - war and land sharing
Adds method to validate min, max on values
HEX support message on server startup
Bumps discordsrv to 1.24.1-SNAPSHOT
DiscordHook improvements and bug fixes
Messages updated
Removes floody debugs from ProtectionManager

Co-authored-by: Minat0_ <42711312+Tomut0@users.noreply.github.com>
2022-01-23 17:25:06 -03:00
RoinujNosde 3cac8067a6 Removes floody debugs from ProtectionManager 2022-01-23 17:04:08 -03:00
Edson Passos 993578f13e New Crowdin updates (#266) 2022-01-23 16:49:15 -03:00
Minat0_ 96da1b3936 DiscordHook improvement and fixing (#281)
Removes invalid channels on startup
Updates role after channel creation
Creating a channel on player' linking, joining
New setting - min-linked-players-to-create
Throws new exception ChannelExistsException
Makes DiscordHook#deleteChannel return boolean
2022-01-23 14:43:32 -03:00
RoinujNosde 2fc8a1aa1b Bumps discordsrv to 1.24.1-SNAPSHOT 2022-01-16 22:44:32 -03:00
Edson Passos b4cf94dab2 Merge pull request #279 from Tomut0/fix-discord-clan-creation
Fixes skipping channel creation conditions
2022-01-16 18:19:15 -03:00
Minat0_ a793e933ae Checking resolved 2022-01-17 00:07:10 +03:00
Minat0_ a0ec61cec7 Fixes skipping channel creation conditions, part 3
Capitalizes TAG_SEPARATOR_CHAR
2022-01-16 18:56:14 +03:00
Edson Passos 10b24b99a2 Testing cache setting 2022-01-13 23:43:32 -03:00
RoinujNosde 4ed174970e Merge remote-tracking branch 'origin/dev' into dev 2022-01-13 23:33:36 -03:00
RoinujNosde f7b4f5dfd9 Bumps discordsrv to 1.24.0 2022-01-13 23:33:21 -03:00
Edson Passos 8b7d8e4a72 Merge pull request #280 from Tomut0/dev
HEX support message on server startup
2022-01-12 20:11:17 -03:00
Minat0_ 8ab89cd03f HEX support message on server startup 2022-01-13 01:25:29 +03:00
RoinujNosde 47a5948157 Merge remote-tracking branch 'origin/dev' into dev 2022-01-11 19:38:53 -03:00
RoinujNosde 48e3da9716 Adds method to validate min, max on values
Overrides context resolvers from ACF to check for finite numbers (float and double)
2022-01-11 19:38:16 -03:00
Minat0_ 05ec2241f0 Revert "Replaces deprecated getItemInHand"
This reverts commit 71ad4ce160.
2022-01-10 18:25:16 +03:00
Minat0_ 4c881f4601 Fixes skipping channel creation conditions, part 2 2022-01-10 18:18:13 +03:00
Minat0_ 71ad4ce160 Replaces deprecated getItemInHand 2022-01-10 18:08:52 +03:00
Minat0_ 3c2d5c9b81 Fixes skipping channel creation conditions
Updates PaperLib to the latest
2022-01-10 17:26:27 +03:00
Edson Passos b0a0f951fa Merge pull request #278 from RoinujNosde/fix-leader-role
Fixes adding the leader role to anyone
2022-01-09 16:50:23 -03:00
Minat0_ 408647161e Fixes adding the leader role to anyone 2022-01-09 22:34:12 +03:00
RoinujNosde 55f95b405e Possibly fixes opening double chests - war and land sharing 2022-01-04 19:03:18 -03:00
RoinujNosde 0aeb153293 Adds sender to DisbandClanEvent #271 2021-12-10 19:02:02 -03:00
Edson Passos cdc185c8e7 Merge pull request #272 from RoinujNosde/Tomut0-patch-1
Fixes not kicking a member if there is at least one leader
2021-12-09 13:34:41 -03:00
Minat0_ 1f128e8368 Fixes not kicking a member if there is at least one leader
### Example:
Clan 1:
* Minat0_ (Leader)
* RoinujNosde (Member)

Following the current code logic: let's kick RoinujNosde (Member) -> check if clan leaders size == 1 (true) -> send message, return.
The solution is to *check* if this player is a leader and clan leaders size. ☕
2021-12-09 11:53:42 +03:00
RoinujNosde 2e68e7fe2f Place command now supports offline players 2021-11-29 18:16:47 -03:00
Minat0_ 388d17fe99 Fixes player' permission was not deleted after kicking from the clan (#269) 2021-11-19 15:58:38 -03:00
RoinujNosde 89d59a39d9 Adds bb commands for staff #265 2021-11-07 12:15:40 -03:00
Edson Passos d88c14359a New Crowdin updates (#261) 2021-11-07 11:45:53 -03:00
RoinujNosde ae40b35325 Adds placeholder for bank bb messages #246 2021-11-07 11:44:37 -03:00
RoinujNosde 6a410354e5 Hides the player's own clan from some completions
#263
2021-11-07 11:29:52 -03:00
Minat0_ 96c2b8c718 Adds feature to limit past clans (#264)
* Adds a view limit of past clans

* Removes Helper#toMessage

* Removes Helper#stripTrailing
2021-11-02 13:07:36 -03:00
RoinujNosde 4bf0e69734 Fixes disallowed tags setting #262 2021-10-18 21:24:43 -03:00
RoinujNosde 6803b001ce Adds missing language keys 2021-10-12 18:21:14 -03:00
Edson Passos 366863b63e New Crowdin updates (#254) 2021-10-12 18:02:53 -03:00
RoinujNosde 5c391e33c4 Strips colors from chat messages 2021-10-10 19:38:49 -03:00
RoinujNosde 448cc6093e Fixes unban command not saving changes 2021-10-08 23:33:40 -03:00
RoinujNosde 9d910759cb Possibly fixes bug on home item on ClanDetailsFrame (staff) 2021-10-06 13:42:45 -03:00
RoinujNosde cdc1808078 Fixes NoClassDefFoundError on older GriefPrevention versions 2021-09-29 21:38:06 -03:00
RoinujNosde 87541f9742 Probably adds support for older GriefPrevention versions #258 2021-09-28 23:43:44 -03:00
RoinujNosde 54f3f4ba40 Fixes Vault groups getting removed only on join #259 2021-09-28 23:34:22 -03:00
Edson Passos 4e8850e734 Fixes bb settings 2021-09-25 16:27:20 -03:00
RoinujNosde 9e55a00d68 Adds %clean-tag% placeholder for chat messages 2021-09-19 18:05:10 -03:00
Edson Passos f898631ace Merge pull request #256 from mehmet-27/patch-1
Update LanguageSelectorFrame.java
2021-09-19 16:29:36 -03:00
Mehmet f71a84a70e Update LanguageSelectorFrame.java
underscores should be used in languages shown as desired in the config
2021-09-19 22:15:22 +03:00
RoinujNosde b51f27e68b Merge remote-tracking branch 'origin/dev' into dev 2021-09-18 18:27:23 -03:00
RoinujNosde ad38548440 Fixes resetKdr not resetting ally kills 2021-09-18 18:26:28 -03:00
Edson Passos f69207f0d4 Probably fixes a bug, where JDA was loaded earlier than SC's DiscordHook. (#255) 2021-09-17 18:11:59 -03:00
Minat0_ 9fb42b7093 Probably fixes a bug, where JDA was loaded earlier than SC's DiscordHook. 2021-09-17 23:21:52 +03:00
RoinujNosde bf0670cb88 Fixes bug on create land event 2021-09-17 14:19:30 -03:00
RoinujNosde d4507f41fa Adds Landlord 4 support 2021-09-16 19:36:00 -03:00
Edson Passos 41a978a278 Added 1.17 to curseforge workflow 2021-09-13 20:54:29 -03:00
170 changed files with 7804 additions and 2849 deletions

No files matched your search

+8 -9
View File
@@ -1,24 +1,23 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI Dev Build
name: CI
on:
push:
branches: [ dev ]
branches: [ master ]
pull_request:
branches: [ dev ]
branches: [ master ]
jobs:
build:
strategy:
fail-fast: false
fail-fast: true
max-parallel: 4
matrix:
java-version: [ 8, 11, 16 ]
java-version: [ 8, 11, 16, 17 ]
runs-on: ubuntu-latest
name: Java ${{ matrix.java-version }}
steps:
- name: Checkout
uses: actions/checkout@v2
@@ -27,10 +26,10 @@ jobs:
with:
java-version: "${{ matrix.java-version }}"
distribution: 'adopt'
cache: maven
cache: 'maven'
- name: Build with Maven
run: mvn -B -U package --file pom.xml
- name: Upload a Build Artifact
- name: Upload Build Artifact
if: "${{ matrix.java-version == 8 }}"
uses: actions/upload-artifact@v2
with:
+7 -5
View File
@@ -4,15 +4,16 @@ on:
types: [created]
jobs:
build:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
uses: actions/setup-java@v2
with:
java-version: 1.8
java-version: 8
cache: 'maven'
distribution: 'adopt'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Upload artifact
@@ -23,7 +24,8 @@ jobs:
game_endpoint: minecraft
file_path: target/SimpleClans.jar
changelog: ${{ github.event.release.body }}
changelog_type: markdown
display_name: ${{ github.event.release.tag_name }}
game_versions: 7915,7667,7330,7105,6588,630,591,585,531
game_versions: 8849,8503,7915,7667,7330,7105,6588,630,591,585,531
release_type: release
relations: vault:optionalDependency,worldguard:optionalDependency,grief-prevention:optionalDependency
+31
View File
@@ -0,0 +1,31 @@
name: Publish to Modrinth
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v2
with:
java-version: 8
cache: 'maven'
distribution: 'adopt'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Upload artifact
uses: RubixDev/modrinth-upload@v1.0.0
with:
token: ${{ secrets.MODRINTH_TOKEN }}
project_id: quLDfyDl
file_path: target/SimpleClans.jar
changelog: ${{ github.event.release.body }}
name: ${{ github.event.release.tag_name }}
version: ${{ github.event.release.tag_name }}
game_versions: 1.19,1.18,1.17,1.16,1.15,1.14,1.13,1.12,1.11,1.10,1.9,1.8
release_type: release
loaders: spigot
featured: true
+29
View File
@@ -0,0 +1,29 @@
name: Publish to Reposilite
on:
push:
branches:
- master
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v2
with:
java-version: 8
server-id: reposilite # Value of the distributionManagement/repository/id field of the pom.xml
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
cache: 'maven'
distribution: 'adopt'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Publish to Reposilite
run: mvn -B deploy
env:
MAVEN_USERNAME: simpleclans
MAVEN_PASSWORD: ${{ secrets.REPOSILITE_TOKEN }}
+15
View File
@@ -0,0 +1,15 @@
on:
push:
branches:
- master
name: release-please
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v3
with:
release-type: maven
package-name: SimpleClans
token: ${{ secrets.PAT_TOKEN }}
fork: false
+49
View File
@@ -0,0 +1,49 @@
# Changelog
## [2.18.1](https://github.com/RoinujNosde/SimpleClans/compare/v2.18.0...v2.18.1) (2022-11-29)
### Bug Fixes
* added check for clan_member on land commands ([fc81e76](https://github.com/RoinujNosde/SimpleClans/commit/fc81e765211bebe22a7a6aa5d5158754580bbdc5))
* attempt at fixing NPE on getAllClanPlayers ([26ba9f7](https://github.com/RoinujNosde/SimpleClans/commit/26ba9f73296a772eaa698d2ede6fbc3831da850c))
* **bungee:** error deserializing clan banners ([56c7908](https://github.com/RoinujNosde/SimpleClans/commit/56c7908c332167cec9cca6a4ea054977d0d68b9f))
* channel auto creation setting not respected on join/link ([7f9d133](https://github.com/RoinujNosde/SimpleClans/commit/7f9d133051b9011837d0a5114abc6c3637a3f02c))
* default ranks were getting re-added on config load ([7a37382](https://github.com/RoinujNosde/SimpleClans/commit/7a37382264ff4dd5456f6930045b5102bf491897))
* missing getHandlerList on HomeRegroupEvent ([#338](https://github.com/RoinujNosde/SimpleClans/issues/338)) ([8fa465d](https://github.com/RoinujNosde/SimpleClans/commit/8fa465da385f36b1fb075031c375ef94df78ea52))
* money was not given back when channel creation failed ([#336](https://github.com/RoinujNosde/SimpleClans/issues/336)) ([d8cb61b](https://github.com/RoinujNosde/SimpleClans/commit/d8cb61b0fc9584bb58f421faf98596816621053f))
* wrong path of discord economy section ([#334](https://github.com/RoinujNosde/SimpleClans/issues/334)) ([3f1b06d](https://github.com/RoinujNosde/SimpleClans/commit/3f1b06dcf996e51a878b7fc281069e236ebcbfce))
## [2.18.0](https://github.com/RoinujNosde/SimpleClans/compare/v2.17.0...v2.18.0) (2022-10-14)
### Features
* add help-size config ([25197cd](https://github.com/RoinujNosde/SimpleClans/commit/25197cdd729cea63d7e223dc1e0aaef830613327))
* added method for registering protection providers ([2ea7444](https://github.com/RoinujNosde/SimpleClans/commit/2ea744443f502970b15859818e9d5e45ca69d453))
* adds permission to bypass the teleport delay ([d56a0a9](https://github.com/RoinujNosde/SimpleClans/commit/d56a0a979a47a140115742518e934a2469e6f880))
* adds PlayerHomeClearEvent ([becb88b](https://github.com/RoinujNosde/SimpleClans/commit/becb88b763380bed5a2e1dd209c32c8363a7f88b))
* adds starter-ranks ([a440834](https://github.com/RoinujNosde/SimpleClans/commit/a4408343479d7efa6ae5a65894f8b822ecd47ebb))
* Improves Bungee support ([#327](https://github.com/RoinujNosde/SimpleClans/issues/327)) ([2c9b0f9](https://github.com/RoinujNosde/SimpleClans/commit/2c9b0f98fe3942ea74190c1a81d61be2c8647db8))
* **lang:** new crowdin updates ([#319](https://github.com/RoinujNosde/SimpleClans/issues/319)) ([87ece22](https://github.com/RoinujNosde/SimpleClans/commit/87ece22036fb674c8c362b6a1b86fe884543e6ad))
### Bug Fixes
* changes size of some frames for better visualization on Bedrock ([1adec0b](https://github.com/RoinujNosde/SimpleClans/commit/1adec0b89d676767cdb94dcdf91ba37a231eb4a8))
* ConfigurationSerializableAdapter NPE ([30a501c](https://github.com/RoinujNosde/SimpleClans/commit/30a501c063aa9dbcf596df83adc2b15baf0e4bb9))
* getPastClans() preserves the insertion order ([af07988](https://github.com/RoinujNosde/SimpleClans/commit/af079881030bd299b9bae1ebf0cc62353af7e6fc))
* NoClassDefFoundError in WorldGuard6Provider ([a859928](https://github.com/RoinujNosde/SimpleClans/commit/a8599286225ba603ea124b8b52510245b94ffd24))
* NPE while collecting fees ([c47289c](https://github.com/RoinujNosde/SimpleClans/commit/c47289c5bf8113a9d6a8e1ee74a5afb0358647b6))
* NPE while purging data ([f14c425](https://github.com/RoinujNosde/SimpleClans/commit/f14c42548846feef01b484acbb5f02bcbcabd8db))
* NPE while sending a message to spies ([#322](https://github.com/RoinujNosde/SimpleClans/issues/322)) ([e7f756f](https://github.com/RoinujNosde/SimpleClans/commit/e7f756f3063c646e21415e08eea73f123d2818a0))
* removes duplicate /clan from help ([f7e7ec6](https://github.com/RoinujNosde/SimpleClans/commit/f7e7ec66243359e26d3c456a9740a53753951c48))
* removes rank and join date on disband ([2a1ad5b](https://github.com/RoinujNosde/SimpleClans/commit/2a1ad5b5c8d2937a8ee6dd6f7f43d85c86f08307))
* set useSSL to false ([f484bc1](https://github.com/RoinujNosde/SimpleClans/commit/f484bc16c6176ccd13e05aae2169400e7bcf5d62))
* supports '.' and '*' as username prefix by default ([37f0ecf](https://github.com/RoinujNosde/SimpleClans/commit/37f0ecff506d06f3047e3598848117a14c2b7ead))
* updates join date when joining a clan ([#326](https://github.com/RoinujNosde/SimpleClans/issues/326)) ([96a13d8](https://github.com/RoinujNosde/SimpleClans/commit/96a13d8d6cc18c91d4dee20dd632cd5d65db5213))
### Performance Improvements
* improved UUID lookup performance ([4ab53d1](https://github.com/RoinujNosde/SimpleClans/commit/4ab53d16135ecf5a4067b1a63d058da392dc5313))
+8 -7
View File
@@ -5,7 +5,7 @@ SimpleClans
Full featured clan system for PVP Minecraft Servers!
[![Build Status](https://travis-ci.com/RoinujNosde/SimpleClans.svg?branch=master)](https://travis-ci.com/RoinujNosde/SimpleClans)
[![Build Status](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.roinujnosde.me%2Fjob%2FSimpleClans%2F)](https://ci.roinujnosde.me/job/SimpleClans/)
[![Spiget Downloads](https://img.shields.io/spiget/downloads/71242)](https://www.spigotmc.org/resources/simpleclans.71242/)
[![Issues](https://img.shields.io/github/issues/RoinujNosde/SimpleClans.svg)](https://github.com/RoinujNosde/SimpleClans/issues)
[![Crowdin](https://badges.crowdin.net/simpleclans/localized.svg)](https://crowdin.com/project/simpleclans)
@@ -50,8 +50,8 @@ Including SimpleClans with Maven:
```xml
<repositories>
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public</url>
<id>roinujnosde-repo</id>
<url>https://repo.roinujnosde.me/releases/</url>
</repository>
</repositories>
```
@@ -60,7 +60,7 @@ Including SimpleClans with Maven:
<dependency>
<groupId>net.sacredlabyrinth.phaed.simpleclans</groupId>
<artifactId>SimpleClans</artifactId>
<version>2.15.0</version> <!-- You can find the latest version at the bottom -->
<version>2.17.0</version> <!-- You can find the latest version at the bottom -->
<scope>provided</scope>
</dependency>
</dependencies>
@@ -70,15 +70,16 @@ Using Gradle:
```groovy
repositories {
maven {
url "https://repo.codemc.org/repository/maven-public"
url "https://repo.roinujnosde.me/releases/"
}
}
dependencies {
compileOnly "net.sacredlabyrinth.phaed.simpleclans:SimpleClans:2.15.0"
compileOnly "net.sacredlabyrinth.phaed.simpleclans:SimpleClans:2.17.0"
}
```
Feel free to learn our [Javadoc](https://ci.roinujnosde.me/job/SimpleClans/Javadoc/).
##### Latest version:
[![](https://jitpack.io/v/roinujnosde/simpleclans.svg?label=Maven)]()
[![Maven metadata URL](https://img.shields.io/maven-metadata/v?metadataUrl=https%3A%2F%2Frepo.roinujnosde.me%2Freleases%2Fnet%2Fsacredlabyrinth%2Fphaed%2Fsimpleclans%2FSimpleClans%2Fmaven-metadata.xml)](https://repo.roinujnosde.me/#/releases/net/sacredlabyrinth/phaed/simpleclans/SimpleClans)
##### API Examples
* [Examples of how to use the API](https://simpleclans.gitbook.io/simpleclans/other/simpleclans-api)
+31 -31
View File
@@ -1,24 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="MavenCustomPomFilePath">
<option name="mavenPomFileUrl" value="file://$MODULE_DIR$/dependency-reduced-pom.xml" />
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$/src/main/java">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
</content>
<content url="file://$MODULE_DIR$/src/main/resources">
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
</content>
<content url="file://$MODULE_DIR$/src/test/java">
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.16-R0.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.26" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.MilkBowl:VaultAPI:1.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bukkit:bukkit:1.13.1-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
@@ -26,8 +25,8 @@
<orderEntry type="library" name="Maven: org.bstats:bstats-base:2.2.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: me.clip:placeholderapi:2.10.9" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:22.0.0" level="project" />
<orderEntry type="library" name="Maven: io.papermc:paperlib:1.0.5" level="project" />
<orderEntry type="library" name="Maven: co.aikar:acf-paper:0.5.0-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: io.papermc:paperlib:1.0.8-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: co.aikar:acf-paper:0.5.1-SNAPSHOT" level="project" />
<orderEntry type="library" name="Maven: com.github.cryptomorin:XSeries:8.3.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.7.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
@@ -53,7 +52,6 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.httpcomponents:httpclient:4.5.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.httpcomponents:httpcore:4.4.12" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.slf4j:jcl-over-slf4j:1.7.28" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.java.truevfs:truevfs-driver-odf:0.12.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.java.truevfs:truevfs-comp-zipdriver:0.12.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.java.truevfs:truevfs-comp-zip:0.12.1" level="project" />
@@ -87,13 +85,8 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: org.flywaydb:flyway-core:3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.sk89q:commandbook:2.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.TechFortress:GriefPrevention:16.17.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.plotsquared:PlotSquared-Core:5.13.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.plotsquared:PlotSquared-Bukkit:5.13.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.plotsquared:plotsquared-api:3.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.plotsquared:plotsquared-bukkitapi:3.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.milkbowl.vault:VaultAPI:1.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.discordsrv:discordsrv:1.23.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.dv8tion:JDA:4.2.1_262" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.discordsrv:discordsrv:1.24.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.dv8tion:JDA:4.3.0_349" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.squareup.okhttp3:okhttp:3.13.0" level="project" />
@@ -108,6 +101,7 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.alexheretic:dynamics:4.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.github.alexheretic:fluent:2.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.slf4j:slf4j-jdk14:1.7.25" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.slf4j:jcl-over-slf4j:1.7.25" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-io:commons-io:2.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.apache.commons:commons-lang3:3.5" level="project" />
@@ -123,23 +117,29 @@
<orderEntry type="library" scope="PROVIDED" name="Maven: org.minidns:minidns-iterative-resolver:1.0.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework:spring-expression:5.2.7.RELEASE" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework:spring-core:5.2.7.RELEASE" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.springframework:spring-jcl:5.2.7.RELEASE" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: dev.vankka:MCDiscordReserializer:4.2.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: dev.vankka:SimpleAST:2.2.7" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-api:4.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-key:4.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:examination-api:1.1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.checkerframework:checker-qual:3.10.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:examination-string:1.1.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-legacy:4.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-gson:4.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-bukkit:4.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-api:4.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-bungeecord:4.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-api:4.9.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-key:4.9.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:examination-api:1.3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:examination-string:1.3.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-legacy:4.9.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-gson:4.9.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-plain:4.9.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-bukkit:4.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-api:4.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-bungeecord:4.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-nbt:4.9.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-serializer-gson-legacy-impl:4.9.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-facet:4.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-viaversion:4.0.0-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-facet:4.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-platform-viaversion:4.0.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.kyori:adventure-text-minimessage:4.1.0-20210316.192746" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: biz.princeps:landlord-latest:4.351" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: biz.princeps:landlord-core:4.351" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: biz.princeps:landlord-api:4.351" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.zaxxer:HikariCP:4.0.3" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: io.github.bananapuncher714:nbteditor:7.16.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: de.eldoria:eldo-util:1.9.1" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.9.1" level="project" />
</component>
</module>
+4
View File
@@ -1,3 +1,7 @@
pull_request_title: "feat(lang): new crowdin updates"
pull_request_labels: ["l10n"]
commit_message: "feat(lang): new translations for %language%"
append_commit_message: false
files:
- source: src/main/resources/messages.properties
translation: /src/main/resources/%file_name%_%locale_with_underscore%.%file_extension%
+90 -97
View File
@@ -4,7 +4,7 @@
<groupId>net.sacredlabyrinth.phaed.simpleclans</groupId>
<artifactId>SimpleClans</artifactId>
<name>SimpleClans</name>
<version>2.16.0</version>
<version>2.18.1-SNAPSHOT</version>
<url>https://www.spigotmc.org/resources/simpleclans.71242/</url>
<build>
<resources>
@@ -29,7 +29,6 @@
<target>1.8</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<fork>true</fork>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
@@ -76,6 +75,10 @@
<pattern>com.cryptomorin.xseries</pattern>
<shadedPattern>net.sacredlabyrinth.phaed.simpleclans.xseries</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>net.sacredlabyrinth.phaed.simpleclans.gson</shadedPattern>
</relocation>
</relocations>
<artifactSet>
<excludes>
@@ -84,6 +87,62 @@
</artifactSet>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>copy-installed</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>${env.TEST_SERVER}\plugins</outputDirectory>
<silent>true</silent>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
</configuration>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
</executions>
<configuration>
<source>8</source>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
@@ -111,18 +170,14 @@
<id>sk89q-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
<repository>
<id>IntellectualSites</id>
<url>https://mvn.intellectualsites.com/content/groups/public/</url>
</repository>
<repository>
<id>plotsquared</id>
<url>https://plotsquared.com/mvn/</url>
</repository>
<repository>
<id>Scarsz-Nexus</id>
<url>https://nexus.scarsz.me/content/groups/public/</url>
</repository>
<repository>
<id>eldonexus</id>
<url>https://eldonexus.de/repository/maven-public</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
@@ -143,10 +198,6 @@
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
@@ -169,18 +220,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
@@ -243,76 +282,10 @@
<version>16.17.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>PlotSquared-Core</artifactId>
<version>5.13.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>PlotSquared-Bukkit</artifactId>
<version>5.13.3</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>PlotSquared-Core</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>plotsquared-api</artifactId>
<version>3.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>com.sk89q.worldedit</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>plotsquared-bukkitapi</artifactId>
<version>3.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>com.sk89q.worldedit</groupId>
</exclusion>
<exclusion>
<artifactId>Core</artifactId>
<groupId>PlotSquared</groupId>
</exclusion>
<exclusion>
<artifactId>VaultAPI</artifactId>
<groupId>net.milkbowl.vault</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.23.0</version>
<version>1.24.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
@@ -335,6 +308,10 @@
<artifactId>slf4j-jdk14</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
@@ -387,6 +364,10 @@
<artifactId>adventure-text-serializer-gson</artifactId>
<groupId>net.kyori</groupId>
</exclusion>
<exclusion>
<artifactId>adventure-text-serializer-plain</artifactId>
<groupId>net.kyori</groupId>
</exclusion>
<exclusion>
<artifactId>adventure-platform-bukkit</artifactId>
<groupId>net.kyori</groupId>
@@ -401,15 +382,27 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>biz.princeps</groupId>
<artifactId>landlord-latest</artifactId>
<version>4.351</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>landlord-core</artifactId>
<groupId>biz.princeps</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>codemc-releases</id>
<url>https://repo.codemc.io/repository/maven-releases/</url>
<id>reposilite</id>
<url>https://repo.roinujnosde.me/releases/</url>
</repository>
<snapshotRepository>
<id>codemc-snapshots</id>
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
<id>reposilite</id>
<url>https://repo.roinujnosde.me/snapshots/</url>
</snapshotRepository>
</distributionManagement>
<properties>
+91 -72
View File
@@ -1,9 +1,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">
<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>
<groupId>net.sacredlabyrinth.phaed.simpleclans</groupId>
<artifactId>SimpleClans</artifactId>
<version>2.16.0</version>
<version>2.18.2-SNAPSHOT</version>
<name>SimpleClans</name>
<url>https://www.spigotmc.org/resources/simpleclans.71242/</url>
@@ -36,7 +35,6 @@
<target>1.8</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<fork>true</fork>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
@@ -84,6 +82,10 @@
<pattern>com.cryptomorin.xseries</pattern>
<shadedPattern>net.sacredlabyrinth.phaed.simpleclans.xseries</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>net.sacredlabyrinth.phaed.simpleclans.gson</shadedPattern>
</relocation>
</relocations>
<artifactSet>
<excludes>
@@ -100,6 +102,68 @@
</execution>
</executions>
</plugin>
<!-- Dependency plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>copy-installed</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>${env.TEST_SERVER}\plugins</outputDirectory>
<silent>true</silent>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>revision</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.2</version>
<executions>
<execution>
<goals>
<goal>javadoc</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<source>8</source>
</configuration>
</plugin>
</plugins>
</build>
<!-- Dependencies -->
@@ -116,12 +180,6 @@
<version>1.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
@@ -142,13 +200,13 @@
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.5</version>
<version>1.0.8-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-paper</artifactId>
<version>0.5.0-SNAPSHOT</version>
<version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.cryptomorin</groupId>
@@ -173,58 +231,23 @@
<version>16.17.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>PlotSquared-Core</artifactId>
<version>5.13.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>PlotSquared-Bukkit</artifactId>
<version>5.13.3</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>PlotSquared-Core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>plotsquared-api</artifactId>
<version>3.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.plotsquared</groupId>
<artifactId>plotsquared-bukkitapi</artifactId>
<version>3.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>PlotSquared</groupId>
<artifactId>Core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.discordsrv</groupId>
<artifactId>discordsrv</artifactId>
<version>1.23.0</version>
<version>1.24.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>biz.princeps</groupId>
<artifactId>landlord-latest</artifactId>
<version>4.351</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.1</version>
</dependency>
</dependencies>
<!-- Repositories -->
@@ -253,18 +276,14 @@
<id>sk89q-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
<repository>
<id>IntellectualSites</id>
<url>https://mvn.intellectualsites.com/content/groups/public/</url>
</repository>
<repository>
<id>plotsquared</id>
<url>https://plotsquared.com/mvn/</url>
</repository>
<repository>
<id>Scarsz-Nexus</id>
<url>https://nexus.scarsz.me/content/groups/public/</url>
</repository>
<repository>
<id>eldonexus</id>
<url>https://eldonexus.de/repository/maven-public</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
@@ -279,12 +298,12 @@
<distributionManagement>
<repository>
<id>codemc-releases</id>
<url>https://repo.codemc.io/repository/maven-releases/</url>
<id>reposilite</id>
<url>https://repo.roinujnosde.me/releases/</url>
</repository>
<snapshotRepository>
<id>codemc-snapshots</id>
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
<id>reposilite</id>
<url>https://repo.roinujnosde.me/snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
</project>
@@ -3,7 +3,6 @@ package net.sacredlabyrinth.phaed.simpleclans;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -523,6 +522,9 @@ public class ChatBlock {
/**
* Outputs a single line out, crops overflow
*
* @param receiver the receiver
* @param msg the message
*/
public static void saySingle(CommandSender receiver, String msg) {
if (receiver == null) {
@@ -534,6 +536,9 @@ public class ChatBlock {
/**
* Outputs a message to a user
*
* @param receiver the receiver
* @param msg the message
*/
public static void sendMessage(@Nullable CommandSender receiver, @NotNull String msg) {
if (receiver == null) {
@@ -541,11 +546,6 @@ public class ChatBlock {
}
receiver.sendMessage(ChatUtils.parseColors(msg));
// String[] message = colorize(wordWrap(msg));
//
// for (String out : message) {
// receiver.sendMessage(out);
// }
}
public static void sendMessage(@Nullable ClanPlayer receiver, @NotNull String msg) {
@@ -553,12 +553,7 @@ public class ChatBlock {
return;
}
Player player = receiver.toPlayer();
if (player == null) {
return;
}
player.sendMessage(ChatUtils.parseColors(msg));
SimpleClans.getInstance().getProxyManager().sendMessage(receiver.getName(), ChatUtils.parseColors(msg));
}
// ClanCommands#setbanner, LandCommands#Allow/BlockCommand/verify, StaffCommands#kick, etc
@@ -572,7 +567,9 @@ public class ChatBlock {
}
/**
* Send blank line
* Sends a blank line
*
* @param receiver the receiver
*/
public static void sendBlank(CommandSender receiver) {
if (receiver == null) {
@@ -6,7 +6,7 @@ import net.sacredlabyrinth.phaed.simpleclans.events.*;
import net.sacredlabyrinth.phaed.simpleclans.hooks.papi.Placeholder;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLog;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLogger;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankOperator;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import org.bukkit.Bukkit;
@@ -53,7 +53,7 @@ public class Clan implements Serializable, Comparable<Clan> {
private List<String> allies = new ArrayList<>();
private List<String> rivals = new ArrayList<>();
private List<String> bb = new ArrayList<>();
private final List<String> members = new ArrayList<>();
private final List<ClanPlayer> members = new ArrayList<>();
private Flags flags = new Flags(null);
private boolean feeEnabled;
private List<Rank> ranks = new ArrayList<>();
@@ -118,17 +118,17 @@ public class Clan implements Serializable, Comparable<Clan> {
setBalance(getBalance() + amount);
SimpleClans.getInstance().getStorageManager().updateClan(this);
} else {
player.sendMessage(AQUA + lang("not.sufficient.money", player));
player.sendMessage(AQUA + lang("not.sufficient.money", player, amount));
}
} else {
player.sendMessage(AQUA + lang("not.sufficient.money", player));
player.sendMessage(AQUA + lang("not.sufficient.money", player, amount));
}
}
/**
* Deposits money to the clan
*/
public EconomyResponse deposit(@Nullable CommandSender sender, @NotNull Cause cause, double amount) {
public EconomyResponse deposit(@NotNull BankOperator sender, @NotNull Cause cause, double amount) {
EconomyResponse response = null;
if (amount < 0) {
@@ -162,7 +162,7 @@ public class Clan implements Serializable, Comparable<Clan> {
/**
* Withdraws money from the clan
*/
public EconomyResponse withdraw(@Nullable CommandSender sender, @NotNull Cause cause, double amount) {
public EconomyResponse withdraw(@NotNull BankOperator sender, @NotNull Cause cause, double amount) {
EconomyResponse response = null;
if (amount < 0) {
@@ -250,14 +250,15 @@ public class Clan implements Serializable, Comparable<Clan> {
*
* @param balance the balance to set
*/
public void setBalance(double balance) {
setBalance(null, Cause.API, SET, balance);
private void setBalance(double balance) {
setBalance(BankOperator.INTERNAL, Cause.INTERNAL, SET, balance);
}
public EconomyResponse setBalance(@Nullable CommandSender updater, @NotNull Cause cause, @NotNull BankLogger.Operation operation, double balance) {
public EconomyResponse setBalance(@NotNull BankOperator operator, @NotNull Cause cause,
@NotNull BankLogger.Operation operation, double balance) {
EconomyResponse response = SUCCESS;
ClanBalanceUpdateEvent event = new ClanBalanceUpdateEvent(updater, this, getBalance(), balance, cause);
ClanBalanceUpdateEvent event = new ClanBalanceUpdateEvent(operator, this, getBalance(), balance, cause);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
response = CANCELLED;
@@ -266,7 +267,7 @@ public class Clan implements Serializable, Comparable<Clan> {
this.balance = event.getNewBalance();
if (cause != Cause.LOADING) {
if (operation == SET) {
SimpleClans.getInstance().getBankLogger().log(new BankLog(updater, this, response, SET, cause, balance));
SimpleClans.getInstance().getBankLogger().log(new BankLog(operator, this, response, SET, cause, balance));
}
SimpleClans.getInstance().getStorageManager().updateClan(this);
}
@@ -335,17 +336,17 @@ public class Clan implements Serializable, Comparable<Clan> {
/**
* Returns the max number of days the clan can be inactive
* A number <= 0 means it won't be purged
* A {@literal <=} 0 means it won't be purged
*/
public int getMaxInactiveDays() {
if (this.isPermanent()) {
if (isPermanent()) {
return -1;
}
int verifiedClanInactiveDays = SimpleClans.getInstance().getSettingsManager().getInt(PURGE_INACTIVE_CLAN_DAYS);
int unverifiedClanInactiveDays = SimpleClans.getInstance().getSettingsManager().getInt(PURGE_UNVERIFIED_CLAN_DAYS);
return this.isVerified() ? verifiedClanInactiveDays : unverifiedClanInactiveDays;
return isVerified() ? verifiedClanInactiveDays : unverifiedClanInactiveDays;
}
/**
@@ -383,17 +384,22 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return confirmation
*/
public boolean isMember(Player player) {
return this.members.contains(player.getUniqueId().toString());
return isMember(player.getUniqueId());
}
/**
* Check if the player is a member of this clan
*
* @param playerUniqueId the Player's UUID
* @param uuid the Player's UUID
* @return confirmation
*/
public boolean isMember(UUID playerUniqueId) {
return this.members.contains(playerUniqueId.toString());
public boolean isMember(UUID uuid) {
for (ClanPlayer cp : members) {
if (cp.getUniqueId().equals(uuid)) {
return true;
}
}
return false;
}
@SuppressWarnings("deprecation")
@@ -520,23 +526,16 @@ public class Clan implements Serializable, Comparable<Clan> {
* (used internally)
*/
public void importMember(ClanPlayer cp) {
String uuid;
if (cp.getUniqueId() != null) {
uuid = cp.getUniqueId().toString();
} else {
return;
}
if (!this.members.contains(uuid)) {
this.members.add(uuid);
if (!members.contains(cp)) {
members.add(cp);
}
}
/**
* (used internally)
*/
public void removeMember(UUID playerUniqueId) {
this.members.remove(playerUniqueId.toString());
public void removeMember(UUID uuid) {
members.removeIf(cp -> cp.getUniqueId().equals(uuid));
}
/**
@@ -544,7 +543,7 @@ public class Clan implements Serializable, Comparable<Clan> {
*/
@Placeholder("size")
public int getSize() {
return this.members.size();
return members.size();
}
/**
@@ -562,12 +561,7 @@ public class Clan implements Serializable, Comparable<Clan> {
}
private boolean removeRival(String rival) {
if (!rivals.contains(rival)) {
return false;
}
rivals.remove(rival);
return true;
return rivals.remove(rival);
}
/**
@@ -638,7 +632,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return the packedBb
*/
public String getPackedBb() {
return Helper.toMessage(bb, "|");
return String.join("|", bb);
}
/**
@@ -647,7 +641,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @param packedBb the packedBb to set
*/
public void setPackedBb(String packedBb) {
this.bb = Helper.fromArrayToList(packedBb.split("[|]"));
bb = Helper.fromArrayToList(packedBb.split("[|]"));
}
/**
@@ -656,7 +650,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return the packedAllies
*/
public String getPackedAllies() {
return Helper.toMessage(allies, "|");
return String.join("|", allies);
}
/**
@@ -665,7 +659,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @param packedAllies the packedAllies to set
*/
public void setPackedAllies(String packedAllies) {
this.allies = Helper.fromArrayToList(packedAllies.split("[|]"));
allies = Helper.fromArrayToList(packedAllies.split("[|]"));
}
/**
@@ -674,7 +668,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return the packedRivals
*/
public String getPackedRivals() {
return Helper.toMessage(rivals, "|");
return String.join("|", rivals);
}
/**
@@ -683,7 +677,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @param packedRivals the packedRivals to set
*/
public void setPackedRivals(String packedRivals) {
this.rivals = Helper.fromArrayToList(packedRivals.split("[|]"));
rivals = Helper.fromArrayToList(packedRivals.split("[|]"));
}
/**
@@ -691,23 +685,13 @@ public class Clan implements Serializable, Comparable<Clan> {
* tags
*/
public String getAllyString(String sep, @Nullable CommandSender viewer) {
StringBuilder out = new StringBuilder();
String coloredAllies = getAllies().stream().
map(allyTag -> SimpleClans.getInstance().getClanManager().getClan(allyTag)).
filter(Objects::nonNull).
map(Clan::getColorTag).
collect(Collectors.joining(sep));
for (String allyTag : getAllies()) {
Clan ally = SimpleClans.getInstance().getClanManager().getClan(allyTag);
if (ally != null) {
out.append(ally.getColorTag()).append(sep);
}
}
out = new StringBuilder(Helper.stripTrailing(out.toString(), sep));
if (out.toString().trim().isEmpty()) {
return lang("none", viewer);
}
return ChatUtils.parseColors(out.toString());
return coloredAllies.isEmpty() ? lang("none", viewer) : coloredAllies;
}
/**
@@ -723,29 +707,14 @@ public class Clan implements Serializable, Comparable<Clan> {
* tags
*/
public String getRivalString(String sep, @Nullable CommandSender viewer) {
StringBuilder out = new StringBuilder();
String coloredRivals = getRivals().stream().
map(rivalTag -> SimpleClans.getInstance().getClanManager().getClan(rivalTag)).
filter(Objects::nonNull).
map(rival -> isWarring(rival) ? DARK_RED + "[" + rival.getTag() + "]" : rival.getColorTag()).
map(ChatUtils::parseColors).
collect(Collectors.joining(sep));
for (String rivalTag : getRivals()) {
Clan rival = SimpleClans.getInstance().getClanManager().getClan(rivalTag);
if (rival != null) {
if (isWarring(rivalTag)) {
out.append(DARK_RED).append("[").append(ChatUtils.stripColors(rival.getColorTag()))
.append("]").append(sep);
} else {
out.append(rival.getColorTag()).append(sep);
}
}
}
out = new StringBuilder(Helper.stripTrailing(out.toString(), sep));
if (out.toString().trim().isEmpty()) {
return lang("none", viewer);
}
return ChatUtils.parseColors(out.toString());
return coloredRivals.isEmpty() ? lang("none", viewer) : coloredRivals;
}
/**
@@ -762,20 +731,8 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return the formatted leaders string
*/
public String getLeadersString(String prefix, String sep) {
StringBuilder out = new StringBuilder();
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
if (cp.isLeader()) {
out.append(prefix).append(cp.getName()).append(sep);
}
}
return Helper.stripTrailing(out.toString(), sep);
return members.stream().filter(ClanPlayer::isLeader).map(ClanPlayer::getName).
collect(Collectors.joining(sep, prefix, ""));
}
/**
@@ -814,8 +771,10 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return the fee payers
*/
public Set<ClanPlayer> getFeePayers() {
PermissionsManager permissions = SimpleClans.getInstance().getPermissionsManager();
return getNonLeaders().stream().filter(cp -> !permissions.has(cp.toPlayer(), "simpleclans.member.bypass-fee")).collect(Collectors.toSet());
return getMembers().stream().filter(cp -> !cp.isLeader()).filter(cp -> {
Rank rank = getRank(cp.getRankId());
return rank == null || !rank.getPermissions().contains(RankPermission.FEE_BYPASS.toString());
}).collect(Collectors.toSet());
}
/**
@@ -824,19 +783,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return the members
*/
public List<ClanPlayer> getMembers() {
List<ClanPlayer> out = new ArrayList<>();
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
out.add(cp);
}
Collections.sort(out);
return out;
return new ArrayList<>(members);
}
/**
@@ -846,22 +793,9 @@ public class Clan implements Serializable, Comparable<Clan> {
*/
@Placeholder(value = "onlinemembers_count", resolver = "list_size", config = "filter_vanished")
public List<ClanPlayer> getOnlineMembers() {
List<ClanPlayer> out = new ArrayList<>();
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
if (cp.toPlayer() != null) {
out.add(cp);
}
}
return out;
return members.stream().filter(cp -> cp.toPlayer() != null).collect(Collectors.toList());
}
/**
* Get all leaders in the clan
*
@@ -869,20 +803,7 @@ public class Clan implements Serializable, Comparable<Clan> {
*/
@Placeholder(value = "leader_size", resolver = "list_size")
public List<ClanPlayer> getLeaders() {
List<ClanPlayer> out = new ArrayList<>();
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
if (cp.isLeader()) {
out.add(cp);
}
}
return out;
return members.stream().filter(ClanPlayer::isLeader).collect(Collectors.toList());
}
/**
@@ -891,22 +812,7 @@ public class Clan implements Serializable, Comparable<Clan> {
* @return non leaders
*/
public List<ClanPlayer> getNonLeaders() {
List<ClanPlayer> out = new ArrayList<>();
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
if (!cp.isLeader()) {
out.add(cp);
}
}
Collections.sort(out);
return out;
return members.stream().filter(cp -> !cp.isLeader()).collect(Collectors.toList());
}
/**
@@ -945,16 +851,10 @@ public class Clan implements Serializable, Comparable<Clan> {
if (members.isEmpty()) {
return 0;
}
double totalWeightedKills = 0;
int totalDeaths = 0;
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
for (ClanPlayer cp : members) {
totalWeightedKills += cp.getWeightedKills();
totalDeaths += cp.getDeaths();
}
@@ -977,12 +877,7 @@ public class Clan implements Serializable, Comparable<Clan> {
return totalDeaths;
}
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
for (ClanPlayer cp : members) {
totalDeaths += cp.getDeaths();
}
@@ -1000,12 +895,7 @@ public class Clan implements Serializable, Comparable<Clan> {
return total;
}
for (String member : members) {
ClanPlayer cp = SimpleClans.getInstance().getClanManager().getClanPlayer(UUID.fromString(member));
if (cp == null) {
continue;
}
for (ClanPlayer cp : members) {
total += cp.getWeightedKills();
}
@@ -1090,6 +980,7 @@ public class Clan implements Serializable, Comparable<Clan> {
cp.removePastClan(getColorTag());
cp.setClan(this);
cp.setLeader(false);
cp.setJoinDate(new Date().getTime());
cp.setTrusted(SimpleClans.getInstance().getSettingsManager().is(CLAN_TRUST_MEMBERS_BY_DEFAULT));
if (defaultRank != null) {
cp.setRank(defaultRank);
@@ -1210,7 +1101,7 @@ public class Clan implements Serializable, Comparable<Clan> {
}
/**
* Remove an ally form the clan, and the clan from the ally
* Remove an ally from the clan, and the clan from the ally
*/
public void removeAlly(Clan ally) {
removeAlly(ally.getTag());
@@ -1261,7 +1152,7 @@ public class Clan implements Serializable, Comparable<Clan> {
*/
@Placeholder("is_anyonline")
public boolean isAnyOnline() {
return members.stream().map(UUID::fromString).map(Bukkit::getPlayer).anyMatch(Objects::nonNull);
return members.stream().anyMatch(cp -> cp.toPlayer() != null);
}
/**
@@ -1361,18 +1252,14 @@ public class Clan implements Serializable, Comparable<Clan> {
String message = SimpleClans.getInstance().getSettingsManager().getColored(CLANCHAT_ANNOUNCEMENT_COLOR) + msg;
for (ClanPlayer cp : getMembers()) {
Player pl = cp.toPlayer();
if (pl != null) {
ChatBlock.sendMessage(pl, message);
}
ChatBlock.sendMessage(cp, message);
}
SimpleClans.getInstance().getServer().getConsoleSender().sendMessage(AQUA + "[" + lang("clan.announce") + AQUA + "] " + AQUA + "[" + Helper.getColorName(playerName) + WHITE + "] " + message);
Bukkit.getConsoleSender().sendMessage(AQUA + "[" + lang("clan.announce") + AQUA + "] " + AQUA + "[" + Helper.getColorName(playerName) + WHITE + "] " + message);
}
/**
* Announce message to a all the leaders of a clan
* Announce message to all the leaders of a clan
*/
public void leaderAnnounce(String msg) {
String message = SimpleClans.getInstance().getSettingsManager().getColored(CLANCHAT_ANNOUNCEMENT_COLOR) + msg;
@@ -1380,13 +1267,9 @@ public class Clan implements Serializable, Comparable<Clan> {
List<ClanPlayer> leaders = getLeaders();
for (ClanPlayer cp : leaders) {
Player pl = cp.toPlayer();
if (pl != null) {
ChatBlock.sendMessage(pl, message);
}
ChatBlock.sendMessage(cp, message);
}
SimpleClans.getInstance().getServer().getConsoleSender().sendMessage(AQUA + "[" + lang("leader.announce") + AQUA + "] " + WHITE + message);
Bukkit.getConsoleSender().sendMessage(AQUA + "[" + lang("leader.announce") + AQUA + "] " + WHITE + message);
}
/**
@@ -1487,24 +1370,25 @@ public class Clan implements Serializable, Comparable<Clan> {
Collection<ClanPlayer> clanPlayers = SimpleClans.getInstance().getClanManager().getAllClanPlayers();
List<Clan> clans = SimpleClans.getInstance().getClanManager().getClans();
if (this.isPermanent() && !force) {
if (isPermanent() && !force) {
ChatBlock.sendMessage(sender, RED + lang("cannot.disband.permanent"));
return;
}
if (announce) {
if (SimpleClans.getInstance().getSettingsManager().is(DISABLE_MESSAGES) && sender != null) {
this.clanAnnounce(sender.getName(), AQUA + lang("clan.has.been.disbanded", this.getName()));
clanAnnounce(sender.getName(), AQUA + lang("clan.has.been.disbanded", getName()));
} else {
SimpleClans.getInstance().getClanManager().serverAnnounce(AQUA + lang("clan.has.been.disbanded", this.getName()));
SimpleClans.getInstance().getClanManager().serverAnnounce(AQUA + lang("clan.has.been.disbanded", getName()));
}
}
SimpleClans.getInstance().getPermissionsManager().removeClanPermissions(this);
for (ClanPlayer cp : clanPlayers) {
if (cp.getTag().equals(getTag())) {
SimpleClans.getInstance().getPermissionsManager().removeClanPermissions(this);
cp.setClan(null);
cp.setJoinDate(0);
cp.setRank(null);
if (isVerified()) {
cp.addPastClan(getColorTag() + (cp.isLeader() ? DARK_RED + "*" : ""));
}
@@ -1513,7 +1397,7 @@ public class Clan implements Serializable, Comparable<Clan> {
}
}
Bukkit.getPluginManager().callEvent(new DisbandClanEvent(this));
Bukkit.getPluginManager().callEvent(new DisbandClanEvent(sender, this));
clans.remove(this);
for (Clan c : clans) {
@@ -1534,7 +1418,7 @@ public class Clan implements Serializable, Comparable<Clan> {
SimpleClans.getInstance().getRequestManager().removeRequest(getTag());
SimpleClans.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(SimpleClans.getInstance(), () -> {
SimpleClans.getInstance().getClanManager().removeClan(this.getTag());
SimpleClans.getInstance().getClanManager().removeClan(getTag());
SimpleClans.getInstance().getStorageManager().deleteClan(this);
}, 1);
}
@@ -1578,8 +1462,8 @@ public class Clan implements Serializable, Comparable<Clan> {
warring.add(targetClan.getTag());
flags.put(WARRING_KEY, warring);
if (requestPlayer != null) {
this.addBb(requestPlayer.getName(), AQUA + lang("you.are.at.war",
this.getName(), targetClan.getColorTag()));
addBb(requestPlayer.getName(), AQUA + lang("you.are.at.war",
getName(), targetClan.getColorTag()));
}
SimpleClans.getInstance().getStorageManager().updateClan(this);
}
@@ -1652,6 +1536,8 @@ public class Clan implements Serializable, Comparable<Clan> {
flags.put("homeYaw", home != null ? home.getYaw() : 0);
String world = home != null && home.getWorld() != null ? home.getWorld().getName() : "";
flags.put("homeWorld", world);
String name = SimpleClans.getInstance().getProxyManager().getServerName();
flags.put("homeServer", name);
SimpleClans.getInstance().getStorageManager().updateClan(this);
}
@@ -1670,11 +1556,8 @@ public class Clan implements Serializable, Comparable<Clan> {
double z = flags.getNumber("homeZ").doubleValue();
float yaw = flags.getNumber("homeYaw").floatValue();
float pitch = flags.getNumber("homePitch").floatValue();
Location location = new Location(world, x, y, z, yaw, pitch);
if (!Helper.isAir(location.getBlock().getType(), location.clone().add(0, 1, 0).getBlock().getType())) {
location.setY(world.getHighestBlockYAt(location) + 1);
}
return location;
return new Location(world, x, y, z, yaw, pitch);
}
public String getTagLabel(boolean isLeader) {
@@ -1684,7 +1567,7 @@ public class Clan implements Serializable, Comparable<Clan> {
String bracketLeft = sm.getColored(TAG_BRACKET_LEFT);
String bracketRight = sm.getColored(TAG_BRACKET_RIGHT);
String tagSeparatorColor = isLeader ? sm.getColored(TAG_SEPARATOR_LEADER_COLOR) : sm.getColored(TAG_SEPARATOR_COLOR);
String tagSeparator = sm.getString(TAG_SEPARATOR_char);
String tagSeparator = sm.getString(TAG_SEPARATOR_CHAR);
return bracketColor + bracketLeft + bracketDefaultColor + getColorTag() + bracketColor + bracketRight + tagSeparatorColor + tagSeparator;
}
@@ -17,6 +17,7 @@ import java.sql.Timestamp;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*;
@@ -37,7 +38,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
private int deaths;
private long lastSeen;
private long joinDate;
private Set<String> pastClans = new HashSet<>();
private final Set<String> pastClans = new LinkedHashSet<>();
private final Map<String, Long> resignTimes = new HashMap<>();
private @Nullable VoteResult vote;
private Flags flags = new Flags(null);
@@ -47,6 +48,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
private @Nullable Locale locale;
/**
*
*/
@@ -66,17 +68,17 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
* @param uuid the Player's UUID
*/
public ClanPlayer(UUID uuid) {
this.uniqueId = uuid;
uniqueId = uuid;
Player onlinePlayer = SimpleClans.getInstance().getServer().getPlayer(uuid);
if (onlinePlayer != null) {
this.displayName = onlinePlayer.getName();
displayName = onlinePlayer.getName();
} else {
OfflinePlayer offlinePlayer = SimpleClans.getInstance().getServer().getOfflinePlayer(uuid);
this.displayName = offlinePlayer.getName() != null ? offlinePlayer.getName() : "null";
displayName = offlinePlayer.getName() != null ? offlinePlayer.getName() : "null";
}
this.lastSeen = (new Date()).getTime();
this.joinDate = (new Date()).getTime();
this.tag = "";
lastSeen = (new Date()).getTime();
joinDate = (new Date()).getTime();
tag = "";
}
@Override
@@ -91,12 +93,12 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
}
ClanPlayer other = (ClanPlayer) obj;
return other.getName().equals(this.getName());
return other.getName().equals(getName());
}
@Override
public int compareTo(ClanPlayer other) {
return this.getUniqueId().compareTo(other.getUniqueId());
return getUniqueId().compareTo(other.getUniqueId());
}
@Override
@@ -139,7 +141,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
* @param name the name to set
*/
public void setName(String name) {
this.displayName = name;
displayName = name;
}
/**
@@ -225,7 +227,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
* Updates last seen date to today
*/
public void updateLastSeen() {
this.lastSeen = (new Date()).getTime();
lastSeen = (new Date()).getTime();
}
/**
@@ -486,7 +488,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
return "";
}
return new java.text.SimpleDateFormat("MMM dd, ''yy h:mm a").format(new Date(this.joinDate));
return new java.text.SimpleDateFormat("MMM dd, ''yy h:mm a").format(new Date(joinDate));
}
/**
@@ -507,11 +509,10 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
}
public String getLastSeenString(@Nullable CommandSender sender) {
Player player = toPlayer();
if (player != null && player.isOnline() && !VanishUtils.isVanished(sender, player)) {
if (!VanishUtils.isVanished(sender, this)) {
return lang("online", sender);
}
return new java.text.SimpleDateFormat("MMM dd, ''yy h:mm a").format(new Date(this.lastSeen));
return new java.text.SimpleDateFormat("MMM dd, ''yy h:mm a").format(new Date(lastSeen));
}
/**
@@ -529,31 +530,24 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
* @return the PackedPastClans
*/
public String getPackedPastClans() {
StringBuilder packedPastClans = new StringBuilder();
Set<String> pt = getPastClans();
for (String pastClan : pt) {
packedPastClans.append(pastClan).append("|");
}
return Helper.stripTrailing(packedPastClans.toString(), "|");
return String.join("|", getPastClans());
}
/**
* (used internally)
*
* @param PackedPastClans the PackedPastClans to set
* @param packedPastClans the packedPastClans to set
*/
public void setPackedPastClans(String PackedPastClans) {
this.pastClans = Helper.fromArrayToSet(PackedPastClans.split("[|]"));
public void setPackedPastClans(String packedPastClans) {
String[] clans = packedPastClans.split("\\|");
Collections.addAll(pastClans, clans);
}
/**
* Adds a past clan to the player (does not update the clanplayer to db)
*/
public void addPastClan(String tag) {
this.getPastClans().add(tag);
getPastClans().add(tag);
}
/**
@@ -562,7 +556,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
* @param tag is the clan's colored tag
*/
public void removePastClan(String tag) {
this.getPastClans().remove(tag);
getPastClans().remove(tag);
}
/**
@@ -581,19 +575,15 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
*/
@NotNull
public String getPastClansString(String sep, @Nullable Player viewer) {
StringBuilder out = new StringBuilder();
for (String pastClan : getPastClans()) {
out.append(pastClan).append(sep);
}
out = new StringBuilder(Helper.stripTrailing(out.toString(), sep));
if (out.toString().trim().isEmpty()) {
if (getPastClans().isEmpty()) {
return lang("none", viewer);
}
return out.toString();
SettingsManager settings = SimpleClans.getInstance().getSettingsManager();
return getPastClans().stream().
sorted(Collections.reverseOrder()).
limit(settings.getInt(PAST_CLANS_LIMIT)).
collect(Collectors.joining(sep));
}
/**
@@ -626,7 +616,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
/**
* Sets the resign times (does not update to db)
*/
public void setResignTimes(Map<String, Long> resignTimes) {
public void setResignTimes(@Nullable Map<String, Long> resignTimes) {
if (resignTimes != null) {
final int cooldown = SimpleClans.getInstance().getSettingsManager().getInt(REJOIN_COOLDOWN);
resignTimes.forEach((k, v) -> {
@@ -663,9 +653,9 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
*/
public void setClan(@Nullable Clan clan) {
if (clan == null) {
this.tag = "";
tag = "";
} else {
this.tag = clan.getTag();
tag = clan.getTag();
}
this.clan = clan;
@@ -814,7 +804,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
flags.put("hide-tag", tagEnabled);
SimpleClans.getInstance().getStorageManager().updateClanPlayer(this);
SimpleClans.getInstance().getClanManager().updateDisplayName(this.toPlayer());
SimpleClans.getInstance().getClanManager().updateDisplayName(toPlayer());
}
@Deprecated
@@ -855,10 +845,7 @@ public class ClanPlayer implements Serializable, Comparable<ClanPlayer> {
flags.put("rank", rank == null ? "" : rank);
}
public @NotNull Locale getLocale() {
if (locale == null) {
return SimpleClans.getInstance().getSettingsManager().getLanguage();
}
public @Nullable Locale getLocale() {
return locale;
}
@@ -77,7 +77,7 @@ public class Dates {
/**
* @author RoboMWM, LaxWasHere
* @param seconds the time in seconds
* @param depth Max amount of detail (e.g. only display days and hours if set to 1 and seconds > 1 day)
* @param depth Max amount of detail (e.g. only display days and hours if set to 1 and seconds {@literal >} 1 day)
* @return the string representation of the amount of time labeled as days, hours, minutes, seconds
*/
public static String formatTime(Long seconds, int depth) {
@@ -1,36 +1,34 @@
package net.sacredlabyrinth.phaed.simpleclans;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import java.util.ArrayList;
import java.util.List;
public class Flags {
private final JSONObject flags;
private static final Gson gson = new Gson();
private final JsonObject flags;
public Flags(@Nullable String json) {
JSONObject flags = null;
if (json != null && !json.isEmpty()) {
flags = (JSONObject) JSONValue.parse(json);
flags = gson.fromJson(json, JsonObject.class);
} else {
flags = new JsonObject();
}
if (flags == null) {
flags = new JSONObject();
}
this.flags = flags;
}
@NotNull
public List<String> getStringList(@NotNull String key) {
Object object = flags.get(key);
JsonElement object = flags.get(key);
ArrayList<String> list = new ArrayList<>();
if (object instanceof JSONArray) {
for (Object o : ((JSONArray) object)) {
list.add(String.valueOf(o));
if (object != null && object.isJsonArray()) {
for (JsonElement element : object.getAsJsonArray()) {
list.add(element.getAsString());
}
}
return list;
@@ -38,11 +36,11 @@ public class Flags {
@Nullable
public String getString(@NotNull String key) {
Object object = flags.get(key);
if (object == null) {
JsonElement element = flags.get(key);
if (element == null || element.isJsonNull()) {
return null;
}
return String.valueOf(object);
return element.getAsString();
}
@NotNull
@@ -56,11 +54,11 @@ public class Flags {
@NotNull
public Number getNumber(@NotNull String key) {
Object object = flags.get(key);
if (object instanceof Number) {
return (Number) object;
JsonElement element = flags.get(key);
if (element == null || element.isJsonNull()) {
return 0;
}
return 0;
return element.getAsNumber();
}
public boolean getBoolean(@NotNull String key) {
@@ -68,26 +66,22 @@ public class Flags {
}
public boolean getBoolean(@NotNull String key, boolean def) {
Object object = flags.get(key);
if (object instanceof Boolean) {
return (Boolean) object;
JsonElement element = flags.get(key);
if (element == null || element.isJsonNull()) {
return def;
}
return def;
return element.getAsBoolean();
}
@SuppressWarnings("unchecked")
public void put(@NotNull String key, @NotNull List<?> value) {
JSONArray array = new JSONArray();
array.addAll(value);
flags.put(key, array);
flags.add(key, gson.toJsonTree(value));
}
@SuppressWarnings("unchecked")
public void put(@NotNull String key, @NotNull Object object) {
flags.put(key, object);
flags.add(key, gson.toJsonTree(object));
}
public String toJSONString() {
return flags.toJSONString();
return flags.toString();
}
}
@@ -1,18 +1,19 @@
package net.sacredlabyrinth.phaed.simpleclans;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.FileSystem;
@@ -35,8 +36,11 @@ import static net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils.stripColors;
* @author phaed
*/
public class Helper {
public final class Helper {
private static final Gson GSON = new Gson();
private static final Type RANKS_TYPE = TypeToken.getParameterized(List.class, Rank.class).getType();
private static final Type RESIGN_TYPE = TypeToken.getParameterized(Map.class, String.class, Long.class).getType();
private Helper() {
}
@@ -49,15 +53,10 @@ public class Helper {
return Locale.forLanguageTag(languageTag);
}
public static @Nullable JSONObject parseJson(String json) {
if (json != null && !json.isEmpty()) {
try {
return (JSONObject) new JSONParser().parse(json);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
@Contract("null -> null")
@Nullable
public static String toLanguageTag(@Nullable Locale locale) {
return locale != null ? locale.toLanguageTag() : null;
}
public static Set<Path> getPathsIn(String path, Predicate<? super Path> filter) {
@@ -117,47 +116,32 @@ public class Helper {
}
/**
* Parses a list of ranks from the specified JSONObject
* Parses a list of ranks from the specified Json String
*
* @param jo the JSON Object
* @param json the Json String
* @return a list of ranks or null if the JSON String is null/empty
*/
public static @Nullable List<Rank> ranksFromJson(@Nullable JSONObject jo) {
if (jo != null && !jo.isEmpty()) {
Object ranks = jo.get("ranks");
if (ranks != null) {
JSONArray array = (JSONArray) ranks;
List<Rank> rankList = new ArrayList<>();
for (Object o : array) {
JSONObject r = (JSONObject) o;
String name = (String) r.get("name");
String displayName = (String) r.get("displayName");
Set<String> permissions = new HashSet<>();
for (Object p : (JSONArray) r.get("permissions")) {
permissions.add((String) p);
}
Rank rank = new Rank(name, displayName, permissions);
rankList.add(rank);
}
return rankList;
}
public static @Nullable List<Rank> ranksFromJson(@Nullable String json) {
if (json != null && !json.isEmpty()) {
JsonObject object = GSON.fromJson(json, JsonObject.class);
JsonElement ranks = object.get("ranks");
return GSON.fromJson(ranks, RANKS_TYPE);
}
return null;
}
/**
* Parses the default rank from the specified JSONObject
* Parses the default rank from the specified Json String
*
* @param jo the JSON object
* @param json the Json String
* @return the default rank or null if not found and/or it does not exist
*/
public static @Nullable String defaultRankFromJson(@Nullable JSONObject jo) {
if (jo != null && !jo.isEmpty()) {
if (!jo.containsKey("defaultRank")) {
return null;
} else {
return (String) jo.get("defaultRank");
public static @Nullable String defaultRankFromJson(@Nullable String json) {
if (json != null && !json.isEmpty()) {
JsonObject object = GSON.fromJson(json, JsonObject.class);
JsonElement defaultRank = object.get("defaultRank");
if (defaultRank != null && !defaultRank.isJsonNull()) {
return defaultRank.getAsString();
}
}
return null;
@@ -170,36 +154,24 @@ public class Helper {
* @param defaultRank the default rank
* @return a JSON String
*/
@SuppressWarnings("unchecked")
public static String ranksToJson(List<Rank> ranks, @Nullable String defaultRank) {
if (ranks == null)
ranks = new ArrayList<>();
JSONArray array = new JSONArray();
for (Rank rank : ranks) {
JSONObject o = new JSONObject();
o.put("name", rank.getName());
o.put("displayName", rank.getDisplayName());
JSONArray permArray = new JSONArray();
permArray.addAll(rank.getPermissions());
o.put("permissions", permArray);
array.add(o);
}
JSONObject object = new JSONObject();
object.put("ranks", array);
object.put("defaultRank", defaultRank);
return object.toJSONString();
JsonObject object = new JsonObject();
object.add("ranks", GSON.toJsonTree(ranks));
object.addProperty("defaultRank", defaultRank);
return object.toString();
}
/**
* Converts a resign times map to a JSON String
*
* @param resignTimes
* @param resignTimes the resign times
* @return a JSON String
*/
public static String resignTimesToJson(Map<String, Long> resignTimes) {
return JSONObject.toJSONString(resignTimes);
return GSON.toJson(resignTimes);
}
/**
@@ -208,14 +180,9 @@ public class Helper {
* @param json JSON String
* @return a map
*/
@SuppressWarnings("unchecked")
public static Map<String, Long> resignTimesFromJson(String json) {
if (json != null) {
try {
return (Map<String, Long>) new JSONParser().parse(json);
} catch (ParseException e) {
e.printStackTrace();
}
public static @Nullable Map<String, Long> resignTimesFromJson(String json) {
if (json != null && !json.isEmpty()) {
return GSON.fromJson(json, RESIGN_TYPE);
}
return null;
}
@@ -259,7 +226,7 @@ public class Helper {
}
/**
* Converts string array to ArrayList<String>, remove empty strings
* Converts string array to {@literal ArrayList<String>}, remove empty strings
*
* @param values
* @return
@@ -272,11 +239,12 @@ public class Helper {
}
/**
* Converts string array to HashSet<String>, remove empty strings
* Converts string array to {@literal HashSet<String>}, remove empty strings
*
* @param values
* @return
*/
@Deprecated
public static Set<String> fromArrayToSet(String... values) {
HashSet<String> results = new HashSet<>();
Collections.addAll(results, values);
@@ -285,7 +253,7 @@ public class Helper {
}
/**
* Converts ArrayList<String> to string array
* Converts {@literal ArrayList<String>} to string array
*
* @param list
* @return
@@ -308,40 +276,6 @@ public class Helper {
return sa;
}
/**
* Converts a string array to a string with custom separators
*
* @param args
* @param sep
* @return
*/
public static String toMessage(String[] args, String sep) {
String out = "";
for (String arg : args) {
out += arg + ", ";
}
return stripTrailing(out, ", ");
}
/**
* Converts a string array to a string with custom separators
*
* @param args
* @param sep
* @return
*/
public static String toMessage(List<String> args, String sep) {
String out = "";
for (String arg : args) {
out += arg + sep;
}
return stripTrailing(out, sep);
}
/**
* Cleans up the tag from color codes and makes it lowercase
*
@@ -352,33 +286,6 @@ public class Helper {
return stripColors(tag).toLowerCase();
}
/**
* Removes trailing separators
*
* @param msg
* @param sep
* @return
*/
public static String stripTrailing(String msg, String sep) {
if (msg.length() < sep.length()) {
return msg;
}
String out = msg;
String first = msg.substring(0, sep.length());
String last = msg.substring(msg.length() - sep.length());
if (first.equals(sep)) {
out = msg.substring(sep.length());
}
if (last.equals(sep)) {
out = msg.substring(0, msg.length() - sep.length());
}
return out;
}
/**
* Generates page separator line
*
@@ -426,7 +333,7 @@ public class Helper {
}
/**
* Returns a prettier coordinate, does not include world
* Returns a prettier coordinate
*
* @param loc
* @return
@@ -435,17 +342,6 @@ public class Helper {
return loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + " " + loc.getWorld().getName();
}
/**
* Whether the two locations refer to the same block
*
* @param loc
* @param loc2
* @return
*/
public static boolean isSameBlock(Location loc, Location loc2) {
return loc.getBlockX() == loc2.getBlockX() && loc.getBlockY() == loc2.getBlockY() && loc.getBlockZ() == loc2.getBlockZ();
}
/**
* Sorts a Map by value
*
@@ -490,19 +386,4 @@ public class Helper {
}
return String.join(", ", statuses);
}
/**
* Checks if all passed materials are some kind of AIR
*
* @param materials materials to test
* @return true if all materials are AIR
*/
public static boolean isAir(@NotNull Material... materials) {
for (Material m : materials) {
if (!m.name().contains("AIR")) {
return false;
}
}
return true;
}
}
@@ -1,5 +1,7 @@
package net.sacredlabyrinth.phaed.simpleclans;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
@@ -15,11 +17,11 @@ public class Rank implements Comparable<Rank> {
public Rank(String name) {
setName(name);
permissions = new HashSet<String>();
permissions = new HashSet<>();
setDisplayName(displayName);
}
public Rank(String name, String displayName, Set<String> permissions) {
public Rank(String name, @Nullable String displayName, Set<String> permissions) {
setName(name);
setDisplayName(displayName);
setPermissions(permissions);
@@ -32,7 +34,7 @@ public class Rank implements Comparable<Rank> {
this.name = name;
}
public void setDisplayName(String displayName) {
public void setDisplayName(@Nullable String displayName) {
if (displayName == null || displayName.isEmpty()) {
displayName = name;
}
@@ -41,7 +43,7 @@ public class Rank implements Comparable<Rank> {
public void setPermissions(Set<String> permissions) {
if (permissions == null) {
permissions = new HashSet<String>();
permissions = new HashSet<>();
}
this.permissions = permissions;
}
@@ -21,6 +21,7 @@ public enum RankPermission {
COORDS("simpleclans.member.coords", PermissionLevel.TRUSTED),
FEE_ENABLE("simpleclans.leader.fee", PermissionLevel.LEADER),
FEE_SET("simpleclans.leader.fee", PermissionLevel.LEADER),
FEE_BYPASS("", PermissionLevel.LEADER),
REGROUP_HOME("simpleclans.leader.regroup.home", PermissionLevel.LEADER),
REGROUP_ME("simpleclans.leader.regroup.me", PermissionLevel.LEADER),
HOME_SET("simpleclans.leader.home-set", PermissionLevel.LEADER),
@@ -9,6 +9,8 @@ import net.sacredlabyrinth.phaed.simpleclans.listeners.*;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLogger;
import net.sacredlabyrinth.phaed.simpleclans.loggers.CSVBankLogger;
import net.sacredlabyrinth.phaed.simpleclans.managers.*;
import net.sacredlabyrinth.phaed.simpleclans.proxy.BungeeManager;
import net.sacredlabyrinth.phaed.simpleclans.proxy.ProxyManager;
import net.sacredlabyrinth.phaed.simpleclans.tasks.*;
import net.sacredlabyrinth.phaed.simpleclans.ui.InventoryController;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatFormatMigration;
@@ -34,6 +36,7 @@ import java.util.logging.Logger;
import java.util.regex.Pattern;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*;
import static org.bukkit.Bukkit.getPluginManager;
/**
* @author Phaed
@@ -54,6 +57,7 @@ public class SimpleClans extends JavaPlugin {
private TeleportManager teleportManager;
private ProtectionManager protectionManager;
private ChatManager chatManager;
private ProxyManager proxyManager;
private boolean hasUUID;
private static final Pattern ACF_PLACEHOLDER_PATTERN = Pattern.compile("\\{(?<key>[a-zA-Z]+?)}");
@@ -100,6 +104,7 @@ public class SimpleClans extends JavaPlugin {
permissionsManager = new PermissionsManager();
requestManager = new RequestManager();
clanManager = new ClanManager();
proxyManager = new BungeeManager(this);
storageManager = new StorageManager();
teleportManager = new TeleportManager();
protectionManager = new ProtectionManager();
@@ -119,16 +124,17 @@ public class SimpleClans extends JavaPlugin {
}
private void logStatus() {
getLogger().info("Multithreading: " + SimpleClans.getInstance().getSettingsManager().is(PERFORMANCE_USE_THREADS));
getLogger().info("BungeeCord: " + SimpleClans.getInstance().getSettingsManager().is(PERFORMANCE_USE_BUNGEECORD));
getLogger().info("Multithreading: " + settingsManager.is(PERFORMANCE_USE_THREADS));
getLogger().info("BungeeCord: " + settingsManager.is(PERFORMANCE_USE_BUNGEECORD));
getLogger().info("HEX support: " + ChatUtils.HEX_COLOR_SUPPORT);
getLogger().info("Help us translate SimpleClans to your language! " +
"Access https://crowdin.com/project/simpleclans/");
}
private void registerEvents() {
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new PlayerDeath(), this);
pm.registerEvents(new SCPlayerListener(), this);
pm.registerEvents(new PlayerDeath(this), this);
pm.registerEvents(new SCPlayerListener(this), this);
pm.registerEvents(new InventoryController(), this);
pm.registerEvents(new TamableMobsSharing(this), this);
pm.registerEvents(new PvPOnlyInWar(this), this);
@@ -142,7 +148,7 @@ public class SimpleClans extends JavaPlugin {
}
private void hookIntoPAPI() {
if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) {
if (getPluginManager().getPlugin("PlaceholderAPI") != null) {
getLogger().info("PlaceholderAPI found. Registering hook...");
new SimpleClansExpansion(this).register();
}
@@ -246,6 +252,10 @@ public class SimpleClans extends JavaPlugin {
return chatManager;
}
public ProxyManager getProxyManager() {
return proxyManager;
}
public BankLogger getBankLogger() {
return bankLogger;
}
@@ -267,7 +277,7 @@ public class SimpleClans extends JavaPlugin {
@Nullable
public static String optionalLang(@NotNull String key, @Nullable ClanPlayer clanPlayer, Object... arguments) {
Locale locale = instance.getSettingsManager().getLanguage();
if (clanPlayer != null && instance.getSettingsManager().is(LANGUAGE_SELECTOR)) {
if (clanPlayer != null && clanPlayer.getLocale() != null && instance.getSettingsManager().is(LANGUAGE_SELECTOR)) {
locale = clanPlayer.getLocale();
}
@@ -1,32 +1,31 @@
package net.sacredlabyrinth.phaed.simpleclans;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.CLAN_TELEPORT_DELAY;
public class TeleportState {
private final UUID playerUniqueId;
private final Location playerLocation;
private final OfflinePlayer offlinePlayer;
private final Location origin;
private final Location destination;
private int counter;
private final String clanName;
private boolean processing;
public TeleportState(Player player, Location destination, String clanName) {
public TeleportState(Player player, Location destination, String clanName, int counter) {
this.offlinePlayer = player;
this.destination = destination;
this.playerLocation = player.getLocation();
this.origin = player.getLocation();
this.clanName = clanName;
this.counter = SimpleClans.getInstance().getSettingsManager().getInt(CLAN_TELEPORT_DELAY);
this.playerUniqueId = player.getUniqueId();
this.counter = counter;
}
public Location getLocation() {
return this.playerLocation;
return this.origin;
}
public boolean isTeleportTime() {
@@ -44,7 +43,7 @@ public class TeleportState {
* @return the player
*/
public @Nullable Player getPlayer() {
return SimpleClans.getInstance().getServer().getPlayer(this.playerUniqueId);
return offlinePlayer.getPlayer();
}
/**
@@ -76,7 +75,4 @@ public class TeleportState {
this.processing = processing;
}
public UUID getUniqueId() {
return this.playerUniqueId;
}
}
@@ -2,12 +2,15 @@ package net.sacredlabyrinth.phaed.simpleclans.chat;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.managers.ChatManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager;
public interface ChatHandler {
SimpleClans plugin = SimpleClans.getInstance();
SettingsManager settingsManager = plugin.getSettingsManager();
ChatManager chatManager = plugin.getChatManager();
PermissionsManager permissionsManager = plugin.getPermissionsManager();
void sendMessage(SCMessage message);
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class SCMessage {
public class SCMessage implements Cloneable {
private final Source source;
private final ClanPlayer.Channel channel;
@@ -23,7 +23,8 @@ public class SCMessage {
* @param content The content of message
* @param receivers The clan players, who will receive the content
*/
public SCMessage(@NotNull Source source, @NotNull ClanPlayer.Channel channel, @NotNull ClanPlayer sender, String content, @NotNull List<ClanPlayer> receivers) {
public SCMessage(@NotNull Source source, @NotNull ClanPlayer.Channel channel,
@NotNull ClanPlayer sender, String content, @NotNull List<ClanPlayer> receivers) {
this.source = source;
this.channel = channel;
this.sender = sender;
@@ -34,7 +35,7 @@ public class SCMessage {
/**
* Creates a new SCMessage without receivers
*
* @see SCMessage#SCMessage(Source, ClanPlayer.Channel, ClanPlayer, String, List instantiate with initial receievers
* @see SCMessage#SCMessage(Source, ClanPlayer.Channel, ClanPlayer, String, List) instantiate with initial receievers
*/
public SCMessage(@NotNull Source source, @NotNull ClanPlayer.Channel channel, @NotNull ClanPlayer sender, String content) {
this(source, channel, sender, content, new ArrayList<>());
@@ -68,6 +69,15 @@ public class SCMessage {
this.receivers = receivers;
}
@Override
public SCMessage clone() {
try {
return (SCMessage) super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(); //never thrown
}
}
/**
* The place where the message came from.
* Used by ChatHandlers to know which SCMessages they can handle.
@@ -75,6 +85,6 @@ public class SCMessage {
* @see ChatHandler initiate the handler
*/
public enum Source {
SPIGOT, DISCORD, BUNGEE
SPIGOT, DISCORD, PROXY
}
}
@@ -5,17 +5,17 @@ import github.scarsz.discordsrv.util.DiscordUtil;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.chat.ChatHandler;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
import net.sacredlabyrinth.phaed.simpleclans.hooks.DiscordHook;
import net.sacredlabyrinth.phaed.simpleclans.hooks.discord.DiscordHook;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.Optional;
import static net.sacredlabyrinth.phaed.simpleclans.ClanPlayer.Channel.CLAN;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.SPIGOT;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.DISCORDCHAT_ENABLE;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.SPIGOT;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.DISCORDCHAT_FORMAT_TO;
import static org.bukkit.Bukkit.getPluginManager;
/**
* Handles delivering messages from {@link Source#SPIGOT} to {@link Source#DISCORD}.
@@ -23,27 +23,26 @@ import static org.bukkit.Bukkit.getPluginManager;
public class DiscordChatHandler implements ChatHandler {
@Override
public void sendMessage(SCMessage message) {
public void sendMessage(@NotNull SCMessage message) {
if (message.getChannel() != CLAN) {
return;
}
String format = settingsManager.getString(DISCORDCHAT_FORMAT_TO);
String formattedMessage = chatManager.parseChatFormat(format, message);
String formattedMessage = ChatUtils.stripColors(chatManager.parseChatFormat(format, message));
Clan clan = message.getSender().getClan();
if (clan == null) {
return;
}
DiscordHook discordHook = Objects.requireNonNull(chatManager.getDiscordHook(), "DiscordHook cannot be null");
Optional<TextChannel> channel = discordHook.getChannel(clan.getTag());
Optional<TextChannel> channel = discordHook.getCachedChannel(clan.getTag());
channel.ifPresent(textChannel -> DiscordUtil.sendMessage(textChannel, formattedMessage));
}
@Override
public boolean canHandle(SCMessage.Source source) {
return source == SPIGOT && settingsManager.is(DISCORDCHAT_ENABLE) &&
getPluginManager().getPlugin("DiscordSRV") != null;
return source == SPIGOT && chatManager.isDiscordHookEnabled();
}
}
@@ -0,0 +1,20 @@
package net.sacredlabyrinth.phaed.simpleclans.chat.handlers;
import net.sacredlabyrinth.phaed.simpleclans.chat.ChatHandler;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.PERFORMANCE_USE_BUNGEECORD;
public class ProxyChatHandler implements ChatHandler {
@Override
public void sendMessage(SCMessage message) {
plugin.getProxyManager().sendMessage(message);
}
@Override
public boolean canHandle(Source source) {
return source == Source.SPIGOT && settingsManager.is(PERFORMANCE_USE_BUNGEECORD);
}
}
@@ -5,14 +5,15 @@ import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.chat.ChatHandler;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
import net.sacredlabyrinth.phaed.simpleclans.events.ChatEvent;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import org.bukkit.scheduler.BukkitRunnable;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.DISCORD;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.SPIGOT;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.*;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.DISCORDCHAT_ENABLE;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.PERFORMANCE_USE_BUNGEECORD;
import static org.bukkit.Bukkit.getPluginManager;
@SuppressWarnings("unused")
public class SpigotChatHandler implements ChatHandler {
@Override
@@ -30,14 +31,15 @@ public class SpigotChatHandler implements ChatHandler {
if (event.isCancelled()) {
return;
}
message.setContent(stripColorsAndFormatsPerPermission(message.getSender(),event.getMessage()));
ConfigField configField = ConfigField.valueOf(String.format("%sCHAT_FORMAT",
message.getSource() == SPIGOT ? message.getChannel() : message.getSource()));
message.getSource() == DISCORD ? "DISCORD" : message.getChannel()));
String format = settingsManager.getString(configField);
String formattedMessage = chatManager.parseChatFormat(format, message, event.getPlaceholders());
plugin.getLogger().info(formattedMessage);
plugin.getLogger().info(ChatUtils.stripColors(formattedMessage));
for (ClanPlayer cp : message.getReceivers()) {
ChatBlock.sendMessage(cp, formattedMessage);
@@ -46,9 +48,27 @@ public class SpigotChatHandler implements ChatHandler {
}.runTask(plugin);
}
private String stripColorsAndFormatsPerPermission(ClanPlayer sender, String message) {
if (!permissionsManager.has(sender.toPlayer(), "simpleclans.member.chat.color")) {
message = stripColors(message);
}
if (!permissionsManager.has(sender.toPlayer(), "simpleclans.member.chat.format")) {
message = stripFormats(message);
}
return message;
}
private String stripColors(String message) {
return message.replaceAll("[§&][0-9a-fA-FxX]", "");
}
private String stripFormats(String message) {
return message.replaceAll("[§&][k-orK-OR]", "");
}
@Override
public boolean canHandle(SCMessage.Source source) {
return source == SPIGOT || (source == DISCORD && settingsManager.is(DISCORDCHAT_ENABLE) &&
getPluginManager().getPlugin("DiscordSRV") != null);
return source == SPIGOT || (source == PROXY && settingsManager.is(PERFORMANCE_USE_BUNGEECORD))
|| (source == DISCORD && chatManager.isDiscordHookEnabled());
}
}
@@ -4,48 +4,51 @@ import net.sacredlabyrinth.phaed.simpleclans.ChatBlock;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.chat.ChatHandler;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import org.bukkit.Bukkit;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.DISCORD;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.SPIGOT;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.*;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.DISCORDCHAT_ENABLE;
import static org.bukkit.Bukkit.getPluginManager;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.PERFORMANCE_USE_BUNGEECORD;
/**
* Handles delivering messages from {@link Source#SPIGOT} and {@link Source#DISCORD} to internal spy chat.
* Handles delivering messages from {@link Source#SPIGOT} or {@link Source#DISCORD} to internal spy chat.
*/
public class SpyChatHandler implements ChatHandler {
@Override
public void sendMessage(SCMessage message) {
ConfigField configField = ConfigField.valueOf(String.format("%sCHAT_SPYFORMAT",
message.getSource() == SPIGOT ? message.getChannel() : message.getSource()));
String format = settingsManager.getString(configField);
ConfigField formatField = ConfigField.valueOf(String.format("%sCHAT_SPYFORMAT",
message.getSource() == DISCORD ? "DISCORD" : message.getChannel()));
String format = settingsManager.getString(formatField);
message.setContent(ChatUtils.stripColors(message.getContent()));
String formattedMessage = chatManager.parseChatFormat(format, message);
List<ClanPlayer> onlinePlayers = getOnlineClanPlayers().stream()
.filter(player -> plugin.getPermissionsManager().has(player.toPlayer(), "simpleclans.admin.all-seeing-eye"))
.filter(player -> !player.isMuted())
.collect(Collectors.toList());
List<ClanPlayer> onlineSpies = getOnlineSpies();
onlinePlayers.removeAll(message.getReceivers());
onlinePlayers.forEach(receiver -> ChatBlock.sendMessage(receiver, formattedMessage));
// Don't send a duplicate message if a spy is inside the clan
onlineSpies.removeAll(message.getReceivers());
onlineSpies.forEach(receiver -> ChatBlock.sendMessage(receiver, formattedMessage));
}
@Override
public boolean canHandle(SCMessage.Source source) {
return source == SPIGOT || (source == DISCORD && settingsManager.is(DISCORDCHAT_ENABLE) &&
getPluginManager().getPlugin("DiscordSRV") != null);
return source == SPIGOT || (source == PROXY && settingsManager.is(PERFORMANCE_USE_BUNGEECORD))
|| (source == DISCORD && chatManager.isDiscordHookEnabled());
}
private List<ClanPlayer> getOnlineClanPlayers() {
return plugin.getClanManager().getAllClanPlayers().stream().
filter(cp -> cp.toPlayer() != null).
private List<ClanPlayer> getOnlineSpies() {
return Bukkit.getOnlinePlayers().stream().
filter(Objects::nonNull).
filter(player -> permissionsManager.has(player, "simpleclans.admin.all-seeing-eye")).
map(player -> plugin.getClanManager().getCreateClanPlayer(player.getUniqueId())).
filter(Objects::nonNull).
filter(clanPlayer -> !clanPlayer.isMuted()).
collect(Collectors.toList());
}
}
@@ -53,6 +53,7 @@ public class SCCommandManager extends PaperCommandManager {
registerCommands();
registerConditions();
registerCompletions();
defaultHelpPerPage = plugin.getSettingsManager().getInt(HELP_SIZE);
}
private void registerDependencies() {
@@ -223,6 +224,6 @@ public class SCCommandManager extends PaperCommandManager {
"setdisplayname", "permissions", "tag", "deposit", "withdraw", "set", "status", "tp", "all", "everyone",
"lookup", "roster", "profile", "list", "create", "description", "start", "end", "admin", "help", "mod",
"setdefault", "removedefault", "land", "break", "interact", "place_block", "damage", "interact_entity",
"container", "permanent", "take", "give", "join", "leave", "mute", "confirm", "balance");
"container", "permanent", "take", "give", "join", "leave", "mute", "confirm", "balance", "discord");
}
}
@@ -7,13 +7,15 @@ import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.EconomyResponse;
import net.sacredlabyrinth.phaed.simpleclans.events.BankDepositEvent;
import net.sacredlabyrinth.phaed.simpleclans.events.BankWithdrawEvent;
import net.sacredlabyrinth.phaed.simpleclans.events.ClanBalanceUpdateEvent;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLogger;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankOperator;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.events.ClanBalanceUpdateEvent.Cause.REVERT;
import static net.sacredlabyrinth.phaed.simpleclans.events.ClanBalanceUpdateEvent.Cause.COMMAND;
import static org.bukkit.ChatColor.AQUA;
import static org.bukkit.ChatColor.RED;
@@ -67,13 +69,14 @@ public class BankCommand extends BaseCommand {
/*
* ——————————————————————————————————
*/
switch (clan.withdraw(player, ClanBalanceUpdateEvent.Cause.COMMAND, amount)) {
BankOperator operator = new BankOperator(player, permissions.playerGetMoney(player));
switch (clan.withdraw(operator, COMMAND, amount)) {
case SUCCESS:
if (permissions.playerGrantMoney(player, amount)) {
player.sendMessage(AQUA + lang("player.clan.withdraw", player, amount));
clan.addBb(player.getName(), AQUA + lang("bb.clan.withdraw", amount));
clan.addBb(player.getName(), AQUA + lang("bb.clan.withdraw", amount, player.getName()));
} else {
clan.setBalance(player, ClanBalanceUpdateEvent.Cause.REVERT, BankLogger.Operation.WITHDRAW, clan.getBalance() + amount);
clan.setBalance(operator, REVERT, BankLogger.Operation.WITHDRAW, clan.getBalance() + amount);
}
break;
case NOT_ENOUGH_BALANCE:
@@ -120,17 +123,18 @@ public class BankCommand extends BaseCommand {
*/
if (!permissions.playerHasMoney(player, amount)) {
player.sendMessage(AQUA + lang("not.sufficient.money", player));
player.sendMessage(AQUA + lang("not.sufficient.money", player, amount));
return;
}
EconomyResponse response = clan.deposit(player, ClanBalanceUpdateEvent.Cause.COMMAND, amount);
BankOperator operator = new BankOperator(player, permissions.playerGetMoney(player));
EconomyResponse response = clan.deposit(operator, COMMAND, amount);
if (response == EconomyResponse.SUCCESS) {
if (permissions.playerChargeMoney(player, amount)) {
player.sendMessage(AQUA + lang("player.clan.deposit", player, amount));
clan.addBb(player.getName(), AQUA + lang("bb.clan.deposit", amount));
clan.addBb(player.getName(), AQUA + lang("bb.clan.deposit", amount, player.getName()));
} else {
//Reverts the deposit if something went wrong with Vault
clan.setBalance(player, ClanBalanceUpdateEvent.Cause.REVERT, BankLogger.Operation.DEPOSIT, clan.getBalance() - amount);
clan.setBalance(operator, REVERT, BankLogger.Operation.DEPOSIT, clan.getBalance() - amount);
}
}
}
@@ -22,8 +22,6 @@ public class ChatCommand extends BaseCommand {
@Dependency
private ChatManager chatManager;
@Dependency
private SettingsManager settingsManager;
@Dependency
private StorageManager storageManager;
@Default
@@ -241,7 +241,7 @@ public class ClanCommands extends BaseCommand {
@Subcommand("%rival %add")
@CommandPermission("simpleclans.leader.rival")
@Conditions("verified|rivable|minimum_to_rival|rank:name=RIVAL_ADD")
@CommandCompletion("@clans")
@CommandCompletion("@clans:hide_own")
@Description("{@@command.description.rival.add}")
public void addRival(Player player, Clan issuerClan, @Conditions("verified|different") @Name("clan") ClanInput rival) {
Clan rivalInput = rival.getClan();
@@ -286,7 +286,7 @@ public class ClanCommands extends BaseCommand {
@Subcommand("%ally %add")
@CommandPermission("simpleclans.leader.ally")
@Conditions("verified|rank:name=ALLY_ADD|minimum_to_ally")
@CommandCompletion("@clans")
@CommandCompletion("@clans:hide_own")
@Description("{@@command.description.ally.add}")
public void addAlly(Player player,
ClanPlayer cp,
@@ -337,7 +337,7 @@ public class ClanCommands extends BaseCommand {
@Subcommand("%kick")
@CommandPermission("simpleclans.leader.kick")
@CommandCompletion("@clan_members")
@CommandCompletion("@clan_members:hide_own")
@Conditions("rank:name=KICK")
@Description("{@@command.description.kick}")
public void kick(@Conditions("clan_member") Player sender,
@@ -4,12 +4,14 @@ import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.*;
import net.sacredlabyrinth.phaed.simpleclans.*;
import net.sacredlabyrinth.phaed.simpleclans.events.HomeRegroupEvent;
import net.sacredlabyrinth.phaed.simpleclans.events.PlayerHomeClearEvent;
import net.sacredlabyrinth.phaed.simpleclans.events.PlayerHomeSetEvent;
import net.sacredlabyrinth.phaed.simpleclans.managers.ClanManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.ProtectionManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager;
import net.sacredlabyrinth.phaed.simpleclans.utils.VanishUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@@ -59,17 +61,12 @@ public class HomeCommands extends BaseCommand {
@CommandPermission("simpleclans.leader.regroup.home")
@Conditions("rank:name=REGROUP_HOME")
@Description("{@@command.description.regroup.home}")
public void regroupHome(Player player, ClanPlayer cp, Clan clan) {
public void regroupHome(Player player, ClanPlayer cp, @Conditions("can_teleport") Clan clan) {
if (!settings.is(ALLOW_REGROUP)) {
ChatBlock.sendMessage(player, RED + lang("insufficient.permissions", player));
return;
}
Location location = clan.getHomeLocation();
if (location == null) {
ChatBlock.sendMessage(player, RED + lang("hombase.not.set", player));
return;
}
processRegroup(player, cp, clan, location);
}
@@ -77,16 +74,11 @@ public class HomeCommands extends BaseCommand {
@CommandPermission("simpleclans.member.home")
@Conditions("rank:name=HOME_TP")
@Description("{@@command.description.home.tp}")
public void teleport(Player player, Clan clan, ClanPlayer cp) {
Location loc = clan.getHomeLocation();
if (loc == null) {
ChatBlock.sendMessage(player, RED + lang("hombase.not.set", player));
return;
}
public void teleport(Player player, @Conditions("can_teleport") Clan clan, ClanPlayer cp) {
Location homeLocation = clan.getHomeLocation();
if (cm.purchaseHomeTeleport(player)) {
plugin.getTeleportManager().addPlayer(player, clan.getHomeLocation(), clan.getName());
plugin.getTeleportManager().addPlayer(player, homeLocation, clan.getName());
}
}
@@ -94,13 +86,19 @@ public class HomeCommands extends BaseCommand {
@CommandPermission("simpleclans.leader.home-set")
@Conditions("rank:name=HOME_SET")
@Description("{@@command.description.home.clear}")
public void clear(Player player, Clan clan) {
public void clear(Player player, ClanPlayer cp, Clan clan) {
if (settings.is(CLAN_HOMEBASE_CAN_BE_SET_ONLY_ONCE) && clan.getHomeLocation() != null &&
!permissions.has(player, "simpleclans.mod.home")) {
ChatBlock.sendMessage(player, RED + lang("home.base.only.once", player));
return;
}
PlayerHomeClearEvent event = new PlayerHomeClearEvent(clan, cp);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
clan.setHomeLocation(null);
ChatBlock.sendMessage(player, AQUA + lang("hombase.cleared", player));
}
@@ -18,7 +18,7 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con
@CommandAlias("%clan")
@Subcommand("%land")
@Conditions("%basic_conditions|land_sharing|own_land")
@Conditions("%basic_conditions|clan_member|land_sharing|own_land")
@CommandPermission("simpleclans.member.land")
public class LandCommand extends BaseCommand {
@@ -5,7 +5,12 @@ import co.aikar.commands.annotation.*;
import net.sacredlabyrinth.phaed.simpleclans.ChatBlock;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.commands.ClanPlayerInput;
import net.sacredlabyrinth.phaed.simpleclans.conversation.DisbandPrompt;
import net.sacredlabyrinth.phaed.simpleclans.conversation.SCConversation;
import net.sacredlabyrinth.phaed.simpleclans.hooks.discord.DiscordHook;
import net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions.DiscordHookException;
import net.sacredlabyrinth.phaed.simpleclans.managers.*;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
@@ -14,13 +19,14 @@ import java.util.Objects;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*;
import static org.bukkit.ChatColor.AQUA;
import static org.bukkit.ChatColor.RED;
import static org.bukkit.ChatColor.*;
@CommandAlias("%clan")
@Conditions("%basic_conditions|leader")
public class LeaderCommands extends BaseCommand {
@Dependency
private SimpleClans plugin;
@Dependency
private StorageManager storage;
@Dependency
@@ -31,6 +37,8 @@ public class LeaderCommands extends BaseCommand {
private RequestManager requestManager;
@Dependency
private ClanManager cm;
@Dependency
private ChatManager chatManager;
@Subcommand("%demote")
@CommandCompletion("@clan_leaders")
@@ -103,7 +111,7 @@ public class LeaderCommands extends BaseCommand {
return;
}
clan.disband(player, true, false);
new SCConversation(plugin, player, new DisbandPrompt()).begin();
}
@Subcommand("%verify")
@@ -178,4 +186,42 @@ public class LeaderCommands extends BaseCommand {
trustedInput.setTrusted(false);
storage.updateClanPlayer(trustedInput);
}
@Subcommand("%discord %create")
@CommandPermission("simpleclans.leader.discord.create")
@Description("{@@command.description.discord.create}")
@Conditions("verified")
public void discord(Player player, Clan clan) {
DiscordHook discordHook = chatManager.getDiscordHook();
if (discordHook == null) {
ChatBlock.sendMessageKey(player, "discordhook.is.disabled");
return;
}
double amount = settings.getDouble(ECONOMY_DISCORD_CREATION_PRICE);
if (settings.is(ECONOMY_PURCHASE_DISCORD_CREATE)) {
if (!permissions.playerHasMoney(player, amount)) {
player.sendMessage(AQUA + lang("not.sufficient.money", player, amount));
return;
}
if (!permissions.playerChargeMoney(player, amount)) {
return;
}
}
try {
discordHook.createChannel(clan.getTag());
ChatBlock.sendMessageKey(player, "discord.created.successfully");
} catch (DiscordHookException ex) {
// Return player's money if clan creation went wrong
if (settings.is(ECONOMY_PURCHASE_DISCORD_CREATE)) {
permissions.playerGrantMoney(player, amount);
}
String messageKey = ex.getMessageKey();
if (messageKey != null) {
ChatBlock.sendMessage(player, RED + lang(messageKey));
}
}
}
}
@@ -157,7 +157,7 @@ public class RankCommand extends BaseCommand {
@Subcommand("%permissions")
public class PermissionsCommand extends BaseCommand {
private final String validPermissionsToMessage = Helper.toMessage(Helper.fromPermissionArray(), ",");
private final String validPermissionsToMessage = String.join(",", Helper.fromPermissionArray());
@Default
@CommandPermission("simpleclans.leader.rank.permissions.available")
@@ -178,7 +178,7 @@ public class RankCommand extends BaseCommand {
return;
}
ChatBlock.sendMessage(player, AQUA + lang("rank.0.permissions", player, rank.getDisplayName()));
ChatBlock.sendMessage(player, AQUA + Helper.toMessage(permissions.toArray(new String[0]), ","));
ChatBlock.sendMessage(player, AQUA + String.join(",", permissions));
}
@Subcommand("%add")
@@ -10,8 +10,10 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class ClanMembersCompletion extends AbstractSyncCompletion {
public ClanMembersCompletion(@NotNull SimpleClans plugin) {
super(plugin);
@@ -23,7 +25,11 @@ public class ClanMembersCompletion extends AbstractSyncCompletion {
if (player != null) {
Clan clan = clanManager.getClanByPlayerUniqueId(player.getUniqueId());
if (clan != null) {
return clan.getMembers().stream().map(ClanPlayer::getName).collect(Collectors.toList());
List<String> list = clan.getMembers().stream().map(ClanPlayer::getName).collect(Collectors.toList());
if (c.hasConfig("hide_own")) {
list.remove(player.getName());
}
return list;
}
}
return Collections.emptyList();
@@ -1,14 +1,16 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.completions;
import co.aikar.commands.BukkitCommandCompletionContext;
import co.aikar.commands.CommandIssuer;
import co.aikar.commands.InvalidCommandArgument;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ClansCompletion extends AbstractSyncCompletion {
public ClansCompletion(@NotNull SimpleClans plugin) {
@@ -17,18 +19,28 @@ public class ClansCompletion extends AbstractSyncCompletion {
@Override
public Collection<String> getCompletions(BukkitCommandCompletionContext c) throws InvalidCommandArgument {
Stream<Clan> clans = clanManager.getClans().stream();
List<Clan> clans = clanManager.getClans();
if (c.hasConfig("has_home")) {
clans = clans.filter(clan -> clan.getHomeLocation() != null);
clans.removeIf(clan -> clan.getHomeLocation() == null);
}
if (c.hasConfig("unverified")) {
clans = clans.filter(clan -> !clan.isVerified());
clans.removeIf(Clan::isVerified);
}
return clans.map(Clan::getTag).collect(Collectors.toList());
if (c.hasConfig("hide_own")) {
Clan clan = getClan(c.getIssuer());
if (clan != null) {
clans.remove(clan);
}
}
return clans.stream().map(Clan::getTag).collect(Collectors.toList());
}
@Override
public @NotNull String getId() {
return "clans";
}
private @Nullable Clan getClan(CommandIssuer issuer) {
return clanManager.getClanByPlayerUniqueId(issuer.getUniqueId());
}
}
@@ -0,0 +1,42 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.conditions;
import co.aikar.commands.*;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.Flags;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
public class TeleportCondition extends AbstractParameterCondition<Clan> {
public TeleportCondition(@NotNull SimpleClans plugin) {
super(plugin);
}
@Override
public Class<Clan> getType() {
return Clan.class;
}
@Override
public void validateCondition(ConditionContext<BukkitCommandIssuer> context,
BukkitCommandExecutionContext execContext,
Clan value) throws InvalidCommandArgument {
Player player = execContext.getPlayer();
if (value.getHomeLocation() == null) {
throw new ConditionFailedException(lang("hombase.not.set", player));
}
Flags flags = new Flags(value.getFlags());
String homeServer = flags.getString("homeServer", "");
if (!homeServer.isEmpty() && !plugin.getProxyManager().getServerName().equals(homeServer)) {
throw new ConditionFailedException(lang("home.set.in.different.server"));
}
}
@Override
public @NotNull String getId() {
return "can_teleport";
}
}
@@ -0,0 +1,31 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.conditions;
import co.aikar.commands.BukkitCommandExecutionContext;
import co.aikar.commands.BukkitCommandIssuer;
import co.aikar.commands.ConditionContext;
import co.aikar.commands.InvalidCommandArgument;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.commands.ClanInput;
import org.jetbrains.annotations.NotNull;
public class TeleportInputCondition extends AbstractParameterCondition<ClanInput> {
public TeleportInputCondition(@NotNull SimpleClans plugin) {
super(plugin);
}
@Override
public Class<ClanInput> getType() {
return ClanInput.class;
}
@Override
public void validateCondition(ConditionContext<BukkitCommandIssuer> context, BukkitCommandExecutionContext execContext, ClanInput value) throws InvalidCommandArgument {
new TeleportCondition(plugin).validateCondition(context, execContext, value.getClan());
}
@Override
public @NotNull String getId() {
return "can_teleport";
}
}
@@ -2,32 +2,43 @@ package net.sacredlabyrinth.phaed.simpleclans.commands.contexts;
import co.aikar.commands.BukkitCommandExecutionContext;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.MinecraftMessageKeys;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.commands.ClanPlayerInput;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.regex.Pattern;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.USERNAME_REGEX;
@SuppressWarnings("unused")
public class ClanPlayerInputContextResolver extends AbstractInputOnlyContextResolver<ClanPlayerInput> {
private final Pattern validUsername;
public ClanPlayerInputContextResolver(@NotNull SimpleClans plugin) {
super(plugin);
validUsername = Pattern.compile(plugin.getSettingsManager().getString(USERNAME_REGEX));
}
@Override
public ClanPlayerInput getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument {
String arg = context.popFirstArg();
if (!validUsername.matcher(arg).matches()) {
throw new InvalidCommandArgument(MinecraftMessageKeys.IS_NOT_A_VALID_NAME, "{name}", arg);
}
ClanPlayer cp = clanManager.getAnyClanPlayer(arg);
if (cp == null) {
@SuppressWarnings("deprecation")
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(arg);
if (!offlinePlayer.hasPlayedBefore()) {
Player player = Bukkit.getPlayer(arg);
if (player == null) {
throw new InvalidCommandArgument(lang("user.hasnt.played.before", context.getSender()));
}
cp = clanManager.getCreateClanPlayer(offlinePlayer.getUniqueId());
cp = clanManager.getCreateClanPlayer(player.getUniqueId());
}
return new ClanPlayerInput(cp);
@@ -37,4 +48,5 @@ public class ClanPlayerInputContextResolver extends AbstractInputOnlyContextReso
public Class<ClanPlayerInput> getType() {
return ClanPlayerInput.class;
}
}
@@ -2,12 +2,12 @@ package net.sacredlabyrinth.phaed.simpleclans.commands.contexts;
import co.aikar.commands.BukkitCommandIssuer;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.MessageKeys;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.managers.ClanManager;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import static co.aikar.commands.MessageKeys.*;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
public class Contexts {
@@ -30,8 +30,17 @@ public class Contexts {
public static Player assertPlayer(@NotNull BukkitCommandIssuer issuer) {
Player player = issuer.getPlayer();
if (player == null) {
throw new InvalidCommandArgument(MessageKeys.NOT_ALLOWED_ON_CONSOLE, false);
throw new InvalidCommandArgument(NOT_ALLOWED_ON_CONSOLE, false);
}
return player;
}
public static void validateMinMax(Number val, Number minValue, Number maxValue) throws InvalidCommandArgument {
if (maxValue != null && val.doubleValue() > maxValue.doubleValue()) {
throw new InvalidCommandArgument(PLEASE_SPECIFY_AT_MOST, "{max}", String.valueOf(maxValue));
}
if (minValue != null && val.doubleValue() < minValue.doubleValue()) {
throw new InvalidCommandArgument(PLEASE_SPECIFY_AT_LEAST, "{min}", String.valueOf(minValue));
}
}
}
@@ -0,0 +1,16 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.contexts;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
public class DoubleContextResolver extends DoublePrimitiveContextResolver {
public DoubleContextResolver(@NotNull SimpleClans plugin) {
super(plugin);
}
@Override
public Class<Double> getType() {
return Double.class;
}
}
@@ -0,0 +1,39 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.contexts;
import co.aikar.commands.BukkitCommandExecutionContext;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.MessageKeys;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.jetbrains.annotations.NotNull;
import static net.sacredlabyrinth.phaed.simpleclans.commands.contexts.Contexts.validateMinMax;
@SuppressWarnings("unused")
public class DoublePrimitiveContextResolver extends AbstractInputOnlyContextResolver<Double> {
public DoublePrimitiveContextResolver(@NotNull SimpleClans plugin) {
super(plugin);
}
@Override
public Double getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument {
String number = context.popFirstArg();
try {
double val = Double.parseDouble(number);
if (!Double.isFinite(val)) {
throw new NumberFormatException();
}
validateMinMax(val, Double.MIN_VALUE, Double.MAX_VALUE);
return val;
} catch (NumberFormatException e) {
throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", number);
}
}
@Override
public Class<Double> getType() {
return double.class;
}
}
@@ -0,0 +1,16 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.contexts;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
public class FloatContextResolver extends FloatPrimitiveContextResolver {
public FloatContextResolver(@NotNull SimpleClans plugin) {
super(plugin);
}
@Override
public Class<Float> getType() {
return Float.class;
}
}
@@ -0,0 +1,36 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.contexts;
import co.aikar.commands.BukkitCommandExecutionContext;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.MessageKeys;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.jetbrains.annotations.NotNull;
import static net.sacredlabyrinth.phaed.simpleclans.commands.contexts.Contexts.validateMinMax;
@SuppressWarnings("unused")
public class FloatPrimitiveContextResolver extends AbstractInputOnlyContextResolver<Float> {
public FloatPrimitiveContextResolver(@NotNull SimpleClans plugin) {
super(plugin);
}
@Override
public Float getContext(BukkitCommandExecutionContext context) throws InvalidCommandArgument {
String number = context.popFirstArg();
try {
float val = Float.parseFloat(number);
if (!Float.isFinite(val)) {
throw new NumberFormatException();
}
validateMinMax(val, Float.MIN_VALUE, Float.MAX_VALUE);
return val;
} catch (NumberFormatException e) {
throw new InvalidCommandArgument(MessageKeys.MUST_BE_A_NUMBER, "{num}", number);
}
}
@Override
public Class<Float> getType() {
return float.class;
}
}
@@ -4,7 +4,6 @@ import net.sacredlabyrinth.phaed.simpleclans.*;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import net.sacredlabyrinth.phaed.simpleclans.utils.VanishUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -35,10 +34,8 @@ public class ClanRoster extends Sendable {
List<ClanPlayer> members = clan.getNonLeaders();
plugin.getClanManager().sortClanPlayersByLastSeen(members);
for (ClanPlayer cp : members) {
Player p = cp.toPlayer();
String name = (cp.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) : sm.getColored(PAGE_UNTRUSTED_COLOR)) + cp.getName();
String lastSeen = p != null && p.isOnline() && !VanishUtils.isVanished(sender, p) ? GREEN + lang("online", sender) : WHITE + cp.getLastSeenDaysString(sender);
String lastSeen = VanishUtils.isVanished(sender, cp) ? WHITE + cp.getLastSeenDaysString(sender) : GREEN + lang("online", sender);
chatBlock.addRow(" " + name, YELLOW + ChatUtils.parseColors(cp.getRankDisplayName()) + RESET, lastSeen);
}
@@ -48,11 +45,9 @@ public class ClanRoster extends Sendable {
List<ClanPlayer> leaders = clan.getLeaders();
plugin.getClanManager().sortClanPlayersByLastSeen(leaders);
for (ClanPlayer cp : leaders) {
Player p = cp.toPlayer();
String name = sm.getColored(PAGE_LEADER_COLOR) + cp.getName();
String lastSeen = p != null && p.isOnline() && !VanishUtils.isVanished(sender, p) ? GREEN + lang("online", sender)
: WHITE + cp.getLastSeenDaysString(sender);
String lastSeen = VanishUtils.isVanished(sender, cp) ? WHITE + cp.getLastSeenDaysString(sender) :
GREEN + lang("online", sender);
chatBlock.addRow(" " + name, YELLOW + ChatUtils.parseColors(cp.getRankDisplayName()) + RESET, lastSeen);
}
@@ -6,6 +6,7 @@ import net.sacredlabyrinth.phaed.simpleclans.Helper;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.utils.KDRFormat;
import net.sacredlabyrinth.phaed.simpleclans.utils.RankingNumberResolver;
import net.sacredlabyrinth.phaed.simpleclans.utils.VanishUtils;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
@@ -37,7 +38,7 @@ public class Leaderboard extends Sendable {
private void addLines() {
for (ClanPlayer cp : clanPlayers) {
boolean online = cp.toPlayer() != null;
boolean online = !VanishUtils.isVanished(cp);
String name = (cp.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) : (cp.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR) :
sm.getColored(PAGE_UNTRUSTED_COLOR))) + cp.getName();
@@ -66,8 +66,8 @@ public class Vitals extends Sendable {
if (p != null) {
String name = (cpm.isLeader() ? sm.getColored(PAGE_LEADER_COLOR) : (cpm.isTrusted() ? sm.getColored(PAGE_TRUSTED_COLOR)
: sm.getColored(PAGE_UNTRUSTED_COLOR))) + cpm.getName();
String health = cm.getHealthString(p.getHealth());
String hunger = cm.getHungerString(p.getFoodLevel());
String health = cm.getBar(p.getHealth());
String hunger = cm.getBar(p.getFoodLevel());
String armor = cm.getArmorString(p.getInventory());
String weapons = cm.getWeaponString(p.getInventory());
String food = cm.getFoodString(p.getInventory());
@@ -52,7 +52,6 @@ public class GeneralCommands extends BaseCommand {
@Default
@Description("{@@command.description.clan}")
@CommandAlias("%clan")
@HelpSearchTags("menu gui interface ui")
public void main(CommandSender sender) {
if (sender instanceof Player && settings.is(ENABLE_GUI)) {
@@ -123,7 +122,7 @@ public class GeneralCommands extends BaseCommand {
@Subcommand("%profile")
@CommandPermission("simpleclans.anyone.profile")
@CommandCompletion("@clans")
@CommandCompletion("@clans:hide_own")
@Description("{@@command.description.profile.other}")
public void profile(CommandSender sender, @Conditions("verified") @Name("clan") ClanInput clan) {
ClanProfile p = new ClanProfile(plugin, sender, clan.getClan());
@@ -131,7 +130,7 @@ public class GeneralCommands extends BaseCommand {
}
@Subcommand("%roster")
@CommandCompletion("@clans")
@CommandCompletion("@clans:hide_own")
@CommandPermission("simpleclans.anyone.roster")
@Description("{@@command.description.roster.other}")
public void roster(CommandSender sender, @Conditions("verified") @Name("clan") ClanInput clan) {
@@ -8,7 +8,10 @@ import net.sacredlabyrinth.phaed.simpleclans.EconomyResponse;
import net.sacredlabyrinth.phaed.simpleclans.commands.ClanInput;
import net.sacredlabyrinth.phaed.simpleclans.events.ClanBalanceUpdateEvent;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLogger;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankOperator;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static net.md_5.bungee.api.ChatColor.RED;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
@@ -19,6 +22,9 @@ import static org.bukkit.ChatColor.AQUA;
@Subcommand("%admin %bank")
public class BankCommand extends BaseCommand {
@Dependency
private PermissionsManager permissions;
@Subcommand("%status")
@CommandPermission("simpleclans.admin.bank.status")
@CommandCompletion("@clans")
@@ -35,12 +41,13 @@ public class BankCommand extends BaseCommand {
public void take(CommandSender sender, @Name("clan") ClanInput clanInput, @Name("amount") double amount) {
Clan clan = clanInput.getClan();
amount = Math.abs(amount);
BankOperator operator = new BankOperator(sender, sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0);
EconomyResponse economyResponse = clan.withdraw(sender, ClanBalanceUpdateEvent.Cause.COMMAND, amount);
EconomyResponse economyResponse = clan.withdraw(operator, ClanBalanceUpdateEvent.Cause.COMMAND, amount);
switch (economyResponse) {
case SUCCESS:
ChatBlock.sendMessage(sender, AQUA + lang("clan.admin.take", sender, amount, clan.getName()));
clan.addBb(sender.getName(), AQUA + lang("bb.clan.take", sender, amount));
clan.addBb(sender.getName(), AQUA + lang("bb.clan.take", sender, amount, sender.getName()));
break;
case NOT_ENOUGH_BALANCE:
sender.sendMessage(RED + lang("clan.admin.bank.not.enough.money", sender, clan.getName()));
@@ -55,11 +62,12 @@ public class BankCommand extends BaseCommand {
public void give(CommandSender sender, @Name("clan") ClanInput clanInput, @Name("amount") double amount) {
Clan clan = clanInput.getClan();
amount = Math.abs(amount);
BankOperator operator = new BankOperator(sender, sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0);
EconomyResponse economyResponse = clan.deposit(sender, ClanBalanceUpdateEvent.Cause.COMMAND, amount);
EconomyResponse economyResponse = clan.deposit(operator, ClanBalanceUpdateEvent.Cause.COMMAND, amount);
if (economyResponse == EconomyResponse.SUCCESS) {
ChatBlock.sendMessage(sender, AQUA + lang("clan.admin.give", sender, amount, clan.getName()));
clan.addBb(sender.getName(), AQUA + lang("bb.clan.give", sender, amount));
clan.addBb(sender.getName(), AQUA + lang("bb.clan.give", sender, amount, sender.getName()));
}
}
@@ -70,11 +78,12 @@ public class BankCommand extends BaseCommand {
public void set(CommandSender sender, @Name("clan") ClanInput clanInput, @Name("amount") double amount) {
Clan clan = clanInput.getClan();
amount = Math.abs(amount);
BankOperator operator = new BankOperator(sender, sender instanceof Player ? permissions.playerGetMoney((Player) sender) : 0);
EconomyResponse response = clan.setBalance(sender, ClanBalanceUpdateEvent.Cause.COMMAND, BankLogger.Operation.SET, amount);
EconomyResponse response = clan.setBalance(operator, ClanBalanceUpdateEvent.Cause.COMMAND, BankLogger.Operation.SET, amount);
if (response == EconomyResponse.SUCCESS) {
ChatBlock.sendMessage(sender, AQUA + lang("clan.admin.set", sender, clan.getName(), amount));
clan.addBb(sender.getName(), AQUA + lang("bb.clan.set", sender, amount));
clan.addBb(sender.getName(), AQUA + lang("bb.clan.set", sender, amount, sender.getName()));
}
}
}
@@ -0,0 +1,59 @@
package net.sacredlabyrinth.phaed.simpleclans.commands.staff;
import org.bukkit.entity.Player;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Conditions;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.Dependency;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Name;
import co.aikar.commands.annotation.Subcommand;
import net.sacredlabyrinth.phaed.simpleclans.ChatBlock;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.commands.ClanInput;
import net.sacredlabyrinth.phaed.simpleclans.managers.ClanManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.StorageManager;
import static org.bukkit.ChatColor.RED;
import static org.bukkit.ChatColor.AQUA;
import static org.bukkit.ChatColor.WHITE;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
@CommandAlias("%clan")
@Conditions("%basic_conditions")
@Subcommand("%mod %bb")
public class BbCommand extends BaseCommand {
@Dependency
private StorageManager storage;
@Dependency
private ClanManager cm;
@Default
@CommandPermission("simpleclans.mod.bb")
@Description("{@@command.description.mod.bb.display}")
public void display(Player sender, @Name("clan") ClanInput input) {
input.getClan().displayBb(sender);
}
@Subcommand("%clear")
@CommandPermission("simpleclans.mod.bb-clear")
@Description("{@@command.description.mod.bb.clear}")
public void clear(Player player, @Name("clan") ClanInput input) {
input.getClan().clearBb();
ChatBlock.sendMessage(player, RED + lang("cleared.bb", player));
}
@Subcommand("%add")
@CommandPermission("simpleclans.mod.bb-add")
@Description("{@@command.description.mod.bb.post}")
public void postMessage(Player player, @Name("clan") ClanInput input, @Name("message") String msg) {
Clan clan = input.getClan();
clan.addBb(player.getName(), AQUA + player.getName() + ": " + WHITE + msg);
storage.updateClan(clan);
}
}
@@ -2,20 +2,22 @@ package net.sacredlabyrinth.phaed.simpleclans.commands.staff;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.*;
import co.aikar.commands.bukkit.contexts.OnlinePlayer;
import net.sacredlabyrinth.phaed.simpleclans.*;
import net.sacredlabyrinth.phaed.simpleclans.commands.ClanInput;
import net.sacredlabyrinth.phaed.simpleclans.commands.ClanPlayerInput;
import net.sacredlabyrinth.phaed.simpleclans.events.PlayerHomeSetEvent;
import net.sacredlabyrinth.phaed.simpleclans.events.TagChangeEvent;
import net.sacredlabyrinth.phaed.simpleclans.language.LanguageResource;
import net.sacredlabyrinth.phaed.simpleclans.managers.*;
import net.sacredlabyrinth.phaed.simpleclans.managers.ClanManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.StorageManager;
import net.sacredlabyrinth.phaed.simpleclans.ui.InventoryController;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import net.sacredlabyrinth.phaed.simpleclans.utils.TagValidator;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -47,31 +49,32 @@ public class StaffCommands extends BaseCommand {
@CommandCompletion("@players @clans")
@HelpSearchTags("move put")
@Description("{@@command.description.place}")
public void place(CommandSender sender, @Name("player") OnlinePlayer onlinePlayer, @Name("clan") ClanInput clan) {
Player player = onlinePlayer.getPlayer();
ClanPlayer oldCp = cm.getClanPlayer(player);
Clan newClanInput = clan.getClan();
public void place(CommandSender sender, @Name("player") ClanPlayerInput cpInput, @Name("clan") ClanInput clanInput) {
UUID uuid = cpInput.getClanPlayer().getUniqueId();
ClanPlayer oldCp = cm.getClanPlayer(uuid);
Clan newClan = clanInput.getClan();
if (oldCp != null) {
Clan oldClan = Objects.requireNonNull(oldCp.getClan());
if (oldClan.equals(newClanInput)) {
if (oldClan.equals(newClan)) {
ChatBlock.sendMessage(sender, lang("player.already.in.this.clan", sender));
return;
}
if (!oldClan.isPermanent() && oldClan.isLeader(player) && oldClan.getLeaders().size() <= 1) {
if (!oldClan.isPermanent() && oldClan.isLeader(uuid) && oldClan.getLeaders().size() <= 1) {
ChatBlock.sendMessage(sender, RED + lang("you.cannot.move.the.last.leader", sender));
return;
} else {
oldClan.addBb(player.getName(), AQUA + lang("0.has.resigned", player.getName()));
oldClan.removePlayerFromClan(player.getUniqueId());
oldClan.addBb(oldCp.getName(), AQUA + lang("0.has.resigned", oldCp.getName()));
oldClan.removePlayerFromClan(uuid);
}
}
ClanPlayer cp = Objects.requireNonNull(cm.getCreateClanPlayerUUID(player.getName()));
ClanPlayer cp = cm.getCreateClanPlayer(uuid);
newClanInput.addBb(AQUA + lang("joined.the.clan", player.getName()));
cm.serverAnnounce(lang("has.joined", player.getName(), newClanInput.getName()));
newClanInput.addPlayerToClan(cp);
newClan.addBb(AQUA + lang("joined.the.clan", cp.getName()));
cm.serverAnnounce(lang("has.joined", cp.getName(), newClan.getName()));
newClan.addPlayerToClan(cp);
}
@Subcommand("%mod %modtag")
@@ -125,11 +128,18 @@ public class StaffCommands extends BaseCommand {
@CommandPermission("simpleclans.mod.home")
@CommandCompletion("@clans")
@Description("{@@command.description.mod.home.set}")
public void homeSet(Player player, @Name("clan") ClanInput clan) {
public void homeSet(Player player, ClanPlayer cp, @Name("clan") ClanInput clanInput) {
Location loc = player.getLocation();
Clan clan = clanInput.getClan();
clan.getClan().setHomeLocation(loc);
ChatBlock.sendMessage(player, AQUA + lang("hombase.mod.set", player, clan.getClan().getName()) + " " +
PlayerHomeSetEvent event = new PlayerHomeSetEvent(clan, cp, loc);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
clan.setHomeLocation(loc);
ChatBlock.sendMessage(player, AQUA + lang("hombase.mod.set", player, clan.getName()) + " " +
ChatColor.YELLOW + Helper.toLocationString(loc));
}
@@ -137,14 +147,7 @@ public class StaffCommands extends BaseCommand {
@CommandCompletion("@clans:has_home")
@CommandPermission("simpleclans.mod.hometp")
@Description("{@@command.description.mod.home.tp}")
public void homeTp(Player player, @Name("clan") ClanInput clan) {
Location loc = clan.getClan().getHomeLocation();
if (loc == null) {
ChatBlock.sendMessage(player, ChatColor.RED + lang("hombase.not.set", player));
return;
}
public void homeTp(Player player, @Name("clan") @Conditions("can_teleport") ClanInput clan) {
plugin.getTeleportManager().teleportToHome(player, clan.getClan());
}
@@ -152,8 +155,8 @@ public class StaffCommands extends BaseCommand {
@CommandPermission("simpleclans.mod.ban")
@CommandCompletion("@players")
@Description("{@@command.description.ban}")
public void ban(CommandSender sender, @Name("player") OfflinePlayer player) {
UUID uuid = player.getUniqueId();
public void ban(CommandSender sender, @Name("player") ClanPlayerInput player) {
UUID uuid = player.getClanPlayer().getUniqueId();
if (settings.isBanned(uuid)) {
ChatBlock.sendMessage(sender, RED + lang("this.player.is.already.banned", sender));
return;
@@ -172,8 +175,8 @@ public class StaffCommands extends BaseCommand {
@CommandPermission("simpleclans.mod.ban")
@CommandCompletion("@players")
@Description("{@@command.description.unban}")
public void unban(CommandSender sender, @Name("player") OfflinePlayer player) {
UUID uuid = player.getUniqueId();
public void unban(CommandSender sender, @Name("player") ClanPlayerInput player) {
UUID uuid = player.getClanPlayer().getUniqueId();
if (!settings.isBanned(uuid)) {
ChatBlock.sendMessage(sender, RED + lang("this.player.is.not.banned", sender));
return;
@@ -255,7 +258,7 @@ public class StaffCommands extends BaseCommand {
public void kick(CommandSender sender, @Conditions("clan_member") @Name("player") ClanPlayerInput cp) {
ClanPlayer clanPlayer = cp.getClanPlayer();
Clan clan = Objects.requireNonNull(clanPlayer.getClan());
if (clan.getLeaders().size() == 1) {
if (clanPlayer.isLeader() && clan.getLeaders().size() == 1) {
ChatBlock.sendMessageKey(sender, "cannot.kick.last.leader");
return;
}
@@ -0,0 +1,57 @@
package net.sacredlabyrinth.phaed.simpleclans.conversation;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.managers.ClanManager;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static org.bukkit.ChatColor.RED;
abstract public class ConfirmationPrompt extends StringPrompt {
protected abstract Prompt confirm(ClanPlayer sender, Clan clan);
protected Prompt decline(ClanPlayer sender) {
return new MessagePromptImpl(RED + lang(getDeclineTextKey(), sender));
}
protected abstract String getPromptTextKey();
protected abstract String getDeclineTextKey();
@NotNull
@Override
public String getPromptText(@NotNull ConversationContext context) {
Player player = (Player) context.getForWhom();
List<String> options = Arrays.asList(lang("yes", player), lang("cancel", player));
return RED + lang(getPromptTextKey(), player, options);
}
@Override
public Prompt acceptInput(@NotNull ConversationContext cc, @Nullable String input) {
final SimpleClans plugin = (SimpleClans) cc.getPlugin();
Player player = (Player) cc.getForWhom();
String yes = lang("yes", player);
ClanManager cm = Objects.requireNonNull(plugin).getClanManager();
ClanPlayer cp = cm.getCreateClanPlayer(player.getUniqueId());
Clan clan = cp.getClan();
if (clan == null) {
return END_OF_CONVERSATION;
}
return yes.equalsIgnoreCase(input) ? confirm(cp, clan) : decline(cp);
}
}
@@ -0,0 +1,28 @@
package net.sacredlabyrinth.phaed.simpleclans.conversation;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import org.bukkit.conversations.Prompt;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static org.bukkit.ChatColor.RED;
public class DisbandPrompt extends ConfirmationPrompt {
@Override
protected Prompt confirm(ClanPlayer sender, Clan clan) {
clan.disband(sender.toPlayer(), true, false);
return new MessagePromptImpl(RED + lang("clan.has.been.disbanded", sender, clan.getName()));
}
@Override
protected String getPromptTextKey() {
return "disband.confirmation";
}
@Override
protected String getDeclineTextKey() {
return "disband.request.cancelled";
}
}
@@ -1,13 +1,14 @@
package net.sacredlabyrinth.phaed.simpleclans.conversation;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.MessagePrompt;
import org.bukkit.conversations.Prompt;
import org.jetbrains.annotations.NotNull;
/**
* @author roinujnosde
*/
public class MessagePromptImpl extends org.bukkit.conversations.MessagePrompt {
public class MessagePromptImpl extends MessagePrompt {
private final String message;
private Prompt nextPrompt;
public MessagePromptImpl(String message) {
@@ -2,17 +2,7 @@ package net.sacredlabyrinth.phaed.simpleclans.conversation;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.managers.ClanManager;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Objects;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static org.bukkit.ChatColor.AQUA;
@@ -21,45 +11,31 @@ import static org.bukkit.ChatColor.RED;
/**
* @author roinujnosde
*/
public class ResignPrompt extends StringPrompt {
public class ResignPrompt extends ConfirmationPrompt {
@Override
public Prompt acceptInput(ConversationContext cc, String input) {
final SimpleClans plugin = (SimpleClans) cc.getPlugin();
protected Prompt confirm(ClanPlayer sender, Clan clan) {
if (clan.isPermanent() || !sender.isLeader() || clan.getLeaders().size() > 1) {
clan.addBb(sender.getName(), AQUA + lang("0.has.resigned", sender.getName()));
sender.addResignTime(clan.getTag());
clan.removePlayerFromClan(sender.getUniqueId());
Player player = (Player) cc.getForWhom();
String yes = lang("yes", player);
ClanManager cm = Objects.requireNonNull(plugin).getClanManager();
ClanPlayer cp = cm.getCreateClanPlayer(player.getUniqueId());
Clan clan = cp.getClan();
if (clan == null) {
return END_OF_CONVERSATION;
}
if (yes.equalsIgnoreCase(input)) {
if (clan.isPermanent() || !clan.isLeader(player) || clan.getLeaders().size() > 1) {
clan.addBb(player.getName(), AQUA + lang("0.has.resigned", player.getName()));
cp.addResignTime(clan.getTag());
clan.removePlayerFromClan(player.getUniqueId());
return new MessagePromptImpl(AQUA + lang("resign.success", player));
} else if (clan.isLeader(player) && clan.getLeaders().size() == 1) {
clan.disband(player, true, false);
return new MessagePromptImpl(RED + lang("clan.has.been.disbanded", player, clan.getName()));
} else {
return new MessagePromptImpl(RED + lang("last.leader.cannot.resign.you.must.appoint.another.leader.or.disband.the.clan", player));
}
return new MessagePromptImpl(AQUA + lang("resign.success", sender));
} else if (sender.isLeader() && clan.getLeaders().size() == 1) {
clan.disband(sender.toPlayer(), true, false);
return new MessagePromptImpl(RED + lang("clan.has.been.disbanded", sender, clan.getName()));
} else {
return new MessagePromptImpl(RED + lang("resign.request.cancelled", player));
return new MessagePromptImpl(RED + lang("last.leader.cannot.resign.you.must.appoint.another.leader.or.disband.the.clan", sender));
}
}
@Override
public @NotNull String getPromptText(@NotNull ConversationContext cc) {
Player player = (Player) cc.getForWhom();
return RED + MessageFormat.format(
lang("resign.confirmation", player), Arrays.asList(
lang("yes", player), lang("cancel", player)));
protected String getPromptTextKey() {
return "resign.confirmation";
}
@Override
protected String getDeclineTextKey() {
return "resign.request.cancelled";
}
}
@@ -1,25 +1,24 @@
package net.sacredlabyrinth.phaed.simpleclans.events;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import org.bukkit.command.CommandSender;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankOperator;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ClanBalanceUpdateEvent extends Event implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final CommandSender updater;
private final BankOperator updater;
private final Clan clan;
private final Cause cause;
private final double balance;
private double newBalance;
private boolean cancelled;
public ClanBalanceUpdateEvent(@Nullable CommandSender updater,
public ClanBalanceUpdateEvent(@NotNull BankOperator updater,
@NotNull Clan clan,
double balance,
double newBalance,
@@ -32,9 +31,9 @@ public class ClanBalanceUpdateEvent extends Event implements Cancellable {
}
/**
* @return the balance updater, may be null
* @return the balance updater
*/
public @Nullable CommandSender getUpdater() {
public @NotNull BankOperator getUpdater() {
return updater;
}
@@ -115,6 +114,10 @@ public class ClanBalanceUpdateEvent extends Event implements Cancellable {
* When the balance is updated via API methods
*/
API,
/**
* WHen the balance is updated via Internal methods
*/
INTERNAL,
/**
* When the clan data is being loaded and the balance is set, usually on server start up or plugin reload
*/
@@ -0,0 +1,54 @@
package net.sacredlabyrinth.phaed.simpleclans.events;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import org.bukkit.Location;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class ClanPlayerTeleportEvent extends Event implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancelled;
private final ClanPlayer player;
private final Location origin;
private final Location destination;
public ClanPlayerTeleportEvent(ClanPlayer player, Location origin, Location destination) {
this.player = player;
this.origin = origin;
this.destination = destination;
}
@Override
public @NotNull HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
public ClanPlayer getClanPlayer() {
return player;
}
public Location getOrigin() {
return origin;
}
public Location getDestination() {
return destination;
}
}
@@ -1,6 +1,9 @@
package net.sacredlabyrinth.phaed.simpleclans.events;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@@ -11,9 +14,14 @@ import org.bukkit.event.HandlerList;
public class DisbandClanEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private final CommandSender sender;
private final Clan clan;
public DisbandClanEvent(Clan clan) {
public DisbandClanEvent(CommandSender sender, Clan clan) {
if (sender == null) {
sender = Bukkit.getConsoleSender();
}
this.sender = sender;
this.clan = clan;
}
@@ -21,6 +29,10 @@ public class DisbandClanEvent extends Event {
return this.clan;
}
public CommandSender getSender() {
return sender;
}
@Override
public HandlerList getHandlers() {
return handlers;
@@ -50,12 +50,16 @@ public class HomeRegroupEvent extends Event implements Cancellable {
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
@@ -0,0 +1,51 @@
package net.sacredlabyrinth.phaed.simpleclans.events;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerHomeClearEvent extends Event implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Clan clan;
private final ClanPlayer cp;
private boolean cancelled;
public PlayerHomeClearEvent(Clan clan, ClanPlayer cp) {
this.clan = clan;
this.cp = cp;
}
public Clan getClan() {
return clan;
}
public ClanPlayer getCp() {
return cp;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -1,4 +1,4 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks;
package net.sacredlabyrinth.phaed.simpleclans.hooks.discord;
import github.scarsz.discordsrv.DiscordSRV;
import github.scarsz.discordsrv.api.Subscribe;
@@ -9,6 +9,8 @@ import github.scarsz.discordsrv.dependencies.commons.lang3.StringUtils;
import github.scarsz.discordsrv.dependencies.emoji.EmojiParser;
import github.scarsz.discordsrv.dependencies.jda.api.Permission;
import github.scarsz.discordsrv.dependencies.jda.api.entities.*;
import github.scarsz.discordsrv.dependencies.jda.api.exceptions.ErrorResponseException;
import github.scarsz.discordsrv.dependencies.jda.api.requests.Response;
import github.scarsz.discordsrv.dependencies.jda.api.requests.RestAction;
import github.scarsz.discordsrv.dependencies.kyori.adventure.text.Component;
import github.scarsz.discordsrv.objects.managers.AccountLinkManager;
@@ -18,6 +20,7 @@ import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.events.*;
import net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions.*;
import net.sacredlabyrinth.phaed.simpleclans.managers.ChatManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.ClanManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager;
@@ -33,12 +36,13 @@ import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.stream.Collectors;
import static github.scarsz.discordsrv.dependencies.jda.api.Permission.MANAGE_CHANNEL;
import static github.scarsz.discordsrv.dependencies.jda.api.Permission.VIEW_CHANNEL;
import static net.sacredlabyrinth.phaed.simpleclans.ClanPlayer.Channel.CLAN;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.DISCORD;
import static net.sacredlabyrinth.phaed.simpleclans.hooks.DiscordHook.DiscordAction.ADD;
import static net.sacredlabyrinth.phaed.simpleclans.hooks.DiscordHook.DiscordAction.REMOVE;
import static net.sacredlabyrinth.phaed.simpleclans.hooks.discord.DiscordHook.DiscordAction.ADD;
import static net.sacredlabyrinth.phaed.simpleclans.hooks.discord.DiscordHook.DiscordAction.REMOVE;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*;
/**
@@ -56,7 +60,7 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con
* <ul>
* <li>Clan creation/deletion</li>
* <li>ClanPlayer joining/resigning</li>
* <li>Player linking</li>
* <li>Player linking/unlinking</li>
* <li>ClanPlayer promoting/demoting</li>
* </ul>
* <p>
@@ -78,6 +82,7 @@ public class DiscordHook implements Listener {
private final List<String> discordClanTags;
private final List<String> clanTags;
private final Role leaderRole;
private final List<String> whitelist;
public DiscordHook(SimpleClans plugin) {
this.plugin = plugin;
@@ -86,21 +91,10 @@ public class DiscordHook implements Listener {
clanManager = plugin.getClanManager();
textCategories = settingsManager.getStringList(DISCORDCHAT_TEXT_CATEGORY_IDS).stream().
filter(this::categoryExists).collect(Collectors.toList());
whitelist = settingsManager.getStringList(DISCORDCHAT_TEXT_WHITELIST);
List<String> whitelist = settingsManager.getStringList(DISCORDCHAT_TEXT_WHITELIST);
clanTags = clanManager.getClans().stream().
filter(Clan::isVerified).
filter(clan -> clan.getMembers().stream().
anyMatch(clanPlayer -> getMember(clanPlayer) != null) || clan.isPermanent()).
map(Clan::getTag).
filter(clanTag -> whitelist.isEmpty() || whitelist.contains(clanTag)).
limit(settingsManager.getInt(DISCORDCHAT_TEXT_LIMIT)).
collect(Collectors.toList());
discordClanTags = getChannels().stream().
map(GuildChannel::getName).
collect(Collectors.toList());
clanTags = clanManager.getClans().stream().map(Clan::getTag).collect(Collectors.toList());
discordClanTags = getCachedChannels().stream().map(GuildChannel::getName).collect(Collectors.toList());
leaderRole = getLeaderRole();
setupDiscord();
@@ -108,7 +102,7 @@ public class DiscordHook implements Listener {
@Subscribe
public void onMessageReceived(DiscordGuildMessageReceivedEvent event) {
Optional<TextChannel> channel = getChannel(event.getChannel().getName());
Optional<TextChannel> channel = getCachedChannel(event.getChannel().getName());
if (channel.isPresent()) {
Message eventMessage = event.getMessage();
@@ -136,7 +130,7 @@ public class DiscordHook implements Listener {
sendPrivateMessage(textChannel, eventMessage, lang("cannot.send.discord.message", clanPlayer, channelLink));
return;
}
// DiscordSRV start
String emojiBehavior = DiscordSRV.config().getString("DiscordChatChannelEmojiBehavior");
boolean hideEmoji = emojiBehavior.equalsIgnoreCase("hide");
@@ -159,7 +153,7 @@ public class DiscordHook implements Listener {
// parse emojis from unicode back to :code:
message = EmojiParser.parseToAliases(message);
}
// DiscordSRV end
chatManager.processChat(DISCORD, CLAN, clanPlayer, message);
}
}
@@ -171,58 +165,102 @@ public class DiscordHook implements Listener {
@EventHandler
public void onClanCreate(CreateClanEvent event) {
createChannel(event.getClan().getTag());
try {
if (settingsManager.is(DISCORDCHAT_AUTO_CREATION)) {
createChannel(event.getClan().getTag());
}
} catch (DiscordHookException ex) {
// Clan is not following the conditions, categories are fulled or discord reaches the limit, nothing to do here.
SimpleClans.debug(ex.getMessage());
}
}
@EventHandler
public void onPlayerClanLeave(PlayerKickedClanEvent event) {
ClanPlayer clanPlayer = event.getClanPlayer();
Clan clan = event.getClan();
Member member = getMember(clanPlayer);
if (member == null || clan == null) {
return;
}
updatePermissions(clanPlayer, REMOVE);
updateRole(clanPlayer, REMOVE);
updateViewPermission(member, clan, REMOVE);
updateLeaderRole(member, clanPlayer, REMOVE);
}
@EventHandler
public void onPlayerClanJoin(PlayerJoinedClanEvent event) {
ClanPlayer clanPlayer = event.getClanPlayer();
Clan clan = event.getClan();
Member member = getMember(clanPlayer);
if (member == null || clan == null) {
return;
}
updatePermissions(clanPlayer, ADD);
updateRole(clanPlayer, ADD);
if (!createChannelSilently(clanPlayer)) {
return;
}
updateViewPermission(member, clan, ADD);
}
@EventHandler
public void onPlayerPromote(PlayerPromoteEvent event) {
updateRole(event.getClanPlayer(), ADD);
ClanPlayer clanPlayer = event.getClanPlayer();
Member member = getMember(clanPlayer);
if (member == null) {
return;
}
updateLeaderRole(member, clanPlayer, ADD);
}
@EventHandler
public void onPlayerDemote(PlayerDemoteEvent event) {
updateRole(event.getClanPlayer(), REMOVE);
ClanPlayer clanPlayer = event.getClanPlayer();
Member member = getMember(clanPlayer);
if (member == null) {
return;
}
updateLeaderRole(member, clanPlayer, REMOVE);
}
@Subscribe
public void onPlayerLinking(AccountLinkedEvent event) {
ClanPlayer clanPlayer = clanManager.getClanPlayer(event.getPlayer());
if (clanPlayer == null) {
Member member = guild.getMember(event.getUser());
if (clanPlayer == null || member == null) {
return;
}
updatePermissions(clanPlayer, ADD);
Clan clan = clanPlayer.getClan();
if (clan == null) {
return;
}
if (!createChannelSilently(clanPlayer)) {
return;
}
updateViewPermission(member, clan, ADD);
updateLeaderRole(member, clanPlayer, ADD);
}
@Subscribe
public void onPlayerUnlinking(AccountUnlinkedEvent event) {
ClanPlayer clanPlayer = clanManager.getClanPlayer(event.getPlayer());
if (clanPlayer == null) {
Member member = guild.getMember(event.getDiscordUser());
if (clanPlayer == null || clanPlayer.getClan() == null || member == null) {
return;
}
updatePermissions(clanPlayer, REMOVE);
guild.removeRoleFromMember(event.getDiscordId(), leaderRole).queue();
updateViewPermission(member, clanPlayer.getClan(), REMOVE);
updateLeaderRole(member, clanPlayer, REMOVE);
}
protected void setupDiscord() {
removeInvalidChannels();
clearChannels();
resetPermissions();
createChannels();
}
@@ -291,6 +329,9 @@ public class DiscordHook implements Listener {
guild.getPublicRole().getIdLong(),
Collections.emptyList(),
Collections.singletonList(VIEW_CHANNEL)).
addMemberPermissionOverride(guild.getSelfMember().getIdLong(),
Arrays.asList(VIEW_CHANNEL, MANAGE_CHANNEL),
Collections.emptyList()).
submit().get();
textCategories.add(category.getId());
@@ -305,83 +346,123 @@ public class DiscordHook implements Listener {
}
/**
* Creates a new {@link ClanPlayer.Channel} in available categories,
* otherwise creates one
* Creates a new {@link TextChannel} in available SimpleClans' categories,
* otherwise creates one.
*
* <p>Sets positive {@link Permission#VIEW_CHANNEL} permission to all linked clan members.</p>
*
* @param clanTag the clan tag
*
* @throws InvalidChannelException clan is not verified or permanent,
* no one member is linked or clan is not in the whitelist.
* @throws ChannelExistsException if channel is already exist
* @throws CategoriesLimitException if categories reached the limit.
* @throws ChannelsLimitException if discord reached the channels limit.
*/
public boolean createChannel(@NotNull String clanTag) {
Category availableCategory = getCategories().stream().
public void createChannel(@NotNull String clanTag)
throws InvalidChannelException, CategoriesLimitException, ChannelsLimitException, ChannelExistsException {
validateChannel(clanTag);
Map<ClanPlayer, Member> discordClanPlayers = getDiscordPlayers(clanManager.getClan(clanTag));
if (getChannels().size() >= settingsManager.getInt(DISCORDCHAT_TEXT_LIMIT)) {
throw new ChannelsLimitException("Discord reached the channels limit", "discord.reached.channels.limit");
}
Category availableCategory = getCachedCategories().stream().
filter(category -> category.getTextChannels().size() < MAX_CHANNELS_PER_CATEGORY).
findAny().orElseGet(this::createCategory);
return availableCategory != null && createChannel(availableCategory, clanTag);
if (availableCategory == null) {
throw new CategoriesLimitException("Discord reached the categories limit", "discord.reached.category.limit");
}
try {
availableCategory.createTextChannel(clanTag).complete();
} catch (ErrorResponseException ex) {
Response response = ex.getResponse();
plugin.getLogger().warning(String.format("Could not create a channel for clan %s, error %d - %s",
clanTag, response.code, response.message));
return;
}
for (Map.Entry<ClanPlayer, Member> entry : discordClanPlayers.entrySet()) {
// The map is formed from clan#getMembers (so the clan exists)
//noinspection ConstantConditions
updateViewPermission(entry.getValue(), entry.getKey().getClan(), ADD);
updateLeaderRole(entry.getValue(), entry.getKey(), ADD);
}
}
/**
* Retrieves channel in SimpleClans categories.
*
* @see #getCategories() retreive categories.
* @param channelName the channel name
*
* @see #getCachedCategories() retreive categories.
*
* @return the channel
*/
public Optional<TextChannel> getChannel(@NotNull String channelName) {
return getChannels().stream().filter(textChannel -> textChannel.getName().equals(channelName)).findFirst();
public Optional<TextChannel> getCachedChannel(@NotNull String channelName) {
return getCachedChannels().stream().filter(textChannel -> textChannel.getName().equals(channelName)).findFirst();
}
/**
* Checks if category can be obtained by id.
* Checks if a category can be obtained by id.
*
* @param categoryId the category id
* @see #channelExists(String)
*
* @return true if the category exists
*/
public boolean categoryExists(String categoryId) {
return guild.getCategoryById(categoryId) != null;
}
/**
* Creates a new {@link ClanPlayer.Channel} in defined {@link Category}
* Checks if a channel with the specified clan tag exists
*
* <p>Sets {@link Permission#VIEW_CHANNEL} permission to all linked clan members.</p>
*
* @return true, if channel was created. False, if category reached the limit.
* @see #categoryExists(String)
*/
public boolean createChannel(@NotNull Category category, @NotNull String clanTag) {
if (category.getTextChannels().size() >= MAX_CHANNELS_PER_CATEGORY) {
return false;
}
TextChannel textChannel = category.createTextChannel(clanTag).complete();
Clan clan = clanManager.getClan(clanTag);
if (clan != null) {
for (ClanPlayer member : clan.getMembers()) {
updatePermissions(member, ADD);
}
}
return true;
public boolean channelExists(String clanTag) {
return getChannels().stream().map(TextChannel::getName).anyMatch(name -> name.equals(clanTag));
}
/**
* Deletes channel from SimpleClans categories.
* If there are no channels, removes category as well.
*
* @param channelName the channel name
*
* @return true, if channel was deleted and false if not.
*/
public void deleteChannel(@NotNull String channelName) {
for (Category category : getCategories()) {
if (category.getTextChannels().size() > 0) {
for (TextChannel textChannel : category.getTextChannels()) {
if (textChannel.getName().equals(channelName)) {
textChannel.delete().complete();
@SuppressWarnings("UnusedReturnValue")
public boolean deleteChannel(@NotNull String channelName) {
if (channelExists(channelName)) {
for (Category category : getCachedCategories()) {
if (category.getTextChannels().size() > 0) {
for (TextChannel textChannel : category.getTextChannels()) {
if (textChannel.getName().equals(channelName)) {
textChannel.delete().complete();
return true;
}
}
}
if (category.getTextChannels().size() == 0) {
textCategories.remove(category.getId());
settingsManager.set(DISCORDCHAT_TEXT_CATEGORY_IDS, textCategories);
settingsManager.save();
category.delete().complete();
if (category.getTextChannels().size() == 0) {
textCategories.remove(category.getId());
settingsManager.set(DISCORDCHAT_TEXT_CATEGORY_IDS, textCategories);
settingsManager.save();
category.delete().complete();
}
}
}
}
return false;
}
/**
* @return All categories, which contains in configuration.
* @return categories from config
*/
public List<Category> getCategories() {
public List<Category> getCachedCategories() {
return textCategories.stream().
filter(this::categoryExists).
map(guild::getCategoryById).
@@ -389,47 +470,91 @@ public class DiscordHook implements Listener {
}
/**
* @return All channels in categories
* In most cases, you will use {@link #getCachedCategories()}.
*
* @return categories from guild
*/
public List<Category> getCategories() {
return guild.getCategoriesByName(settingsManager.getString(DISCORDCHAT_TEXT_CATEGORY_FORMAT), false);
}
/**
* In most cases, you will use {@link #getCachedChannels()}.
*
* @return all channels from guild
*/
public List<TextChannel> getChannels() {
return getCategories().stream().map(Category::getTextChannels).flatMap(Collection::stream).
collect(Collectors.toList());
}
/**
* @return All channels in categories
*/
public List<TextChannel> getCachedChannels() {
return getCachedCategories().stream().map(Category::getTextChannels).flatMap(Collection::stream).
collect(Collectors.toList());
}
@Nullable
public Member getMember(@NotNull ClanPlayer clanPlayer) {
String discordId = accountManager.getDiscordId(clanPlayer.getUniqueId());
return DiscordUtil.getMemberById(discordId);
}
private void removeInvalidChannels() {
private void clearChannels() {
// Removes abandoned channels
ArrayList<String> clansToDelete = new ArrayList<>(discordClanTags);
clansToDelete.removeAll(clanTags);
clansToDelete.forEach(this::deleteChannel);
// Removes invalid channels
for (String clanTag : clanTags) {
try {
validateChannel(clanTag);
} catch (InvalidChannelException ex) {
SimpleClans.debug(ex.getMessage());
deleteChannel(clanTag);
} catch (ChannelExistsException | ChannelsLimitException ex) {
SimpleClans.debug(ex.getMessage());
}
}
}
private void resetPermissions() {
getChannels().stream().
getCachedChannels().stream().
map(TextChannel::getMemberPermissionOverrides).
flatMap(Collection::stream).
filter(permissionOverride -> !Objects.equals(permissionOverride.getPermissionHolder(), guild.getPublicRole())).
filter(permissionOverride -> !Objects.equals(permissionOverride.getMember(), guild.getSelfMember())).
forEach(permissionOverride -> permissionOverride.delete().queue());
clanTags.stream().map(clanManager::getClan).
filter(Objects::nonNull).
map(Clan::getMembers).
flatMap(Collection::stream).
forEach(clanPlayer -> updatePermissions(clanPlayer, ADD));
forEach(clanPlayer -> {
Member member = getMember(clanPlayer);
Clan clan = clanPlayer.getClan();
if (member != null && clan != null) {
updateViewPermission(member, clan, ADD);
}
});
}
private void createChannels() {
clanTags.removeAll(discordClanTags);
Iterator<String> tagIter = clanTags.iterator();
while (tagIter.hasNext()) {
if (createChannel(tagIter.next())) {
tagIter.remove();
} else {
if (!settingsManager.is(DISCORDCHAT_AUTO_CREATION)) {
return;
}
for (String clan : clanTags) {
try {
createChannel(clan);
} catch (CategoriesLimitException | ChannelsLimitException ex) {
SimpleClans.debug(ex.getMessage());
break;
} catch (InvalidChannelException | ChannelExistsException ignored) {
// There is already debug on #clearChannels
}
}
}
@@ -437,15 +562,56 @@ public class DiscordHook implements Listener {
@SuppressWarnings("ResultOfMethodCallIgnored")
private void sendPrivateMessage(TextChannel textChannel, Message eventMessage, String message) {
RestAction<PrivateChannel> privateChannelAction = eventMessage.getAuthor().openPrivateChannel();
textChannel.deleteMessageById(eventMessage.getId()).queue(unused -> {
String channelLink = "<#" + textChannel.getId() + ">";
privateChannelAction.flatMap(privateChannel -> privateChannel.sendMessage(message));
});
textChannel.deleteMessageById(eventMessage.getId()).queue(unused ->
privateChannelAction.flatMap(privateChannel -> privateChannel.sendMessage(message)));
}
private void updateRole(ClanPlayer clanPlayer, DiscordAction action) {
Member member = getMember(clanPlayer);
if (member == null) {
private void validateChannel(@NotNull String clanTag)
throws InvalidChannelException, ChannelExistsException, ChannelsLimitException {
Clan clan = clanManager.getClan(clanTag);
if (clan == null) {
throw new InvalidChannelException(String.format("Clan %s is null", clanTag));
}
if (!clan.isVerified() && !clan.isPermanent()) {
throw new InvalidChannelException(String.format("Clan %s is not verified or permanent", clanTag));
}
Map<ClanPlayer, Member> discordClanPlayers = getDiscordPlayers(clan);
if (discordClanPlayers.size() == 0) {
throw new InvalidChannelException(String.format("Clan %s doesn't have any linked players", clanTag),
"your.clan.doesnt.have.any.linked.player");
}
if (discordClanPlayers.size() < settingsManager.getInt(DISCORDCHAT_MINIMUM_LINKED_PLAYERS)) {
throw new InvalidChannelException(String.format("Clan %s doesn't have minimum linked players", clanTag),
"your.clan.doesnt.have.minimum.linked.player");
}
if (!whitelist.isEmpty() && !whitelist.contains(clan.getTag())) {
throw new InvalidChannelException(String.format("Clan %s is not listed on the whitelist", clanTag),
"your.clan.is.not.on.the.whitelist");
}
if (channelExists(clanTag)) {
throw new ChannelExistsException(String.format("Channel %s is already exist", clanTag),
"your.clan.already.has.channel");
}
}
@NotNull
private Map<ClanPlayer, Member> getDiscordPlayers(@NotNull Clan clan) {
Map<ClanPlayer, Member> discordClanPlayers = new HashMap<>();
for (ClanPlayer cp : clan.getMembers()) {
Member member = getMember(cp);
if (member != null) {
discordClanPlayers.put(cp, member);
}
}
return discordClanPlayers;
}
private void updateLeaderRole(@NotNull Member member, @NotNull ClanPlayer clanPlayer, DiscordAction action) {
if (!clanPlayer.isLeader()) {
return;
}
@@ -456,14 +622,8 @@ public class DiscordHook implements Listener {
}
}
private void updatePermissions(@NotNull ClanPlayer clanPlayer, DiscordAction action) {
Clan clan = clanPlayer.getClan();
Member member = getMember(clanPlayer);
if (clan == null || member == null) {
return;
}
Optional<TextChannel> channel = getChannel(clan.getTag());
private void updateViewPermission(@NotNull Member member, @NotNull Clan clan, DiscordAction action) {
Optional<TextChannel> channel = getCachedChannel(clan.getTag());
if (channel.isPresent()) {
TextChannel textChannel = channel.get();
@@ -476,6 +636,23 @@ public class DiscordHook implements Listener {
}
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean createChannelSilently(ClanPlayer clanPlayer) {
Clan clan = clanPlayer.getClan();
if (clan == null || !settingsManager.is(DISCORDCHAT_AUTO_CREATION)) {
return false;
}
try {
createChannel(clan.getTag());
} catch (DiscordHookException ex) {
// Clan is not following the conditions, categories are fulled or discord reaches the limit, nothing to do here.
SimpleClans.debug(ex.getMessage());
}
return true;
}
enum DiscordAction {
ADD, REMOVE
}
@@ -0,0 +1,8 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions;
public class CategoriesLimitException extends DiscordHookException {
public CategoriesLimitException(String debugMessage, String messageKey) {
super(debugMessage, messageKey);
}
}
@@ -0,0 +1,8 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions;
public class ChannelExistsException extends DiscordHookException {
public ChannelExistsException(String debugMessage, String messageKey) {
super(debugMessage, messageKey);
}
}
@@ -0,0 +1,8 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions;
public class ChannelsLimitException extends DiscordHookException {
public ChannelsLimitException(String debugMessage, String messageKey) {
super(debugMessage, messageKey);
}
}
@@ -0,0 +1,32 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions;
import org.jetbrains.annotations.Nullable;
/**
* Superclass of all discord exceptions
*
* @see InvalidChannelException
* @see ChannelsLimitException
* @see ChannelExistsException
* @see CategoriesLimitException
*/
public class DiscordHookException extends Exception {
private String messageKey;
public DiscordHookException(String debugMessage) {
super(debugMessage);
}
public DiscordHookException(String debugMessage, String messageKey) {
super(debugMessage);
this.messageKey = messageKey;
}
/**
* @return message key or null if this key is not used in-game
*/
public @Nullable String getMessageKey() {
return messageKey;
}
}
@@ -0,0 +1,12 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.discord.exceptions;
public class InvalidChannelException extends DiscordHookException {
public InvalidChannelException(String debugMessage, String messageKey) {
super(debugMessage, messageKey);
}
public InvalidChannelException(String debugMessage) {
super(debugMessage);
}
}
@@ -31,6 +31,8 @@ public abstract class PlaceholderResolver {
* @param method the annotated method
* @param placeholder the placeholder to resolve
* @param config configuration for the resolver
*
* @return the resolved placeholder
*/
@NotNull
public abstract String resolve(@Nullable OfflinePlayer player, @NotNull Object object, @NotNull Method method,
@@ -1,5 +1,6 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.papi;
import me.clip.placeholderapi.expansion.Configurable;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Relational;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
@@ -20,9 +21,7 @@ import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.bukkit.ChatColor.*;
public class SimpleClansExpansion extends PlaceholderExpansion implements Relational {
public class SimpleClansExpansion extends PlaceholderExpansion implements Relational, Configurable {
private static final Pattern TOP_CLANS_PATTERN = Pattern.compile("(?<strip>^topclans_(?<position>\\d+)_)clan_");
private static final Pattern TOP_PLAYERS_PATTERN = Pattern.compile("(?<strip>^topplayers_(?<position>\\d+)_)");
@@ -77,6 +76,18 @@ public class SimpleClansExpansion extends PlaceholderExpansion implements Relati
return true;
}
@Override
public Map<String, Object> getDefaults() {
Map<String, Object> defaults = new HashMap<>();
defaults.put("color.rival", "&c");
defaults.put("color.ally", "&b");
defaults.put("color.same_clan", "&a");
return defaults;
}
@Override
@Nullable
public String onPlaceholderRequest(Player player1, Player player2, String params) {
@@ -90,13 +101,13 @@ public class SimpleClansExpansion extends PlaceholderExpansion implements Relati
}
//noinspection ConstantConditions -- getClanPlayer != null == getClan() != null
if (cp1.getClan().isMember(player2)) {
return GREEN.toString();
return getString("color.same_clan", null);
}
if (cp1.isRival(player2)) {
return RED.toString();
return getString("color.rival", null);
}
if (cp1.isAlly(player2)) {
return AQUA.toString();
return getString("color.ally", null);
}
return "";
}
@@ -0,0 +1,43 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.protection;
import org.bukkit.Location;
import java.util.Objects;
public class Coordinate {
private final double x;
private final double z;
public Coordinate(double x, double z) {
this.x = x;
this.z = z;
}
public Coordinate(Location location) {
this.x = location.getX();
this.z = location.getZ();
}
public double getX() {
return x;
}
public double getZ() {
return z;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinate that = (Coordinate) o;
return Double.compare(that.getX(), getX()) == 0 && Double.compare(that.getZ(), getZ()) == 0;
}
@Override
public int hashCode() {
return Objects.hash(getX(), getZ());
}
}
@@ -2,18 +2,22 @@ package net.sacredlabyrinth.phaed.simpleclans.hooks.protection;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.*;
public class Land {
private final String id;
private final Set<UUID> owners;
private final List<Coordinate> coordinates;
public Land(@NotNull String id, @NotNull Set<UUID> owners) {
this(id, owners, Collections.emptyList());
}
public Land(@NotNull String id, @NotNull Set<UUID> owners, @NotNull List<Coordinate> coordinates) {
this.id = id;
this.owners = owners;
this.coordinates = coordinates;
}
@NotNull
@@ -26,6 +30,10 @@ public class Land {
return owners;
}
public @NotNull List<Coordinate> getCoordinates() {
return coordinates;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -1,5 +1,6 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.protection;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
@@ -12,6 +13,10 @@ import java.util.Set;
public interface ProtectionProvider {
default void register() {
SimpleClans.getInstance().getProtectionManager().registerProvider(this);
}
void setup() throws LinkageError, Exception;
@NotNull
@@ -4,8 +4,10 @@ import me.ryanhamshire.GriefPrevention.Claim;
import me.ryanhamshire.GriefPrevention.DataStore;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
import me.ryanhamshire.GriefPrevention.events.ClaimCreatedEvent;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Coordinate;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Land;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.ProtectionProvider;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
@@ -14,19 +16,13 @@ import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.debug;
import java.util.*;
@SuppressWarnings("unused")
public class GriefPreventionProvider implements ProtectionProvider {
@Override
public void setup() throws NoSuchMethodException {
//noinspection ResultOfMethodCallIgnored
Claim.class.getMethod("getOwnerID");
public void setup() {
}
@Override
@@ -38,16 +34,6 @@ public class GriefPreventionProvider implements ProtectionProvider {
return Collections.singleton(getLand(claim));
}
@Nullable
private Land getLand(@Nullable Claim claim) {
if (claim == null) {
return null;
}
debug(String.format("id %s name %s uuid %s", claim.getID(), claim.getOwnerName(), claim.getOwnerID()));
return new Land(getIdPrefix() + claim.getID().toString(), Collections.singleton(claim.getOwnerID()));
}
@Override
public @NotNull Set<Land> getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) {
HashSet<Land> lands = new HashSet<>();
@@ -76,7 +62,11 @@ public class GriefPreventionProvider implements ProtectionProvider {
@Override
public @Nullable Class<? extends Event> getCreateLandEvent() {
return ClaimCreatedEvent.class;
try {
return ClaimCreatedEvent.class;
} catch (NoClassDefFoundError error) {
return null;
}
}
@Override
@@ -93,4 +83,25 @@ public class GriefPreventionProvider implements ProtectionProvider {
public @Nullable String getRequiredPluginName() {
return "GriefPrevention";
}
@Nullable
private Land getLand(@Nullable Claim claim) {
if (claim == null) {
return null;
}
List<Coordinate> coords = Arrays.asList(new Coordinate(claim.getLesserBoundaryCorner()),
new Coordinate(claim.getGreaterBoundaryCorner()));
return new Land(getIdPrefix() + claim.getID().toString(), Collections.singleton(getOwnerID(claim)), coords);
}
@SuppressWarnings("deprecation")
@NotNull
private UUID getOwnerID(@NotNull Claim claim) {
try {
return claim.getOwnerID();
} catch (NoSuchMethodError error) {
return Bukkit.getOfflinePlayer(claim.getOwnerName()).getUniqueId();
}
}
}
@@ -0,0 +1,91 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.protection.providers;
import biz.princeps.landlord.api.ILandLord;
import biz.princeps.landlord.api.IOwnedLand;
import biz.princeps.landlord.api.events.LandPreClaimEvent;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Land;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.ProtectionProvider;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@SuppressWarnings("unused")
public class Landlord4Provider implements ProtectionProvider {
private ILandLord landlord;
@Override
public void setup() throws LinkageError, Exception {
//noinspection ConstantConditions
landlord = (ILandLord) Bukkit.getPluginManager().getPlugin("Landlord");
}
@Override
public @NotNull Set<Land> getLandsAt(@NotNull Location location) {
IOwnedLand ownedLand = landlord.getWGManager().getRegion(location);
if (ownedLand == null) {
return Collections.emptySet();
}
HashSet<Land> lands = new HashSet<>();
lands.add(getLand(ownedLand));
return lands;
}
@Override
public @NotNull Set<Land> getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) {
HashSet<Land> lands = new HashSet<>();
Set<IOwnedLand> ownedLands = landlord.getWGManager().getRegions(player.getUniqueId(), world);
for (IOwnedLand ownedLand : ownedLands) {
lands.add(getLand(ownedLand));
}
return lands;
}
@Override
public @NotNull String getIdPrefix() {
return "ll";
}
@Override
public void deleteLand(@NotNull String id, @NotNull World world) {
id = id.replace(getIdPrefix(), "");
landlord.getWGManager().unclaim(world, id);
}
@Override
public @Nullable Class<? extends Event> getCreateLandEvent() {
return LandPreClaimEvent.class;
}
@Override
public @Nullable Player getPlayer(Event event) {
if (!(event instanceof LandPreClaimEvent)) {
return null;
}
return ((LandPreClaimEvent) event).getPlayer();
}
@Override
public @Nullable String getRequiredPluginName() {
return "Landlord";
}
private @NotNull Land getLand(@NotNull IOwnedLand ownedLand) {
String id = getIdPrefix() + ownedLand.getName();
HashSet<UUID> owners = new HashSet<>();
owners.add(ownedLand.getOwner());
return new Land(id, owners);
}
}
@@ -1,100 +0,0 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.protection.providers;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.Plot;
import com.plotsquared.bukkit.events.PlayerClaimPlotEvent;
import com.plotsquared.bukkit.util.BukkitUtil;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Land;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.ProtectionProvider;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class PlotSquared3Provider implements ProtectionProvider {
private Method getLocation;
private Method getPlots;
@Override
public void setup() throws ClassNotFoundException, NoSuchMethodException {
Class.forName("com.intellectualcrafters.plot.object.Location");
Class.forName("com.intellectualcrafters.plot.object.Plot");
getLocation = BukkitUtil.class.getMethod("getLocation", Location.class);
}
@Override
public @NotNull Set<Land> getLandsAt(@NotNull Location location) {
Plot plot = getPlot(location);
if (plot != null) {
return Collections.singleton(getLand(plot));
}
return Collections.emptySet();
}
private @Nullable Plot getPlot(@NotNull Location location) {
try {
return Plot.getPlot((com.intellectualcrafters.plot.object.Location) getLocation.invoke(null, location));
} catch (IllegalAccessException | InvocationTargetException e) {
return null;
}
}
private Land getLand(@NotNull Plot plot) {
String id = getIdPrefix() + plot.getId().toString();
return new Land(id, plot.getOwners());
}
@Override
public @NotNull Set<Land> getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) {
Set<Plot> plots = PS.get().getPlots(world.getName(), player.getUniqueId());
return plots.stream().map(this::getLand).collect(Collectors.toSet());
}
@Override
public @NotNull String getIdPrefix() {
return "ps";
}
@Override
public void deleteLand(@NotNull String id, @NotNull World world) {
id = id.replace(getIdPrefix(), "");
Collection<Plot> plots = PS.get().getPlots(world.getName());
for (Plot plot : plots) {
if (plot.getId().toString().equals(id)) {
plot.deletePlot(null);
break;
}
}
}
@Override
public @Nullable Class<? extends Event> getCreateLandEvent() {
return PlayerClaimPlotEvent.class;
}
@Override
public @Nullable Player getPlayer(Event event) {
if (event instanceof PlayerClaimPlotEvent) {
return ((PlayerClaimPlotEvent) event).getPlayer();
}
return null;
}
@Override
public @Nullable String getRequiredPluginName() {
return "PlotSquared";
}
}
@@ -1,79 +0,0 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.protection.providers;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.plot.Plot;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Land;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.ProtectionProvider;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class PlotSquared5Provider implements ProtectionProvider {
@Override
public void setup() throws NoSuchMethodException {
//noinspection ResultOfMethodCallIgnored
BukkitUtil.class.getMethod("getPlot", Location.class);
}
@Override
public @NotNull Set<Land> getLandsAt(@NotNull Location location) {
Plot plot = BukkitUtil.getPlot(location);
if (plot != null) {
return Collections.singleton(getLand(plot));
}
return Collections.emptySet();
}
@NotNull
private Land getLand(@NotNull Plot plot) {
return new Land(getIdPrefix() + plot.getId(), plot.getOwners());
}
@Override
public @NotNull Set<Land> getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) {
Set<Plot> plots = PlotSquared.get().getPlots(world.getName(), player.getUniqueId());
return plots.stream().map(this::getLand).collect(Collectors.toSet());
}
@Override
public @NotNull String getIdPrefix() {
return "ps";
}
@Override
public void deleteLand(@NotNull String id, @NotNull World world) {
id = id.replace(getIdPrefix(), "");
for (Plot plot : PlotSquared.get().getPlots(world.getName())) {
if (plot.getId().toString().equals(id)) {
plot.deletePlot(null);
break;
}
}
}
@Override
public @Nullable Class<? extends Event> getCreateLandEvent() {
return null;
}
@Override
public @Nullable Player getPlayer(Event event) {
return null;
}
@Override
public @Nullable String getRequiredPluginName() {
return "PlotSquared";
}
}
@@ -4,6 +4,7 @@ import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Coordinate;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Land;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.ProtectionProvider;
import org.bukkit.Location;
@@ -16,9 +17,7 @@ import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
@SuppressWarnings("unused")
public class WorldGuard6Provider implements ProtectionProvider {
@@ -26,14 +25,20 @@ public class WorldGuard6Provider implements ProtectionProvider {
private WorldGuardPlugin worldGuard;
private Method getRegionManager;
private Method getApplicableRegions;
private Method getPoints;
private Method getX;
private Method getZ;
@SuppressWarnings("JavaReflectionMemberAccess")
@Override
public void setup() throws NoSuchMethodException {
public void setup() throws NoSuchMethodException, ClassNotFoundException {
worldGuard = WorldGuardPlugin.inst();
getRegionManager = worldGuard.getClass().getMethod("getRegionManager", World.class);
//noinspection JavaReflectionMemberAccess
getApplicableRegions = RegionManager.class.getMethod("getApplicableRegions", Location.class);
getPoints = ProtectedRegion.class.getMethod("getPoints");
Class<?> blockVector = Class.forName("com.sk89q.worldedit.BlockVector2");
getX = blockVector.getMethod("getX");
getZ = blockVector.getMethod("getZ");
}
private @Nullable RegionManager getRegionManager(@Nullable World world) {
@@ -56,7 +61,25 @@ public class WorldGuard6Provider implements ProtectionProvider {
@NotNull
private Land getLand(ProtectedRegion region) {
return new Land(getIdPrefix() + region.getId(), region.getOwners().getUniqueIds());
List<Coordinate> coordinates = getCoordinates(region);
return new Land(getIdPrefix() + region.getId(), region.getOwners().getUniqueIds(), coordinates);
}
@NotNull
private List<Coordinate> getCoordinates(ProtectedRegion region) {
List<Coordinate> coordinates = new ArrayList<>();
try {
List<?> points = (List<?>) getPoints.invoke(region);
for (Object point : points) {
double x = (double) getX.invoke(point);
double z = (double) getZ.invoke(point);
coordinates.add(new Coordinate(x, z));
}
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
}
return coordinates;
}
@Override
@@ -1,11 +1,13 @@
package net.sacredlabyrinth.phaed.simpleclans.hooks.protection.providers;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Coordinate;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.Land;
import net.sacredlabyrinth.phaed.simpleclans.hooks.protection.ProtectionProvider;
import org.bukkit.Location;
@@ -16,9 +18,7 @@ import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
@SuppressWarnings({"unused"})
public class WorldGuardProvider implements ProtectionProvider {
@@ -46,7 +46,12 @@ public class WorldGuardProvider implements ProtectionProvider {
@NotNull
private Land getLand(ProtectedRegion region) {
return new Land(getIdPrefix() + region.getId(), region.getOwners().getUniqueIds());
//noinspection DuplicatedCode
List<Coordinate> coordinates = new ArrayList<>();
for (BlockVector2 point : region.getPoints()) {
coordinates.add(new Coordinate(point.getX(), point.getZ()));
}
return new Land(getIdPrefix() + region.getId(), region.getOwners().getUniqueIds(), coordinates);
}
@Override
@@ -7,7 +7,6 @@ import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -18,20 +17,18 @@ import java.util.UUID;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*;
public class FriendlyFire implements Listener {
public class FriendlyFire extends SCListener {
private final SimpleClans plugin;
private final Map<UUID, Long> warned = new HashMap<>();
private static final long WARN_DELAY = 10000;
public FriendlyFire(@NotNull SimpleClans plugin) {
this.plugin = plugin;
super(plugin);
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof Player) ||
plugin.getSettingsManager().getStringList(BLACKLISTED_WORLDS).contains(event.getEntity().getWorld().getName())) {
if (!(event.getEntity() instanceof Player) || isBlacklistedWorld(event.getEntity())) {
return;
}
Player victim = (Player) event.getEntity();
@@ -13,6 +13,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.DoubleChest;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.*;
@@ -60,7 +61,7 @@ public class LandProtection implements Listener {
public void registerCreateLandEvent(ProtectionProvider provider, @Nullable Class<? extends Event> createLandEvent) {
if (createLandEvent == null) return;
Bukkit.getPluginManager().registerEvent(createLandEvent, this, EventPriority.NORMAL, (listener, event) -> {
if (!createLandEvent.isInstance(createLandEvent)) {
if (!createLandEvent.isInstance(event)) {
return;
}
Player player = provider.getPlayer(event);
@@ -261,6 +262,9 @@ public class LandProtection implements Listener {
if (holder instanceof BlockState) {
return ((BlockState) holder).getLocation();
}
if (holder instanceof DoubleChest) {
return ((DoubleChest) holder).getLocation();
}
return null;
}
@@ -8,7 +8,6 @@ import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -24,21 +23,16 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con
/**
* @author phaed
*/
public class PlayerDeath implements Listener {
public class PlayerDeath extends SCListener {
private final SimpleClans plugin;
public PlayerDeath() {
plugin = SimpleClans.getInstance();
public PlayerDeath(SimpleClans plugin) {
super(plugin);
}
@EventHandler(priority = EventPriority.LOW)
public void onEntityDeath(PlayerDeathEvent event) {
SimpleClans.debug("A player died");
Player victim = event.getEntity();
if (plugin.getSettingsManager().getStringList(BLACKLISTED_WORLDS).contains(victim.getLocation().getWorld().getName())
|| victim.hasMetadata("NPC")) {
SimpleClans.debug("Blacklisted world");
if (isNPC(victim) || isBlacklistedWorld(victim)) {
return;
}
@@ -194,4 +188,16 @@ public class PlayerDeath implements Listener {
}
return reward;
}
private boolean isNPC(Player player) {
if (player.hasMetadata("NPC")) {
SimpleClans.debug(String.format("%s has NPC metadata", player.getName()));
return true;
}
if (Bukkit.getOfflinePlayer(player.getUniqueId()).getName() == null) {
SimpleClans.debug(String.format("%s has a null name", player.getUniqueId()));
return true;
}
return false;
}
}
@@ -6,26 +6,20 @@ import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.BLACKLISTED_WORLDS;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.PVP_ONLY_WHILE_IN_WAR;
public class PvPOnlyInWar implements Listener {
public class PvPOnlyInWar extends SCListener {
private final SimpleClans plugin;
public PvPOnlyInWar(@NotNull SimpleClans plugin) {
this.plugin = plugin;
public PvPOnlyInWar(SimpleClans plugin) {
super(plugin);
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onEntityDamage(EntityDamageEvent event) {
if (!(event.getEntity() instanceof Player) ||
plugin.getSettingsManager().getStringList(BLACKLISTED_WORLDS).contains(event.getEntity().getWorld().getName())) {
if (!(event.getEntity() instanceof Player) || isBlacklistedWorld(event.getEntity())) {
return;
}
Player victim = (Player) event.getEntity();
@@ -0,0 +1,29 @@
package net.sacredlabyrinth.phaed.simpleclans.listeners;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField;
import org.bukkit.entity.Entity;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public abstract class SCListener implements Listener {
protected final SimpleClans plugin;
public SCListener(SimpleClans plugin) {
this.plugin = plugin;
}
public boolean isBlacklistedWorld(@NotNull Entity entity) {
List<String> words = plugin.getSettingsManager().getStringList(ConfigField.BLACKLISTED_WORLDS);
if (words.contains(entity.getWorld().getName())) {
SimpleClans.debug("Blacklisted world");
return true;
}
return false;
}
}
@@ -1,10 +1,7 @@
package net.sacredlabyrinth.phaed.simpleclans.listeners;
import net.sacredlabyrinth.phaed.simpleclans.ChatBlock;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.*;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer.Channel;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.managers.PermissionsManager;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager;
import org.bukkit.Bukkit;
@@ -13,8 +10,8 @@ import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.*;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@@ -27,14 +24,14 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con
/**
* @author phaed
*/
public class SCPlayerListener implements Listener {
public class SCPlayerListener extends SCListener {
private final SimpleClans plugin;
private final SettingsManager settingsManager;
public SCPlayerListener() {
plugin = SimpleClans.getInstance();
public SCPlayerListener(@NotNull SimpleClans plugin) {
super(plugin);
settingsManager = plugin.getSettingsManager();
registerChatListener();
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
@@ -52,31 +49,10 @@ public class SCPlayerListener implements Listener {
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
ClanPlayer cp = plugin.getClanManager().getClanPlayer(player.getUniqueId());
if (cp == null || settingsManager.getStringList(BLACKLISTED_WORLDS).contains(player.getLocation().getWorld().getName())) {
return;
}
Channel channel = cp.getChannel();
if (channel != NONE) {
PermissionsManager pm = plugin.getPermissionsManager();
if ((channel == Channel.ALLY && !pm.has(player, "simpleclans.member.ally")) ||
(channel == CLAN && !pm.has(player, "simpleclans.member.chat"))) {
ChatBlock.sendMessage(player, ChatColor.RED + lang("insufficient.permissions", player));
return;
}
plugin.getChatManager().processChat(SPIGOT, channel, cp, event.getMessage());
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void handleChatTags(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
if (settingsManager.getStringList(BLACKLISTED_WORLDS).contains(player.getWorld().getName())) {
if (isBlacklistedWorld(player)) {
return;
}
@@ -104,27 +80,18 @@ public class SCPlayerListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
final Player player = event.getPlayer();
if (settingsManager.getStringList(BLACKLISTED_WORLDS).contains(player.getLocation().getWorld().getName())) {
if (isBlacklistedWorld(player)) {
return;
}
ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId());
ClanPlayer cp;
if (settingsManager.is(PERFORMANCE_USE_BUNGEECORD)) {
cp = plugin.getClanManager().getClanPlayerJoinEvent(player);
} else {
cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId());
}
plugin.getStorageManager().updatePlayerNameAsync(player);
updatePlayerName(player);
plugin.getClanManager().updateLastSeen(player);
plugin.getClanManager().updateDisplayName(player);
if (cp == null) {
return;
}
cp.setName(player.getName());
plugin.getPermissionsManager().addPlayerPermissions(cp);
if (settingsManager.is(BB_SHOW_ON_LOGIN) && cp.isBbEnabled() && cp.getClan() != null) {
@@ -137,15 +104,16 @@ public class SCPlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
if (!settingsManager.is(TELEPORT_HOME_ON_SPAWN) || settingsManager.getStringList(BLACKLISTED_WORLDS).contains(player.getWorld().getName())) {
if (!settingsManager.is(TELEPORT_HOME_ON_SPAWN) || isBlacklistedWorld(player)) {
return;
}
Clan clan = plugin.getClanManager().getClanByPlayerUniqueId(player.getUniqueId());
if (clan != null) {
Location home = clan.getHomeLocation();
if (home != null) {
event.setRespawnLocation(home);
Location home;
if (clan != null && (home = clan.getHomeLocation()) != null) {
String homeServer = new Flags(clan.getFlags()).getString("homeServer", "");
if (homeServer.isEmpty() || plugin.getProxyManager().getServerName().equals(homeServer)) {
event.setRespawnLocation(plugin.getTeleportManager().getSafe(home));
}
}
}
@@ -162,7 +130,7 @@ public class SCPlayerListener implements Listener {
}
});
}
if (settingsManager.getStringList(BLACKLISTED_WORLDS).contains(event.getPlayer().getLocation().getWorld().getName())) {
if (isBlacklistedWorld(event.getPlayer())) {
return;
}
@@ -174,10 +142,61 @@ public class SCPlayerListener implements Listener {
@EventHandler
public void onPlayerKick(PlayerKickEvent event) {
if (settingsManager.getStringList(BLACKLISTED_WORLDS).contains(event.getPlayer().getLocation().getWorld().getName())) {
if (isBlacklistedWorld(event.getPlayer())) {
return;
}
plugin.getClanManager().updateLastSeen(event.getPlayer());
}
private void registerChatListener() {
EventPriority priority = EventPriority.valueOf(settingsManager.getString(CLANCHAT_LISTENER_PRIORITY));
plugin.getServer().getPluginManager().registerEvent(AsyncPlayerChatEvent.class, this, priority, (l, e) -> {
if (!(e instanceof AsyncPlayerChatEvent)) {
return;
}
AsyncPlayerChatEvent event = (AsyncPlayerChatEvent) e;
Player player = event.getPlayer();
ClanPlayer cp = plugin.getClanManager().getClanPlayer(player.getUniqueId());
if (cp == null || isBlacklistedWorld(player)) {
return;
}
Channel channel = cp.getChannel();
if (channel != NONE) {
PermissionsManager pm = plugin.getPermissionsManager();
if ((channel == Channel.ALLY && !pm.has(player, "simpleclans.member.ally")) ||
(channel == CLAN && !pm.has(player, "simpleclans.member.chat"))) {
ChatBlock.sendMessage(player, ChatColor.RED + lang("insufficient.permissions", player));
return;
}
plugin.getChatManager().processChat(SPIGOT, channel, cp, event.getMessage());
event.setCancelled(true);
}
}, plugin, true);
}
private void updatePlayerName(@NotNull final Player player) {
final ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(player.getUniqueId());
ClanPlayer duplicate = null;
for (ClanPlayer other : plugin.getClanManager().getAllClanPlayers()) {
if (other.getName().equals(player.getName()) && !other.getUniqueId().equals(player.getUniqueId())) {
duplicate = other;
break;
}
}
if (duplicate != null) {
plugin.getLogger().warning(String.format("Found duplicate for %s, UUIDs: %s, %s", player.getName(),
player.getUniqueId(), duplicate.getUniqueId()));
duplicate.setName(duplicate.getUniqueId().toString());
plugin.getStorageManager().updatePlayerName(duplicate);
}
if (cp != null) {
cp.setName(player.getName());
plugin.getStorageManager().updatePlayerName(cp);
}
}
}
@@ -2,12 +2,8 @@ package net.sacredlabyrinth.phaed.simpleclans.loggers;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.EconomyResponse;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.events.ClanBalanceUpdateEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
@@ -25,16 +21,16 @@ public class BankLog {
private final DecimalFormat decimalFormat = new DecimalFormat("##.##");
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd - HH:mm");
private final CommandSender sender;
private final BankOperator operator;
private final Clan clan;
private final EconomyResponse economyResponse;
private final BankLogger.Operation operation;
private final ClanBalanceUpdateEvent.Cause cause;
private final double amount;
public BankLog(@Nullable CommandSender sender, @NotNull Clan clan, @NotNull EconomyResponse economyResponse,
public BankLog(@NotNull BankOperator operator, @NotNull Clan clan, @NotNull EconomyResponse economyResponse,
@NotNull BankLogger.Operation operation, ClanBalanceUpdateEvent.Cause cause, double amount) {
this.sender = sender;
this.operator = operator;
this.clan = clan;
this.economyResponse = economyResponse;
this.operation = operation;
@@ -43,28 +39,27 @@ public class BankLog {
}
public static List<String> getHeader() {
return Arrays.asList("Date", "Sender", "Clan Name", "Response", "Operation", "Cause", "Sender Balance", "Amount", "Clan Balance");
return Arrays.asList("Date", "Sender", "Clan Name", "Response",
"Operation", "Cause", "Sender Balance", "Amount", "Clan Balance");
}
public List<String> getValues() {
double senderMoney = (sender instanceof Player) ? SimpleClans.getInstance().getPermissionsManager().playerGetMoney((Player) sender) : 0;
List<String> values = new ArrayList<>();
values.add(dateFormat.format(new Date()));
values.add(sender != null ? sender.getName() : "API");
values.add(operator.getName());
values.add(clan.getName());
values.add(economyResponse.name());
values.add(operation.name());
values.add(cause.name());
values.add(decimalFormat.format(senderMoney));
values.add(decimalFormat.format(operator.getBalance()));
values.add(decimalFormat.format(amount));
values.add(decimalFormat.format(clan.getBalance()));
return values;
}
public CommandSender getSender() {
return sender;
public BankOperator getOperator() {
return operator;
}
public Clan getClan() {
@@ -0,0 +1,34 @@
package net.sacredlabyrinth.phaed.simpleclans.loggers;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class BankOperator {
public static final BankOperator API = new BankOperator("API", 0);
public static final BankOperator INTERNAL = new BankOperator("Internal", 0);
private final String name;
private final double balance;
public BankOperator(@NotNull CommandSender sender, double balance) {
this(sender.getName(), balance);
}
public BankOperator(@NotNull ClanPlayer sender, double balance) {
this(sender.getName(), balance);
}
public BankOperator(@NotNull String name, double balance) {
this.name = name;
this.balance = balance;
}
public @NotNull String getName() {
return name;
}
public double getBalance() {
return balance;
}
}
@@ -3,6 +3,7 @@ package net.sacredlabyrinth.phaed.simpleclans.managers;
import github.scarsz.discordsrv.DiscordSRV;
import github.scarsz.discordsrv.api.Subscribe;
import github.scarsz.discordsrv.api.events.DiscordReadyEvent;
import github.scarsz.discordsrv.dependencies.jda.api.JDA;
import me.clip.placeholderapi.PlaceholderAPI;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
@@ -10,9 +11,10 @@ import net.sacredlabyrinth.phaed.simpleclans.Helper;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.chat.ChatHandler;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
import net.sacredlabyrinth.phaed.simpleclans.hooks.DiscordHook;
import net.sacredlabyrinth.phaed.simpleclans.hooks.discord.DiscordHook;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -23,7 +25,7 @@ import java.util.stream.Collectors;
import static net.sacredlabyrinth.phaed.simpleclans.ClanPlayer.Channel;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.SPIGOT;
import static net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source.DISCORD;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*;
import static org.bukkit.Bukkit.getPluginManager;
@@ -31,14 +33,13 @@ import static org.bukkit.Bukkit.getPluginManager;
public final class ChatManager {
private final SimpleClans plugin;
private DiscordHook discordHook;
private final Set<ChatHandler> handlers = new HashSet<>();
private DiscordHook discordHook;
public ChatManager(SimpleClans plugin) {
this.plugin = plugin;
registerHandlers();
if (getPluginManager().getPlugin("DiscordSRV") != null && plugin.getSettingsManager().is(DISCORDCHAT_ENABLE)) {
if (isDiscordHookEnabled()) {
DiscordSRV.api.subscribe(this);
}
}
@@ -52,44 +53,54 @@ public final class ChatManager {
@Nullable
public DiscordHook getDiscordHook() {
if (isDiscordHookEnabled()) {
// Manually instantiate, if JDA did load faster than SC
if (discordHook == null && DiscordSRV.getPlugin().getJda().getStatus() == JDA.Status.CONNECTED) {
registerDiscord(new DiscordReadyEvent());
}
}
return discordHook;
}
public void processChat(@NotNull Source source, @NotNull Channel channel,
@NotNull ClanPlayer clanPlayer, String message) {
Clan clan = Objects.requireNonNull(clanPlayer.getClan(), "Clan cannot be null");
List<ClanPlayer> receivers = new ArrayList<>();
public void processChat(@NotNull SCMessage message) {
Clan clan = Objects.requireNonNull(message.getSender().getClan(), "Clan cannot be null");
switch (channel) {
List<ClanPlayer> receivers = new ArrayList<>();
switch (message.getChannel()) {
case ALLY:
if (!plugin.getSettingsManager().is(ALLYCHAT_ENABLE)) {
return;
}
receivers.addAll(getOnlineAllyMembers(clan).stream().filter(allymember ->
!allymember.isMutedAlly()).collect(Collectors.toList()));
receivers.addAll(clan.getOnlineMembers().stream().filter(allymember ->
!allymember.isMutedAlly()).collect(Collectors.toList()));
receivers.addAll(getOnlineAllyMembers(clan).stream().filter(allyMember ->
!allyMember.isMutedAlly()).collect(Collectors.toList()));
receivers.addAll(clan.getOnlineMembers().stream().filter(onlineMember ->
!onlineMember.isMutedAlly()).collect(Collectors.toList()));
break;
case CLAN:
if (!plugin.getSettingsManager().is(CLANCHAT_ENABLE)) {
return;
}
receivers.addAll(clan.getOnlineMembers().stream().
filter(member -> !member.isMuted()).
receivers.addAll(clan.getOnlineMembers().stream().filter(member -> !member.isMuted()).
collect(Collectors.toList()));
}
SCMessage scMessage = new SCMessage(source, channel, clanPlayer, message, receivers);
message.setReceivers(receivers);
for (ChatHandler ch : handlers) {
if (ch.canHandle(source)) {
ch.sendMessage(scMessage);
if (ch.canHandle(message.getSource())) {
ch.sendMessage(message.clone());
}
}
}
public void processChat(@NotNull Source source, @NotNull Channel channel,
@NotNull ClanPlayer clanPlayer, String message) {
Objects.requireNonNull(clanPlayer.getClan(), "Clan cannot be null");
processChat(new SCMessage(source, channel, clanPlayer, message));
}
public String parseChatFormat(String format, SCMessage message) {
return parseChatFormat(format, message, new HashMap<>());
}
@@ -97,7 +108,6 @@ public final class ChatManager {
public String parseChatFormat(String format, SCMessage message, Map<String, String> placeholders) {
SettingsManager sm = plugin.getSettingsManager();
ClanPlayer sender = message.getSender();
Channel channel = message.getChannel();
String leaderColor = sm.getColored(ConfigField.valueOf(message.getChannel() + "CHAT_LEADER_COLOR"));
String memberColor = sm.getColored(ConfigField.valueOf(message.getChannel() + "CHAT_MEMBER_COLOR"));
@@ -105,7 +115,7 @@ public final class ChatManager {
String rank = sender.getRankId().isEmpty() ? null : ChatUtils.parseColors(sender.getRankDisplayName());
ConfigField configField = ConfigField.valueOf(String.format("%sCHAT_RANK",
message.getSource() == SPIGOT ? message.getChannel() : message.getSource()));
message.getSource() == DISCORD ? "DISCORD" : message.getChannel()));
String rankFormat = (rank != null) ? sm.getColored(configField).replace("%rank%", rank) : "";
if (placeholders != null) {
@@ -116,15 +126,33 @@ public final class ChatManager {
String parsedFormat = ChatUtils.parseColors(format)
.replace("%clan%", Objects.requireNonNull(sender.getClan()).getColorTag())
.replace("%clean-tag%", sender.getClan().getTag())
.replace("%nick-color%",
(sender.isLeader() ? leaderColor : sender.isTrusted() ? trustedColor : memberColor))
.replace("%player%", sender.getName())
.replace("%rank%", rankFormat)
.replace("%message%", message.getContent());
return getPluginManager().getPlugin("PlaceholderAPI") != null ?
PlaceholderAPI.setPlaceholders(Bukkit.getOfflinePlayer(message.getSender().getUniqueId()), parsedFormat)
: parsedFormat;
return parseWithPapi(message.getSender(), parsedFormat);
}
public boolean isDiscordHookEnabled() {
return getPluginManager().getPlugin("DiscordSRV") != null && plugin.getSettingsManager().is(DISCORDCHAT_ENABLE);
}
private String parseWithPapi(ClanPlayer cp, String message) {
if (getPluginManager().getPlugin("PlaceholderAPI") == null) {
return message;
}
OfflinePlayer sender = Bukkit.getOfflinePlayer(cp.getUniqueId());
message = PlaceholderAPI.setPlaceholders(sender, message);
// If there are still placeholders left, try to parse them
// E.g. if the user has a placeholder as LuckPerms prefix/suffix
if (message.contains("%")) {
message = PlaceholderAPI.setPlaceholders(sender, message);
}
return message;
}
private void registerHandlers() {
@@ -136,7 +164,7 @@ public final class ChatManager {
try {
handlers.add(handler.getConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
plugin.getLogger().log(Level.SEVERE, "Error while trying to register {0} handler: " +
plugin.getLogger().log(Level.SEVERE, "Error while trying to register {0}: " +
ex.getMessage(), handler.getSimpleName());
}
}
@@ -4,6 +4,7 @@ import com.cryptomorin.xseries.XMaterial;
import net.sacredlabyrinth.phaed.simpleclans.*;
import net.sacredlabyrinth.phaed.simpleclans.events.ClanBalanceUpdateEvent;
import net.sacredlabyrinth.phaed.simpleclans.events.CreateClanEvent;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankOperator;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import net.sacredlabyrinth.phaed.simpleclans.utils.VanishUtils;
import net.sacredlabyrinth.phaed.simpleclans.uuid.UUIDMigration;
@@ -23,6 +24,8 @@ import java.time.Instant;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*;
@@ -34,8 +37,8 @@ import static org.bukkit.ChatColor.RED;
public final class ClanManager {
private final SimpleClans plugin;
private final HashMap<String, Clan> clans = new HashMap<>();
private final HashMap<String, ClanPlayer> clanPlayers = new HashMap<>();
private final ConcurrentHashMap<String, Clan> clans = new ConcurrentHashMap<>();
private final ConcurrentHashMap<UUID, ClanPlayer> clanPlayers = new ConcurrentHashMap<>();
private final HashMap<ClanPlayer, List<Kill>> kills = new HashMap<>();
/**
@@ -121,7 +124,7 @@ public final class ClanManager {
*/
public void importClanPlayer(ClanPlayer cp) {
if (cp.getUniqueId() != null) {
this.clanPlayers.put(cp.getUniqueId().toString(), cp);
this.clanPlayers.put(cp.getUniqueId(), cp);
}
}
@@ -131,11 +134,13 @@ public final class ClanManager {
public void createClan(Player player, String colorTag, String name) {
ClanPlayer cp = getCreateClanPlayer(player.getUniqueId());
boolean verified = !plugin.getSettingsManager().is(REQUIRE_VERIFICATION) || plugin.getPermissionsManager().has(player, "simpleclans.mod.verify");
boolean verified = !plugin.getSettingsManager().is(REQUIRE_VERIFICATION)
|| plugin.getPermissionsManager().has(player, "simpleclans.mod.verify");
Clan clan = new Clan(colorTag, name, verified);
clan.addPlayerToClan(cp);
cp.setLeader(true);
clan.getRanks().addAll(plugin.getSettingsManager().getStarterRanks());
plugin.getStorageManager().insertClan(clan);
importClan(clan);
@@ -153,6 +158,7 @@ public final class ClanManager {
cp.setCivilianKills(0);
cp.setNeutralKills(0);
cp.setRivalKills(0);
cp.setAllyKills(0);
cp.setDeaths(0);
plugin.getStorageManager().updateClanPlayer(cp);
}
@@ -165,7 +171,7 @@ public final class ClanManager {
if (clan != null) {
clan.removePlayerFromClan(cp.getUniqueId());
}
clanPlayers.remove(cp.getUniqueId().toString());
clanPlayers.remove(cp.getUniqueId());
plugin.getStorageManager().deleteClanPlayer(cp);
}
@@ -173,7 +179,7 @@ public final class ClanManager {
* Delete a player data from memory
*/
public void deleteClanPlayerFromMemory(UUID playerUniqueId) {
clanPlayers.remove(playerUniqueId.toString());
clanPlayers.remove(playerUniqueId);
}
/**
@@ -237,6 +243,7 @@ public final class ClanManager {
* Gets the ClanPlayer data object if a player is currently in a clan, null
* if he's not in a clan Used for BungeeCord Reload ClanPlayer and your Clan
*/
@Deprecated
public @Nullable ClanPlayer getClanPlayerJoinEvent(Player player) {
SimpleClans.getInstance().getStorageManager().importFromDatabaseOnePlayer(player);
return getClanPlayer(player.getUniqueId());
@@ -263,7 +270,7 @@ public final class ClanManager {
* if he's not in a clan
*/
public @Nullable ClanPlayer getClanPlayer(UUID playerUniqueId) {
ClanPlayer cp = clanPlayers.get(playerUniqueId.toString());
ClanPlayer cp = clanPlayers.get(playerUniqueId);
if (cp == null) {
return null;
@@ -286,14 +293,15 @@ public final class ClanManager {
* Gets the ClanPlayer data object if a player is currently in a clan, null
* if he's not in a clan
*/
public @Nullable ClanPlayer getClanPlayerName(String playerDisplayName) {
UUID uuid = UUIDMigration.getForcedPlayerUUID(playerDisplayName);
@Deprecated
public @Nullable ClanPlayer getClanPlayerName(String playerName) {
UUID uuid = UUIDMigration.getForcedPlayerUUID(playerName);
if (uuid == null) {
return null;
}
ClanPlayer cp = clanPlayers.get(uuid.toString());
ClanPlayer cp = clanPlayers.get(uuid);
if (cp == null) {
return null;
@@ -314,8 +322,8 @@ public final class ClanManager {
*/
@Nullable
public ClanPlayer getAnyClanPlayer(UUID playerUniqueId) {
return clanPlayers.get(playerUniqueId.toString());
public ClanPlayer getAnyClanPlayer(UUID uuid) {
return clanPlayers.get(uuid);
}
@SuppressWarnings("deprecation")
@@ -332,8 +340,8 @@ public final class ClanManager {
/**
* Gets the ClanPlayer object for the player, creates one if not found
*/
public @Nullable ClanPlayer getCreateClanPlayerUUID(String playerDisplayName) {
UUID playerUniqueId = UUIDMigration.getForcedPlayerUUID(playerDisplayName);
public @Nullable ClanPlayer getCreateClanPlayerUUID(String playerName) {
UUID playerUniqueId = UUIDMigration.getForcedPlayerUUID(playerName);
if (playerUniqueId != null) {
return getCreateClanPlayer(playerUniqueId);
} else {
@@ -344,16 +352,28 @@ public final class ClanManager {
/**
* Gets the ClanPlayer object for the player, creates one if not found
*/
public ClanPlayer getCreateClanPlayer(UUID playerUniqueId) {
Objects.requireNonNull(playerUniqueId, "UUID must not be null");
if (clanPlayers.containsKey(playerUniqueId.toString())) {
return clanPlayers.get(playerUniqueId.toString());
public ClanPlayer getCreateClanPlayer(UUID uuid) {
Objects.requireNonNull(uuid, "UUID must not be null");
if (clanPlayers.containsKey(uuid)) {
return clanPlayers.get(uuid);
}
ClanPlayer cp = new ClanPlayer(playerUniqueId);
ClanPlayer cp = new ClanPlayer(uuid);
plugin.getStorageManager().insertClanPlayer(cp);
importClanPlayer(cp);
boolean save = true;
for (ClanPlayer other : getAllClanPlayers()) {
if (other.getName().equals(cp.getName())) {
save = false;
break;
}
}
if (save) {
plugin.getStorageManager().insertClanPlayer(cp);
importClanPlayer(cp);
} else if (plugin.getSettingsManager().is(DEBUG)) {
plugin.getLogger().log(Level.WARNING, String.format("There already is a ClanPlayer with the name %s",
cp.getName()), new Exception());
}
return cp;
}
@@ -373,13 +393,8 @@ public final class ClanManager {
if (plugin.getSettingsManager().is(DISABLE_MESSAGES)) {
return;
}
Collection<? extends Player> players = Bukkit.getOnlinePlayers();
for (Player player : players) {
ChatBlock.sendMessage(player, ChatColor.DARK_GRAY + "* " + ChatColor.AQUA + msg);
}
SimpleClans.getInstance().getServer().getConsoleSender().sendMessage(ChatColor.AQUA + "[" + lang("server.announce") + "] " + ChatColor.WHITE + msg);
plugin.getProxyManager().sendMessage("ALL", ChatColor.DARK_GRAY + "* " + ChatColor.AQUA + msg);
Bukkit.getConsoleSender().sendMessage(ChatColor.AQUA + "[" + lang("server.announce") + "] " + ChatColor.WHITE + msg);
}
/**
@@ -747,41 +762,20 @@ public final class ClanManager {
}
/**
* Returns a formatted string detailing the players health
* Returns a colored bar based on the length
*/
public String getHealthString(double health) {
public String getBar(double length) {
StringBuilder out = new StringBuilder();
if (health >= 16) {
if (length >= 16) {
out.append(ChatColor.GREEN);
} else if (health >= 8) {
} else if (length >= 8) {
out.append(ChatColor.GOLD);
} else {
out.append(RED);
}
for (int i = 0; i < health; i++) {
out.append('|');
}
return out.toString();
}
/**
* Returns a formatted string detailing the players hunger
*/
public String getHungerString(int health) {
StringBuilder out = new StringBuilder();
if (health >= 16) {
out.append(ChatColor.GREEN);
} else if (health >= 8) {
out.append(ChatColor.GOLD);
} else {
out.append(RED);
}
for (int i = 0; i < health; i++) {
for (int i = 0; i < length; i++) {
out.append('|');
}
@@ -936,7 +930,7 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
@@ -959,7 +953,7 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
@@ -982,7 +976,7 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
@@ -1005,7 +999,7 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
@@ -1028,7 +1022,7 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
@@ -1051,7 +1045,7 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
@@ -1084,14 +1078,15 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
} else {
switch (clan.withdraw(player, ClanBalanceUpdateEvent.Cause.COMMAND, price)) {
double money = plugin.getPermissionsManager().playerGetMoney(player);
switch (clan.withdraw(new BankOperator(player, money), ClanBalanceUpdateEvent.Cause.COMMAND, price)) {
case SUCCESS:
if (SimpleClans.getInstance().getPermissionsManager().playerGrantMoney(player, price)) {
if (plugin.getPermissionsManager().playerGrantMoney(player, price)) {
player.sendMessage(ChatColor.AQUA + lang("player.clan.withdraw", player, price));
clan.addBb(player.getName(), ChatColor.AQUA + lang("bb.clan.withdraw", price));
return true;
@@ -1121,7 +1116,7 @@ public final class ClanManager {
plugin.getPermissionsManager().playerChargeMoney(player, price);
player.sendMessage(RED + MessageFormat.format(lang("account.has.been.debited", player), price));
} else {
player.sendMessage(RED + lang("not.sufficient.money", player));
player.sendMessage(RED + lang("not.sufficient.money", player, price));
return false;
}
}
@@ -4,6 +4,7 @@ import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import net.sacredlabyrinth.phaed.simpleclans.*;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
@@ -14,40 +15,34 @@ import org.jetbrains.annotations.Nullable;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.ENABLE_AUTO_GROUPS;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.PERMISSIONS_AUTO_GROUP_GROUPNAME;
/**
* @author phaed
*/
public final class PermissionsManager {
/**
*
*/
private final SimpleClans plugin;
private static Permission permission = null;
private static Economy economy = null;
private static Chat chat = null;
private @Nullable Permission permission;
private @Nullable Economy economy;
private @Nullable Chat chat;
private final HashMap<String, List<String>> permissions = new HashMap<>();
private final HashMap<Player, PermissionAttachment> permAttaches = new HashMap<>();
/**
*
*/
public PermissionsManager() {
plugin = SimpleClans.getInstance();
try {
Class.forName("net.milkbowl.vault.permission.Permission");
setupChat();
setupEconomy();
setupPermissions();
chat = getProvider(Chat.class);
economy = getProvider(Economy.class);
permission = getProvider(Permission.class);
} catch (ClassNotFoundException e) {
SimpleClans.getInstance().getLogger().info("Vault not found. No economy or extended Permissions support.");
}
@@ -67,7 +62,8 @@ public final class PermissionsManager {
public void loadPermissions() {
permissions.clear();
for (Clan clan : plugin.getClanManager().getClans()) {
permissions.put(clan.getTag(), SimpleClans.getInstance().getConfig().getStringList("permissions." + clan.getTag()));
permissions.put(clan.getTag(), SimpleClans.getInstance().getSettingsManager().getConfig().
getStringList("permissions." + clan.getTag()));
}
}
@@ -114,7 +110,7 @@ public final class PermissionsManager {
for (String perm : getPermissions(clan)) {
permAttaches.get(player).setPermission(perm, true);
}
if (plugin.getSettingsManager().is(ENABLE_AUTO_GROUPS)) {
if (plugin.getSettingsManager().is(PERMISSIONS_AUTO_GROUP_GROUPNAME)) {
permAttaches.get(player).setPermission("group." + clan.getTag(), true);
}
player.recalculatePermissions();
@@ -129,6 +125,7 @@ public final class PermissionsManager {
public void removeClanPermissions(Clan clan) {
for (ClanPlayer cp : clan.getMembers()) {
removeClanPlayerPermissions(cp);
removeClanPermissions(cp);
}
}
@@ -146,6 +143,22 @@ public final class PermissionsManager {
}
}
/**
* Removes permissions linked to a clan from the player
*/
public void removeClanPermissions(ClanPlayer cp) {
if (!plugin.getSettingsManager().is(ENABLE_AUTO_GROUPS)) {
return;
}
if (permission != null && cp.toPlayer() != null) {
permission.playerRemoveGroup(null, cp.toPlayer(), "clan_" + cp.getTag());
permission.playerRemoveGroup(null, cp.toPlayer(), "sc_untrusted");
permission.playerRemoveGroup(null, cp.toPlayer(), "sc_trusted");
permission.playerRemoveGroup(null, cp.toPlayer(), "sc_leader");
}
}
/**
* @return the permissions for a clan
*/
@@ -153,22 +166,6 @@ public final class PermissionsManager {
return permissions.get(clan.getTag());
}
/**
* @return the PermissionsAttachments for every player
*/
public Map<Player, PermissionAttachment> getPermAttaches() {
return permAttaches;
}
/**
* Charge a player some money
*
*/
@Deprecated
public boolean playerChargeMoney(String player, double money) {
return economy.withdrawPlayer(player, money).transactionSuccess();
}
/**
* Charge a player some money
*
@@ -177,31 +174,6 @@ public final class PermissionsManager {
return economy.withdrawPlayer(player, money).transactionSuccess();
}
/**
* Charge a player some money
*
*/
public boolean playerChargeMoney(Player player, double money) {
return playerChargeMoney((OfflinePlayer) player, money);
}
/**
* Grants a player some money
*
*/
public boolean playerGrantMoney(Player player, double money) {
return economy.depositPlayer(player, money).transactionSuccess();
}
/**
* Grants a player some money
*
*/
@Deprecated
public boolean playerGrantMoney(String player, double money) {
return economy.depositPlayer(player, money).transactionSuccess();
}
/**
* Grants a player some money
*
@@ -215,7 +187,7 @@ public final class PermissionsManager {
*
* @return whether he has the money
*/
public boolean playerHasMoney(Player player, double money) {
public boolean playerHasMoney(OfflinePlayer player, double money) {
return economy.has(player, money);
}
@@ -224,28 +196,10 @@ public final class PermissionsManager {
*
* @return the players money
*/
public double playerGetMoney(Player player) {
public double playerGetMoney(OfflinePlayer player) {
return economy.getBalance(player);
}
/**
* Check if a player has permissions
*
* @param world the world
* @param player the player
* @param perm the permission
* @return whether he has the permission
*
* @deprecated use {@link PermissionsManager#has(Player, RankPermission, boolean)} or {@link PermissionsManager#has(Player, String)}
*/
public boolean has(@Nullable String world, OfflinePlayer player, String perm) {
if (player != null && permission != null) {
return permission.playerHas(world, player, perm);
}
return false;
}
/**
* Check if a player has permissions
*
@@ -253,7 +207,7 @@ public final class PermissionsManager {
* @param perm the permission
* @return whether he has the permission
*/
public boolean has(Player player, String perm) {
public boolean has(@Nullable Player player, String perm) {
if (player == null) {
SimpleClans.debug("null player");
return false;
@@ -280,35 +234,35 @@ public final class PermissionsManager {
*/
@Deprecated
public boolean has(Player player, RankPermission permission, PermissionLevel level, boolean notify) {
if (player == null || permission == null) {
return false;
if (player == null || permission == null) {
return false;
}
ClanPlayer clanPlayer = plugin.getClanManager().getClanPlayer(player);
if (clanPlayer == null) {
return false;
ClanPlayer clanPlayer = plugin.getClanManager().getClanPlayer(player);
if (clanPlayer == null) {
return false;
}
boolean hasBukkitPermission = has(player, permission.getBukkitPermission());
if (!hasBukkitPermission) {
return false;
boolean hasBukkitPermission = has(player, permission.getBukkitPermission());
if (!hasBukkitPermission) {
return false;
}
boolean hasLevel = false;
if (level != null) {
switch (level) {
case LEADER:
hasLevel = clanPlayer.isLeader();
break;
case TRUSTED:
hasLevel = clanPlayer.isTrusted();
break;
}
boolean hasLevel = false;
if (level != null) {
switch (level) {
case LEADER:
hasLevel = clanPlayer.isLeader();
break;
case TRUSTED:
hasLevel = clanPlayer.isTrusted();
break;
}
}
boolean hasRankPermission = false;
String rankName = clanPlayer.getRankId();
Clan clan = clanPlayer.getClan();
boolean hasRankPermission = false;
String rankName = clanPlayer.getRankId();
Clan clan = clanPlayer.getClan();
//noinspection ConstantConditions
if (clan.hasRank(rankName)) {
//noinspection ConstantConditions
@@ -317,12 +271,12 @@ public final class PermissionsManager {
clanPlayer.setRank(null);
}
if (notify && !hasLevel && !hasRankPermission) {
if (notify && !hasLevel && !hasRankPermission) {
ChatBlock.sendMessage(player, ChatColor.RED + MessageFormat.format(lang("you.must.be.0.or.have.the.permission.1.to.use.this", player),
level == PermissionLevel.LEADER ? lang("leader", player) : lang("trusted", player), permission.toString()));
level == PermissionLevel.LEADER ? lang("leader", player) : lang("trusted", player), permission.toString()));
}
return hasLevel || hasRankPermission;
return hasLevel || hasRankPermission;
}
/**
@@ -333,54 +287,54 @@ public final class PermissionsManager {
* @param notify notify the player if they don't have permission
*/
public boolean has(Player player, RankPermission permission, boolean notify) {
if (player == null || permission == null) {
return false;
if (player == null || permission == null) {
return false;
}
ClanPlayer clanPlayer = plugin.getClanManager().getClanPlayer(player);
if (clanPlayer == null) {
if (notify) {
player.sendMessage(ChatColor.RED + lang("not.a.member.of.any.clan", player));
ClanPlayer clanPlayer = plugin.getClanManager().getClanPlayer(player);
if (clanPlayer == null) {
if (notify) {
player.sendMessage(ChatColor.RED + lang("not.a.member.of.any.clan", player));
}
return false;
return false;
}
boolean hasBukkitPermission = has(player, permission.getBukkitPermission());
if (!hasBukkitPermission) {
if (notify) {
ChatBlock.sendMessage(player,ChatColor.RED + lang("insufficient.permissions", player));
boolean hasBukkitPermission = has(player, permission.getBukkitPermission());
if (!hasBukkitPermission) {
if (notify) {
ChatBlock.sendMessage(player, ChatColor.RED + lang("insufficient.permissions", player));
}
return false;
return false;
}
boolean hasLevel = false;
switch (permission.getPermissionLevel()) {
case LEADER:
hasLevel = clanPlayer.isLeader();
break;
case TRUSTED:
hasLevel = clanPlayer.isTrusted();
break;
boolean hasLevel = false;
switch (permission.getPermissionLevel()) {
case LEADER:
hasLevel = clanPlayer.isLeader();
break;
case TRUSTED:
hasLevel = clanPlayer.isTrusted();
break;
}
boolean hasRankPermission = false;
String rankName = clanPlayer.getRankId();
Clan clan = clanPlayer.getClan();
boolean hasRankPermission = false;
String rankName = clanPlayer.getRankId();
Clan clan = clanPlayer.getClan();
if (clan != null) {
Rank rank = clan.getRank(rankName);
if (rank != null) {
hasRankPermission = rank.getPermissions().contains(permission.toString());
}
} else if (!rankName.isEmpty()) {
clanPlayer.setRank(null);
} else if (!rankName.isEmpty()) {
clanPlayer.setRank(null);
}
if (notify && !hasLevel && !hasRankPermission) {
ChatBlock.sendMessage(player, ChatColor.RED + MessageFormat.format(lang("you.must.be.0.or.have.the.permission.1.to.use.this",player),
permission.getPermissionLevel() == PermissionLevel.LEADER ? lang("leader",player) : lang("trusted",player), permission.toString()));
if (notify && !hasLevel && !hasRankPermission) {
ChatBlock.sendMessage(player, ChatColor.RED + MessageFormat.format(lang("you.must.be.0.or.have.the.permission.1.to.use.this", player),
permission.getPermissionLevel() == PermissionLevel.LEADER ? lang("leader", player) : lang("trusted", player), permission.toString()));
}
return hasLevel || hasRankPermission;
return hasLevel || hasRankPermission;
}
/**
@@ -388,89 +342,32 @@ public final class PermissionsManager {
*
*/
public void addClanPermissions(ClanPlayer cp) {
if (!plugin.getSettingsManager().is(ENABLE_AUTO_GROUPS)) {
if (!plugin.getSettingsManager().is(ENABLE_AUTO_GROUPS) || cp == null || permission == null) {
return;
}
Player player = cp.toPlayer();
if (player == null) {
return;
}
if (permission != null) {
if (cp != null && cp.toPlayer() != null) {
if (cp.getClan() != null) {
if (!permission.playerInGroup(cp.toPlayer(), "clan_" + cp.getTag())) {
permission.playerAddGroup(cp.toPlayer(), "clan_" + cp.getTag());
}
permission.playerRemoveGroup(null, player, "sc_leader");
permission.playerRemoveGroup(null, player, "sc_trusted");
permission.playerRemoveGroup(null, player, "sc_untrusted");
if (cp.isLeader()) {
if (!permission.playerInGroup(cp.toPlayer(), "sc_leader")) {
permission.playerAddGroup(cp.toPlayer(), "sc_leader");
}
permission.playerRemoveGroup(cp.toPlayer(), "sc_untrusted");
permission.playerRemoveGroup(cp.toPlayer(), "sc_trusted");
return;
}
if (cp.isTrusted()) {
if (!permission.playerInGroup(cp.toPlayer(), "sc_trusted")) {
permission.playerAddGroup(cp.toPlayer(), "sc_trusted");
}
permission.playerRemoveGroup(cp.toPlayer(), "sc_untrusted");
permission.playerRemoveGroup(cp.toPlayer(), "sc_leader");
return;
}
if (!permission.playerInGroup(cp.toPlayer(), "sc_untrusted")) {
permission.playerAddGroup(cp.toPlayer(), "sc_untrusted");
}
} else {
permission.playerRemoveGroup(cp.toPlayer(), "sc_untrusted");
}
permission.playerRemoveGroup(cp.toPlayer(), "sc_trusted");
permission.playerRemoveGroup(cp.toPlayer(), "sc_leader");
if (cp.getClan() != null) {
permission.playerAddGroup(null, player, "clan_" + cp.getTag());
if (cp.isLeader()) {
permission.playerAddGroup(null, player, "sc_leader");
return;
}
if (cp.isTrusted()) {
permission.playerAddGroup(null, player, "sc_trusted");
return;
}
permission.playerAddGroup(null, player, "sc_untrusted");
}
}
/**
* Removes permissions linked to a clan from the player
*
*/
public void removeClanPermissions(ClanPlayer cp) {
if (!plugin.getSettingsManager().is(ENABLE_AUTO_GROUPS)) {
return;
}
if (permission != null && cp.toPlayer() != null) {
permission.playerRemoveGroup(cp.toPlayer(), "clan_" + cp.getTag());
permission.playerRemoveGroup(cp.toPlayer(), "sc_untrusted");
permission.playerRemoveGroup(cp.toPlayer(), "sc_trusted");
permission.playerRemoveGroup(cp.toPlayer(), "sc_leader");
}
}
private void setupPermissions() {
RegisteredServiceProvider<Permission> permissionProvider = plugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
if (permissionProvider != null) {
permission = permissionProvider.getProvider();
}
}
private void setupChat() {
RegisteredServiceProvider<Chat> chatProvider = plugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.chat.Chat.class);
if (chatProvider != null) {
chat = chatProvider.getProvider();
}
}
private void setupEconomy() {
RegisteredServiceProvider<Economy> economyProvider = plugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economyProvider != null) {
economy = economyProvider.getProvider();
}
}
/**
*/
public String getPrefix(Player p) {
String out = "";
@@ -500,21 +397,9 @@ public final class PermissionsManager {
}
}
// add in colorMe color
/*
Plugin colorMe = plugin.getServer().getPluginManager().getPlugin("ColorMe");
if (colorMe != null)
{
out += ((ColorMe) colorMe).getColor(p.getName());
}
*/
return out;
}
/**
*/
public String getSuffix(Player p) {
try {
if (chat != null) {
@@ -543,4 +428,12 @@ public final class PermissionsManager {
}
return "";
}
private <T> @Nullable T getProvider(Class<T> clazz) {
RegisteredServiceProvider<T> registration = Bukkit.getServicesManager().getRegistration(clazz);
if (registration != null) {
return registration.getProvider();
}
return null;
}
}
@@ -105,10 +105,8 @@ public class ProtectionManager {
}
public boolean can(@NotNull Action action, @NotNull Location location, @NotNull Player player, @Nullable Player other) {
debug(String.format("Action %s, Player %s (%s), Other Player %s", action, player, player.getUniqueId(), other));
for (Land land : getLandsAt(location)) {
for (UUID owner : land.getOwners()) {
debug(String.valueOf(owner));
if (owner == null) {
continue;
}
@@ -120,12 +118,10 @@ public class ProtectionManager {
}
if (isWarringAndAllowed(action, owner, involved) ||
isSameClanAndAllowed(action, owner, involved, land.getId())) {
debug("Allowed action");
return true;
}
}
}
debug("Denied action");
return false;
}
@@ -252,7 +248,7 @@ public class ProtectionManager {
}
if (instance instanceof ProtectionProvider) {
registerProvider((ProtectionProvider) instance);
} else {
} else if (instance != null) {
logger.warning(String.format("%s is not an instance of ProtectionProvider", className));
}
}
@@ -17,7 +17,9 @@ import java.text.MessageFormat;
import java.util.*;
import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.CLAN_MAX_MEMBERS;
import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.REQUEST_FREQUENCY;
import static org.bukkit.ChatColor.RED;
/**
* @author phaed
@@ -193,24 +195,30 @@ public final class RequestManager {
}
public void processInvite(Request req, VoteResult vote) {
Clan clan = req.getClan();
String invited = req.getTarget();
requests.remove(req.getTarget().toLowerCase());
if (vote.equals(VoteResult.ACCEPT)) {
ClanPlayer cp = plugin.getClanManager().getCreateClanPlayerUUID(invited);
if (cp == null) {
return;
}
ChatBlock.sendMessageKey(Bukkit.getPlayerExact(invited), "accepted.invitation", clan.getName());
clan.addBb(ChatColor.AQUA + lang("joined.the.clan", invited));
plugin.getClanManager().serverAnnounce(lang("has.joined", invited, clan.getName()));
clan.addPlayerToClan(cp);
} else {
ChatBlock.sendMessageKey(Bukkit.getPlayerExact(invited), "denied.invitation", clan.getName());
clan.leaderAnnounce(ChatColor.RED + lang("membership.invitation", invited));
Clan clan = req.getClan();
Player invited = Bukkit.getPlayerExact(req.getTarget());
if (invited == null) {
return;
}
requests.remove(req.getTarget().toLowerCase());
if (vote.equals(VoteResult.ACCEPT)) {
ClanPlayer cp = plugin.getClanManager().getCreateClanPlayer(invited.getUniqueId());
int maxMembers = plugin.getSettingsManager().getInt(CLAN_MAX_MEMBERS);
if (maxMembers > 0 && maxMembers > clan.getSize()) {
ChatBlock.sendMessageKey(invited, "accepted.invitation", clan.getName());
clan.addBb(ChatColor.AQUA + lang("joined.the.clan", invited.getName()));
plugin.getClanManager().serverAnnounce(lang("has.joined", invited.getName(), clan.getName()));
clan.addPlayerToClan(cp);
} else {
ChatBlock.sendMessageKey(invited, "this.clan.has.reached.the.member.limit");
}
} else {
ChatBlock.sendMessageKey(invited, "denied.invitation", clan.getName());
clan.leaderAnnounce(RED + lang("membership.invitation", invited.getName()));
}
}
public void processResults(Request req) {
@@ -258,7 +266,7 @@ public final class RequestManager {
if (!req.votingFinished()) {
return;
}
processDisband(requestClan, denies);
processDisband(requester, requestClan, denies);
break;
default:
return;
@@ -269,12 +277,12 @@ public final class RequestManager {
req.cleanVotes();
}
private void processDisband(Clan requestClan, List<String> denies) {
private void processDisband(ClanPlayer requester, Clan requestClan, List<String> denies) {
if (denies.isEmpty()) {
requestClan.disband();
requestClan.disband(requester.toPlayer(), true, false);
} else {
String deniers = Helper.toMessage(Helper.toArray(denies), ", ");
requestClan.leaderAnnounce(ChatColor.RED + lang("clan.deletion", deniers));
String deniers = String.join(", ", denies);
requestClan.leaderAnnounce(RED + lang("clan.deletion", deniers));
}
}
@@ -284,85 +292,84 @@ public final class RequestManager {
requestClan.addBb(lang("leaders"), ChatColor.AQUA + lang("promoted.to.leader", promotedName));
requestClan.promote(targetPlayer);
} else {
String deniers = Helper.toMessage(Helper.toArray(denies), ", ");
requestClan.leaderAnnounce(ChatColor.RED + lang("denied.the.promotion", deniers, promotedName));
String deniers = String.join(", ", denies);
requestClan.leaderAnnounce(RED + lang("denied.the.promotion", deniers, promotedName));
}
}
private void processDemote(Request req, Clan requestClan, UUID targetPlayer, List<String> denies) {
String demotedName = req.getTarget();
String demotedName = req.getTarget();
if (denies.isEmpty()) {
requestClan.addBb(lang("leaders"), ChatColor.AQUA
+ lang("demoted.back.to.member", demotedName));
requestClan.demote(targetPlayer);
} else {
String deniers = String.join(", ", denies);
requestClan.leaderAnnounce(
RED + lang("denied.demotion", deniers, demotedName));
}
}
if (denies.isEmpty()) {
requestClan.addBb(lang("leaders"), ChatColor.AQUA
+ lang("demoted.back.to.member", demotedName));
requestClan.demote(targetPlayer);
} else {
String deniers = Helper.toMessage(Helper.toArray(denies), ", ");
requestClan.leaderAnnounce(
ChatColor.RED + lang("denied.demotion", deniers, demotedName));
}
}
private void processBreakRivalry(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan,
List<String> accepts, List<String> denies) {
if (targetClan != null && requestClan != null) {
if (!accepts.isEmpty()) {
requestClan.removeRival(targetClan);
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("broken.the.rivalry", accepts.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("broken.the.rivalry.with", requester.getName(), targetClan.getName()));
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.to.make.peace", denies.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("peace.agreement.denied", targetClan.getName()));
}
}
}
private void processBreakRivalry(ClanPlayer requester, Clan requestClan, Clan targetClan, List<String> accepts,
List<String> denies) {
if (targetClan != null && requestClan != null) {
if (!accepts.isEmpty()) {
requestClan.removeRival(targetClan);
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("broken.the.rivalry", accepts.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("broken.the.rivalry.with", requester.getName(), targetClan.getName()));
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.to.make.peace", denies.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("peace.agreement.denied", targetClan.getName()));
}
}
}
private void processCreateAlly(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan,
List<String> accepts, List<String> denies) {
if (targetClan != null && requestClan != null) {
if (!accepts.isEmpty()) {
requestClan.addAlly(targetClan);
private void processCreateAlly(ClanPlayer requester, Clan requestClan, Clan targetClan, List<String> accepts,
List<String> denies) {
if (targetClan != null && requestClan != null) {
if (!accepts.isEmpty()) {
requestClan.addAlly(targetClan);
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("accepted.an.alliance", accepts.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("created.an.alliance", requester.getName(), targetClan.getName()));
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.an.alliance", denies.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("the.alliance.was.denied", targetClan.getName()));
}
}
}
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("accepted.an.alliance", accepts.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("created.an.alliance", requester.getName(), targetClan.getName()));
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.an.alliance", denies.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("the.alliance.was.denied", targetClan.getName()));
}
}
}
private void processEndWar(ClanPlayer requester, Clan requestClan, Clan targetClan, List<String> accepts,
private void processEndWar(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan, List<String> accepts,
List<String> denies) {
if (requestClan != null && targetClan != null) {
if (!accepts.isEmpty()) {
War war = plugin.getProtectionManager().getWar(requestClan, requestClan);
if (requestClan != null && targetClan != null) {
if (!accepts.isEmpty()) {
War war = plugin.getProtectionManager().getWar(requestClan, targetClan);
plugin.getProtectionManager().removeWar(war, WarEndEvent.Reason.REQUEST);
requestClan.removeWarringClan(targetClan);
targetClan.removeWarringClan(requestClan);
requestClan.removeWarringClan(targetClan);
targetClan.removeWarringClan(requestClan);
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("you.are.no.longer.at.war", accepts.get(0), requestClan.getColorTag()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("you.are.no.longer.at.war", requestClan.getName(), targetClan.getColorTag()));
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.war.end", denies.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("end.war.denied", targetClan.getName()));
}
}
}
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("you.are.no.longer.at.war", accepts.get(0), requestClan.getColorTag()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("you.are.no.longer.at.war", requestClan.getName(), targetClan.getColorTag()));
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.war.end", denies.get(0), requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("end.war.denied", targetClan.getName()));
}
}
}
private void processStartWar(ClanPlayer requester, Clan requestClan, Clan targetClan, List<String> accepts,
List<String> denies) {
if (requestClan != null && targetClan != null) {
if (!accepts.isEmpty()) {
plugin.getProtectionManager().addWar(requester, requestClan, targetClan);
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.war.req", denies.get(0),
private void processStartWar(ClanPlayer requester, Clan requestClan, @Nullable Clan targetClan,
List<String> accepts, List<String> denies) {
if (requestClan != null && targetClan != null) {
if (!accepts.isEmpty()) {
plugin.getProtectionManager().addWar(requester, requestClan, targetClan);
} else {
targetClan.addBb(requester.getName(), ChatColor.AQUA + lang("denied.war.req", denies.get(0),
requestClan.getName()));
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("end.war.denied",
requestClan.addBb(requester.getName(), ChatColor.AQUA + lang("end.war.denied",
targetClan.getName()));
}
}
}
}
}
}
/**
* End a pending request prematurely
@@ -373,7 +380,7 @@ public final class RequestManager {
for (Request req : new LinkedList<>(requests.values())) {
for (ClanPlayer cp : req.getAcceptors()) {
if (cp.getName().equalsIgnoreCase(playerName)) {
req.getClan().leaderAnnounce(lang("signed.off.request.cancelled", ChatColor.RED + playerName, req.getType()));
req.getClan().leaderAnnounce(lang("signed.off.request.cancelled", RED + playerName, req.getType()));
requests.remove(req.getClan().getTag());
break;
}
@@ -1,6 +1,7 @@
package net.sacredlabyrinth.phaed.simpleclans.managers;
import com.cryptomorin.xseries.XMaterial;
import net.sacredlabyrinth.phaed.simpleclans.Rank;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils;
import org.bukkit.Material;
@@ -30,7 +31,7 @@ public final class SettingsManager {
public SettingsManager(SimpleClans plugin) {
this.plugin = plugin;
this.config = plugin.getConfig();
config = plugin.getConfig();
config.options().copyDefaults(true);
configFile = new File(plugin.getDataFolder() + File.separator + "config.yml");
loadAndSave();
@@ -151,7 +152,9 @@ public final class SettingsManager {
*/
public boolean isDisallowedWord(String word) {
for (String disallowedTag : getStringList(DISALLOWED_TAGS)) {
return disallowedTag.equalsIgnoreCase(word);
if (disallowedTag.equalsIgnoreCase(word)) {
return true;
}
}
return word.equalsIgnoreCase(getString(COMMANDS_CLAN)) || word.equalsIgnoreCase(getString(COMMANDS_MORE)) ||
@@ -228,6 +231,7 @@ public final class SettingsManager {
List<String> bannedPlayers = getStringList(BANNED_PLAYERS);
bannedPlayers.remove(playerUniqueId.toString());
set(BANNED_PLAYERS, bannedPlayers);
save();
}
public boolean isActionAllowedInWar(@NotNull ProtectionManager.Action action) {
@@ -247,6 +251,22 @@ public final class SettingsManager {
}
}
@SuppressWarnings("unchecked")
public @NotNull Collection<Rank> getStarterRanks() {
List<Rank> ranks = new ArrayList<>();
List<Map<?, ?>> mapList = config.getMapList("clan.starter-ranks");
for (Map<?, ?> rankMap : mapList) {
Set<String> names = (Set<String>) rankMap.keySet();
for (String name : names) {
Map<String, Object> rank = (Map<String, Object>) rankMap.get(name);
String displayName = (String) rank.get("display-name");
List<String> permissions = (List<String>) rank.get("permissions");
ranks.add(new Rank(name, displayName, new HashSet<>(permissions)));
}
}
return ranks;
}
public FileConfiguration getConfig() {
return config;
}
@@ -292,6 +312,8 @@ public final class SettingsManager {
LIST_DEFAULT_ORDER_BY("settings.list-default-order-by", "kdr"),
LORE_LENGTH("settings.lore-length", 36),
PVP_ONLY_WHILE_IN_WAR("settings.pvp-only-while-at-war", false),
PAST_CLANS_LIMIT("settings.past-clans-limit", 10),
USERNAME_REGEX("settings.username-regex", "^\\**[a-zA-Z0-9_$]{1,16}$"),
/*
================
> Tag Settings
@@ -307,6 +329,8 @@ public final class SettingsManager {
TAG_MIN_LENGTH("tag.min-length", 2),
TAG_SEPARATOR_COLOR("tag.separator.color", "8"),
TAG_SEPARATOR_LEADER_COLOR("tag.separator.leader-color", "4"),
TAG_SEPARATOR_CHAR("tag.separator.char", " ."),
@Deprecated
TAG_SEPARATOR_char("tag.separator.char", " ."),
/*
================
@@ -376,6 +400,8 @@ public final class SettingsManager {
ECONOMY_PURCHASE_HOME_TELEPORT_SET("economy.purchase-home-teleport-set", false),
ECONOMY_REGROUP_PRICE("economy.home-regroup-price", 5.0),
ECONOMY_PURCHASE_HOME_REGROUP("economy.purchase-home-regroup", false),
ECONOMY_PURCHASE_DISCORD_CREATE("economy.purchase-discord-create", false),
ECONOMY_DISCORD_CREATION_PRICE("economy.discord-creation-price", 1000.0),
ECONOMY_UNIQUE_TAX_ON_REGROUP("economy.unique-tax-on-regroup", true),
ECONOMY_ISSUER_PAYS_REGROUP("economy.issuer-pays-regroup", true),
ECONOMY_MONEY_PER_KILL("economy.money-per-kill", false),
@@ -450,6 +476,7 @@ public final class SettingsManager {
PAGE_HEADINGS_COLOR("page.headings-color", "8"),
PAGE_SEPARATOR("page.separator", "-"),
PAGE_SIZE("page.size", 100),
HELP_SIZE("page.help-size", 10),
/*
================
> Clan Chat Settings
@@ -472,6 +499,7 @@ public final class SettingsManager {
CLANCHAT_PLAYER_BRACKET_LEFT("clanchat.player-bracket.left", ""),
CLANCHAT_PLAYER_BRACKET_RIGHT("clanchat.player-bracket.right", ""),
CLANCHAT_MESSAGE_COLOR("clanchat.message-color", "b"),
CLANCHAT_LISTENER_PRIORITY("clanchat.listener-priority", "LOW"),
/*
================
> Request Settings
@@ -486,11 +514,11 @@ public final class SettingsManager {
> BB Settings
================
*/
BB_COLOR("clanchat.color", "e"),
BB_ACCENT_COLOR("clanchat.accent-color", "8"),
BB_SHOW_ON_LOGIN("clanchat.show-on-login", true),
BB_SIZE("clanchat.size", 6),
BB_LOGIN_SIZE("clanchat.login-size", 6),
BB_COLOR("bb.color", "e"),
BB_ACCENT_COLOR("bb.accent-color", "8"),
BB_SHOW_ON_LOGIN("bb.show-on-login", true),
BB_SIZE("bb.size", 6),
BB_LOGIN_SIZE("bb.login-size", 6),
/*
================
> Ally Chat Settings
@@ -516,6 +544,7 @@ public final class SettingsManager {
================
*/
DISCORDCHAT_ENABLE("discordchat.enable", false),
DISCORDCHAT_AUTO_CREATION("discordchat.auto-creation", true),
DISCORDCHAT_FORMAT_TO("discordchat.discord-format", "%player% » %message%"),
DISCORDCHAT_FORMAT("discordchat.format", "&b[&9D&b] &b[%clan%&b] &4<%nick-color%%player%&4> %rank%: &b%message%"),
DISCORDCHAT_SPYFORMAT("discordchat.spy-format", "&8[Spy] [&9D&8] <%clan%&8> <%nick-color%*&8%player%>&8 %rank%: %message%"),
@@ -527,6 +556,7 @@ public final class SettingsManager {
DISCORDCHAT_TEXT_CATEGORY_IDS("discordchat.text.category-ids"),
DISCORDCHAT_TEXT_WHITELIST("discordchat.text.whitelist"),
DISCORDCHAT_TEXT_LIMIT("discordchat.text.clans-limit", 100),
DISCORDCHAT_MINIMUM_LINKED_PLAYERS("discordchat.min-linked-players-to-create", 3),
/*
================
> Purge Settings
@@ -575,7 +605,7 @@ public final class SettingsManager {
ConfigField(String path) {
this.path = path;
this.defaultValue = null;
defaultValue = null;
}
}
}
@@ -4,6 +4,7 @@ import com.google.common.base.Charsets;
import net.sacredlabyrinth.phaed.simpleclans.*;
import net.sacredlabyrinth.phaed.simpleclans.events.ClanBalanceUpdateEvent;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankLogger;
import net.sacredlabyrinth.phaed.simpleclans.loggers.BankOperator;
import net.sacredlabyrinth.phaed.simpleclans.storage.DBCore;
import net.sacredlabyrinth.phaed.simpleclans.storage.MySQLCore;
import net.sacredlabyrinth.phaed.simpleclans.storage.SQLiteCore;
@@ -18,7 +19,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.simple.JSONObject;
import java.sql.*;
import java.text.MessageFormat;
@@ -285,6 +285,7 @@ public final class StorageManager {
* Used for BungeeCord Reload ClanPlayer and your Clan
*
*/
@Deprecated
public void importFromDatabaseOnePlayer(Player player) {
plugin.getClanManager().deleteClanPlayerFromMemory(player.getUniqueId());
@@ -297,8 +298,8 @@ public final class StorageManager {
tm.importMember(cp);
}
plugin.getClanManager().importClanPlayer(cp);
plugin.getLogger().info("ClanPlayer Reloaded: " + player.getName() + ", UUID: " + player.getUniqueId().toString());
plugin.getLogger().info("ClanPlayer Reloaded: " + player.getName() + ", UUID: " + player.getUniqueId());
}
}
@@ -377,7 +378,7 @@ public final class StorageManager {
String packed_rivals = res.getString("packed_rivals");
String packed_bb = res.getString("packed_bb");
String flags = res.getString("flags");
JSONObject ranks = Helper.parseJson(res.getString("ranks"));
String ranksJson = res.getString("ranks");
long founded = res.getLong("founded");
long last_used = res.getLong("last_used");
double balance = res.getDouble("balance");
@@ -406,11 +407,11 @@ public final class StorageManager {
clan.setPackedBb(packed_bb);
clan.setFounded(founded);
clan.setLastUsed(last_used);
clan.setBalance(null, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, balance);
clan.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, balance);
clan.setMemberFee(feeValue);
clan.setMemberFeeEnabled(feeEnabled);
clan.setRanks(Helper.ranksFromJson(ranks));
clan.setDefaultRank(Helper.defaultRankFromJson(ranks));
clan.setRanks(Helper.ranksFromJson(ranksJson));
clan.setDefaultRank(Helper.defaultRankFromJson(ranksJson));
clan.setBanner(banner);
out.add(clan);
@@ -451,7 +452,7 @@ public final class StorageManager {
String packed_rivals = res.getString("packed_rivals");
String packed_bb = res.getString("packed_bb");
String flags = res.getString("flags");
JSONObject ranks = Helper.parseJson(res.getString("ranks"));
String ranksJson = res.getString("ranks");
long founded = res.getLong("founded");
long last_used = res.getLong("last_used");
double balance = res.getDouble("balance");
@@ -480,11 +481,11 @@ public final class StorageManager {
clan.setPackedBb(packed_bb);
clan.setFounded(founded);
clan.setLastUsed(last_used);
clan.setBalance(null, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, balance);
clan.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, balance);
clan.setMemberFee(feeValue);
clan.setMemberFeeEnabled(feeEnabled);
clan.setRanks(Helper.ranksFromJson(ranks));
clan.setDefaultRank(Helper.defaultRankFromJson(ranks));
clan.setRanks(Helper.ranksFromJson(ranksJson));
clan.setDefaultRank(Helper.defaultRankFromJson(ranksJson));
clan.setBanner(banner);
out = clan;
@@ -535,11 +536,7 @@ public final class StorageManager {
if (last_seen == 0) {
last_seen = (new Date()).getTime();
}
if (join_date == 0) {
join_date = (new Date()).getTime();
}
}
ClanPlayer cp = new ClanPlayer();
if (uuid != null) {
@@ -619,10 +616,6 @@ public final class StorageManager {
last_seen = (new Date()).getTime();
}
if (join_date == 0) {
join_date = (new Date()).getTime();
}
ClanPlayer cp = new ClanPlayer();
if (uuid != null) {
cp.setUniqueId(UUID.fromString(uuid));
@@ -660,7 +653,7 @@ public final class StorageManager {
clanReSync.setPackedBb(clanDB.getPackedBb());
clanReSync.setFounded(clanDB.getFounded());
clanReSync.setLastUsed(clanDB.getLastUsed());
clanReSync.setBalance(null, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, clanDB.getBalance());
clanReSync.setBalance(BankOperator.INTERNAL, ClanBalanceUpdateEvent.Cause.LOADING, BankLogger.Operation.SET, clanDB.getBalance());
cp.setClan(clanReSync);
} else {
plugin.getClanManager().importClan(clanDB);
@@ -689,29 +682,31 @@ public final class StorageManager {
*
*/
public void insertClan(Clan clan) {
plugin.getProxyManager().sendUpdate(clan);
String query = "INSERT INTO `sc_clans` (`banner`, `ranks`, `description`, `fee_enabled`, `fee_value`, `verified`, `tag`," +
" `color_tag`, `name`, `friendly_fire`, `founded`, `last_used`, `packed_allies`, `packed_rivals`, " +
"`packed_bb`, `cape_url`, `flags`, `balance`) ";
String values = "VALUES ( '"
+ Helper.escapeQuotes(YAMLSerializer.serialize(clan.getBanner())) + "','"
+ Helper.escapeQuotes(Helper.ranksToJson(clan.getRanks(), clan.getDefaultRank())) + "','"
+ Helper.escapeQuotes(clan.getDescription())+ "',"
+ Helper.escapeQuotes(clan.getDescription())+ "',"
+ (clan.isMemberFeeEnabled() ? 1 : 0) +","
+ Helper.escapeQuotes(String.valueOf(clan.getMemberFee())) + ","
+ (clan.isVerified() ? 1 : 0) + ",'"
+ Helper.escapeQuotes(clan.getTag()) + "','"
+ Helper.escapeQuotes(clan.getColorTag()) + "','"
+ Helper.escapeQuotes(clan.getName()) + "',"
+ (clan.isFriendlyFire() ? 1 : 0) + ",'"
+ clan.getFounded() + "','"
+ clan.getLastUsed() + "','"
+ Helper.escapeQuotes(clan.getPackedAllies()) + "','"
+ Helper.escapeQuotes(clan.getPackedRivals()) + "','"
+ Helper.escapeQuotes(clan.getPackedBb()) + "','"
+ Helper.escapeQuotes(clan.getCapeUrl()) + "','"
+ Helper.escapeQuotes(clan.getFlags()) + "','"
+ Helper.escapeQuotes(String.valueOf(clan.getMemberFee())) + ","
+ (clan.isVerified() ? 1 : 0) + ",'"
+ Helper.escapeQuotes(clan.getTag()) + "','"
+ Helper.escapeQuotes(clan.getColorTag()) + "','"
+ Helper.escapeQuotes(clan.getName()) + "',"
+ (clan.isFriendlyFire() ? 1 : 0) + ",'"
+ clan.getFounded() + "','"
+ clan.getLastUsed() + "','"
+ Helper.escapeQuotes(clan.getPackedAllies()) + "','"
+ Helper.escapeQuotes(clan.getPackedRivals()) + "','"
+ Helper.escapeQuotes(clan.getPackedBb()) + "','"
+ Helper.escapeQuotes(clan.getCapeUrl()) + "','"
+ Helper.escapeQuotes(clan.getFlags()) + "','"
+ Helper.escapeQuotes(String.valueOf(clan.getBalance())) + "');";
core.insert(query + values);
core.executeUpdate(query + values);
}
/**
@@ -731,13 +726,13 @@ public final class StorageManager {
/**
* Change the name of a player in the database asynchronously
*
* @param p to update
* @param cp to update
*/
public void updatePlayerNameAsync(final Player p) {
public void updatePlayerNameAsync(final @NotNull ClanPlayer cp) {
new BukkitRunnable() {
@Override
public void run() {
updatePlayerName(p);
updatePlayerName(cp);
}
}.runTaskAsynchronously(plugin);
}
@@ -745,11 +740,11 @@ public final class StorageManager {
/**
* Change the name of a player in the database
*
* @param p to update
* @param cp to update
*/
public void updatePlayerName(final Player p) {
String query = "UPDATE `sc_players` SET `name` = '" + p.getName() + "' WHERE uuid = '" + p.getUniqueId().toString() + "';";
core.update(query);
public void updatePlayerName(final @NotNull ClanPlayer cp) {
String query = "UPDATE `sc_players` SET `name` = '" + cp.getName() + "' WHERE uuid = '" + cp.getUniqueId() + "';";
core.executeUpdate(query);
}
/**
@@ -759,7 +754,7 @@ public final class StorageManager {
public void updateClan(Clan clan) {
updateClan(clan, true);
}
/**
* Update a clan to the database
*
@@ -771,6 +766,7 @@ public final class StorageManager {
if (updateLastUsed) {
clan.updateLastUsed();
}
plugin.getProxyManager().sendUpdate(clan);
if (plugin.getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) {
modifiedClans.add(clan);
return;
@@ -815,8 +811,9 @@ public final class StorageManager {
* Delete a clan from the database
*/
public void deleteClan(Clan clan) {
plugin.getProxyManager().sendDelete(clan);
String query = "DELETE FROM `sc_clans` WHERE tag = '" + clan.getTag() + "';";
core.delete(query);
core.executeUpdate(query);
}
/**
@@ -824,9 +821,17 @@ public final class StorageManager {
*
*/
public void insertClanPlayer(ClanPlayer cp) {
String query = "INSERT INTO `sc_players` (`locale`, `resign_times`, `uuid`, `name`, `leader`, `tag`, `friendly_fire`, `neutral_kills`, `rival_kills`, `civilian_kills`, `deaths`, `last_seen`, `join_date`, `packed_past_clans`, `flags`) ";
String values = "VALUES ('"+cp.getLocale().toLanguageTag()+"', '"+ Helper.escapeQuotes(Helper.resignTimesToJson(cp.getResignTimes()))+ "', '" + cp.getUniqueId().toString() + "', '" + cp.getName() + "'," + (cp.isLeader() ? 1 : 0) + ",'" + Helper.escapeQuotes(cp.getTag()) + "'," + (cp.isFriendlyFire() ? 1 : 0) + "," + cp.getNeutralKills() + "," + cp.getRivalKills() + "," + cp.getCivilianKills() + "," + cp.getDeaths() + ",'" + cp.getLastSeen() + "',' " + cp.getJoinDate() + "','" + Helper.escapeQuotes(cp.getPackedPastClans()) + "','" + Helper.escapeQuotes(cp.getFlags()) + "');";
core.insert(query + values);
plugin.getProxyManager().sendUpdate(cp);
String query = "INSERT INTO `sc_players` (`uuid`, `name`, `leader`, `tag`, `friendly_fire`, `neutral_kills`, " +
"`rival_kills`, `civilian_kills`, `deaths`, `last_seen`, `join_date`, `packed_past_clans`, `flags`) ";
String values = "VALUES ('" + cp.getUniqueId().toString() + "', '" + cp.getName() + "',"
+ (cp.isLeader() ? 1 : 0) + ",'" + Helper.escapeQuotes(cp.getTag()) + "',"
+ (cp.isFriendlyFire() ? 1 : 0) + "," + cp.getNeutralKills() + "," + cp.getRivalKills()
+ "," + cp.getCivilianKills() + "," + cp.getDeaths() + ",'" + cp.getLastSeen() + "',' "
+ cp.getJoinDate() + "','" + Helper.escapeQuotes(cp.getPackedPastClans()) + "','"
+ Helper.escapeQuotes(cp.getFlags()) + "');";
core.executeUpdate(query + values);
}
/**
@@ -849,6 +854,7 @@ public final class StorageManager {
*/
public void updateClanPlayer(ClanPlayer cp) {
cp.updateLastSeen();
plugin.getProxyManager().sendUpdate(cp);
if (plugin.getSettingsManager().is(PERFORMANCE_SAVE_PERIODICALLY)) {
modifiedClanPlayers.add(cp);
return;
@@ -869,7 +875,7 @@ public final class StorageManager {
}
private void setValues(PreparedStatement statement, ClanPlayer cp) throws SQLException {
statement.setString(1, cp.getLocale().toLanguageTag());
statement.setString(1, Helper.toLanguageTag(cp.getLocale()));
statement.setString(2, Helper.resignTimesToJson(cp.getResignTimes()));
statement.setInt(3, cp.isLeader() ? 1 : 0);
statement.setString(4, cp.getTag());
@@ -896,8 +902,9 @@ public final class StorageManager {
clan.addBbWithoutSaving(ChatColor.AQUA + MessageFormat.format(lang("has.been.purged"), cp.getName()));
updateClan(clan, false);
}
plugin.getProxyManager().sendDelete(cp);
String query = "DELETE FROM `sc_players` WHERE uuid = '" + cp.getUniqueId() + "';";
core.delete(query);
core.executeUpdate(query);
deleteKills(cp.getUniqueId());
}
@@ -909,7 +916,7 @@ public final class StorageManager {
public void insertKill(Player attacker, String attackerTag, Player victim, String victimTag, String type) {
String query = "INSERT INTO `sc_kills` ( `attacker_uuid`, `attacker`, `attacker_tag`, `victim_uuid`, `victim`, `victim_tag`, `kill_type`) ";
String values = "VALUES ( '" + attacker.getUniqueId() + "','" + attacker.getName() + "','" + attackerTag + "','" + victim.getUniqueId() + "','" + victim.getName() + "','" + victimTag + "','" + type + "');";
core.insert(query + values);
core.executeUpdate(query + values);
}
/**
@@ -924,7 +931,7 @@ public final class StorageManager {
"`victim`, `victim_tag`, `kill_type`) ";
String values = "VALUES ( '" + attacker.getUniqueId() + "','" + attacker.getName() + "','" + attacker.getTag()
+ "','" + victim.getUniqueId() + "','" + victim.getName() + "','" + victim.getTag() + "','" + type + "');";
core.insert(query + values);
core.executeUpdate(query + values);
}
/**
@@ -934,7 +941,7 @@ public final class StorageManager {
@Deprecated
public void deleteKills(String playerName) {
String query = "DELETE FROM `sc_kills` WHERE `attacker` = '" + playerName + "'";
core.delete(query);
core.executeUpdate(query);
}
/**
@@ -943,11 +950,15 @@ public final class StorageManager {
*/
public void deleteKills(UUID playerUniqueId) {
String query = "DELETE FROM `sc_kills` WHERE `attacker_uuid` = '" + playerUniqueId + "'";
core.delete(query);
core.executeUpdate(query);
}
/**
* Returns a map of victim->count of all kills that specific player did
* Returns a map of victim-{@literal >}count of all kills that specific player did
*
* @param playerName the attacker name
*
* @return a map of kills per victim
*
*/
public Map<String, Integer> getKillsPerPlayer(String playerName) {
@@ -979,8 +990,9 @@ public final class StorageManager {
}
/**
* Returns a map of tag->count of all kills
* Returns a map of tag-{@literal >}count of all kills
*
* @return a map of kills per attacker+victim
*/
public Map<String, Integer> getMostKilled() {
HashMap<String, Integer> out = new HashMap<>();
@@ -1012,21 +1024,22 @@ public final class StorageManager {
}
/**
* Gets, asynchronously, a map of tag->count of all kills and notifies via callback when it's ready
*
* Gets, asynchronously, a map of tag-{@literal >}count of all kills and notifies via callback when it's ready
*
* @param callback the callback
*/
public void getMostKilled(DataCallback<Map<String, Integer>> callback) {
new BukkitRunnable() {
@Override
public void run() {
callback.onResultReady(getMostKilled());
}
}.runTaskAsynchronously(plugin);
}
/**
* Gets, asynchronously, a map of victim->count of all kills that specific player did and notifies via callback when it's ready
* Gets, asynchronously, a map of victim-{@literal >}count of all kills that specific player did and notifies via callback when it's ready
*
*/
public void getKillsPerPlayer(final String playerName, final DataCallback<Map<String, Integer>> callback) {
@@ -1037,21 +1050,21 @@ public final class StorageManager {
}
}.runTaskAsynchronously(plugin);
}
/**
* Callback that returns some data
*
*
* @author roinujnosde
*
*/
public interface DataCallback<T> {
/**
* Notifies when the result is ready
*
*
*/
void onResultReady(T data);
}
/**
* Updates the database to the latest version
*
@@ -1162,7 +1175,7 @@ public final class StorageManager {
* Updates the database to the latest version
*
*/
private void updatePlayersToUUID() {
plugin.getLogger().log(Level.WARNING, "Starting Migration to UUID Players !");
plugin.getLogger().log(Level.WARNING, "==================== ATTENTION DONT STOP BUKKIT ! ==================== ");
@@ -1181,13 +1194,13 @@ public final class StorageManager {
uuidPlayer = UUID.nameUUIDFromBytes(("OfflinePlayer:" + cp.getName()).getBytes(Charsets.UTF_8));
}
String query = "UPDATE `sc_players` SET uuid = '" + uuidPlayer.toString() + "' WHERE name = '" + cp.getName() + "';";
core.update(query);
core.executeUpdate(query);
String query2 = "UPDATE `sc_kills` SET attacker_uuid = '" + uuidPlayer.toString() + "' WHERE attacker = '" + cp.getName() + "';";
core.update(query2);
String query2 = "UPDATE `sc_kills` SET attacker_uuid = '" + uuidPlayer + "' WHERE attacker = '" + cp.getName() + "';";
core.executeUpdate(query2);
String query3 = "UPDATE `sc_kills` SET victim_uuid = '" + uuidPlayer.toString() + "' WHERE victim = '" + cp.getName() + "';";
core.update(query3);
String query3 = "UPDATE `sc_kills` SET victim_uuid = '" + uuidPlayer + "' WHERE victim = '" + cp.getName() + "';";
core.executeUpdate(query3);
plugin.getLogger().info("[" + i + " / " + cps.size() + "] Success: " + cp.getName() + "; UUID: " + uuidPlayer.toString());
} catch (Exception ex) {
plugin.getLogger().log(Level.WARNING, "[" + i + " / " + cps.size() + "] Failed [ERRO]: " + cp.getName() + "; UUID: ???");
@@ -1205,10 +1218,10 @@ public final class StorageManager {
SimpleClans.getInstance().setUUID(true);
}
/**
* Saves modified Clans and ClanPlayers to the database
*
*
* @author RoinujNosde
* @since 2.10.2
*/
@@ -2,9 +2,12 @@ package net.sacredlabyrinth.phaed.simpleclans.managers;
import io.papermc.lib.PaperLib;
import net.sacredlabyrinth.phaed.simpleclans.*;
import net.sacredlabyrinth.phaed.simpleclans.events.ClanPlayerTeleportEvent;
import net.sacredlabyrinth.phaed.simpleclans.utils.VanishUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.ItemStack;
@@ -23,6 +26,9 @@ import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.Con
import static org.bukkit.ChatColor.AQUA;
import static org.bukkit.ChatColor.RED;
/**
* Class responsible for managing teleports and its queue
*/
public final class TeleportManager {
private final SimpleClans plugin;
private final HashMap<String, TeleportState> waitingPlayers = new HashMap<>();
@@ -40,15 +46,157 @@ public final class TeleportManager {
* @param clanName the Clan name
*/
public void addPlayer(Player player, Location destination, String clanName) {
PermissionsManager pm = plugin.getPermissionsManager();
int secs = SimpleClans.getInstance().getSettingsManager().getInt(CLAN_TELEPORT_DELAY);
waitingPlayers.put(player.getUniqueId().toString(), new TeleportState(player, destination, clanName));
if (pm.has(player, "simpleclans.mod.bypass") || pm.has(player, "simpleclans.vip.teleport-delay")) {
secs = 0;
}
waitingPlayers.put(player.getUniqueId().toString(), new TeleportState(player, destination, clanName, secs));
if (secs > 0) {
ChatBlock.sendMessage(player, AQUA
+ MessageFormat.format(lang("waiting.for.teleport.stand.still.for.0.seconds", player), secs));
ChatBlock.sendMessage(player, AQUA + lang("waiting.for.teleport.stand.still.for.0.seconds", player, secs));
}
}
/**
* Teleports all online and non-vanished members of this {@link Clan} to the specified {@link Location}
*
* @param requester the Player requesting the teleport
* @param clan the Clan
* @param location the Location
*/
public void teleport(@NotNull Player requester, @NotNull Clan clan, @NotNull Location location) {
teleport(clan, location, VanishUtils.getNonVanished(requester, clan));
}
/**
* Teleports all online and non-vanished members of this {@link Clan} to the specified {@link Location}
*
* @param clan the Clan
* @param location the Location
*/
public void teleport(Clan clan, Location location) {
teleport(clan, location, VanishUtils.getNonVanished(null, clan));
}
public void teleportToHome(@NotNull Player player, @NotNull Location destination, @NotNull String clanName) {
PaperLib.teleportAsync(player, getSafe(destination), PlayerTeleportEvent.TeleportCause.COMMAND).thenAccept(result -> {
if (result) {
ChatBlock.sendMessage(player, AQUA + lang("now.at.homebase", player, clanName));
} else {
plugin.getLogger().log(Level.WARNING, "An error occurred while teleporting a player");
}
});
}
public void teleportToHome(@NotNull Player player, @NotNull Clan clan) {
if (clan.getHomeLocation() == null) {
return;
}
teleportToHome(player, clan.getHomeLocation(), clan.getName());
}
private boolean isSameBlock(Location loc, Location loc2) {
return loc.getBlockX() == loc2.getBlockX() && loc.getBlockY() == loc2.getBlockY() &&
loc.getBlockZ() == loc2.getBlockZ();
}
/**
* Converts the specified {@link Location} to a safe one, i.e. where there is no risk of suffocation
*
* @param location the Location
* @return the safe Location
*/
public @NotNull Location getSafe(@NotNull Location location) {
int counter = 0;
while (counter < 256) { //max world height
counter++;
Block bottom = location.getBlock();
Block top = location.add(0, 1, 0).getBlock();
if (!isAir(bottom)) {
continue;
}
if (!isAir(top)) {
location.add(0, 1, 0); //skips checking the same block again
continue;
}
location.subtract(0, 1, 0); //remove what was added above
return location;
}
//noinspection ConstantConditions
location.setY(location.getWorld().getHighestBlockYAt(location) + 1);
return location;
}
private void dropItems(Player player) {
if (plugin.getPermissionsManager().has(player, "simpleclans.mod.keep-items")) {
return;
}
List<Material> itemsList = plugin.getSettingsManager().getItemList();
PlayerInventory inv = player.getInventory();
boolean dropOnHome = plugin.getSettingsManager().is(DROP_ITEMS_ON_CLAN_HOME);
boolean keepOnHome = plugin.getSettingsManager().is(KEEP_ITEMS_ON_CLAN_HOME);
ItemStack[] contents = inv.getContents();
for (ItemStack item : contents) {
if (item == null) {
continue;
}
if ((dropOnHome && itemsList.contains(item.getType())) ||
(keepOnHome && !itemsList.contains(item.getType()))) {
player.getWorld().dropItemNaturally(player.getLocation(), item);
inv.remove(item);
}
}
}
private void startCounter() {
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
waitingPlayers.values().removeIf(ts -> ts.getPlayer() == null);
for (Iterator<TeleportState> iter = waitingPlayers.values().iterator(); iter.hasNext(); ) {
TeleportState state = iter.next();
Player player = state.getPlayer();
if (state.isProcessing() || player == null) {
continue;
}
state.setProcessing(true);
if (!isSameBlock(player.getLocation(), state.getLocation())) {
ChatBlock.sendMessage(player, RED + lang("you.moved.teleport.cancelled", player));
iter.remove();
continue;
}
if (state.isTeleportTime()) {
teleport(state);
iter.remove();
} else {
ChatBlock.sendMessage(player, AQUA + "" + state.getCounter());
}
state.setProcessing(false);
}
}, 0, 20L);
}
private void teleport(TeleportState state) {
Player player = state.getPlayer();
if (player == null) {
return;
}
ClanPlayer cp = plugin.getClanManager().getCreateClanPlayer(player.getUniqueId());
ClanPlayerTeleportEvent event = new ClanPlayerTeleportEvent(cp, state.getLocation(), state.getDestination());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
Location loc = state.getDestination();
sendTeleportBlocks(player, loc);
dropItems(player);
loc.clone().add(.5, .5, .5);
teleportToHome(player, loc, state.getClanName());
}
@SuppressWarnings("deprecation")
private void sendTeleportBlocks(Player player, Location loc) {
int x = loc.getBlockX();
@@ -90,89 +238,20 @@ public final class TeleportManager {
}
}
public void teleport(@NotNull Player requester, @NotNull Clan clan, @NotNull Location location) {
teleport(clan, location, VanishUtils.getNonVanished(requester, clan));
}
public void teleport(Clan clan, Location location) {
teleport(clan, location, VanishUtils.getNonVanished(null, clan));
}
private void dropItems(Player player) {
if (plugin.getPermissionsManager().has(player, "simpleclans.mod.keep-items")) {
return;
}
List<Material> itemsList = plugin.getSettingsManager().getItemList();
PlayerInventory inv = player.getInventory();
boolean dropOnHome = plugin.getSettingsManager().is(DROP_ITEMS_ON_CLAN_HOME);
boolean keepOnHome = plugin.getSettingsManager().is(KEEP_ITEMS_ON_CLAN_HOME);
ItemStack[] contents = inv.getContents();
for (ItemStack item : contents) {
if (item == null) {
continue;
}
if ((dropOnHome && itemsList.contains(item.getType())) ||
(keepOnHome && !itemsList.contains(item.getType()))) {
player.getWorld().dropItemNaturally(player.getLocation(), item);
inv.remove(item);
/**
* Checks if all passed blocks are some kind of AIR
*
* @param blocks blocks to test
* @return true if all blocks are AIR
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean isAir(@NotNull Block... blocks) {
for (Block b : blocks) {
if (!b.getType().name().contains("AIR")) {
return false;
}
}
return true;
}
private void startCounter() {
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
waitingPlayers.values().removeIf(ts -> ts.getPlayer() == null);
for (Iterator<TeleportState> iter = waitingPlayers.values().iterator(); iter.hasNext(); ) {
TeleportState state = iter.next();
Player player = state.getPlayer();
if (state.isProcessing() || player == null) {
continue;
}
state.setProcessing(true);
if (!Helper.isSameBlock(player.getLocation(), state.getLocation())) {
ChatBlock.sendMessage(player, RED + lang("you.moved.teleport.cancelled", player));
iter.remove();
continue;
}
if (state.isTeleportTime()) {
teleport(state);
iter.remove();
} else {
ChatBlock.sendMessage(player, AQUA + "" + state.getCounter());
}
state.setProcessing(false);
}
}, 0, 20L);
}
private void teleport(TeleportState state) {
Player player = state.getPlayer();
if (player == null) {
return;
}
Location loc = state.getDestination();
sendTeleportBlocks(player, loc);
dropItems(player);
loc.clone().add(.5, .5, .5);
teleportToHome(player, loc, state.getClanName());
}
public void teleportToHome(@NotNull Player player, @NotNull Location destination, @NotNull String clanName) {
PaperLib.teleportAsync(player, destination, PlayerTeleportEvent.TeleportCause.COMMAND).thenAccept(result -> {
if (result) {
ChatBlock.sendMessage(player, AQUA + lang("now.at.homebase", player, clanName));
} else {
plugin.getLogger().log(Level.WARNING, "An error occurred while teleporting a player");
}
});
}
public void teleportToHome(@NotNull Player player, @NotNull Clan clan) {
if (clan.getHomeLocation() == null) {
return;
}
teleportToHome(player, clan.getHomeLocation(), clan.getName());
}
}
@@ -0,0 +1,213 @@
package net.sacredlabyrinth.phaed.simpleclans.proxy;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField;
import net.sacredlabyrinth.phaed.simpleclans.proxy.adapters.ClanPlayerListAdapter;
import net.sacredlabyrinth.phaed.simpleclans.proxy.adapters.ClanPlayerTypeAdapterFactory;
import net.sacredlabyrinth.phaed.simpleclans.proxy.adapters.ConfigurationSerializableAdapter;
import net.sacredlabyrinth.phaed.simpleclans.proxy.adapters.SCMessageAdapter;
import net.sacredlabyrinth.phaed.simpleclans.proxy.listeners.MessageListener;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.messaging.PluginMessageListener;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.logging.Level;
public final class BungeeManager implements ProxyManager, PluginMessageListener {
private static final String UPDATE_CLAN_CHANNEL = "UpdateClan";
private static final String UPDATE_CLANPLAYER_CHANNEL = "UpdateClanPlayer";
private static final String DELETE_CLAN_CHANNEL = "DeleteClan";
private static final String DELETE_CLANPLAYER_CHANNEL = "DeleteClanPlayer";
private static final String CHAT_CHANNEL = "Chat";
private final SimpleClans plugin;
private final Gson gson;
private final List<String> onlinePlayers = new ArrayList<>();
private String serverName = "";
private final Set<String> unknownChannels = new HashSet<>();
public BungeeManager(SimpleClans plugin) {
this.plugin = plugin;
gson = new GsonBuilder().registerTypeAdapterFactory(new ClanPlayerTypeAdapterFactory(plugin))
.registerTypeAdapterFactory(new ConfigurationSerializableAdapter())
.registerTypeAdapter(ClanPlayerListAdapter.getType(), new ClanPlayerListAdapter(plugin))
.registerTypeAdapter(SCMessage.class, new SCMessageAdapter(plugin)).setExclusionStrategies()
.create();
if (!plugin.getSettingsManager().is(ConfigField.PERFORMANCE_USE_BUNGEECORD)) {
return;
}
Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, "BungeeCord");
Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "BungeeCord", this);
Bukkit.getScheduler().runTaskTimer(plugin, this::requestPlayerList, 0, 60 * 20);
requestServerName();
}
@SuppressWarnings("UnstableApiUsage")
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] data) {
ByteArrayDataInput input = ByteStreams.newDataInput(data);
String subChannel = input.readUTF();
if (unknownChannels.contains(subChannel)) {
return;
}
SimpleClans.debug("Message received, sub-channel: " + subChannel);
try {
Class<?> clazz = Class.forName("net.sacredlabyrinth.phaed.simpleclans.proxy.listeners." + subChannel);
MessageListener listener = (MessageListener) clazz.getConstructor(BungeeManager.class).newInstance(this);
listener.accept(input);
SimpleClans.debug("Message processed");
} catch (ClassNotFoundException e) {
SimpleClans.debug(String.format("Unknown channel: %s", subChannel));
unknownChannels.add(subChannel);
} catch (ReflectiveOperationException ex) {
plugin.getLogger().log(Level.SEVERE, String.format("Error processing channel %s", subChannel), ex);
}
}
@Override
public boolean isOnline(String playerName) {
if (Bukkit.getOnlinePlayers().stream().anyMatch(player -> player.getName().equals(playerName))) {
return true;
}
return onlinePlayers.contains(playerName);
}
public void setOnlinePlayers(@NotNull List<String> onlinePlayers) {
this.onlinePlayers.clear();
this.onlinePlayers.addAll(onlinePlayers);
}
@Override
public String getServerName() {
return serverName;
}
public void setServerName(@NotNull String name) {
this.serverName = name;
}
@Override
public void sendMessage(SCMessage message) {
forwardPluginMessage(CHAT_CHANNEL, gson.toJson(message), false);
}
@SuppressWarnings("UnstableApiUsage")
@Override
public void sendMessage(@NotNull String target, @NotNull String message) {
if (isChannelRegistered()) {
ByteArrayDataOutput output = ByteStreams.newDataOutput();
output.writeUTF("Message");
output.writeUTF(target);
output.writeUTF(message);
sendOnBungeeChannel(output);
} else {
if ("ALL".equals(target)) {
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(message));
} else {
Optional.ofNullable(Bukkit.getPlayer(target)).ifPresent(p -> p.sendMessage(message));
}
}
}
@Override
public void sendDelete(Clan clan) {
forwardPluginMessage(DELETE_CLAN_CHANNEL, clan.getTag());
}
@Override
public void sendDelete(ClanPlayer cp) {
forwardPluginMessage(DELETE_CLANPLAYER_CHANNEL, cp.getUniqueId().toString());
}
@Override
public void sendUpdate(Clan clan) {
forwardPluginMessage(UPDATE_CLAN_CHANNEL, gson.toJson(clan));
}
@Override
public void sendUpdate(ClanPlayer cp) {
forwardPluginMessage(UPDATE_CLANPLAYER_CHANNEL, gson.toJson(cp));
}
public SimpleClans getPlugin() {
return plugin;
}
public Gson getGson() {
return gson;
}
@SuppressWarnings("UnstableApiUsage")
private void requestPlayerList() {
if (!isChannelRegistered()) {
return;
}
ByteArrayDataOutput output = ByteStreams.newDataOutput();
output.writeUTF("PlayerList");
output.writeUTF("ALL");
sendOnBungeeChannel(output);
}
private void requestServerName() {
Listener listener = new Listener() {
@SuppressWarnings("UnstableApiUsage")
@EventHandler
void on(PlayerJoinEvent event) {
ByteArrayDataOutput output = ByteStreams.newDataOutput();
output.writeUTF("GetServer");
Bukkit.getScheduler().runTask(plugin, () -> {
event.getPlayer().sendPluginMessage(plugin, "BungeeCord", output.toByteArray());
PlayerJoinEvent.getHandlerList().unregister(this); //only needed once
});
}
};
Bukkit.getPluginManager().registerEvents(listener, plugin);
}
private void forwardPluginMessage(final String subChannel, final String message) {
forwardPluginMessage(subChannel, message, true);
}
@SuppressWarnings("UnstableApiUsage")
private void forwardPluginMessage(final String subChannel, final String message, final boolean all) {
SimpleClans.debug(String.format("Forwarding message, channel %s, message %s, all %s", subChannel, message, all));
if (!isChannelRegistered()) {
SimpleClans.debug("Not registered");
return;
}
String target = all ? "ALL" : "ONLINE";
ByteArrayDataOutput output = ByteStreams.newDataOutput();
output.writeUTF("Forward");
output.writeUTF(target);
output.writeUTF(subChannel);
output.writeUTF(message);
sendOnBungeeChannel(output);
}
private void sendOnBungeeChannel(ByteArrayDataOutput output) {
Bukkit.getOnlinePlayers().stream().findAny().ifPresent(player ->
player.sendPluginMessage(plugin, "BungeeCord", output.toByteArray()));
}
private boolean isChannelRegistered() {
return Bukkit.getMessenger().isOutgoingChannelRegistered(plugin, "BungeeCord");
}
}
@@ -0,0 +1,24 @@
package net.sacredlabyrinth.phaed.simpleclans.proxy;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
public interface ProxyManager {
String getServerName();
boolean isOnline(String playerName);
void sendMessage(SCMessage message);
void sendMessage(String target, String message);
void sendUpdate(Clan clan);
void sendUpdate(ClanPlayer cp);
void sendDelete(Clan clan);
void sendDelete(ClanPlayer cp);
}
@@ -0,0 +1,57 @@
package net.sacredlabyrinth.phaed.simpleclans.proxy.adapters;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class ClanPlayerListAdapter extends TypeAdapter<List<ClanPlayer>> {
private final SimpleClans plugin;
public ClanPlayerListAdapter(SimpleClans plugin) {
this.plugin = plugin;
}
@Override
public void write(JsonWriter out, List<ClanPlayer> value) throws IOException {
out.beginArray();
for (ClanPlayer clanPlayer : value) {
out.beginObject();
out.name("uuid");
out.value(clanPlayer.getUniqueId().toString());
out.endObject();
}
out.endArray();
}
@Override
public List<ClanPlayer> read(JsonReader in) throws IOException {
List<ClanPlayer> list = new ArrayList<>();
in.beginArray();
while (in.peek() == JsonToken.BEGIN_OBJECT) {
in.beginObject();
in.nextName();
UUID uuid = UUID.fromString(in.nextString());
ClanPlayer cp = plugin.getClanManager().getAnyClanPlayer(uuid);
in.endObject();
if (cp != null) {
list.add(cp);
}
}
in.endArray();
return list;
}
public static Type getType() {
return TypeToken.getParameterized(List.class, ClanPlayer.class).getType();
}
}
@@ -0,0 +1,52 @@
package net.sacredlabyrinth.phaed.simpleclans.proxy.adapters;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import net.sacredlabyrinth.phaed.simpleclans.Clan;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import org.jetbrains.annotations.Nullable;
public class ClanPlayerTypeAdapterFactory implements TypeAdapterFactory {
private final SimpleClans plugin;
public ClanPlayerTypeAdapterFactory(SimpleClans plugin) {
this.plugin = plugin;
}
@SuppressWarnings("unchecked")
@Override
public <T> @Nullable TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getType() != ClanPlayer.class) {
return null;
}
final TypeAdapter<ClanPlayer> delegate = (TypeAdapter<ClanPlayer>) gson.getDelegateAdapter(this, type);
return (TypeAdapter<T>) new TypeAdapter<ClanPlayer>() {
@Override
public void write(JsonWriter out, ClanPlayer value) {
JsonObject object = delegate.toJsonTree(value).getAsJsonObject();
object.addProperty("clan", value.getTag());
gson.toJson(object, out);
}
@Override
public ClanPlayer read(JsonReader in) {
JsonObject object = gson.fromJson(in, JsonObject.class);
String tag = object.get("clan").getAsString();
Clan clan = plugin.getClanManager().getClan(tag);
object.add("clan", null);
ClanPlayer cp = delegate.fromJsonTree(object);
cp.setClan(clan);
return cp;
}
};
}
}
@@ -0,0 +1,47 @@
package net.sacredlabyrinth.phaed.simpleclans.proxy.adapters;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.JsonToken;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import java.io.IOException;
import java.util.Map;
@SuppressWarnings({"unchecked", "rawtypes"})
public class ConfigurationSerializableAdapter implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (!ConfigurationSerializable.class.isAssignableFrom(type.getRawType())) {
return null;
}
TypeAdapter<Map> adapter = gson.getAdapter(Map.class);
return (TypeAdapter<T>) new TypeAdapter<ConfigurationSerializable>() {
@Override
public void write(JsonWriter out, ConfigurationSerializable value) throws IOException {
if (value == null) {
out.nullValue();
} else {
adapter.write(out, value.serialize());
}
}
@Override
public ConfigurationSerializable read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) { //could be replaced with map == null?
in.nextNull();
return null;
}
Map map = adapter.read(in);
return ConfigurationSerialization.deserializeObject(map,
(Class<? extends ConfigurationSerializable>) type.getRawType());
}
};
}
}
@@ -0,0 +1,52 @@
package net.sacredlabyrinth.phaed.simpleclans.proxy.adapters;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import net.sacredlabyrinth.phaed.simpleclans.ClanPlayer;
import net.sacredlabyrinth.phaed.simpleclans.SimpleClans;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage;
import net.sacredlabyrinth.phaed.simpleclans.chat.SCMessage.Source;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.UUID;
public class SCMessageAdapter extends TypeAdapter<SCMessage> {
private final SimpleClans plugin;
public SCMessageAdapter(SimpleClans plugin) {
this.plugin = plugin;
}
@Override
public void write(JsonWriter out, SCMessage value) throws IOException {
out.beginObject();
out.name("channel");
out.value(value.getChannel().toString());
out.name("sender");
out.value(value.getSender().getUniqueId().toString());
out.name("content");
out.value(value.getContent());
out.endObject();
}
@Override
public @Nullable SCMessage read(JsonReader in) throws IOException {
in.beginObject();
in.nextName();
ClanPlayer.Channel channel = ClanPlayer.Channel.valueOf(in.nextString());
in.nextName();
UUID uuid = UUID.fromString(in.nextString());
ClanPlayer sender = plugin.getClanManager().getAnyClanPlayer(uuid);
in.nextName();
String content = in.nextString();
in.endObject();
if (sender == null) {
return null;
}
return new SCMessage(Source.PROXY, channel, sender, content);
}
}
Loaded 100 of 170 files, more files were not shown because too many files have changed in this diff. Show more