Compare commits

..
880 Commits
Author SHA1 Message Date
Luck 175a21c0e4 API 4.0 - this is a breaking change 2017-11-07 22:05:49 +00:00
Luck a2801bff7c Inject a fake map into the super PermissionAttachment instance to fix compat with plugins using reflection to change attachment data (#528) 2017-11-07 17:05:16 +00:00
Luck f1a50f433f Throw exception earlier if an invalid permission is added/removed via Vault (#526) 2017-11-07 15:22:31 +00:00
Luck 76bfde4d77 Don't prevent modification of group.<group name> nodes with permission subcommands 2017-11-04 19:12:46 +00:00
Luck d393a4c9ca Alias /lp player --> /lp user 2017-11-03 16:26:54 +00:00
Luck 9ea6b0b8bb Use "None" instead of "global" when no server name is specified 2017-11-02 19:32:13 +00:00
Luck c20b91d5ea Increase actor_name field length to account for changes to logging 2017-11-02 19:28:49 +00:00
Luck fad8a38bdf Use a string version of the full static context, as opposed to the server name 2017-11-02 19:25:35 +00:00
Luck 2440a38e82 add RedisBungee context calculator for the BungeeCord platform 2017-11-02 19:01:53 +00:00
Luck b7541c43c8 Add Sender#getNameWithLocation 2017-11-02 18:51:59 +00:00
Luck 0f10bb0bc9 Deprecate some unused methods in ImmutableNode, refactor #shouldApplyWithContext 2017-11-02 18:22:42 +00:00
Luck 357717886e Refactor the log creation process 2017-10-30 21:06:45 +00:00
Luck 94a4051d29 Add extra catch for null primary group in powerfulperms migration 2017-10-30 20:03:59 +00:00
Luck 0e581cbcf3 Increase actions actor_name column length (#525) 2017-10-30 20:03:03 +00:00
Luck 230d9725e8 cleanup & fix build 2017-10-29 20:37:29 +00:00
Luck dee41b315f Inject our own subscription map into the plugin manager instead of registering permissions individually for each player 2017-10-29 15:16:48 +00:00
Luck 72e6c75433 Cleanup / tidy up a number of classes 2017-10-29 12:58:49 +00:00
Luck ebe12f838c Fix user exports 2017-10-28 00:15:34 +01:00
Luck 7279fdc25f Fix changes not being saved for flatfile bulkupdate operations 2017-10-27 23:17:57 +01:00
Luck af5c859385 Fix temporary group display format in parent info command (#518) 2017-10-24 13:17:27 +01:00
Luck e8896fbdf7 Fix NPE on startup (#520) 2017-10-24 13:05:06 +01:00
Luck 54695b8046 Form more descriptive console & import usernames 2017-10-23 23:37:55 +01:00
Luck c573c755d2 Add option to cancel failed logins on BungeeCord variant 2017-10-23 16:59:07 +01:00
Luck b299301b69 Cleanup 2017-10-22 21:02:48 +01:00
Luck a3a7198777 More storage refactoring 2017-10-22 20:09:53 +01:00
Luck ca8cc91f37 Add group setdisplayname command (#493) 2017-10-22 16:58:53 +01:00
Luck 26c813c07b Mode storage refactoring - write group nodes into their own section in flatfile types (#502) 2017-10-22 14:22:52 +01:00
Luck f109cb684a Apply PermissionAttachment permissions at a higher priority than normal nodes using the transient system (#515) 2017-10-22 10:24:04 +01:00
Luck 1baefaade4 Try to find the most appropriate primary group before just adding a user to default - closes #506 2017-10-22 09:16:04 +01:00
Luck 5ac0f93214 Fix migrating null / non-existent usernames - reverts parts of 6bfeec6, fixes #514 2017-10-22 09:07:08 +01:00
Luck ecfbed00b1 Add config option to allow invalid usernames (#516) 2017-10-22 09:00:10 +01:00
Luck 6e429d6c78 Throw exception if directories cannot be created 2017-10-22 08:48:00 +01:00
Luck fa4bb0447a Rewrite flatfile storage (YAML & JSON) to use configurate, add HOCON storage method 2017-10-21 23:20:45 +01:00
Luck aa0be40124 Cleanup verbose handler & only send sponge OP command notification if the sender has permission 2017-10-16 18:55:17 +01:00
Luck 04d5310c04 Ensure users are a member of their primary group (#506) 2017-10-16 18:53:02 +01:00
Luck 74069af309 Throw an exception if we're unable to create the lib dir 2017-10-16 15:28:02 +01:00
Luck 6bfeec6d16 Fix updating primary groups for players who've never joined the server with SQL storage types (#500) 2017-10-16 14:43:58 +01:00
Luck 0f4c057395 Add highest_inherited and lowest_inherited meta stack elements 2017-10-15 15:13:23 +01:00
Luck 2fd74f3b7e fix MetaStackElement equality checks 2017-10-15 14:51:42 +01:00
Luck fb171a57c2 Ensure stored primary groups are always lowercase'd 2017-10-15 14:32:57 +01:00
Luck b26fc69e73 Remove usage of the now-redundant ExtractedContexts class, other misc cleanup 2017-10-15 14:23:51 +01:00
Luck 28961b1cfa Primary groups should come first, not last, when ordering groups for inheritance (#500) 2017-10-15 11:22:38 +01:00
Luck 597f2f7b1b Make parents-by-weight the default primary group calculation method 2017-10-14 22:54:54 +01:00
Luck 00cd8bb3f3 Prioritise primary groups when two inherited groups have the same weight (#500) 2017-10-14 22:50:50 +01:00
Luck 5732e60510 Remove cleanupUsers functionality
It was pretty useless (and wasn't implemented on SQL/Mongo storage types.) Data is naturally cleaned up over time as users are loaded/saved.
2017-10-12 20:38:08 +01:00
Luck 7b271e21e3 Update readme 2017-10-12 20:25:51 +01:00
Luck 1a5f9683c2 Fix build (whoops) 2017-10-12 20:21:49 +01:00
Luck 3b74d55442 Remove sponge comparison chart from readme 2017-10-12 20:19:53 +01:00
Luck 8920396360 Remove context pre-processing (mostly)
This approach isn't very effective when contexts are frequently changing, and it is hard to guess in advance which contexts are going to be in-use.

The Sponge version has proven that this whole system isn't really necessary.

Contexts for 'allow all' and 'global' are still pre-processed, however this should be significantly less work for the server. (even if it is being done async)
2017-10-12 20:17:52 +01:00
Luck 9c505e4402 Move Track methods away from checked exceptions, refactor ContextManager & primary group holders 2017-10-12 19:43:42 +01:00
Luck de4c6b384c Export using the /lp alias 2017-10-12 18:47:35 +01:00
Luck 6dec1ba8af Add hu_HU locale - thanks @montlikadani 2017-10-03 19:04:47 +01:00
Luck 9e6788de2f Refactor context manager 2017-10-03 19:02:14 +01:00
Luck 1bd7e5c9c4 Refactor sponge cache invalidation 2017-09-29 23:21:12 +01:00
Luck ec75fdddb5 Make verbose output more readable when a check is made against a lot of contexts 2017-09-27 20:11:17 +01:00
Luck f98aafb97c Fix world content on BungeeCord not being lowercase'd 2017-09-24 23:43:39 +01:00
Luck f4d2a0daf9 Bump dependency versions 2017-09-23 23:36:13 +01:00
Luck de8fb8de90 Only load slf4j if it's not already present on the server 2017-09-23 21:15:45 +01:00
Luck 44d137b8f9 Add project Code of Conduct 2017-09-22 16:09:50 +01:00
Luck 777c972bdc Cache SubjectReference instances, general cleanup 2017-09-21 21:59:27 +01:00
Luck f9efa15781 Re-add 'list' as an alias of 'permission info' - reverts #461, closes #473 2017-09-20 20:31:24 +01:00
Luck 1d1cd679dd Fix tab completion inconsistencies caused by argument rewrites - closes #481 2017-09-20 20:27:46 +01:00
Luck a9ed4686dd Avoid loading slf4j when running on Sponge 2017-09-19 22:13:02 +01:00
Luck 5b742eb5b2 Only schedule a user cleanup when LuckPermsApi#cleanupUser is called 2017-09-18 20:50:50 +01:00
Luck a3d78f4d0e Always load dependencies into the plugin classloader, and not it's parent - fixes #479 2017-09-17 19:30:43 +01:00
Luck 214929e5e5 Fix group expiry time not being exported (#474) 2017-09-14 19:10:18 +01:00
Luck 67602b8d85 Fix startup deadlock 2017-09-13 21:24:35 +01:00
Luck 2412edaa3a Cleanup subscription updates & UserManager#loadAllUsers 2017-09-13 20:18:48 +01:00
EuropeJing b1584aa2c3 Update zh-CN locale (#466) 2017-09-12 08:47:37 +01:00
Luck a14a416193 Make some ingame messages more consistent with the LP theme, general cleanup 2017-09-11 22:21:57 +01:00
Luck f3251e9407 Fix missing depend 2017-09-10 21:45:47 +01:00
Luck 096885d91f Add tracing to /lp verbose, API updates/cleanup, add login process event, and utilise string interning for faster context/node comparisons 2017-09-10 21:25:00 +01:00
Frank Zhang 368700156c Added uranium server support to DependencyManager (#464) 2017-09-08 14:25:49 +01:00
Luck 81cf50520b Fix NodeFactory#nodeAsCommand when unsetting meta nodes, fix meta unset command 2017-09-06 21:56:41 +01:00
Luck 649748c2d3 Bump caffeine and hikari versions (#462) 2017-09-05 23:56:45 +01:00
Luck bf7a708440 Send some extra data to the editor data object 2017-09-05 14:54:22 +01:00
Luck 8faa4d137b Fix some issues with the recent import/export changes 2017-09-04 23:20:21 +01:00
Luck 479bd91b74 Fix build 2017-09-04 22:32:02 +01:00
Luck 6bc7f1fca2 Refactor Importer/Exporter to use multiple threads (#317) 2017-09-04 22:24:07 +01:00
Luck dadd8e2c50 Don't publish/broadcast log entries from the import process - towards #317 2017-09-04 20:47:45 +01:00
Luck 03f342a21c Refactor command execution to use Locks per target instead of (effectively) one for all commands - towards #317 2017-09-04 20:42:21 +01:00
Luck 7fe5397e21 Fix incorrect usage of CompletableFuture#thenCombineAsync 2017-09-04 17:56:01 +01:00
Luck b6e1fd179e Add type argument to 'meta clear' command (#457) 2017-09-04 17:25:59 +01:00
Luck 754c7d8e3b Add config option to prevent primary group removal (#405) 2017-09-04 17:03:17 +01:00
Luck 925d3ccd1b Remove "list" alias for holder info (#461) 2017-09-04 16:55:10 +01:00
Luck d60d0ac9c5 Reduce buffer times, refactor MessagingService init 2017-09-04 16:49:43 +01:00
Luck e1b51dd6af Catch Throwable instead of Exception when setting up BukkitJsonMessageHandler 2017-09-04 13:03:09 +01:00
Luck fbe9d9f128 Run user cleanup task async and not on Storage init 2017-09-03 16:16:21 +01:00
Luck 509826949d Add login debug option 2017-08-27 13:54:26 +01:00
Luck 39aaa8a292 Update for latest Text version 2017-08-22 22:51:49 +01:00
Luck 069c76c53a Fix time test for node expiry times 2017-08-22 16:30:46 +01:00
Luck f45c0caa45 Refactor metastacks & primary group calculation 2017-08-21 15:45:29 +02:00
EuropeJing 41b0e10709 Update zh-CN locale (#450) 2017-08-21 10:38:30 +02:00
EuropeJing 8e8da20c13 Update zh-CN locale (#449) 2017-08-20 19:43:58 +02:00
Luck 269aa39378 Fix comparator and ensure @Nonnull annotated methods never return null in LogEntry 2017-08-20 14:51:46 +02:00
Luck ae8be97db7 Dispatch log entries via the messaging service 2017-08-20 13:32:52 +02:00
Luck f0ad40825b Refactor and cleanup Log classes 2017-08-20 01:35:03 +02:00
Luck 36d292747a Format times in /lp log into a shorter form 2017-08-19 11:38:08 +02:00
Luck b65d2262bf Remove "... data was saved to storage" messages 2017-08-19 11:08:28 +02:00
Luck a7ab0c6b36 Send a more helpful message when the non legacy version of LP is installed on Bukkit 1.7 (#437) 2017-08-18 13:58:41 +02:00
Luck c02fcb6508 Refactor weight lookups 2017-08-18 11:14:03 +02:00
Luck 07c38de44b Allow permission info command to be filtered by context (#442) 2017-08-18 10:44:54 +02:00
Luck 188d62c99b Fix issue with casting UUIDs in MongoDB backing (#443) 2017-08-18 10:35:56 +02:00
Luck 76b203ad10 Fix text dependencies being shaded 2017-08-17 10:12:08 +02:00
Luck 909844aef5 Update KyoriPowered/text dependency 2017-08-16 10:56:35 +02:00
Luck 046202719a Correctly export meta/prefix/suffix nodes to command strings 2017-08-14 18:58:12 +02:00
Luck ed15e2838d Fix checkinherits command not returning the inheritance data 2017-08-14 09:38:08 +02:00
Luck 82466c2e5d Properly implement Contexts#allowAll - bump API to 3.3 2017-08-13 22:21:04 +02:00
Luck c598daf350 Fix negating group permissions to cancel inheritance 2017-08-13 19:40:59 +02:00
Luck a40421fa1f Optimizations to the core PermissionHolder class
- Remove usage of Java 8 streams from frequently called methods
- Use LinkedLists where appropriate to improve Iterator#remove speed
- Cache immutable multimap conversion
- Rename some methods to make the intended use/behaviour clearer
2017-08-13 19:24:00 +02:00
Luck d98b464ce9 Cleanup verbose & treeview packages. Return known permissions from the PermissionVault as Sponge PermissionDescriptions 2017-08-13 12:07:05 +02:00
Luck 1d5e3205ac Refactoring & misc cleanup 2017-08-12 19:34:14 +02:00
Luck 07eb17f5d5 Fix Sponge PermissionDescription lookups (#425) 2017-08-08 10:37:54 +02:00
Luck 3951725852 Fix 'meta settemp' command using duration as the server context (#421) 2017-08-05 23:46:19 +02:00
Luck 77956d69ad Fix NPE with Vault #getPlayerGroups 2017-08-05 17:30:40 +02:00
Luck 5784458d03 Make Sponge's #getFriendlyIdentifier return usernames of Users and display names of Groups (#412) 2017-08-03 18:39:39 +01:00
Luck 3d2115ff3c Remove unnecessary extra cache in ContextManager 2017-08-02 21:48:22 +01:00
Luck 8618a67e2e Fix sponge config loading - closes #407 2017-07-31 22:26:59 +01:00
Luck 234b9cafd7 Give default group if needed after "parent remove" (#405) 2017-07-30 21:08:05 +01:00
Luck 4ecd899bac Fix IndexOutOfBoundsException with 'permission settemp' command (#403) 2017-07-30 15:23:42 +01:00
Luck ce2c943397 Inject bukkit permissible at lowest priority instead of low 2017-07-27 12:58:31 +01:00
Luck 51898abb71 Don't load contexts file twice 2017-07-26 10:31:14 +01:00
Luck e2f800dd63 Throw an NPE if a null delegate sender is passed to SenderFactory#wrap 2017-07-26 10:10:25 +01:00
Luck d9e5bc9345 fix error with null subject in ContextManager removal listener - closes #392 2017-07-24 19:42:35 +01:00
Luck e42cc101cc Cleanup & document a number of Bukkit impl classes 2017-07-24 14:32:10 +01:00
Luck 845367e847 Flush storage buffer more frequently 2017-07-22 20:42:53 +01:00
Luck 90afd3c3ed Cleanup handling of empty permissions when migrating data (closes #387) 2017-07-22 20:04:55 +01:00
Luck b4aeb04d1b Fix possible NPEs when calling API storage events - fixes #384 2017-07-22 00:06:37 +01:00
Luck 65b0d45738 Fix IllegalStateException in meta info command - closes #385 2017-07-22 00:00:58 +01:00
Luck 3c44388883 Update /lp info output 2017-07-19 22:15:12 +01:00
Luck 400f3a9156 Add option to disable colored logging (#382) 2017-07-18 17:58:40 +01:00
creator3 ad6e837aa5 Use single quotes in escapeStringForSql (#379) 2017-07-16 23:53:15 +02:00
Luck cadd7545c5 Use saner class naming 2017-07-16 21:16:08 +01:00
Luck b41dea9ee1 Implement support for futures & other changes in the Sponge Permissions API 2017-07-16 14:12:36 +01:00
Luck 7a6c0ab154 Improve /lp listgroups output - closes #368 2017-07-10 10:09:29 +01:00
Luck 1bb1f5ebb3 Fail silently when the Sponge Server is not available - closes #367 2017-07-10 09:18:58 +01:00
Luck fce5b8430d Use GA MySQL version 2017-07-09 18:05:08 +01:00
Luck 0befa6a491 Fix generating unset commands for temporary nodes 2017-07-07 19:39:31 +01:00
Luck b12ce943f7 Make 'meta info' and 'parent info' clickable (#311) 2017-07-07 19:28:26 +01:00
Luck d23b29aeb1 Update dependency versions 2017-07-07 14:48:42 +01:00
Luck 42d48c8da2 Implement argument based permissions for LP commands - closes #52, #170, #174 2017-07-07 12:43:13 +01:00
Luck 9e83a5e4d9 Add RedisBungee messaging service option for BungeeCord 2017-07-03 16:24:00 +01:00
Luck d2bf940105 Add option to use the servers uuid cache/lookup facility (#354) 2017-07-03 16:07:33 +01:00
Luck 7d4aca68cc Fix jsr being shaded & tweak javadoc generation to link to guava docs correctly 2017-07-02 22:04:37 +01:00
Luck d7094909c0 Change verbose output slightly 2017-07-02 21:29:48 +01:00
Luck 7083d55a9b Fix vault lookups with a specified world 2017-07-02 10:49:07 +01:00
Luck 770db2fee0 Export groups in order of weight, then alphabetically 2017-06-30 19:43:45 +01:00
Luck b8e65c4f26 Fix bukkit defaults still being applied to subscriptions when disabled 2017-06-30 19:32:12 +01:00
Luck 5cd5186092 Don't cancel re-allowed connections unless the cancel was made by LP 2017-06-26 21:39:59 +01:00
Luck fa0b66c2dc Fix lp tree max recursion property 2017-06-26 16:31:30 +01:00
Luck 1b199fd2c7 Fix NPE when loading locale file - closes #338 2017-06-24 17:26:52 +01:00
Luck 2ffbeeef8e Add jsr305 annotations to the API 2017-06-24 17:25:13 +01:00
Chris N 26ce8b8ab7 YAML/JSON batch permission defining (#337) 2017-06-22 10:41:29 +01:00
Luck 8e224c4a27 Don't force cancel Sponge ClientConnection.Join if the cancellation state changes, shuffle event orders slightly - fixes #335 2017-06-20 21:37:38 +01:00
Luck cf5318b92b Make command defintion/usage messages translatable 2017-06-20 20:20:41 +01:00
Luck e50fa17f7c Store all accumulated meta values in MetaCache 2017-06-19 21:48:52 +01:00
Luck 8766e3b408 Add jar signing to build scripts 2017-06-19 20:09:18 +01:00
Luck c4c7f06d83 Fix BungeePerms migration - closes #333 2017-06-19 16:43:00 +01:00
Luck 413e304845 Fix NPE with null context in FileWatcher 2017-06-14 17:32:02 +01:00
Luck 046daf23d0 Deploy source & javadoc jar with the API 2017-06-13 20:17:41 +01:00
Luck c57947949c Don't send messages to command blocks async 2017-06-13 17:30:01 +01:00
Luck 0acefde805 Tidy up configuration file layouts 2017-06-12 21:41:23 +01:00
Luck a9e751b4b8 Replace fanciful with KyoriPowered/text 2017-06-11 14:46:56 +01:00
Luck 3df1ae8ded Fix argument validation for parent settrack command - closes #321 2017-06-11 10:27:26 +01:00
Luck b4a2da0ea8 Add some missing tab completions, remove /lp log export command 2017-06-09 22:19:07 +01:00
Luck 5c5d1e8d0a Fixes some issues with username storage and handling
- Fix the yaml/json UUID cache corrupting username data when performing uuid --> username checks
- Fix handling of usernames when users are loaded

Closes #301
2017-06-09 18:20:12 +01:00
Luck ff0c988a1d Don't store attributes for permissions with only 'value: true' in YAML/JSON storage files 2017-06-07 21:04:14 +01:00
Luck b9fc8f4b5f Add MongoDB collection prefix option 2017-06-05 16:09:02 +01:00
Luck 2ecaa39cb6 Only resolve inheritances for groups which exist already 2017-06-04 16:41:20 +01:00
Luck 7b8654339c Maybe fix usernames not being updated in storage after name changes (#301) 2017-06-03 16:40:16 +01:00
dzegarek 306e252c31 Add pl_PL locale (#306) 2017-06-03 14:47:34 +01:00
Luck 87c3bd6293 Update README.md 2017-05-26 20:48:41 +01:00
Luck 307beebb58 Cleanup Bukkit PEX migration, fix user parents being transferred incorrectly 2017-05-25 22:24:55 +01:00
Luck 4109863aa9 Fix -s flag (#132) 2017-05-25 21:35:47 +01:00
Luck 0febdbe3a4 Update copyright headers in the API module 2017-05-21 09:47:08 +01:00
Luck 139dd5302b Cleanup login handling & reduce the amount of unnecessary logging output on startup 2017-05-18 22:30:01 +01:00
Luck cc907b6530 Don't catch exceptions thrown inside i/o (#291) 2017-05-18 21:16:31 +01:00
Luck ca1dacf2b6 Invalidate active context cache when a player changes world - closes #288 2017-05-16 21:52:46 +01:00
Luck abc1c164cf Expose MetaStacks in the API, general cleanup, release 3.2 2017-05-16 21:41:20 +01:00
Luck dc801464ef Refactor meta stacking to be mapped in MetaCache - towards lucko/LuckPermsPlaceholders#1 2017-05-16 19:13:08 +01:00
Luck 99c6fe20c2 Catch exceptions thrown by context calculators 2017-05-16 13:50:28 +01:00
Luck 9d780ae24a Fix misleading Vault debug message 2017-05-15 21:26:43 +01:00
Luck a44dec0402 Fix typo 2017-05-15 12:07:59 +01:00
Luck a081152baa Fix web editor url 2017-05-15 12:05:54 +01:00
Luck 9b50d48f46 fix compile 2017-05-14 22:41:25 +01:00
Luck 5121fc6b1f Cleanup 2017-05-14 22:15:25 +01:00
Luck d4ac261e85 Cleanup config keys, make editor URL configurable 2017-05-14 21:36:02 +01:00
Luck 2e9561371d Implement initial web editor support 2017-05-13 20:36:05 +01:00
Luck 942fd3c4ce Fix vault lookups with static context 2017-05-11 20:04:11 +01:00
Luck 8cf32752e9 Fix meta info only showing values in global context 2017-05-11 19:46:28 +01:00
Luck b240ca9939 Add parent cleartrack command, cleanup Messages enum 2017-05-09 16:26:55 +01:00
Luck e25d99129c Implement parent settrack command - closes #112 2017-05-09 14:06:16 +01:00
Luck 1fee47e087 Implement default contexts - closes #241 2017-05-09 13:36:43 +01:00
Luck e835b31277 Apply world rewrites on-top of the real world name, and apply recursively (#255) 2017-05-09 13:07:39 +01:00
Luck 6817945e12 Bump sponge API version, cleanup 2017-05-09 12:55:45 +01:00
Luck 030fb1262e Fix being able to negate permissions/parents/meta in specific contexts 2017-05-08 22:27:46 +01:00
Luck fae49096f3 Fix retrieving meta keys from Vault which contain delimited characters - closes #270 2017-05-08 21:43:20 +01:00
EuropeJing afd491ecea Update zh-CN locale (#281) 2017-05-08 20:17:51 +01:00
EuropeJing 09bc100ad9 Add zh-CN locale (#279) 2017-05-08 18:11:29 +01:00
Luck 037f18ac56 Fix zPerms parent group migration for users, and fix migration of temporary memberships 2017-05-08 17:45:17 +01:00
Luck a5746dfa21 Support sponge selector resolution - closes #275 2017-05-07 22:52:45 +01:00
Luck cedc5108fc Refactor Patterns to PatternCache 2017-05-07 13:56:42 +01:00
Luck 65af3d0f54 Add data constraints - closes #256 2017-05-07 13:44:29 +01:00
Luck 6c4fa65f91 Fix migrating weight with zPerms 2017-05-06 23:35:58 +01:00
Luck 4731ad8061 Fix migrating false zPerms nodes 2017-05-06 21:06:22 +01:00
Luck 7dc41e15d3 Fix users being cleaned up too early and then logging back into the server - closes #271 2017-05-06 18:24:44 +01:00
Luck 8326539d40 Refactor LP PermissionService to implement a modified API & add proxied classes 2017-05-03 20:14:31 +01:00
Luck 163e6e0f2a Always load user data caches alongside user instances 2017-05-02 16:55:08 +01:00
Luck f56bb251e9 Cleanup some stuff 2017-05-02 16:36:46 +01:00
Luck 152ca99276 Fix issue with bulk removing suffixes 2017-04-25 16:51:21 +01:00
Luck 7c398d2c67 Split up chat messages sent to console containing new lines 2017-04-23 20:51:24 +01:00
Luck a526c942ca Add config options to allow for finer control over how permissions are calculated, and set include-global to true on BungeeCord by default 2017-04-23 20:30:58 +01:00
Luck af8fd15929 improve speed of NodeTools#removeSamePermission 2017-04-23 11:51:56 +01:00
Luck 7bfd5d4bc8 implement atomic group insertion 2017-04-22 22:53:29 +01:00
Luck 4382d5c56d show uuid in log messages if username is null 2017-04-21 21:28:50 +01:00
Luck f43b9c96de cleanup login handling & add CountdownLatch to ensure the plugin has started before logins are handled 2017-04-21 19:10:25 +01:00
Luck c64f72e394 Fix issue with loading usernames on MongoDB - closes #257 2017-04-21 16:58:07 +01:00
Luck 3d54f832c5 cleanup duplicated method 2017-04-20 19:26:47 +01:00
Luck 867ba24c6c support glowstone (maybe) 2017-04-20 19:15:37 +01:00
Luck 9715c5394c Fix NPE caused by AllParentsByWeight primary group selector - closes #252 2017-04-18 17:11:07 +01:00
Luck 67b5c72520 Cleanup handling of unknown/null usernames for users 2017-04-17 19:31:52 +01:00
Articuno 43450f6cc7 Update RU locale (#250) 2017-04-17 10:12:37 +01:00
Luck a3737d4f35 fix typo 2017-04-16 11:08:54 +01:00
Luck 3314e94a9a Add not_on_track meta stack criteria 2017-04-16 11:06:05 +01:00
Luck a27436b086 Fix getting primary groups for offline users 2017-04-15 20:32:03 +01:00
Luck fe5554ffb1 fix build 2017-04-15 19:53:12 +01:00
Luck f305f8d822 Determine dynamic primary groups using current context 2017-04-15 19:08:04 +01:00
Luck 1f54bc41cc Cleanup poms, update copyright header 2017-04-15 19:01:52 +01:00
Luck c82d028429 fix yaml/json schema migration 2017-04-12 21:33:59 +01:00
Luck be2a8b7b07 Fix incorrect chat meta command usage 2017-04-12 17:59:51 +01:00
Luck 261fc82016 Remove getuuid command
why did that ever exist anyways
2017-04-12 17:25:22 +01:00
Luck 37b940f3a5 Convert promote / demote commands to use new context system, update en locale with latest changes 2017-04-12 17:11:01 +01:00
Luck 0504e904a2 Only perform flatfile schema migration if the new dir doesn't exist 2017-04-12 14:28:39 +01:00
Luck 71bfdd9bfd log the file name when exceptions are thrown during i/o 2017-04-12 14:09:51 +01:00
Articuno c7305f6b06 Update ru_RU locale (#238) 2017-04-11 10:47:43 +01:00
Luck 4fb07ff181 API changes for 3.1 2017-04-10 22:26:20 +01:00
Luck 4631dcf857 Ensure expired permissions are removed when users/groups are loaded for commands 2017-04-10 20:57:59 +01:00
Luck f6f9840eb7 Re-implement bulk updates 2017-04-10 19:33:23 +01:00
Luck 4de8165c95 fix issue with /reloading and permission registration 2017-04-10 18:17:09 +01:00
Luck 242672f49d Remove old bulk edit commands 2017-04-10 14:56:46 +01:00
creator3 c32c975a71 Fix accumulation of temporary perms with a world or server context (#235) 2017-04-08 20:49:10 +01:00
Luck 82e759d708 Make sure world names are lowercase'd 2017-04-08 17:00:36 +01:00
Luck 9de44d2605 Don't attempt to migrate empty permissions 2017-04-07 21:03:27 +01:00
Luck 132d0cf578 Fix export command switchprimarygroup output, and log player uuid if their username isn't included 2017-04-07 19:59:53 +01:00
Luck 029dc9f8d9 Make the standard MySQL driver the default again 2017-04-06 11:30:17 +01:00
Luck 5567b1dad8 Use the mariadb driver by default 2017-04-05 21:23:18 +01:00
Luck ea00ec64af Refactor NodeModel into a more useful class, remove duplicate context serialization methods 2017-04-04 19:19:31 +01:00
Luck 7259e6be0a Fixes for the verbose uploader 2017-04-04 17:17:57 +01:00
Luck 2e40557b39 Add '/lp group <group> listmembers' command - closes #203 2017-04-04 16:07:41 +01:00
Luck e68fc7c558 Improve performance of resolve methods in PermissionHolder, other cleanup 2017-04-04 15:22:25 +01:00
Luck 055dfb000d Only allow one server and one world in context sets parsed from command args 2017-04-04 13:47:50 +01:00
Luck b997ab6e3f Properly sort storage files - closes #227 2017-04-03 10:57:29 +01:00
Luck 25f31d0bb8 Cleanup sponge delegate classes 2017-04-03 10:27:31 +01:00
Luck 4cfd8a7e2c Fix broken command parameter & update default locale file 2017-04-03 09:53:26 +01:00
Luck 0ec19a8fee Implement accumulation of static contexts from a file 2017-04-03 01:42:49 +01:00
Luck 2749563f5d Replace guava caches with caffeine 2017-04-03 00:53:04 +01:00
Luck e7e2e3f7e0 Allow context pairs to be specified in commands, fix misuse of exceptions in the permission holder class 2017-04-02 18:44:05 +01:00
Luck 0a33c0aac5 Fix compatibility with older gson versions - closes #222 2017-04-01 07:26:05 +01:00
Articuno 24e09fd2d9 Add ru_RU.yml (#224) 2017-03-30 18:45:50 +01:00
Luck 4d0499a61e Avoid parsing UUID in sponge world calculator 2017-03-30 18:40:36 +01:00
Luck ae82807139 Add "use-vault-server" config option, depreciate vault primary group override feature 2017-03-27 17:35:28 +01:00
Luck 65147e1935 Remove missing permission nodes before adding new ones when saving users/groups with SQL storage 2017-03-27 16:54:59 +01:00
Luck 8e557d122b Fix some concurrency issues with login handling 2017-03-26 18:40:09 +01:00
Luck 486b19aa90 Cleanup some misc stuff 2017-03-26 16:10:49 +01:00
Luck 14cb34ac95 Force some config options to be read as lower case 2017-03-25 23:23:20 +00:00
Luck abfc23b04d Provide tab completion for rewritten arguments & add some more rules 2017-03-25 20:27:33 +00:00
Luck ebb24aefa1 Fix parent set command also adding default 2017-03-25 20:06:30 +00:00
Luck 2573f46f40 Fix removing temporary permissions/parents/meta in global context 2017-03-25 19:58:56 +00:00
Luck 5dcb8cd73a Output group/track lists in alphabetical order 2017-03-25 19:48:17 +00:00
Luck e4bfe09882 Don't bother loading test classes (#217) 2017-03-25 11:38:02 +00:00
Luck eecbfe04db Add es_ES locale 2017-03-25 11:13:45 +00:00
Luck 671e2adc32 Cleanup remaining (un)setPermission methods 2017-03-25 11:04:25 +00:00
Luck 1137e476dd Rewrite inheritance resolution implementation 2017-03-24 22:18:18 +00:00
Luck cb63b321d0 correct zPermissions migration logging tag 2017-03-23 23:18:03 +00:00
Luck c36b0d2975 Automatically push updates to other servers via the messaging service when commands are ran 2017-03-21 21:58:45 +00:00
Luck f8ad562b95 Rename "debug" classes to "verbose" 2017-03-20 17:22:18 +00:00
Luck c35ab38f36 Slight speed improvement for import processes 2017-03-19 20:52:35 +00:00
Luck 073b775566 Implement nicer json format for Sponge local data 2017-03-19 17:54:12 +00:00
Luck 85c7a7db8d Implement new file layout for YAML / JSON storage files (#211) 2017-03-19 15:37:30 +00:00
Luck 1e134df27d Clarify the file names of H2 and SQLite databases 2017-03-18 23:00:12 +00:00
Luck bdff84885a Enforce that ContextSets use the HashMultimap variant - closes #208 2017-03-18 20:18:18 +00:00
Luck f1a9c3722c Fix PM migration command not being registered 2017-03-18 17:26:44 +00:00
Luck 8b402f6423 Fix NoSuchMethodError being thrown for older Bukkit config classes 2017-03-18 15:34:29 +00:00
Luck a0aec52661 Correct the case of group names when retrieved from Node instances 2017-03-18 14:43:34 +00:00
Luck 407ab43dd1 Update PM migration to support latest version 2017-03-17 23:21:57 +00:00
Luck c2165e0196 Fix primary groups being selected in reverse order 2017-03-17 23:00:37 +00:00
Luck 2e75bc3f3b Add some alternate options for primary group calculation 2017-03-17 22:54:18 +00:00
Luck e91c2ca427 Add method to export Message enum and update language file 2017-03-17 21:17:59 +00:00
Luck 965ff04bcc Fix ClassCastException with MongoDB user search 2017-03-17 20:54:40 +00:00
Luck ac4bd418f3 Rename online-mode config option to use-server-uuids to better reflect/clarify its purpose 2017-03-17 20:51:06 +00:00
Luck e9e844c1f7 Include internal weight value in meta output if not already present 2017-03-13 20:17:54 +00:00
Luck aa2941fcdb Refactor and cleanup commands 2017-03-13 20:03:03 +00:00
Luck dbc909a317 Cleanup migration commands 2017-03-13 19:10:36 +00:00
Luck 11465a4ce9 Fix BungeePerms migration to account for group weights and negated permissions 2017-03-12 20:00:02 +00:00
Luck f5007f94dc Add server version info to the startup banner 2017-03-12 14:59:27 +00:00
Luck d18ac2e6eb Cleanup pom files, maybe improve build speed a bit 2017-03-12 14:28:35 +00:00
Luck b9fc5c39ae Listen for changes in data files and automatically update 2017-03-11 23:05:03 +00:00
Luck 9dc2278083 Cleanup a bit 2017-03-11 21:10:27 +00:00
Luck 281060a972 Make the clone commands work for existing tracks/groups too 2017-03-11 18:30:27 +00:00
Luck 91626f079d Fix mistake in removeprefix/removesuffix command descriptions 2017-03-11 18:26:29 +00:00
Luck 7305c6c54b Migrate group weightings onto the group itself as well as to the chat meta held by it 2017-03-11 18:24:25 +00:00
Luck bce7fa871d Fix getAllNodes cache not working properly, remove pre-process contexts on Bungee & cleanup some unused methods 2017-03-11 17:55:50 +00:00
Luck a35fd80763 remove placeholder expansion from main project 2017-03-11 14:02:17 +00:00
Luck b383f9dfbc Add some more placeholders to the expansion 2017-03-11 13:30:08 +00:00
Luck 680ad3c145 Update hikari version 2017-03-11 10:32:10 +00:00
Luck 7b712e7f90 Update readme 2017-03-10 23:30:08 +00:00
Luck 2462eac497 Run exporter in own thread and process user exports concurrently 2017-03-10 20:44:19 +00:00
Luck bb818c8942 Cleanup powerfulperms migration & remove support for older PP versions 2017-03-09 19:10:48 +00:00
Luck ddc881af11 Add new argument util method for reading context pairs 2017-03-09 17:56:15 +00:00
Luck 838fba9173 Switch all usages of file reader/writers to use java nio methods - closes #204 2017-03-09 17:55:33 +00:00
Luck 0b6f326c18 Fallback to uuid in the search command if the username is unknown 2017-03-07 22:17:49 +00:00
Luck 00895fc7ab Don't send json text on MC 1.7 2017-03-06 18:22:11 +00:00
Luck 07f38aa283 Fix possible issue with context conversion 2017-03-05 22:56:00 +00:00
Luck ecf1d3790c Fix issue where group nodes could be unset using the permission commands, and where users with per-server groups wouldn't be assigned to the default group globally 2017-03-05 19:05:05 +00:00
Luck 53c9e5bb4a Fix race condition with Bukkit join handling where players are denied entry but subsequently login slightly later 2017-03-05 00:59:44 +00:00
Luck b20b03113a Fix groupmanager global group migration on windows systems 2017-03-01 21:26:20 +00:00
Luck ec8273aa9f Change bungeecord leave event priority to wait longer before unloading data 2017-02-26 21:53:03 +00:00
Luck 2862f0dfae Fix creating delimiter patterns 2017-02-26 21:28:40 +00:00
Luck fd4963c74b Fix getUuid and getName API methods returning null for User, Group and Track instances 2017-02-26 20:46:37 +00:00
Luck df99ef4481 misc cleanup 2017-02-26 12:43:35 +00:00
Luck 35d1057673 Refactor sponge commands to use the proxied interfaces (closes #197) 2017-02-26 11:55:59 +00:00
Luck e6a90a18c4 Sort subjects properly 2017-02-26 01:16:54 +00:00
Luck 26afb69a14 Cleanup LuckPermsSubjectData (fixes #194) 2017-02-26 01:00:02 +00:00
Luck e8c0c43e9d misc cleanup 2017-02-24 19:31:45 +00:00
Luck 1707f333bf update javadocs link in readme 2017-02-23 21:59:43 +00:00
Luck 6798fb21b2 Events rewrite, remove most deprecated API methods (v3.0) 2017-02-19 14:57:20 +00:00
Luck 89ff3b169b Fix bukkit child permission handling to not include permissions with no children & cleanup permission registration 2017-02-18 21:01:09 +00:00
Luck abddb265be ensure all bukkit permissions are registered on startup 2017-02-18 08:50:06 +00:00
Luck b328fa74a7 Clarify thrown exception when a null context is returned 2017-02-16 21:45:43 +00:00
Luck f97aa651a0 Fix NPE caused by generating the wrong ExtractedContexts type - closes #185 2017-02-16 21:43:27 +00:00
Luck 8d86eed0a7 Don't bother adding checks to the listener queue if no listeners are registered 2017-02-15 19:39:24 +00:00
Luck 05f906a759 Add /lp tree command - closes #175 2017-02-15 19:21:27 +00:00
Luck 4b16be1b75 Fix setting chat meta with Vault, remove unnecessary permissible recalculations & general cleanup 2017-02-15 12:53:52 +00:00
Luck bd97a7c5d2 Respect prefix option set in subject - closes #149 2017-02-14 17:11:17 +00:00
Luck a3a23d8870 Remove redundant SQL queries and fix issue where multiple uuids could be mapped to the same username - fixes #179 2017-02-14 16:23:54 +00:00
Luck 30bddceac5 import log should be sent to console too 2017-02-13 16:26:41 +00:00
Luck 989a2cc89c Make the bukkit command manager more accessible 2017-02-13 12:53:22 +00:00
Luck 3f17e8c3c8 Test verbose filters before registering them (#178) 2017-02-12 17:19:16 +00:00
Luck 140e6b08ca Apply regex perms before wildcards 2017-02-11 12:12:28 +00:00
Luck 6a39b721ba Fix sponge service returning subjects in reverse priority order 2017-02-09 23:00:48 +00:00
Luck 1df6f4b9df Allow negated group permissions 2017-02-08 21:04:34 +00:00
Luck 9493fb3a7a Switch SpongeGroup meta handling to use MetaHolder - closes #171 2017-02-06 22:38:03 +00:00
Luck 0d1f3b855f Ignore commented lines on dump imports & add annotations to export files - closes #169 2017-02-05 09:58:24 +00:00
Michael Vorburger 0982154a15 "Explaination" --> "Explanation" (#168) 2017-02-04 22:32:34 +00:00
Luck 378f3f5efa Fix NPE for vault getUserMeta when defaultValue is null and the LP value is also null 2017-02-04 17:45:26 +00:00
Luck 9b8d6e1dc7 Modify node escaping to use "\" characters, and remove all limits on node/server/world strings - closes #166 2017-02-04 12:18:45 +00:00
Luck 6540c695de Add configurable duration handling when a holder already has a temporary permission/parent/option set - closes #152 2017-02-03 22:24:42 +00:00
Luck 1d71ec07be fix option lookups in specific contexts returning as global instead 2017-02-03 17:18:18 +00:00
Luck c837dd5cc8 fix jedis shading - closes #158 2017-02-02 16:00:18 +00:00
Luck bc52e4da0e Fix OPs disabled message 2017-02-02 15:58:34 +00:00
Luck f0b4040458 Fix Sponge PEX meta migration weightings 2017-02-02 15:33:15 +00:00
Luck d804c4be2a fix build 2017-02-02 15:16:08 +00:00
Luck ede413a213 Fix import/export handling - closes #159 2017-02-02 15:13:44 +00:00
Luck 9cee319ed9 Cleanup all migration commands - closes #63 2017-02-01 18:41:15 +00:00
Luck f7b281f655 Fix build 2017-01-31 12:32:18 +00:00
Luck 8dbb083b90 Fix migration log being sent to the console twice 2017-01-31 12:29:06 +00:00
Luck 0be6d658ed Refactor plugin and scheduler interfaces 2017-01-31 12:14:42 +00:00
Luck 1efce41767 Fix search command page number 2017-01-30 20:13:19 +00:00
Luck da23b6ea9a Fix search command page number 2017-01-30 20:13:19 +00:00
Luck a61d3b3fd4 Fix sponge PEX/PM migration issue with defaults 2017-01-29 21:56:09 +00:00
Luck ab9284b80f Use reflection in the #getAllKeys method instead of a list 2017-01-29 14:52:42 +00:00
Luck 424af27a47 Change update messages to account for more than just redis messaging 2017-01-29 11:09:11 +00:00
Luck 5039a05055 Update readme 2017-01-27 20:37:27 +00:00
Luck d150b22eae fix NPE on login 2017-01-26 21:05:44 +00:00
Luck a617675771 prettify the verbose paste output 2017-01-26 19:47:46 +00:00
Luck f27034bb35 Pull git commit id once only - should improve build time 2017-01-26 13:55:06 +00:00
Luck 86b203c21b Compile with shaded redis version - fixes #150 2017-01-26 13:54:23 +00:00
Luck 73c5a1ad9b Fix apache pool2 jar not loading correctly - closes #150 2017-01-25 22:07:50 +00:00
Luck 81c71777cb Fix some usage messages 2017-01-24 21:48:47 +00:00
Luck 599072eef6 Fix null config values throwing exception - closes #147 2017-01-24 20:13:18 +00:00
Luck 02ea3afbe9 Add "!" delimiter to verbose matching 2017-01-23 22:47:39 +00:00
Luck 0c1a2e82bf implement verbose expression matching 2017-01-23 22:43:52 +00:00
Luck f89fb87c92 Log the file name when I/O fails 2017-01-23 21:15:25 +00:00
Luck 98d6cf842a reword check result message slightly 2017-01-23 21:08:27 +00:00
Luck 69dc02b2c2 Add /lp check <user> <permission> command 2017-01-23 21:03:58 +00:00
Luck 7d1a3d32e9 Fix login NPE when async tasks run after the event has been fully handled 2017-01-23 16:22:25 +00:00
Luck d93cc826b2 Fix backwards compatibility with redis 2017-01-22 22:49:11 +00:00
Luck 8025f3a082 Fix all users sharing the same meta state 2017-01-22 22:19:29 +00:00
Luck 247871f678 Cancel messaging task when the message is sent 2017-01-22 21:47:57 +00:00
Luck 327c8b83be Implement BungeeCord & LilyPad messaging services - closes #142 2017-01-22 21:46:22 +00:00
Luck 0f8c334de8 FIx stacking backwards compatibility 2017-01-22 19:01:34 +00:00
Luck 292d4cd450 Implement stacking prefixes - closes #60 2017-01-22 18:23:08 +00:00
Luck 38d1c9974b Soften server checking regex - also towards #143 2017-01-22 16:36:06 +00:00
Luck 0be7300677 Fix node shorthand parsing - closes #143 2017-01-22 16:29:52 +00:00
Luck c03585aeca Fix using UTF-8 characters with MySQL - closes #129 2017-01-22 12:19:29 +00:00
Luck d39dad3287 Fix config reloading causing ClassCastExceptions 2017-01-22 11:58:48 +00:00
Luck 0a3ca3affe Add /lp reloadconfig command - closes #100 2017-01-21 20:14:25 +00:00
Luck b7cf0e6bc7 Refactor config handling - towards #100 2017-01-21 15:36:13 +00:00
Luck 7430013cc3 don't unload sponge data when a player quits 2017-01-20 20:02:42 +00:00
Luck 6dd093fe72 fix API ClassCastException 2017-01-19 21:29:54 +00:00
Luck 8a8d6f16ae Return subjects in priority order - related CodeCrafter47/BungeeTabListPlus#175 2017-01-19 21:09:44 +00:00
Luck 2e16844141 Remove console only commands - closes #137 2017-01-19 20:39:09 +00:00
Luck a152cc47c7 Fix bukkit login handling - closes #110 2017-01-19 20:04:22 +00:00
Luck 241507228f Colorize console info messages 2017-01-19 19:51:41 +00:00
Luck 8aa7d272fa Include license file in the jars 2017-01-19 19:03:59 +00:00
Luck 01ac5382ea Prevent some shutdown exceptions - closes #136 2017-01-19 18:56:22 +00:00
Luck 02b88a8357 Maybe fix default assignment parsing error with sponge 2017-01-18 22:40:25 +00:00
Luck c99d6556db Fix issues with default assignment loading on Sponge 2017-01-18 21:37:41 +00:00
Luck 1db777cd31 Remove world cache - fixes #135 2017-01-18 21:05:14 +00:00
Luck aea44fc8bc API changes for 2.17 - closes #123 2017-01-16 20:01:41 +00:00
Luck c0da9d49d9 make clickable message invert filter more specific 2017-01-16 16:55:59 +00:00
Luck ce42573f43 Properly invalidate user caches when defaults chance - fixes #118 2017-01-15 17:47:59 +00:00
Luck 148fe4c729 Make prefix/suffix string optional in the meta remove commands - related to #83 2017-01-15 15:11:35 +00:00
Luck 32fd484b58 Change promote / demote behaviour at the end of tracks - towards #112 2017-01-15 13:22:50 +00:00
Luck 7d24e748b7 Fix reading and writing UTF-8 characters from storage files - closes #129 2017-01-15 12:18:12 +00:00
Luck f1a1612f5d Subscribe to default permissions too 2017-01-14 23:49:45 +00:00
Luck 6501e5cf8d Fix bukkit permission subscriptions 2017-01-14 23:19:11 +00:00
Luck cd4a684613 Fix demote command not removing old group 2017-01-14 08:27:09 +00:00
Luck d06fda6d9d Add /lp search command 2017-01-13 20:11:25 +00:00
Luck 139010e75b Fix repo 2017-01-12 21:59:38 +00:00
Luck 7638b07e34 bump fanciful version 2017-01-12 21:48:16 +00:00
Luck f7bf4416c9 Fix illegal cast from LPSubject to SpongeGroup - fixes #126 2017-01-12 21:19:34 +00:00
Luck 2b96b656a9 constants do not need getters 2017-01-12 21:14:27 +00:00
Luck 0fe251b6ec Fix promote/demote commands and primary groups conflicting 2017-01-12 19:45:44 +00:00
Luck a1afc70bcb Cache regex permissions when they get processed 2017-01-12 19:45:15 +00:00
Luck ced3e6959c Add methods to get a list of users/groups with a specific permission 2017-01-11 21:25:57 +00:00
Luck 1c229d54d9 Cleanup 2017-01-11 18:55:46 +00:00
Luck dd50193c18 Fix Sponge subjects from being unloaded and never reinitialized - closes #124 2017-01-10 19:17:45 +00:00
Luck ab0f9bbdbd Fix creating new tracks with SQLBacking 2017-01-09 19:24:12 +00:00
Luck 055d181c67 Fix KCauldron dependency loading - closes #121 2017-01-09 18:20:03 +00:00
Luck 7042c45deb Fix retrieving log from SQLBacking 2017-01-08 20:12:33 +00:00
Luck 960c2291b6 Fully implement new SQL schema & add migration code 2017-01-08 19:33:27 +00:00
Luck 773bfe1407 Automatically sort YAML/JSON storage - closes #113 2017-01-08 11:02:13 +00:00
Luck a23f995717 Hopefully fix #118 2017-01-08 10:44:48 +00:00
Luck bd509b3c75 Fix build 2017-01-05 18:30:09 +00:00
Luck a0f8ba9afb Fix NPE in LuckPermsSubjectData - closes #115 2017-01-05 18:27:58 +00:00
Luck a71e040c6d Fix NPE with Vault transient permissions - closes #117 2017-01-05 18:20:17 +00:00
Luck 454abec468 Cleanup vault hook 2017-01-05 18:19:14 +00:00
Luck 96035d5257 Fix clickable node list 2016-12-30 15:02:22 +00:00
Luck 9f2b59f2a2 Refactor SQLBacking - still towards #77 2016-12-30 14:27:43 +00:00
Luck a54046907d change first login event handling 2016-12-30 12:46:24 +00:00
Luck 2ce5679373 Fix issue where only the first request for a user subject would wait for the loading task to complete. Closes #108 2016-12-30 00:42:33 +00:00
Luck 2dad9f84fc Fixes towards #77 2016-12-27 14:55:21 +00:00
Luck a81a361a93 Fully implement new SQLBacking - towards #77 2016-12-27 14:27:05 +00:00
Luck 4660e68abf Some small fixes for new SQL backing 2016-12-27 13:03:59 +00:00
bakatrouble f8a77cf809 Change comments on configs; default ports for all storage backends 2016-12-27 12:39:54 +00:00
bakatrouble 0abe9598f6 It shouldn't be here 2016-12-27 12:39:54 +00:00
bakatrouble 20de713716 Some readability 2016-12-27 12:39:54 +00:00
bakatrouble 9dbef6acc2 Change providers syntax; fix port for PostgreSQL provider 2016-12-27 12:39:54 +00:00
bakatrouble 4c93bf7cf0 Fix connection leaking on batch inserts; fix IDEA analyser warning 2016-12-27 12:39:54 +00:00
bakatrouble a8fea0fc49 Implement NodeDataHolder 2016-12-27 12:39:54 +00:00
Luck 2d5975d6e3 Vault only save if a change was made 2016-12-27 12:24:19 +00:00
Luck 6874cfd5b1 WIP: implement better sql schema - towards #77 2016-12-24 20:30:35 +00:00
Luck d34013396a woops 2016-12-23 16:59:01 +00:00
Luck a35b0915ab Refactor SQL storage - towards #77 2016-12-23 16:55:35 +00:00
Luck b35f3b4375 Properly cleanup in the case of a reload - towards #100 2016-12-23 11:28:42 +00:00
Luck f4f9612789 Fix MongoDB auth-less connection 2016-12-23 10:14:41 +00:00
Luck bfc79c6051 Reduce page entry count to 15 - resolves #95 2016-12-22 22:06:41 +00:00
Luck d3e60487bb Download dependencies at runtime instead of shading them in the jar 2016-12-22 21:17:02 +00:00
Luck f36f411a8d Fix broken inheritance caching system - closes #97 2016-12-22 17:50:56 +00:00
Luck 35f4aea69f Maybe fix caching issues - closes #99 2016-12-22 15:34:22 +00:00
Luck 8795383e7c Make sync command reload sponge data too - resolves #98 2016-12-21 21:34:43 +00:00
Luck fc4750706b Cleanup sponge files and don't persist empty sections - resolves #96 2016-12-21 21:33:32 +00:00
Luck 0ae59bd3e6 show group weight value in the group info command output 2016-12-21 21:26:22 +00:00
Luck 61fd14c816 Add group setweight command - closes #94 2016-12-21 21:22:48 +00:00
Luck c7d3d87b09 Fix verbose recording filters (again) 2016-12-20 13:59:56 +00:00
Luck 5e68f7b58c Implement paginated permission listings - closes #80 2016-12-20 13:55:42 +00:00
Luck 8a692200d5 Improve memory footprint in low throughput caches 2016-12-20 12:42:20 +00:00
Luck 829eacb0fb Fix verbose recording not taking note of filters 2016-12-20 02:53:37 +00:00
Luck 9aeca91f22 Allow space on Sponge Group subjectcollection 2016-12-19 21:52:26 +00:00
Luck 1bdb512826 Ease handling of group names containing spaces, after a faulty migration process 2016-12-19 21:50:34 +00:00
Luck 060fa6e5f7 change weight node 2016-12-19 18:22:32 +00:00
Luck 171a54c0fc PEX migration - include username too. Closes #92 2016-12-19 01:22:47 +00:00
Luck 17406b448d Add more detail to the group info command 2016-12-18 23:34:33 +00:00
Luck b4b661a3ad Set default port 2016-12-18 10:16:05 +00:00
Luck 4857969ca4 Cache calls querying parent groups in bridge subjects - closes #69 2016-12-18 09:57:39 +00:00
Luck d9d01e09aa Cache collation keys - resolves #90 2016-12-18 09:42:27 +00:00
Luck dadca97d8a actually remove 2016-12-17 00:04:04 +00:00
Luck 8afba8b53d remove /p alias 2016-12-17 00:03:21 +00:00
Luck 85dac1184c silence NPE in autoop listener 2016-12-16 22:47:44 +00:00
Luck 4167460d28 Print true/false alongside permission info output for consoles without color. Closes #84 2016-12-16 19:21:36 +00:00
Eric Coan 1d8a60749d help tame mysql connection settings
this commit further helps tame the mysql connection pool (and really
reconnecting to the pool even when the underlying db goes down) further
from commit: #31a597c

this sets up `setValidationTimeout`, and `setConnectionTestQuery`
in order to better (more speedily(?)/fastly(?)/<other adective>ly(?))
handle connection timeouts in a timely manner. (although admittedly
this is already handeled well imo with the cache). however, it could
be better ™️.

in order to do this I did the following things:
  1. Switch to `TimeUnit.SECONDS.toMillis` instead of manually entering
     milliseconds, and having the time in seconds as a comment. just
     makes it more readable imo. if you want me to change it back I can
     I'm not like attached to this or anything.
  2. Perform more common validation timeouts with `setValidationTimeout`
     this allows us to potentially bump back up the connection timeout
     (although I see no harm leaving it where it is), although allows
     us to still "fail-fast" in a way when doing validations.
  3. Use `setConnectionTestQuery` for people who somehow someway
     may not be using a JDBC4 compliant driver.
2016-12-16 17:14:24 +00:00
Luck 31a597ca81 lower mysql connection timeout - may help with #81 2016-12-12 22:21:54 +00:00
Luck e5e77ffec5 Add PEX track migration - closes #78 2016-12-12 19:51:21 +00:00
Luck 41c3df41b4 Allow group weights as permission nodes - resolves #73 2016-12-12 19:30:42 +00:00
Luck 053066f1a7 add parent clear command - closes #67 2016-12-12 19:06:23 +00:00
Luck 21135dac07 Implement (partially) clickable permission lists - towards #68 2016-12-12 18:56:48 +00:00
Luck 22ccce3208 Default the value to true in set/settemp commands if no arg is given. Closes #82 2016-12-12 16:52:15 +00:00
Luck 70aa3964ee Run all commands on the same thread - fixes #79 2016-12-11 11:34:18 +00:00
Luck 167489823a more lenient command blocking 2016-12-09 19:39:05 +00:00
Luck d1426f1b37 change jar names 2016-12-08 19:33:49 +00:00
Luck 7dcdc59c8e Fix IllegalArgumentException with BiMap#put 2016-12-08 16:30:00 +00:00
Luck 1e13ee87af cleanup imports 2016-12-07 22:21:22 +00:00
Luck 5101c1a759 fix build 2016-12-07 22:16:01 +00:00
Slind14 74bb079625 Fix zPermissions imports (PR #72, fixes #61)
* removed zPerm inherit loop check. (blocked the import due to throwing NPE)

* should fix zperm migration (group inheritance and memberships)

* zperm import, include username

* zperm import: fixed memberships
2016-12-07 22:13:50 +00:00
Luck 2da7979d94 Partially add clickable command listings - towards #68 2016-12-07 22:09:11 +00:00
Luck 4ecb2c7c27 Closes #58 - Disable OP commands on Sponge 2016-12-07 21:27:50 +00:00
Luck 251f51b01c add missing messages 2016-12-07 21:20:54 +00:00
Luck 2fba9b83af apply group rewrites to vault - resolves #59 2016-12-07 21:18:57 +00:00
Luck 1c97cb3cec Sponge: Fix migration for subjects with identifiers containing spaces 2016-12-07 21:14:24 +00:00
Luck 25511f898c implement clickable message base - towards #68 2016-12-07 21:08:40 +00:00
Luck d820f153a9 idk 2016-12-06 22:35:06 +00:00
Luck 77b06acad4 declare child states 2016-12-06 21:53:57 +00:00
Luck 6760a96527 Ensure holder state is always declared 2016-12-06 21:48:37 +00:00
Luck 257f426ab9 implement cached state for all permission holders. towards #69 2016-12-06 21:33:55 +00:00
Luck 3771a50f30 cleanup 2016-12-06 19:21:48 +00:00
dracnis 85ee211172 Update VaultChatHook.java
need update as soon as possible.
2016-12-06 19:03:01 +00:00
Luck 1b7a66b41a Fix #66 2016-12-04 23:09:12 +00:00
Luck 8f9a1aa931 Add verbose pastebin upload functionality - resolves #55 2016-12-03 19:30:25 +00:00
Luck 8b60fd0e55 Sponge: remove spammy user not already loaded message 2016-12-03 14:11:53 +00:00
Luck cd7b3b4f6e Fix compat with older guava versions 2016-12-03 13:55:51 +00:00
Luck 83b0f62d59 Implement full caching for non user/group subjects 2016-12-03 13:26:17 +00:00
Luck dd3a78ada8 Fix #65 2016-12-03 11:08:47 +00:00
Luck 307e2b889c Changes for version 2.16 2016-12-02 20:20:31 +00:00
Luck a063f7664d Fix #54 - getPermissionValue not checking default user 2016-12-02 17:26:38 +00:00
Luck b1ab857592 Merge remote-tracking branch 'origin/master' 2016-12-02 17:21:10 +00:00
Luck 2b8bbc434f WIP: Sponge service refactor 2016-12-02 17:20:36 +00:00
Luck c6878c27b9 Fix Vault #setPrefix method 2016-11-30 21:43:10 +00:00
Luck 02ff4a4acb cleanup 2016-11-29 23:35:25 +00:00
Luck 23f757e916 fix formatting 2016-11-28 21:50:19 +00:00
Luck f0ababa409 Maybe fix lilypad uuid retrieval 2016-11-28 21:39:10 +00:00
Luck 331ff341f3 Fix autoop 2016-11-28 20:11:10 +00:00
Luck 793a84edfb Sponge: replace MemorySubjectData with own implementation 2016-11-26 17:19:04 +00:00
Luck 2893d4aebd Silence InterruptedException when the plugin disables 2016-11-26 13:21:21 +00:00
Luck b7ac7680d9 Fix NPE 2016-11-25 21:19:12 +00:00
Luck 18dd59ed0f Refactor Sponge subject handling 2016-11-25 20:59:28 +00:00
Luck 443906da55 Refactor managers 2016-11-25 18:28:10 +00:00
Luck a9f29da4f8 Fix potential memory leak 2016-11-24 21:59:48 +00:00
Luck cf456cff81 Implement tab completion for permissions 2016-11-24 19:07:01 +00:00
Luck 69b3c96e09 Fix Sponge subject data permission overrides 2016-11-23 22:17:49 +00:00
Luck 61eb86b3a0 Fix Sponge defaults serialization 2016-11-23 21:44:59 +00:00
Luck f0ad32bc37 Change PermissionService handling 2016-11-22 21:57:51 +00:00
Luck aeeb2820f9 Sponge: also migrate defaults 2016-11-22 21:14:43 +00:00
Luck 2d88405d69 Fix onLateEnable always being fired 2016-11-22 20:42:43 +00:00
Luck f32ed5db89 Fix Sponge PEX migration 2016-11-22 20:39:56 +00:00
Luck f1606ac51b API changes for 2.15 2016-11-22 18:27:40 +00:00
Luck d13eb1a55d Fix default assignments never being applied on Bungee 2016-11-21 18:26:37 +00:00
Luck 384fbf5464 Revert: Use faster wildcard parsing method 2016-11-21 17:07:13 +00:00
Luck 4874f9d051 Use faster wildcard parsing method 2016-11-20 20:41:39 +00:00
Luck 51732fa660 Rearrange some packages, general cleanup 2016-11-20 13:44:36 +00:00
Luck bb25632178 Improve info command 2016-11-19 21:56:11 +00:00
Luck 9a2cf82623 Improve user info command 2016-11-19 17:52:39 +00:00
Luck c0734fc29e refactor contexts slightly 2016-11-18 22:39:00 +00:00
Luck c60067e733 Maybe fix zPerms migration & tidy up shorthand parser 2016-11-17 22:02:47 +00:00
Luck 6293634e36 refactor shorthand nodes 2016-11-17 20:50:37 +00:00
Luck a047695a84 Fix issue with nodes never being removed on sync with flatfile storage types 2016-11-17 19:01:58 +00:00
Luck db9d84ed76 Maybe fix issue with corrupted permission migration 2016-11-15 20:18:32 +00:00
Luck e296b1df60 Fix migration commands never being executed 2016-11-15 18:17:35 +00:00
Luck b72e5f5437 Update plugin.yml to make LuckPerms always enable before Vault 2016-11-14 22:50:11 +00:00
Luck de09ae94b8 Fix Vault hook - thanks @Yann151924 2016-11-14 22:32:06 +00:00
Luck b36a33f015 Make meta info command show where meta was inherited from 2016-11-14 20:40:33 +00:00
Luck d95891256b Setup a users calculated data when loaded by the SubjectCollection 2016-11-14 18:55:10 +00:00
Luck 9c8097ecb9 Sponge: Implement support for editing more than just users/groups with commands 2016-11-14 18:45:48 +00:00
Luck 18a3dfd604 cleanup 2016-11-13 19:30:46 +00:00
Luck 59fd337e44 remove debug messages, woops 2016-11-13 11:12:06 +00:00
Luck 696cd235fd Fix meta serialization. Resolves #41 2016-11-13 11:09:57 +00:00
Luck 59c7efccb2 Fix Sponge plugin guice load failure. Thanks @gravityfox 2016-11-13 09:44:34 +00:00
Luck b031ebbffd Update readme 2016-11-12 17:27:15 +00:00
Luck 67415babc2 Fix javadocs & fix compile 2016-11-12 16:25:44 +00:00
Luck 563dd4683d Changes for & release of API 2.14 2016-11-12 14:10:42 +00:00
Luck e9131f729a add methods for older sponge api versions 2016-11-11 22:54:09 +00:00
Luck c4ea626e33 Fix PM migration 2016-11-11 20:43:05 +00:00
Luck fefba7976b Actually register new migration command 2016-11-11 20:35:11 +00:00
Luck 2ce8555692 Add Sponge PermissionManager migration support 2016-11-11 20:31:42 +00:00
Luck 9fe9c386bb Sponge: rely less on dummy subjects 2016-11-11 19:32:25 +00:00
Luck e8cd2c7548 More command refactors 2016-11-10 22:13:53 +00:00
Luck 158d8b086a Command refactor 2016-11-10 19:19:43 +00:00
Luck 1c534d7475 More cleanup 2016-11-08 20:46:29 +00:00
Luck 90f8dbe243 Refactor commands 2016-11-07 22:02:48 +00:00
Luck 0c33b26fa9 Refactor meta accumulation 2016-11-07 19:01:15 +00:00
Luck d320679f69 Implement proper meta inheritance handling 2016-11-07 17:32:17 +00:00
Luck 8d5398b5a3 Make nodes with more contexts take priority over nodes with less 2016-11-06 16:15:45 +00:00
Luck 6cd8593fa5 Fix vault primary group override feature 2016-11-06 15:11:28 +00:00
Luck 5ebbc178a5 Remove messenger system & more cleanup 2016-11-06 14:56:13 +00:00
Luck 4f6e229943 Small cleanup 2016-11-05 23:23:08 +00:00
Luck 3e846d9527 Maybe fix split storage - closes #38 2016-11-05 21:43:48 +00:00
Luck 981d745b74 Fix verbose system 2016-11-05 19:19:29 +00:00
Luck 2dd0858960 Allow multiple verbose filters 2016-11-05 19:01:06 +00:00
Luck f72819a664 Try to reduce contention in PermissionHolder 2016-11-05 17:49:52 +00:00
Luck 5361b1e87b Implement group weights 2016-11-05 09:04:26 +00:00
Luck e15d03ed4e Fix parents being cleared on promote/demote 2016-11-05 07:53:18 +00:00
Luck 6c9041ce40 Improve meta info command 2016-11-04 19:13:39 +00:00
Luck 8da96e6e48 Re-add showtracks/showpos commands 2016-11-04 18:36:32 +00:00
Luck 385aa6d438 Add set "none" command as an alternative to unset 2016-11-04 16:40:55 +00:00
Luck 79f24a5944 Improve track functionality. Resolves #39 2016-11-01 21:34:54 +00:00
Luck 80570717f9 Fix slow datastore performance when using the API 2016-11-01 19:41:40 +00:00
Luck ebab79c4ca Maybe fix blocking issue with #getPermissions 2016-11-01 19:38:08 +00:00
Luck 42882ebe11 Update some ugly messages 2016-10-31 22:25:42 +00:00
Luck d2de26f765 Move hasperm/inheritsperm commands & add parent set command. Resolves #40 2016-10-31 19:27:04 +00:00
Luck e2cebfbd16 Refactor Node class 2016-10-31 18:18:31 +00:00
Luck a58cc6bdf3 Refactor PermissionHolder 2016-10-30 21:29:14 +00:00
Luck 36bc1553c0 Implement Sponge timings 2016-10-30 19:35:11 +00:00
Luck 17b06c39e9 Ignore negated primary group override nodes & fix broken message 2016-10-30 15:29:55 +00:00
Luck ba2f6eb7be Update .gitignore 2016-10-30 13:37:25 +00:00
Luck b93145f26d Change some listener priorities 2016-10-30 13:23:45 +00:00
Luck e88ea9c13d Don't fully unload Sponge user subjects 2016-10-30 13:21:43 +00:00
Luck 1275d0023d Listen to PlayerQuit on monitor priority 2016-10-29 22:58:06 +01:00
Luck 27f6f225c9 whoops 2016-10-29 21:56:55 +01:00
Luck 41362aa34a Use a temporary executor until the bukkit one has started 2016-10-29 21:54:13 +01:00
Luck a99609e016 Don't wrap buffer tasks in scheduler calls 2016-10-29 21:23:30 +01:00
Luck c0ea2d8ec3 Fix data not being loaded sync when the plugin starts 2016-10-29 21:14:59 +01:00
Luck bb6b31d715 change Sponge listener priorities 2016-10-29 21:12:55 +01:00
Luck 21695dd2cb Implement support for Bukkit child permissions 2016-10-28 19:16:32 +01:00
Luck 531835c948 Fix GroupManager primary group migration 2016-10-28 18:00:18 +01:00
Luck 77e3b351fd Fix GroupManager user migration 2016-10-28 17:58:36 +01:00
Luck 66f756575a Remove redundant config option 2016-10-27 18:48:38 +01:00
Luck 7acc8bc7ed Add verbose command 2016-10-27 17:46:44 +01:00
Luck 0a4d337a53 Cache context lookups & refactor Sponge subjects 2016-10-27 16:32:14 +01:00
Luck 0198068a13 Improve permission lookup speed (slightly) 2016-10-26 21:35:44 +01:00
Luck 1c15f8462f Don't run commands through the buffer system 2016-10-26 19:52:03 +01:00
Luck 3929ce0dfc Fix compile 2016-10-26 19:32:41 +01:00
Luck 7deeaf305d Experimental: Run I/O after commands in a new thread 2016-10-26 17:55:38 +01:00
Luck 0f04c06e13 Remove redundant method 2016-10-26 17:19:56 +01:00
Luck d1863fa714 Implement more customizable primary groups 2016-10-26 17:19:33 +01:00
Luck 46b122a167 Fix memory leak preventing users from being unloaded 2016-10-25 18:44:11 +01:00
Luck ee3db1e5c5 Maybe fix GroupManager primary group migration 2016-10-25 15:02:49 +01:00
Luck bd830617c9 Small cleanup 2016-10-25 11:14:56 +01:00
Luck a9b6493091 A few small optimizations 2016-10-24 18:48:39 +01:00
Luck 9894e45516 Fix issue with Vault lookups not being preprocessed 2016-10-24 15:57:05 +01:00
Luck 2cfc82f3aa Implement support for instant data propagation with Redis 2016-10-24 14:38:12 +01:00
Luck bb9eab0989 Lower sync wait buffer & fix export command 2016-10-24 13:02:26 +01:00
Luck dc87ec1c82 Update placeholder expansion 2016-10-24 09:57:29 +01:00
Luck 98b7b65ce7 Remove PEX dependency 2016-10-24 09:22:53 +01:00
Luck 9f8f32b33e Fix suffixes not being applied 2016-10-23 22:02:48 +01:00
Luck a80ec6d893 Implement PermissionsEx 2.0 migration for Sponge 2016-10-23 20:42:58 +01:00
Luck 4d85930f5a Refactor migration classes 2016-10-23 20:42:25 +01:00
Luck f722f4112d Update default-lang.yml 2016-10-23 17:59:34 +01:00
Luck 383276f47a Refactor contexts, expose cached data in the API & release 2.13 2016-10-23 16:46:53 +01:00
Luck 33c78e4a17 Use LoadingCache instead of a regular map + more datastore fixes 2016-10-22 20:39:26 +01:00
Luck 55a0de7899 Lower buffer time to 1 second. Should resolve any issues with changes being overridden. (related: #32) 2016-10-22 18:52:51 +01:00
Luck 6b3aab66bf Fix some #saveX methods being waited for, when they can just be ran async 2016-10-22 09:35:11 +01:00
Luck 77e70ef8d3 Fix deadlocks caused by waiting for async operations to complete before the scheduler has started 2016-10-22 09:21:30 +01:00
Luck 9b92143501 prevent logins until the plugin has started 2016-10-22 00:07:30 +01:00
Luck 87f94f6b8f add started value to bukkit plugin 2016-10-22 00:05:33 +01:00
Luck 5d955e77b6 Make the max pool size configurable 2016-10-21 22:22:06 +01:00
Luck 270a276b98 Refactor SQL storage to not hold onto connections for as long 2016-10-21 22:07:14 +01:00
Luck be7d914e39 Finish the buffering refactor - still WIP. Towards #32 2016-10-21 18:34:53 +01:00
Luck 37fc00cce8 Refactoring storage - WIP. Towards #32 2016-10-20 21:55:34 +01:00
Luck 0d515abadb Cleanup some bad code in SQLDatastore. Might help #32 2016-10-19 23:30:30 +01:00
Luck daef01194e Shade MySQL connector into Sponge jar. Resolves #31 2016-10-19 22:23:43 +01:00
Luck 258bf1cc41 small cleanup 2016-10-19 20:57:53 +01:00
Luck ce3d7829d7 Update internal permissions to match the new command layouts 2016-10-19 20:14:16 +01:00
Luck c66a01c1a6 Fix temporary permission expirations never persisting. Fixes #30 2016-10-19 17:37:26 +01:00
Luck d113a92ce5 Cleanup permission calculation 2016-10-18 20:48:59 +01:00
Luck 7b655d12df Add set-primary-group option to the default assignments 2016-10-17 18:23:41 +01:00
Luck a4c872f1e8 Fix per-world permissions not working until a user switches worlds 2016-10-17 17:10:02 +01:00
Luck 0e7d9bf9c1 Bump hikari version 2016-10-16 21:05:25 +01:00
Luck 6252a5bc75 Fix invalid property 2016-10-16 20:53:12 +01:00
Luck e4e80c9c31 Update to SpongeAPI 5.0.0 release 2016-10-16 18:13:55 +01:00
Luck 165c5610c3 Add extra Hikari flag 2016-10-16 17:24:02 +01:00
Luck 13fbc7dd39 Implement default assignment system (#25) 2016-10-16 13:58:57 +01:00
Luck 02a75fc32a Reimplement autoop on Bukkit & other misc fixes 2016-10-15 21:04:04 +01:00
Luck 699c4d107b Swap the javaassist maven plugin with a better method 2016-10-15 08:59:49 +01:00
Luck e4810302e1 Implement meta / Sponge option commands & fix meta caching system. Fully resolves #23 2016-10-14 22:49:32 +01:00
Luck 73f10cad66 Make the recent command changes backwards compatible 2016-10-14 20:42:00 +01:00
Luck f1d670dc46 refactor permission commands 2016-10-14 19:55:22 +01:00
Luck 045539c752 refactor inheritance commands 2016-10-14 19:19:57 +01:00
Luck 782c09b686 Refine bulk group edit primary group check 2016-10-13 21:29:30 +01:00
Luck 6109718c67 Cleanup some remaining TODOs 2016-10-13 21:16:34 +01:00
Luck cd758d7e48 Bump minor version 2016-10-13 20:40:09 +01:00
Luck fcb0fcadeb Fix StackOverflowException 2016-10-13 20:36:08 +01:00
Luck 26fb506560 Reorganize packages 2016-10-13 20:07:10 +01:00
Luck b6c4239322 Fix NPE 2016-10-13 19:43:48 +01:00
Luck 74f9283f18 Silence exception on #giveDefaultIfNeeded. Resolves #26 2016-10-13 19:25:31 +01:00
Luck 60e6ae6e23 Fix Sponge implementation, remove standalone module 2016-10-13 19:13:34 +01:00
Luck 83d9229295 Refactor caching system (WIP) - still working towards #23 2016-10-12 21:57:57 +01:00
Luck e079b0f3ed Fix meta command showing when a user doesn't have permission to use it 2016-10-11 21:17:04 +01:00
Luck d433a5461d Refactor meta commands, working towards #23 2016-10-11 21:12:10 +01:00
Luck 2c43f6bf21 Fix global permissions and groups sometimes not applying 2016-10-11 19:31:55 +01:00
Luck ac57509a29 Fix prefix/suffix priorities being ignored 2016-10-11 19:31:26 +01:00
Luck c5ce655cf6 Add Vault chat debug messages 2016-10-11 19:06:18 +01:00
Luck 9fe05efb4e Don't force the default group 2016-10-11 18:54:42 +01:00
Luck dcf207f5e5 Fix exception, resolves #20 and #22 2016-10-10 22:39:24 +01:00
Luck 11facab71c Fix NPE, resolves #19 2016-10-10 22:26:39 +01:00
Luck 5b4975f34c Implement persisting subjects (+ defaults) 2016-10-10 18:58:43 +01:00
Luck 069e535f1a Avoid odd behavior where Sponge prevents User subjects from being GCed 2016-10-09 21:34:05 +01:00
Luck 1eb053447e Make refresh calls in SpongeListener run async 2016-10-09 20:49:17 +01:00
Luck 93c7c06b2d Cleanup some Sponge subject classes 2016-10-09 13:14:58 +01:00
Luck b0085bc1e1 Update readme 2016-10-09 10:58:14 +01:00
Luck 9133951446 I'm dumb 2016-10-08 16:45:18 +01:00
Luck 7853d4686a Fix NPE with LPPermissibles & refreshing users 2016-10-08 16:43:57 +01:00
Luck ed5892eb56 add option to ignore vault world parameters 2016-10-08 15:01:54 +01:00
Luck 687804de2c small change to BukkitConfig 2016-10-08 09:05:48 +01:00
Luck 9d166041ab Account for inheritance and wildcards in SimpleSubject 2016-10-07 18:11:59 +01:00
Luck 924041bff4 Add server and world args to clear command, and add clearmeta command 2016-10-06 21:23:27 +01:00
Luck e9216d3e0f Allow the prefix to be modified by the lang file 2016-10-06 19:54:52 +01:00
Luck db8f1bca66 Fix API javadoc & fix Bukkit legacy build 2016-10-06 17:21:04 +01:00
Luck 2429831153 API changes for 2.11 2016-10-05 21:40:54 +01:00
Luck 80d2246634 Fix exporting users not in the default group 2016-10-04 20:48:58 +01:00
Luck 56df2477ca Fix UnsupportedOperationExceptions with #getPermissions 2016-10-04 17:30:27 +01:00
Luck 9b4384dc33 Revert: Merge dummy implementations 2016-10-04 17:15:10 +01:00
Luck bc65857831 Fix CME 2016-10-04 17:13:32 +01:00
Luck de462d2385 Merge dummy implementations 2016-10-04 16:58:54 +01:00
Luck 90150428be Inject a dummy on quit instead of a real PermBase instance 2016-10-04 16:19:41 +01:00
Luck 2a7f951f4f Fix NPE / crash on player quit 2016-10-04 16:10:06 +01:00
Luck 82789328c1 Pre-process permissions and apply immediately on login events 2016-10-04 14:57:00 +01:00
Luck 13bccd1d3f Fix users not receiving permission updates 2016-10-03 21:41:47 +01:00
Luck 43c514132d Cache node deserialization 2016-10-03 21:18:59 +01:00
Luck 9e0fdcbfee Fix memory leak, woops 2016-10-03 20:43:36 +01:00
Luck 008dc3fc52 Move some classes around 2016-10-03 20:42:11 +01:00
Luck 9fde237d9b Swap slow get method 2016-10-03 19:53:43 +01:00
Luck d626c08b4c Small fix for #getAllWithPermission 2016-10-03 16:45:52 +01:00
Luck 58e223e74b Implement bulk prefix/suffix removal 2016-10-02 21:17:59 +01:00
Luck 1da1df156e Fix issues related to Node comparisons 2016-10-02 15:44:46 +01:00
Luck 3442372281 Cleanup random debug messages 2016-10-02 15:43:44 +01:00
Luck 1b3b50c113 Refactor PermissionHolder & Sponge subjects 2016-10-02 15:05:53 +01:00
Luck 18e126b781 Fix issue with permissions sometimes not being removed 2016-10-02 10:33:58 +01:00
Luck c88600adda Make User constructor protected. Closes #18. 2016-10-01 22:56:57 +01:00
Luck 4787361e66 Implement locks to hopefully resolve race conditions with I/O - experimental 2016-10-01 19:03:05 +01:00
Luck b5ece8b5bd Fix exception 2016-09-30 22:26:39 +01:00
Luck 7ee3116f29 Maybe fix broken inheritance 2016-09-30 20:43:08 +01:00
Luck 1fc0d77971 Cache & fix (and maybe break) Vault Chat implementation 2016-09-30 20:08:59 +01:00
Luck a32ab4bf7f Show where a permission was inherited from in the inheritsperm command 2016-09-30 19:21:19 +01:00
Luck 2d8083bf18 Another Vault fix & cleanup User / Group classes 2016-09-30 17:45:29 +01:00
Luck 63b9be9845 Change Vault behavior & cleanup Node class 2016-09-30 17:09:19 +01:00
Luck 85a83d8c71 Add logging output to Vault 2016-09-29 22:04:46 +01:00
Luck 71b33a296c Calculate Sponge defaults using context 2016-09-29 20:38:03 +01:00
Luck becdfd6f03 Silence subject load errors unless debug-permission-checks is true 2016-09-29 20:02:38 +01:00
Luck 41744f9416 Add clone commands 2016-09-29 18:07:41 +01:00
Luck cb89a92ba9 Message colour changes and standardization 2016-09-28 21:16:07 +01:00
Luck 93d54373c6 Add detailed command info system 2016-09-28 20:59:08 +01:00
Luck 385addfe08 cleanup 2016-09-27 20:21:13 +01:00
Luck 4c21957b04 Cache Vault lookups & properly sort listnodes output 2016-09-27 20:18:06 +01:00
Luck ab6b011225 Fix permission lookups being case sensitive 2016-09-26 18:52:01 +01:00
Luck e72d91503c Maybe nicer looking messages 2016-09-26 18:42:46 +01:00
Luck b9ee206908 Add some more bulk edit commands 2016-09-25 21:23:48 +01:00
Luck 4c9abba5fa Maybe fix vault (again) 2016-09-25 19:26:36 +01:00
Luck 3424b0542a Release 2.10 2016-09-25 17:32:58 +01:00
Luck fec90b8958 Add bulkchange commands 2016-09-25 17:29:11 +01:00
Luck 4da7fe4ff9 Small fixes to context system 2016-09-25 16:55:14 +01:00
Luck c53623dd67 Make command usage output easier to read 2016-09-25 14:34:27 +01:00
Luck 6540ffa4dd Refactor storage 2016-09-25 12:47:15 +01:00
Luck 5ee6db02ff Proper context implementation - WIP 2016-09-25 10:19:36 +01:00
Luck d8221f466a Fix messages not being formatted correctly 2016-09-24 17:22:33 +01:00
Luck 462bea2a09 Remove broken repo, maybe fix build 2016-09-24 16:58:45 +01:00
Luck f452a97278 fix typo 2016-09-23 22:19:17 +01:00
Luck eb9d2be587 Add locale file support 2016-09-23 22:14:40 +01:00
Luck df1e747861 Add commands to view inherited groups 2016-09-23 19:23:31 +01:00
Luck f48595b1ff Add world and group name rewriting, refactor configs 2016-09-23 18:58:19 +01:00
Luck 12cd4e19cb Update config comments 2016-09-22 18:25:49 +01:00
Luck a195e94522 Calculate defaults after all plugins have loaded 2016-09-22 17:34:51 +01:00
Luck 02abb39dc2 Change #isPermissionSet to be more like the Bukkit impl 2016-09-21 22:04:18 +01:00
Luck f7a0b1ef78 Refactor default permissions to be less bad 2016-09-21 21:30:42 +01:00
Luck 7678f25879 Fix default permissions not properly applying on Bukkit 2016-09-21 17:40:05 +01:00
Luck fa9324bda8 Implement basic standalone base, working towards #9 2016-09-20 21:50:28 +01:00
Luck 1e72f9d8fe Listen on lowest priority, may fix issues with plugins checking for permissions on login events 2016-09-20 21:04:53 +01:00
Luck 50fd954599 Use a BiMap in UuidCache 2016-09-19 21:13:45 +01:00
Luck b1e34b55f8 Re-add regex permissions & actually take note of the config options 2016-09-19 21:00:23 +01:00
Luck cff1b8a411 Separate PermissionProcessor into own class 2016-09-19 20:45:37 +01:00
Luck 6ffa6720be Make more specific wildcards take priority over less specific ones 2016-09-19 20:36:52 +01:00
Luck f52a106165 Order nodes alphabetically after other priority rules have been applied 2016-09-19 17:31:00 +01:00
Luck bf247b71e1 Fix possible race condition & maybe use better Hikari flags 2016-09-18 23:13:20 +01:00
Luck 66818e4c82 Fix build 2016-09-17 23:46:11 +01:00
Luck 23d53d39b4 Refactor permission calculation 2016-09-17 23:15:07 +01:00
Luck 30ea5a5b69 Fix no permissions applying when include-global is false, and better support per-server/per-world groups 2016-09-17 19:05:56 +01:00
Luck e7a210dc06 Update default configs 2016-09-16 22:09:55 +01:00
Luck 497de9824a Actually pass on a single wildcard node so it gets applied 2016-09-16 21:46:55 +01:00
Luck be74b50762 Fixes for offline mode servers 2016-09-16 21:24:25 +01:00
Luck f2e06b56e7 Cache permission lookups 2016-09-16 21:11:12 +01:00
Luck f6aa20c300 Fix compile 2016-09-15 17:12:19 +01:00
Luck 5e16134f6f Provide prefixes and suffixes through the PS options 2016-09-15 17:06:27 +01:00
Luck 6165fcbb21 Fix #getDefaults for users 2016-09-15 16:54:12 +01:00
Luck 831e882db0 Actually apply default permissions on Sponge 2016-09-15 16:53:03 +01:00
Luck feb8bf4bd3 Update readme 2016-09-14 20:16:36 +01:00
Luck ce3ee866ca Sponge fixes 2016-09-14 19:37:20 +01:00
Luck d29dd35689 Support the latest powerfulperms so-called "api" 2016-09-13 20:14:16 +01:00
Luck 3a0a89853f Apply negated wildcards 2016-09-13 17:23:16 +01:00
Luck e7ca79d251 Use Splitter instead of Patterns, don't split arguments in quotes 2016-09-12 19:00:37 +01:00
Luck 22426bab33 Update placeholders to use the latest API version 2016-09-11 15:36:19 +01:00
Luck 116094ea96 Maybe fix an issue with per-server prefixes/suffixes 2016-09-11 14:34:38 +01:00
Luck 9df39a9545 Inject PermissibleBase instead of using attachments. Resolves #14 2016-09-11 11:50:59 +01:00
Luck b8f44df723 Add missing headers 2016-09-10 22:40:36 +01:00
Luck 74f275eb69 Add more info the importer error output 2016-09-10 22:08:07 +01:00
Luck 1142cbcb2c Add platform type to the info command 2016-09-10 21:54:31 +01:00
Luck 37749e5829 Don't apply the default group when exporting users 2016-09-10 16:53:04 +01:00
Luck f9025c7a51 fix #getUniqueUsers for SQL storage types 2016-09-10 16:38:37 +01:00
Luck c7bfc38477 Build an extra jar with guava and gson shaded to support 1.7 2016-09-10 16:32:37 +01:00
Luck 7ca394d7b9 Add some extra console output to the debug command 2016-09-10 14:35:12 +01:00
Luck 31884ea59d Maybe fix race condition with messages not sending 2016-09-10 14:31:42 +01:00
Luck e79b7c7023 Update readme 2016-09-10 09:04:59 +01:00
Luck 1fdb4e8ade Merge pull request #11 from HeroCC/patch-1
Fix PermissionsEx false node migration
2016-09-09 21:49:43 +01:00
HeroCC 53db8c5928 Fix PermissionsEx false node migration
PermissionsEx false nodes begin with a '-' not a '!'
2016-09-09 16:39:13 -04:00
Luck 07514000a4 Fix global groups not being migrated from GroupManager 2016-09-09 18:41:15 +01:00
Luck f28721e55a Possible fix for permissions not applying on BungeeCord 2016-09-09 18:32:50 +01:00
Luck fc230291d3 Fix ops not receiving all permission nodes 2016-09-09 18:00:38 +01:00
Luck 89ff4cfa40 Add a much better system for exporting data 2016-09-08 21:01:37 +01:00
Luck d786b6abb2 Fix removing negative nodes 2016-09-08 17:28:31 +01:00
Luck fb0e694155 Add auto-op. Closes #8 2016-09-07 23:21:24 +01:00
Luck cd6cac1fb6 Fix bad grammar in config option comment 2016-09-07 21:01:03 +01:00
Luck ea07f05097 Release 2.8 2016-09-07 20:53:33 +01:00
Luck d84767af68 Fix blank users not receiving group permission updates 2016-09-06 22:28:37 +01:00
Luck aab73a8d81 Add more shorthand nodes 2016-09-06 22:27:46 +01:00
Luck 995fc2ccd8 Bump internal release version and add missing javadoc 2016-09-05 20:06:41 +01:00
Luck 60bcd5f643 Release 2.7 2016-09-05 20:00:01 +01:00
Luck ba04fb320b Remove unnecessary reflection 2016-09-05 16:44:59 +01:00
Luck 770b7dc282 Fix permissions not being removed on Sponge 2016-09-04 17:59:01 +01:00
Luck ed85eee36c Fix inherited permissions not applying on Sponge 2016-09-04 16:25:10 +01:00
Luck 23df8a2df8 Some small fixes 2016-09-04 16:24:36 +01:00
Luck 36cd388607 Slight re-wording 2016-09-03 21:34:35 +01:00
Luck 4d48ef1939 Add comment about Paper's "bungee-online-mode" option. Resolves #6 2016-09-03 21:30:37 +01:00
Luck 7970e2a1c6 Add bPermissions migration 2016-09-03 18:15:52 +01:00
Luck cee96d7daa make SenderFactory nicer & maybe faster 2016-09-03 00:14:40 +01:00
Luck 861c1ddd69 remove #childInit 2016-09-02 19:19:22 +01:00
Luck 5dec5a54cb Add YAML storage support 2016-09-02 19:15:31 +01:00
Luck 5c760aabd4 Fire PermissionRefreshEvent after the nodes have actually updated 2016-09-01 13:00:22 +01:00
Luck 1a2fa5d8c3 Fix log notify 2016-08-31 21:02:06 +01:00
Luck ef0c53da82 fix formatting 2016-08-31 09:38:47 +01:00
Luck 3fd62a80e2 Add support for split storage 2016-08-31 09:30:19 +01:00
Luck 5c19dd8b15 .-. 2016-08-30 22:38:08 +01:00
Luck 1fc88e147f Make output of listnodes nicer 2016-08-30 18:04:30 +01:00
Luck 9b4bbe0500 Make log notifications toggleable 2016-08-30 16:02:01 +01:00
Luck b37fdd3619 Add user to group instead of failing in setprimarygroup command 2016-08-30 13:23:48 +01:00
Luck ab00c41452 Fix NPE, and properly send possible permissions in BukkitUser 2016-08-30 13:06:36 +01:00
Luck c15727377b Apply single '*' wildcard 2016-08-30 12:49:46 +01:00
Luck 1e6f32bdc4 Add extra disallowed character 2016-08-30 11:54:18 +01:00
Luck 42e69c98a7 Change name limitation to be more flexible 2016-08-30 11:52:32 +01:00
Luck a217727bb4 Match negative priorities and fix PEX weight migration 2016-08-30 11:04:34 +01:00
Luck ba10b1c06e Fix removal of temporary nodes 2016-08-30 10:22:55 +01:00
Luck 075ba33e8b Add prefix/suffix/meta commands 2016-08-30 10:22:25 +01:00
Luck 19dbc7d90a formatting pls 2016-08-30 07:47:52 +01:00
Boomclaw ade70bb7ba PEX migration carries weights of prefixes/suffixes of groups and individuals (#5)
* PEX migration carries weights of prefixes/suffixes of groups and individuals.

* Forgot to increase maxGroupWeight.
2016-08-29 22:45:19 +01:00
Luck 4b67913eee getGroup methods should not include inherited groups 2016-08-29 22:03:10 +01:00
Luck 75858c1555 Use new Node system in #getGroups 2016-08-29 21:38:47 +01:00
Luck 659baaf5fb Make #getPlayerGroups return global too 2016-08-29 21:35:11 +01:00
Luck 3c83c578eb Fix typo 2016-08-29 18:40:37 +01:00
Luck 3ddbf1da87 Migrate PEX primary groups 2016-08-29 17:57:47 +01:00
Luck 35cb5b81dc hopefully fix server stopped responding error with SkipListSet 2016-08-29 16:28:36 +01:00
Luck 02d9b996a7 woops 2016-08-29 15:51:19 +01:00
Luck d4cf6a5ad7 Remove subjects from cache when they leave the server 2016-08-29 13:32:21 +01:00
Luck 9fdb4fa25f Maybe fix sponge permissions not expiring 2016-08-29 13:02:56 +01:00
Luck d5bc1cdf5d Fix not clearing user's permissions, and issue with unsetting permissions 2016-08-29 12:53:05 +01:00
Luck f5995c0afa Fix usernames showing as "null" and NPE related to primaryGroup not copying correctly 2016-08-29 12:11:03 +01:00
Luck 2cc65160b4 Bump release version 2016-08-28 22:12:34 +01:00
Luck 57f5a7c4cd Release 1.6 2016-08-28 22:05:10 +01:00
Luck 6aea3b53f3 Only save unique users 2016-08-28 21:36:16 +01:00
Luck 9f5e194a6e bug fixes 2016-08-28 17:43:02 +01:00
Luck 0831585a27 Fix SQL datastore 2016-08-28 15:43:21 +01:00
Luck b2cf6dce2d Prepare for 1.6 release 2016-08-28 15:29:02 +01:00
Luck a3ebf86f6b More progress towards 1.6: implement PermissionService 2016-08-28 14:57:03 +01:00
Luck 2a305b1c55 More progress towards 1.6: add transient permissions 2016-08-27 22:01:17 +01:00
Luck 2ea9b36c77 Build against Sponge API 5.0.0 2016-08-27 16:59:00 +01:00
Luck edaf174ebf Complete refactor of permissions/nodes. progress towards 1.6 2016-08-27 00:32:39 +01:00
Luck c4497db06c progress towards permissionservice 2016-08-26 16:58:47 +01:00
Luck 9873415303 Fix NPE 2016-08-25 18:07:50 +01:00
Luck 2b71476cfe Implement ConsecutiveExecutor 2016-08-25 18:07:32 +01:00
Luck 44d14001e1 Partially implement PermissionService 2016-08-25 17:23:27 +01:00
Luck de5fda6a18 Add some extra debugging output to PP migration 2016-08-25 01:31:38 +01:00
Luck 8b83a1d9a2 Fix sponge startup exception 2016-08-24 22:38:52 +01:00
Luck c0a0239eeb Update readme 2016-08-24 10:24:37 +01:00
Luck 84f377451e Make placeholder identifier lowercase 2016-08-23 20:11:53 +01:00
Luck 21d0c9ab0e Add some PlaceholderAPI placeholders 2016-08-23 19:32:58 +01:00
Luck f9c1cdb4bd Add group and track rename commands 2016-08-23 15:52:51 +01:00
Luck e89444141b Add logging for the migration processes 2016-08-23 15:18:20 +01:00
Luck 9cd4e01d8e Copy prefixes and suffixes during migration processes 2016-08-23 12:36:20 +01:00
Luck f7fa08d5e9 Call #recalculatePermissions on the main thread 2016-08-23 12:10:11 +01:00
Luck 7a4135319f Convert PermissionAttachment to use ConcurrentMap, and do refreshPermissions async 2016-08-22 22:39:40 +01:00
Luck 41fca40a36 Add some null / arg checks to Vault chat impl 2016-08-22 21:12:42 +01:00
Luck 9dbfa76b26 Add Vault chat support using permission nodes 2016-08-22 20:59:52 +01:00
Luck 20eeade06f Migration for BungeePerms 2016-08-22 19:46:37 +01:00
Luck cd9f18ffdb Properly close DB objects once PP migration is complete 2016-08-22 17:01:41 +01:00
Luck f7baf67985 Improvements to the JavaDocs in the API 2016-08-22 15:50:20 +01:00
Luck 692bf30cf5 Attempt to fix PermissionsEx migration 2016-08-22 07:07:13 +01:00
Luck 41b33fbd7a Fix typo 2016-08-22 00:22:06 +01:00
Luck 5dc551c05d Complete the migration system 2016-08-21 23:31:38 +01:00
Luck dd7aee9d15 Partially add migration support 2016-08-21 22:20:14 +01:00
Luck bbeed1e4ed A few small fixes 2016-08-20 17:49:23 +01:00
Luck 471084a9ef Fix NPE 2016-08-20 16:29:59 +01:00
Luck 6fc00976a0 Fire PermRefreshEvent in sponge too 2016-08-20 16:26:32 +01:00
Luck 4aa753515d Add events 2016-08-20 15:43:54 +01:00
Luck 7e933966cf revert remove sources 2016-08-20 02:19:03 +01:00
Luck b4d179f7b2 use a proper repo instead of the rubbish jenkins one 2016-08-20 01:39:19 +01:00
Luck a51acdbc88 remove sources 2016-08-19 22:23:28 +01:00
Luck 52e63a228d Update readme 2016-08-19 21:54:40 +01:00
Luck 9424d2d2ba Process shorthand in server/world names 2016-08-19 19:36:04 +01:00
Luck 0c12eebe6f Check temporary permissions separately to the sync task 2016-08-19 19:10:36 +01:00
Luck a15a0752f4 Add support for MongoDB and H2 database formats 2016-08-19 18:21:16 +01:00
Luck 31cef46b56 Fix sponge tab complete, fix bungee listeners & change some messages 2016-08-18 20:14:12 +01:00
Luck bfe0126816 fix format 2016-08-18 13:52:38 +01:00
Luck 98b56691dd Allow expiry timestamp for temporary assignment args 2016-08-18 13:51:31 +01:00
Luck 6451175d0e Fix some broken messages 2016-08-18 12:47:33 +01:00
Luck 9b4319c42d fix readme 2016-08-18 12:33:46 +01:00
Luck e9e7d81ddf Add import/export support 2016-08-18 12:30:51 +01:00
Luck 84afbf26f8 refactor LogEntry & cleanup stream formatting 2016-08-18 00:07:56 +01:00
Luck ca9037461a remove lombok from api and attach sources 2016-08-15 16:09:16 +02:00
Luck 9a3eeca411 idk 2016-08-15 12:06:36 +02:00
Luck e216c235ce Add logging, prepare for import/export system 2016-08-15 01:51:38 +02:00
Luck fbf062933f Fix build 2016-08-09 13:52:25 +02:00
Luck cf85f31da8 Bump minor version 2016-08-09 11:13:01 +02:00
Luck b70b6f8af1 Add support for regex permissions/servers/worlds and shorthand permissions 2016-08-09 11:09:45 +02:00
Luck 90e074d3ab Apply bukkit permissions directly, fix sponge listener, other misc changes/fixes 2016-08-07 17:10:37 +02:00
650 changed files with 68943 additions and 12860 deletions

No files matched your search

+151 -24
View File
@@ -1,31 +1,27 @@
# built application files
*.jar
# Created by https://www.gitignore.io/
# Java class files
*.class
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# Local configuration file (sdk path, etc)
logs/
# Eclipse project files
.classpath
.project
# Intellij project files
*.iml
*.ipr
*.iws
# User-specific stuff:
.idea/
*.iws
/out/
*.iml
.idea_modules/
# Gradle
.gradletasknamecache
.gradle/
build/
bin/
gradle/
gradlew*
# JIRA plugin
atlassian-ide-plugin.xml
# Maven
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
@@ -34,4 +30,135 @@ pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/timing.properties
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Windows ###
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+728
View File
@@ -0,0 +1,728 @@
# LuckPerms Language File
# Locale: en_US (English)
# Author: Luck
prefix: "&7&l[&b&lL&3&lP&7&l] &c"
empty: "{0}"
player-online: "&aOnline"
player-offline: "&cOffline"
loading-error: "&cPermissions data could not be loaded. Please try again later."
op-disabled: "&bThe vanilla OP system is disabled on this server."
op-disabled-sponge: "&2Please note that Server Operator status has no effect on Sponge permission checks when a permission plugin is installed. Please edit user data directly."
log-info: "&7&l[&bL&3P&7&l] &3{0}"
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[WARN] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[ERROR] {0}"
log: "&3LOG &3&l> {0}"
verbose-log: "&3VB &3&l> {0}"
export-log: "&3EXPORT &3&l> &f{0}"
export-log-progress: "&3EXPORT &3&l> &7{0}"
migration-log: "&3MIGRATION &7[&3{0}&7] &3&l> &f{1}"
migration-log-progress: "&3MIGRATION &7[&3{0}&7] &3&l> &7{1}"
command-not-recognised: "&cCommand not recognised."
command-no-permission: "&cYou do not have permission to use this command!"
user-not-found: "&cA user for &4{0}&c could not be found."
user-not-online: "&aUser &b{0}&a is not online."
user-save-error: "&cThere was an error whilst saving user data for &4{0}&c."
group-not-found: "&cA group named &4{0}&c could not be found."
group-save-error: "&cThere was an error whilst saving group data for &4{0}&c."
track-not-found: "&cA track named &4{0}&c could not be found."
track-save-error: "&cThere was an error whilst saving track data for &4{0}&c."
user-invalid-entry: "&4{0}&c is not a valid username/uuid."
group-invalid-entry: "&4{0}&c is not a valid group name."
track-invalid-entry: "&4{0}&c is not a valid track name."
server-world-invalid-entry: "&cServer/world names can only contain alphanumeric characters and cannot exceed 36 characters in length."
use-inherit-command: "&cUse the 'parent add' and 'parent remove' commands instead of specifying the node."
verbose-invalid-filter: "&4{0}&c is not a valid verbose filter."
verbose-on: "&bVerbose logging &aenabled &bfor checks matching &aANY&b."
verbose-on-query: "&bVerbose logging &aenabled &bfor checks matching &a{0}&b."
verbose-off: "&bVerbose logging &cdisabled&b."
verbose-recording-on: "&bVerbose recording &aenabled &bfor checks matching &aANY&b."
verbose-recording-on-query: "&bVerbose recording &aenabled &bfor checks matching &a{0}&b."
verbose-upload-start: "&bVerbose logging &cdisabled&b. Uploading results..."
verbose-results-url: "&aVerbose results URL:"
tree-upload-start: "&bGenerating permission tree..."
tree-empty: "&cUnable to generate tree. No results were found."
tree-url: "&aPermission tree URL:"
search-searching: "&aSearching for users and groups with &b{0}&a..."
search-searching-members: "&aSearching for users and groups who inherit from &b{0}&a..."
search-result: "&aFound &b{0}&a entries from &b{1}&a users and &b{2}&a groups."
search-showing-users: "&bShowing user entries:"
search-showing-groups: "&bShowing group entries:"
search-showing-users-with-page: "&bShowing user entries: {0}"
search-showing-groups-with-page: "&bShowing group entries: {0}"
apply-edits-invalid-code: "&cInvalid code. &7({0})"
apply-edits-unable-to-read: "&cUnable to read data using the given code. &7({0})"
apply-edits-no-target: "&cUnable to parse the target of the edit. Please supply it as an extra argument."
apply-edits-target-group-not-exists: "&cTarget group &4{0}&c does not exist."
apply-edits-target-user-not-uuid: "&cTarget user &4{0}&c is not a valid uuid."
apply-edits-target-user-unable-to-load: "&cUnable to load target user &4{0}&c."
apply-edits-target-unknown: "&cInvalid target. &7({0})"
apply-edits-success: "&aSuccessfully applied &b{0}&a nodes to &b{1}&a."
editor-upload-failure: "&cUnable to upload permission data to the editor."
editor-url: "&aEditor URL:"
check-result: "&aPermission check result on user &b{0}&a for permission &b{1}&a: &f{2}"
create-success: "&b{0}&a was successfully created."
delete-success: "&b{0}&a was successfully deleted."
rename-success: "&b{0}&a was successfully renamed to &b{1}&a."
clone-success: "&b{0}&a was successfully cloned onto &b{1}&a."
already-inherits: "&b{0}&a already inherits from &b{1}&a in context {2}&a."
does-not-inherit: "&b{0}&a does not inherit from &b{1}&a in context {2}&a."
already-temp-inherits: "&b{0}&a already temporarily inherits from &b{1}&a in context {2}&a."
does-not-temp-inherit: "&b{0}&a does not temporarily inherit from &b{1}&a in context {2}&a."
track-already-contains: "&b{0}&a already contains &b{1}&a."
track-does-not-contain: "&b{0}&a doesn't contain &b{1}&a."
track-ambiguous-call: "&4{0}&c is a member of multiple groups on this track. Unable to determine their location."
already-exists: "&4{0}&c already exists!"
does-not-exist: "&4{0}&c does not exist!"
group-load-error: "&cAn unexpected error occurred. Group not loaded."
groups-load-error: "&cAn unexpected error occurred. Unable to load all groups."
track-load-error: "&cAn unexpected error occurred. Track not loaded."
tracks-load-error: "&cAn unexpected error occurred. Unable to load all tracks."
track-empty: "&4{0}&c cannot be used as it is empty or contains only one group."
update-task-request: "&bAn update task has been requested. Please wait..."
update-task-complete: "&aUpdate task complete."
update-task-complete-network: "&aUpdate task complete. Now attempting to push to other servers."
update-task-push-success: "&aOther servers were notified via &b{0} Messaging &asuccessfully."
update-task-push-failure: "&cError whilst pushing changes to other servers."
update-task-push-failure-not-setup: "&cError whilst pushing changes to other servers. &7(a messaging service has not been configured)"
reload-config-success: "&aThe configuration file was reloaded. &7(some options will only apply after the server has restarted)"
info-top: >
{PREFIX}&2Running &bLuckPerms v{0}&2 by &bLuck&2.\n
{PREFIX}&f- &3Platform: &f{1}\n
{PREFIX}&f- &3Server Brand: &f{2}\n
{PREFIX}&f- &3Server Version: &f{3}
info-middle: >
{PREFIX}&f- &bMessaging Type: &f{0}\n
{PREFIX}&f- &bInstance:\n
{PREFIX}&f- &3Server Name: &f{1}\n
{PREFIX}&f- &3Online Players: &a{2}\n
{PREFIX}&f- &3Unique Connections: &a{3}\n
{PREFIX}&f- &3Uptime: &7{4}\n
{PREFIX}&f- &3Local Data: &a{5} &7users, &a{6} &7groups, &a{7} &7tracks\n
{PREFIX}&f- &3Context Calculators: &a{8}\n
{PREFIX}&f- &3Known permissions: &a{9}\n
{PREFIX}&f- &3Active processors: &7{10}
create-error: "&cThere was an error whilst creating &4{0}&c."
delete-error: "&cThere was an error whilst deleting &4{0}&c."
delete-group-error-default: "&cYou cannot delete the default group."
groups-list: "&aGroups: &7(name, weight, tracks)"
groups-list-entry: "&f- &3{0} &7- &b{1}"
groups-list-entry-with-tracks: "&f- &3{0} &7- &b{1} &7- [&3{2}&7]"
tracks-list: "&aTracks: {0}"
listnodes: "&b{0}'s Permissions:"
listnodes-with-page: "&b{0}'s Permissions: {1}"
listnodes-temp: "&b{0}'s Temporary Permissions:"
listnodes-temp-with-page: "&b{0}'s Temporary Permissions: {1}"
listparents: "&b{0}'s Parent Groups:"
listparents-temp: "&b{0}'s Temporary Parent Groups:"
list-tracks: >
&b{0}'s Tracks:\n
{1}
list-tracks-empty: "&b{0}&a is not on any tracks."
context-pair-inline: "&3{0}=&b{1}"
context-pair--global-inline: "&eglobal"
context-pair-sep: "&a, "
context-pair: "&8(&7{0}=&f{1}&8)"
check-permission: "&b{0}&a has permission &b{1}&a set to {2}&a in context {3}&a."
check-inherits-permission: "&b{0}&a has permission &b{1}&a set to {2}&a in context {3}&a. &7(inherited from &a{4}&7)"
setpermission-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a in context {3}&a."
already-haspermission: "&b{0}&a already has &b{1}&a set in context {2}&a."
setpermission-temp-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a for a duration of &b{3}&a in context {4}&a."
already-has-temp-permission: "&b{0}&a already has &b{1}&a set temporarily in context {2}&a."
unsetpermission-success: "&aUnset &b{0}&a for &b{1}&a in context {2}&a."
does-not-have-permission: "&b{0}&a does not have &b{1}&a set in context {2}&a."
unset-temp-permission-success: "&aUnset temporary permission &b{0}&a for &b{1}&a in context {2}&a."
does-not-have-temp-permission: "&b{0}&a does not have &b{1}&a set temporarily in context {2}&a."
set-inherit-success: "&b{0}&a now inherits permissions from &b{1}&a in context {2}&a."
set-temp-inherit-success: "&b{0}&a now inherits permissions from &b{1}&a for a duration of &b{2}&a in context {3}&a."
set-parent-success: "&b{0}&a had their existing parent groups cleared, and now only inherits &b{1}&a in context {2}&a."
set-track-parent-success: "&b{0}&a had their existing parent groups on track &b{1}&a cleared, and now only inherits &b{2}&a in context {3}&a."
unset-inherit-success: "&b{0}&a no longer inherits permissions from &b{1}&a in context {2}&a."
unset-temp-inherit-success: "&b{0}&a no longer temporarily inherits permissions from &b{1}&a in context {2}&a."
clear-success: "&b{0}&a's permissions were cleared in context {1}&a. (&b{2}&a nodes were removed.)"
clear-success-singular: "&b{0}&a's permissions were cleared in context {1}&a. (&b{2}&a node was removed.)"
parent-clear-success: "&b{0}&a's parents were cleared in context {1}&a. (&b{2}&a nodes were removed.)"
parent-clear-success-singular: "&b{0}&a's parents were cleared in context {1}&a. (&b{2}&a node was removed.)"
parent-clear-track-success: "&b{0}&a's parents on track &b{1}&a were cleared in context {2}&a. (&b{3}&a nodes were removed.)"
parent-clear-track-success-singular: "&b{0}&a's parents on track &b{1}&a were cleared in context {2}&a. (&b{3}&a node was removed.)"
meta-clear-success: "&b{0}&a's meta matching type &b{1}&a was cleared in context {2}&a. (&b{3}&a nodes were removed.)"
meta-clear-success-singular: "&b{0}&a's meta matching type &b{1}&a was cleared in context {2}&a. (&b{3}&a node was removed.)"
illegal-date-error: "&cCould not parse date &4{0}&c."
past-date-error: "&cYou cannot set a date in the past!"
chat-meta-prefix-header: "&b{0}'s Prefixes"
chat-meta-suffix-header: "&b{0}'s Suffixes"
meta-header: "&b{0}'s Meta"
chat-meta-entry: "&b-> {0} &f- &f'{1}&f' &8(&7inherited from &a{2}&8)"
chat-meta-entry-with-context: "&b-> {0} &f- &f'{1}&f' &8(&7inherited from &a{2}&8){3}"
meta-entry: "&b-> &a{0} &f= &f'{1}&f' &8(&7inherited from &a{2}&8)"
meta-entry-with-context: "&b-> &a{0} &f= &f'{1}&f' &8(&7inherited from &a{2}&8){3}"
chat-meta-prefix-none: "&b{0} has no prefixes."
chat-meta-suffix-none: "&b{0} has no suffixes."
meta-none: "&b{0} has no meta."
meta-invalid-priority: "&cInvalid priority &4{0}&c. Expected a number."
already-has-chat-meta: "&b{0}&a already has {1} &f'{2}&f'&a set at a priority of &b{3}&a in context {4}&a."
already-has-temp-chat-meta: "&b{0}&a already has {1} &f'{2}&f'&a set temporarily at a priority of &b{3}&a in context {4}&a."
does-not-have-chat-meta: "&b{0}&a doesn't have {1} &f'{2}&f'&a set at a priority of &b{3}&a in context {4}&a."
does-not-have-temp-chat-meta: "&b{0}&a doesn't have {1} &f'{2}&f'&a set temporarily at a priority of &b{3}&a in context {4}&a."
add-chatmeta-success: "&b{0}&a had {1} &f'{2}&f'&a set at a priority of &b{3}&a in context {4}&a."
add-temp-chatmeta-success: "&b{0}&a had {1} &f'{2}&f'&a set at a priority of &b{3}&a for a duration of &b{4}&a in context {5}&a."
remove-chatmeta-success: "&b{0}&a had {1} &f'{2}&f'&a at priority &b{3}&a removed in context {4}&a."
bulk-remove-chatmeta-success: "&b{0}&a had all {1}es at priority &b{2}&a removed in context {3}&a."
remove-temp-chatmeta-success: "&b{0}&a had temporary {1} &f'{2}&f'&a at priority &b{3}&a removed in context {4}&a."
bulk-remove-temp-chatmeta-success: "&b{0}&a had all temporary {1}es at priority &b{2}&a removed in context {3}&a."
already-has-meta: "&b{0}&a already has meta key &f'{1}&f'&a set to &f'{2}&f'&a in context {3}&a."
already-has-temp-meta: "&b{0}&a already has meta key &f'{1}&f'&a temporarily set to &f'{2}&f'&a in context {3}&a."
doesnt-have-meta: "&b{0}&a doesn't have meta key &f'{1}&f'&a set in context {2}&a."
doesnt-have-temp-meta: "&b{0}&a doesn't have meta key &f'{1}&f'&a set temporarily in context {2}&a."
set-meta-success: "&aSet meta key &f'{0}&f'&a to &f'{1}&f'&a for &b{2}&a in context {3}&a."
set-meta-temp-success: "&aSet meta key &f'{0}&f'&a to &f'{1}&f'&a for &b{2}&a for a duration of &b{3}&a in context {4}&a."
unset-meta-success: "&aUnset meta key &f'{0}&f'&a for &b{1}&a in context {2}&a."
unset-meta-temp-success: "&aUnset temporary meta key &f'{0}&f'&a for &b{1}&a in context {2}&a."
bulk-update-invalid-data-type: "&cInvalid type. Was expecting 'all', 'users' or 'groups'."
bulk-update-invalid-constraint: "&cInvalid constraint &4{0}&c. Constraints should be in the format '&f<field> <comparison operator> <value>&c'."
bulk-update-invalid-comparison: "&cInvalid comparison operator '&4{0}&c'. Expected one of the following: &f== != ~~ ~!"
bulk-update-queued: "&aBulk update operation was queued. &7(&f{0}&7)"
bulk-update-confirm: "&aRun &b/{0} bulkupdate confirm {1} &ato execute the update."
bulk-update-unknown-id: "&aOperation with id &b{0}&a does not exist or has expired."
bulk-update-starting: "&aRunning bulk update."
bulk-update-success: "&bBulk update completed successfully."
bulk-update-failure: "&cBulk update failed. Check the console for errors."
user-info-general: >
{PREFIX}&b&l> &bUser Info: &f{0}\n
{PREFIX}&f- &3UUID: &f{1}\n
{PREFIX}&f- &3Status: {2}\n
{PREFIX}&f- &3Primary Group: &f{3}\n
{PREFIX}&f- &aCounts:\n
{PREFIX}&f- &3Nodes: &a{4}\n
{PREFIX}&f- &3Permissions: &a{5}\n
{PREFIX}&f- &3Prefixes: &a{6}\n
{PREFIX}&f- &3Suffixes: &a{7}\n
{PREFIX}&f- &3Meta: &a{8}
user-info-data: >
{PREFIX}&f- &aCached Data:\n
{PREFIX}&f- &3Has contextual data: {0}\n
{PREFIX}&f- &3Current Contexts: {1}\n
{PREFIX}&f- &3Current Prefix: {2}\n
{PREFIX}&f- &3Current Suffix: {3}
info-parent-header: "&f- &aParent Groups:"
info-temp-parent-header: "&f- &aTemporary Parent Groups:"
user-removegroup-error-primary: "&aYou cannot remove a user from their primary group."
user-primarygroup-success: "&b{0}&a's primary group was set to &b{1}&a."
user-primarygroup-warn-option: "&aWarning: The primary group calculation method being used by this server &7({0}) &amay not reflect this change."
user-primarygroup-error-alreadyhas: "&b{0}&a already has &b{1}&a set as their primary group."
user-primarygroup-error-notmember: "&b{0}&a was not already a member of &b{1}&a, adding them now."
user-track-error-not-contain-group: "&b{0}&a isn't already in any groups on &b{1}&a."
user-track-added-to-first: "&b{0}&a isn't in any groups on this track, so they were added to the first group, &b{1}&a in context {2}&a."
user-promote-success: "&aPromoting &b{0}&a along track &b{1}&a from &b{2}&a to &b{3}&a in context {4}&a."
user-promote-error-endoftrack: "&aThe end of track &b{0}&a was reached. Unable to promote &b{1}&a."
user-promote-error-malformed: >
{PREFIX}&aThe next group on the track, &b{0}&a, no longer exists. Unable to promote user.\n
{PREFIX}&aEither create the group, or remove it from the track and try again.
user-demote-success: "&aDemoting &b{0}&a along track &b{1}&a from &b{2}&a to &b{3}&a in context {4}&a."
user-demote-endoftrack: "&aThe end of track &b{0}&a was reached, so &b{1}&a was removed from &b{2}&a."
user-demote-error-malformed: >
{PREFIX}&aThe previous group on the track, &b{0}&a, no longer exists. Unable to demote user.\n
{PREFIX}&aEither create the group, or remove it from the track and try again.
group-info-general: >
{PREFIX}&b&l> &bGroup Info: &f{0}\n
{PREFIX}&f- &3Display Name: &f{1}\n
{PREFIX}&f- &3Weight: &f{2}\n
{PREFIX}&f- &aCounts:\n
{PREFIX}&f- &3Nodes: &a{3}\n
{PREFIX}&f- &3Permissions: &a{4}\n
{PREFIX}&f- &3Prefixes: &a{5}\n
{PREFIX}&f- &3Suffixes: &a{6}\n
{PREFIX}&f- &3Meta: &a{7}
group-set-weight: "&aSet weight to &b{0}&a for group &b{1}&a."
track-info: >
{PREFIX}&b&l> &bShowing Track: &f{0}\n
{PREFIX}&f- &7Path: &f{1}
track-clear: "&b{0}&a's groups track was cleared."
track-append-success: "&aGroup &b{0}&a was appended to track &b{1}&a."
track-insert-success: "&aGroup &b{0}&a was inserted into track &b{1}&a at position &b{2}&a."
track-insert-error-number: "&cExpected number but instead received: {0}"
track-insert-error-invalid-pos: "&cUnable to insert at position &4{0}&c. &7(invalid position)"
track-remove-success: "&aGroup &b{0}&a was removed from track &b{1}&a."
log-load-error: "&cThe log could not be loaded."
log-invalid-page: "&cInvalid page number."
log-invalid-page-range: "&cInvalid page number. Please enter a value between &41&c and &4{0}&c."
log-no-entries: "&bNo log entries to show."
log-entry: "&b#{0} -> &8(&7{1} ago&8) {2}"
log-notify-console: "&cCannot toggle notifications for console."
log-notify-toggle-on: "&aEnabled&b logging output."
log-notify-toggle-off: "&cDisabled&b logging output."
log-notify-already-on: "&cYou are already receiving notifications."
log-notify-already-off: "&cYou aren't currently receiving notifications."
log-notify-unknown: "&cState unknown. Expecting \"on\" or \"off\"."
log-search-header: "&aShowing recent actions for query &b{0} &a(page &f{1}&a of &f{2}&a)"
log-recent-header: "&aShowing recent actions (page &f{0}&a of &f{1}&a)"
log-recent-by-header: "&aShowing recent actions by &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-user-header: "&aShowing history for user &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-group-header: "&aShowing history for group &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-track-header: "&aShowing history for track &b{0} &a(page &f{1}&a of &f{2}&a)"
log-export-already-exists: "&cError: File &4{0}&c already exists."
log-export-not-writable: "&cError: File &4{0}&c is not writable."
log-export-empty: "&cThe log is empty and therefore cannot be exported."
log-export-failure: "&cAn unexpected error occured whilst writing to the file."
log-export-success: "&aSuccessfully exported the log to &b{0}&a."
import-already-running: "&cAnother import process is already running. Please wait for it to finish and try again."
export-already-running: "&cAnother export process is already running. Please wait for it to finish and try again."
import-log-doesnt-exist: "&cError: File &4{0}&c does not exist."
import-log-not-readable: "&cError: File &4{0}&c is not readable."
import-log-failure: "&cAn unexpected error occured whilst reading from the log file."
import-progress: "&b(Import) &b-> &f{0}&f% complete &7- &b{1}&f/&b{2} &foperations complete with &c{3} &ferrors."
import-progress-sin: "&b(Import) &b-> &f{0}&f% complete &7- &b{1}&f/&b{2} &foperations complete with &c{3} &ferror."
import-start: "&b(Import) &b-> &fStarting import process."
import-end-complete: "&b(Import) &a&lCOMPLETED &7- took &b{0} &7seconds - &7No errors."
import-end-complete-err: "&b(Import) &a&lCOMPLETED &7- took &b{0} &7seconds - &c{1} errors."
import-end-complete-err-sin: "&b(Import) &a&lCOMPLETED &7- took &b{0} &7seconds - &c{1} error."
import-end-error-header: >
{PREFIX}&b(Import) &7------------> &fShowing Error #&b{0} &7<------------\n
{PREFIX}&b(Import) &fWhilst executing: &3Command #{1}\n
{PREFIX}&b(Import) &fCommand: &7{2}\n
{PREFIX}&b(Import) &fType: &3{3}\n
{PREFIX}&b(Import) &fOutput:
import-end-error-content: "&b(Import) &b-> &c{0}"
import-end-error-footer: "&b(Import) &7<------------------------------------------>"
command-specs:
user:
description: "User commands"
usage: "/%s user <user>"
group:
description: "Group commands"
usage: "/%s group <group>"
track:
description: "Track commands"
usage: "/%s track <track>"
log:
description: "Log commands"
usage: "/%s log"
sync:
description: "Sync changes with the storage"
usage: "/%s sync"
info:
description: "Print general plugin info"
usage: "/%s info"
verbose:
description: "Manage verbose permission checking"
usage: "/%s verbose <true|false> [filter]"
args:
"on|record|off|paste": "whether to enable/disable logging, or to paste the logged output"
"filter": "the filter to match entries against"
"--slim": "add \"--slim\" to exclude trace data from the pasted output"
tree:
description: "Generate a tree view of permissions"
usage: "/%s tree [selection] [max level] [player]"
args:
"selection": "the root of the tree. specify \".\" to include all permissions"
"max level": "how many branch levels should be returned"
"player": "the name of an online player to check against"
search:
description: "Search for users/groups with a specific permission"
usage: "/%s search <permission>"
args:
"permission": "the permission to search for"
"page": "the page to view"
check:
description: "Perform a standard permission check on an online player"
usage: "/%s check <user> <permission>"
args:
"user": "the user to check"
"permission": "the permission to check for"
network-sync:
description: "Sync changes with the storage and request that all other servers on the network do the same"
usage: "/%s networksync"
import:
description: "Import data from a file"
usage: "/%s import <file>"
args:
"file": "the file to import from"
export:
description: "Export data to a file"
usage: "/%s export <file>"
args:
"file": "the file to export to"
reload-config:
description: "Reload some of the config options"
usage: "/%s reloadconfig"
bulk-update:
description: "Execute bulk change queries on all data"
usage: "/%s bulkupdate"
args:
"data type": "the type of data being changed. ('all', 'users' or 'groups')"
"action": "the action to perform on the data. ('update' or 'delete')"
"action field": "the field to act upon. only required for 'update'. ('permission', 'server' or 'world')"
"action value": "the value to replace with. only required for 'update'."
"constraint...": "the constraints required for the update"
migration:
description: "Migration commands"
usage: "/%s migration"
apply-edits:
description: "Applies permission changes made from the web editor"
usage: "/%s applyedits <code> [target]"
args:
"code": "the unique code for the data"
"target": "who to apply the data to"
create-group:
description: "Create a new group"
usage: "/%s creategroup <group>"
args:
"name": "the name of the group"
delete-group:
description: "Delete a group"
usage: "/%s deletegroup <group>"
args:
"name": "the name of the group"
list-groups:
description: "List all groups on the platform"
usage: "/%s listgroups"
create-track:
description: "Create a new track"
usage: "/%s createtrack <track>"
args:
"name": "the name of the track"
delete-track:
description: "Delete a track"
usage: "/%s deletetrack <track>"
args:
"name": "the name of the track"
list-tracks:
description: "List all tracks on the platform"
usage: "/%s listtracks"
user-info:
description: "Shows info about the user"
user-switchprimarygroup:
description: "Switches the user's primary group"
args:
"group": "the group to switch to"
user-promote:
description: "Promotes the user up a track"
args:
"track": "the track to promote the user up"
"context...": "the contexts to promote the user in"
user-demote:
description: "Demotes the user down a track"
args:
"track": "the track to demote the user down"
"context...": "the contexts to demote the user in"
group-info:
description: "Gives info about the group"
group-listmembers:
description: "Show the users/groups who inherit from this group"
args:
"page": "the page to view"
group-setweight:
description: "Set the groups weight"
args:
"weight": "the weight to set"
group-rename:
description: "Rename the group"
args:
"name": "the new name"
group-clone:
description: "Clone the group"
args:
"name": "the name of the group to clone onto"
holder-editor:
description: "Opens the web permission editor"
holder-showtracks:
description: "Lists the tracks that the object is on"
holder-clear:
description: "Removes all permissions, parents and meta"
args:
"context...": "the contexts to filter by"
permission:
description: "Edit permissions"
parent:
description: "Edit inheritances"
meta:
description: "Edit metadata values"
permission-info:
description: "Lists the permission nodes the object has"
args:
"page": "the page to view"
"filter": "the string to filter by"
permission-set:
description: "Sets a permission for the object"
args:
"node": "the permission node to set"
"true|false": "the value of the node"
"context...": "the contexts to add the permission in"
permission-unset:
description: "Unsets a permission for the object"
args:
"node": "the permission node to unset"
"context...": "the contexts to remove the permission in"
permission-settemp:
description: "Sets a permission for the object temporarily"
args:
"node": "the permission node to set"
"true|false": "the value of the node"
"duration": "the duration until the permission node expires"
"context...": "the contexts to add the permission in"
permission-unsettemp:
description: "Unsets a temporary permission for the object"
args:
"node": "the permission node to unset"
"context...": "the contexts to remove the permission in"
permission-check:
description: "Checks to see if the object has a certain permission node"
args:
"node": "the permission node to check for"
"context...": "the contexts to check in"
permission-check-inherits:
description: "Checks to see if the object inherits a certain permission node"
args:
"node": "the permission node to check for"
"context...": "the contexts to check in"
parent-info:
description: "Lists the groups that this object inherits from"
parent-set:
description: "Removes all other groups the object inherits already and adds them to the one given"
args:
"group": "the group to set to"
"context...": "the contexts to set the group in"
parent-add:
description: "Sets another group for the object to inherit permissions from"
args:
"group": "the group to inherit from"
"context...": "the contexts to inherit the group in"
parent-remove:
description: "Removes a previously set inheritance rule"
args:
"group": "the group to remove"
"context...": "the contexts to remove the group in"
parent-set-track:
description: "Removes all other groups the object inherits from already on the given track and adds them to the one given"
args:
"track": "the track to set on"
"group": "the group to set to, or a number relating to the position of the group on the given track"
"context...": "the contexts to set the group in"
parent-add-temp:
description: "Sets another group for the object to inherit permissions from temporarily"
args:
"group": "the group to inherit from"
"duration": "the duration of the group membership"
"context...": "the contexts to inherit the group in"
parent-remove-temp:
description: "Removes a previously set temporary inheritance rule"
args:
"group": "the group to remove"
"context...": "the contexts to remove the group in"
parent-clear:
description: "Clears all parents"
args:
"context...": "the contexts to filter by"
parent-clear-track:
description: "Clears all parents on a given track"
args:
"track": "the track to remove on"
"context...": "the contexts to filter by"
meta-info:
description: "Shows all chat meta"
meta-set:
description: "Sets a meta value"
args:
"key": "the key to set"
"value": "the value to set"
"context...": "the contexts to add the meta pair in"
meta-unset:
description: "Unsets a meta value"
args:
"key": "the key to unset"
"context...": "the contexts to remove the meta pair in"
meta-settemp:
description: "Sets a meta value temporarily"
args:
"key": "the key to set"
"value": "the value to set"
"duration": "the duration until the meta value expires"
"context...": "the contexts to add the meta pair in"
meta-unsettemp:
description: "Unsets a temporary meta value"
args:
"key": "the key to unset"
"context...": "the contexts to remove the meta pair in"
meta-addprefix:
description: "Adds a prefix"
args:
"priority": "the priority to add the prefix at"
"prefix": "the prefix string"
"context...": "the contexts to add the prefix in"
meta-addsuffix:
description: "Adds a suffix"
args:
"priority": "the priority to add the suffix at"
"suffix": "the suffix string"
"context...": "the contexts to add the suffix in"
meta-removeprefix:
description: "Removes a prefix"
args:
"priority": "the priority to remove the prefix at"
"prefix": "the prefix string"
"context...": "the contexts to remove the prefix in"
meta-removesuffix:
description: "Removes a suffix"
args:
"priority": "the priority to remove the suffix at"
"suffix": "the suffix string"
"context...": "the contexts to remove the suffix in"
meta-addtemp-prefix:
description: "Adds a prefix temporarily"
args:
"priority": "the priority to add the prefix at"
"prefix": "the prefix string"
"duration": "the duration until the prefix expires"
"context...": "the contexts to add the prefix in"
meta-addtemp-suffix:
description: "Adds a suffix temporarily"
args:
"priority": "the priority to add the suffix at"
"suffix": "the suffix string"
"duration": "the duration until the suffix expires"
"context...": "the contexts to add the suffix in"
meta-removetemp-prefix:
description: "Removes a temporary prefix"
args:
"priority": "the priority to remove the prefix at"
"prefix": "the prefix string"
"context...": "the contexts to remove the prefix in"
meta-removetemp-suffix:
description: "Removes a temporary suffix"
args:
"priority": "the priority to remove the suffix at"
"suffix": "the suffix string"
"context...": "the contexts to remove the suffix in"
meta-clear:
description: "Clears all meta"
args:
"type": "the type of meta to remove"
"context...": "the contexts to filter by"
track-info:
description: "Gives info about the track"
track-append:
description: "Appends a group onto the end of the track"
args:
"group": "the group to append"
track-insert:
description: "Inserts a group at a given position along the track"
args:
"group": "the group to insert"
"position": "the position to insert the group at (the first position on the track is 1)"
track-remove:
description: "Removes a group from the track"
args:
"group": "the group to remove"
track-clear:
description: "Clears the groups on the track"
track-rename:
description: "Rename the track"
args:
"name": "the new name"
track-clone:
description: "Clone the track"
args:
"name": "the name of the track to clone onto"
log-recent:
description: "View recent actions"
args:
"user": "the name/uuid of the user to filter by"
"page": "the page number to view"
log-search:
description: "Search the log for an entry"
args:
"query": "the query to search by"
"page": "the page number to view"
log-notify:
description: "Toggle log notifications"
args:
"on|off": "whether to toggle on or off"
log-user-history:
description: "View a user's history"
args:
"user": "the name/uuid of the user"
"page": "the page number to view"
log-group-history:
description: "View an group's history"
args:
"group": "the name of the group"
"page": "the page number to view"
log-track-history:
description: "View a track's history"
args:
"track": "the name of the track"
"page": "the page number to view"
sponge:
description: "Edit extra Sponge data"
usage: "/%s sponge <collection> <subject>"
args:
"collection": "the collection to query"
"subject": "the subject to modify"
sponge-permission-info:
description: "Shows info about the subject's permissions"
args:
"contexts...": "the contexts to filter by"
sponge-permission-set:
description: "Sets a permission for the Subject"
args:
"node": "the permission node to set"
"tristate": "the value to set the permission to"
"contexts...": "the contexts to set the permission in"
sponge-permission-clear:
description: "Clears the Subjects permissions"
args:
"contexts...": "the contexts to clear permissions in"
sponge-parent-info:
description: "Shows info about the subject's parents"
args:
"contexts...": "the contexts to filter by"
sponge-parent-add:
description: "Adds a parent to the Subject"
args:
"collection": "the subject collection where the parent Subject is"
"subject": "the name of the parent Subject"
"contexts...": "the contexts to add the parent in"
sponge-parent-remove:
description: "Removes a parent from the Subject"
args:
"collection": "the subject collection where the parent Subject is"
"subject": "the name of the parent Subject"
"contexts...": "the contexts to remove the parent in"
sponge-parent-clear:
description: "Clears the Subjects parents"
args:
"contexts...": "the contexts to clear parents in"
sponge-option-info:
description: "Shows info about the subject's options"
args:
"contexts...": "the contexts to filter by"
sponge-option-set:
description: "Sets an option for the Subject"
args:
"key": "the key to set"
"value": "the value to set the key to"
"contexts...": "the contexts to set the option in"
sponge-option-unset:
description: "Unsets an option for the Subject"
args:
"key": "the key to unset"
"contexts...": "the contexts to unset the key in"
sponge-option-clear:
description: "Clears the Subjects options"
args:
"contexts...": "the contexts to clear options in"
migration-command:
description: "Migration command"
migration-groupmanager:
description: "Migration command"
args:
"migrate as global": "if world permissions should be ignored, and just migrated as global"
migration-powerfulperms:
description: "Migration command"
args:
"address": "the address of the PP database"
"database": "the name of the PP database"
"username": "the username to log into the DB"
"password": "the password to log into the DB"
"db table": "the name of the PP table where player data is stored"
+338
View File
@@ -0,0 +1,338 @@
# LuckPerms Language File
# Locale: es_ES (Spanish)
# Author: Jose Chavez (Twitter: @JoCHav3z)
prefix: "&7&l[&b&lL&3&lP&7&l] &c"
log-info: "&7&l[&bL&3P&7&l] &3{0}"
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[ADVERTENCIA] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[ERROR] {0}"
empty: "{0}"
player-online: "&aConectado"
player-offline: "&cDesconectado"
loading-error: "La Informacion de los permisos no pudo ser cargada. Por favor contacte al administrador."
op-disabled: "&bEl sistema OP de Vanilla esta deshabilitado en este servidor."
op-disabled-sponge: "&2El estado de operador del servidor no tiene efecto cuando un plugin de permisos esta instalado. Por favor edite la informacion de usuario directamente."
log: "&3LOG &3&l> {0}"
export-log: "&3EXPORTAR &3&l> &f{0}"
export-log-progress: "&3EXPORTADO &3&l> &7{0}"
migration-log: "&3MIGRACION &7[&3{0}&7] &3&l> &f{1}"
migration-log-progress: "&3MIGRADO &7[&3{0}&7] &3&l> &7{1}"
command-not-recognised: "Comando no reconocido."
command-no-permission: "¡No tienes permiso de usar este comando!"
already-haspermission: "{0} ¡Ya tienes este permiso!"
does-not-havepermission: "{0} No tienes este permiso establecido."
already-has-temp-permission: "{0} ¡Ya tienes este permiso establecido temporalmente!"
does-not-have-temp-permission: "{0} No tienes este permiso establecido temporalmente."
user-not-found: "&bNo se pudo encontrar al usuario."
user-not-online: "&bUsuario &a{0}&b no esta conectado."
user-no-data: "&bUsuario &a{0}&b no tiene ningún dato cargado."
user-save-success: "&7(Los datos del usuario se guardaron en el almacenamiento)"
user-save-error: "Se ha producido un error al guardar el usuario."
user-create-fail: "Se produjo un error al crear un nuevo usuario."
group-not-found: "&bEl Grupo no se pudo encontrar."
group-save-success: "&7(Los datos del grupo se guardaron en el almacenamiento)"
group-save-error: "Se ha producido un error al guardar el grupo."
track-not-found: "&bNo se pudo encontrar la pista."
track-save-success: "&7(Los datos de la pista se guardaron en el almacenamiento)"
track-save-error: "Se ha producido un error al guardar la pista."
user-invalid-entry: "&d{0}&c El username/uuid no es valido."
group-invalid-entry: "Los nombres de grupo sólo pueden contener caracteres alfanuméricos."
track-invalid-entry: "Los nombres de pista sólo pueden contener caracteres alfanuméricos."
server-invalid-entry: "Los nombres de servidor sólo pueden contener caracteres alfanuméricos."
use-inherit-command: "Usa el comando 'parent add' y 'parent remove' en vez de especificar el nodo."
verbose-invalid-filter: "&cFiltro Verbose invalido: &f{0}"
verbose-on: "&bEl chequeo Verbose de salida se ha establecido en &aTRUE &bpara todos los permisos."
verbose-on-query: "&bEl chequeo Verbose de salida que se establecio en &aTRUE &bpara los permisos se ha pareado con los siguientes filtros: &f{0}"
verbose-off: "&bEl chequeo Verbose de salida que se establecio en &cFALSE&b."
verbose-recording-on: "&bGrabacion de Verbose establecida en &aTRUE &bpara todos los permisos."
verbose-recording-on-query: "&bGrabacion de Verbose establecida en &aTRUE &bpara los permisos se ha pareado con los siguientes filtros: &f{0}"
verbose-recording-upload-start: "&bGrabacion de Verbose se ha deshabilitado. Cargando resultados..."
verbose-recording-url: "&aURL de resultados de Verbose:"
tree-upload-start: "&bGenerando arbol de permisos..."
tree-empty: "&aNo se puede generar el árbol. No se encontraron resultados."
tree-url: "&aURL de arbol de permisos:"
search-searching: "&aBúsqueda de usuarios y grupos con &b{0}&a..."
search-result: "&aEncontradas &b{0}&a entradas por parte de &b{1}&a usuarios y &b{2}&a grupos."
search-showing-users: "&bMostrando entradas del usuario:"
search-showing-groups: "&bMostrando entradas del grupo:"
search-showing-users-with-page: "&bMostrando entradas del usuario: {0}"
search-showing-groups-with-page: "&bMostrando entradas del grupo: {0}"
check-result: "&aResultado de la comprobación del permiso en el usuario &b{0}&a para permiso &b{1}&a: &f{2}"
create-success: "&b{0}&a se creó correctamente."
delete-success: "&b{0}&a fue eliminado correctamente."
rename-success: "&b{0}&a fue exitosamente renombrado a &b{1}&a."
clone-success: "&b{0}&a fue clonado con éxito en &b{1}&a."
already-inherits: "{0} ya hereda '{1}'."
does-not-inherit: "{0} no hereda '{1}'."
already-temp-inherits: "{0} ya lo heredo temporalmente a '{1}'."
does-not-temp-inherit: "{0} no lo heredo temporalmente a '{1}'."
track-already-contains: "La pista {0} ya contiene el grupo '{1}'."
track-does-not-contain: "La pista {0} no contiene el grupo '{1}'."
track-ambiguous-call: "El usuario especificado es miembro de varios grupos en esta pista. No se puede determinar su ubicación."
group-already-exists: "¡Ese grupo ya existe!"
group-does-not-exist: "¡Ese grupo no existe!"
group-load-error: "Ocurrió un error inesperado. No se pudo cargar el grupo."
groups-load-error: "Ocurrió un error inesperado. No se pueden cargar todos los grupos."
track-already-exists: "¡La pista ya existe!"
track-does-not-exist: "¡La pista no existe!"
track-load-error: "Ocurrió un error inesperado. No se pudo cargar la pista."
tracks-load-error: "Ocurrió un error inesperado. No se pueden cargar todas las pistas."
track-empty: "La pista no se puede utilizar porque está vacía o contiene sólo un grupo."
update-task-request: "&bActualizar tarea programada."
update-task-complete: "&aLa actualizacion de la tarea a finalizado."
update-task-complete-network: "&aLa actualizacion de la tarea a finalizado. Ahora intentando enviar a otros servidores."
update-task-push-success: "&aOtros servidores fueron notificados vía &b{0} Mensajería &aexitoxamente."
update-task-push-failure: "&cError al empujar cambios a otros servidores."
update-task-push-failure-not-setup: "&cError al presionar los cambios a otros servidores. No se ha configurado un servicio de mensajería."
reload-config-success: "&aSe ha vuelto a cargar el archivo de configuración. &7(Algunas opciones sólo se aplicarán después de que el servidor se haya reiniciado.)"
info: >
{PREFIX}&2Running &bLuckPerms v{0}&2 by &bLuck&2.\n
{PREFIX}&f- &3Platform: &f{1}\n
{PREFIX}&f- &3Storage Method: &f{2}\n
{PREFIX}&f- &3Server Name: &f{3}\n
{PREFIX}&f- &3Sync Interval: &a{4} &fminutes\n
{PREFIX}&f- &3Messaging Service: &f{5}\n
{PREFIX}&f- &bCounts:\n
{PREFIX}&f- &3Online Players: &a{6}\n
{PREFIX}&f- &3Loaded Users: &a{7}\n
{PREFIX}&f- &3Loaded Groups: &a{8}\n
{PREFIX}&f- &3Loaded Tracks: &a{9}\n
{PREFIX}&f- &3Log size: &a{10}\n
{PREFIX}&f- &3UUID Cache size: &a{11}\n
{PREFIX}&f- &3Translations loaded: &a{12}\n
{PREFIX}&f- &3Pre-process contexts: &a{13}\n
{PREFIX}&f- &3Context Calculators: &a{14}\n
{PREFIX}&f- &3Unique permissions: &a{15}\n
{PREFIX}&f- &bConfiguration:\n
{PREFIX}&f- &3Use Server UUIDs: {16}\n
{PREFIX}&f- &bPermission Calculation:\n
{PREFIX}&f- &3Including Global: {17}\n
{PREFIX}&f- &3Including Global World: {18}\n
{PREFIX}&f- &3Applying Global Groups: {19}\n
{PREFIX}&f- &3Applying Global World Groups: {20}\n
{PREFIX}&f- &3Applying Wildcards: {21}\n
{PREFIX}&f- &3Applying Regex: {22}\n
{PREFIX}&f- &3Applying Shorthand: {23}
create-group-error: "Se produjo un error al crear el grupo."
delete-group-error: "Se produjo un error al eliminar el grupo."
delete-group-error-default: "No puede eliminar el grupo predeterminado."
groups-list: "&aGrupos: {0}"
create-track-error: "Se produjo un error al crear la pista."
delete-track-error: "Se produjo un error al eliminar la pista."
tracks-list: "&aPistas: {0}"
listnodes: "&b{0}'s Nodos:"
listnodes-with-page: "&b{0}'s Nodos: {1}"
listnodes-temp: >
&b{0}'s Temporary Nodes:\n
{1}
listparents: >
&b{0}'s Parent Groups:\n
{1}
listparents-temp: >
&b{0}'s Temporary Parent Groups:\n
{1}
listgroups: >
&b{0}'s Groups:\n
{1}
listgroups-temp: >
&b{0}'s Temporary Groups:\n
{1}
list-tracks: >
&b{0}'s Tracks:\n
{1}
list-tracks-empty: "{0} no está en ninguna pista."
setpermission-success: "&aEstablecer &b{0}&a a &b{1}&a para &b{2}&a."
setpermission-server-success: "&aEstablecer &b{0}&a a &b{1}&a para &b{2}&a en el servidor &b{3}&a."
setpermission-server-world-success: "&aEstablecer &b{0}&a a &b{1}&a para &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a."
setpermission-temp-success: "&aEstablecer &b{0}&a a &b{1}&a para &b{2}&a por una duracion de &b{3}&a."
setpermission-temp-server-success: "&aEstablecer &b{0}&a a &b{1}&a para &b{2}&a en el servidor &b{3}&a por una duracion de &b{4}&a."
setpermission-temp-server-world-success: "&aEstablecer &b{0}&a a &b{1}&a para &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a, por una duracion de &b{5}&a."
unsetpermission-success: "&aDesestablecer &b{0}&a para &b{1}&a."
unsetpermission-server-success: "&aDesestablecer &b{0}&a para &b{1}&a en el servidor &b{2}&a."
unsetpermission-server-world-success: "&aDesestablecer &b{0}&a para &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
unset-temp-permission-success: "&aDesestablecer temporalmente el permiso &b{0}&a para &b{1}&a."
unset-temp-permission-server-success: "&aDesestablecer temporalmente el permiso &b{0}&a para &b{1}&a en el servidor &b{2}&a."
unset-temp-permission-server-world-success: "&aDesestablecer temporalmente el permiso &b{0}&a para &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
set-inherit-success: "&b{0}&a ahora hereda los permisos de &b{1}&a."
set-inherit-server-success: "&b{0}&a ahora hereda los permisos de &b{1}&a en el servidor &b{2}&a."
set-inherit-server-world-success: "&b{0}&a ahora hereda los permisos de &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
set-parent-success: "&b{0}&a sus grupos parentales existentes han sido borrados, y ahora solo heredan &b{1}&a."
set-parent-server-success: "&b{0}&a sus grupos parentales existentes han sido borrados, y ahora solo heredan &b{1}&a en el servidor &b{2}&a."
set-parent-server-world-success: "&b{0}&a sus grupos parentales existentes han sido borrados, y ahora solo heredan &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
set-temp-inherit-success: "&b{0}&a ahora heredan permisos de &b{1}&a por una duracion de &b{2}&a."
set-temp-inherit-server-success: "&b{0}&a ahora heredan permisos de &b{1}&a en el servidor &b{2}&a por una duracion de &b{3}&a."
set-temp-inherit-server-world-success: "&b{0}&a ahora heredan permisos de &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a, por una duracion de &b{4}&a."
unset-inherit-success: "&b{0}&a ya no hereda los permisos de &b{1}&a."
unset-inherit-server-success: "&b{0}&a ya no hereda los permisos de &b{1}&a en el servidor &b{2}&a."
unset-inherit-server-world-success: "&b{0}&a ya no hereda los permisos de &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
unset-temp-inherit-success: "&b{0}&a ya no hereda temporalmente los permisos de &b{1}&a."
unset-temp-inherit-server-success: "&b{0}&a ya no hereda temporalmente los permisos &b{1}&a en el servidor &b{2}&a."
unset-temp-inherit-server-world-success: "&b{0}&a ya no hereda temporalmente los permisos &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
clear-success: "&b{0}&a's permisos fueron borrados. (&b{1}&a nodos fueron removidos.)"
clear-success-singular: "&b{0}&a's permisos fueron borrados. (&b{1}&a nodo fue removido.)"
parent-clear-success: "&b{0}&a's los padres fueron eliminados. (&b{1}&a nodos fueron removidos.)"
parent-clear-success-singular: "&b{0}&a's los padres fueron eliminados. (&b{1}&a nodo fue removido.)"
meta-clear-success: "&b{0}&a's meta fue eliminada. (&b{1}&a nodos fueron removidos.)"
meta-clear-success-singular: "&b{0}&a's meta fue eliminada. (&b{1}&a nodo fue removido.)"
illegal-date-error: "No se pudo analizar la fecha '{0}'."
past-date-error: "¡No puedes fijar una fecha en el pasado!"
chat-meta-prefix-header: "&b{0}'s Prefijos"
chat-meta-suffix-header: "&b{0}'s Sufijos"
meta-header: "&b{0}'s Meta"
chat-meta-entry: "&b-> {0} &f- &f\"{1}&f\" &8(&7heredado de &a{2}&8)"
chat-meta-entry-with-context: "&b-> {0} &f- &f\"{1}&f\" &8(&7heredado de &a{2}&8){3}"
meta-entry: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7heredado de &a{2}&8)"
meta-entry-with-context: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7heredado de &a{2}&8){3}"
chat-meta-prefix-none: "&b{0} no tiene prefijos."
chat-meta-suffix-none: "&b{0} no tiene sufijos."
meta-none: "&b{0} no tiene meta."
meta-invalid-priority: "Prioridad no válida '{0}'. Se esperaba un número."
already-has-prefix: "{0} ya tiene ese prefijo establecido."
already-has-suffix: "{0} ya tiene ese sufijo establecido."
does-not-have-prefix: "{0} no tiene ese prefijo establecido."
does-not-have-suffix: "{0} no tiene ese sufijo establecido."
addprefix-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a establecido como prioridad de &b{2}&a."
addprefix-server-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a establecido como prioridad de &b{2}&a en el servidor &b{3}&a."
addprefix-server-world-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a establecido como prioridad de &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a."
removeprefix-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido."
removeprefix-server-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a."
removeprefix-server-world-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a, mundo &b{4}&a."
addsuffix-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a."
addsuffix-server-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a en el servidor &b{3}&a."
addsuffix-server-world-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a."
removesuffix-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido."
removesuffix-server-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a."
removesuffix-server-world-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a, mundo &b{4}&a."
add-temp-prefix-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a en prioridad de &b{2}&a por una duracion de &b{3}&a."
add-temp-prefix-server-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a en el servidor &b{3}&a, por una duracion de &b{4}&a."
add-temp-prefix-server-world-success: "&b{0}&a tiene el prefijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a, por una duracion de &b{5}&a."
remove-temp-prefix-success: "&b{0}&a tiene temporalmente el prefijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido."
remove-temp-prefix-server-success: "&b{0}&a tiene temporalmente el prefijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a."
remove-temp-prefix-server-world-success: "&b{0}&a tiene temporalmente el prefijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a, mundo &b{4}&a."
add-temp-suffix-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a por una duracion de &b{3}&a."
add-temp-suffix-server-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a en el servidor &b{3}&a, por una duracion de &b{4}&a."
add-temp-suffix-server-world-success: "&b{0}&a tiene el sufijo &f\"{1}&f\"&a establecido en prioridad de &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a, por una duracion de &b{5}&a."
remove-temp-suffix-success: "&b{0}&a tiene temporalmente el sufijo &f\"{1}&f\"&a en prioridad de &b{1}&a removido."
remove-temp-suffix-server-success: "&b{0}&a tiene temporalmente el sufijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a."
remove-temp-suffix-server-world-success: "&b{0}&a tiene temporalmente el sufijo &f\"{1}&f\"&a en prioridad de &b{2}&a removido en el servidor &b{3}&a, mundo &b{4}&a."
already-has-meta: "{0} ya tiene ese par de valores de llave meta establecido."
set-meta-success: "&aEstablecer el valor meta para la llave &f\"{0}&f\"&a a &f\"{1}&f\"&a para &b{2}&a."
set-meta-server-success: "&aEstablecer el valor meta para la llave &f\"{0}&f\"&a a &f\"{1}&f\"&a para &b{2}&a en el servidor &b{3}&a."
set-meta-server-world-success: "&aEstablecer el valor meta para la llave &f\"{0}&f\"&a a &f\"{1}&f\"&a para &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a."
set-meta-temp-success: "&aEstablecer el valor meta para la llave &f\"{0}&f\"&a a &f\"{1}&f\"&a para &b{2}&a por una duracion de &b{3}&a."
set-meta-temp-server-success: "&aEstablecer el valor meta para la llave &f\"{0}&f\"&a a &f\"{1}&f\"&a para &b{2}&a en el servidor &b{3}&a por una duracion de &b{4}&a."
set-meta-temp-server-world-success: "&aEstablecer el valor meta para la llave &f\"{0}&f\"&a a &f\"{1}&f\"&a para &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a, por una duracion de &b{5}&a."
unset-meta-success: "&aDesestablecer el valor meta con la llave &f\"{0}&f\"&a para &b{1}&a."
unset-meta-server-success: "&aDesestablecer el valor meta con la llave &f\"{0}&f\"&a para &b{1}&a en el servidor &b{2}&a."
unset-meta-server-world-success: "&aDesestablecer el valor meta con la llave &f\"{0}&f\"&a for &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
unset-meta-temp-success: "&aDesestablecer temporalmente el valor meta con la llave &f\"{0}&f\"&a para &b{1}&a."
unset-meta-temp-server-success: "&aDesestablecer temporalmente el valor meta con la llave &f\"{0}&f\"&a para &b{1}&a en el servidor &b{2}&a."
unset-meta-temp-server-world-success: "&aDesestablecer temporalmente el valor meta con la llave &f\"{0}&f\"&a para &b{1}&a en el servidor &b{2}&a, mundo &b{3}&a."
bulk-change-type-error: "Tipo no válido. Se estaba esperando 'server' o 'world'."
bulk-change-success: "&aEl cambio masivo fue aplicado correctamente. {0} los registros fueron cambiados."
user-info-general: >
{PREFIX}&b&l> &bUser Info: &f{0}\n
{PREFIX}&f- &3UUID: &f{1}\n
{PREFIX}&f- &3Status: {2}\n
{PREFIX}&f- &3Primary Group: &f{3}\n
{PREFIX}&f- &aCounts:\n
{PREFIX}&f- &3Permissions: &a{4}\n
{PREFIX}&f- &3Temporary Permissions: &a{5}\n
{PREFIX}&f- &3Prefixes: &a{6}\n
{PREFIX}&f- &3Suffixes: &a{7}\n
{PREFIX}&f- &3Meta: &a{8}
user-info-data: >
{PREFIX}&f- &aCached Data:\n
{PREFIX}&f- &3Is Loaded: {0}\n
{PREFIX}&f- &3Current Contexts: {1}\n
{PREFIX}&f- &3Current Prefix: {2}\n
{PREFIX}&f- &3Current Suffix: {3}
info-parent-header: "&f- &aGrupos Parentales:"
info-temp-parent-header: "&f- &aGrupos Temporalmente Parentales:"
user-getuuid: "&bEl UUID de &b{0}&b es &b{1}&b."
user-removegroup-error-primary: "No puede eliminar un usuario de su grupo principal."
user-primarygroup-success: "&b{0}&a's grupo primario se estableció &b{1}&a."
user-primarygroup-warn-option: "&cAdvertencia: El método de cálculo de grupo primario utilizado por este servidor &7({0}) &cpuede no reflejar este cambio."
user-primarygroup-error-alreadyhas: "El usuario ya tiene este grupo configurado como su grupo principal."
user-primarygroup-error-notmember: "&b{0}&a ya no era miembro de &b{1}&a, agregándolos ahora."
user-track-error-not-contain-group: "El usuario especificado ya no está en ningún grupo de esta pista."
user-track-added-to-first: "&b{0}&a no está en ningún grupo en esta pista, por lo que se agregaron al primer grupo, &b{1}&a."
user-track-added-to-first-server: "&b{0}&a no está en ningún grupo en esta pista, por lo que se agregaron al primer grupo, &b{1}&a, en el servidor &b{2}&a."
user-track-added-to-first-server-world: "&b{0}&a no está en ningún grupo en esta pista, por lo que se agregaron al primer grupo, &b{1}&a, en el servidor &b{2}&a, mundo &b{3}&a."
user-promote-success: "&aPromover al usuario a lo largo de la pista &b{0}&a desde &b{1}&a a &b{2}&a."
user-promote-success-server: "&aPromover al usuario a lo largo de la pista &b{0}&a desde &b{1}&a a &b{2}&a en el servidor &b{3}&a."
user-promote-success-server-world: "&aPromover al usuario a lo largo de la pista &b{0}&a desde &b{1}&a a &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a."
user-promote-error-endoftrack: "El final de la pista &4{0}&c fue alcanzado. No se puede promover al usuario."
user-promote-error-malformed: >
{PREFIX}The next group on the track, {0}, no longer exists. Unable to promote user.\n
{PREFIX}Either create the group, or remove it from the track and try again.
user-demote-success: "&aDegradando al usuario a lo largo de la pista &b{0}&a desde &b{1}&a a &b{2}&a."
user-demote-success-server: "&aDegradando al usuario a lo largo de la pista &b{0}&a desde &b{1}&a a &b{2}&a en el servidor &b{3}&a."
user-demote-success-server-world: "&aDegradando al usuario a lo largo de la pista &b{0}&a desde &b{1}&a a &b{2}&a en el servidor &b{3}&a, mundo &b{4}&a."
user-demote-endoftrack: "El final de la pista &4{0}&c fue alcanzado, asi que &4{1}&c fue removido de &4{2}&c."
user-demote-error-malformed: >
{PREFIX}The previous group on the track, {0}, no longer exists. Unable to demote user.\n
{PREFIX}Either create the group, or remove it from the track and try again.
user-showpos: >
&aShowing &b{0}&a's position on track &b{1}&a.\n
{2}
group-info-general: >
{PREFIX}&b&l> &bGroup Info: &f{0}\n
{PREFIX}&f- &3Display Name: &f{1}\n
{PREFIX}&f- &3Weight: &f{2}\n
{PREFIX}&f- &aCounts:\n
{PREFIX}&f- &3Permissions: &a{3}\n
{PREFIX}&f- &3Temporary Permissions: &a{4}\n
{PREFIX}&f- &3Prefixes: &a{5}\n
{PREFIX}&f- &3Suffixes: &a{6}\n
{PREFIX}&f- &3Meta: &a{7}
group-set-weight: "&aEstablesca el peso a &b{0}&a para el grupo &b{1}&a."
track-info: >
{PREFIX}&b&l> &bShowing Track: &f{0}\n
{PREFIX}&f- &7Path: &f{1}
track-clear: "&b{0}&a's pista de grupos fue borrada."
track-append-success: "&aGrupo &b{0}&a fue añadido con éxito a la pista &b{1}&a."
track-insert-success: "&aGrupo &b{0}&a fue insertado con éxito en la pista &b{1}&a en la posicion &b{2}&a."
track-insert-error-number: "Numero esperado en lugar de recibido: {0}"
track-insert-error-invalid-pos: "No se puede insertar en la posición {0}. Indice fuera de los limites."
track-remove-success: "&aGrupo &b{0}&a se eliminó correctamente de la pista &b{1}&a."
log-load-error: "No se pudo cargar el registro."
log-invalid-page: "Número de página no válido."
log-invalid-page-range: "Número de página no válido. Por favor introduzca un valor entre 1 y {0}."
log-no-entries: "&bNo hay entradas de registro que mostrar."
log-entry: "&b#{0} -> &8(&7{1} hace&8) {2}"
log-notify-toggle-on: "&aHabilitada&b salida de registro."
log-notify-toggle-off: "&cDeshabilitada&b salida de registro."
log-notify-already-on: "Ya está recibiendo notificaciones."
log-notify-already-off: "Actualmente no estás recibiendo notificaciones."
log-notify-unknown: "Estado desconocido. Esperando \"on\" o \"off\"."
log-search-header: "&aMostrar acciones recientes para la consulta &b{0} &a(pagina &f{1}&a de &f{2}&a)"
log-recent-header: "&aMostrando acciones recientes (pagina &f{0}&a de &f{1}&a)"
log-recent-by-header: "&aMostrando las acciones recientes por &b{0} &a(pagina &f{1}&a de &f{2}&a)"
log-history-user-header: "&aMostrando el historial del usuario &b{0} &a(pagina &f{1}&a de &f{2}&a)"
log-history-group-header: "&aMostrando la historia del grupo &b{0} &a(pagina &f{1}&a de &f{2}&a)"
log-history-track-header: "&aMostrando la historia de la pista &b{0} &a(pagina &f{1}&a de &f{2}&a)"
log-export-already-exists: "Error: Archivo {0} ya existe."
log-export-not-writable: "Error: Archivo {0} no se puede escribir."
log-export-empty: "El registro está vacío y por lo tanto no puede ser exportado."
log-export-failure: "Se ha producido un error inesperado al escribir en el archivo."
log-export-success: "&aExitosamente exportó el registro a &b{0}&a."
import-already-running: "Ya se está ejecutando otro proceso de importación. Por favor espere a que finalice e inténtelo de nuevo."
export-already-running: "Ya se está ejecutando otro proceso de exportación. Por favor espere a que finalice e inténtelo de nuevo."
import-log-doesnt-exist: "Error: Archivo {0} no existe."
import-log-not-readable: "Error: Archivo {0} no es legible."
import-log-failure: "Se ha producido un error inesperado al leer del archivo de registro."
import-progress: "&b(Import) &b-> &f{0} &fporcentaje completado &7- &b{1}&f/&b{2} &fOperaciones completas con &c{3} &ferrores."
import-progress-sin: "&b(Import) &b-> &f{0} &fporcentaje completado &7- &b{1}&f/&b{2} &fOperaciones completas con &c{3} &ferrores."
import-start: "&b(Import) &b-> &fInicio del proceso de importación."
import-end-complete: "&b(Import) &a&lCOMPLETADO &7- tomo &b{0} &7segundos - &7No errores."
import-end-complete-err: "&b(Import) &a&lCOMPLETADO &7- tomo &b{0} &7segundos - &c{1} errores."
import-end-complete-err-sin: "&b(Import) &a&lCOMPLETADO &7- tomo &b{0} &7segundos - &c{1} errores."
import-end-error-header: >
{PREFIX}&b(Import) &7------------> &fShowing Error #&b{0} &7<------------\n
{PREFIX}&b(Import) &fWhilst executing: &3Command #{1}\n
{PREFIX}&b(Import) &fCommand: &7{2}\n
{PREFIX}&b(Import) &fType: &3{3}\n
{PREFIX}&b(Import) &fOutput:
import-end-error-content: "&b(Import) &b-> &c{0}"
import-end-error-footer: "&b(Import) &7<------------------------------------------>"
+728
View File
@@ -0,0 +1,728 @@
# LuckPerms Language File
# Locale: hu_HU (Hungarian)
# Author: montlikadani
prefix: "&7&l[&b&lL&3&lP&7&l] &c"
empty: "{0}"
player-online: "&aOnline"
player-offline: "&cOffline"
loading-error: "&cNem sikerült betölteni az engedélyezési adatokat. Kérlek, próbáld újra később."
op-disabled: "&bA vanilla OP rendszer le van tiltva ezen a szerveren."
op-disabled-sponge: "&2Kérjük, vegye figyelembe, hogy a kiszolgálói operátor állapota nem befolyásolja a Sponge engedély-ellenőrzéseket, ha engedélyezési bővítmény van telepítve. Kérjük, közvetlenül módosítsa a felhasználói adatokat."
log-info: "&7&l[&bL&3P&7&l] &3{0}"
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[FIGYELEM] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[HIBA] {0}"
log: "&3LOG &3&l> {0}"
verbose-log: "&3VB &3&l> {0}"
export-log: "&3EXPORT &3&l> &f{0}"
export-log-progress: "&3EXPORT &3&l> &7{0}"
migration-log: "&3VÁNDORLÁS &7[&3{0}&7] &3&l> &f{1}"
migration-log-progress: "&3VÁNDORLÁS &7[&3{0}&7] &3&l> &7{1}"
command-not-recognised: "&cA parancs nem ismeretes."
command-no-permission: "&cNincs jogosultságod a használatára!"
user-not-found: "&cEgy felhasználó számára &4{0}&c nem található."
user-not-online: "&b{0}&a felhasználó nem elérhető."
user-save-error: "&cHiba történt a felhasználói adatok mentése közben &4{0}&c."
group-not-found: "&cEgy nevű csoport &4{0}&c nem található."
group-save-error: "&cHiba történt a csoportadatok mentése közben &4{0}&c."
track-not-found: "&cEgy nevű sáv &4{0}&c nem található."
track-save-error: "&cHiba történt a track adatok mentése közben &4{0}&c."
user-invalid-entry: "&4{0}&c nem érvényes felhasználónév/uuid."
group-invalid-entry: "&4{0}&c nem érvényes csoportnév."
track-invalid-entry: "&4{0}&c nem érvényes track név."
server-world-invalid-entry: "&cA szerver/világnév csak alfanumerikus karaktereket tartalmazhat, és nem haladhatja meg a 36 karakter hosszúságú karaktereket."
use-inherit-command: "&cHasználd a 'parent add' és a 'parent remove' parancsokat ahelyett, hogy meghatározta volna a csomópontot."
verbose-invalid-filter: "&4{0}&c nem érvényes kiterjedt szűrő."
verbose-on: "&bRészletes naplózás &aengedélyezve &ba megfelelő ellenőrzésekhez &aBÁRMILYEN&b."
verbose-on-query: "&bRészletes naplózás &aengedélyezve &ba megfelelő ellenőrzésekhez &a{0}&b."
verbose-off: "&bRészletes naplózás &cletiltva&b."
verbose-recording-on: "&bRészletes felvétel &aengedélyezve &ba megfelelő ellenőrzésekhez &aBÁRMILYEN&b."
verbose-recording-on-query: "&bRészletes felvétel &aengedélyezve &ba megfelelő ellenőrzésekhez &a{0}&b."
verbose-upload-start: "&bRészletes naplózás &cletiltva&b. Eredmények feltöltése..."
verbose-results-url: "&aRészletes eredmények URL-je:"
tree-upload-start: "&bEngedélyezési fa létrehozása..."
tree-empty: "&cNem lehet létrehozni a fát. Nincs találat."
tree-url: "&aEngedélyezési fa URL:"
search-searching: "&aFelhasználók és csoportok keresése a következővel: &b{0}&a..."
search-searching-members: "&aFelhasználók és csoportok keresése, akik örökölnek &b{0}&a..."
search-result: "&aTalál &b{0}&a bejegyzéseket a &b{1}&a felhasználók és &b{2}&a csoportok."
search-showing-users: "&bFelhasználói bejegyzések megjelenítése:"
search-showing-groups: "&bCsoportbejegyzések megjelenítése:"
search-showing-users-with-page: "&bFelhasználói bejegyzések megjelenítése: {0}"
search-showing-groups-with-page: "&bCsoportbejegyzések megjelenítése: {0}"
apply-edits-invalid-code: "&cÉrvénytelen kód. &7({0})"
apply-edits-unable-to-read: "&cA megadott kóddal nem lehet adatokat olvasni. &7({0})"
apply-edits-no-target: "&cNem lehet elemezni a szerkesztés célját. Kérjük, nyújtsa be, mint egy extra érv."
apply-edits-target-group-not-exists: "&cCélcsoport &4{0}&c nem létezik."
apply-edits-target-user-not-uuid: "&cCélcsoport &4{0}&c nem érvényes uuid."
apply-edits-target-user-unable-to-load: "&cA célfelhasználó nem tölthető be &4{0}&c."
apply-edits-target-unknown: "&cÉrvénytelen cél. &7({0})"
apply-edits-success: "&aSikeresen alkalmazott &b{0}&a csomópontok &b{1}&a."
editor-upload-failure: "&cNem sikerült feltölteni az engedélyezési adatokat a szerkesztőhöz."
editor-url: "&aSzerkesztő URL:"
check-result: "&aEngedély-ellenőrzés eredmény a felhasználó számára &b{0}&a engedélyért &b{1}&a: &f{2}"
create-success: "&b{0}&a sikeresen létrehozva."
delete-success: "&b{0}&a sikeresen törölve."
rename-success: "&b{0}&a sikeresen átnevezve &b{1}&a."
clone-success: "&b{0}&a sikeresen klónozva &b{1}&a."
already-inherits: "&b{0}&a már örökli &b{1}&a a szövegkörnyezetben {2}&a."
does-not-inherit: "&b{0}&a nem örököl &b{1}&a a szövegkörnyezetben {2}&a."
already-temp-inherits: "&b{0}&a már átmenetileg örökli &b{1}&a a szövegkörnyezetben {2}&a."
does-not-temp-inherit: "&b{0}&a nem átmenetileg örökli &b{1}&a a szövegkörnyezetben {2}&a."
track-already-contains: "&b{0}&a már tartalmazza &b{1}&a."
track-does-not-contain: "&b{0}&a nem tartalmaz &b{1}&a."
track-ambiguous-call: "&4{0}&c ezen a pályán több csoport tagja. Nem tudják meghatározni a helyüket."
already-exists: "&4{0}&c már létezik!"
does-not-exist: "&4{0}&c nem létezik!"
group-load-error: "&cVáratlan hiba történt. A csoport nincs betöltve."
groups-load-error: "&cVáratlan hiba történt. Nem sikerült betölteni az összes csoportot."
track-load-error: "&cVáratlan hiba történt. A nyomvonal nincs betöltve."
tracks-load-error: "&cVáratlan hiba történt. Nem sikerült betölteni az összes számot."
track-empty: "&4{0}&c nem használható, mivel üres vagy csak egy csoportot tartalmaz."
update-task-request: "&bFrissítési feladatot kértek. Kérlek, várj..."
update-task-complete: "&aA feladat frissítése befejeződött."
update-task-complete-network: "&aA feladat frissítése befejeződött. Most más szerverekre próbálkozni."
update-task-push-success: "&aMás szervereket értesítettek &b{0} Üzenetek &asikeresen."
update-task-push-failure: "&cHiba történt a többi kiszolgálóra történő változtatás közben."
update-task-push-failure-not-setup: "&cHiba történt a többi kiszolgálóra történő változtatás közben. &7(egy üzenetkezelő szolgáltatást nem konfigurált)"
reload-config-success: "&aA konfigurációs fájl újratöltve. &7(néhány opció csak a szerver újraindítása után fog működni)"
info-top: >
{PREFIX}&2Running &bLuckPerms v{0}&2 by &bLuck&2.\n
{PREFIX}&f- &3Emelvény: &f{1}\n
{PREFIX}&f- &3Szerver márka: &f{2}\n
{PREFIX}&f- &3Szerver verzió: &f{3}
info-middle: >
{PREFIX}&f- &bÜzenet típusa: &f{0}\n
{PREFIX}&f- &bPélda:\n
{PREFIX}&f- &3Szerver név: &f{1}\n
{PREFIX}&f- &3Elérhető játékosok: &a{2}\n
{PREFIX}&f- &3Egyedi kapcsolatok: &a{3}\n
{PREFIX}&f- &3Üzemidő: &7{4}\n
{PREFIX}&f- &3Helyi adatok: &a{5} &7felhasználó, &a{6} &7csoport, &a{7} &7pályák\n
{PREFIX}&f- &3Kontextus számológépek: &a{8}\n
{PREFIX}&f- &3Ismert engedélyek: &a{9}\n
{PREFIX}&f- &3Aktív processzorok: &7{10}
create-error: "&cHiba történt a létrehozás során &4{0}&c."
delete-error: "&cTörlés közben hiba történt &4{0}&c."
delete-group-error-default: "&cAz alapértelmezett csoportot nem törölheti."
groups-list: "&aCsoportok: &7(név, súly, pályák)"
groups-list-entry: "&f- &3{0} &7- &b{1}"
groups-list-entry-with-tracks: "&f- &3{0} &7- &b{1} &7- [&3{2}&7]"
tracks-list: "&aPályák: {0}"
listnodes: "&b{0}'s Jogok:"
listnodes-with-page: "&b{0} Jogai: {1}"
listnodes-temp: "&b{0} Ideiglenes engedélyei:"
listnodes-temp-with-page: "&b{0} Ideiglenes engedélyei: {1}"
listparents: "&b{0} Szülői csoportok:"
listparents-temp: "&b{0} Ideiglenes szülői csoportok:"
list-tracks: >
&b{0} Pályái:\n
{1}
list-tracks-empty: "&b{0}&a nincs rajta."
context-pair-inline: "&3{0}=&b{1}"
context-pair--global-inline: "&eglobális"
context-pair-sep: "&a, "
context-pair: "&8(&7{0}=&f{1}&8)"
check-permission: "&b{0}&a engedéllyel rendelkezik &b{1}&a állítva {2}&a a szövegkörnyezetben {3}&a."
check-inherits-permission: "&b{0}&a engedéllyel rendelkezik &b{1}&a állítva {2}&a a szövegkörnyezetben {3}&a. &7(örökölt &a{4}&7)"
setpermission-success: "&aBeállítva &b{0}&a-nak/-nek &b{1}&a, mert &b{2}&a a szövegkörnyezetben {3}&a."
already-haspermission: "&b{0}&a már van &b{1}&a összefüggésben {2}&a."
setpermission-temp-success: "&aBeállítva &b{0}&a-nak/-nek &b{1}&a, mert &b{2}&a egy ideig &b{3}&a a szövegkörnyezetben {4}&a."
already-has-temp-permission: "&b{0}&a már van &b{1}&a ideiglenesen környezetben {2}&a."
unsetpermission-success: "&aVisszaállítva &b{0}&a, mert &b{1}&a a szövegkörnyezetben {2}&a."
does-not-have-permission: "&b{0}&a nem rendelkezik &b{1}&a összefüggésben {2}&a."
unset-temp-permission-success: "&aIdeiglenes engedély érvénytelenítése &b{0}&a, mert &b{1}&a a szövegkörnyezetben {2}&a."
does-not-have-temp-permission: "&b{0}&a nem rendelkezik &b{1}&a ideiglenesen környezetben {2}&a."
set-inherit-success: "&b{0}&a most örökli az engedélyeket &b{1}&a a szövegkörnyezetben {2}&a."
set-temp-inherit-success: "&b{0}&a most örökli az engedélyeket &b{1}&a egy ideig &b{2}&a a szövegkörnyezetben {3}&a."
set-parent-success: "&b{0}&a meglévő szüloi csoportjaik tiszták, és most csak örökölnek &b{1}&a a szövegkörnyezetben {2}&a."
set-track-parent-success: "&b{0}&a meglévő szülői csoportjaik voltak a pályán &b{1}&a törölni, és most csak örökli &b{2}&a a szövegkörnyezetben {3}&a."
unset-inherit-success: "&b{0}&a többé nem örökli az engedélyeket &b{1}&a a szövegkörnyezetben {2}&a."
unset-temp-inherit-success: "&b{0}&a már nem ideiglenesen örökli az engedélyeket &b{1}&a a szövegkörnyezetben {2}&a."
clear-success: "&b{0}&a a jogosultságokat a kontextusban törölték {1}&a. (&b{2}&a a csomópontokat eltávolítottuk.)"
clear-success-singular: "&b{0}&a a jogosultságokat a kontextusban törölték {1}&a. (&b{2}&a csomópontot eltávolítottuk.)"
parent-clear-success: "&b{0}&a a szülei a kontextusban megszűntek {1}&a. (&b{2}&a a csomópontokat eltávolítottuk.)"
parent-clear-success-singular: "&b{0}&a a szülei a kontextusban megszűntek {1}&a. (&b{2}&a a csomópontokat eltávolítottuk.)"
parent-clear-track-success: "&b{0}&a szülők a pályán &b{1}&a összefüggésben {2}&a. (&b{3}&a a csomópontokat eltávolítottuk.)"
parent-clear-track-success-singular: "&b{0}&a szülők a pályán &b{1}&a összefüggésben {2}&a. (&b{3}&a csomópontot eltávolítottuk.)"
meta-clear-success: "&b{0}&a meta egyezéstípusa &b{1}&a összefüggésben {2}&a. (&b{3}&a a csomópontokat eltávolítottuk.)"
meta-clear-success-singular: "&b{0}&a meta egyezéstípusa &b{1}&a összefüggésben {2}&a. (&b{3}&a csomópontot eltávolítottuk.)"
illegal-date-error: "&cNem sikerült elemezni a dátumot &4{0}&c."
past-date-error: "&cNem állíthat be dátumot a múltban!"
chat-meta-prefix-header: "&b{0} Előtagjai"
chat-meta-suffix-header: "&b{0} Utótagja"
meta-header: "&b{0} Metája"
chat-meta-entry: "&b-> {0} &f- &f'{1}&f' &8(&7örökölt &a{2}&8)"
chat-meta-entry-with-context: "&b-> {0} &f- &f'{1}&f' &8(&7örökölt &a{2}&8){3}"
meta-entry: "&b-> &a{0} &f= &f'{1}&f' &8(&7örökölt &a{2}&8)"
meta-entry-with-context: "&b-> &a{0} &f= &f'{1}&f' &8(&7örökölt &a{2}&8){3}"
chat-meta-prefix-none: "&b{0} nincsenek előtagjai."
chat-meta-suffix-none: "&b{0} nincs utótagja."
meta-none: "&b{0} nincs meta."
meta-invalid-priority: "&cÉrvénytelen prioritás &4{0}&c. Várható szám."
already-has-chat-meta: "&b{0}&a már van {1} &f'{2}&f'&a elsőbbséget élvez &b{3}&a a szövegkörnyezetben {4}&a."
already-has-temp-chat-meta: "&b{0}&a már van {1} &f'{2}&f'&a ideiglenesen &b{3}&a a szövegkörnyezetben {4}&a."
does-not-have-chat-meta: "&b{0}&a nincs {1} &f'{2}&f'&a elsőbbséget élvez &b{3}&a a szövegkörnyezetben {4}&a."
does-not-have-temp-chat-meta: "&b{0}&a nincs {1} &f'{2}&f'&a ideiglenesen &b{3}&a a szövegkörnyezetben {4}&a."
add-chatmeta-success: "&b{0}&a volt {1} &f'{2}&f'&a elsőbbséget élvez &b{3}&a a szövegkörnyezetben {4}&a."
add-temp-chatmeta-success: "&b{0}&a volt {1} &f'{2}&f'&a elsőbbséget élvez &b{3}&a egy ideig &b{4}&a a szövegkörnyezetben {5}&a."
remove-chatmeta-success: "&b{0}&a volt {1} &f'{2}&f'&a prioritásként &b{3}&a eltávolítva a kontextusban {4}&a."
bulk-remove-chatmeta-success: "&b{0}&a minden volt {1}es a prioritás &b{2}&a eltávolítva a kontextusban {3}&a."
remove-temp-chatmeta-success: "&b{0}&a ideiglenes volt {1} &f'{2}&f'&a prioritásként &b{3}&a eltávolítva a kontextusban {4}&a."
bulk-remove-temp-chatmeta-success: "&b{0}&a minden ideiglenes volt {1}es prioritásként &b{2}&a eltávolítva a kontextusban {3}&a."
already-has-meta: "&b{0}&a már van meta kulcs &f'{1}&f'&a állítva &f'{2}&f'&a a szövegkörnyezetben {3}&a."
already-has-temp-meta: "&b{0}&a már van meta kulcs &f'{1}&f'&a átmenetileg beállítva &f'{2}&f'&a a szövegkörnyezetben {3}&a."
doesnt-have-meta: "&b{0}&a nincs meta kulcs &f'{1}&f'&a összefüggésben {2}&a."
doesnt-have-temp-meta: "&b{0}&a nincs meta kulcs &f'{1}&f'&a ideiglenesen a környezetben {2}&a."
set-meta-success: "&aÁllítva a meta kulcsot &f'{0}&f'&a-nak/-nek &f'{1}&f'&a, mert &b{2}&a a szövegkörnyezetben {3}&a."
set-meta-temp-success: "&aÁllítva a meta kulcsot &f'{0}&f'&a-nak/-nek &f'{1}&f'&a, mert &b{2}&a egy ideig &b{3}&a a szövegkörnyezetben {4}&a."
unset-meta-success: "&aLeválasztva a meta kulcsot &f'{0}&f'&a, mert &b{1}&a a szövegkörnyezetben {2}&a."
unset-meta-temp-success: "&aIdeiglenes meta kulcs kikapcsolása &f'{0}&f'&a, mert &b{1}&a a szövegkörnyezetben {2}&a."
bulk-update-invalid-data-type: "&cÉrvénytelen típus. Típusok 'all', 'users' vagy 'groups'."
bulk-update-invalid-constraint: "&cÉrvénytelen kényszer &4{0}&c. A korlátozásoknak formátumban kell lenniük '&f<mező> <összehasonlító operátor> <érték>&c'."
bulk-update-invalid-comparison: "&cÉrvénytelen összehasonlító operátor '&4{0}&c'. Várható az alábbiak közül: &f== != ~~ ~!"
bulk-update-queued: "&aA tömeges frissítés sorba állt. &7(&f{0}&7)"
bulk-update-confirm: "&aA futtatáshoz &b/{0} a tömeges frissítés megerősítéséhez {1} &aa frissítés végrehajtásához."
bulk-update-unknown-id: "&aMűködési id &b{0}&a nem létezik, vagy lejárt."
bulk-update-starting: "&aFolyamatos frissítés futtatása."
bulk-update-success: "&bA tömeges frissítés sikeresen befejeződött."
bulk-update-failure: "&cA tömeges frissítés sikertelen. Ellenőrizze a konzolt hiba esetén."
user-info-general: >
{PREFIX}&b&l> &bFelhasználói adatok: &f{0}\n
{PREFIX}&f- &3UUID: &f{1}\n
{PREFIX}&f- &3Állapot: {2}\n
{PREFIX}&f- &3Elsődleges csoport: &f{3}\n
{PREFIX}&f- &aGrófok:\n
{PREFIX}&f- &3Csomópontok: &a{4}\n
{PREFIX}&f- &3Jogok: &a{5}\n
{PREFIX}&f- &3Előtagok: &a{6}\n
{PREFIX}&f- &3Utótagok: &a{7}\n
{PREFIX}&f- &3Meta: &a{8}
user-info-data: >
{PREFIX}&f- &aGyorsítótár adat:\n
{PREFIX}&f- &3Kontextuális adatok vannak: {0}\n
{PREFIX}&f- &3Jelenlegi kontextusok: {1}\n
{PREFIX}&f- &3Jelenlegi előtag: {2}\n
{PREFIX}&f- &3Jelenlegi utótag: {3}
info-parent-header: "&f- &aSzülői csoportok:"
info-temp-parent-header: "&f- &aIdeiglenes szülői csoportok:"
user-removegroup-error-primary: "&aNem lehet eltávolítani egy felhasználót az elsődleges csoportból."
user-primarygroup-success: "&b{0}&a az elsődleges csoportot &b{1}&a."
user-primarygroup-warn-option: "&aFigyelmeztetés: A kiszolgáló által használt elsődleges csoportszámítási módszer &7({0}) &anem tükrözheti ezt a változást."
user-primarygroup-error-alreadyhas: "&b{0}&a már van &b{1}&a mint elsődleges csoportjuk."
user-primarygroup-error-notmember: "&b{0}&a már nem tagja &b{1}&a, hozzátéve őket."
user-track-error-not-contain-group: "&b{0}&a már nincsenek benne &b{1}&a."
user-track-added-to-first: "&b{0}&a nincsenek ezen a pályán egyetlen csoportban sem, így az első csoportba kerültek, &b{1}&a a szövegkörnyezetben {2}&a."
user-promote-success: "&aElőmozdítása &b{0}&a a pályán &b{1}&a-tól/-től &b{2}&a-nak/-nek &b{3}&a a szövegkörnyezetben {4}&a."
user-promote-error-endoftrack: "&aA pálya vége &b{0}&a elérte. Nem lehetett népszerűsíteni &b{1}&a."
user-promote-error-malformed: >
{PREFIX}&aA következő csoport a pályán, &b{0}&a, nem létezik többé. Nem sikerült népszerűsíteni a felhasználót.\n
{PREFIX}&aVagy hozzon létre egy csoportot, vagy távolítsa el a zeneszámból, és próbálkozzon újra.
user-demote-success: "&aLefokozandó &b{0}&a a pályán &b{1}&a-tól/-től &b{2}&a-nak/-nek &b{3}&a a szövegkörnyezetben {4}&a."
user-demote-endoftrack: "&aA pálya vége &b{0}&a, így elérte &b{1}&a eltávolították &b{2}&a."
user-demote-error-malformed: >
{PREFIX}&aAz előző csoport a pályán, &b{0}&a, nem létezik többé. Nem lehet lecsökkenteni a felhasználót.\n
{PREFIX}&aVagy hozzon létre egy csoportot, vagy távolítsa el a zeneszámból, és próbálkozzon újra.
group-info-general: >
{PREFIX}&b&l> &bCsoport info: &f{0}\n
{PREFIX}&f- &3Megjelenítendő név: &f{1}\n
{PREFIX}&f- &3Súly: &f{2}\n
{PREFIX}&f- &aGrófok:\n
{PREFIX}&f- &3Csomópontok: &a{3}\n
{PREFIX}&f- &3Jogok: &a{4}\n
{PREFIX}&f- &3Előtagok: &a{5}\n
{PREFIX}&f- &3Utótagok: &a{6}\n
{PREFIX}&f- &3Meta: &a{7}
group-set-weight: "&aA súly beállítása &b{0} &b{1}&a csoporthoz."
track-info: >
{PREFIX}&b&l> &bPálya megjelenítése: &f{0}\n
{PREFIX}&f- &7Pálya: &f{1}
track-clear: "&b{0}&a csoportok nyomvonalát törölték."
track-append-success: "&aCsoport &b{0}&a csatolták a követéshez &b{1}&a."
track-insert-success: "&aCsoport &b{0}&a beillesztésre került a pályára &b{1}&a helyzetben &b{2}&a."
track-insert-error-number: "&cVárható szám, de helyette beérkezett: {0}"
track-insert-error-invalid-pos: "&cNem helyezhető be a pozícióba &4{0}&c. &7(érvénytelen pozíció)"
track-remove-success: "&aCsoport &b{0}&a eltávolították a pályáról &b{1}&a."
log-load-error: "&cA napló nem tölthető be."
log-invalid-page: "&cÉrvénytelen oldalszám."
log-invalid-page-range: "&cÉrvénytelen oldalszám. Kérjük, adjon meg egy értéket &41&c és &4{0}&c."
log-no-entries: "&bNincs megjeleníthető naplóbejegyzés."
log-entry: "&b#{0} -> &8(&7{1} ezelőtt&8) {2}"
log-notify-console: "&cA konzolra vonatkozó értesítések átváltása nem lehetséges."
log-notify-toggle-on: "&aEngedélyezve a&b naplózási kimenet."
log-notify-toggle-off: "&cLetiltva a&b naplózási kimenet."
log-notify-already-on: "&cMár értesítést kapsz."
log-notify-already-off: "&cJelenleg nem kap értesítést."
log-notify-unknown: "&cÁllam ismeretlen. Várandós \"on\" vagy \"off\"."
log-search-header: "&aA lekérdezés legutóbbi műveleteinek megjelenítése &b{0} &a(oldal &f{1} &f{2}&a-ból/-ből)"
log-recent-header: "&aA legutóbbi műveletek megjelenítése (oldal &f{0} &f{1}&a-ból/-ből)"
log-recent-by-header: "&aLegutóbbi fellépések megjelenítése a következővel: &b{0} &a(oldal &f{1} &f{2}&a-ból/-ből)"
log-history-user-header: "&aA felhasználó előzményeinek megjelenítése &b{0} &a(oldal &f{1} &f{2}&a-ból/-ből)"
log-history-group-header: "&aA csoport előzményeinek megjelenítése &b{0} &a(oldal &f{1} &f{2}&a-ból/-ből)"
log-history-track-header: "&aA sáv előzményeinek megjelenítése &b{0} &a(oldal &f{1} &f{2}&a-ból/-ből)"
log-export-already-exists: "&cHiba: A fájl &4{0}&c már létezik."
log-export-not-writable: "&cHiba: A fájl &4{0}&c nem írható."
log-export-empty: "&cA napló üres, ezért nem exportálható."
log-export-failure: "&cVáratlan hiba történt a fájl írása közben."
log-export-success: "&aSikeresen exportálta a naplót &b{0}&a."
import-already-running: "&cEgy másik behozatali folyamat már fut. Kérjük, várjon, amíg befejeződik, és próbálkozzon újra."
export-already-running: "&cEgy másik exportfolyamat már fut. Kérjük, várjon, amíg befejeződik, és próbálkozzon újra."
import-log-doesnt-exist: "&cHiba: A fájl &4{0}&c nem létezik."
import-log-not-readable: "&cHiba: A fájl &4{0}&c nem olvasható."
import-log-failure: "&cA naplófájl olvasása közben váratlan hiba történt."
import-progress: "&b(Import) &b-> &f{0}&f% sikeres &7- &b{1}&f/&b{2} &fműveletekkel kiegészítve &c{3} &fhibák."
import-progress-sin: "&b(Import) &b-> &f{0}&f% sikeres &7- &b{1}&f/&b{2} &fműveletekkel kiegészítve &c{3} &fhiba."
import-start: "&b(Import) &b-> &fImportálás indítása."
import-end-complete: "&b(Import) &a&lSIKERES &7- vett &b{0} &7másodperc - &7Nincs hibák."
import-end-complete-err: "&b(Import) &a&lSIKERES &7- vett &b{0} &7másodperc - &c{1} hibák."
import-end-complete-err-sin: "&b(Import) &a&lSIKERES &7- vett &b{0} &7másodperc - &c{1} hiba."
import-end-error-header: >
{PREFIX}&b(Import) &7------------> &fHiba megjelenítése #&b{0} &7<------------\n
{PREFIX}&b(Import) &fFuttatás közben: &3Parancs #{1}\n
{PREFIX}&b(Import) &fParancs: &7{2}\n
{PREFIX}&b(Import) &fTípus: &3{3}\n
{PREFIX}&b(Import) &fKibocsátás:
import-end-error-content: "&b(Import) &b-> &c{0}"
import-end-error-footer: "&b(Import) &7<------------------------------------------>"
command-specs:
user:
description: "Felhasználói parancsok"
usage: "/%s user <felhasználó>"
group:
description: "Csoport parancsok"
usage: "/%s group <csoport>"
track:
description: "Sávparancsok"
usage: "/%s track <track>"
log:
description: "Napló parancsok"
usage: "/%s log"
sync:
description: "A szinkronizálás megváltozik a tárolóval"
usage: "/%s sync"
info:
description: "Általános plugin info nyomtatása"
usage: "/%s info"
verbose:
description: "Rendszeres engedély ellenőrzése"
usage: "/%s verbose <true|false> [szűrő]"
args:
"on|record|off|paste": "hogy bekapcsolják/kikapcsolják a naplózást, vagy beillesztik-e a naplózott kimenetet"
"filter": "a szűrő a bejegyzések ellen"
"--slim": "hozzáad \"--slim\" a nyomkövetési adatok kizárása a beillesztett kimenetből"
tree:
description: "Hozzon létre egy fa nézetet az engedélyekről"
usage: "/%s tree [kiválasztás] [max. szint] [játékos]"
args:
"selection": "a fa gyökere. Meghatározza \".\", hogy az összes engedélyt tartalmazza"
"max level": "hány fiókszintet kell visszaküldeni"
"player": "az elérhető játékos nevét ellenőrizni"
search:
description: "Keressen olyan felhasználókat/csoportokat, akiknek engedélye van"
usage: "/%s search <jog>"
args:
"permission": "a keresési engedély"
"page": "a megtekinteni kívánt oldalt"
check:
description: "Végezzen el egy szabványos engedélyt egy elérhető játékoson"
usage: "/%s check <felhasználó> <jog>"
args:
"user": "a felhasználó ellenőrizni"
"permission": "az ellenőrzés engedélye"
network-sync:
description: "A szinkronizálás a tárhely módosításával történik, és kérni fogja, hogy a hálózaton lévő összes többi szerver ugyanezt tegye"
usage: "/%s networksync"
import:
description: "Adatok importálása fájlból"
usage: "/%s import <fájl>"
args:
"file": "az importálni kívánt fájl"
export:
description: "Adatok exportálása egy fájlba"
usage: "/%s export <fájl>"
args:
"file": "az exportálni kívánt fájl"
reload-config:
description: "Betölt néhány konfigurációs beállítást"
usage: "/%s reloadconfig"
bulk-update:
description: "Végezzen ömlesztett változás lekérdezéseket az összes adaton"
usage: "/%s bulkupdate"
args:
"data type": "a megváltoztatott adatok típusa. ('all', 'users' vagy 'groups')"
"action": "az elvégzendő művelet az adatokon. ('update' vagy 'delete')"
"action field": "a cselekvési terület. Csak a szükséges 'update'. ('permission', 'server' vagy 'world')"
"action value": "a cserélendő érték. Csak a szükséges 'update'."
"constraint...": "a frissítéshez szükséges korlátokat"
migration:
description: "Migrációs parancsok"
usage: "/%s migration"
apply-edits:
description: "A webszerkesztő által végrehajtott engedély módosításokat alkalmazza"
usage: "/%s applyedits <kód> [cél]"
args:
"code": "az adatok egyedi kódja"
"target": "aki az adatokat alkalmazza"
create-group:
description: "Létrehoz egy új csoportot"
usage: "/%s creategroup <csoport>"
args:
"name": "a csoport neve"
delete-group:
description: "Csoport eltávolítása"
usage: "/%s deletegroup <csoport>"
args:
"name": "a csoport neve"
list-groups:
description: "Felsorolja az összes csoportot a platformon"
usage: "/%s listgroups"
create-track:
description: "Hozzon létre egy új számot"
usage: "/%s createtrack <track>"
args:
"name": "a pálya neve"
delete-track:
description: "Egy szám törlése"
usage: "/%s deletetrack <track>"
args:
"name": "a pálya neve"
list-tracks:
description: "Felsorolja az összes zeneszámot a platformon"
usage: "/%s listtracks"
user-info:
description: "Információkat jelenít meg a felhasználóról"
user-switchprimarygroup:
description: "A felhasználó elsődleges csoportjának átváltása"
args:
"group": "a csoport, amelyre váltani"
user-promote:
description: "Segít a felhasználónak egy számot feltölteni"
args:
"track": "a pálya, hogy elősegítse a felhasználó fel"
"context...": "a felhasználót elősegítő kontextusok"
user-demote:
description: "Megszünteti a felhasználót egy pályán"
args:
"track": "a sáv, amely leállítja a felhasználót"
"context...": "a felhasználókat lecsökkentő kontextusok"
group-info:
description: "Információkat ad a csoportról"
group-listmembers:
description: "Mutassa be a csoportból öröklődő felhasználókat/csoportokat"
args:
"page": "a megtekinteni kívánt oldal"
group-setweight:
description: "Beállítja a csoportok súlyát"
args:
"weight": "a beállítani kívánt súly"
group-rename:
description: "Átnevezi a csoportot"
args:
"name": "az új név"
group-clone:
description: "Klónozza a csoportot"
args:
"name": "a klónozni kívánt csoport neve"
holder-editor:
description: "Megnyitja a webes engedély-szerkesztőt"
holder-showtracks:
description: "Megadja az objektum sávjait"
holder-clear:
description: "Eltávolítja az összes jogosultságot, szülőt és meta-t"
args:
"context...": "a szövegszűrés körülményei"
permission:
description: "Jogok szerkesztése"
parent:
description: "Örökletek szerkesztése"
meta:
description: "Metaadatértékek szerkesztése"
permission-info:
description: "Megadja az objektum engedélyezési csomópontjait"
args:
"page": "a megtekinteni a kívánt oldalt"
"filter": "a string szűrni"
permission-set:
description: "Beállítja az objektum engedélyét"
args:
"node": "a beállítandó jog csomópont"
"true|false": "a csomópont értéke"
"context...": "az engedéllyel rendelkező szövegkörnyezetek"
permission-unset:
description: "Megadja az objektum engedélyét"
args:
"node": "az engedéllyel rendelkező csomópont kiiktatásához"
"context...": "az engedélyek eltávolításának kontextusai"
permission-settemp:
description: "Beállítja az objektum ideiglenes engedélyét"
args:
"node": "a beállítandó engedély csomópont"
"true|false": "a csomópont értéke"
"duration": "amíg az engedély csomópontja lejárt"
"context...": "az engedéllyel rendelkező szövegkörnyezetek"
permission-unsettemp:
description: "Megadja az ideiglenes engedélyt az objektumhoz"
args:
"node": "az engedéllyel rendelkező csomópont kiiktatásához"
"context...": "az engedélyek eltávolításának kontextusai"
permission-check:
description: "Ellenőrzi, hogy az objektumnak van-e engedélyezési csomópontja"
args:
"node": "az engedéllyel rendelkező csomópontot"
"context...": "a bejelentkezés körülményei"
permission-check-inherits:
description: "Ellenőrzi, hogy az objektum örökli-e az engedélyezési csomópontot"
args:
"node": "az engedéllyel rendelkező csomópontot"
"context...": "a bejelentkezés körülményei"
parent-info:
description: "Megadja azokat a csoportokat, amelyeket ez az objektum örököl"
parent-set:
description: "Eltávolítja az összes többi csoportot, amelyet az objektum már örököl, és hozzáadja azokat az adott objektumhoz"
args:
"group": "a csoport, amelyre állít"
"context...": "a csoport beállításához szükséges kontextusok"
parent-add:
description: "Beállít egy másik csoportot az objektumhoz, hogy örökli a jogokat"
args:
"group": "a csoport örökölni"
"context...": "a csoportot örökli a szövegkörnyezetben"
parent-remove:
description: "Eltávolítja a korábban beállított öröklési szabályt"
args:
"group": "a csoport eltávolítani"
"context...": "a csoport eltávolításának kontextusai"
parent-set-track:
description: "Eltávolítja az összes többi olyan csoportot, amelyet az adott objektum már örököl az adott sávon, és hozzáadja azokat az adott sávhoz"
args:
"track": "a pálya bekapcsolásához"
"group": "a beállítani kívánt csoportot, vagy a csoport helyzetét az adott sávon"
"context...": "a csoport beállításához szükséges kontextusok"
parent-add-temp:
description: "Egy másik csoportot állít be, hogy az objektum átmenetileg átengedi az engedélyeket"
args:
"group": "a csoport örökölni"
"duration": "a csoporttagság időtartamát"
"context...": "a csoportot örökli a szövegkörnyezetben"
parent-remove-temp:
description: "Eltávolítja a korábban beállított ideiglenes öröklési szabályt"
args:
"group": "a csoport eltávolítani"
"context...": "a csoport eltávolításának kontextusai"
parent-clear:
description: "Törli az összes szülőt"
args:
"context...": "a szövegszűrés körülményei"
parent-clear-track:
description: "Törli az összes szülőt egy adott pályán"
args:
"track": "az eltávolítandó sáv"
"context...": "a szövegszűrés körülményei"
meta-info:
description: "Az összes csevegési meta megjelenítése"
meta-set:
description: "Meta értéket állít be"
args:
"key": "a beállítani kívánt kulcs"
"value": "a beállítani kívánt érték"
"context...": "a meta-pár beillesztésének kontextusai"
meta-unset:
description: "Megszünteti a meta értéket"
args:
"key": "a kiiktatás kulcsa"
"context...": "a meta-pár eltávolításának kontextusai"
meta-settemp:
description: "Átmenetileg beállítja a metaértéket"
args:
"key": "a beállítani kívánt kulcs"
"value": "a beállítani kívánt érték"
"duration": "amíg a meta érték lejár"
"context...": "a meta-pár beillesztésének kontextusai"
meta-unsettemp:
description: "Megszünteti az ideiglenes metaértéket"
args:
"key": "a kiiktatás kulcsa"
"context...": "a metapár eltávolításának kontextusai"
meta-addprefix:
description: "Hozzáad egy előtagot"
args:
"priority": "az elsőbbséget az előtag hozzáadásához"
"prefix": "az előtag karaktersorozat"
"context...": "az előtag beillesztésének kontextusai"
meta-addsuffix:
description: "Hozzáad egy utótagot"
args:
"priority": "elsőbbséget kell adni az utótagnak a következőhöz:"
"suffix": "az utótagsor"
"context...": "azok a kontextusok, amelyekhez hozzá kell adni az utótagot"
meta-removeprefix:
description: "Eltávolít egy előtagot"
args:
"priority": "az elsőbbség eltávolítása az előtagon"
"prefix": "az előtag karaktersorozat"
"context...": "az előtagot eltávolító szövegkörnyezetek"
meta-removesuffix:
description: "Eltávolít egy utótagot"
args:
"priority": "az elsőbbség, hogy eltávolítsák az utótagot"
"suffix": "az utótagsor"
"context...": "azok a kontextusok, amelyek eltávolítják az utótagot"
meta-addtemp-prefix:
description: "Privát előtagot ad át ideiglenesen"
args:
"priority": "az elsőbbséget az előtag hozzáadásához"
"prefix": "az előtag karaktersorozat"
"duration": "az időtartam, amíg az előtag lejár"
"context...": "az előtag beillesztésének kontextusai"
meta-addtemp-suffix:
description: "Egy ideiglenes utótagot ad hozzá"
args:
"priority": "elsőbbséget kell adni az utótagnak a következőhöz:"
"suffix": "az utótagsor"
"duration": "az időtartam, amíg az utótag lejár"
"context...": "azok a kontextusok, amelyekhez hozzá kell adni az utótagot"
meta-removetemp-prefix:
description: "Eltávolít ideiglenes előtagot"
args:
"priority": "az elsőbbség eltávolítása az előtagon"
"prefix": "az előtag karaktersorozat"
"context...": "az előtagot eltávolító szövegkörnyezetek"
meta-removetemp-suffix:
description: "Eltávolítja az ideiglenes utótagot"
args:
"priority": "az elsőbbség, hogy eltávolítsák az utótagot"
"suffix": "az utótagsor"
"context...": "azok a kontextusok, amelyek eltávolítják az utótagot"
meta-clear:
description: "Törli az összes metódust"
args:
"type": "a eltávolítandó meta típusa"
"context...": "a szövegszűrés körülményei"
track-info:
description: "Ad információt a pályáról"
track-append:
description: "Csatol egy csoportot a pálya végére"
args:
"group": "a csoport hozzáfűzése"
track-insert:
description: "Beilleszti a csoportot egy adott pozícióban a pálya mentén"
args:
"group": "beszúrni a kívánt csoport"
"position": "a helyzet a csoport beillesztésére (az első pozíció a pályán 1)"
track-remove:
description: "Eltávolít egy csoportot a sávról"
args:
"group": "a csoport eltávolítani"
track-clear:
description: "Törli a csoportokat a pályán"
track-rename:
description: "Nevezze át a sávot"
args:
"name": "az új név"
track-clone:
description: "Klónozza a sávot"
args:
"name": "a pálya neve, hogy klónozzanak"
log-recent:
description: "A legutóbbi műveletek megtekintése"
args:
"user": "a felhasználó neve/uuid-je, hogy kiszűrje"
"page": "a megtekinteni kívánt oldalszám"
log-search:
description: "Keressen egy bejegyzés naplót"
args:
"query": "keresési lekérdezés"
"page": "a megtekinteni kívánt oldalszám"
log-notify:
description: "A naplóbejelentések módosítása"
args:
"on|off": "hogy be vagy ki van kapcsolva"
log-user-history:
description: "A felhasználó előzményeinek megtekintése"
args:
"user": "a felhasználó neve/uuid-je"
"page": "a megtekinteni kívánt oldalszám"
log-group-history:
description: "A csoport előzményeinek megtekintése"
args:
"group": "a csoport neve"
"page": "a megtekinteni kívánt oldalszám"
log-track-history:
description: "A sáv előzményeinek megtekintése"
args:
"track": "a pálya neve"
"page": "a megtekinteni kívánt oldalszám"
sponge:
description: "Extra Szivacs adatok szerkesztése"
usage: "/%s sponge <gyűjtemény> <tárgy>"
args:
"collection": "a lekérdezésre kerülő gyűjtemény"
"subject": "módosítani a tárgyat"
sponge-permission-info:
description: "A tárgyhoz tartozó jogokkal kapcsolatos információkat jeleníti meg"
args:
"contexts...": "a szövegszűrés körülményei"
sponge-permission-set:
description: "Engedélyt ad a Tárgyhoz"
args:
"node": "a beállítandó engedély csomópont"
"tristate": "az engedélyhez szükséges érték megadása"
"contexts...": "az engedéllyel rendelkező szövegkörnyezetek"
sponge-permission-clear:
description: "Törli a Tárgy engedélyeit"
args:
"contexts...": "a szövegkörnyezetek engedélyeinek törlése"
sponge-parent-info:
description: "Megjeleníti a tárgy szüleinek adatait"
args:
"contexts...": "a szövegszűrés körülményei"
sponge-parent-add:
description: "Szülő hozzáadása a tárgyhoz"
args:
"collection": "az a tárgyi gyűjtemény, ahol a szülő Tárgy"
"subject": "a szülő Tárgy neve"
"contexts...": "a szülő hozzáadásának összefüggései"
sponge-parent-remove:
description: "Eltávolít egy szülőt a tárgytól"
args:
"collection": "az a tárgyi gyűjtemény, ahol a szülő Tárgy"
"subject": "a szülő Tárgy neve"
"contexts...": "a szülő eltávolításának összefüggései"
sponge-parent-clear:
description: "Törli a Tárgyi szülőket"
args:
"contexts...": "a szülők egyértelművé tételének összefüggései"
sponge-option-info:
description: "Megmutatja a tárggyal kapcsolatos információkat"
args:
"contexts...": "a szövegszűrés körülményei"
sponge-option-set:
description: "Beállít egy opciót a Tárgyhoz"
args:
"key": "a beállítani kívánt kulcs"
"value": "a kulcs beállításához"
"contexts...": "az opció beállításához szükséges kontextusok"
sponge-option-unset:
description: "Lefuttat egy opciót a Tárgyhoz"
args:
"key": "a kiiktatás kulcsa"
"contexts...": "a kulcshoz való hozzáférés megszüntetésének kontextusai"
sponge-option-clear:
description: "Törli a Tárgy opciókat"
args:
"contexts...": "a szövegkörnyezetek egyértelművé tételének lehetőségei"
migration-command:
description: "Migrációs parancs"
migration-groupmanager:
description: "Migrációs parancs"
args:
"migrate as global": "ha a világi engedélyeket figyelmen kívül kell hagyni, és csak globális áttérést kell alkalmazni"
migration-powerfulperms:
description: "Migrációs parancs"
args:
"address": "a PP adatbázis címe"
"database": "a PP adatbázis neve"
"username": "a DB-be való bejelentkezéshez használt felhasználónév"
"password": "a DB-be való bejelentkezéshez használt jelszó"
"db table": "a PP tábla neve, ahol a játékos adatait tárolják"
+290
View File
@@ -0,0 +1,290 @@
# LuckPerms Language File
# Locale: pl_PL (Polish)
# Author: dzegarek
prefix: "&7&l[&b&lL&3&lP&7&l] &c"
log-info: "&7&l[&bL&3P&7&l] &3{0}"
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[UWAGA] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[BŁĄD] {0}"
empty: "{0}"
player-online: "&aOnline"
player-offline: "&cOffline"
loading-error: "Nie można załadować danych uprawnień. Spróbuj ponownie później."
op-disabled: "&bSystem vanilla OP jest wyłączony na tym serwerze."
op-disabled-sponge: "&2Stan operatora serwera nie ma wpływu na instalację wtyczki uprawnień. Proszę bezpośrednio edytować dane użytkownika."
log: "&3LOG &3&l> {0}"
export-log: "&3Eksport &3&l> &f{0}"
export-log-progress: "&3Eksport &3&l> &7{0}"
migration-log: "&3MIGRACJA &7[&3{0}&7] &3&l> &f{1}"
migration-log-progress: "&3MIGRACJA &7[&3{0}&7] &3&l> &7{1}"
command-not-recognised: "Komenda nie została rozpoznana."
command-no-permission: "Nie masz uprawnień do korzystania z tego polecenia!"
already-haspermission: "{0} ma już to uprawnienie!"
does-not-havepermission: "{0} nie ma tego zestawu uprawnień."
already-has-temp-permission: "{0} ma już tymczasowo uprawnienie!"
does-not-have-temp-permission: "{0} nie ma tymczasowego zezwolenia."
user-not-found: "&bNie można znaleźć użytkownika."
user-not-online: "&bUżytkownik &a{0}&b nie jest online."
user-save-success: "&7(Dane użytkownika zostały zapisane w pamięci)"
user-save-error: "Podczas zapisywania użytkownika wystąpił błąd."
group-not-found: "&bNie można odnaleźć grupy."
group-save-success: "&7(Dane grupy zostały zapisane w pamięci)"
group-save-error: "Podczas zapisywania grupy wystąpił błąd."
track-not-found: "&bŚcieżka nie została odnaleziona."
track-save-success: "&7(Dane ścieżki zostały zapisane w pamięci)"
track-save-error: "Podczas zapisywania ścieżki wystąpił błąd."
user-invalid-entry: "&d{0}&c nie jest poprawną nazwą użytkownika/uuid."
group-invalid-entry: "Nazwy grup mogą zawierać tylko znaki alfanumeryczne."
track-invalid-entry: "Nazwy dróg mogą zawierać tylko znaki alfanumeryczne."
server-world-invalid-entry: "Nazwy serwerów/świata mogą zawierać znaki alfanumeryczne, ale nie mogą przekraczać 36 znaków."
use-inherit-command: "Użyj komendy 'parent add' lub 'parent remove' zamiast określenia węzła."
verbose-invalid-filter: "&cNieprawidłowy szczegółowy filtr: &f{0}"
verbose-on: "&bZapis szczegółowych plików wyjściowych ustawiony jest na & aTRUE & bdla wszystkich uprawnień."
verbose-on-query: "&bZapis szczegółowych plików wyjściowych ustawiony jest na & aTRUE & bdla wszystkich pasujących do filtra: &f{0}"
verbose-off: "&bZapis szczegółowych plików wyjściowych jest ustawiony na &cFALSE&b."
verbose-recording-on: "&bVerbose recording set to &aTRUE &bfor all permissions."
verbose-recording-on-query: "&bZapis szczegółowych zapisów jest ustawiony na &aTRUE &bdla wszystkich uprawnień pasujących do filtra: &f{0}"
verbose-recording-upload-start: "&Zapis szczegółowych zapisów został wyłączony. Przesyłanie wyników..."
verbose-recording-url: "&aSzczegółowe URL wyników:"
tree-upload-start: "&bGenerowanie drzewa uprawnień..."
tree-empty: "&aNie można wygenerować drzewa. Nie znaleziono żadnych wyników."
tree-url: "&aURL drzewa uprawnień:"
search-searching: "&aPoszukiwanie użytkowników i grup &b{0}&a..."
search-searching-members: "&aWyszukiwanie użytkowników i grup, które dziedziczą &b{0}&a..."
search-result: "&aZnaleziono &b{0}&a wpisy z &b{1}&a użytkowników i &b{2}&a grup."
search-showing-users: "&bWyświetlanie wpisów użytkownika:"
search-showing-groups: "&bWyświetlanie wpisów grup:"
search-showing-users-with-page: "&bWyświetlanie wpisów użytkownika: {0}"
search-showing-groups-with-page: "&bWyświetlanie wpisów grup: {0}"
check-result: "&aWynik sprawdzenia uprawnień dla użytkownika &b{0}&a dla uprawnień &b{1}&a: &f{2}"
create-success: "&b{0}&a został pomyślnie utworzone."
delete-success: "&b{0}&a został pomyślnie usunięty."
rename-success: "&b{0}&a został pomyślnie zmieniony na &b{1}&a."
clone-success: "&b{0}&a został pomyślnie sklonowany na &b{1}&a."
already-inherits: "{0} już dziedziczy '{1}'."
does-not-inherit: "{0} nie dziedziczy '{1}'."
already-temp-inherits: "{0} już tymczasowo dziedziczy '{1}'."
does-not-temp-inherit: "{0} nie dziedziczy tymczasowo '{1}'."
track-already-contains: "Ścieżka {0} zawiera już grupę '{1}'."
track-does-not-contain: "Ścieżka {0} nie zawiera tej grupy '{1}'."
track-ambiguous-call: "Podany użytkownik jest członkiem wielu grup na tej ścieżce. Nie można określić ich lokalizacji."
group-already-exists: "Ta grupa już istnieje!"
group-does-not-exist: "Ta grupa nie istnieje!"
group-load-error: "Wystąpił nieoczekiwany błąd. Grupa nie została załadowana."
groups-load-error: "Wystąpił nieoczekiwany błąd. Nie można załadować wszystkich grup."
track-already-exists: "Ta ścieżka już istnieje!"
track-does-not-exist: "Ta ścieżka nie istnieje!"
track-load-error: "Wystąpił nieoczekiwany błąd. Ścieżka nie została załadowana."
tracks-load-error: "Wystąpił nieoczekiwany błąd. Nie można wczytać wszystkich ścieżek."
track-empty: "Ścieżka nie może być używana jako pusta lub zawierać tylko jedną grupę."
update-task-request: "&bZaktualizuj zaplanowane zadanie."
update-task-complete: "&aZaktualizowano zadanie."
update-task-complete-network: "&aZaktualizowano zadanie. Teraz próbuj wejść na inne serwery."
update-task-push-success: "&aInne serwery zostały powiadomione za pośrednictwem & b {0} wiadomości &apomyślnie."
update-task-push-failure: "&cPodczas przesyłania zmian do innych serwerów wystąpił błąd."
update-task-push-failure-not-setup: "&cPodczas przesyłania zmian do innych serwerów wystąpił błąd. Usługa wiadomości nie została skonfigurowana."
reload-config-success: "&aPlik konfiguracyjny został ponownie załadowany. &7(niektóre opcje będą obowiązywać tylko po ponownym uruchomieniu serwera.)"
info: >
{PREFIX}&2Uruchamianie &bLuckPerms v{0}&2 by &bLuck&2.\n
{PREFIX}&f- &3Platforma: &f{1}\n
{PREFIX}&f- &3Metoda Składowania: &f{2}\n
{PREFIX}&f- &3Nazwa Serwera: &f{3}\n
{PREFIX}&f- &3Synchronizacja Czasu: &a{4} &fminuty\n
{PREFIX}&f- &3Usługa wiadomości: &f{5}\n
{PREFIX}&f- &bLiczba:\n
{PREFIX}&f- &3Online Graczy: &a{6}\n
{PREFIX}&f- &3Załadowanych użytkowników: &a{7}\n
{PREFIX}&f- &3Załadowanych grup: &a{8}\n
{PREFIX}&f- &3Załadowanych Ścieżek: &a{9}\n
{PREFIX}&f- &3Rozmiar Loga: &a{10}\n
{PREFIX}&f- &3Rozmiar pamięci podręcznej UUID: &a{11}\n
{PREFIX}&f- &3Załadowane tłumaczenia: &a{12}\n
{PREFIX}&f- &3Kontrole wstępne: &a{13}\n
{PREFIX}&f- &3Kalkulatory Kontekstu: &a{14}\n
{PREFIX}&f- &3Unikalne uprawnienia: &a{15}\n
{PREFIX}&f- &bKonfiguracja:\n
{PREFIX}&f- &3Używany Server UUIDs: {16}\n
{PREFIX}&f- &bObliczanie uprawnień:\n
{PREFIX}&f- &3Łącznie ze światem: {17}\n
{PREFIX}&f- &3Łącznie z globalnym światem: {18}\n
{PREFIX}&f- &3Stosowanie grup globalnych: {19}\n
{PREFIX}&f- &3Stosowanie Globalnych Grup Światowych: {20}\n
{PREFIX}&f- &3Stosowanie symboli wieloznacznych: {21}\n
{PREFIX}&f- &3Stosowanie Regex: {22}\n
{PREFIX}&f- &3Stosowanie skrótu: {23}
create-group-error: "Podczas tworzenia grupy wystąpił błąd."
delete-group-error: "Podczas usuwania grupy wystąpił błąd."
delete-group-error-default: "Nie można usunąć grupy domyślnej."
groups-list: "&aGrupy: {0}"
create-track-error: "Podczas tworzenia ścieżki wystąpił błąd."
delete-track-error: "Podczas usuwania ścieżki wystąpił błąd."
tracks-list: "&aŚcieżki: {0}"
listnodes: "&b{0}'s Węzły:"
listnodes-with-page: "&b{0}'s Węzły: {1}"
listnodes-temp: >
&b{0}'s Tymczasowe Węzły:\n
{1}
listparents: >
&b{0}'s Grupy Rodzicielskie:\n
{1}
listparents-temp: >
&b{0}'s Tymczasowe Grupy Rodzicielskie:\n
{1}
list-tracks: >
&b{0}'s Ścieżki:\n
{1}
list-tracks-empty: "{0} nie jest na żadnej ścieżce."
context-pair-inline: "&3{0}=&b{1}"
context-pair--global-inline: "&eglobalnie"
context-pair-sep: "&a, "
context-pair: "&8(&7{0}=&f{1}&8)"
check-permission: "&b{0}&a ma uprawnienia &b{1}&a ustawione na {2}&a w kontekście {3}&a."
setpermission-success: "&aUstawiono &b{0}&a na &b{1}&a dla &b{2}&a w kontekście {3}&a."
setpermission-temp-success: "&aUstawiono &b{0}&a na &b{1}&a dla &b{2}&a na czas trwania &b{3}&a w kontekście {4}&a."
unsetpermission-success: "&aUsunięto &b{0}&a dla &b{1}&a w kontekście {2}&a."
unset-temp-permission-success: "&aTymczasowe uprawnienia &b{0}&a dla &b{1}&a w kontekście {2}&a."
set-inherit-success: "&b{0}&a teraz dziedziczy uprawnienia od &b{1}&a w kontekście {2}&a."
set-temp-inherit-success: "&b{0}&a teraz dziedziczy uprawnienia &b{1}&a na czas trwania &b{2}&a w kontekście {3}&a."
set-parent-success: "&b{0}&a gdyby istniejące grupy macierzyste zostały wyczyszczone, a teraz tylko dziedziczą &b{1}&a w kontekście {2}&a."
set-track-parent-success: "&b{0}&a miały istniejące grupy macierzyste na ścieżce &b{1}&a wyczyszczone, a teraz dziedziczą &b{2}&a w kontekście {3}&a."
unset-inherit-success: "&b{0}&a już nie dziedziczy uprawnień &b{1}&a w kontekście {2}&a."
unset-temp-inherit-success: "&b{0}&a przestaje tymczasowo dziedziczyć uprawnienia &b{1}&a w kontekście {2}&a."
clear-success: "&b{0}&a's uprawnienia zostały wyczyszczone w kontekście {1}&a. (&b{2}&a węzły zostały usunięte.)"
clear-success-singular: "&b{0}&a's uprawnienia zostały wyczyszczone w kontekście {1}&a. (&b{2}&a węzeł został usunięty.)"
parent-clear-success: "&b{0}&a's rodzice zostali wyczyszczeni w kontekście {1}&a. &b{2}&a węzły zostały usunięte.)"
parent-clear-success-singular: "&b{0}&a's rodzice zostali wyczyszczeni w kontekście {1}&a. &b{2}&a węzeł został usunięty.)"
parent-clear-track-success: "&b{0}&a's rodzice na ścieżce &b{1}&a zostali wyczyszczeni w kontekście {2}&a. &b{3}&a węzły zostały usunięte.)"
parent-clear-track-success-singular: "&b{0}&a's parents on track &b{1}&a were cleared in context {2}&a. &b{3}&a węzeł został usunięty.)"
meta-clear-success: "&b{0}&a's meta zostały usunięte w kontekście {1}&a. &b{2}&a węzły zostały usunięte.)"
meta-clear-success-singular: "&b{0}&a's meta zostały usunięte w kontekście {1}&a. &b{2}&a węzeł został usunięty.)"
illegal-date-error: "Nie można przeanalizować daty '{0}'."
past-date-error: "W przeszłości nie można ustawić daty!"
chat-meta-prefix-header: "&b{0}'s Prefiksy"
chat-meta-suffix-header: "&b{0}'s Suffiksy"
meta-header: "&b{0}'s Meta"
chat-meta-entry: "&b-> {0} &f- &f\"{1}&f\" &8(&7odziedziczone po &a{2}&8)"
chat-meta-entry-with-context: "&b-> {0} &f- &f\"{1}&f\" &8(&7odziedziczone po &a{2}&8){3}"
meta-entry: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7odziedziczone po &a{2}&8)"
meta-entry-with-context: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7odziedziczone po &a{2}&8){3}"
chat-meta-prefix-none: "&b{0} nie ma prefiksów."
chat-meta-suffix-none: "&b{0} has no suffiksów."
meta-none: "&b{0} nie ma meta."
meta-invalid-priority: "Nieprawidłowy priorytet '{0}'. Spodziewany numer."
already-has-chat-meta: "{0} już to ma {1} ustawione."
does-not-have-chat-meta: "{0} nie ma tego {1} ustawionego."
add-chatmeta-success: "&b{0}&a ma {1} &f\"{2}&f\"&a ustawiony priorytet z &b{3}&a w kontekście {4}&a."
add-temp-chatmeta-success: "&b{0}&a ma {1} &f\"{2}&f\"&a ustawiony priorytet z &b{3}&a na czas trwania &b{4}&a w kontekście {5}&a."
remove-chatmeta-success: "&b{0}&a ma {1} &f\"{2}&f\"&a at priority &b{3}&a removed in context {4}&a."
bulk-remove-chatmeta-success: "&b{0}&a ma cały {1}es na priorytecie &b{2}&a usunięte w kontekście {3}&a."
remove-temp-chatmeta-success: "&b{0}&a ma tymczasowo {1} &f\"{2}&f\"&a at priority &b{3}&a usunięte w kontekście {4}&a."
bulk-remove-temp-chatmeta-success: "&b{0}&a miał wszystkie tymczasowe {1}es na priorytecie &b{2}&a usunięte w kontekście {3}&a."
already-has-meta: "{0} ma już tę parę par kluczy meta."
set-meta-success: "&aUstawiono wartość meta dla klucza &f\"{0}&f\"&a do &f\"{1}&f\"&a dla &b{2}&a w kontekście {3}&a."
set-meta-temp-success: "&aUstawiono wartości meta dla klucza &f\"{0}&f\"&a do &f\"{1}&f\"&a dla &b{2}&a na czas trwania &b{3}&a w kontekście {4}&a."
unset-meta-success: "&aUsunięto wartość meta za pomocą klucza &f\"{0}&f\"&a dla &b{1}&a w kontekście {2}&a."
unset-meta-temp-success: "&aUsunięcie tymczasowej wartości meta za pomocą klucza &f\"{0}&f\"&a dla &b{1}&a w kontekście {2}&a."
bulk-update-invalid-data-type: "Nieprawidłowy typ. Spodziewane 'all', 'users' lub 'groups'."
bulk-update-invalid-constraint: "Nieprawidłowe ograniczenie &4{0}&c. Ograniczenia powinny być w formacie '&f<field> <comparison operator> <value>&c'."
bulk-update-invalid-comparison: "Nieprawidłowy operator porównania '&4{0}&c'. Oczekiwany jeden z poniższych: &f== != ~~ ~!"
bulk-update-queued: "&aOperacja aktualizacji została w kolejce. &7(&f{0}&7)"
bulk-update-confirm: "&aUruchom &b/{0} uaktualnianie zbiorcze {1} &a i wykonaj aktualizacje."
bulk-update-unknown-id: "&aOperacja z id &b{0}&a nie istnieje lub upłynął."
bulk-update-starting: "&aUaktualnianie zbiorcze."
bulk-update-success: "&bAktualizacja zbiorcza powiodła się pomyślnie."
bulk-update-failure: "&cAktualizacja zbiorcza nie powiodła się. Sprawdź, czy konsola nie zawiera błędów."
user-info-general: >
{PREFIX}&b&l> &bInfo Użytkownika: &f{0}\n
{PREFIX}&f- &3UUID: &f{1}\n
{PREFIX}&f- &3Status: {2}\n
{PREFIX}&f- &3Grupa Podstawowa: &f{3}\n
{PREFIX}&f- &aLiczba:\n
{PREFIX}&f- &3Uprawnień: &a{4}\n
{PREFIX}&f- &3Tymczasowych uprawnień: &a{5}\n
{PREFIX}&f- &3Prefiksów: &a{6}\n
{PREFIX}&f- &3Suffiksów: &a{7}\n
{PREFIX}&f- &3Meta: &a{8}
user-info-data: >
{PREFIX}&f- &aDane buforowane:\n
{PREFIX}&f- &3Posiada dane kontekstowe: {0}\n
{PREFIX}&f- &3Obecne konteksty: {1}\n
{PREFIX}&f- &3Obecny Prefiks: {2}\n
{PREFIX}&f- &3Obecny Suffiks: {3}
info-parent-header: "&f- &aGrupy Rodziców:"
info-temp-parent-header: "&f- &aTymczasowe Grupy Rodziców:"
user-removegroup-error-primary: "Nie można usunąć użytkownika z podstawowej grupy."
user-primarygroup-success: "&b{0}&a's pierwsza grupa została ustawiona na &b{1}&a."
user-primarygroup-warn-option: "&cUwaga: Podstawowa metoda obliczania grupy jest używana przez ten serwer &7({0}) &cmoże nie odzwierciedlać tej zmiany."
user-primarygroup-error-alreadyhas: "Użytkownik ma już tę grupę jako pierwszą."
user-primarygroup-error-notmember: "&b{0}&a nie był już użytkownikiem z &b{1}&a, dodając je teraz."
user-track-error-not-contain-group: "Podany przez Ciebie użytkownik nie jest jeszcze w żadnej z grup na tej ścieżce."
user-track-added-to-first: "&b{0}&a nie jest w żadnej grupie na tej ścieżce, więc został dodany do pierwszej grupy, &b{1}&a w kontekście {2}&a."
user-promote-success: "&aPromowanie użytkownika wzdłuż toru &b{0}&a z &b{1}&a do &b{2}&a w kontekście {3}&a."
user-promote-error-endoftrack: "Koniec ścieżki &4{0}&c został osiągnięty. Nie można promować użytkownika."
user-promote-error-malformed: >
{PREFIX}Następna grupa na ścieżce, {0}, już nie istnieje. Nie można promować użytkownika..\n
{PREFIX}Albo utwórz grupę lub usuń ją ze ścieżki i spróbuj ponownie.
user-demote-success: "&aObniżanie użytkownika wzdłuż ścieżki &b{0}&a z &b{1}&a do &b{2}&a w kontekście {3}&a."
user-demote-endoftrack: "Koniec ścieżki &4{0}&c został osiągnięty, więc &4{1}&c zostało usunięte z &4{2}&c."
user-demote-error-malformed: >
{PREFIX}Poprzednia grupa na ścieżce, {0}, już nie istnieje. Nie można obniżyć użytkownika.\n
{PREFIX}Albo utwórz grupę lub usuń ją ze ścieżki i spróbuj ponownie.
group-info-general: >
{PREFIX}&b&l> &bInfo Grupy: &f{0}\n
{PREFIX}&f- &3Wyświetlana Nazwa: &f{1}\n
{PREFIX}&f- &3Rola: &f{2}\n
{PREFIX}&f- &aLiczba:\n
{PREFIX}&f- &3Uprawnienia: &a{3}\n
{PREFIX}&f- &3Tymczasowe Uprawnienia: &a{4}\n
{PREFIX}&f- &3Prefiksy: &a{5}\n
{PREFIX}&f- &3Suffiksy: &a{6}\n
{PREFIX}&f- &3Meta: &a{7}
group-set-weight: "&aSet weight to &b{0}&a for group &b{1}&a."
track-info: >
{PREFIX}&b&l> &bWyświetlanie ścieżki: &f{0}\n
{PREFIX}&f- &7Ścieżka: &f{1}
track-clear: "&b{0}&a grupy zostały usunięte"
track-append-success: "&aGrupa &b{0}&a została z powodzeniem dodana do śledzenia &b{1}&a."
track-insert-success: "&aGrupa &b{0}&a została pomyślnie wstawiona do ścieżki &b{1}&a na pozycji &b{2}&a."
track-insert-error-number: "Przewidywany numer, ale otrzymany: {0}"
track-insert-error-invalid-pos: "Nie można wstawić w pozycji {0}. Wyloguj się z granic."
track-remove-success: "&aGrupa &b{0}&a została z powodzeniem usunięta ze ścieżki &b{1}&a."
log-load-error: "Nie można załadować loga."
log-invalid-page: "Nieprawidłowy numer strony."
log-invalid-page-range: "Nieprawidłowy numer strony. Wprowadź wartość między 1 a {0}."
log-no-entries: "&bBrak wpisów do logów."
log-entry: "&b#{0} -> &8(&7{1} temu&8) {2}"
log-notify-toggle-on: "&aWłączone&b wyjście z logowania."
log-notify-toggle-off: "&cWyłączone&b wyjście z logowania."
log-notify-already-on: "Obecnie otrzymujesz powiadomienia."
log-notify-already-off: "Obecnie nie otrzymujesz powiadomień."
log-notify-unknown: "Stan nieznany. Oczekiwanie na \"on\" lub \"off\"."
log-search-header: "&aWyświetlanie ostatnich działań dotyczących zapytania &b{0} &a(strona &f{1}&a z &f{2}&a)"
log-recent-header: "&aWyświetlanie ostatnich działań (strona &f{0}&a z &f{1}&a)"
log-recent-by-header: "&aPokazanie ostatnich działań przez &b{0} &a(strona &f{1}&a z &f{2}&a)"
log-history-user-header: "&aWyświetlanie historii dla użytkowników &b{0} &a(strona &f{1}&a z &f{2}&a)"
log-history-group-header: "&aWyświetlanie historii dla grup &b{0} &a(strona &f{1}&a z &f{2}&a)"
log-history-track-header: "&aWyświetlanie historii dla ścieżki &b{0} &a(strona &f{1}&a z &f{2}&a)"
log-export-already-exists: "Błąd: Plik {0} już istnieje."
log-export-not-writable: "Błąd: Plik {0} jest tylko do odczytu."
log-export-empty: "Log jest pusty i dlatego nie może być eksportowany"
log-export-failure: "Podczas zapisywania do pliku wystąpił nieoczekiwany błąd."
log-export-success: "&aPomyślnie exportowano log do &b{0}&a."
import-already-running: "Inny proces importowania jest już uruchomiony. Spróbuj ponownie później."
export-already-running: "Inny proces eksportowania jest już uruchomiony. Spróbuj ponownie później."
import-log-doesnt-exist: "Błąd: Plik {0} nie istnieje."
import-log-not-readable: "Błąd: Plik {0} nie można odczytać."
import-log-failure: "Podczas odtwarzania loga wystąpił nieoczekiwany błąd."
import-progress: "&b(Import) &b-> &f{0} &fprocent kompletne &7- &b{1}&f/&b{2} &foperacja zakończona z &c{3} &fbłędami."
import-progress-sin: "&b(Import) &b-> &f{0} &fprocent kompletne &7- &b{1}&f/&b{2} &foperacja zakończona z &c{3} &fbłędami."
import-start: "&b(Import) &b-> &fUruchamianie procesu importowania."
import-end-complete: "&b(Import) &a&lZAKOŃCZONE &7- zajęło &b{0} &7sekundy - &7Nie ma błędów."
import-end-complete-err: "&b(Import) &a&lZAKOŃCZONE &7- zajęło &b{0} &7sekundy - &c{1} błędy."
import-end-complete-err-sin: "&b(Import) &a&lZAKOŃCZONE &7- zajęło &b{0} &7sekundy - &c{1} błąd."
import-end-error-header: >
{PREFIX}&b(Import) &7------------> &fWyświetlanie błędu #&b{0} &7<------------\n
{PREFIX}&b(Import) &fWykonując: &3Komende #{1}\n
{PREFIX}&b(Import) &fKomenda: &7{2}\n
{PREFIX}&b(Import) &fWpisane: &3{3}\n
{PREFIX}&b(Import) &fWyjście:
import-end-error-content: "&b(Import) &b-> &c{0}"
import-end-error-footer: "&b(Import) &7<------------------------------------------>"
+303
View File
@@ -0,0 +1,303 @@
# LuckPerms Language File
# Locale: ru_RU
# Author: Pixelmon.PRO
prefix: "&7&l[&b&lL&3&lP&7&l] &c"
log-info: "&7&l[&bL&3P&7&l] &3{0}"
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[ПРЕДУПРЕЖДЕНИЕ] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[ОШИБКА] {0}"
empty: "{0}"
player-online: "&aОнлайн"
player-offline: "&cОффлайн"
loading-error: "Не удалось загрузить данные разрешений. Пожалуйста обратитесь к Администратору."
op-disabled: "&bНа этом сервере отключена ванильная система OP."
op-disabled-sponge: "&2Статус Оператора Сервера не влияет на установленный плагин разрешений. Пожалуйста, отредактируйте данные пользователя напрямую."
log: "&3LOG &3&l> {0}"
export-log: "&3ЭКСПОРТ &3&l> &f{0}"
export-log-progress: "&3ЭКСПОРТ &3&l> &7{0}"
migration-log: "&3ПЕРЕМЕЩЕНИЕ &7[&3{0}&7] &3&l> &f{1}"
migration-log-progress: "&3ПЕРЕМЕЩЕНИЕ &7[&3{0}&7] &3&l> &7{1}"
command-not-recognised: "Команда не распознана."
command-no-permission: "У вас нет разрешения на использование этой команды!"
already-haspermission: "{0} уже имеет такое разрешение!"
does-not-havepermission: "{0} не имеет этого набора разрешений."
already-has-temp-permission: "{0} уже имеет этот набор временных разрешений!"
does-not-have-temp-permission: "{0} не имеет этого набора временных разрешений."
user-not-found: "&bНе удалось найти пользователя."
user-not-online: "&bПользователь &a{0}&b не онлайн."
user-no-data: "&bПользователь &a{0}&b не имеет загруженных данных."
user-save-success: "&7(Пользовательские данные были сохранены на хранение)"
user-save-error: "При сохранении пользователя произошла ошибка."
user-create-fail: "При создании нового пользователя возникла ошибка."
group-not-found: "&bНе удалось найти группу."
group-save-success: "&7(Групповые данные были сохранены на хранение)"
group-save-error: "При сохранении группы произошла ошибка."
track-not-found: "&bНе удалось найти путь."
track-save-success: "&7(Данные о путе сохранены на хранение)"
track-save-error: "При сохранении пути произошла ошибка."
user-invalid-entry: "&d{0}&c не является допустимым именем пользователя/uuid."
group-invalid-entry: "Имена групп могут содержать только буквенно-цифровые символы."
track-invalid-entry: "Имена путей могут содержать только буквенно-цифровые символы."
server-invalid-entry: "Имена серверов могут содержать только буквенно-цифровые символы."
use-inherit-command: "Используйте команды «parent add» и «parent remove» вместо указания узла (node)."
verbose-invalid-filter: "&cНедопустимый подробный (verbose) фильтр: &f{0}"
verbose-on: "&Запись подробной проверки установлена на &aTRUE &bдля всех разрешений (пермов)."
verbose-on-query: "&Запись подробной проверки установлена на &aTRUE &bДля разрешений, соответствующих следующим фильтрам: &f{0}"
verbose-off: "&Запись подробной проверки установлена на &cFALSE&b."
verbose-recording-on: "&Запись подробной записи установлена ​​на &aTRUE &bдля всех разрешений."
verbose-recording-on-query: "&Запись подробной записи установлена ​​на &aTRUE &bДля разрешений, соответствующих следующим фильтрам: &f{0}"
verbose-recording-upload-start: "&bЗапись подробной информации была отключена. Загрузка результатов..."
verbose-recording-url: "&aПодробный URL результатов:"
tree-upload-start: "&bСоздание дерева разрешений..."
tree-empty: "&aНе удалось создать дерево. Ничего не найдено."
tree-url: "&aURL дерева разрешений:"
search-searching: "&aПоиск пользователей и групп с помощью &b{0}&a..."
search-searching-members: "&aПоиск пользователей и групп, унаследовавших от &b{0}&a..."
search-result: "&aНайдено &b{0}&a записи из &b{1}&a пользователей и &b{2}&a групп."
search-showing-users: "&bПросмотр записей пользователя:"
search-showing-groups: "&bПросмотр записей в группах:"
search-showing-users-with-page: "&bПросмотр записей пользователя: {0}"
search-showing-groups-with-page: "&bПросмотр записей в группах: {0}"
check-result: "&aРезультат проверки разрешения пользователя &b{0}&a на разрешение &b{1}&a: &f{2}"
create-success: "&b{0}&a было успешно создано."
delete-success: "&b{0}&a успешно удален."
rename-success: "&b{0}&a был успешно переименован в &b{1}&a."
clone-success: "&b{0}&a был успешно клонирован на &b{1}&a."
already-inherits: "{0} уже наследует '{1}'."
does-not-inherit: "{0} не наследует '{1}'."
already-temp-inherits: "{0} уже временно наследует '{1}'."
does-not-temp-inherit: "{0} временно не наследует '{1}'."
track-already-contains: "Путь {0} уже содержит группу '{1}'."
track-does-not-contain: "Путь {0} не содержит группу '{1}'."
track-ambiguous-call: "Указанный пользователь является членом нескольких групп на этом пути. Невозможно определить их местоположение."
group-already-exists: "Эта группа уже существует!"
group-does-not-exist: "Эта группа не существует!"
group-load-error: "Произошла непредвиденная ошибка. Группа не загружена."
groups-load-error: "Произошла непредвиденная ошибка. Не удалось загрузить все группы."
track-already-exists: "Этот путь уже существует!"
track-does-not-exist: "Этот путь не существует!"
track-load-error: "Произошла непредвиденная ошибка. Путь не загружен."
tracks-load-error: "Произошла непредвиденная ошибка. Не удалось загрузить все пути."
track-empty: "Путь нельзя использовать, так как он пуст или содержит только одну группу."
update-task-request: "&bОбновление задачи запланировано."
update-task-complete: "&aОбновление задачи завершено."
update-task-complete-network: "&aОбновление задачи завершено. Теперь пытаемся подключиться к другим серверам."
update-task-push-success: "&aДругие серверы были уведомлены через &b{0} cообщения и удаленный доступ."
update-task-push-failure: "&cОшибка при нажатии изменений на других серверах."
update-task-push-failure-not-setup: "&cОшибка при нажатии изменений на других серверах. Служба обмена сообщениями не настроена."
reload-config-success: "&aФайл конфигурации был перезагружен. &7(Некоторые параметры будут применяться только после перезапуска сервера.)"
info: >
{PREFIX}&2Выполнение &bLuckPerms v{0}&2 by &bLuck&2.\n
{PREFIX}&f- &3Платформа: &f{1}\n
{PREFIX}&f- &3Способ Хранения: &f{2}\n
{PREFIX}&f- &3Имя Сервера: &f{3}\n
{PREFIX}&f- &3Интервал Синхронизации: &a{4} &fминут\n
{PREFIX}&f- &3Служба обмена сообщениями: &f{5}\n
{PREFIX}&f- &bГрафы:\n
{PREFIX}&f- &3Игроки Онлайн: &a{6}\n
{PREFIX}&f- &3Загруженные пользователи: &a{7}\n
{PREFIX}&f- &3Загруженные группы: &a{8}\n
{PREFIX}&f- &3Загруженные пути: &a{9}\n
{PREFIX}&f- &3Размер лога: &a{10}\n
{PREFIX}&f- &3UUID Размер кеша: &a{11}\n
{PREFIX}&f- &3Переводы загружены: &a{12}\n
{PREFIX}&f- &3Контексты перед обработкой: &a{13}\n
{PREFIX}&f- &3Счетчик контекста: &a{14}\n
{PREFIX}&f- &3Уникальные разрешения: &a{15}\n
{PREFIX}&f- &bКонфигурация:\n
{PREFIX}&f- &3Использует сервер UUIDs: {16}\n
{PREFIX}&f- &bСчетчик разрешений:\n
{PREFIX}&f- &3Включая глобальные: {17}\n
{PREFIX}&f- &3Включая глобальный мир: {18}\n
{PREFIX}&f- &3Применения глобальных групп: {19}\n
{PREFIX}&f- &3Применения глобальных групп мира: {20}\n
{PREFIX}&f- &3Применения подстановочных знаков (Wildcards): {21}\n
{PREFIX}&f- &3Применение регулярных выражений: {22}\n
{PREFIX}&f- &3Применение стенографии (Shorthand): {23}
create-group-error: "При создании группы произошла ошибка."
delete-group-error: "При удалении группы произошла ошибка."
delete-group-error-default: "Вы не можете удалить группу по умолчанию."
groups-list: "&aГруппы: {0}"
create-track-error: "При создании пути произошла ошибка."
delete-track-error: "При удалении пути произошла ошибка."
tracks-list: "&aГенеральные пути: {0}"
listnodes: "&b{0}'s Узлы:"
listnodes-with-page: "&b{0}'s Узлы: {1}"
listnodes-temp: >
&b{0}'s Временные узлы:\n
{1}
listparents: >
&b{0}'s Родительские группы:\n
{1}
listparents-temp: >
&b{0}'s Временные родительские группы:\n
{1}
listgroups: >
&b{0}'s Группы:\n
{1}
listgroups-temp: >
&b{0}'s Временные группы:\n
{1}
list-tracks: >
&b{0}'s Пути:\n
{1}
list-tracks-empty: "{0} не на каких-либо путях."
context-pair-inline: "&3{0}=&b{1}"
context-pair--global-inline: "&eГлобальный"
context-pair-end: "&a."
context-pair-sep: "&a, "
context-pair: "&8(&7{0}=&f{1}&8)"
check-permission: "&b{0}&a имеет разрешение &b{1}&a установленое в {2}&a в контексте {3}&a."
check-permission-inherited: "&b{0}&a имеет разрешение &b{1}&a установленое в {2}&a в контексте {3}&a, наследованный от &b{4}&a."
setpermission-success: "&aУстановить &b{0}&a к &b{1}&a для &b{2}&a."
setpermission-temp-success: "&aУстановить &b{0}&a к &b{1}&a для &b{2}&a На срок &b{3}&a."
unsetpermission-success: "&aСбросить &b{0}&a для &b{1}&a."
unset-temp-permission-success: "&aСбросить временное разрешение &b{0}&a для &b{1}&a."
set-inherit-success: "&b{0}&a теперь наследует разрешения от &b{1}&a."
set-parent-success: "&b{0}&a их существующие родительские группы очищены, и теперь только наследуют &b{1}&a."
set-temp-inherit-success: "&b{0}&a теперь наследует разрешения от &b{1}&a на срок &b{2}&a."
unset-inherit-success: "&b{0}&a больше не наследует разрешения от &b{1}&a."
unset-temp-inherit-success: "&b{0}&a больше не наследует временные разрешения (пермы) &b{1}&a."
clear-success: "&b{0}&a's разрешения были очищены. (&b{1}&a узлы были удалены.)"
clear-success-singular: "&b{0}&a's разрешения были очищены. (&b{1}&a узел удален.)"
parent-clear-success: "&b{0}&a's родители очищены. (&b{1}&a узлы были удалены.)"
parent-clear-success-singular: "&b{0}&a's родители очищены. (&b{1}&a узел удален.)"
meta-clear-success: "&b{0}&a's мета очищена. (&b{1}&a узлы были удалены.)"
meta-clear-success-singular: "&b{0}&a's мета очищена. (&b{1}&a узел удален.)"
illegal-date-error: "Не удалось выполнить синтаксический анализ даты '{0}'."
past-date-error: "Вы не можете установить дату в прошлом!"
chat-meta-prefix-header: "&b{0}'s Префиксы"
chat-meta-suffix-header: "&b{0}'s Суффиксы"
meta-header: "&b{0}'s Мета"
chat-meta-entry: "&b-> {0} &f- &f\"{1}&f\" &8(&7унаследованный от &a{2}&8)"
chat-meta-entry-with-context: "&b-> {0} &f- &f\"{1}&f\" &8(&7унаследованный от &a{2}&8){3}"
meta-entry: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7унаследованный от &a{2}&8)"
meta-entry-with-context: "&b-> &a{0} &f= &f\"{1}&f\" &8(&7унаследованный от &a{2}&8){3}"
chat-meta-prefix-none: "&b{0} не имеет префиксов."
chat-meta-suffix-none: "&b{0} не имеет суффиксов."
meta-none: "&b{0} не имеет мету."
meta-invalid-priority: "Недопустимый приоритет '{0}'. Ожидается число."
already-has-chat-meta: "{0} уже имеет этот {1}."
does-not-have-chat-meta: "{0} не имеет этого {1}."
add-chatmeta-success: "&b{0}&a имеет {1} &f\"{2}&f\"&a установлен в приоритете &b{3}&a в контексте {4}&a."
add-temp-chatmeta-success: "&b{0}&a имеет {1} &f\"{2}&f\"&a установлен в приоритете &b{3}&a на срок &b{4}&a в контексте {5}&a."
remove-chatmeta-success: "&b{0}&a имеет {1} &f\"{2}&f\"&a в приоритете &b{3}&a удален из контекста {4}&a."
bulk-remove-chatmeta-success: "&b{0}&a все временные {1}es в приоритете &b{3}&a были удалены из контекста {4}&a."
remove-temp-chatmeta-success: "&b{0}&a временно установленный {1} &f\"{2}&f\"&a в приоритете &b{3}&a был удален из контекста {4}&a."
bulk-remove-temp-chatmeta-success: "&b{0}&a все временные {1}es в приоритете &b{3}&a были удалены из контекста {4}&a."
already-has-meta: "{0} уже установлено, что установлена ​​пара мета-значения клавиши."
set-meta-success: "&aУстановить метазначение для клавиши &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a."
set-meta-temp-success: "&aУстановить метазначение для клавиши &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a на срок &b{3}&a."
unset-meta-success: "&aСбросить метазначение с помощью клавиши &f\"{0}&f\"&a для &b{1}&a."
unset-meta-temp-success: "&aСбросить временное мета-значение с помощью клавиши &f\"{0}&f\"&a для &b{1}&a."
bulk-update-invalid-data-type: "Недопустимый тип. Выберите 'all', 'users' или 'groups'."
bulk-update-invalid-constraint: "Недопустимое ограничение &4{0}&c. Ограничения должны быть в формате '&f<поле> <оператор сравнения> <значение>&c'."
bulk-update-invalid-comparison: "Недопустимый оператор сравнения '&4{0}&c'. Выберите одно из следующих: &f== != ~~ ~!"
bulk-update-queued: "&aМассовое обновление было поставлено в очередь. &7(&f{0}&7)"
bulk-update-confirm: "&aВведите &b/{0} bulkupdate confirm {1} &aчтобы подтвердить выполнение массового обновления."
bulk-update-unknown-id: "&aОперация с id &b{0} &aне существует или истек срок действия."
bulk-update-starting: "&aВыполнение массового обновления."
bulk-update-success: "&bМассовое обновление успешно завершено."
bulk-update-failure: "&cНе удалось выполнить массовое обновление. Проверьте консоль на наличие ошибок."
bulk-change-type-error: "Недопустимый тип. Введите 'server' или 'world'."
bulk-change-success: "&aПрименение изменения успешно. {0} записей изменено."
user-info-general: >
{PREFIX}&b&l> &bИнформация о пользователе: &f{0}\n
{PREFIX}&f- &3UUID: &f{1}\n
{PREFIX}&f- &3Статус: {2}\n
{PREFIX}&f- &3Первичная группа: &f{3}\n
{PREFIX}&f- &aГрафы:\n
{PREFIX}&f- &3Разрешения: &a{4}\n
{PREFIX}&f- &3Временные разрешения: &a{5}\n
{PREFIX}&f- &3Префиксы: &a{6}\n
{PREFIX}&f- &3Суффиксы: &a{7}\n
{PREFIX}&f- &3Мета: &a{8}
user-info-data: >
{PREFIX}&f- &aКэшированные данные:\n
{PREFIX}&f- &3Загружается: {0}\n
{PREFIX}&f- &3Текущие контексты: {1}\n
{PREFIX}&f- &3Текущие префиксы: {2}\n
{PREFIX}&f- &3Текущие суффиксы: {3}
info-parent-header: "&f- &aРодительские группы:"
info-temp-parent-header: "&f- &aВременные родительские группы:"
user-getuuid: "&bUUID для &b{0}&b это &b{1}&b."
user-removegroup-error-primary: "Вы не можете удалить пользователя из своей основной группы."
user-primarygroup-success: "&b{0}&a's для основной группы установил значение &b{1}&a."
user-primarygroup-warn-option: "&cВнимание: метод расчета основной группы, используемый этим сервером &7({0}) &cМожет не отражать это изменение."
user-primarygroup-error-alreadyhas: "Пользователь уже установил эту группу в качестве основной группы."
user-primarygroup-error-notmember: "&b{0}&a еще не был членом &b{1}&a, Добавить его сейчас."
user-track-error-not-contain-group: "Указанный пользователь не находится ни в каких группах на этом пути."
user-track-added-to-first: "&b{0}&a не находится ни в каких группах на этом треке, поэтому они были добавлены в первую группу &b{1}&a в контексте {2}&a."
user-promote-success: "&aПовышение пользователя &b{0}&a от &b{1}&a к &b{2}&a в контексте {3}&a."
user-promote-error-endoftrack: "Конец пути &4{0}&c, был достигнут. Не удалось повысить пользователя."
user-promote-error-malformed: >
{PREFIX}Следующая группа на пути, {0}, более не существует. Не удалось продвинуть пользователя.\n
{PREFIX}Создайте группу или удалите ее с пути и повторите попытку.
user-demote-success: "&aПонижение пользователя по пути &b{0}&a от &b{1}&a к &b{2}&a в контексте {3}&a."
user-demote-endoftrack: "Конец пути &4{0}&c был достингут, поэтому &4{1}&c был удален из &4{2}&c."
user-demote-error-malformed: >
{PREFIX}Предыдущая группа на пути, {0}, более не существуют. Невозможно понизить рейтинг пользователя.\n
{PREFIX}Создайте группу или удалите ее с пути и повторите попытку.
user-showpos: >
&aпоказывает &b{0}&a's позицию на пути &b{1}&a.\n
{2}
group-info-general: >
{PREFIX}&b&l> &bИнфо о группе: &f{0}\n
{PREFIX}&f- &3Отображаемое имя: &f{1}\n
{PREFIX}&f- &3Значение: &f{2}\n
{PREFIX}&f- &aГрафы:\n
{PREFIX}&f- &3Разрешения: &a{3}\n
{PREFIX}&f- &3Временные разрешения: &a{4}\n
{PREFIX}&f- &3Префиксы: &a{5}\n
{PREFIX}&f- &3Суффиксы: &a{6}\n
{PREFIX}&f- &3Мета: &a{7}
group-set-weight: "&aУстановить значение &b{0}&a для группы &b{1}&a."
track-info: >
{PREFIX}&b&l> &bПоказать путь: &f{0}\n
{PREFIX}&f- &7Путь: &f{1}
track-clear: "&b{0}&a's путь групп был очищен."
track-append-success: "&aГруппа &b{0}&a успешно добавлен в путь &b{1}&a."
track-insert-success: "&aГруппа &b{0}&a был успешно добавлен в путь &b{1}&a на позиции &b{2}&a."
track-insert-error-number: "Ожидаемое число, но вместо этого получено: {0}"
track-insert-error-invalid-pos: "Невозможно вставить в позицию {0}. Индекс вне пределов."
track-remove-success: "&aГруппа &b{0}&a Успешно удален с пути &b{1}&a."
log-load-error: "Не удалось загрузить лог."
log-invalid-page: "Недействительный номер страницы."
log-invalid-page-range: "Недопустимый номер страницы. Введите значение от 1 до {0}."
log-no-entries: "&bНет логов для отображения."
log-entry: "&b#{0} -> &8(&7{1} тому назад&8) {2}"
log-notify-toggle-on: "&aВключен&b вывод лога."
log-notify-toggle-off: "&cОтключен&b вывод лога."
log-notify-already-on: "Вы уже получаете оповещения."
log-notify-already-off: "Вы не получаете оповещений."
log-notify-unknown: "Состояние неизвестно. Ожидание \"on\" или \"off\"."
log-search-header: "&aПросмотр недавних действий для запроса &b{0} &a(страница &f{1}&a из &f{2}&a)"
log-recent-header: "&aПоследние действия (страница &f{0}&a из &f{1}&a)"
log-recent-by-header: "&aПоказывать последние действия &b{0} &a(страница &f{1}&a из &f{2}&a)"
log-history-user-header: "&aОтображение истории для пользователя &b{0} &a(страница &f{1}&a из &f{2}&a)"
log-history-group-header: "&aОтображение истории для группы &b{0} &a(страница &f{1}&a из &f{2}&a)"
log-history-track-header: "&aОтображение истории для пути &b{0} &a(страница &f{1}&a из &f{2}&a)"
log-export-already-exists: "Ошибка: файл {0} уже существует."
log-export-not-writable: "Ошибка: файл {0} недоступен для записи."
log-export-empty: "Логи пусты и поэтому не могут быть экспортированы."
log-export-failure: "Произошла непредвиденная ошибка во время записи в файл."
log-export-success: "&aФайл логов успешно экспортирован в &b{0}&a."
import-already-running: "Другой процесс импорта уже запущен. Дождитесь завершения и повторите попытку."
export-already-running: "Другой процесс экспорта уже запущен. Дождитесь завершения и повторите попытку."
import-log-doesnt-exist: "Ошибка: файл {0} не существует."
import-log-not-readable: "Ошибка: файл {0} не читается."
import-log-failure: "Произошла непредвиденная ошибка при чтении лога."
import-progress: "&b(Импортировать) &b-> &f{0} &fПроцент завершен &7- &b{1}&f/&b{2} &fОперации в комплекте с &c{3} &fошибками."
import-progress-sin: "&b(Импортировать) &b-> &f{0} &fПроцент завершен &7- &b{1}&f/&b{2} &fОперации в комплекте с &c{3} &fошибками."
import-start: "&b(Импортировать) &b-> &fЗапуск процесса импорта."
import-end-complete: "&b(Импортировать) &a&lЗАВЕРШЕНО &7- заняло &b{0} &7секунд - &7Нет ошибок."
import-end-complete-err: "&b(Импортировать) &a&lЗАВЕРШЕНО &7- заняло &b{0} &7секунд - &c{1} ошибок."
import-end-complete-err-sin: "&b(Импортировать) &a&lЗАВЕРШЕНО &7- заняло &b{0} &7секунд - &c{1} ошибок."
import-end-error-header: >
{PREFIX}&b(Import) &7------------> &fОтображение ошибки #&b{0} &7<------------\n
{PREFIX}&b(Import) &fВыполняя: &3Команду #{1}\n
{PREFIX}&b(Import) &fКоманда: &7{2}\n
{PREFIX}&b(Import) &fТип: &3{3}\n
{PREFIX}&b(Import) &fВывод:
import-end-error-content: "&b(Импортировать) &b-> &c{0}"
import-end-error-footer: "&b(Импортировать) &7<------------------------------------------>"
+728
View File
@@ -0,0 +1,728 @@
# LuckPerms Language File
# Locale: zh-CN (Simplified Chinese)
# Author: EuropeJing
prefix: "&7&l[&b&lL&3&lP&7&l] &c"
empty: "{0}"
player-online: "&a在线"
player-offline: "&c离线"
loading-error: "&c权限数据无法加载,请稍后再试。"
op-disabled: "&b此服务器上禁用了vanilla OP系统。"
op-disabled-sponge: "&2请注意,当安装权限插件时,服务器OP状态无效。请直接编辑用户数据。"
log-info: "&7&l[&bL&3P&7&l] &3{0}"
log-warn: "&7&l[&bLuck&3Perms&7&l] &c[警告] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[错误] {0}"
log: "&3日志 &3&l> {0}"
verbose-log: "&3详细 &3&l> {0}"
export-log: "&3输出 &3&l> &f{0}"
export-log-progress: "&3输出 &3&l> &7{0}"
migration-log: "&3移动 &7[&3{0}&7] &3&l> &f{1}"
migration-log-progress: "&3移动 &7[&3{0}&7] &3&l> &7{1}"
command-not-recognised: "&c命令未被识别。"
command-no-permission: "&c你没有权限使用这个命令!"
user-not-found: "&c找不到用户&4{0}&c。"
user-not-online: "&a用户&b{0}&a不在线。"
user-save-error: "&c保存用户&4{0}&c数据时出错。"
group-not-found: "&b找不到名为&4{0}&c的组。"
group-save-error: "&c保存组&4{0}&c数据时出错。"
track-not-found: "&b无法找到为&4{0}&c的权限组轨道。"
track-save-error: "&c保存权限组轨道&4{0}&c时出错。"
user-invalid-entry: "&4{0}&c不是有效的用户名/uuid。"
group-invalid-entry: "&4{0}&c不是有效的组名称。"
track-invalid-entry: "&4{0}&c不是有效的权限组轨道名称。"
server-world-invalid-entry: "&c服务器/世界名称只能包含字母数字字符,长度不能超过36个字符。"
use-inherit-command: "&c使用'parent add'和'parent remove'命令,而不是指定节点。"
verbose-invalid-filter: "&4{0}&c不是有效的详细过滤器"
verbose-on: "&b将匹配过滤器:&aANY&b的权限详细输出设置为&a开&b。"
verbose-on-query: "&b将匹配过滤器:&a{0}&b的权限详细输出设置为&a开&b。"
verbose-off: "&b详细输出设置为&c关&b。"
verbose-recording-on: "&b将匹配过滤器:&aANY&b的权限详细记录设置为&a开&b。"
verbose-recording-on-query: "&b将匹配过滤器:&a{0}&b的权限详细记录设置为&a开&b。"
verbose-upload-start: "&b详细记录被禁用。正在上传结果..."
verbose-results-url: "&a详细结果的网址:"
tree-upload-start: "&b生成权限树..."
tree-empty: "&c无法生成树,没有找到结果。"
tree-url: "&a权限树网址:"
search-searching: "&a使用&b{0}&a搜索用户和组..."
search-searching-members: "&a正在搜索继承自&b{0}&a的用户和组..."
search-result: "&a从&b{1}&a用户和&b{2}&a组找到&b{0}&a个条目。"
search-showing-users: "&b显示用户条目:"
search-showing-groups: "&b显示组条目:"
search-showing-users-with-page: "&b显示用户条目: {0}"
search-showing-groups-with-page: "&b显示组条目: {0}"
apply-edits-invalid-code: "&c无效的代码。&7({0})"
apply-edits-unable-to-read: "&c无法使用给定代码读取数据。&7({0})"
apply-edits-no-target: "&c无法解析编辑的目标。请提供它作为一个额外的参数。"
apply-edits-target-group-not-exists: "&c目标组&4{0}&c不存在。"
apply-edits-target-user-not-uuid: "&c目标用户&4{0}&c不是一个有效的uuid。"
apply-edits-target-user-unable-to-load: "&c无法加载目标用户&4{0}&c。"
apply-edits-target-unknown: "&c目标无效。&7({0})"
apply-edits-success: "&a成功应用&b{0}&a节点到&b{1}&a。"
editor-upload-failure: "&c无法将权限数据上传到编辑器。"
editor-url: "&a编辑器URL:"
check-result: "&a用户&b{0}&a获得允许&b{1}&a权限的检查结果&a: &f{2}"
create-success: "&b{0}&a创建成功。"
delete-success: "&b{0}&a删除成功。"
rename-success: "&b{0}&a成功被重命名为&b{1}&a。"
clone-success: "&b{0}&a成功地复制到&b{1}&a。"
already-inherits: "&b{0}&a已经从环境&b{2}&a中继承&b{1}&a。"
does-not-inherit: "&b{0}&a不再从环境&b{2}&a中继承&b{1}&a。"
already-temp-inherits: "&b{0}&a已经从环境&b{2}&a中临时继承&b{1}&a。"
does-not-temp-inherit: "&b{0}&a不再从环境&b{2}&a中临时继承&b{1}&a。"
track-already-contains: "&a权限组轨道&b{0}&a已经包含组&b{1}&a。"
track-does-not-contain: "&a权限组轨道&b{0}&a不包含组&b{1}&a。"
track-ambiguous-call: "&c用户&4{0}&c是此权限组轨道上多个组的成员,无法确定他们的位置。"
already-exists: "&4{0}&c已存在!"
does-not-exist: "&4{0}&c不存在!"
group-load-error: "&c发生意外错误,组未加载。"
groups-load-error: "&c发生意外错误,无法加载所有组。"
track-load-error: "&c发生意外错误。权限组轨道未加载。"
tracks-load-error: "&c发生意外错误,无法加载所有权限组轨道。"
track-empty: "&c权限组轨道&4{0}&c不能使用,因为它是空的或只包含一个组。"
update-task-request: "&b已请求更新任务。请稍候..."
update-task-complete: "&a更新任务完成。"
update-task-complete-network: "&a更新任务完成,现在尝试推送到其他服务器。"
update-task-push-success: "&a其他服务器通过&b{0}消息传递成功通知。"
update-task-push-failure: "&c将更改推送到其他服务器时出错。"
update-task-push-failure-not-setup: "&c将更改推送到其他服务器时出错。&7(未配置消息传递服务)"
reload-config-success: "&a重新加载配置文件。&7(一些选项将仅在服务器重新启动后才应用)"
info-top: >
{PREFIX}&2运行 &bLuckPerms v{0}&2 by &bLuck&2。\n
{PREFIX}&f- &3平台: &f{1}\n
{PREFIX}&f- &3服务器型号: &f{2}\n
{PREFIX}&f- &3服务器版本: &f{3}
info-middle: >
{PREFIX}&f- &3消息类型: &f{0}\n
{PREFIX}&f- &b详情:\n
{PREFIX}&f- &3服务器名称: &f{1}\n
{PREFIX}&f- &3在线玩家: &a{2}\n
{PREFIX}&f- &3唯一连接: &a{3}\n
{PREFIX}&f- &3正常运行时间: &7{4}\n
{PREFIX}&f- &3本地数据: &a{5}&7用户,&a{6}&7组,&a{7}&7权限组轨道\n
{PREFIX}&f- &3环境统计: &a{8}\n
{PREFIX}&f- &3已知权限: &a{9}\n
{PREFIX}&f- &3活动处理器: &7{10}
create-group-error: "&c创建组&4{0}&c时出错。"
delete-group-error: "&c删除组&4{0}&c时出错。"
delete-group-error-default: "&c你不能删除默认组。"
groups-list: "&a组: &7(名字,权重,权限组轨道)"
groups-list-entry: "&f- &3{0} &7- &b{1}"
groups-list-entry-with-tracks: "&f- &3{0} &7- &b{1} &7- [&3{2}&7]"
tracks-list: "&a权限组轨道: {0}"
listnodes: "&b{0}的权限:"
listnodes-with-page: "&b{0}的权限: {1}"
listnodes-temp: "&b{0}的临时权限:"
listnodes-temp-with-page: "&b{0}的临时权限: {1}"
listparents: "&b{0}的父组"
listparents-temp: "&b{0}的临时父组:"
list-tracks: >
&b{0}的权限组轨道:\n
{1}
list-tracks-empty: "&b{0}&a不在任何权限组轨道上。"
context-pair-inline: "&3{0}=&b{1}"
context-pair--global-inline: "&e全局"
context-pair-sep: "&a,"
context-pair: "&8(&7{0}=&f{1}&8)"
check-permission: "&b在环境&b{3}&b中,&b{0}&b的权限&b{1}&b被设置为&b{2}&b。"
check-inherits-permission: "&a在环境&b{3}&a中将&b{0}&a的&b{1}&a权限设置为&b{2}&a。&7(从&a{4}&7继承)"
setpermission-success: "&a在环境&b{3}&a中将&b{2}&a的&b{0}&a权限设置为&b{1}&a。"
already-haspermission: "&a在环境&b{2}&a中&b{0}&a已经设置权限&b{1}&a。"
setpermission-temp-success: "&a在环境&b{4}&a中将&b{2}&a的&b{0}&a临时权限设为&b{1}&a,持续时间&b{3}&a。"
already-has-temp-permission: "&a在环境&b{2}&a中&b{0}&a已经设置临时权限&b{1}&a。"
unsetpermission-success: "&a在环境&b{2}&a中取消&b{1}&a的&b{0}&a权限。"
does-not-have-permission: "&a在环境&b{2}&a中&b{0}&a没有设置权限&b{1}&a。"
unset-temp-permission-success: "&a在环境&b{2}&a中取消&b{1}&a的临时权限&b{0}&a。"
does-not-have-temp-permission: "&a在环境&b{2}&a中&b{0}&a没有设置临时权限&b{1}&a。"
set-inherit-success: "&b{0}&a现在在环境&b{2}&a中继承&b{1}&a的权限&a。"
set-temp-inherit-success: "&b{0}&a现在在环境&b{3}&a中继承&b{1}&a的权限,持续时间&b{2}&a。"
set-parent-success: "&b{0}&a现有的父组被清除,现在只在&b{2}&a中继承&b{1}&a。"
set-track-parent-success: "在权限组轨道&b{1}&a上&b{0}&a现有的父组被清除,现在只在&b{3}&a中继承&b{2}&a。"
unset-inherit-success: "&b{0}&a不再继承环境&b{2}&a中&b{1}&a的权限。"
unset-temp-inherit-success: "&b{0}&a在环境&b{2}&a中不再继承临时权限&b{1}&a。"
clear-success: "&b{0}&a的权限在环境&b{1}&a中被清除。(&b{2}&a节点已被删除。)"
clear-success-singular: "&b{0}&a的权限在环境&b{1}&a中被清除。(&b{2}&a节点已被删除。)"
parent-clear-success: "&b{0}&a的父组在环境&b{1}&a中被清除。(&b{2}&a节点被删除。)"
parent-clear-success-singular: "&b{0}&a的父组在环境&b{1}&a中被清除。(&b{2}&a节点被删除。)"
parent-clear-track-success: "在权限组轨道&b{1}&a上,&b{0}&a的父组在环境&b{2}&a中被清除。(&b{3}&a节点被删除。)"
parent-clear-track-success-singular: "在权限组轨道&b{1}&a上,&b{0}&a的父组在环境&b{2}&a中被清除。(&b{3}&a节点被删除。)"
meta-clear-success: "&b{0}&a的元数据匹配类型&b{1}&a在环境&b{2}&a中被清除。(&b{3}&a节点已被删除。)"
meta-clear-success-singular: "&b{0}&a的元数据匹配类型&b{1}&a在环境&b{2}&a中被清除。(&b{3}&a节点已被删除。)"
illegal-date-error: "&c无法解析日期'{0}'。"
past-date-error: "&c你不能设定一个过去的日期!"
chat-meta-prefix-header: "&b{0}的前缀"
chat-meta-suffix-header: "&b{0}的后缀"
meta-header: "&b{0}的元信息"
chat-meta-entry: "&b-> {0} &f- &f'{1}&f' &8(&7继承自&a{2}&8)"
chat-meta-entry-with-context: "&b-> {0} &f- &f'{1}&f' &8(&7继承自&a{2}&8){3}"
meta-entry: "&b-> &a{0} &f= &f'{1}&f' &8(&7继承自&a{2}&8)"
meta-entry-with-context: "&b-> &a{0} &f= &f'{1}&f' &8(&7继承自&a{2}&8){3}"
chat-meta-prefix-none: "&b{0}没有前缀。"
chat-meta-suffix-none: "&b{0}没有后缀。"
meta-none: "&b{0}没有元信息。"
meta-invalid-priority: "&c优先级&4{0}&c无效。应该是一个数字。"
already-has-chat-meta: "在环境&b{4}&a中设置&b{0}&a的元信息{1}&f'{2}&f'&a优先级为&b{3}&a。"
already-has-temp-chat-meta: "在环境&b{4}&a中设置&b{0}&a的元信息{1}&f'{2}&f'&a临时优先级为&b{3}&a。"
does-not-have-chat-meta: "在环境&b{4}&a中没有设置&b{0}&a的元信息{1}&f'{2}&f'&a优先级为&b{3}&a。"
does-not-have-temp-chat-meta: "在环境&b{4}&a中没有设置&b{0}&a的元信息{1}&f'{2}&f'&a临时优先级为&b{3}&a。"
add-chatmeta-success: "在环境&b{4}&a中将&b{0}&a的{1}设置为&f'{2}&f',优先级&b{3}&a。"
add-temp-chatmeta-success: "在环境&b{5}&a中将&b{0}&a的{1}设置为&f'{2}&f'&a,优先级&b{3}&a,持续时间为&b{4}&a。"
remove-chatmeta-success: "在环境&b{4}&a中删除了&b{0}&a优先级为&b{3}&a的{1} &f'{2}&f'&a。"
bulk-remove-chatmeta-success: "在环境&b{3}&a中删除了&b{0}&a优先级&b{2}&a的所有&b{1}&a。"
remove-temp-chatmeta-success: "在环境&b{4}&a中删除了&b{0}&a优先级&b{3}&a的临时{1} &f'{2}&f'&a。"
bulk-remove-temp-chatmeta-success: "在环境&b{3}&a中删除了&b{0}&a优先级&b{2}&a的所有临时&b{1}&a。"
already-has-meta: "&b{0}&a在环境&b{3}&a中设置了元信息&f'{1}&f'&a为&b&f'{2}&f'&a。"
already-has-temp-meta: "&b{0}&a在环境&b{3}&a中设置了临时元信息&f'{1}&f'&a为&b&f'{2}&f'&a。"
doesnt-have-meta: "&b{0}&a在环境&b{2}&a中没有设置元信息&f'{1}&f'&a。"
doesnt-have-temp-meta: "&b{0}&a在环境&b{2}&a中没有设置临时元信息&f'{1}&f'&a。"
set-meta-success: "&a在环境&b{3}&a中将&b{2}&a的元信息&f'{0}&f'&a设置为&f'{1}&f'&a。"
set-meta-temp-success: "&a在环境&b{4}&a中将&b{2}&a的元信息&f'{0}&f'&a设置为&f'{1}&f'&a,持续时间为&b{3}&a。"
unset-meta-success: "&a在环境{2}中取消设置&b{1}&a的元信息&f'{0}&f'&a。"
unset-meta-temp-success: "&a在环境{2}中取消设置&b{1}&a的临时元信息&f'{0}&f'&a。"
bulk-update-invalid-data-type: "&c类型无效。期望类型是'全部'、'用户'或'组'。"
bulk-update-invalid-constraint: "&c无效的约束&4{0}&c。约束的格式应该是'&f<field> <comparison operator> <value>&c'。"
bulk-update-invalid-comparison: "&c比较运算符无效'&4{0}&c'。应该以下之一: &f== != ~~ ~!"
bulk-update-queued: "&a批量更新操作已排队。&7(&f{0}&7)"
bulk-update-confirm: "&a运行&b/{0} bulkupdate &a确认{1}执行更新。"
bulk-update-unknown-id: "&a使用id&b{0}&a的操作不存在或已过期。"
bulk-update-starting: "&a运行批量更新。"
bulk-update-success: "&b批量更新已成功完成。"
bulk-update-failure: "&c批量更新失败。检查控制台是否有错误。"
user-info-general: >
{PREFIX}&b&l> &b用户信息: &f{0}\n
{PREFIX}&f- &3UUID: &f{1}\n
{PREFIX}&f- &3状态: {2}\n
{PREFIX}&f- &3主组: &f{3}\n
{PREFIX}&f- &a统计:\n
{PREFIX}&f- &3节点: &a{4}\n
{PREFIX}&f- &3权限: &a{5}\n
{PREFIX}&f- &3前缀: &a{6}\n
{PREFIX}&f- &3后缀: &a{7}\n
{PREFIX}&f- &3元信息: &a{8}
user-info-data: >
{PREFIX}&f- &a缓存数据:\n
{PREFIX}&f- &3具有环境数据: {0}\n
{PREFIX}&f- &3当前环境: {1}\n
{PREFIX}&f- &3当前前缀: {2}\n
{PREFIX}&f- &3当前后缀: {3}
info-parent-header: "&f- &a父组:"
info-temp-parent-header: "&f- &a临时父组:"
user-removegroup-error-primary: "&a你不能从其主组中删除用户。"
user-primarygroup-success: "&b{0}&a的主组已设为&b{1}&a。"
user-primarygroup-warn-option: "&a警告:此服务器&7({0})&a使用的主组计算方法可能无法反映此更改。"
user-primarygroup-error-alreadyhas: "&a已将&b{1}&a设置为用户&b{0}&a的主组。"
user-primarygroup-error-notmember: "&b{0}&a不是&b{1}&a的成员,现在添加它们。"
user-track-error-not-contain-group: "&a用户&b{0}&a尚未在权限组轨道&b{1}&a上的任何组中。"
user-track-added-to-first: "&b{0}&a不在此权限组轨道上的任何组中,因此在环境&b{2}&a中将其添加到第一组&b{2}&a。"
user-promote-success: "&a在环境&b{4}&a中将用户&b{0}&a沿权限组轨道&b{1}&a从&b{2}&a提升到&b{3}&a。"
user-promote-error-endoftrack: "&a已达到权限组轨道&b{0}&a的结尾,所以无法提升用户&b{1}&a。"
user-promote-error-malformed: >
{PREFIX}&a权限组轨道上的下一个组&b{0}&a不存在。无法提升用户。\n
{PREFIX}&a创建组,或将其从权限组轨道中删除,然后重试。
user-demote-success: "&a在环境&b{4}&a中将&b{0}&a沿权限组轨道&b{1}&a从&b{2}&a下降到&b{3}&a。"
user-demote-endoftrack: "&a已达到权限组轨道&b{0}&a的结尾,所以&b{1}&a已从&b{2}&a中移除。"
user-demote-error-malformed: >
{PREFIX}&a权限组轨道上的上一组&b{0}&a不存在。无法降级用户。\n
{PREFIX}&a创建组,或将其从权限组轨道中删除,然后重试。
group-info-general: >
{PREFIX}&b&l> &b组信息: &f{0}\n
{PREFIX}&f- &3显示名称: &f{1}\n
{PREFIX}&f- &3权重: &f{2}\n
{PREFIX}&f- &a统计:\n
{PREFIX}&f- &3节点: &a{3}\n
{PREFIX}&f- &3临时权限: &a{4}\n
{PREFIX}&f- &3前缀: &a{5}\n
{PREFIX}&f- &3后缀: &a{6}\n
{PREFIX}&f- &3元信息: &a{7}
group-set-weight: "&a将组&b{1}&a的权重设置为&b{0}&a。"
track-info: >
{PREFIX}&b&l> &b显示权限组轨道: &f{0}\n
{PREFIX}&f- &7路径: &f{1}
track-clear: "&b{0}&a的权限组轨道已被清除。"
track-append-success: "&a组&b{0}&a已成功添加到权限组轨道&b{1}&a。"
track-insert-success: "&a组&b{0}&a已成功插入权限组轨道&b{1}&a的&b{2}&a位置。"
track-insert-error-number: "&c没有预期的数量,而是收到: {0}"
track-insert-error-invalid-pos: "&c无法插入位置&4{0}&c。&7(无效位置)"
track-remove-success: "&a组&b{0}&a已成功从权限组轨道&b{1}&a移除。"
log-load-error: "&c日志无法加载。"
log-invalid-page: "&c页码无效。"
log-invalid-page-range: "&c页码无效,请输入&41&c和&4{0}&c之间的值。"
log-no-entries: "&b没有日志条目显示。"
log-entry: "&b#{0} -> &8(&7{1} ago&8) {2}"
log-notify-console: "&c无法切换控制台通知。"
log-notify-toggle-on: "&a启用&b记录输出。"
log-notify-toggle-off: "&c禁用&b记录输出。"
log-notify-already-on: "&c你已经收到通知。"
log-notify-already-off: "&c你目前没有收到通知。"
log-notify-unknown: "&c状态未知。输入 \"on\" 或者 \"off\"。"
log-search-header: "&a显示最近的查询操作&b{0} &a(&f{1}&a/&f{2}&a)"
log-recent-header: "&a显示最近操作 (&f{0}&a/&f{1}&a)"
log-recent-by-header: "&a显示&b{0}&a的最近操作 (&f{1}&a/&f{2}&a)"
log-history-user-header: "&a显示用户的历史记录&b{0} &a(&f{1}&a/&f{2}&a)"
log-history-group-header: "&a显示组的历史记录 &b{0} &a(&f{1}&a/&f{2}&a)"
log-history-track-header: "&a显示权限组轨道的历史记录 &b{0} &a(&f{1}&a/&f{2}&a)"
log-export-already-exists: "&c错误: 文件&4{0}&c已经存在。"
log-export-not-writable: "&c错误: 文件&4{0}&c不可写。"
log-export-empty: "&c日志为空,因此无法导出。"
log-export-failure: "&c写入文件时出现意外错误。"
log-export-success: "&a成功导出日志&b{0}&a。"
import-already-running: "&c另一个导入过程已经在运行,请等待完成,然后重试。"
export-already-running: "&c另一个导出过程已经在运行,请等待完成,然后重试。"
import-log-doesnt-exist: "&c错误: 文件&4{0}&c不存在。"
import-log-not-readable: "&c错误: 文件&4{0}&c不可读。"
import-log-failure: "&c从日志文件读取时发生意外错误。"
import-progress: "&b(导入) &b-> &f{0}&f%完成 &7- &b{1}&f/&b{2} &f完成 &c{3}&f错误。"
import-progress-sin: "&b(导入) &b-> &f{0}&f%完成 &7- &b{1}&f/&b{2} &f完成 &c{3}&f错误。"
import-start: "&b(导入) &b-> &f开始导入过程。"
import-end-complete: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &7没有错误。"
import-end-complete-err: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &c{1}错误。"
import-end-complete-err-sin: "&b(导入) &a&l已完成 &7- 用了 &b{0} &7秒 - &c{1}错误。"
import-end-error-header: >
{PREFIX}&b(导入) &7------------> &f显示错误 #&b{0} &7<------------\n
{PREFIX}&b(导入) &f执行: &3命令 #{1}\n
{PREFIX}&b(导入) &f命令: &7{2}\n
{PREFIX}&b(导入) &f类型: &3{3}\n
{PREFIX}&b(导入) &f输出:
import-end-error-content: "&b(导入) &b-> &c{0}"
import-end-error-footer: "&b(导入) &7<------------------------------------------>"
command-specs:
user:
description: "用户命令"
usage: "/%s user <用户>"
group:
description: "组命令"
usage: "/%s group <组>"
track:
description: "权限组轨道指令"
usage: "/%s track <权限组轨道>"
log:
description: "日志命令"
usage: "/%s log"
sync:
description: "与存储同步更改"
usage: "/%s sync"
info:
description: "打印通用插件信息"
usage: "/%s info"
verbose:
description: "管理详细权限检查"
usage: "/%s verbose <true|false> [filter]"
args:
"on|record|off|paste": "是否启用/禁用日志记录,或粘贴记录的输出"
"filter": "过滤器匹配项"
"--slim": "添加\"--slim\"从粘贴的输出中排除跟踪数据"
tree:
description: "生成权限的树视图"
usage: "/%s tree [selection] [max level] [player]"
args:
"selection": "树的根,指定\".\"包括所有权限"
"max level": "应该返回多少分支级别"
"player": "要检查的在线玩家的名称"
search:
description: "搜索具有特定权限的用户/组"
usage: "/%s search <permission>"
args:
"permission": "权限搜索"
"page": "页面查看"
check:
description: "对用户执行标准的权限检查"
usage: "/%s check <user> <permission>"
args:
"user": "检查用户"
"permission": "允许检查"
network-sync:
description: "与存储同步更改并请求网络上所有其他服务器都同步"
usage: "/%s networksync"
import:
description: "从文件导入数据"
usage: "/%s import <file>"
args:
"file": "要导入的文件"
export:
description: "将数据导出到文件"
usage: "/%s export <file>"
args:
"file": "要导出的文件"
reload-config:
description: "重新加载部分配置选项"
usage: "/%s reloadconfig"
bulk-update:
description: "对所有数据执行批量更改查询"
usage: "/%s bulkupdate"
args:
"data type": "正在更改的数据类型。('all'、'users'、'groups')"
"action": "对数据执行的操作。('update' or 'delete')"
"action field": "要采取行动的领域。只需要'update'。('permission'、'server'、'world')"
"action value": "替换的值。只需要'update'。"
"constraint...": "更新所需的限制"
migration:
description: "迁移命令"
usage: "/%s migration"
apply-edits:
description: "应用从Web编辑器进行的权限更改"
usage: "/%s applyedits <code> [target]"
args:
"code": "数据的唯一代码"
"target": "应用数据到谁"
create-group:
description: "创建新组"
usage: "/%s creategroup <group>"
args:
"name": "组的名称"
delete-group:
description: "删除组"
usage: "/%s deletegroup <group>"
args:
"name": "组的名称"
list-groups:
description: "列出平台上的所有组"
usage: "/%s listgroups"
create-track:
description: "创建新权限组轨道"
usage: "/%s createtrack <track>"
args:
"name": "权限组轨道的名称"
delete-track:
description: "删除权限组轨道"
usage: "/%s deletetrack <track>"
args:
"name": "权限组轨道的名称"
list-tracks:
description: "列出平台上的所有权限组轨道"
usage: "/%s listtracks"
user-info:
description: "显示有关用户的信息"
user-switchprimarygroup:
description: "切换用户的主组"
args:
"group": "组切换到"
user-promote:
description: "在权限组轨道提升用户"
args:
"track": "提升用户的权限组轨道"
"context...": "提升用户使用的环境"
user-demote:
description: "在权限组轨道降低用户"
args:
"track": "降低用户的权限组轨道"
"context...": "降低用户使用的环境"
group-info:
description: "提供有关组的信息"
group-listmembers:
description: "显示从该组继承的用户/组"
args:
"page": "页面查看"
group-setweight:
description: "设置组权重"
args:
"weight": "设定权重"
group-rename:
description: "重命名组"
args:
"name": "新名字"
group-clone:
description: "克隆组"
args:
"name": "要克隆到的组的名称"
holder-editor:
description: "打开网页权限编辑器"
holder-showtracks:
description: "列出对象所在的权限组轨道"
holder-clear:
description: "删除所有权限,父组和元"
args:
"context...": "过滤的环境"
permission:
description: "编辑权限"
parent:
description: "编辑继承"
meta:
description: "编辑元数据值"
permission-info:
description: "列出对象拥有的权限节点"
args:
"page": "页面查看"
"filter": "要过滤的字符串"
permission-set:
description: "设置对象的权限"
args:
"node": "要添加的权限"
"true|false": "节点的值"
"context...": "添加权限的环境"
permission-unset:
description: "取消对象的权限"
args:
"node": "取消的权限节点"
"context...": "删除权限的环境"
permission-settemp:
description: "设置对象的临时权限"
args:
"node": "要添加的权限"
"true|false": "节点的值"
"duration": "到期时间"
"context...": "权限的环境"
permission-unsettemp:
description: "取消对对象的临时权限"
args:
"node": "要取消的权限"
"context...": "权限的环境"
permission-check:
description: "检查对象是否具有某个权限节点"
args:
"node": "要检查的权限"
"context...": "权限的环境"
permission-check-inherits:
description: "检查对象是否继承某个权限节点"
args:
"node": "要检查的权限"
"context...": "权限的环境"
parent-info:
description: "列出此对象从哪里继承的组"
parent-set:
description: "删除对象已经继承的所有其他组,并将其添加到给定的对象组中。"
args:
"group": "组设为"
"context...": "设置组的环境"
parent-add:
description: "为该对象设置另一个组来继承权限"
args:
"group": "要继承的组"
"context...": "继承该组的环境"
parent-remove:
description: "删除先前设置的继承规则"
args:
"group": "删除的组"
"context...": "删除组的环境"
parent-set-track:
description: "删除对象在给定权限组轨道上继承的所有其他组,并将其添加到给定的权限组轨道上。"
args:
"track": "设置的权限组轨道"
"group": "组中设置的组,或与组中在给定权限组轨道上的位置相关的数字"
"context...": "设置组的环境"
parent-add-temp:
description: "为对象设置另一个组,以便从临时继承权限"
args:
"group": "要继承的组"
"duration": "持续时间"
"context...": "继承该组的环境"
parent-remove-temp:
description: "删除以前设置的临时继承规则"
args:
"group": "组删除"
"context...": "删除组的环境"
parent-clear:
description: "清除所有的父组"
args:
"context...": "过滤的环境"
parent-clear-track:
description: "清除给定权限组轨道上的所有父组"
args:
"track": "删除的权限组轨道"
"contexts...": "选择的环境"
meta-info:
description: "显示所有聊天元"
meta-set:
description: "设置元值"
args:
"key": "设定的键"
"value": "要设置的值"
"context...": "将元添加到"
meta-unset:
description: "取消设定元值"
args:
"key": "要取消的键"
"context...": "删除元的环境"
meta-settemp:
description: "暂时设置一个元值"
args:
"key": "设定的键"
"value": "要设置的值"
"duration": "持续时间"
"context...": "将元组添加到"
meta-unsettemp:
description: "取消设置临时元值"
args:
"key": "要取消的键"
"context...": "删除元的环境"
meta-addprefix:
description: "添加前缀"
args:
"priority": "添加的前缀优先级"
"prefix": "前缀字符串"
"context...": "添加前缀的环境"
meta-addsuffix:
description: "添加后缀"
args:
"priority": "添加的后缀优先级"
"suffix": "后缀字符串"
"context...": "添加后缀的环境"
meta-removeprefix:
description: "删除前缀"
args:
"priority": "删除的前缀优先级"
"prefix": "前缀字符串"
"context...": "删除前缀的环境"
meta-removesuffix:
description: "删除后缀"
args:
"priority": "删除的后缀优先级"
"suffix": "后缀字符串"
"context...": "删除后缀的环境"
meta-addtemp-prefix:
description: "添加临时前缀"
args:
"priority": "删除的前缀优先级"
"prefix": "前缀字符串"
"duration": "持续时间"
"context...": "添加前缀的环境"
meta-addtemp-suffix:
description: "添加临时后缀"
args:
"priority": "添加的后缀优先级"
"suffix": "后缀字符串"
"duration": "持续时间"
"context...": "添加后缀的环境"
meta-removetemp-prefix:
description: "删除临时前缀"
args:
"priority": "删除的前缀优先级"
"prefix": "前缀字符串"
"context...": "删除前缀的环境"
meta-removetemp-suffix:
description: "删除临时后缀"
args:
"priority": "删除的后缀优先级"
"suffix": "后缀字符串"
"context...": "删除后缀的环境"
meta-clear:
description: "清除所有元"
args:
"type": "要删除的元数据类型"
"context...": "过滤的环境"
track-info:
description: "提供有关权限组轨道的信息"
track-append:
description: "追加一个组到权限组轨道的最后"
args:
"group": "追加的组"
track-insert:
description: "在权限组轨道上的给定位置插入一个组"
args:
"group": "插入的组"
"position": "插入组的位置(权限组轨道上的第一个位置为1)"
track-remove:
description: "从权限组轨道中删除一个组"
args:
"group": "删除的组"
track-clear:
description: "清除权限组轨道上的组"
track-rename:
description: "重命名权限组轨道"
args:
"name": "新名字"
track-clone:
description: "克隆权限组轨道"
args:
"name": "要克隆的权限组轨道的名称"
log-recent:
description: "查看最近的登陆"
args:
"user": "用户的名称/uuid"
"page": "要查看的页码"
log-search:
description: "搜索日志中的条目"
args:
"query": "搜索的查询"
"page": "要查看的页码"
log-notify:
description: "切换日志通知"
args:
"on|off": "是否打开或关闭"
log-user-history:
description: "查看用户的历史记录"
args:
"user": "用户名/ uuid"
"page": "要查看的页码"
log-group-history:
description: "查看组的历史"
args:
"group": "组名"
"page": "要查看的页码"
log-track-history:
description: "查看权限组轨道的历史"
args:
"track": "权限组轨道的名称"
"page": "要查看的页码"
sponge:
description: "编辑额外的Sponge数据"
usage: "/%s sponge <collection> <subject>"
args:
"collection": "要查询的集合"
"subject": "修改的主题"
sponge-permission-info:
description: "显示有关主题权限的信息"
args:
"contexts...": "选择的环境"
sponge-permission-set:
description: "设置一个主题的权限"
args:
"node": "要设置的权限节点"
"tristate": "设置允许值"
"contexts...": "选择的环境"
sponge-permission-clear:
description: "清除一个主题的权限"
args:
"contexts...": "清除的环境"
sponge-parent-info:
description: "显示关于该主题父项的信息"
args:
"contexts...": "选择的环境"
sponge-parent-add:
description: "向主题添加父项"
args:
"collection": "父主题的主题集合"
"subject": "父主题的名称"
"contexts...": "添加父项的环境"
sponge-parent-remove:
description: "从主题中删除父项"
args:
"collection": "父主题的主题集合"
"subject": "父主题的名称"
"contexts...": "删除父项的环境"
sponge-parent-clear:
description: "清除主题父项"
args:
"contexts...": "清除父项的主题"
sponge-option-info:
description: "显示有关主题选项的信息"
args:
"contexts...": "选择的环境"
sponge-option-set:
description: "为主题设置一个选项"
args:
"key": "设定键"
"value": "设置的键"
"contexts...": "设置选项的环境"
sponge-option-unset:
description: "取消主题一个选项"
args:
"key": "取消的键"
"contexts...": "取消选项的环境"
sponge-option-clear:
description: "清除对象的选择"
args:
"contexts...": "清除选项的环境"
migration-command:
description: "迁移命令"
migration-groupmanager:
description: "迁移命令"
args:
"migrate as global": "如果世界权限应该被忽略,并且刚刚迁移为全局"
migration-powerfulperms:
description: "迁移命令"
args:
"address": "PP数据库的地址"
"database": "PP数据库的名称"
"username": "登录DB的用户名"
"password": "登录DB的用密码"
"db table": "存储用户数据的PP表的名称"
+3 -2
View File
@@ -1,6 +1,7 @@
MIT License
The MIT License.
Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
Copyright (c) lucko (Luck) <luck@lucko.me>
Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+48 -190
View File
@@ -1,205 +1,63 @@
![alt text](https://i.imgur.com/7TwJZ5e.png "Banner")
# LuckPerms [![Build Status](https://ci.lucko.me/job/LuckPerms/badge/icon)](https://ci.lucko.me/job/LuckPerms/)
A permissions implementation for Bukkit/Spigot, BungeeCord and Sponge.
LuckPerms is an advanced permissions implementation aiming to be a fast, reliable and flexible alternative to existing permission plugins. The project's main goals are centered around high performance and a wide feature set, filling the gaps of functionality and building upon existing features found in other plugins.
## Links
LuckPerms also includes an extensive API for developers, and support for a variety of Minecraft server software & data storage options.
[See the charts below](https://github.com/lucko/LuckPerms#luckperms-vs-other-plugins) for a partial list of features & comparison with other providers.
* [Spigot Plugin Release Page](https://www.spigotmc.org/resources/luckperms-an-advanced-permissions-system.28140/ "Spigot Plugin Page")
* [Sponge Plugin Release Page](https://forums.spongepowered.org/t/luckperms-an-advanced-permissions-system/14274 "Sponge Plugin Page")
## Useful Links
* **Development Builds** - <https://ci.lucko.me/job/LuckPerms>
* **Javadocs** - <https://jd.lucko.me/LuckPerms>
* **Javadocs** - <https://luckperms.lucko.me/javadocs/>
* **Wiki** - <https://github.com/lucko/LuckPerms/wiki>
## Features
* **Group inheritance** - users can be members of multiple groups, groups can inherit other groups
* **Temporary permissions** - users/groups can be given permissions that expire after a given time
* **Wildcard permissions** - users/groups can be given wildcard permissions (e.g. "minecraft.command.*"), even when plugins haven't implemented their own wildcards.
* **Temporary groups** - users/groups can be added to/inherit other groups temporarily
* **Multi-server support** - data is synced across all servers/platforms
* **Full offline-mode/mixed-mode support** - player permissions are synced properly over offline-mode or mixed online/offline-mode networks.
* **Per-server permissions/groups** - define user/group permissions that only apply on certain servers
* **Per-world permissions/groups** - define user/group permissions that only apply on certain worlds (on BungeeCord, a connected Bukkit/Spigot instance is treated as a world)
* **Tracks / paths / ladders** - users can be promoted/demoted along multiple group tracks
* **Vault Support** - hooks into Vault to integrate with other plugins
* **Developer API** - easily integrate LuckPerms into your own projects
* **Easy and simple setup and configuration using commands** - no editing yml files, yuck
* **Negated permissions and groups** - define special rules for certain users/groups
* **Full support for UUIDs, even in Offline Mode** - users can change their usernames without losing permissions. In offline mode, a single user has the same internal UUID across a network.
* **Permission data stored within MySQL in a json format** - easily integrate the LuckPerms backend into your other projects
* **Well documented** - API methods have comprehensive Java docs, it's clear what each method does.
* **Efficient/lightweight** - maybe? Who knows, it might be.
* **Open Sourced, Free...** - you shouldn't have to pay $10+ for a "powerful" permissions plugin.
* **BungeeCord compatible** - permissions, users and groups are synced across all LuckPerms instances
* **Sponge compatible** - permissions, users and groups are synced across all LuckPerms instances (bukkit --> sponge, for example)
* **Support for MySQL, SQLite & Flatfile (JSON)** - other storage methods coming soon (maybe)
## Building
LuckPerms uses Maven to handle dependencies.
## Setup
All configuration options are in the **config.yml/luckperms.conf** file, which is generated automagically when the plugin first starts.
#### Requirements
* Java 8 JDK
* Maven 3.3.x (the older versions will not work.)
* Git
You can define the settings for per-server permissions, the storage method and credentials within this file.
## Info
### Permission Calculation
#### Permissions are calculated based on a priority system as follows.
* **Non wildcard permissions will override wildcard permissions**
Example: if a user has a true permission set for "luckperms.\*", and a false permission set for "luckperms.something", the non-wildcard permission will override the wildcard, and "luckperms.something" will be set to false, despite the wildcard.
* **More specific wildcards override less specific ones**
Example: if a user has "luckperms.\*" set to true, but "luckperms.user.\*" set to false, all of the user permissions will be set to false, despite the more generic wildcard for "luckperms.*".
* **Temporary permissions will override non-temporary permissions.**
Example: if a user has a false permission set for "test.node", and a temporary true permission set for "test.node", the temporary permission will override the permanent one, and the user will be granted the true node.
* **World specific permissions will override generic permissions.**
Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission in the "world_nether" world, the world specific permission will override the globally defined one, and the user will be granted the negated node (provided they're in that world, of course.).
* **Server specific permissions will override generic/global permissions.**
Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission on the "factions" server, the server specific permission will override the globally defined one, and the user will be granted the negated node (provided they're on that server).
* **Inherited permissions will be overridden by an objects own permissions.**
Example: A user is a member of the default group, which grants "some.thing.perm", but the users own permissions has "some.thing.perm" set to false. The inherited permission will be overridden by the users own permissions, and the user will be granted the negative node.
### Temporary Permissions
Temporary permissions are checked each time a user/group is loaded, and when the sync task runs. This means if you set a temporary permission to expire after 30 seconds, it won't actually be removed until the sync task runs.
The only way around this is to decrease the sync interval.
## API
LuckPerms has an extensive API, allowing for easy integration with other projects. To use the Api, you need to obtain an instance of the `LuckPermsApi` interface. This can be done in a number of ways.
```java
// On all platforms (throws IllegalStateException if the API is not loaded)
final LuckPermsApi api = LuckPerms.getApi();
// Or with Optional
Optional<LuckPermsApi> provider = LuckPerms.getApiSafe();
if (provider.isPresent()) {
final LuckPermsApi api = provider.get();
}
// On Bukkit/Spigot
ServicesManager manager = Bukkit.getServicesManager();
if (manager.isProvidedFor(LuckPermsApi.class)) {
final LuckPermsApi api = manager.getRegistration(LuckPermsApi.class).getProvider();
}
// On Sponge
Optional<LuckPermsApi> provider = Sponge.getServiceManager().provide(LuckPermsApi.class);
if (provider.isPresent()) {
final LuckPermsApi api = provider.get();
}
#### Then run
```sh
git clone https://github.com/lucko/LuckPerms.git
cd LuckPerms/
mvn clean package
```
If you want to use LuckPerms in your onEnable method, you need to add the following to your plugins `plugin.yml`.
```yml
depend: [LuckPerms]
```
All of the available methods can be seen in the various interfaces in the `luckperms-api` module.
You can find the output jars in the `target` directories.
You can add LuckPerms as a Maven dependency by adding the following to your projects `pom.xml`.
````xml
<repositories>
<repository>
<id>luck-repo</id>
<url>https://repo.lucko.me/</url>
</repository>
</repositories>
## Contributing
In order to contribute to and make changes to the plugin, you will need the dependencies listed above, plus the [Lombok plugin](https://projectlombok.org/download.html) for your IDE.
<dependencies>
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
````
#### Pull Requests
If you make any changes or improvements to the plugin which you think would be beneficial upstream, please consider making a Pull Request to merge your changes back into the upstream project. (especially if your changes are bug fixes!)
## Versioning
As of version 2.0, LuckPerms roughly follows the standards set out in Semantic Versioning.
LuckPerms loosely follows the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html), with a few minor changes here and there. Generally, try to copy the style of code found in the class you're editing.
The only difference is that patch number is not included anywhere within the pom, and is calculated each build, based upon how may commits have been made since the last tag. (A new tag is made every minor version)
#### Project Layout
The project is split up into 5 seperate modules.
This means that API versions do not have a patch number (as no API changes are made in patches). API versions will be x.y, and each individual build of LuckPerms will follow x.y.z.
## Commands
Command usage is printed to the console/chat whenever invalid arguments are provided. Simply typing /perms will list all commands a user has permission to use.
### Aliases
| Bukkit | Bungee |
|------------------|------------------|
| /luckperms | /luckpermsbungee |
| /perms | /bperms |
| /permissions | /bpermissions |
| /lp | /lpb |
| /perm | /bperm |
Arguments: \<required\> [optional]
Users with OP have access to all commands.
Additionally, you can use wildcards to grant users access to a selection of commands.
* **All commands** - luckperms.*
* **All user commands** - luckperms.user.*
* **All group commands** - luckperms.group.*
* **All track commands** - luckperms.track.*
### General
* /perms - n/a
* /perms sync - luckperms.sync
* /perms info - luckperms.info
* /perms debug - luckperms.debug
* /perms creategroup \<group\> - luckperms.creategroup
* /perms deletegroup \<group\> - luckperms.deletegroup
* /perms listgroups - luckperms.listgroups
* /perms createtrack \<track\> - luckperms.createtrack
* /perms deletetrack \<track\> - luckperms.deletetrack
* /perms listtracks - luckperms.listtracks
### User
* /perms user \<user\> info - luckperms.user.info
* /perms user \<user\> getuuid - luckperms.user.getuuid
* /perms user \<user\> listnodes - luckperms.user.listnodes
* /perms user \<user\> haspermission \<node\> [server] [world] - luckperms.user.haspermission
* /perms user \<user\> inheritspermission \<node\> [server] [world] - luckperms.user.inheritspermission
* /perms user \<user\> set \<node\> \<true/false\> [server] [world] - luckperms.user.setpermission
* /perms user \<user\> unset \<node\> [server] [world] - luckperms.user.unsetpermission
* /perms user \<user\> addgroup \<group\> [server] [world] - luckperms.user.addgroup
* /perms user \<user\> removegroup \<group\> [server] [world] - luckperms.user.removegroup
* /perms user \<user\> settemp \<node\> \<true/false\> \<duration\> [server] [world] - luckperms.user.settemppermission
* /perms user \<user\> unsettemp \<node\> [server] [world] - luckperms.user.unsettemppermission
* /perms user \<user\> addtempgroup \<group\> \<duration\> [server] [world] - luckperms.user.addtempgroup
* /perms user \<user\> removetempgroup \<group\> [server] [world] - luckperms.user.removetempgroup
* /perms user \<user\> setprimarygroup \<group\> - luckperms.user.setprimarygroup
* /perms user \<user\> showtracks - luckperms.user.showtracks
* /perms user \<user\> promote \<track\> - luckperms.user.promote
* /perms user \<user\> demote \<track\> - luckperms.user.demote
* /perms user \<user\> showpos \<track\> - luckperms.user.showpos
* /perms user \<user\> clear - luckperms.user.clear
### Group
* /perms group \<group\> info - luckperms.group.info
* /perms group \<group\> listnodes - luckperms.group.listnodes
* /perms group \<group\> haspermission \<node\> [server] [world] - luckperms.group.haspermission
* /perms group \<group\> inheritspermission \<node\> [server] [world] - luckperms.group.inheritspermission
* /perms group \<group\> set \<node\> \<true/false\> [server] [world] - luckperms.group.setpermission
* /perms group \<group\> unset \<node\> [server] [world] - luckperms.group.unsetpermission
* /perms group \<group\> setinherit \<group\> [server] [world] - luckperms.group.setinherit
* /perms group \<group\> unsetinherit \<group\> [server] [world] - luckperms.group.unsetinherit
* /perms group \<group\> settemp \<node\> \<true/false\> \<duration\> [server] [world] - settemppermission
* /perms group \<group\> unsettemp \<node\> [server] [world] - luckperms.group.unsettemppermission
* /perms group \<group\> settempinherit \<group\> \<duration\> [server] [world] - luckperms.group.settempinherit
* /perms group \<group\> unsettempinherit \<group\> [server] [world] - luckperms.group.unsettempinherit
* /perms group \<group\> showtracks - luckperms.group.showtracks
* /perms group \<group\> clear - luckperms.group.clear
### Track
* /perms track \<track\> info - luckperms.track.info
* /perms track \<track\> append \<group\> - luckperms.track.append
* /perms track \<track\> insert \<group\> \<position\> - luckperms.track.insert
* /perms track \<track\> remove \<group\> - luckperms.track.remove
* /perms track \<track\> clear - luckperms.track.clear
* **API** - The public facing API classes used by other plugins when integrating with LuckPerms. This is basically just a collection of interfaces implemented inside of the plugin.
* **Common** - This includes all of the classes shared by separate implementations of LuckPerms. This is where the bulk of the project is.
* **Bukkit, BungeeCord & Sponge** - Includes all of the platform specific classes used to implement LuckPerms on each of the 3 supported platforms.
## License
See LICENSE.md.
LuckPerms is licensed under the permissive MIT license. Please see [`LICENSE.txt`](https://github.com/lucko/LuckPerms/blob/master/LICENSE.txt) for more info.
## Why use LuckPerms?
The main features of LuckPerms are detailed on this wiki page: [Why LuckPerms?](https://github.com/lucko/LuckPerms/wiki/Why-LuckPerms)
### Bukkit
See [here](https://luckperms.lucko.me/assets/bukkit-compare.png) for a comparison chart showing the differences between LuckPerms and other permission plugins for Bukkit.
### Sponge
LuckPerms is currently the only maintained and 'working' permissions plugin for Sponge servers.
## Thanks
Thanks to ej-technologies for granting LuckPerms an open source licence to their [Java Profiling Software](http://www.ej-technologies.com/products/jprofiler/overview.html "Java Profiler").
+94 -4
View File
@@ -1,21 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.1</version>
<version>4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luckperms-api</artifactId>
<build>
<finalName>LuckPerms-API-${release.version}</finalName>
<resources>
<resource>
<directory>../</directory>
<filtering>false</filtering>
<includes>
<include>LICENSE.txt</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<version>${compiler.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@@ -23,4 +34,83 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>deployment</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<links>
<link>https://google.github.io/guava/releases/21.0/api/docs/</link>
</links>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>sign</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${gpg.version}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<!-- guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,48 +25,70 @@
package me.lucko.luckperms;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import me.lucko.luckperms.api.LuckPermsApi;
import java.util.Optional;
import javax.annotation.Nonnull;
/**
* Static access to LuckPerms
* Provides static access to the {@link LuckPermsApi}.
*
* <p>Ideally, the ServiceManager for the platform should be used to obtain an instance,
* however, this provider can be used if you need static access.</p>
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class LuckPerms {
private static LuckPermsApi api = null;
private static LuckPermsApi instance = null;
/**
* Gets an instance of {@link LuckPermsApi}
* Gets an instance of the {@link LuckPermsApi},
* throwing {@link IllegalStateException} if an instance is not yet loaded.
*
* <p>Will never return null.</p>
*
* @return an api instance
* @throws IllegalStateException if the api is not loaded
*/
@Nonnull
public static LuckPermsApi getApi() {
if (api == null) {
if (instance == null) {
throw new IllegalStateException("API is not loaded.");
}
return api;
return instance;
}
/**
* Gets an instance of {@link LuckPermsApi} safely. Unlike {@link LuckPerms#getApi}, this method will not throw an
* {@link IllegalStateException} if the api is not loaded, rather return an empty {@link Optional}.
* Gets an instance of {@link LuckPermsApi}, if it is loaded.
*
* <p>Unlike {@link LuckPerms#getApi}, this method will not throw an
* {@link IllegalStateException} if an instance is not yet loaded, rather return
* an empty {@link Optional}.
*
* @return an optional api instance
*/
@Nonnull
public static Optional<LuckPermsApi> getApiSafe() {
return Optional.ofNullable(api);
return Optional.ofNullable(instance);
}
static void registerProvider(LuckPermsApi luckPermsApi) {
api = luckPermsApi;
/**
* Registers an instance of the {@link LuckPermsApi} with this provider.
*
* @param instance the instance
*/
static void registerProvider(LuckPermsApi instance) {
LuckPerms.instance = instance;
}
/**
* Removes the current instance from this provider.
*/
static void unregisterProvider() {
api = null;
LuckPerms.instance = null;
}
private LuckPerms() {
throw new UnsupportedOperationException("This class cannot be instantiated.");
}
}
@@ -0,0 +1,126 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import com.google.common.base.Preconditions;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nonnull;
/**
* Represents a type of chat meta
*
* @since 3.2
*/
public enum ChatMetaType {
/**
* Represents a prefix
*/
PREFIX {
@Override
public boolean matches(Node node) {
return Preconditions.checkNotNull(node, "node").isPrefix();
}
@Override
public boolean shouldIgnore(Node node) {
return !Preconditions.checkNotNull(node, "node").isPrefix();
}
@Override
public Map.Entry<Integer, String> getEntry(Node node) {
return Preconditions.checkNotNull(node, "node").getPrefix();
}
},
/**
* Represents a suffix
*/
SUFFIX {
@Override
public boolean matches(Node node) {
return Preconditions.checkNotNull(node, "node").isSuffix();
}
@Override
public boolean shouldIgnore(Node node) {
return !Preconditions.checkNotNull(node, "node").isSuffix();
}
@Override
public Map.Entry<Integer, String> getEntry(Node node) {
return Preconditions.checkNotNull(node, "node").getSuffix();
}
};
/**
* Returns if the passed node matches the type
*
* @param node the node to test
* @return true if the node has the same type
*/
public abstract boolean matches(@Nonnull Node node);
/**
* Returns if the passed node should be ignored when searching for meta of this type
*
* @param node the node to test
* @return true if the node does not share the same type
*/
public abstract boolean shouldIgnore(@Nonnull Node node);
/**
* Maps the corresponding entry from the given node
*
* @param node the node to retrieve the entry from
* @return the entry
* @throws IllegalStateException if the node does not share the same type
*/
@Nonnull
public abstract Map.Entry<Integer, String> getEntry(@Nonnull Node node);
/**
* Parses a ChatMetaType from the given node.
*
* @param node the node
* @return the parsed chat meta type
* @since 3.4
*/
@Nonnull
public static Optional<ChatMetaType> ofNode(@Nonnull Node node) {
if (node.isPrefix()) {
return Optional.of(PREFIX);
} else if (node.isSuffix()) {
return Optional.of(SUFFIX);
} else {
return Optional.empty();
}
}
}
@@ -0,0 +1,260 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import javax.annotation.Nonnull;
/**
* Encapsulates the options and settings for a permission lookup.
*
* <p>This class is immutable.</p>
*
* @since 2.11
*/
public class Contexts {
/**
* The context key used to denote the subjects server
*/
public static final String SERVER_KEY = "server";
/**
* The context key used to denote the subjects world
*/
public static final String WORLD_KEY = "world";
/**
* A 'global' or default contexts instance.
*
* Simply passes an empty context set, with all accumulation settings set to true.
*/
private static final Contexts GLOBAL = new Contexts(
ContextSet.empty(),
true,
true,
true,
true,
true,
false
);
/**
* Gets the {@link FullySatisfiedContexts} instance.
*
* @return a context that will satisfy all contextual requirements.
*/
@Nonnull
public static Contexts allowAll() {
return FullySatisfiedContexts.getInstance();
}
/**
* A contexts instance with no defined context.
*
* @return the global contexts
* @since 3.3
*/
@Nonnull
public static Contexts global() {
return GLOBAL;
}
public static Contexts of(@Nonnull ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
return new Contexts(context, includeGlobal, includeGlobalWorld, applyGroups, applyGlobalGroups, applyGlobalWorldGroups, op);
}
/**
* The contexts that apply for this lookup
*/
private final ImmutableContextSet context;
/**
* If the target subject is OP. This is used to parse defaults on Bukkit,
* and is ignored on all other platforms.
*
* @since 2.12
*/
private final boolean op;
/**
* If global or non server specific nodes should be applied
*/
private final boolean includeGlobal;
/**
* If global or non world specific nodes should be applied
*/
private final boolean includeGlobalWorld;
/**
* If parent groups should be applied
*/
private final boolean applyGroups;
/**
* If global or non server specific group memberships should be applied
*/
private final boolean applyGlobalGroups;
/**
* If global or non world specific group memberships should be applied
*/
private final boolean applyGlobalWorldGroups;
// cache hashcode - this class is immutable, and is used as an index in the permission cache.
private final int hashCode;
public Contexts(@Nonnull ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
this.context = Preconditions.checkNotNull(context, "context").makeImmutable();
this.includeGlobal = includeGlobal;
this.includeGlobalWorld = includeGlobalWorld;
this.applyGroups = applyGroups;
this.applyGlobalGroups = applyGlobalGroups;
this.applyGlobalWorldGroups = applyGlobalWorldGroups;
this.op = op;
this.hashCode = calculateHashCode();
}
/**
* Gets the contexts that apply for this lookup
*
* @return an immutable set of context key value pairs
* @since 2.13
*/
@Nonnull
public ContextSet getContexts() {
return this.context;
}
/**
* Gets if the target subject is OP. This is used to parse defaults on Bukkit,
* and is ignored on all other platforms.
*
* @return true if op defaults should be included
*/
public boolean isOp() {
return this.op;
}
/**
* Gets if global or non server specific nodes should be applied
*
* @return true if global or non server specific nodes should be applied
*/
public boolean isIncludeGlobal() {
return this.includeGlobal;
}
/**
* Gets if global or non world specific nodes should be applied
*
* @return true if global or non world specific nodes should be applied
*/
public boolean isIncludeGlobalWorld() {
return this.includeGlobalWorld;
}
/**
* Gets if parent groups should be applied
*
* @return true if parent groups should be applied
*/
public boolean isApplyGroups() {
return this.applyGroups;
}
/**
* Gets if global or non server specific group memberships should be applied
*
* @return true if global or non server specific group memberships should be applied
*/
public boolean isApplyGlobalGroups() {
return this.applyGlobalGroups;
}
/**
* Gets if global or non world specific group memberships should be applied
*
* @return true if global or non world specific group memberships should be applied
*/
public boolean isApplyGlobalWorldGroups() {
return this.applyGlobalWorldGroups;
}
@Override
@Nonnull
public String toString() {
return "Contexts(" +
"context=" + this.getContexts() + ", " +
"op=" + this.isOp() + ", " +
"includeGlobal=" + this.isIncludeGlobal() + ", " +
"includeGlobalWorld=" + this.isIncludeGlobalWorld() + ", " +
"applyGroups=" + this.isApplyGroups() + ", " +
"applyGlobalGroups=" + this.isApplyGlobalGroups() + ", " +
"applyGlobalWorldGroups=" + this.isApplyGlobalWorldGroups() +
")";
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == allowAll()) return false;
if (!(o instanceof Contexts)) return false;
final Contexts other = (Contexts) o;
return this.getContexts().equals(other.getContexts()) &&
this.isOp() == other.isOp() &&
this.isIncludeGlobal() == other.isIncludeGlobal() &&
this.isIncludeGlobalWorld() == other.isIncludeGlobalWorld() &&
this.isApplyGroups() == other.isApplyGroups() &&
this.isApplyGlobalGroups() == other.isApplyGlobalGroups() &&
this.isApplyGlobalWorldGroups() == other.isApplyGlobalWorldGroups();
}
private int calculateHashCode() {
final int PRIME = 59;
int result = 1;
final Object contexts = this.getContexts();
result = result * PRIME + contexts.hashCode();
result = result * PRIME + (this.isOp() ? 79 : 97);
result = result * PRIME + (this.isIncludeGlobal() ? 79 : 97);
result = result * PRIME + (this.isIncludeGlobalWorld() ? 79 : 97);
result = result * PRIME + (this.isApplyGroups() ? 79 : 97);
result = result * PRIME + (this.isApplyGlobalGroups() ? 79 : 97);
result = result * PRIME + (this.isApplyGlobalWorldGroups() ? 79 : 97);
return result;
}
@Override
public int hashCode() {
return hashCode;
}
}
@@ -0,0 +1,88 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
/**
* Represents the result of a mutation call.
*/
public enum DataMutateResult {
/**
* Indicates the mutation was a success
*/
SUCCESS(true),
/**
* Indicates the mutation failed because the subject already has something
*/
ALREADY_HAS(false),
/**
* Indicates the mutation failed because the subject lacks something
*/
LACKS(false),
/**
* Indicates the mutation failed
*/
FAIL(false);
private final boolean value;
DataMutateResult(boolean value) {
this.value = value;
}
/**
* Gets a boolean representation of the result.
*
* @return a boolean representation
*/
public boolean asBoolean() {
return value;
}
/**
* Gets if the result indicates a success
*
* @return if the result indicates a success
* @since 3.4
*/
public boolean wasSuccess() {
return value;
}
/**
* Gets if the result indicates a failure
*
* @return if the result indicates a failure
* @since 3.4
*/
public boolean wasFailure() {
return !value;
}
}
@@ -1,78 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.data.Callback;
import java.util.UUID;
/**
* Wrapper interface for the internal Datastore instance
* The implementations of this interface limit access to the datastore and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the plugin.
*/
@SuppressWarnings("unused")
public interface Datastore {
String getName();
boolean isAcceptingLogins();
Async async();
Sync sync();
interface Async {
void loadOrCreateUser(UUID uuid, String username, Callback<Boolean> callback);
void loadUser(UUID uuid, Callback<Boolean> callback);
void saveUser(User user, Callback<Boolean> callback);
void createAndLoadGroup(String name, Callback<Boolean> callback);
void loadGroup(String name, Callback<Boolean> callback);
void loadAllGroups(Callback<Boolean> callback);
void saveGroup(Group group, Callback<Boolean> callback);
void deleteGroup(Group group, Callback<Boolean> callback);
void createAndLoadTrack(String name, Callback<Boolean> callback);
void loadTrack(String name, Callback<Boolean> callback);
void loadAllTracks(Callback<Boolean> callback);
void saveTrack(Track track, Callback<Boolean> callback);
void deleteTrack(Track track, Callback<Boolean> callback);
void saveUUIDData(String username, UUID uuid, Callback<Boolean> callback);
void getUUID(String username, Callback<UUID> callback);
}
interface Sync {
boolean loadOrCreateUser(UUID uuid, String username);
boolean loadUser(UUID uuid);
boolean saveUser(User user);
boolean createAndLoadGroup(String name);
boolean loadGroup(String name);
boolean loadAllGroups();
boolean saveGroup(Group group);
boolean deleteGroup(Group group);
boolean createAndLoadTrack(String name);
boolean loadTrack(String name);
boolean loadAllTracks();
boolean saveTrack(Track track);
boolean deleteTrack(Track track);
boolean saveUUIDData(String username, UUID uuid);
UUID getUUID(String username);
}
}
@@ -0,0 +1,81 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.caching.MetaContexts;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.ContextSet;
import javax.annotation.Nonnull;
/**
* A special instance of {@link Contexts}, which when passed to:
*
* <p></p>
* <ul>
* <li>{@link UserData#getPermissionData(Contexts)}</li>
* <li>{@link UserData#getMetaData(Contexts)}</li>
* <li>{@link UserData#getMetaData(MetaContexts)}</li>
* </ul>
*
* <p>... will always satisfy all contextual requirements.</p>
*
* <p>This effectively allows you to do lookups which ignore context.</p>
*
* @since 3.3
*/
public final class FullySatisfiedContexts extends Contexts {
// singleton
private static final FullySatisfiedContexts INSTANCE = new FullySatisfiedContexts();
@Nonnull
public static Contexts getInstance() {
return INSTANCE;
}
private FullySatisfiedContexts() {
super(ContextSet.empty(), true, true, true, true, true, false);
}
@Nonnull
@Override
public String toString() {
return "FullySatisfiedContexts()";
}
@Override
public boolean equals(Object o) {
// this class is a singleton, so we can use object comparison to check equality.
return o == this;
}
@Override
public int hashCode() {
// just use the system hashcode - we need to override the hashcode impl in super
return System.identityHashCode(this);
}
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,173 +25,54 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.List;
import java.util.OptionalInt;
import javax.annotation.Nonnull;
/**
* Wrapper interface for internal Group instances
* The implementations of this interface limit access to the Group and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the group.
* An inheritable holder of permission data.
*/
@SuppressWarnings("unused")
public interface Group extends PermissionHolder {
/**
* Get the name of the group
*
* @return the name of the group
*/
@Nonnull
String getName();
/**
* check to see if a group inherits a group
* Check to see if a group inherits another group directly
*
* @param group The group to check membership of
* @return true if the user is a member of the group
* @return true if the group inherits the other group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
boolean inheritsGroup(Group group);
boolean inheritsGroup(@Nonnull Group group);
/**
* check to see if the group inherits a group on a specific server
* Check to see if a group inherits another group directly
*
* @param group The group to check membership of
* @param server The server to check on
* @return true if the group inherits the group
* @param contextSet the context set to filter by
* @return true if the group inherits the other group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @since 3.2
*/
boolean inheritsGroup(Group group, String server);
boolean inheritsGroup(@Nonnull Group group, @Nonnull ContextSet contextSet);
/**
* check to see if the group inherits a group on a specific server
* @param group The group to check membership of
* @param server The server to check on
* @param world The world to check on
* @return true if the group inherits the group
* Gets the weight of this group, if present.
*
* @return the group weight
* @since 2.17
*/
boolean inheritsGroup(Group group, String server, String world);
@Nonnull
OptionalInt getWeight();
/**
* Make this group inherit another group
* @param group the group to be inherited
* @throws ObjectAlreadyHasException if the group already inherits the group
*/
void setInheritGroup(Group group) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @param world The world to add the group on
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @param world The world to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @param world The world to remove the group on
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server, String world) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @param world The world to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
/**
* Clear all of the groups permission nodes
*/
void clearNodes();
/**
* Get a {@link List} of all of the groups the group inherits, on all servers
* @return a {@link List} of group names
*/
List<String> getGroupNames();
/**
* Get a {@link List} of the groups the group inherits on a specific server
* @param server the server to check
* @param world the world to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server, String world);
/**
* Get a {@link List} of the groups the group inherits on a specific server
* @param server the server to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server);
}
@@ -0,0 +1,104 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.Optional;
import java.util.OptionalLong;
import javax.annotation.Nonnull;
/**
* A relationship between a PermissionHolder and a permission
*
* @param <T> the identifier type of the holder
* @since 2.17
*/
public interface HeldPermission<T> {
/**
* Gets the holder of the permission
*
* @return the holder
*/
@Nonnull
T getHolder();
/**
* Gets the permission being held
*
* @return the permission
*/
@Nonnull
String getPermission();
/**
* Gets the value of the permission
*
* @return the value
*/
boolean getValue();
/**
* Gets the server where the permission is held
*
* @return the server
*/
@Nonnull
Optional<String> getServer();
/**
* Gets the world where the permission is held
*
* @return the world
*/
@Nonnull
Optional<String> getWorld();
/**
* Gets the time in unix time when the permission will expire
*
* @return the expiry time
*/
OptionalLong getExpiry();
/**
* Gets the extra context for the permission.
*
* @return the extra context
*/
ContextSet getContexts();
/**
* Converts this permission into a Node
*
* @return a Node copy of this permission
*/
@Nonnull
Node asNode();
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,56 +25,98 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.data.MySQLConfiguration;
import java.util.Map;
import javax.annotation.Nonnull;
/**
* A wrapper interface for the internal LuckPerms configuration, providing read only access.
* Wrapper around parts of the LuckPerms configuration file
*/
public interface LPConfiguration {
/**
* Gets the name of this server
*
* @return the name of this server
*/
@Nonnull
String getServer();
/**
* @return how often a sync task will run in minutes
*/
int getSyncTime();
/**
* @return the default group, in a node representation
*/
String getDefaultGroupNode();
/**
* @return the name of the default group
*/
String getDefaultGroupName();
/**
* Gets if the users on this server will have their global permissions applied
*
* @return if the users on this server will have their global permissions applied
*/
boolean getIncludeGlobalPerms();
/**
* @return the online mode setting in the config
* Gets if the users on this server will have their global world permissions applied
*
* @return if the users on this server will have their global world permissions applied
* @since 2.9
*/
boolean getOnlineMode();
boolean getIncludeGlobalWorldPerms();
/**
* @return if LuckPerms is applying wildcard permissions
* Gets if the platform is applying global groups
*
* @return true if the platform is applying global groups
* @since 2.9
*/
boolean getApplyWildcards();
boolean getApplyGlobalGroups();
/**
* @return the database values set in the configuration
* Gets if the platform is applying global world groups
*
* @return true if the platform is applying global world groups
* @since 2.9
*/
MySQLConfiguration getDatabaseValues();
boolean getApplyGlobalWorldGroups();
/**
* Gets the storage method string from the configuration
*
* @return the storage method string from the configuration
*/
@Nonnull
String getStorageMethod();
/**
* Gets true if split storage is enabled
*
* @return true if split storage is enabled
* @since 2.7
*/
boolean getSplitStorage();
/**
* Gets a map of split storage options
*
* @return a map of split storage options, where the key is the storage section, and the value is the storage
* method. For example: key = user, value = json
* @since 2.7
*/
@Nonnull
Map<String, String> getSplitStorageOptions();
@Nonnull
Unsafe unsafe();
interface Unsafe {
/**
* Gets an Object from the config.
*
* <p>This method is nested under {@link Unsafe} because the keys
* and return types may change between versions without warning.</p>
*
* @param key the key, as defined as a field name in
* the "ConfigKeys" class.
* @return the corresponding object, if one is present
* @throws IllegalArgumentException if the key isn't known
*/
@Nonnull
Object getObject(String key);
}
}
@@ -0,0 +1,54 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* A node with a traceable origin
*
* @since 2.11
*/
public interface LocalizedNode extends Node {
/**
* Gets the delegate node
*
* @return the node this instance is representing
*/
@Nonnull
Node getNode();
/**
* Gets the location where the {@link Node} is inherited from
*
* @return where the node was inherited from. Will not return null.
* @see PermissionHolder#getObjectName()
*/
@Nonnull
String getLocation();
}
@@ -0,0 +1,230 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Represents the internal LuckPerms log.
*
* <p>The returned instance provides a copy of the data at the time of retrieval.</p>
*
* <p>Any changes made to log entries will only apply to this instance of the log.
* You can add to the log using the {@link Storage}, and then request an updated copy.</p>
*
* <p>All methods are thread safe, and return immutable and thread safe collections.</p>
*/
public interface Log {
/**
* Get the content of the log
*
* @return a {@link SortedSet} of all of the {@link LogEntry} objects in this {@link Log}
*/
@Nonnull
SortedSet<LogEntry> getContent();
/**
* Get the content of the log
*
* @return all content in this log
*/
@Nonnull
SortedSet<LogEntry> getRecent();
/**
* Gets the recent content separated by page
*
* @param pageNo the page number
* @return the page content
* @throws IllegalArgumentException if the pageNo is less than 1
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getRecentMaxPages()}
*/
@Nonnull
SortedMap<Integer, LogEntry> getRecent(int pageNo);
/**
* Gets the max page number for the recent pages.
*
* @return the max page number allowed in the {@link #getRecent(int)} method
*/
int getRecentMaxPages();
/**
* Gets the recent content for a given actor
*
* @param actor the uuid of the actor to filter by
* @return all content in this log where is actor = uuid
*/
@Nonnull
SortedSet<LogEntry> getRecent(@Nonnull UUID actor);
/**
* Gets the recent content for a given actor, separated by page
*
* @param pageNo the page number
* @param actor the uuid of the actor to filter by
* @return the page content
* @throws IllegalArgumentException if the pageNo is less than 1
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getRecentMaxPages(UUID)}
*/
@Nonnull
SortedMap<Integer, LogEntry> getRecent(int pageNo, @Nonnull UUID actor);
/**
* Gets the max page number for the recent pages.
*
* @param actor the actor to filter by
* @return the max page number allowed in the {@link #getRecent(int, UUID)} method
*/
int getRecentMaxPages(@Nonnull UUID actor);
/**
* Gets the log content for a given user
*
* @param uuid the uuid to filter by
* @return all content in this log where the user = uuid
*/
@Nonnull
SortedSet<LogEntry> getUserHistory(@Nonnull UUID uuid);
/**
* Gets the log content for a given user, separated by page
*
* @param pageNo the page number
* @param uuid the uuid of the acted user to filter by
* @return the page content
* @throws IllegalArgumentException if the pageNo is less than 1
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getUserHistoryMaxPages(UUID)}
*/
@Nonnull
SortedMap<Integer, LogEntry> getUserHistory(int pageNo, @Nonnull UUID uuid);
/**
* Gets the max page number for the user history pages.
*
* @param uuid the uuid to filter by
* @return the max page number allowed in the {@link #getUserHistory(int, UUID)} method
*/
int getUserHistoryMaxPages(@Nonnull UUID uuid);
/**
* Gets the log content for a given group
*
* @param name the name to filter by
* @return all content in this log where the group = name
*/
@Nonnull
SortedSet<LogEntry> getGroupHistory(@Nonnull String name);
/**
* Gets the log content for a given group, separated by page
*
* @param pageNo the page number
* @param name the name of the acted group to filter by
* @return the page content
* @throws IllegalArgumentException if the pageNo is less than 1
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getGroupHistoryMaxPages(String)}
*/
@Nonnull
SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, @Nonnull String name);
/**
* Gets the max page number for the group history pages.
*
* @param name the name to filter by
* @return the max page number allowed in the {@link #getGroupHistory(int, String)} method
*/
int getGroupHistoryMaxPages(@Nonnull String name);
/**
* Gets the log content for a given track
*
* @param name the name to filter by
* @return all content in this log where the track = name
*/
@Nonnull
SortedSet<LogEntry> getTrackHistory(@Nonnull String name);
/**
* Gets the log content for a given track, separated by page
*
* @param pageNo the page number
* @param name the name of the acted track to filter by
* @return the page content
* @throws IllegalArgumentException if the pageNo is less than 1
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getTrackHistoryMaxPages(String)}
*/
@Nonnull
SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, @Nonnull String name);
/**
* Gets the max page number for the track history pages.
*
* @param name the name to filter by
* @return the max page number allowed in the {@link #getTrackHistory(int, String)} method
*/
int getTrackHistoryMaxPages(@Nonnull String name);
/**
* Gets the log content for a given search query
*
* @param query the query to filter by
* @return all content in this log where the content matches query
*/
@Nonnull
SortedSet<LogEntry> getSearch(@Nonnull String query);
/**
* Gets the log content for a given search query, separated by page
*
* @param pageNo the page number
* @param query the query to filter by
* @return the page content
* @throws IllegalArgumentException if the pageNo is less than 1
* @throws IllegalStateException if the log doesn't contain enough entries to populate the page. See {@link #getSearchMaxPages(String)}}
*/
@Nonnull
SortedMap<Integer, LogEntry> getSearch(int pageNo, @Nonnull String query);
/**
* Gets the max page number for the search query pages.
*
* @param query the query to filter by
* @return the max page number allowed in the {@link #getSearch(int, String)} method
*/
int getSearchMaxPages(@Nonnull String query);
}
@@ -0,0 +1,163 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import java.util.Optional;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents a logged action.
*/
public interface LogEntry extends Comparable<LogEntry> {
/**
* Gets the time in unix seconds when the action occurred.
*
* @return the timestamp
*/
long getTimestamp();
/**
* Gets the id of the object which performed the action.
*
* <p>This is the players uuid in most cases.</p>
*
* @return the actor id
*/
UUID getActor();
/**
* Gets the name describing the actor.
*
* @return the name of the actor
*/
String getActorName();
/**
* Gets the type of action.
*
* @return the action type
*/
Type getType();
/**
* Gets the uuid of the object which was acted upon.
*
* <p>Will only return a value for {@link Type#USER} entries.</p>
*
* @return the uuid of acted object
*/
Optional<UUID> getActed();
/**
* Gets the name describing the object which was acted upon
*
* @return the name of the acted object
*/
String getActedName();
/**
* Returns a string describing the action which took place.
*
* <p>In most instances, this returns a variation of the command string which caused
* the change.</p>
*
* @return the action
*/
String getAction();
/**
* Represents the type of a {@link LogEntry}.
*
* @since 3.3
*/
enum Type {
USER('U'),
GROUP('G'),
TRACK('T');
private final char code;
Type(char code) {
this.code = code;
}
public char getCode() {
return this.code;
}
public static Type valueOf(char code) {
switch (code) {
case 'U':
case 'u':
return USER;
case 'G':
case 'g':
return GROUP;
case 'T':
case 't':
return TRACK;
default:
throw new IllegalArgumentException("Unknown code: " + code);
}
}
}
/**
* Builds a LogEntry instance
*/
interface Builder {
@Nonnull
Builder setTimestamp(long timestamp);
@Nonnull
Builder setActor(@Nonnull UUID actor);
@Nonnull
Builder setActorName(@Nonnull String actorName);
@Nonnull
Builder setType(@Nonnull Type type);
@Nonnull
Builder setActed(@Nullable UUID acted);
@Nonnull
Builder setActedName(@Nonnull String actedName);
@Nonnull
Builder setAction(@Nonnull String action);
@Nonnull
LogEntry build();
}
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,124 +25,391 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.LuckPerms;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ContextManager;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.event.EventBus;
import me.lucko.luckperms.api.manager.GroupManager;
import me.lucko.luckperms.api.manager.TrackManager;
import me.lucko.luckperms.api.manager.UserManager;
import me.lucko.luckperms.api.metastacking.MetaStackFactory;
import me.lucko.luckperms.api.platform.PlatformInfo;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* The root Api interface in LuckPerms
* The LuckPerms API.
*
* <p>This interface is the base of the entire API package. All API functions
* are accessed via this interface.</p>
*
* <p>An instance can be obtained via {@link LuckPerms#getApi()}, or the platforms
* Services Manager.</p>
*/
@SuppressWarnings("unused")
public interface LuckPermsApi {
/**
* Gets information about the platform LuckPerms is running on.
*
* @return the platform info
* @since 4.0
*/
@Nonnull
PlatformInfo getPlatformInfo();
/**
* Gets the user manager
*
* @return the user manager
* @since 4.0
*/
@Nonnull
UserManager getUserManager();
/**
* Gets the group manager
*
* @return the group manager
* @since 4.0
*/
@Nonnull
GroupManager getGroupManager();
/**
* Gets the track manager
*
* @return the track manager
* @since 4.0
*/
@Nonnull
TrackManager getTrackManager();
/**
* Schedules an update task to run
*
* @since 4.0
*/
void runUpdateTask();
@Nonnull
CompletableFuture<Void> runUpdateTask();
/**
* @return the version of the plugin running on the platform
* Gets the event bus, used for subscribing to events
*
* @return the event bus
* @since 3.0
*/
String getVersion();
@Nonnull
EventBus getEventBus();
/**
* Gets a wrapped {@link LPConfiguration} instance, with read only access
* Gets the configuration
*
* @return a configuration instance
*/
@Nonnull
LPConfiguration getConfiguration();
/**
* Gets a wrapped {@link Datastore} instance, with somewhat limited access
* @return a datastore instance
* Gets the backend storage dao
*
* @return a storage instance
* @since 2.14
*/
Datastore getDatastore();
@Nonnull
Storage getStorage();
/**
* Gets the {@link Logger} wrapping used by the platform
* @return the logger instance
* Gets the messaging service
*
* @return an optional that may contain a messaging service instance.
*/
Logger getLogger();
@Nonnull
Optional<MessagingService> getMessagingService();
/**
* Gets a wrapped {@link UuidCache} instance, providing read access to the LuckPerms internal uuid caching system
* @return a uuidcache instance
* Gets a {@link UuidCache} instance, providing read access to the LuckPerms
* internal uuid caching system
*
* @return a uuid cache instance
*/
@Nonnull
UuidCache getUuidCache();
/**
* Gets the context manager
*
* @return the context manager
* @since 4.0
*/
ContextManager getContextManager();
/**
* Gets the node factory
*
* @return the node factory
*/
@Nonnull
NodeFactory getNodeFactory();
/**
* Gets the MetaStackFactory
*
* @return the meta stack factory
* @since 3.2
*/
@Nonnull
MetaStackFactory getMetaStackFactory();
// convenience methods
/**
* Gets a wrapped user object from the user storage
*
* @param uuid the uuid of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
* @throws NullPointerException if the uuid is null
*/
User getUser(UUID uuid);
@Nullable
default User getUser(@Nonnull UUID uuid) {
return getUserManager().getUser(uuid);
}
/**
* Gets a wrapped user object from the user storage. This method does not return null, unlike {@link #getUser(UUID)}
* Gets a wrapped user object from the user storage.
*
* @param uuid the uuid of the user to get
* @return an optional {@link User} object
* @throws NullPointerException if the uuid is null
*/
Optional<User> getUserSafe(UUID uuid);
@Nonnull
default Optional<User> getUserSafe(@Nonnull UUID uuid) {
return getUserManager().getUserOpt(uuid);
}
/**
* Gets a wrapped user object from the user storage
*
* @param name the username of the user to get
* @return a a {@link User} object, if one matching the uuid is loaded, or null if not
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
* @throws NullPointerException if the name is null
*/
User getUser(String name);
@Nullable
default User getUser(@Nonnull String name) {
return getUserManager().getUser(name);
}
/**
* Gets a wrapped user object from the user storage. This method does not return null, unlike {@link #getUser(String)}
* Gets a wrapped user object from the user storage.
*
* @param name the username of the user to get
* @return an optional {@link User} object
* @throws NullPointerException if the name is null
*/
Optional<User> getUserSafe(String name);
@Nonnull
default Optional<User> getUserSafe(@Nonnull String name) {
return getUserManager().getUserOpt(name);
}
/**
* Gets a set of all loaded users.
*
* @return a {@link Set} of {@link User} objects
*/
@Nonnull
default Set<User> getUsers() {
return getUserManager().getLoadedUsers();
}
/**
* Check if a user is loaded in memory
*
* @param uuid the uuid to check for
* @return true if the user is loaded
* @throws NullPointerException if the uuid is null
*/
boolean isUserLoaded(UUID uuid);
default boolean isUserLoaded(@Nonnull UUID uuid) {
return getUserManager().isLoaded(uuid);
}
/**
* Unload a user from the internal storage, if they're not currently online.
*
* @param user the user to unload
* @throws NullPointerException if the user is null
*/
default void cleanupUser(@Nonnull User user) {
getUserManager().cleanupUser(user);
}
/**
* Gets a wrapped group object from the group storage
*
* @param name the name of the group to get
* @return a {@link Group} object, if one matching the name exists, or null if not
* @throws NullPointerException if the name is null
*/
Group getGroup(String name);
@Nullable
default Group getGroup(@Nonnull String name) {
return getGroupManager().getGroup(name);
}
/**
* Gets a wrapped group object from the group storage. This method does not return null, unlike {@link #getGroup}
* Gets a wrapped group object from the group storage.
*
* <p>This method does not return null, unlike {@link #getGroup}</p>
*
* @param name the name of the group to get
* @return an optional {@link Group} object
* @throws NullPointerException if the name is null
*/
Optional<Group> getGroupSafe(String name);
@Nonnull
default Optional<Group> getGroupSafe(@Nonnull String name) {
return getGroupManager().getGroupOpt(name);
}
/**
* Gets a set of all loaded groups.
*
* @return a {@link Set} of {@link Group} objects
*/
@Nonnull
default Set<Group> getGroups() {
return getGroupManager().getLoadedGroups();
}
/**
* Check if a group is loaded in memory
*
* @param name the name to check for
* @return true if the group is loaded
* @throws NullPointerException if the name is null
*/
boolean isGroupLoaded(String name);
default boolean isGroupLoaded(@Nonnull String name) {
return getGroupManager().isLoaded(name);
}
/**
* Gets a wrapped track object from the track storage
*
* @param name the name of the track to get
* @return a {@link Track} object, if one matching the name exists, or null if not
* @return a {@link Track} object, if one matching the name exists, or null
* if not
* @throws NullPointerException if the name is null
*/
Track getTrack(String name);
@Nullable
default Track getTrack(@Nonnull String name) {
return getTrackManager().getTrack(name);
}
/**
* Gets a wrapped tracj object from the track storage. This method does not return null, unlike {@link #getTrack}
* Gets a wrapped track object from the track storage.
*
* <p>This method does not return null, unlike {@link #getTrack}</p>
*
* @param name the name of the track to get
* @return an optional {@link Track} object
* @throws NullPointerException if the name is null
*/
Optional<Track> getTrackSafe(String name);
@Nonnull
default Optional<Track> getTrackSafe(@Nonnull String name) {
return getTrackManager().getTrackOpt(name);
}
/**
* Gets a set of all loaded tracks.
*
* @return a {@link Set} of {@link Track} objects
*/
@Nonnull
default Set<Track> getTracks() {
return getTrackManager().getLoadedTracks();
}
/**
* Check if a track is loaded in memory
*
* @param name the name to check for
* @return true if the track is loaded
* @throws NullPointerException if the name is null
*/
boolean isTrackLoaded(String name);
default boolean isTrackLoaded(@Nonnull String name) {
return getTrackManager().isLoaded(name);
}
/**
* Returns a new LogEntry Builder instance
*
* @return a new builder
* @since 4.0
*/
LogEntry.Builder newLogEntryBuilder();
/**
* Returns a permission builder instance
*
* @param permission the main permission node to build
* @return a {@link Node.Builder} instance
* @throws IllegalArgumentException if the permission is invalid
* @throws NullPointerException if the permission is null
* @since 2.6
*/
@Nonnull
default Node.Builder buildNode(@Nonnull String permission) throws IllegalArgumentException {
return getNodeFactory().newBuilder(permission);
}
/**
* Register a custom context calculator to the server
*
* @param calculator the context calculator to register. The type MUST be the player class of the platform.
* @throws ClassCastException if the type is not the player class of the platform.
*/
default void registerContextCalculator(@Nonnull ContextCalculator<?> calculator) {
getContextManager().registerCalculator(calculator);
}
/**
* Gets a calculated context instance for the user using the rules of the platform.
*
* <p> These values are calculated using the options in the configuration, and the provided calculators.
*
* @param user the user to get contexts for
* @return an optional containing contexts. Will return empty if the user is not online.
*/
@Nonnull
default Optional<Contexts> getContextForUser(@Nonnull User user) {
return getContextManager().lookupApplicableContexts(user);
}
/**
* Gets set of contexts applicable to a player using the platforms {@link ContextCalculator}s.
*
* @param player the player to calculate for. Must be the player instance for the platform.
* @return a set of contexts.
* @since 2.17
*/
@Nonnull
default ContextSet getContextForPlayer(@Nonnull Object player) {
return getContextManager().getApplicableContext(player);
}
/**
* Gets a Contexts instance for the player using the platforms {@link ContextCalculator}s.
*
* @param player the player to calculate for. Must be the player instance for the platform.
* @return a set of contexts.
* @since 3.3
*/
@Nonnull
default Contexts getContextsForPlayer(@Nonnull Object player) {
return getContextManager().getApplicableContexts(player);
}
}
@@ -0,0 +1,43 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
/**
* A means to push changes to other servers using the platforms networking
*
* @since 2.14
*/
public interface MessagingService {
/**
* Uses the messaging service to inform other servers about changes.
*
* <p>This will push the update asynchronously, and this method will return immediately. Calling this method is
* equivalent to running "/lp networksync", except will not sync this server.</p>
*/
void pushUpdate();
}
@@ -0,0 +1,398 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* Represents a permission node.
*
* <p>All implementations of this interface must be immutable.</p>
*
* <p>Use the {@link NodeFactory} to obtain and construct instances.</p>
*
* @since 2.6
*/
public interface Node extends Map.Entry<String, Boolean> {
/**
* Gets the permission string
*
* @return the actual permission node
*/
@Nonnull
String getPermission();
/**
* Gets the value.
*
* <p>A negated node would return a value of <code>false</code>.</p>
*
* @return the permission's value
*/
@Override
@Nonnull
default Boolean getValue() {
return getValuePrimitive();
}
/**
* Gets the value.
*
* <p>A negated node would return a value of <code>false</code>.</p>
*
* @return the permission's value
*/
boolean getValuePrimitive();
/**
* Gets the value of this node as a {@link Tristate}
*
* @return the value of this node as a Tristate
*/
@Nonnull
default Tristate getTristate() {
return Tristate.fromBoolean(getValuePrimitive());
}
/**
* Gets if the node is negated
*
* @return true if the node is negated
*/
default boolean isNegated() {
return !getValuePrimitive();
}
/**
* Gets if this node is set to override explicitly.
*
* <p>This value does not persist across saves, and is therefore only useful for transient nodes</p>
*
* @return true if this node is set to override explicitly
*/
boolean isOverride();
/**
* Gets the server this node applies on, if the node is server specific
*
* @return an {@link Optional} containing the server, if one is defined
*/
@Nonnull
Optional<String> getServer();
/**
* Gets the world this node applies on, if the node is world specific
*
* @return an {@link Optional} containing the world, if one is defined
*/
@Nonnull
Optional<String> getWorld();
/**
* Gets if this node is server specific
*
* @return true if this node is server specific
*/
boolean isServerSpecific();
/**
* Gets if this node is server specific
*
* @return true if this node is server specific
*/
boolean isWorldSpecific();
/**
* Gets if this node applies globally, and therefore has no specific context
*
* @return true if this node applies globally, and has no specific context
* @since 3.1
*/
boolean appliesGlobally();
/**
* Gets if this node has any specific context in order for it to apply
*
* @return true if this node has specific context
* @since 3.1
*/
boolean hasSpecificContext();
/**
* Gets if this node should apply in the given context
*
* @param context the context key value pairs
* @return true if the node should apply
* @since 2.13
*/
boolean shouldApplyWithContext(@Nonnull ContextSet context);
/**
* Resolves any shorthand parts of this node and returns the full list
*
* @return a list of full nodes
*/
@Nonnull
List<String> resolveShorthand();
/**
* Gets if this node will expire in the future
*
* @return true if this node will expire in the future
*/
boolean isTemporary();
/**
* Gets if this node will not expire
*
* @return true if this node will not expire
*/
default boolean isPermanent() {
return !isTemporary();
}
/**
* Gets a unix timestamp in seconds when this node will expire
*
* @return the time in Unix time when this node will expire
* @throws IllegalStateException if the node is not temporary
*/
long getExpiryUnixTime() throws IllegalStateException;
/**
* Gets the date when this node will expire
*
* @return the {@link Date} when this node will expire
* @throws IllegalStateException if the node is not temporary
*/
@Nonnull
Date getExpiry() throws IllegalStateException;
/**
* Gets the number of seconds until this permission will expire
*
* @return the number of seconds until this permission will expire
* @throws IllegalStateException if the node is not temporary
*/
long getSecondsTilExpiry() throws IllegalStateException;
/**
* Gets if the node has expired.
*
* <p>This also returns false if the node is not temporary.</p>
*
* @return true if this node has expired
*/
boolean hasExpired();
/**
* Gets the extra contexts required for this node to apply
*
* @return the extra contexts required for this node to apply
* @since 2.13
*/
@Nonnull
ContextSet getContexts();
/**
* The same as {@link #getContexts()}, but also includes values for "server" and "world" keys if present.
*
* @return the full contexts required for this node to apply
* @since 3.1
*/
@Nonnull
ContextSet getFullContexts();
/**
* Gets if this is a group node
*
* @return true if this is a group node
*/
boolean isGroupNode();
/**
* Gets the name of the group, if this is a group node.
*
* @return the name of the group
* @throws IllegalStateException if this is not a group node. See {@link #isGroupNode()}
*/
@Nonnull
String getGroupName() throws IllegalStateException;
/**
* Gets if this node is a wildcard node
*
* @return true if this node is a wildcard node
*/
boolean isWildcard();
/**
* Gets the level of this wildcard, higher is more specific
*
* @return the wildcard level
* @throws IllegalStateException if this is not a wildcard
*/
int getWildcardLevel() throws IllegalStateException;
/**
* Gets if this node is a meta node
*
* @return true if this node is a meta node
*/
boolean isMeta();
/**
* Gets the meta value from this node
*
* @return the meta value
* @throws IllegalStateException if this node is not a meta node
*/
@Nonnull
Map.Entry<String, String> getMeta() throws IllegalStateException;
/**
* Gets if this node is a prefix node
*
* @return true if this node is a prefix node
*/
boolean isPrefix();
/**
* Gets the prefix value from this node
*
* @return the prefix value
* @throws IllegalStateException if this node is a not a prefix node
*/
@Nonnull
Map.Entry<Integer, String> getPrefix() throws IllegalStateException;
/**
* Gets if this node is a suffix node
*
* @return true if this node is a suffix node
*/
boolean isSuffix();
/**
* Gets the suffix value from this node
*
* @return the suffix value
* @throws IllegalStateException if this node is a not a suffix node
*/
@Nonnull
Map.Entry<Integer, String> getSuffix() throws IllegalStateException;
/**
* Checks if this Node is equal to another node
*
* @param obj the other node
* @return true if this node is equal to the other provided
* @see #equalsIgnoringValue(Node) for a less strict implementation of this method
*/
@Override
boolean equals(Object obj);
/**
* Similar to {@link Node#equals(Object)}, except doesn't take note of the value
*
* @param other the other node
* @return true if the two nodes are almost equal
*/
boolean equalsIgnoringValue(@Nonnull Node other);
/**
* Similar to {@link Node#equals(Object)}, except doesn't take note of the expiry time or value
*
* @param other the other node
* @return true if the two nodes are almost equal
*/
boolean almostEquals(@Nonnull Node other);
/**
* Similar to {@link Node#equals(Object)}, except doesn't take note of the value or if the node is temporary
*
* @param other the other node
* @return true if the two nodes are almost equal
* @since 2.8
*/
boolean equalsIgnoringValueOrTemp(@Nonnull Node other);
/**
* Builds a Node instance
*/
interface Builder {
@Nonnull
Builder setNegated(boolean negated);
@Nonnull
Builder setValue(boolean value);
/**
* Warning: this value does not persist, and disappears when the holder is re-loaded.
* It is therefore only useful for transient nodes.
*/
@Nonnull
Builder setOverride(boolean override);
@Nonnull
Builder setExpiry(long expireAt);
@Nonnull
Builder setWorld(@Nonnull String world);
@Nonnull
Builder setServer(@Nonnull String server) throws IllegalArgumentException;
@Nonnull
Builder withExtraContext(@Nonnull String key, @Nonnull String value);
@Nonnull
Builder withExtraContext(@Nonnull Map<String, String> map);
@Nonnull
Builder withExtraContext(@Nonnull Set<Map.Entry<String, String>> context);
@Nonnull
Builder withExtraContext(@Nonnull Map.Entry<String, String> entry);
@Nonnull
Builder withExtraContext(@Nonnull ContextSet set);
@Nonnull
Node build();
}
}
@@ -0,0 +1,126 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* Assists with constructing {@link Node} instances.
*
* @since 2.17
*/
public interface NodeFactory {
/**
* Creates a new node builder from a given base permission string
*
* @param permission the permission
* @return a node builder instance
* @throws NullPointerException if the permission is null
*/
@Nonnull
Node.Builder newBuilder(@Nonnull String permission);
/**
* Creates a node builder instance from an existing node
*
* @param other the other node
* @return a node builder instance
* @throws NullPointerException if the other node is null
*/
@Nonnull
Node.Builder newBuilderFromExisting(@Nonnull Node other);
/**
* Creates a node builder from a group
*
* @param group the group
* @return a node builder instance
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @since 3.1
*/
@Nonnull
Node.Builder makeGroupNode(@Nonnull Group group);
/**
* Creates a node builder from a group
*
* @param groupName the name of the group
* @return a node builder instance
* @throws NullPointerException if the groupName is null
* @since 4.0
*/
@Nonnull
Node.Builder makeGroupNode(@Nonnull String groupName);
/**
* Creates a node builder from a key value pair
*
* @param key the key
* @param value the value
* @return a node builder instance
* @throws NullPointerException if the key or value is null
*/
@Nonnull
Node.Builder makeMetaNode(@Nonnull String key, @Nonnull String value);
/**
* Creates a node builder for the given chat meta type
*
* @param priority the priority
* @param value the value for the prefix/suffix
* @return a node builder instance
* @throws NullPointerException if the type or value is null
* @since 3.2
*/
@Nonnull
Node.Builder makeChatMetaNode(@Nonnull ChatMetaType type, int priority, @Nonnull String value);
/**
* Creates a node builder from a prefix string and priority
*
* @param priority the priority
* @param prefix the prefix string
* @return a node builder instance
* @throws NullPointerException if the prefix is null
*/
@Nonnull
Node.Builder makePrefixNode(int priority, @Nonnull String prefix);
/**
* Creates a node builder from a prefix string and priority
*
* @param priority the priority
* @param suffix the suffix string
* @return a node builder instance
* @throws NullPointerException if the suffix is null
*/
@Nonnull
Node.Builder makeSuffixNode(int priority, @Nonnull String suffix);
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,297 +25,442 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
/**
* Wrapper interface for internal PermissionHolder (user/group) instances
* The implementations of this interface limit access to the object and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the object.
* An object which holds permissions.
*
* <p>Any changes made to permission holding objects will be lost unless the
* instance is saved back to the {@link Storage}.</p>
*/
@SuppressWarnings("unused")
public interface PermissionHolder {
/**
* Gets the objects name.
*
* <p>{@link User#getUuid()}, {@link User#getName()} or {@link Group#getName()} should normally be used instead of
* this method.</p>
*
* @return the identifier for this object. Either a uuid string or name.
*/
@Nonnull
String getObjectName();
Map<String, Boolean> getNodes();
/**
* Gets a friendly name for this holder, to be displayed in command output, etc.
*
* <p>This will <strong>always</strong> return a value, eventually falling back to {@link #getObjectName()} if no
* other "friendlier" identifiers are present.</p>
*
* @return a friendly identifier for this holder
* @since 3.2
*/
@Nonnull
String getFriendlyName();
/**
* Checks to see if the object has a certain permission
* @param node The permission node
* @param b If the node is true/false(negated)
* @return true if the user has the permission
* Gets the backing multimap containing every permission this holder has.
*
* <p>This method <b>does not</b> resolve inheritance rules, and returns a
* view of what's 'in the file'.</p>
*
* @return the holders own permissions
* @since 3.3
*/
boolean hasPermission(String node, boolean b);
@Nonnull
ImmutableSetMultimap<ImmutableContextSet, Node> getNodes();
/**
* Checks to see the the object has a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @return true if the user has the permission
* Gets the backing multimap containing every transient permission this holder has.
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Transient permissions only exist for the duration of the session.</p>
*
* @return the holders own permissions
* @since 3.3
*/
boolean hasPermission(String node, boolean b, String server);
@Nonnull
ImmutableSetMultimap<ImmutableContextSet, Node> getTransientNodes();
/**
* Checks to see the the object has a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @return true if the user has the permission
* Gets a flattened/squashed view of the holders permissions.
*
* <p>This list is constructed using the {@link Multimap#values()} method
* of both the transient and enduring backing multimaps.</p>
*
* <p>This means that it <b>may contain</b> duplicate entries.</p>
*
* <p>Use {@link #getPermissions()} for a view without duplicates.</p>
*
* @return a list of the holders own nodes.
* @since 3.3
*/
boolean hasPermission(String node, boolean b, String server, String world);
@Nonnull
List<Node> getOwnNodes();
/**
* Checks to see the the object has a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param temporary if the permission is temporary
* @return true if the user has the permission
* Gets a sorted set of all held permissions.
*
* @return an immutable set of permissions in priority order
* @since 2.6
*/
boolean hasPermission(String node, boolean b, boolean temporary);
@Nonnull
SortedSet<? extends Node> getPermissions();
/**
* Checks to see the the object has a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server to check on
* @param temporary if the permission is temporary
* @return true if the user has the permission
* Similar to {@link #getPermissions()}, except without transient permissions.
*
* <p>Unlike transient permissions, enduring permissions will be saved to storage, and exist after the session.</p>
*
* @return a set of nodes
* @since 2.6
*/
boolean hasPermission(String node, boolean b, String server, boolean temporary);
@Nonnull
Set<? extends Node> getEnduringPermissions();
/**
* Checks to see the the object has a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server to check on
* @param world The world to check on
* @param temporary if the permission is temporary
* @return true if the user has the permission
* Similar to {@link #getPermissions()}, except without enduring permissions.
*
* <p>Transient permissions only exist for the duration of the session.</p>
*
* @return a set of nodes
* @since 2.6
*/
boolean hasPermission(String node, boolean b, String server, String world, boolean temporary);
@Nonnull
Set<? extends Node> getTransientPermissions();
/**
* Checks to see if the object inherits a certain permission
* @param node The permission node
* @param b If the node is true/false(negated)
* @return true if the user inherits the permission
* Processes the nodes and returns the non-temporary ones.
*
* @return a set of permanent nodes
* @since 2.6
*/
boolean inheritsPermission(String node, boolean b);
@Nonnull
Set<Node> getPermanentPermissionNodes();
/**
* Checks to see the the object inherits a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @return true if the user inherits the permission
* Processes the nodes and returns the temporary ones.
*
* @return a set of temporary nodes
* @since 2.6
*/
boolean inheritsPermission(String node, boolean b, String server);
@Nonnull
Set<Node> getTemporaryPermissionNodes();
/**
* Checks to see the the object inherits a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @return true if the user inherits the permission
* Recursively resolves this holders permissions.
*
* <p>The returned list will contain every inherited
* node the holder has, in the order that they were inherited in.</p>
*
* <p>This means the list will contain duplicates.</p>
*
* @param contexts the contexts for the lookup
* @return a list of nodes
* @since 3.3
*/
boolean inheritsPermission(String node, boolean b, String server, String world);
@Nonnull
List<LocalizedNode> resolveInheritances(Contexts contexts);
/**
* Checks to see if the object inherits a certain permission
* @param node The permission node
* @param b If the node is true/false(negated)
* @param temporary if the permission is temporary
* @return true if the user inherits the permission
* Recursively resolves this holders permissions.
*
* <p>The returned list will contain every inherited
* node the holder has, in the order that they were inherited in.</p>
*
* <p>This means the list will contain duplicates.</p>
*
* <p>Unlike {@link #resolveInheritances(Contexts)}, this method does not
* filter by context, at all.</p>
*
* @return a list of nodes
* @since 3.3
*/
boolean inheritsPermission(String node, boolean b, boolean temporary);
@Nonnull
List<LocalizedNode> resolveInheritances();
/**
* Checks to see if the object inherits a certain permission
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param temporary if the permission is temporary
* @return true if the user inherits the permission
* Gets a mutable sorted set of the nodes that this object has and inherits, filtered by context
*
* <p>Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual nodes. The context is only
* used to determine which groups should apply.</p>
*
* <p>Nodes are sorted into priority order.</p>
*
* @param contexts the context for the lookup
* @return a mutable sorted set of permissions
* @throws NullPointerException if the context is null
* @since 2.11
*/
boolean inheritsPermission(String node, boolean b, String server, boolean temporary);
@Nonnull
SortedSet<LocalizedNode> getAllNodes(@Nonnull Contexts contexts);
/**
* Checks to see if the object inherits a certain permission
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @param temporary if the permission is temporary
* @return true if the user inherits the permission
* Gets a mutable sorted set of the nodes that this object has and inherits.
*
* <p>Unlike {@link #getAllNodes(Contexts)}, this method does not filter by context, at all.</p>
*
* <p>Nodes are sorted into priority order.</p>
*
* @return a mutable sorted set of permissions
* @throws NullPointerException if the context is null
* @since 3.3
*/
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
@Nonnull
SortedSet<LocalizedNode> getAllNodes();
/**
* Sets a permission for the object
* @param node The node to be set
* @param value What to set the node to - true/false(negated)
* @throws ObjectAlreadyHasException if the object already has the permission
* Gets a mutable set of the nodes that this object has and inherits, filtered by context.
*
* <p>Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes, and only return ones that fully
* meet the context provided.</p>
*
* @param contexts the context for the lookup
* @return a mutable set of permissions
* @throws NullPointerException if the context is null
* @since 2.11
*/
void setPermission(String node, boolean value) throws ObjectAlreadyHasException;
@Nonnull
Set<LocalizedNode> getAllNodesFiltered(@Nonnull Contexts contexts);
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @throws ObjectAlreadyHasException if the object already has the permission
* Converts the output of {@link #getAllNodesFiltered(Contexts)}, and expands shorthand permissions.
*
* @param contexts the context for the lookup
* @param lowerCase if the keys should be made lowercase whilst being exported
* @return a mutable map of permissions
*/
void setPermission(String node, boolean value, String server) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param world The world to set the permission on
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, String server, String world) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, long expireAt) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param world The world to set the permission on
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, String server, String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param temporary if the permission being removed is temporary
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, boolean temporary) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @param world The world to unset the node on
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server, String world) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @param temporary if the permission being unset is temporary
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server, boolean temporary) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @param world The world to unset the node on
* @param temporary if the permission being unset is temporary
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server, String world, boolean temporary) throws ObjectLacksException;
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param world The world to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes);
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param world The world to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups);
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes);
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups);
/**
* Processes the objects and returns the temporary ones.
* @return a map of temporary nodes
*/
Map<Map.Entry<String, Boolean>, Long> getTemporaryNodes();
/**
* Processes the objects and returns the non-temporary ones.
* @return a map of permanent nodes
*/
Map<String, Boolean> getPermanentNodes();
@Nonnull
Map<String, Boolean> exportNodes(@Nonnull Contexts contexts, boolean lowerCase);
/**
* Removes temporary permissions that have expired
*/
void auditTemporaryPermissions();
/**
* Checks to see if the object has a certain permission
*
* @param node the node to check for
* @return a Tristate for the holders permission status for the node
* @throws NullPointerException if the node is null
* @since 2.6
*/
@Nonnull
Tristate hasPermission(@Nonnull Node node);
/**
* Checks to see if the object has a certain permission
*
* @param node the node to check for
* @return a Tristate for the holders permission status for the node
* @throws NullPointerException if the node is null
* @since 2.6
*/
@Nonnull
Tristate hasTransientPermission(@Nonnull Node node);
/**
* Checks to see if the object inherits a certain permission
*
* @param node the node to check for
* @return a Tristate for the holders inheritance status for the node
* @throws NullPointerException if the node is null
* @since 2.6
*/
@Nonnull
Tristate inheritsPermission(@Nonnull Node node);
/**
* Sets a permission for the object
*
* @param node The node to be set
* @return the result of the operation
* @throws NullPointerException if the node is null
* @since 4.0
*/
@Nonnull
DataMutateResult setPermission(@Nonnull Node node);
/**
* Sets a transient permission for the object
*
* <p>A transient node is a permission that does not persist.
* Whenever a user logs out of the server, or the server restarts, this permission will disappear.
* It is never saved to the datastore, and therefore will not apply on other servers.</p>
*
* <p>This is useful if you want to temporarily set a permission for a user while they're online, but don't
* want it to persist, and have to worry about removing it when they log out.</p>
*
* <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}</p>
*
* @param node The node to be set
* @return the result of the operation
* @throws NullPointerException if the node is null
* @since 4.0
*/
@Nonnull
DataMutateResult setTransientPermission(@Nonnull Node node);
/**
* Unsets a permission for the object
*
* @param node The node to be unset
* @return the result of the operation
* @throws NullPointerException if the node is null
* @since 4.0
*/
@Nonnull
DataMutateResult unsetPermission(@Nonnull Node node);
/**
* Unsets a transient permission for the object
*
* @param node The node to be unset
* @return the result of the operation
* @throws NullPointerException if the node is null
* @since 4.0
*/
@Nonnull
DataMutateResult unsetTransientPermission(@Nonnull Node node);
/**
* Clears any nodes from the holder which pass the predicate
*
* @param test the predicate to test for nodes which should be removed
* @since 3.2
*/
void clearMatching(@Nonnull Predicate<Node> test);
/**
* Clears any transient nodes from the holder which pass the predicate
*
* @param test the predicate to test for nodes which should be removed
* @since 3.2
*/
void clearMatchingTransient(@Nonnull Predicate<Node> test);
/**
* Clears all nodes held by the object
*
* @since 2.17
*/
void clearNodes();
/**
* Clears all nodes held by the object in a specific context
*
* @param contextSet the contexts to filter by
* @since 3.2
*/
void clearNodes(@Nonnull ContextSet contextSet);
/**
* Clears all parent groups
*
* @since 2.17
*/
void clearParents();
/**
* Clears all parent groups in a specific context
*
* @param contextSet the contexts to filter by
* @since 3.2
*/
void clearParents(@Nonnull ContextSet contextSet);
/**
* Clears all meta held by the object
*
* @since 2.17
*/
void clearMeta();
/**
* Clears all meta held by the object in a specific context
*
* @param contextSet the contexts to filter by
* @since 3.2
*/
void clearMeta(@Nonnull ContextSet contextSet);
/**
* Clears all transient permissions the holder has.
*/
void clearTransientNodes();
/**
* Sets a permission for the object
*
* @param node The node to be set
* @return the result of the operation
* @throws NullPointerException if the node is null
* @since 3.1
* @deprecated now forwards to {@link #setPermission(Node)}.
*/
@Nonnull
@Deprecated
default DataMutateResult setPermissionUnchecked(@Nonnull Node node) {
return setPermission(node);
}
/**
* Sets a transient permission for the object
*
* @param node The node to be set
* @return the result of the operation
* @throws NullPointerException if the node is null
* @since 3.1
* @deprecated now forwards to {@link #setTransientPermission(Node)}
*/
@Nonnull
@Deprecated
default DataMutateResult setTransientPermissionUnchecked(@Nonnull Node node) {
return setTransientPermission(node);
}
/**
* Unsets a permission for the object
*
* @param node The node to be unset
* @throws NullPointerException if the node is null
* @return the result of the operation
* @since 3.1
* @deprecated now forwards to {@link #unsetPermission(Node)}
*/
@Nonnull
@Deprecated
default DataMutateResult unsetPermissionUnchecked(@Nonnull Node node) {
return unsetPermission(node);
}
/**
* Unsets a transient permission for the object
*
* @param node The node to be unset
* @throws NullPointerException if the node is null
* @return the result of the operation
* @since 3.1
* @deprecated now forwards to {@link #unsetTransientPermission(Node)}
*/
@Nonnull
@Deprecated
default DataMutateResult unsetTransientPermissionUnchecked(@Nonnull Node node) {
return unsetTransientPermission(node);
}
}
@@ -0,0 +1,307 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A means of loading and saving permission data to/from the backend.
*
* <p>All blocking methods return {@link CompletableFuture}s, which will be populated with the result once the data has been
* loaded/saved asynchronously. Care should be taken when using such methods to ensure that the main server thread is not
* blocked.</p>
*
* <p>Methods such as {@link CompletableFuture#get()} and equivalent should <strong>not</strong> be called on the main
* server thread. If you need to use the result of these operations on the main server thread, register a
* callback using {@link CompletableFuture#thenAcceptAsync(Consumer, Executor)} and {@link #getSyncExecutor()}.</p>
*
* @since 2.14
*/
public interface Storage {
/**
* Get the name of the storage implementation.
*
* @return the name of the implementation
*/
@Nonnull
String getName();
/**
* Gets whether the storage instance is allowing logins on the platform.
*
* @return true if logins are enabled
*/
boolean isAcceptingLogins();
/**
* Returns an executor which will run all passed runnables on the main server thread.
*
* @return an executor instance
*/
@Nonnull
Executor getSyncExecutor();
/**
* Returns an executor which will run all passed runnables asynchronously using the platforms scheduler and thread
* pools.
*
* @return an executor instance
*/
@Nonnull
Executor getAsyncExecutor();
/**
* Saves an action to storage
*
* @param entry the log entry to be saved
* @return true if the operation completed successfully.
* @throws NullPointerException if entry is null
*/
@Nonnull
CompletableFuture<Boolean> logAction(@Nonnull LogEntry entry);
/**
* Loads and returns the entire log from storage
*
* @return a log instance, could be null if loading failed
*/
@Nonnull
CompletableFuture<Log> getLog();
/**
* Loads a user's data from the main storage into the plugins local storage.
*
* @param uuid the uuid of the user to load
* @param username the users username, or null if it is not known.
* @return if the operation completed successfully
* @throws NullPointerException if uuid is null
*/
@Nonnull
CompletableFuture<Boolean> loadUser(@Nonnull UUID uuid, @Nullable String username);
/**
* Loads a user's data from the main storage into the plugins local storage.
*
* @param uuid the uuid of the user to load
* @return if the operation completed successfully
* @throws NullPointerException if uuid is null
*/
@Nonnull
default CompletableFuture<Boolean> loadUser(@Nonnull UUID uuid) {
return loadUser(uuid, null);
}
/**
* Saves a user object back to storage. You should call this after you make any changes to a user.
*
* @param user the user to save
* @return true if the operation completed successfully.
* @throws NullPointerException if user is null
* @throws IllegalStateException if the user instance was not obtained from LuckPerms.
*/
@Nonnull
CompletableFuture<Boolean> saveUser(@Nonnull User user);
/**
* Gets a set all "unique" user UUIDs.
*
* <p>"Unique" meaning the user isn't just a member of the "default" group.</p>
*
* @return a set of uuids, or null if the operation failed.
*/
@Nonnull
CompletableFuture<Set<UUID>> getUniqueUsers();
/**
* Searches for a list of users with a given permission.
*
* @param permission the permission to search for
* @return a list of held permissions, or null if the operation failed
* @throws NullPointerException if the permission is null
* @since 2.17
*/
@Nonnull
CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(@Nonnull String permission);
/**
* Creates and loads a group into the plugins local storage
*
* @param name the name of the group
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
@Nonnull
CompletableFuture<Boolean> createAndLoadGroup(@Nonnull String name);
/**
* Loads a group into the plugins local storage.
*
* @param name the name of the group
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
@Nonnull
CompletableFuture<Boolean> loadGroup(@Nonnull String name);
/**
* Loads all groups from the storage into memory
*
* @return true if the operation completed successfully.
*/
@Nonnull
CompletableFuture<Boolean> loadAllGroups();
/**
* Saves a group back to storage. You should call this after you make any changes to a group.
*
* @param group the group to save
* @return true if the operation completed successfully.
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
@Nonnull
CompletableFuture<Boolean> saveGroup(@Nonnull Group group);
/**
* Permanently deletes a group from storage.
*
* @param group the group to delete
* @return true if the operation completed successfully.
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
@Nonnull
CompletableFuture<Boolean> deleteGroup(@Nonnull Group group);
/**
* Searches for a list of groups with a given permission.
*
* @param permission the permission to search for
* @return a list of held permissions, or null if the operation failed
* @throws NullPointerException if the permission is null
* @since 2.17
*/
@Nonnull
CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(@Nonnull String permission);
/**
* Creates and loads a track into the plugins local storage
*
* @param name the name of the track
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
@Nonnull
CompletableFuture<Boolean> createAndLoadTrack(@Nonnull String name);
/**
* Loads a track into the plugins local storage.
*
* @param name the name of the track
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
@Nonnull
CompletableFuture<Boolean> loadTrack(@Nonnull String name);
/**
* Loads all tracks from the storage into memory
*
* @return true if the operation completed successfully.
*/
@Nonnull
CompletableFuture<Boolean> loadAllTracks();
/**
* Saves a track back to storage. You should call this after you make any changes to a track.
*
* @param track the track to save
* @return true if the operation completed successfully.
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
@Nonnull
CompletableFuture<Boolean> saveTrack(@Nonnull Track track);
/**
* Permanently deletes a track from storage
*
* @param track the track to delete
* @return true if the operation completed successfully.
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
@Nonnull
CompletableFuture<Boolean> deleteTrack(@Nonnull Track track);
/**
* Saves UUID caching data to the global cache
*
* @param username the users username
* @param uuid the users mojang unique id
* @return true if the operation completed successfully.
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
@Nonnull
CompletableFuture<Boolean> saveUUIDData(@Nonnull String username, @Nonnull UUID uuid);
/**
* Gets a UUID from a username
*
* @param username the corresponding username
* @return a uuid object, could be null
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
@Nonnull
CompletableFuture<UUID> getUUID(@Nonnull String username);
/**
* Gets a username from a UUID
*
* @param uuid the corresponding uuid
* @return a name string, could be null
* @throws NullPointerException if either parameters are null
* @since 2.17
*/
@Nonnull
CompletableFuture<String> getName(@Nonnull UUID uuid);
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,95 +25,131 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Wrapper interface for internal Track instances
* The implementations of this interface limit access to the Track and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the track.
* An ordered chain of {@link Group}s.
*/
@SuppressWarnings("unused")
public interface Track {
/**
* Gets the name of this track
*
* @return the name of this track
*/
@Nonnull
String getName();
/**
* Gets an ordered list of the groups on this track
* @return am ordered {@link List} of the groups on this track
* Gets a list of the groups on this track
*
* <p>Index 0 is the first/lowest group in (or start of) the track.</p>
*
* <p>The returned collection is immutable, and cannot be modified.</p>
*
* @return an ordered {@link List} of the groups on this track
*/
@Nonnull
List<String> getGroups();
/**
* Gets the number of groups on this track
*
* @return the number of groups on this track
*/
int getSize();
/**
* Gets the next group on the track, after the one provided
*
* <p>{@code null} is returned if the group is not on the track.</p>
*
* @param current the group before the group being requested
* @return the group name, or null if the end of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
String getNext(Group current) throws ObjectLacksException;
@Nullable
String getNext(@Nonnull Group current);
/**
* Gets the group before the group provided
* Gets the previous group on the track, before the one provided
*
* <p>{@code null} is returned if the group is not on the track.</p>
*
* @param current the group after the group being requested
* @return the group name, or null if the start of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
String getPrevious(Group current) throws ObjectLacksException;
@Nullable
String getPrevious(@Nonnull Group current);
/**
* Appends a group to the end of this track
*
* @param group the group to append
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
* @return the result of the operation
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
void appendGroup(Group group) throws ObjectAlreadyHasException;
DataMutateResult appendGroup(@Nonnull Group group);
/**
* Inserts a group at a certain position on this track
* @param group the group to be inserted
*
* @param group the group to be inserted
* @param position the index position (a value of 0 inserts at the start)
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
* @return the result of the operation
* @throws IndexOutOfBoundsException if the position is less than 0 or greater than the size of the track
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
void insertGroup(Group group, int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException;
DataMutateResult insertGroup(@Nonnull Group group, int position) throws IndexOutOfBoundsException;
/**
* Removes a group from this track
*
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
* @return the result of the operation
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
void removeGroup(Group group) throws ObjectLacksException;
DataMutateResult removeGroup(@Nonnull Group group);
/**
* Removes a group from this track
*
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
* @return the result of the operation
* @throws NullPointerException if the group is null
*/
void removeGroup(String group) throws ObjectLacksException;
DataMutateResult removeGroup(@Nonnull String group);
/**
* Checks if a group features on this track
*
* @param group the group to check
* @return true if the group is on this track
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
boolean containsGroup(Group group);
boolean containsGroup(@Nonnull Group group);
/**
* Checks if a group features on this track
*
* @param group the group to check
* @return true if the group is on this track
* @throws NullPointerException if the group is null
*/
boolean containsGroup(String group);
boolean containsGroup(@Nonnull String group);
/**
* Clear all of the groups within this track
* Clear all of the groups from this track
*/
void clearGroups();
@@ -0,0 +1,85 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* Represents three different states of a setting.
*
* <p>Possible values:</p>
* <p></p>
* <ul>
* <li>{@link #TRUE} - a positive setting</li>
* <li>{@link #FALSE} - a negative (negated) setting</li>
* <li>{@link #UNDEFINED} - a non-existent setting</li>
* </ul>
*/
public enum Tristate {
/**
* A value indicating a positive setting
*/
TRUE(true),
/**
* A value indicating a negative (negated) setting
*/
FALSE(false),
/**
* A value indicating a non-existent setting
*/
UNDEFINED(false);
/**
* Returns a {@link Tristate} from a boolean
*
* @param val the boolean value
* @return {@link #TRUE} or {@link #FALSE}, depending on the value of the boolean.
*/
@Nonnull
public static Tristate fromBoolean(boolean val) {
return val ? TRUE : FALSE;
}
private final boolean booleanValue;
Tristate(boolean booleanValue) {
this.booleanValue = booleanValue;
}
/**
* Returns the value of the Tristate as a boolean.
*
* <p>A value of {@link #UNDEFINED} converts to false.</p>
*
* @return a boolean representation of the Tristate.
*/
public boolean asBoolean() {
return booleanValue;
}
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,198 +25,119 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Wrapper interface for internal User instances
* The implementations of this interface limit access to the User and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the user.
* A player which holds permission data.
*/
@SuppressWarnings("unused")
public interface User extends PermissionHolder {
/**
* Gets the users unique ID
*
* @return the users Mojang assigned unique id
*/
@Nonnull
UUID getUuid();
/**
* @return the Users Username
* Gets the users username
*
* <p>Returns null if no username is associated with this user.</p>
*
* @return the users username
*/
@Nullable
String getName();
/**
* Gets the users primary group
* Gets the users current primary group.
*
* <p>The result of this method depends on which method is configured for primary group calculation. It may not
* be the same as any value set through {@link #setPrimaryGroup(String)}.</p>
*
* @return the users primary group
*/
@Nonnull
String getPrimaryGroup();
/**
* Sets a users primary group
* @param s the new primary group
* @throws ObjectAlreadyHasException if the user already has this set as their primary group
* Sets a users primary group. This will only take effect if platform is using stored primary groups.
*
* @param group the new primary group
* @return if the change was applied successfully
* @throws IllegalStateException if the user is not a member of that group
* @throws NullPointerException if the group is null
*/
void setPrimaryGroup(String s) throws ObjectAlreadyHasException;
DataMutateResult setPrimaryGroup(@Nonnull String group);
/**
* Refresh and re-assign the users permissions
* Gets the user's {@link UserData} cache.
*
* @return the users cached data.
* @since 3.2
*/
@Nonnull
UserData getCachedData();
/**
* Refreshes and applies any changes to the cached user data.
*
* @return the task future
* @since 4.0
*/
@Nonnull
CompletableFuture<Void> refreshCachedData();
/**
* Check to see if the user is a direct member of a group
*
* @param group The group to check membership of
* @return true if the user is a member of the group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
boolean isInGroup(@Nonnull Group group);
/**
* Check to see if the user is a direct member of a group in a specific context
*
* @param group the group to check membership of
* @param contextSet the context set to filter by
* @return true if the user is a member of the group
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @since 3.2
*/
boolean isInGroup(@Nonnull Group group, @Nonnull ContextSet contextSet);
/**
* Refresh and re-assign the users permissions.
*
* <p>This request is not buffered, and the refresh call will be ran directly. This should be called on an
* asynchronous thread.</p>
*
* @deprecated in favour of {@link #refreshCachedData()}.
*/
@Deprecated
void refreshPermissions();
/**
* Check to see if the user is a member of a group
* @param group The group to check membership of
* @return true if the user is a member of the group
* Pre-calculates some values in the user's data cache.
*
* <p>Is it <b>not</b> necessary to call this method before
* using {@link #getCachedData()}.</p>
*
* @since 2.17
* @deprecated because use of this method is no longer necessary.
*/
boolean isInGroup(Group group);
/**
* Check to see if a user is a member of a group on a specific server
* @param group The group to check membership of
* @param server The server to check on
* @return true if the user is a member of the group
*/
boolean isInGroup(Group group, String server);
/**
* Check to see if a user is a member of a group on a specific server
* @param group The group to check membership of
* @param server The server to check on
* @param world The world to check on
* @return true if the user is a member of the group
*/
boolean isInGroup(Group group, String server, String world);
/**
* Add a user to a group
* @param group The group to add the user to
* @throws ObjectAlreadyHasException if the user is already a member of the group
*/
void addGroup(Group group) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @param world The world to add the group on
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @param world The world to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove the user from a group
* @param group the group to remove the user from
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group the group to remove the user from
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param world The world to remove the group on
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server, String world) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param world The world to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
/**
* Clear all of the users permission nodes
*/
void clearNodes();
/**
* Get a {@link List} of all of the groups the user is a member of, on all servers
* @return a {@link List} of group names
*/
List<String> getGroupNames();
/**
* Get a {@link List} of the groups the user is a member of on a specific server
* @param server the server to check
* @param world the world to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server, String world);
/**
* Get a {@link List} of the groups the user is a member of on a specific server
* @param server the server to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server);
@Deprecated
void setupDataCache();
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,31 +27,39 @@ package me.lucko.luckperms.api;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* This UuidCache is a means of allowing users to have the same internal UUID across a network of offline mode servers
* or mixed offline mode and online mode servers. Platforms running in offline mode generate a random UUID for a user when
* they first join the server, but this UUID will then not be consistent across the network. LuckPerms will instead check
* the datastore cache, to get a UUID for a user that is consistent across an entire network.
* A UUID cache for online users, between external Mojang UUIDs, and internal LuckPerms UUIDs.
*
* If you want to get a user object from the datastore using the api on a server in offline mode, you will need to use this cache,
* OR use Datastore#getUUID, for users that are not online.
* <p>A user's internal LuckPerms UUID is always the same as their Mojang one,
* unless <code>use-server-uuids</code> is disabled.</p>
*
* WARNING: THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
* <p>When this setting is disabled, this cache becomes active, and allows you to convert
* between 'internal' and 'server provided' uuids.</p>
*
* <p><strong>This is only effective for online players. Use {@link Storage#getUUID(String)} for offline players.</strong></p>
*/
public interface UuidCache {
/**
* Gets a users internal "LuckPerms" UUID, from the one given by the server.
* @param external the UUID assigned by the server, through Player#getUniqueId or ProxiedPlayer#getUniqueId
* Gets a users "internal" LuckPerms UUID, from the one given by the server.
*
* <p>When <code>use-server-uuids</code> is true, this returns the same UUID instance.</p>
*
* @param mojangUuid the UUID assigned by the server, through <code>Player#getUniqueId</code> or <code>ProxiedPlayer#getUniqueId</code>
* @return the corresponding internal UUID
*/
UUID getUUID(UUID external);
@Nonnull
UUID getUUID(@Nonnull UUID mojangUuid);
/**
* Gets a users external, server assigned or Mojang assigned unique id, from the internal one used within LuckPerms.
* @param internal the UUID used within LuckPerms, through User#getUuid
* Gets a users "external", server assigned unique id, from the internal one used within LuckPerms.
*
* @param internalUuid the UUID used within LuckPerms, through <code>User#getUuid</code>
* @return the corresponding external UUID
*/
UUID getExternalUUID(UUID internal);
@Nonnull
UUID getExternalUUID(@Nonnull UUID internalUuid);
}
@@ -0,0 +1,126 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.caching;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
import javax.annotation.Nonnull;
/**
* Represents the context for a meta lookup.
*
* <p>Consisting of a standard {@link Contexts} element, plus options to define how
* the meta stack should be constructed.</p>
*
* @since 3.2
*/
public final class MetaContexts {
/**
* Creates a new meta contexts instance
*
* @param contexts the standard contexts for the query
* @param prefixStackDefinition the prefix stack definition to be used
* @param suffixStackDefinition the suffix stack definition to be used
* @return the new instance
*/
public static MetaContexts of(@Nonnull Contexts contexts, @Nonnull MetaStackDefinition prefixStackDefinition, @Nonnull MetaStackDefinition suffixStackDefinition) {
return new MetaContexts(contexts, prefixStackDefinition, suffixStackDefinition);
}
private final Contexts contexts;
private final MetaStackDefinition prefixStackDefinition;
private final MetaStackDefinition suffixStackDefinition;
// cache hashcode - this class is immutable, and is used as an index in the permission cache.
private final int hashCode;
/**
* Creates a new meta contexts instance
*
* @param contexts the standard contexts for the query
* @param prefixStackDefinition the prefix stack definition to be used
* @param suffixStackDefinition the suffix stack definition to be used
*/
public MetaContexts(@Nonnull Contexts contexts, @Nonnull MetaStackDefinition prefixStackDefinition, @Nonnull MetaStackDefinition suffixStackDefinition) {
this.contexts = Preconditions.checkNotNull(contexts, "contexts");
this.prefixStackDefinition = Preconditions.checkNotNull(prefixStackDefinition, "prefixStackDefinition");
this.suffixStackDefinition = Preconditions.checkNotNull(suffixStackDefinition, "suffixStackDefinition");
this.hashCode = calculateHashCode();
}
@Nonnull
public Contexts getContexts() {
return this.contexts;
}
@Nonnull
public MetaStackDefinition getPrefixStackDefinition() {
return this.prefixStackDefinition;
}
@Nonnull
public MetaStackDefinition getSuffixStackDefinition() {
return this.suffixStackDefinition;
}
@Override
@Nonnull
public String toString() {
return "MetaContexts(" +
"contexts=" + this.getContexts() + ", " +
"prefixStackDefinition=" + this.getPrefixStackDefinition() + ", " +
"suffixStackDefinition=" + this.getSuffixStackDefinition() +
")";
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof MetaContexts)) return false;
final MetaContexts other = (MetaContexts) o;
return this.getContexts().equals(other.getContexts()) &&
this.getPrefixStackDefinition().equals(other.getPrefixStackDefinition()) &&
this.getSuffixStackDefinition().equals(other.getSuffixStackDefinition());
}
private int calculateHashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.getContexts().hashCode();
result = result * PRIME + this.getPrefixStackDefinition().hashCode();
result = result * PRIME + this.getSuffixStackDefinition().hashCode();
return result;
}
@Override
public int hashCode() {
return hashCode;
}
}
@@ -0,0 +1,123 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.caching;
import com.google.common.collect.ListMultimap;
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
import java.util.Map;
import java.util.SortedMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Holds cached Meta lookup data for a specific set of contexts
*
* @since 2.13
*/
public interface MetaData {
/**
* Gets an immutable copy of the meta this user has.
*
* <p>A list multimap is used because when inherited values are included, each key can be
* mapped to multiple values.</p>
*
* <p>The first value to be accumulated (and used to represent the key in {@link #getMeta()} is at index 0
* in the list. Any additional values are stored in order of accumulation.</p>
*
* @return an immutable multimap of meta
* @since 3.3
*/
@Nonnull
ListMultimap<String, String> getMetaMultimap();
/**
* Gets an immutable copy of the meta this user has.
*
* <p>This map is formed by taking the entries in {@link #getMetaMultimap()}, and mapping each key
* to the value at index 0 in the corresponding list.</p>
*
* @return an immutable map of meta
*/
@Nonnull
Map<String, String> getMeta();
/**
* Gets an immutable sorted map of all of the prefixes the user has, whereby the first value is the highest priority
* prefix.
*
* @return a sorted map of prefixes
*/
@Nonnull
SortedMap<Integer, String> getPrefixes();
/**
* Gets an immutable sorted map of all of the suffixes the user has, whereby the first value is the highest priority
* suffix.
*
* @return a sorted map of suffixes
*/
@Nonnull
SortedMap<Integer, String> getSuffixes();
/**
* Gets the user's highest priority prefix, or null if the user has no prefixes
*
* @return a prefix string, or null
*/
@Nullable
String getPrefix();
/**
* Gets the user's highest priority suffix, or null if the user has no suffixes
*
* @return a suffix string, or null
*/
@Nullable
String getSuffix();
/**
* Gets the definition used for the prefix stack
*
* @return the definition used for the prefix stack
* @since 3.2
*/
@Nonnull
MetaStackDefinition getPrefixStackDefinition();
/**
* Gets the definition used for the suffix stack
*
* @return the definition used for the suffix stack
* @since 3.2
*/
@Nonnull
MetaStackDefinition getSuffixStackDefinition();
}
@@ -0,0 +1,66 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.caching;
import me.lucko.luckperms.api.Tristate;
import java.util.Map;
import javax.annotation.Nonnull;
/**
* Holds cached Permission lookup data for a specific set of contexts
*
* @since 2.13
*/
public interface PermissionData {
/**
* Gets a permission value for the given permission node
*
* @param permission the permission node
* @return a tristate result
* @throws NullPointerException if permission is null
*/
@Nonnull
Tristate getPermissionValue(@Nonnull String permission);
/**
* Invalidates the underlying permission calculator cache.
*
* <p>Can be called to allow for an update in defaults.</p>
*/
void invalidateCache();
/**
* Gets an immutable copy of the permission map backing the permission calculator
*
* @return an immutable set of permissions
*/
@Nonnull
Map<String, Boolean> getImmutableBacking();
}
@@ -0,0 +1,185 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.caching;
import me.lucko.luckperms.api.Contexts;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* Holds cached permission and meta lookup data for a {@link me.lucko.luckperms.api.User}.
*
* <p>Data is only likely to be available for online users. All calls will account for inheritance, as well as any
* default data provided by the platform. This calls are heavily cached and are therefore fast.</p>
*
* <p>For meta, both methods accepting {@link Contexts} and {@link MetaContexts} are provided. The only difference is that
* the latter allows you to define how the meta stack should be structured internally. Where {@link Contexts} are passed, the
* values from the configuration are used.</p>
*
* @since 2.13
*/
public interface UserData {
/**
* Gets PermissionData from the cache, given a specified context.
*
* <p>If the data is not cached, it is calculated. Therefore, this call could be costly.</p>
*
* @param contexts the contexts to get the permission data in
* @return a permission data instance
* @throws NullPointerException if contexts is null
*/
@Nonnull
PermissionData getPermissionData(@Nonnull Contexts contexts);
/**
* Gets MetaData from the cache, given a specified context.
*
* <p>If the data is not cached, it is calculated. Therefore, this call could be costly.</p>
*
* @param contexts the contexts to get the permission data in
* @return a meta data instance
* @throws NullPointerException if contexts is null
* @since 3.2
*/
@Nonnull
MetaData getMetaData(@Nonnull MetaContexts contexts);
/**
* Gets MetaData from the cache, given a specified context.
*
* <p>If the data is not cached, it is calculated. Therefore, this call could be costly.</p>
*
* @param contexts the contexts to get the permission data in
* @return a meta data instance
* @throws NullPointerException if contexts is null
*/
@Nonnull
MetaData getMetaData(@Nonnull Contexts contexts);
/**
* Calculates permission data, bypassing the cache.
*
* @param contexts the contexts to get permission data in
* @return a permission data instance
* @throws NullPointerException if contexts is null
*/
@Nonnull
PermissionData calculatePermissions(@Nonnull Contexts contexts);
/**
* Calculates meta data, bypassing the cache.
*
* @param contexts the contexts to get meta data in
* @return a meta data instance
* @throws NullPointerException if contexts is null
* @since 3.2
*/
@Nonnull
MetaData calculateMeta(@Nonnull MetaContexts contexts);
/**
* Calculates meta data, bypassing the cache.
*
* @param contexts the contexts to get meta data in
* @return a meta data instance
* @throws NullPointerException if contexts is null
*/
@Nonnull
MetaData calculateMeta(@Nonnull Contexts contexts);
/**
* Calculates permission data and stores it in the cache.
*
* <p>If there is already data cached for the given contexts, and if the resultant output is different,
* the cached value is updated.</p>
*
* @param contexts the contexts to recalculate in.
* @throws NullPointerException if contexts is null
*/
void recalculatePermissions(@Nonnull Contexts contexts);
/**
* Calculates meta data and stores it in the cache.
*
* <p>If there is already data cached for the given contexts, and if the resultant output is different,
* the cached value is updated.</p>
*
* @param contexts the contexts to recalculate in.
* @throws NullPointerException if contexts is null
* @since 3.2
*/
void recalculateMeta(@Nonnull MetaContexts contexts);
/**
* Calculates meta data and stores it in the cache.
*
* <p>If there is already data cached for the given contexts, and if the resultant output is different,
* the cached value is updated.</p>
*
* @param contexts the contexts to recalculate in.
* @throws NullPointerException if contexts is null
*/
void recalculateMeta(@Nonnull Contexts contexts);
/**
* Calls {@link #recalculatePermissions(Contexts)} for all current loaded contexts
*/
void recalculatePermissions();
/**
* Calls {@link #recalculateMeta(Contexts)} for all current loaded contexts
*/
void recalculateMeta();
/**
* Calls {@link #preCalculate(Contexts)} for the given contexts
*
* @param contexts a set of contexts
* @throws NullPointerException if contexts is null
*/
void preCalculate(@Nonnull Set<Contexts> contexts);
/**
* Ensures that PermissionData and MetaData is cached for a context.
*
* <p>If the cache does not contain any data for the context, it will be calculated and saved.</p>
*
* @param contexts the contexts to pre-calculate for
* @throws NullPointerException if contexts is null
*/
void preCalculate(@Nonnull Contexts contexts);
/**
* Invalidates all of the underlying Permission calculators.
*
* <p>Can be called to allow for an update in defaults.</p>
*/
void invalidatePermissionCalculators();
}
@@ -0,0 +1,50 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.context;
import javax.annotation.Nonnull;
/**
* Calculates whether contexts are applicable to {@link T}
*
* @param <T> the subject type. Is ALWAYS the player class of the platform.
* @since 2.13
*/
@FunctionalInterface
public interface ContextCalculator<T> {
/**
* Gives the subject all of the applicable contexts they meet
*
* @param subject the subject to add contexts to
* @param accumulator a map of contexts to add to
* @return the map
* @since 2.13
*/
@Nonnull
MutableContextSet giveApplicableContext(@Nonnull T subject, @Nonnull MutableContextSet accumulator);
}
@@ -0,0 +1,172 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.context;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.User;
import java.util.Optional;
import javax.annotation.Nonnull;
/**
* Manages {@link ContextCalculator}s, and calculates applicable contexts for a
* given type.
*
* This interface accepts {@link Object} types as a parameter to avoid having to depend
* on specific server implementations. In all cases, the "player" or "subject" type for
* the platform must be used.
*
* Specifically, {@code org.bukkit.entity.Player},
* {@code net.md_5.bungee.api.connection.ProxiedPlayer} and
* {@code org.spongepowered.api.service.permission.Subject}.
*
* @since 4.0
*/
public interface ContextManager {
/**
* Queries the ContextManager for current context values for the subject.
*
* @param subject the subject
* @return the applicable context for the subject
*/
@Nonnull
ImmutableContextSet getApplicableContext(@Nonnull Object subject);
/**
* Queries the ContextManager for current context values for the subject.
*
* @param subject the subject
* @return the applicable context for the subject
*/
@Nonnull
Contexts getApplicableContexts(@Nonnull Object subject);
/**
* Queries the ContextManager for current context values for the given User.
*
* <p>This will only return a value if the player corresponding to the
* {@link User} is online.</p>
*
* <p>If you need to be a {@link Contexts} instance regardless, you should
* initially try this method, and then fallback on {@link #getStaticContext()}.</p>
*
* @param user the user
* @return the applicable context for the subject
*/
@Nonnull
Optional<ImmutableContextSet> lookupApplicableContext(@Nonnull User user);
/**
* Queries the ContextManager for current context values for the given User.
*
* <p>This will only return a value if the player corresponding to the
* {@link User} is online.</p>
*
* <p>If you need to be a {@link Contexts} instance regardless, you should
* initially try this method, and then fallback on {@link #getStaticContexts()}.</p>
*
* @param user the user
* @return the applicable context for the subject
*/
@Nonnull
Optional<Contexts> lookupApplicableContexts(@Nonnull User user);
/**
* Gets the contexts from the static calculators in this manager.
*
* <p>Static calculators provide the same context for all subjects, and are
* marked as such when registered.</p>
*
* @return the current active static contexts
*/
@Nonnull
ImmutableContextSet getStaticContext();
/**
* Gets the contexts from the static calculators in this manager.
*
* <p>Static calculators provide the same context for all subjects, and are
* marked as such when registered.</p>
*
* @return the current active static contexts
*/
@Nonnull
Contexts getStaticContexts();
/**
* Forms a {@link Contexts} instance from an {@link ImmutableContextSet}.
*
* <p>This method relies on the plugins configuration to form the
* {@link Contexts} instance.</p>
*
* @param subject the reference subject
* @param contextSet the context set
* @return a contexts instance
*/
@Nonnull
Contexts formContexts(@Nonnull Object subject, @Nonnull ImmutableContextSet contextSet);
/**
* Forms a {@link Contexts} instance from an {@link ImmutableContextSet}.
*
* <p>This method relies on the plugins configuration to form the
* {@link Contexts} instance.</p>
*
* @param contextSet the context set
* @return a contexts instance
*/
@Nonnull
Contexts formContexts(@Nonnull ImmutableContextSet contextSet);
/**
* Registers a context calculator with the manager.
*
* @param calculator the calculator
*/
@Nonnull
void registerCalculator(@Nonnull ContextCalculator<?> calculator);
/**
* Registers a static context calculator with the manager.
*
* <p>Static calculators provide the same context for all subjects.</p>
*
* @param calculator the calculator
*/
@Nonnull
void registerStaticCalculator(@Nonnull StaticContextCalculator calculator);
/**
* Invalidates the lookup cache for a given subject
*
* @param subject the subject
*/
@Nonnull
void invalidateCache(@Nonnull Object subject);
}
@@ -0,0 +1,334 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.context;
import com.google.common.base.Preconditions;
import com.google.common.collect.Multimap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* A set of context pairs.
*
* <p>You can think of ContextSets as a wrapped <code>Multimap&lt;String, String&gt;</code>.
* Each key can be mapped to multiple values.</p>
*
* <p>Keys are automatically converted to lowercase when added, and are therefore
* case-insensitive. Values however are not.</p>
*
* <p>Implementations may be either mutable or immutable.</p>
*
* @since 2.13
*/
public interface ContextSet {
/**
* Creates an ImmutableContextSet from a context pair
*
* @param key the key
* @param value the value
* @return a new ImmutableContextSet containing one KV pair
* @throws NullPointerException if key or value is null
*/
@Nonnull
static ImmutableContextSet singleton(@Nonnull String key, @Nonnull String value) {
return ImmutableContextSet.singleton(key, value);
}
/**
* Creates an ImmutableContextSet from two context pairs
*
* @param key1 the first key
* @param value1 the first value
* @param key2 the second key
* @param value2 the second value
* @return a new ImmutableContextSet containing the two pairs
* @throws NullPointerException if any of the keys or values are null
* @since 3.1
*/
@Nonnull
static ImmutableContextSet of(@Nonnull String key1, @Nonnull String value1, @Nonnull String key2, @Nonnull String value2) {
return ImmutableContextSet.of(key1, value1, key2, value2);
}
/**
* Creates an ImmutableContextSet from an existing iterable of Map Entries
*
* @param iterable the iterable to copy from
* @return a new ImmutableContextSet representing the pairs in the iterable
* @throws NullPointerException if the iterable is null
*/
@Nonnull
static ImmutableContextSet fromEntries(@Nonnull Iterable<? extends Map.Entry<String, String>> iterable) {
return ImmutableContextSet.fromEntries(iterable);
}
/**
* Creates an ImmutableContextSet from an existing map
*
* @param map the map to copy from
* @return a new ImmutableContextSet representing the pairs from the map
* @throws NullPointerException if the map is null
*/
@Nonnull
static ImmutableContextSet fromMap(@Nonnull Map<String, String> map) {
return ImmutableContextSet.fromMap(map);
}
/**
* Creates an ImmutableContextSet from an existing multimap
*
* @param multimap the multimap to copy from
* @return a new ImmutableContextSet representing the pairs in the multimap
* @throws NullPointerException if the multimap is null
* @since 2.16
*/
@Nonnull
static ImmutableContextSet fromMultimap(@Nonnull Multimap<String, String> multimap) {
return ImmutableContextSet.fromMultimap(multimap);
}
/**
* Creates an new ImmutableContextSet from an existing set.
* Only really useful for converting between mutable and immutable types.
*
* @param contextSet the context set to copy from
* @return a new ImmutableContextSet with the same content and the one provided
* @throws NullPointerException if contextSet is null
*/
@Nonnull
static ImmutableContextSet fromSet(@Nonnull ContextSet contextSet) {
return ImmutableContextSet.fromSet(contextSet);
}
/**
* Creates a new empty ImmutableContextSet.
*
* @return a new ImmutableContextSet
*/
@Nonnull
static ImmutableContextSet empty() {
return ImmutableContextSet.empty();
}
/**
* Gets if this set is in an immutable form
*
* @return true if the set is immutable
*/
boolean isImmutable();
/**
* If the set is mutable, this method will return an immutable copy. Otherwise just returns itself.
*
* @return an immutable ContextSet
*/
@Nonnull
ImmutableContextSet makeImmutable();
/**
* Creates a mutable copy of this set.
*
* @return a mutable ContextSet
* @since 2.16
*/
@Nonnull
MutableContextSet mutableCopy();
/**
* Converts this ContextSet to an immutable {@link Set} of {@link Map.Entry}s.
*
* @return an immutable set
*/
@Nonnull
Set<Map.Entry<String, String>> toSet();
/**
* Converts this ContextSet to an immutable {@link Map}
*
* <b>IMPORTANT: Use of this method may result in data being lost. ContextSets can contain lots of different values for
* one key.</b>
*
* @return an immutable map
* @deprecated because the resultant map may not contain all data in the ContextSet
*/
@Nonnull
@Deprecated
Map<String, String> toMap();
/**
* Converts this ContextSet to an immutable {@link Multimap}
*
* @return a multimap
* @since 2.16
*/
@Nonnull
Multimap<String, String> toMultimap();
/**
* Check if the set contains at least one value for the given key.
*
* @param key the key to check for
* @return true if the set contains a value for the key
* @throws NullPointerException if the key is null
*/
boolean containsKey(@Nonnull String key);
/**
* Gets a set of all of the values mapped to the given key
*
* @param key the key to find values for
* @return a set of values
* @throws NullPointerException if the key is null
*/
@Nonnull
Set<String> getValues(@Nonnull String key);
/**
* Returns any value from this set matching the key, if present.
*
* @param key the key to find values for
* @return an optional containing any match
* @since 3.1
*/
@Nonnull
default Optional<String> getAnyValue(@Nonnull String key) {
return getValues(key).stream().findAny();
}
/**
* Check if thr set contains a given key mapped to a given value
*
* @param key the key to look for
* @param value the value to look for (case sensitive)
* @return true if the set contains the KV pair
* @throws NullPointerException if the key or value is null
*/
boolean has(@Nonnull String key, @Nonnull String value);
/**
* Check if thr set contains a given key mapped to a given value
*
* @param entry the entry to look for
* @return true if the set contains the KV pair
* @throws NullPointerException if the key or value is null
* @since 3.4
*/
default boolean has(@Nonnull Map.Entry<String, String> entry) {
Preconditions.checkNotNull(entry, "entry");
return has(entry.getKey(), entry.getValue());
}
/**
* Same as {@link #has(String, String)}, except ignores the case of the value.
*
* @param key the key to look for
* @param value the value to look for
* @return true if the set contains the KV pair
* @throws NullPointerException if the key or value is null
*/
boolean hasIgnoreCase(@Nonnull String key, @Nonnull String value);
/**
* Same as {@link #has(Map.Entry)}, except ignores the case of the value.
*
* @param entry the entry to look for
* @return true if the set contains the KV pair
* @throws NullPointerException if the key or value is null
* @since 3.4
*/
default boolean hasIgnoreCase(@Nonnull Map.Entry<String, String> entry) {
Preconditions.checkNotNull(entry, "entry");
return hasIgnoreCase(entry.getKey(), entry.getValue());
}
/**
* Checks to see if all entries in this context set are also included in another set.
*
* @param other the other set to check
* @return true if all entries in this set are also in the other set
* @since 3.1
*/
default boolean isSatisfiedBy(@Nonnull ContextSet other) {
return isSatisfiedBy(other, true);
}
/**
* Checks to see if all entries in this context set are also included in another set.
*
* @param other the other set to check
* @param caseSensitive if the lookup should be case sensitive. see {@link #has(Map.Entry)} and {@link #hasIgnoreCase(Map.Entry)}.
* @return true if all entries in this set are also in the other set
* @since 3.4
*/
default boolean isSatisfiedBy(@Nonnull ContextSet other, boolean caseSensitive) {
Preconditions.checkNotNull(other, "other");
if (this.isEmpty()) {
// this is empty, so is therefore always satisfied.
return true;
} else if (other.isEmpty()) {
// this set isn't empty, but the other one is
return false;
} else if (this.size() > other.size()) {
// this set has more unique entries than the other set, so there's no way this can be satisfied.
return false;
} else {
// neither are empty, we need to compare the individual entries
for (Map.Entry<String, String> pair : toSet()) {
if (caseSensitive) {
if (!other.has(pair)) {
return false;
}
} else {
if (!other.hasIgnoreCase(pair)) {
return false;
}
}
}
return true;
}
}
/**
* Check if the set is empty
*
* @return true if the set is empty
*/
boolean isEmpty();
/**
* Gets the number of key-value context pairs in the set
*
* @return the size of the set
*/
int size();
}
@@ -0,0 +1,274 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.context;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An immutable implementation of {@link ContextSet}.
*
* <p>On construction, all keys/values are {@link String#intern()}ed, in order to increase
* comparison speed.</p>
*
* @since 2.16
*/
public final class ImmutableContextSet implements ContextSet {
private static final ImmutableContextSet EMPTY = new ImmutableContextSet(ImmutableSetMultimap.of());
/**
* Creates an ImmutableContextSet from a context pair
*
* @param key the key
* @param value the value
* @return a new ImmutableContextSet containing one KV pair
* @throws NullPointerException if key or value is null
*/
@Nonnull
public static ImmutableContextSet singleton(@Nonnull String key, @Nonnull String value) {
return new ImmutableContextSet(ImmutableSetMultimap.of(
checkNotNull(key, "key").toLowerCase().intern(),
checkNotNull(value, "value").intern()
));
}
/**
* Creates an ImmutableContextSet from two context pairs
*
* @param key1 the first key
* @param value1 the first value
* @param key2 the second key
* @param value2 the second value
* @return a new ImmutableContextSet containing the two pairs
* @throws NullPointerException if any of the keys or values are null
* @since 3.1
*/
@Nonnull
public static ImmutableContextSet of(@Nonnull String key1, @Nonnull String value1, @Nonnull String key2, @Nonnull String value2) {
return new ImmutableContextSet(ImmutableSetMultimap.of(
checkNotNull(key1, "key1").toLowerCase().intern(),
checkNotNull(value1, "value1").intern(),
checkNotNull(key2, "key2").toLowerCase().intern(),
checkNotNull(value2, "value2").intern()
));
}
/**
* Creates an ImmutableContextSet from an existing iterable of Map Entries
*
* @param iterable the iterable to copy from
* @return a new ImmutableContextSet representing the pairs in the iterable
* @throws NullPointerException if the iterable is null
*/
@Nonnull
public static ImmutableContextSet fromEntries(@Nonnull Iterable<? extends Map.Entry<String, String>> iterable) {
checkNotNull(iterable, "iterable");
ImmutableSetMultimap.Builder<String, String> b = ImmutableSetMultimap.builder();
for (Map.Entry<String, String> e : iterable) {
b.put(checkNotNull(e.getKey()).toLowerCase().intern(), checkNotNull(e.getValue()).intern());
}
return new ImmutableContextSet(b.build());
}
/**
* Creates an ImmutableContextSet from an existing map
*
* @param map the map to copy from
* @return a new ImmutableContextSet representing the pairs from the map
* @throws NullPointerException if the map is null
*/
@Nonnull
public static ImmutableContextSet fromMap(@Nonnull Map<String, String> map) {
return fromEntries(checkNotNull(map, "map").entrySet());
}
/**
* Creates an ImmutableContextSet from an existing multimap
*
* @param multimap the multimap to copy from
* @return a new ImmutableContextSet representing the pairs in the multimap
* @throws NullPointerException if the multimap is null
*/
@Nonnull
public static ImmutableContextSet fromMultimap(@Nonnull Multimap<String, String> multimap) {
return fromEntries(checkNotNull(multimap, "multimap").entries());
}
/**
* Creates a new ImmutableContextSet from an existing set.
* Only really useful for converting between mutable and immutable types.
*
* @param contextSet the context set to copy from
* @return a new ImmutableContextSet with the same content and the one provided
* @throws NullPointerException if contextSet is null
*/
@Nonnull
public static ImmutableContextSet fromSet(@Nonnull ContextSet contextSet) {
return checkNotNull(contextSet, "contextSet").makeImmutable();
}
/**
* Creates an new empty ContextSet.
*
* @return a new ContextSet
*/
@Nonnull
public static ImmutableContextSet empty() {
return EMPTY;
}
private final ImmutableSetMultimap<String, String> map;
ImmutableContextSet(ImmutableSetMultimap<String, String> contexts) {
this.map = contexts;
}
@Override
public boolean isImmutable() {
return true;
}
@Override
@Deprecated // This set is already immutable!
@Nonnull
public ImmutableContextSet makeImmutable() {
return this;
}
@Override
@Nonnull
public MutableContextSet mutableCopy() {
return MutableContextSet.fromSet(this);
}
@Override
@Nonnull
public Set<Map.Entry<String, String>> toSet() {
return map.entries();
}
@Override
@Nonnull
public Map<String, String> toMap() {
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
for (Map.Entry<String, String> e : map.entries()) {
m.put(e.getKey(), e.getValue());
}
return m.build();
}
@Override
@Nonnull
public Multimap<String, String> toMultimap() {
return map;
}
@Override
@Nonnull
public boolean containsKey(@Nonnull String key) {
return map.containsKey(checkNotNull(key, "key").toLowerCase().intern());
}
@Override
@Nonnull
public Set<String> getValues(@Nonnull String key) {
Collection<String> values = map.get(checkNotNull(key, "key").toLowerCase().intern());
return values != null ? ImmutableSet.copyOf(values) : ImmutableSet.of();
}
@Override
@Nonnull
public boolean has(@Nonnull String key, @Nonnull String value) {
return map.containsEntry(checkNotNull(key, "key").toLowerCase().intern(), checkNotNull(value, "value").intern());
}
@Override
@Nonnull
public boolean hasIgnoreCase(@Nonnull String key, @Nonnull String value) {
value = checkNotNull(value, "value").intern();
Collection<String> values = map.get(checkNotNull(key, "key").toLowerCase().intern());
if (values == null || values.isEmpty()) {
return false;
}
for (String val : values) {
if (val.equalsIgnoreCase(value)) {
return true;
}
}
return false;
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public int size() {
return map.size();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ContextSet)) return false;
final ContextSet other = (ContextSet) o;
// saves on copying the multimap
if (other instanceof MutableContextSet) {
return other.equals(this);
}
final Multimap<String, String> thisContexts = this.toMultimap();
final Multimap<String, String> otherContexts = other.toMultimap();
return thisContexts.equals(otherContexts);
}
@Override
public int hashCode() {
return map.hashCode();
}
@Override
public String toString() {
return "ImmutableContextSet(contexts=" + this.map + ")";
}
}
@@ -0,0 +1,407 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.context;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A mutable implementation of {@link ContextSet}.
*
* <p>On construction, all keys/values are {@link String#intern()}ed, in order to increase
* comparison speed.</p>
*
* @since 2.16
*/
public final class MutableContextSet implements ContextSet {
/**
* Make a singleton MutableContextSet from a context pair
*
* @param key the key
* @param value the value
* @return a new MutableContextSet containing one KV pair
* @throws NullPointerException if key or value is null
*/
@Nonnull
public static MutableContextSet singleton(@Nonnull String key, @Nonnull String value) {
checkNotNull(key, "key");
checkNotNull(value, "value");
MutableContextSet set = MutableContextSet.create();
set.add(key, value);
return set;
}
/**
* Makes a MutableContextSet from two context pairs
*
* @param key1 the first key
* @param value1 the first value
* @param key2 the second key
* @param value2 the second value
* @return a new MutableContextSet containing the two pairs
* @throws NullPointerException if any of the keys or values are null
* @since 3.1
*/
@Nonnull
public static MutableContextSet of(@Nonnull String key1, @Nonnull String value1, @Nonnull String key2, @Nonnull String value2) {
checkNotNull(key1, "key1");
checkNotNull(value1, "value1");
checkNotNull(key2, "key2");
checkNotNull(value2, "value2");
MutableContextSet set = MutableContextSet.create();
set.add(key1, value1);
set.add(key2, value2);
return set;
}
/**
* Creates a MutableContextSet from an existing iterable of Map Entries
*
* @param iterable the iterable to copy from
* @return a new MutableContextSet representing the pairs in the iterable
* @throws NullPointerException if the iterable is null
*/
@Nonnull
public static MutableContextSet fromEntries(@Nonnull Iterable<? extends Map.Entry<String, String>> iterable) {
checkNotNull(iterable, "iterable");
MutableContextSet set = MutableContextSet.create();
set.addAll(iterable);
return set;
}
/**
* Creates a MutableContextSet from an existing map
*
* @param map the map to copy from
* @return a new MutableContextSet representing the pairs from the map
* @throws NullPointerException if the map is null
*/
@Nonnull
public static MutableContextSet fromMap(@Nonnull Map<String, String> map) {
checkNotNull(map, "map");
MutableContextSet set = MutableContextSet.create();
set.addAll(map);
return set;
}
/**
* Creates a MutableContextSet from an existing multimap
*
* @param multimap the multimap to copy from
* @return a new MutableContextSet representing the pairs in the multimap
* @throws NullPointerException if the multimap is null
*/
@Nonnull
public static MutableContextSet fromMultimap(@Nonnull Multimap<String, String> multimap) {
checkNotNull(multimap, "multimap");
MutableContextSet set = MutableContextSet.create();
set.addAll(multimap);
return set;
}
/**
* Creates a new MutableContextSet from an existing set.
* Only really useful for converting between mutable and immutable types.
*
* @param contextSet the context set to copy from
* @return a new MutableContextSet with the same content and the one provided
* @throws NullPointerException if contextSet is null
*/
@Nonnull
public static MutableContextSet fromSet(@Nonnull ContextSet contextSet) {
Preconditions.checkNotNull(contextSet, "contextSet");
MutableContextSet set = new MutableContextSet();
set.addAll(contextSet.toSet());
return set;
}
/**
* Creates a new empty MutableContextSet.
*
* @return a new MutableContextSet
*/
@Nonnull
public static MutableContextSet create() {
return new MutableContextSet();
}
private final SetMultimap<String, String> map;
public MutableContextSet() {
this.map = Multimaps.synchronizedSetMultimap(HashMultimap.create());
}
private MutableContextSet(MutableContextSet other) {
this.map = Multimaps.synchronizedSetMultimap(HashMultimap.create(other.map));
}
@Override
public boolean isImmutable() {
return false;
}
@Nonnull
@Override
public ImmutableContextSet makeImmutable() {
return new ImmutableContextSet(ImmutableSetMultimap.copyOf(map));
}
@Nonnull
@Override
public MutableContextSet mutableCopy() {
return new MutableContextSet(this);
}
@Nonnull
@Override
public Set<Map.Entry<String, String>> toSet() {
return ImmutableSet.copyOf(map.entries());
}
@Nonnull
@Override
public Map<String, String> toMap() {
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
for (Map.Entry<String, String> e : map.entries()) {
m.put(e.getKey(), e.getValue());
}
return m.build();
}
@Nonnull
@Override
public Multimap<String, String> toMultimap() {
return ImmutableSetMultimap.copyOf(map);
}
@Nonnull
@Override
public boolean containsKey(@Nonnull String key) {
return map.containsKey(checkNotNull(key, "key").toLowerCase().intern());
}
@Nonnull
@Override
public Set<String> getValues(@Nonnull String key) {
Collection<String> values = map.get(checkNotNull(key, "key").toLowerCase().intern());
return values != null ? ImmutableSet.copyOf(values) : ImmutableSet.of();
}
@Nonnull
@Override
public boolean has(@Nonnull String key, @Nonnull String value) {
return map.containsEntry(checkNotNull(key, "key").toLowerCase().intern(), checkNotNull(value, "value").intern());
}
@Nonnull
@Override
public boolean hasIgnoreCase(@Nonnull String key, @Nonnull String value) {
value = checkNotNull(value, "value").intern();
Collection<String> values = map.get(checkNotNull(key, "key").toLowerCase().intern());
if (values == null || values.isEmpty()) {
return false;
}
for (String val : values) {
if (val.equalsIgnoreCase(value)) {
return true;
}
}
return false;
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public int size() {
return map.size();
}
/**
* Adds a new key value pair to the set
*
* @param key the key to add
* @param value the value to add
* @throws NullPointerException if the key or value is null
*/
public void add(@Nonnull String key, @Nonnull String value) {
map.put(checkNotNull(key, "key").toLowerCase().intern(), checkNotNull(value, "value").intern());
}
/**
* Adds a new key value pair to the set
*
* @param entry the entry to add
* @throws NullPointerException if the entry is null
*/
public void add(@Nonnull Map.Entry<String, String> entry) {
checkNotNull(entry, "entry");
add(entry.getKey(), entry.getValue());
}
/**
* Adds an iterable containing contexts to the set
*
* @param iterable an iterable of key value context pairs
* @throws NullPointerException if iterable is null
*/
public void addAll(@Nonnull Iterable<? extends Map.Entry<String, String>> iterable) {
for (Map.Entry<String, String> e : checkNotNull(iterable, "iterable")) {
add(e);
}
}
/**
* Adds the entry set of a map to the set
*
* @param map the map to add from
* @throws NullPointerException if the map is null
*/
public void addAll(@Nonnull Map<String, String> map) {
addAll(checkNotNull(map, "map").entrySet());
}
/**
* Adds the entries of a multimap to the set
*
* @param multimap the multimap to add from
* @throws NullPointerException if the map is null
* @since 3.4
*/
public void addAll(@Nonnull Multimap<String, String> multimap) {
addAll(checkNotNull(multimap, "multimap").entries());
}
/**
* Adds of of the values in another ContextSet to this set
*
* @param contextSet the set to add from
* @throws NullPointerException if the contextSet is null
*/
public void addAll(@Nonnull ContextSet contextSet) {
checkNotNull(contextSet, "contextSet");
if (contextSet instanceof MutableContextSet) {
MutableContextSet other = ((MutableContextSet) contextSet);
this.map.putAll(other.map);
} else {
addAll(contextSet.toMultimap());
}
}
/**
* Remove a key value pair from this set
*
* @param key the key to remove
* @param value the value to remove (case sensitive)
* @throws NullPointerException if the key or value is null
*/
public void remove(@Nonnull String key, @Nonnull String value) {
String k = checkNotNull(key, "key").toLowerCase().intern();
String v = checkNotNull(value, "value").intern();
//noinspection StringEquality
map.entries().removeIf(entry -> entry.getKey() == k && entry.getValue() == v);
}
/**
* Same as {@link #remove(String, String)}, except ignores the case of the value
*
* @param key the key to remove
* @param value the value to remove
* @throws NullPointerException if the key or value is null
*/
public void removeIgnoreCase(@Nonnull String key, @Nonnull String value) {
String k = checkNotNull(key, "key").toLowerCase().intern();
String v = checkNotNull(value, "value").intern();
//noinspection StringEquality
map.entries().removeIf(e -> e.getKey() == k && e.getValue().equalsIgnoreCase(v));
}
/**
* Removes all pairs with the given key
*
* @param key the key to remove
* @throws NullPointerException if the key is null
*/
public void removeAll(@Nonnull String key) {
map.removeAll(checkNotNull(key, "key").toLowerCase());
}
/**
* Clears the set
*/
public void clear() {
map.clear();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ContextSet)) return false;
final ContextSet other = (ContextSet) o;
final Multimap<String, String> otherContexts;
if (other instanceof MutableContextSet) {
otherContexts = ((MutableContextSet) other).map;
} else {
otherContexts = other.toMultimap();
}
return this.map.equals(otherContexts);
}
@Override
public int hashCode() {
return map.hashCode();
}
@Override
public String toString() {
return "MutableContextSet(contexts=" + this.map + ")";
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.context;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Extension of {@link ContextCalculator} which provides the same context
* regardless of the subject.
*
* @since 4.0
*/
@FunctionalInterface
public interface StaticContextCalculator extends ContextCalculator<Object> {
/**
* Adds this calculators context to the given accumulator.
*
* @param accumulator a map of contexts to add to
* @return the map
*/
@Nonnull
MutableContextSet giveApplicableContext(@Nonnull MutableContextSet accumulator);
/**
* Gives the subject all of the applicable contexts they meet
*
* @param subject the subject to add contexts to
* @param accumulator a map of contexts to add to
* @return the map
*/
@Nonnull
@Override
@Deprecated
default MutableContextSet giveApplicableContext(@Nullable Object subject, @Nonnull MutableContextSet accumulator) {
return giveApplicableContext(accumulator);
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nonnull;
/**
* Represents an event that can be cancelled
*/
public interface Cancellable {
/**
* Gets an {@link AtomicBoolean} holding the cancellation state of the event
*
* @return the cancellation
*/
@Nonnull
AtomicBoolean getCancellationState();
}
@@ -0,0 +1,61 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event;
import java.util.Set;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
/**
* The LuckPerms event bus. Used for subscribing (or registering listeners) to events.
*
* @since 3.0
*/
public interface EventBus {
/**
* Subscribe to an event
*
* @param eventClass the event class
* @param handler the event handler
* @param <T> the event class
* @return an event handler instance representing this subscription
*/
@Nonnull
<T extends LuckPermsEvent> EventHandler<T> subscribe(@Nonnull Class<T> eventClass, @Nonnull Consumer<T> handler);
/**
* Gets a set of all registered handlers for a given event
*
* @param eventClass the event to find handlers for
* @param <T> the event class
* @return an immutable set of event handlers
*/
@Nonnull
<T extends LuckPermsEvent> Set<EventHandler<T>> getHandlers(@Nonnull Class<T> eventClass);
}
@@ -0,0 +1,76 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
/**
* Represents a handler for a LuckPerms event
*
* @param <T> the event class
*/
public interface EventHandler<T extends LuckPermsEvent> {
/**
* Gets the class this handler is listening to
*
* @return the event class
*/
@Nonnull
Class<T> getEventClass();
/**
* Returns true if this handler is active
*
* @return true if this handler is still active
*/
boolean isActive();
/**
* Unregisters this handler from the event bus
*
* @return true if the handler wasn't already unregistered
*/
boolean unregister();
/**
* Gets the event consumer responsible for handling the event
*
* @return the event consumer
*/
@Nonnull
Consumer<T> getConsumer();
/**
* Gets the number of times this handler has been called
*
* @return the number of times this handler has been called
*/
int getCallCount();
}
@@ -0,0 +1,47 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event;
import me.lucko.luckperms.api.LuckPermsApi;
import javax.annotation.Nonnull;
/**
* The base event interface
*
* @since 3.0
*/
public interface LuckPermsEvent {
/**
* Get the API instance this event was dispatched from
*
* @return the api instance
*/
@Nonnull
LuckPermsApi getApi();
}
@@ -0,0 +1,48 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.cause;
/**
* The cause of a group/track creation
*/
public enum CreationCause {
/**
* The creation was caused by a command
*/
COMMAND,
/**
* The creation was caused by an API call
*/
API,
/**
* The creation was caused by a LuckPerms internal
*/
INTERNAL
}
@@ -0,0 +1,48 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.cause;
/**
* The cause of a group/track deletion
*/
public enum DeletionCause {
/**
* The deletion was caused by a command
*/
COMMAND,
/**
* The deletion was caused by an API call
*/
API,
/**
* The deletion was caused by a LuckPerms internal
*/
INTERNAL
}
@@ -0,0 +1,55 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.group;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import me.lucko.luckperms.api.event.cause.CreationCause;
import javax.annotation.Nonnull;
/**
* Called when a group is created
*/
public interface GroupCreateEvent extends LuckPermsEvent {
/**
* Gets the new group
*
* @return the new group
*/
@Nonnull
Group getGroup();
/**
* Gets the cause of the creation
*
* @return the cause of the creation
*/
@Nonnull
CreationCause getCause();
}
@@ -0,0 +1,65 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.group;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import me.lucko.luckperms.api.event.cause.DeletionCause;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* Called when a group is deleted
*/
public interface GroupDeleteEvent extends LuckPermsEvent {
/**
* Gets the name of the deleted group
*
* @return the name of the deleted group
*/
@Nonnull
String getGroupName();
/**
* Gets an immutable copy of the groups existing data
*
* @return a copy of the groups existing data
*/
@Nonnull
Set<Node> getExistingData();
/**
* Gets the cause of the deletion
*
* @return the cause of the deletion
*/
@Nonnull
DeletionCause getCause();
}
@@ -0,0 +1,37 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.group;
import me.lucko.luckperms.api.event.LuckPermsEvent;
/**
* Called when all groups have been loaded in from storage.
*
* <p>Usually only called on startup and in sync tasks.</p>
*/
public interface GroupLoadAllEvent extends LuckPermsEvent {
}
@@ -0,0 +1,48 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.group;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import javax.annotation.Nonnull;
/**
* Called when a group is loaded into memory from the storage.
*
* Note that this event is not the same as {@link GroupCreateEvent}
*/
public interface GroupLoadEvent extends LuckPermsEvent {
/**
* Gets the group that was loaded
*
* @return the group that was loaded
*/
@Nonnull
Group getGroup();
}
@@ -0,0 +1,74 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.Cancellable;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import javax.annotation.Nonnull;
/**
* Called when a log entry is about to be sent to notifiable players on the platform
*/
public interface LogBroadcastEvent extends LuckPermsEvent, Cancellable {
/**
* Gets the log entry to be broadcasted
*
* @return the log entry to be broadcasted
*/
@Nonnull
LogEntry getEntry();
/**
* Gets where the log entry originated from.
*
* @return the origin of the log
* @since 3.3
*/
@Nonnull
Origin getOrigin();
/**
* Represents where a log entry is from
*
* @since 3.3
*/
enum Origin {
/**
* Represents a log entry which originated from the current server instance
*/
LOCAL,
/**
* Represents a log entry which was sent to this server via the messaging service
*/
REMOTE
}
}
@@ -0,0 +1,59 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.Cancellable;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called when a log is about to be published to the network via the MessagingService
*
* @since 3.3
*/
public interface LogNetworkPublishEvent extends LuckPermsEvent, Cancellable {
/**
* Gets the ID of the log entry being published
*
* @return the id of the log entry being published
*/
@Nonnull
UUID getLogId();
/**
* Gets the log entry to be published
*
* @return the log entry to be published
*/
@Nonnull
LogEntry getEntry();
}
@@ -0,0 +1,47 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.Cancellable;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import javax.annotation.Nonnull;
/**
* Called when a log is about to be published to the storage file/table
*/
public interface LogPublishEvent extends LuckPermsEvent, Cancellable {
/**
* Gets the log entry to be published
*
* @return the log entry to be published
*/
@Nonnull
LogEntry getEntry();
}
@@ -0,0 +1,58 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called when a log entry is received via the MessagingService
*
* @since 3.3
*/
public interface LogReceiveEvent extends LuckPermsEvent {
/**
* Gets the ID of the log entry being received
*
* @return the id of the log entry being received
*/
@Nonnull
UUID getLogId();
/**
* Gets the log entry being received
*
* @return the log entry being received
*/
@Nonnull
LogEntry getEntry();
}
@@ -0,0 +1,45 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.node;
import me.lucko.luckperms.api.Node;
import javax.annotation.Nonnull;
/**
* Called when a node is added to a holder
*/
public interface NodeAddEvent extends NodeMutateEvent {
/**
* Gets the node that was added
*
* @return the node that was added
*/
@Nonnull
Node getNode();
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,14 +23,11 @@
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
package me.lucko.luckperms.api.event.node;
/**
* Wrapper class to represent a CommandSender in Bukkit/Bungee within the luckperms-common command implementations.
* Called when a holder has their nodes cleared
*/
public interface Sender {
void sendMessage(String s);
boolean hasPermission(String node);
public interface NodeClearEvent extends NodeMutateEvent {
}
@@ -0,0 +1,83 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.node;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.PermissionHolder;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* Called when a node is added to/removed from a user/group
*/
public interface NodeMutateEvent extends LuckPermsEvent {
/**
* Gets the target of the event
*
* @return the event target
*/
@Nonnull
PermissionHolder getTarget();
/**
* Gets an immutable copy of the holders data before the change
*
* @return the data before the change
*/
@Nonnull
Set<Node> getDataBefore();
/**
* Gets an immutable copy of the holders data after the change
*
* @return the data after the change
*/
@Nonnull
Set<Node> getDataAfter();
/**
* Gets whether the target of this event is a {@link me.lucko.luckperms.api.User}
*
* <p>This is equivalent to checking if getTarget() instanceof User</p>
*
* @return if the event is targeting a user
*/
boolean isUser();
/**
* Gets whether the target of this event is a {@link me.lucko.luckperms.api.Group}
*
* <p>This is equivalent to checking if getTarget() instanceof Group</p>
*
* @return if the event is targeting a group
*/
boolean isGroup();
}
@@ -0,0 +1,45 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.node;
import me.lucko.luckperms.api.Node;
import javax.annotation.Nonnull;
/**
* Called when a node is removed from a holder
*/
public interface NodeRemoveEvent extends NodeMutateEvent {
/**
* Gets the node that was removed
*
* @return the node that was removed
*/
@Nonnull
Node getNode();
}
@@ -0,0 +1,35 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.sync;
import me.lucko.luckperms.api.event.LuckPermsEvent;
/**
* Called when the configuration is reloaded
*/
public interface ConfigReloadEvent extends LuckPermsEvent {
}
@@ -0,0 +1,35 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.sync;
import me.lucko.luckperms.api.event.LuckPermsEvent;
/**
* Called when an sync task has been completed
*/
public interface PostSyncEvent extends LuckPermsEvent {
}
@@ -0,0 +1,48 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.sync;
import me.lucko.luckperms.api.event.Cancellable;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called before a received network sync task runs
*/
public interface PreNetworkSyncEvent extends LuckPermsEvent, Cancellable {
/**
* Gets the ID of the sync request
*
* @return the id of the sync request
*/
@Nonnull
UUID getSyncId();
}
@@ -0,0 +1,36 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.sync;
import me.lucko.luckperms.api.event.Cancellable;
import me.lucko.luckperms.api.event.LuckPermsEvent;
/**
* Called before a sync task runs
*/
public interface PreSyncEvent extends LuckPermsEvent, Cancellable {
}
@@ -0,0 +1,55 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.track;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import me.lucko.luckperms.api.event.cause.CreationCause;
import javax.annotation.Nonnull;
/**
* Called when a track is created
*/
public interface TrackCreateEvent extends LuckPermsEvent {
/**
* Gets the new track
*
* @return the new track
*/
@Nonnull
Track getTrack();
/**
* Gets the cause of the creation
*
* @return the cause of the creation
*/
@Nonnull
CreationCause getCause();
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,26 +23,42 @@
* SOFTWARE.
*/
package me.lucko.luckperms.commands.misc;
package me.lucko.luckperms.api.event.track;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SingleMainCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.utils.LPConfiguration;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import me.lucko.luckperms.api.event.cause.DeletionCause;
import java.util.List;
public class InfoCommand extends SingleMainCommand {
public InfoCommand() {
super("Info", "/%s info", 0, Permission.INFO);
}
import javax.annotation.Nonnull;
/**
* Called when a track is deleted
*/
public interface TrackDeleteEvent extends LuckPermsEvent {
/**
* Gets the name of the deleted track
*
* @return the name of the deleted track
*/
@Nonnull
String getTrackName();
/**
* Gets an immutable copy of the tracks existing data
*
* @return a copy of the tracks existing data
*/
@Nonnull
List<String> getExistingData();
/**
* Gets the cause of the deletion
*
* @return the cause of the deletion
*/
@Nonnull
DeletionCause getCause();
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
final LPConfiguration c = plugin.getConfiguration();
Message.INFO.send(sender, plugin.getVersion(), plugin.getDatastore().getName(), c.getServer(),
c.getDefaultGroupName(), c.getSyncTime(), c.getIncludeGlobalPerms(), c.getOnlineMode());
}
}
@@ -0,0 +1,37 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.track;
import me.lucko.luckperms.api.event.LuckPermsEvent;
/**
* Called when all tracks have been loaded in from storage.
*
* <p>Usually only called on startup and in sync tasks.</p>
*/
public interface TrackLoadAllEvent extends LuckPermsEvent {
}
@@ -0,0 +1,48 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.track;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import javax.annotation.Nonnull;
/**
* Called when a track is loaded into memory from the storage.
*
* Note that this event is not the same as {@link TrackCreateEvent}
*/
public interface TrackLoadEvent extends LuckPermsEvent {
/**
* Gets the track that was loaded
*
* @return the track that was loaded
*/
@Nonnull
Track getTrack();
}
@@ -0,0 +1,43 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.track.mutate;
import javax.annotation.Nonnull;
/**
* Called when a group is added to a track
*/
public interface TrackAddGroupEvent extends TrackMutateEvent {
/**
* Gets the group that was added
*
* @return the group that was added
*/
@Nonnull
String getGroup();
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,11 +23,11 @@
* SOFTWARE.
*/
package me.lucko.luckperms.exceptions;
package me.lucko.luckperms.api.event.track.mutate;
/**
* Thrown when a permission holding object already has a permission, is already a member of a group, or when a track
* already contains a group.
* Called when a track is cleared
*/
public class ObjectAlreadyHasException extends Exception {
public interface TrackClearEvent extends TrackMutateEvent {
}
@@ -0,0 +1,64 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.track.mutate;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.List;
import javax.annotation.Nonnull;
/**
* Called when a track is changed
*/
public interface TrackMutateEvent extends LuckPermsEvent {
/**
* Gets the track that was mutated
*
* @return the track that was mutated
*/
@Nonnull
Track getTrack();
/**
* Gets an immutable copy of the tracks data before the change
*
* @return the data before the change
*/
@Nonnull
List<String> getDataBefore();
/**
* Gets an immutable copy of the tracks data after the change
*
* @return the data after the change
*/
@Nonnull
List<String> getDataAfter();
}
@@ -0,0 +1,43 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.track.mutate;
import javax.annotation.Nonnull;
/**
* Called when a group is removed from a track
*/
public interface TrackRemoveGroupEvent extends TrackMutateEvent {
/**
* Gets the group that was removed
*
* @return the group that was removed
*/
@Nonnull
String getGroup();
}
@@ -0,0 +1,55 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import javax.annotation.Nonnull;
/**
* Called when a users {@link me.lucko.luckperms.api.caching.UserData} is loaded.
*/
public interface UserCacheLoadEvent extends LuckPermsEvent {
/**
* Gets the user whose data was loaded
*
* @return the user
*/
@Nonnull
User getUser();
/**
* Gets the data that was loaded
*
* @return the loaded data
*/
@Nonnull
UserData getLoadedData();
}
@@ -0,0 +1,55 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import javax.annotation.Nonnull;
/**
* Called when a users cached data is refreshed
*/
public interface UserDataRecalculateEvent extends LuckPermsEvent {
/**
* Gets the user whose data was recalculated
*
* @return the user
*/
@Nonnull
User getUser();
/**
* Gets the data that was recalculated
*
* @return the data
*/
@Nonnull
UserData getData();
}
@@ -0,0 +1,63 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called when the user logs into the network for the first time.
*
* <p>Particularly useful for networks with multiple
* lobbies, who want to welcome a user when they join for the first time.</p>
*
* <p>This event is fired before the player has actually joined the game on the async login / auth event. If you want to
* do something with the user, store the UUID in a set, and then check the set in the PlayerJoinEvent o.e.</p>
*
* <p>The users data will not be loaded when this event is called.</p>
*/
public interface UserFirstLoginEvent extends LuckPermsEvent {
/**
* Gets the UUID of the user
*
* @return the uuid of the user
*/
@Nonnull
UUID getUuid();
/**
* Gets the username of the user
*
* @return the username of the user
*/
@Nonnull
String getUsername();
}
@@ -0,0 +1,46 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import javax.annotation.Nonnull;
/**
* Called when a user is loaded into memory from the storage.
*/
public interface UserLoadEvent extends LuckPermsEvent {
/**
* Gets the user that was loaded
*
* @return the user that was loaded
*/
@Nonnull
User getUser();
}
@@ -0,0 +1,72 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called when LuckPerms has finished processing a certain Player's connection.
*
* <p>This event will always execute during the platforms async login/auth event.
* All handlers will be called instantly.</p>
*
* <p>This, among other things, allows you to wait until permission data is loaded
* for a User during the BungeeCord 'LoginEvent', as event priorities are ignored
* by the current implementation.</p>
*
* @since 3.4
*/
public interface UserLoginProcessEvent extends LuckPermsEvent {
/**
* Gets the UUID of the connection which was processed
*
* @return the uuid of the connection which was processed
*/
@Nonnull
UUID getUuid();
/**
* Gets the username of the connection which was processed
*
* @return the username of the connection which was processed
*/
@Nonnull
String getUsername();
/**
* Gets the resultant User instance which was loaded.
*
* @return the user instance
*/
User getUser();
}
@@ -0,0 +1,43 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user.track;
/**
* Represents the type of action performed in a {@link UserTrackEvent}
*/
public enum TrackAction {
/**
* The user was promoted up a track
*/
PROMOTION,
/**
* The user was demoted down a track
*/
DEMOTION
}
@@ -0,0 +1,35 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user.track;
/**
* Called when a user is demoted down a track.
*
* <p>{@link #getAction()} is always {@link TrackAction#DEMOTION}</p>
*/
public interface UserDemoteEvent extends UserTrackEvent {
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,17 +23,13 @@
* SOFTWARE.
*/
package me.lucko.luckperms.api;
package me.lucko.luckperms.api.event.user.track;
/**
* A wrapper class for platform logger instances.
* Bukkit/Bungee both use java.util.logging, and Sponge uses org.slf4j. This class wraps those classes so the commons
* module can access a logger.
* Called when a user is promoted up a track.
*
* <p>{@link #getAction()} is always {@link TrackAction#PROMOTION}</p>
*/
public interface Logger {
void info(String s);
void warn(String s);
void severe(String s);
public interface UserPromoteEvent extends UserTrackEvent {
}
@@ -0,0 +1,83 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.event.user.track;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.Optional;
import javax.annotation.Nonnull;
/**
* Called when a user interacts with a track through a promotion or demotion
*/
public interface UserTrackEvent extends LuckPermsEvent {
/**
* Gets the track involved in the event
*
* @return the track involved in the event
*/
@Nonnull
Track getTrack();
/**
* Gets the user who was promoted or demoted
*
* @return the user involved in the event
*/
@Nonnull
User getUser();
/**
* Gets the action performed
*
* @return the action performed
*/
@Nonnull
TrackAction getAction();
/**
* Gets the group the user was promoted/demoted from.
*
* <p>May be {@link Optional#empty()} if the user wasn't already placed on the track.</p>
*
* @return the group the user was promoted/demoted from
*/
@Nonnull
Optional<String> getGroupFrom();
/**
* Gets the group the user was promoted/demoted to
*
* @return the group the user was promoted/demoted to
*/
@Nonnull
Optional<String> getGroupTo();
}
@@ -0,0 +1,84 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.manager;
import me.lucko.luckperms.api.Group;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents the object responsible for managing {@link Group} instances.
*
* @since 4.0
*/
public interface GroupManager {
/**
* Gets a wrapped group object from the group storage
*
* @param name the name of the group to get
* @return a {@link Group} object, if one matching the name exists, or null if not
* @throws NullPointerException if the name is null
*/
@Nullable
Group getGroup(@Nonnull String name);
/**
* Gets a wrapped group object from the group storage.
*
* <p>This method does not return null, unlike {@link #getGroup}</p>
*
* @param name the name of the group to get
* @return an optional {@link Group} object
* @throws NullPointerException if the name is null
*/
@Nonnull
default Optional<Group> getGroupOpt(@Nonnull String name) {
return Optional.ofNullable(getGroup(name));
}
/**
* Gets a set of all loaded groups.
*
* @return a {@link Set} of {@link Group} objects
*/
@Nonnull
Set<Group> getLoadedGroups();
/**
* Check if a group is loaded in memory
*
* @param name the name to check for
* @return true if the group is loaded
* @throws NullPointerException if the name is null
*/
boolean isLoaded(@Nonnull String name);
}
@@ -0,0 +1,84 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.manager;
import me.lucko.luckperms.api.Track;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents the object responsible for managing {@link Track} instances.
*
* @since 4.0
*/
public interface TrackManager {
/**
* Gets a wrapped track object from the track storage
*
* @param name the name of the track to get
* @return a {@link Track} object, if one matching the name exists, or null if not
* @throws NullPointerException if the name is null
*/
@Nullable
Track getTrack(@Nonnull String name);
/**
* Gets a wrapped track object from the track storage.
*
* <p>This method does not return null, unlike {@link #getTrack}</p>
*
* @param name the name of the track to get
* @return an optional {@link Track} object
* @throws NullPointerException if the name is null
*/
@Nonnull
default Optional<Track> getTrackOpt(@Nonnull String name) {
return Optional.ofNullable(getTrack(name));
}
/**
* Gets a set of all loaded tracks.
*
* @return a {@link Set} of {@link Track} objects
*/
@Nonnull
Set<Track> getLoadedTracks();
/**
* Check if a track is loaded in memory
*
* @param name the name to check for
* @return true if the track is loaded
* @throws NullPointerException if the name is null
*/
boolean isLoaded(@Nonnull String name);
}
@@ -0,0 +1,113 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.manager;
import me.lucko.luckperms.api.User;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents the object responsible for managing {@link User} instances.
*
* @since 4.0
*/
public interface UserManager {
/**
* Gets a wrapped user object from the user storage
*
* @param uuid the uuid of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
* @throws NullPointerException if the uuid is null
*/
@Nullable
User getUser(@Nonnull UUID uuid);
/**
* Gets a wrapped user object from the user storage.
*
* @param uuid the uuid of the user to get
* @return an optional {@link User} object
* @throws NullPointerException if the uuid is null
*/
@Nonnull
default Optional<User> getUserOpt(@Nonnull UUID uuid) {
return Optional.ofNullable(getUser(uuid));
}
/**
* Gets a wrapped user object from the user storage
*
* @param name the username of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
* @throws NullPointerException if the name is null
*/
@Nullable
User getUser(@Nonnull String name);
/**
* Gets a wrapped user object from the user storage.
*
* @param name the username of the user to get
* @return an optional {@link User} object
* @throws NullPointerException if the name is null
*/
@Nonnull
default Optional<User> getUserOpt(@Nonnull String name) {
return Optional.ofNullable(getUser(name));
}
/**
* Gets a set of all loaded users.
*
* @return a {@link Set} of {@link User} objects
*/
@Nonnull
Set<User> getLoadedUsers();
/**
* Check if a user is loaded in memory
*
* @param uuid the uuid to check for
* @return true if the user is loaded
* @throws NullPointerException if the uuid is null
*/
boolean isLoaded(@Nonnull UUID uuid);
/**
* Unload a user from the internal storage, if they're not currently online.
*
* @param user the user to unload
* @throws NullPointerException if the user is null
*/
void cleanupUser(@Nonnull User user);
}
@@ -0,0 +1,77 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.metastacking;
import java.util.List;
import javax.annotation.Nonnull;
/**
* Represents a meta stack model, consisting of a chain of elements, separated by spacers.
*
* <p>The resultant string is constructed as:
* [start spacer] [element] [middle spacer] [element] [middle spacer] [element] [end spacer]</p>
*
* <p>Definitions can be passed to a users UserData instance using MetaContexts, and the result of this stack can be
* retrieved from the returned MetaData instance.</p>
*
* @since 2.3
*/
public interface MetaStackDefinition {
/**
* Gets an immutable list of the elements in this stack definition
*
* @return the elements in this stack
*/
@Nonnull
List<MetaStackElement> getElements();
/**
* Gets the spacer string added before any stack elements
*
* @return the start spacer
*/
@Nonnull
String getStartSpacer();
/**
* Gets the spacer added between stack elements
*
* @return the middle spacer
*/
@Nonnull
String getMiddleSpacer();
/**
* Gets the spacer added after any stack elements
*
* @return the end spacer
*/
@Nonnull
String getEndSpacer();
}
@@ -0,0 +1,56 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.metastacking;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents an element within a {@link MetaStackDefinition}.
*
* @since 3.2
*/
public interface MetaStackElement {
/**
* Returns if the given node should be accumulated onto the stack.
*
* <p>The element being considered can be retrieved using {@link ChatMetaType#getEntry(Node)}.</p>
*
* @param node the node being considered
* @param type the type of entry being accumulated
* @param current the current value being used. If this returns true, the current value will be replaced by this entry
* @return true if the node should be accumulated into this element, replacing the current value
*/
boolean shouldAccumulate(@Nonnull LocalizedNode node, @Nonnull ChatMetaType type, @Nullable Map.Entry<Integer, String> current);
}
@@ -0,0 +1,72 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.metastacking;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
/**
* Factory to create meta stack elements and definitions.
*
* @since 3.2
*/
public interface MetaStackFactory {
/**
* Parses a standard {@link MetaStackElement} from string, using the pre-defined elements in the plugin.
*
* @param definition the definition
* @return the parsed element, if present
*/
@Nonnull
Optional<MetaStackElement> fromString(@Nonnull String definition);
/**
* Parses a list of {@link MetaStackElement}s from string, using the pre-defined elements in the plugin.
*
* <p>If an element cannot be parsed, it will not be included in the resultant list.</p>
*
* @param definitions the definition strings
* @return a list of parsed elements
*/
@Nonnull
List<MetaStackElement> fromStrings(@Nonnull List<String> definitions);
/**
* Creates a new {@link MetaStackDefinition} with the given properties.
*
* @param elements the elements to be included in the stack.
* @param startSpacer the spacer to be included at the start of the stacks output
* @param middleSpacer the spacer to be included between stack elements
* @param endSpacer the spacer to be included at the end of the stacks output
* @return the new stack definition instance
*/
@Nonnull
MetaStackDefinition createDefinition(@Nonnull List<MetaStackElement> elements, @Nonnull String startSpacer, @Nonnull String middleSpacer, @Nonnull String endSpacer);
}
@@ -0,0 +1,78 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.platform;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Provides information about the platform LuckPerms is running on.
*
* @since 4.0
*/
public interface PlatformInfo {
/**
* Gets the plugin version
*
* @return the version of the plugin running on the platform
*/
@Nonnull
String getVersion();
/**
* Gets the API version
*
* @return the version of the API running on the platform
*/
double getApiVersion();
/**
* Gets the type of platform LuckPerms is running on
*
* @return the type of platform LuckPerms is running on
*/
@Nonnull
PlatformType getType();
/**
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
*/
@Nonnull
Set<UUID> getUniqueConnections();
/**
* Gets the time when the plugin first started in milliseconds.
*
* @return the enable time
*/
long getStartTime();
}
@@ -0,0 +1,56 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.platform;
import javax.annotation.Nonnull;
/**
* Represents a type of platform which LuckPerms can run on.
*
* @since 2.7
*/
public enum PlatformType {
BUKKIT("Bukkit"),
BUNGEE("Bungee"),
SPONGE("Sponge");
private final String friendlyName;
PlatformType(String friendlyName) {
this.friendlyName = friendlyName;
}
/**
* Gets a readable name for the platform type.
*
* @return a readable name
*/
@Nonnull
public String getFriendlyName() {
return friendlyName;
}
}
+121
View File
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luckperms-bukkit-legacy</artifactId>
<build>
<defaultGoal>clean package</defaultGoal>
<finalName>LuckPerms-Bukkit-Legacy-${full.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${shade.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>me.lucko.luckperms.lib.guava</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>me.lucko.luckperms.lib.gson</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori.text</pattern>
<shadedPattern>me.lucko.luckperms.lib.text</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<!-- LuckPerms Bukkit -->
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-bukkit</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-common</artifactId>
</exclusion>
<exclusion>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Shade gson and guava, as they are not included in earlier Bukkit releases -->
<!-- gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
<scope>compile</scope>
</dependency>
<!-- guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
+118 -43
View File
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.1</version>
<version>4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,8 +14,7 @@
<build>
<defaultGoal>clean package</defaultGoal>
<finalName>LuckPerms-${project.version}.${git.closest.tag.commit.count}</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<finalName>LuckPerms-Bukkit-${full.version}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
@@ -26,7 +25,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<version>${compiler.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@@ -35,7 +34,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<version>${shade.version}</version>
<executions>
<execution>
<phase>package</phase>
@@ -43,45 +42,51 @@
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<minimizeJar>false</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer.hikari</pattern>
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
<pattern>net.kyori.text</pattern>
<shadedPattern>me.lucko.luckperms.lib.text</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<injectAllReactorProjects>true</injectAllReactorProjects>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${gpg.version}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<!-- BukkitAPI -->
<!-- Spigot API -->
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- Vault -->
@@ -90,6 +95,12 @@
<artifactId>VaultAPI</artifactId>
<version>1.6</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- LuckPerms Common -->
<dependency>
@@ -105,19 +116,83 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<!-- HikariCP -->
<!-- Lombok -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.4.7</version>
<scope>compile</scope>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- slf4j library -->
<!-- LilyPad -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.9</version>
<scope>compile</scope>
<groupId>lilypad.client.connect</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- ************** Migration Plugins ************** -->
<!-- zPermissions -->
<dependency>
<groupId>org.tyrannyofheaven.bukkit</groupId>
<artifactId>zPermissions</artifactId>
<version>1.3</version>
<scope>provided</scope>
</dependency>
<!-- PermissionsEx -->
<dependency>
<groupId>ru.tehkode</groupId>
<artifactId>PermissionsEx</artifactId>
<version>1.23.5</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
<exclusion>
<groupId>net.gravitydevelopment.updater</groupId>
<artifactId>updater</artifactId>
</exclusion>
<exclusion>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
</exclusion>
<exclusion>
<groupId>com.mojang</groupId>
<artifactId>AccountsClient</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- PowerfulPerms -->
<dependency>
<groupId>com.github.cheesesoftware</groupId>
<artifactId>PowerfulPermsAPI</artifactId>
<version>1.4.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- GroupManager -->
<dependency>
<groupId>org.anjocaido</groupId>
<artifactId>GroupManager</artifactId>
<version>1.4</version>
<scope>provided</scope>
</dependency>
<!-- bPermissions -->
<dependency>
<groupId>de.bananaco</groupId>
<artifactId>bpermissions-api</artifactId>
<version>2.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -1,77 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.utils.LPConfiguration;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
class BukkitConfig extends LPConfiguration<LPBukkitPlugin> {
private YamlConfiguration configuration;
BukkitConfig(LPBukkitPlugin plugin) {
super(plugin, "global", true, "sqlite");
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@Override
protected void init() {
File configFile = new File(getPlugin().getDataFolder(), "config.yml");
if (!configFile.exists()) {
configFile.getParentFile().mkdirs();
getPlugin().saveResource("config.yml", false);
}
configuration = new YamlConfiguration();
try {
configuration.load(configFile);
} catch (InvalidConfigurationException | IOException e) {
e.printStackTrace();
}
}
@Override
protected void set(String path, Object value) {
configuration.set(path, value);
}
@Override
protected String getString(String path, String def) {
return configuration.getString(path, def);
}
@Override
protected int getInt(String path, int def) {
return configuration.getInt(path, def);
}
@Override
protected boolean getBoolean(String path, boolean def) {
return configuration.getBoolean(path, def);
}
}
@@ -1,86 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.users.BukkitUser;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.AbstractListener;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.*;
class BukkitListener extends AbstractListener implements Listener {
private final LPBukkitPlugin plugin;
BukkitListener(LPBukkitPlugin plugin) {
super(plugin);
this.plugin = plugin;
}
@EventHandler
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
if (!plugin.getDatastore().isAcceptingLogins()) {
// Datastore is disabled, prevent players from joining the server
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
return;
}
onAsyncLogin(e.getUniqueId(), e.getName());
}
@EventHandler
public void onPlayerLogin(PlayerLoginEvent e) {
final Player player = e.getPlayer();
final User user = plugin.getUserManager().getUser(plugin.getUuidCache().getUUID(player.getUniqueId()));
if (user == null) {
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
return;
}
if (user instanceof BukkitUser) {
BukkitUser u = (BukkitUser) user;
u.setAttachment(player.addAttachment(plugin));
}
user.refreshPermissions();
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
// Refresh permissions again
refreshPlayer(e.getPlayer().getUniqueId());
}
@EventHandler
public void onPlayerChangedWorld(PlayerChangedWorldEvent e) {
refreshPlayer(e.getPlayer().getUniqueId());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
onLeave(e.getPlayer().getUniqueId());
}
}
@@ -1,202 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import lombok.Getter;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.implementation.ApiProvider;
import me.lucko.luckperms.api.vault.VaultHook;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.data.methods.FlatfileDatastore;
import me.lucko.luckperms.data.methods.MySQLDatastore;
import me.lucko.luckperms.data.methods.SQLiteDatastore;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.runnables.UpdateTask;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.BukkitUserManager;
import me.lucko.luckperms.users.UserManager;
import me.lucko.luckperms.utils.LPConfiguration;
import me.lucko.luckperms.utils.LogUtil;
import me.lucko.luckperms.utils.UuidCache;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Getter
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private LPConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
private UuidCache uuidCache;
private Logger log;
@Override
public void onEnable() {
log = LogUtil.wrap(getLogger());
getLog().info("Loading configuration...");
configuration = new BukkitConfig(this);
// register events
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new BukkitListener(this), this);
// register commands
getLog().info("Registering commands...");
BukkitCommand commandManager = new BukkitCommand(this);
PluginCommand main = getServer().getPluginCommand("luckperms");
main.setExecutor(commandManager);
main.setTabCompleter(commandManager);
main.setAliases(Arrays.asList("perms", "lp", "permissions", "p", "perm"));
getLog().info("Detecting storage method...");
final String storageMethod = configuration.getStorageMethod();
if (storageMethod.equalsIgnoreCase("mysql")) {
getLog().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(this, configuration.getDatabaseValues());
} else if (storageMethod.equalsIgnoreCase("sqlite")) {
getLog().info("Using SQLite as storage method.");
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
} else if (storageMethod.equalsIgnoreCase("flatfile")) {
getLog().info("Using Flatfile (JSON) as storage method.");
datastore = new FlatfileDatastore(this, getDataFolder());
} else {
getLog().severe("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
}
getLog().info("Initialising datastore...");
datastore.init();
getLog().info("Loading internal permission managers...");
uuidCache = new UuidCache(getConfiguration().getOnlineMode());
userManager = new BukkitUserManager(this);
groupManager = new GroupManager(this);
trackManager = new TrackManager();
// Run update task to refresh any online users
getLog().info("Scheduling Update Task to refresh any online users.");
try {
new UpdateTask(this).run();
} catch (Exception e) {
e.printStackTrace();
}
int mins = getConfiguration().getSyncTime();
if (mins > 0) {
long ticks = mins * 60 * 20;
getServer().getScheduler().runTaskTimerAsynchronously(this, new UpdateTask(this), ticks, ticks);
}
// Provide vault support
getLog().info("Attempting to hook into Vault...");
try {
if (getServer().getPluginManager().isPluginEnabled("Vault")) {
VaultHook.hook(this);
getLog().info("Registered Vault permission & chat hook.");
} else {
getLog().info("Vault not found.");
}
} catch (Exception e) {
getLog().severe("Error occurred whilst hooking into Vault.");
e.printStackTrace();
}
getLog().info("Registering API...");
final ApiProvider provider = new ApiProvider(this);
LuckPerms.registerProvider(provider);
getServer().getServicesManager().register(LuckPermsApi.class, provider, this, ServicePriority.Normal);
getLog().info("Successfully loaded.");
}
@Override
public void onDisable() {
getLog().info("Closing datastore...");
datastore.shutdown();
getLog().info("Unregistering API...");
LuckPerms.unregisterProvider();
getServer().getServicesManager().unregisterAll(this);
}
@Override
public void doAsync(Runnable r) {
getServer().getScheduler().runTaskAsynchronously(this, r);
}
@Override
public void doSync(Runnable r) {
getServer().getScheduler().runTask(this, r);
}
@Override
public String getVersion() {
return getDescription().getVersion();
}
@Override
public Message getPlayerStatus(UUID uuid) {
return getServer().getPlayer(getUuidCache().getExternalUUID(uuid)) != null ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
}
@Override
public int getPlayerCount() {
return getServer().getOnlinePlayers().size();
}
@Override
public List<String> getPlayerList() {
return getServer().getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
}
@Override
public List<String> getPossiblePermissions() {
final List<String> perms = new ArrayList<>();
getServer().getPluginManager().getPermissions().forEach(p -> {
perms.add(p.getName());
p.getChildren().keySet().forEach(perms::add);
});
return perms;
}
@Override
public void runUpdateTask() {
getServer().getScheduler().runTaskAsynchronously(this, new UpdateTask(this));
}
}
@@ -1,149 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.vault;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission;
/**
* Dummy class for hooking with Vault plugins that need both Chat + Perms
* This doesn't return anything useful, or change anything internally
*
* Registered on the lowest priority so other plugins can override
*/
class VaultChatHook extends Chat {
VaultChatHook(Permission perms) {
super(perms);
}
private void throwNotSupported() {
// throw new UnsupportedOperationException("LuckPerms cannot perform this operation.");
}
public String getName() {
return "LuckPerms";
}
public boolean isEnabled() {
return true;
}
public String getPlayerPrefix(String world, String player) {
return "";
}
public void setPlayerPrefix(String world, String player, String prefix) {
throwNotSupported();
}
public String getPlayerSuffix(String world, String player) {
return "";
}
public void setPlayerSuffix(String world, String player, String suffix) {
throwNotSupported();
}
public String getGroupPrefix(String world, String group) {
return "";
}
public void setGroupPrefix(String world, String group, String prefix) {
throwNotSupported();
}
public String getGroupSuffix(String world, String group) {
return "";
}
public void setGroupSuffix(String world, String group, String suffix) {
throwNotSupported();
}
public int getPlayerInfoInteger(String world, String player, String node, int defaultValue) {
return defaultValue;
}
public void setPlayerInfoInteger(String world, String player, String node, int value) {
throwNotSupported();
}
public int getGroupInfoInteger(String world, String group, String node, int defaultValue) {
return defaultValue;
}
public void setGroupInfoInteger(String world, String group, String node, int value) {
throwNotSupported();
}
public double getPlayerInfoDouble(String world, String player, String node, double defaultValue) {
return defaultValue;
}
public void setPlayerInfoDouble(String world, String player, String node, double value) {
throwNotSupported();
}
public double getGroupInfoDouble(String world, String group, String node, double defaultValue) {
return defaultValue;
}
public void setGroupInfoDouble(String world, String group, String node, double value) {
throwNotSupported();
}
public boolean getPlayerInfoBoolean(String world, String player, String node, boolean defaultValue) {
return defaultValue;
}
public void setPlayerInfoBoolean(String world, String player, String node, boolean value) {
throwNotSupported();
}
public boolean getGroupInfoBoolean(String world, String group, String node, boolean defaultValue) {
return defaultValue;
}
public void setGroupInfoBoolean(String world, String group, String node, boolean value) {
throwNotSupported();
}
public String getPlayerInfoString(String world, String player, String node, String defaultValue) {
return defaultValue;
}
public void setPlayerInfoString(String world, String player, String node, String value) {
throwNotSupported();
}
public String getGroupInfoString(String world, String group, String node, String defaultValue) {
return defaultValue;
}
public void setGroupInfoString(String world, String group, String node, String value) {
throwNotSupported();
}
}
@@ -1,216 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.vault;
import lombok.NonNull;
import lombok.Setter;
import me.lucko.luckperms.LPBukkitPlugin;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.PermissionHolder;
import net.milkbowl.vault.permission.Permission;
class VaultPermissionHook extends Permission {
@Setter
private LPBukkitPlugin plugin;
@Override
public String getName() {
return "LuckPerms";
}
@Override
public boolean isEnabled() {
return plugin.getDatastore().isAcceptingLogins();
}
@Override
public boolean hasSuperPermsCompat() {
return true;
}
private boolean objectHas(String world, PermissionHolder object, String permission) {
if (object == null) return false;
if (world != null && !world.equals("")) {
return object.hasPermission(permission, true, "global", world);
} else {
return object.hasPermission(permission, true);
}
}
private boolean objectAdd(String world, PermissionHolder object, String permission) {
if (object == null) return false;
try {
if (world != null && !world.equals("")) {
object.setPermission(permission, true, "global", world);
} else {
object.setPermission(permission, true);
}
} catch (ObjectAlreadyHasException ignored) {}
objectSave(object);
return true;
}
private boolean objectRemove(String world, PermissionHolder object, String permission) {
if (object == null) return false;
try {
if (world != null && !world.equals("")) {
object.unsetPermission(permission, "global", world);
} else {
object.unsetPermission(permission);
}
} catch (ObjectLacksException ignored) {}
objectSave(object);
return true;
}
private void objectSave(PermissionHolder t) {
if (t instanceof User) {
((User) t).refreshPermissions();
plugin.getDatastore().saveUser(((User) t), aBoolean -> {});
}
if (t instanceof Group) {
plugin.getDatastore().saveGroup(((Group) t), aBoolean -> plugin.runUpdateTask());
}
}
@Override
public boolean playerHas(String world, @NonNull String player, @NonNull String permission) {
return objectHas(world, plugin.getUserManager().getUser(player), permission);
}
@Override
public boolean playerAdd(String world, @NonNull String player, @NonNull String permission) {
final User user = plugin.getUserManager().getUser(player);
return objectAdd(world, user, permission);
}
@Override
public boolean playerRemove(String world, @NonNull String player, @NonNull String permission) {
final User user = plugin.getUserManager().getUser(player);
return objectRemove(world, user, permission);
}
@Override
public boolean groupHas(String world, @NonNull String groupName, @NonNull String permission) {
final Group group = plugin.getGroupManager().getGroup(groupName);
return objectHas(world, group, permission);
}
@Override
public boolean groupAdd(String world, @NonNull String groupName, @NonNull String permission) {
final Group group = plugin.getGroupManager().getGroup(groupName);
return objectAdd(world, group, permission);
}
@Override
public boolean groupRemove(String world, @NonNull String groupName, @NonNull String permission) {
final Group group = plugin.getGroupManager().getGroup(groupName);
return objectRemove(world, group, permission);
}
@Override
public boolean playerInGroup(String world, @NonNull String player, @NonNull String group) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
final Group group1 = plugin.getGroupManager().getGroup(group);
if (group1 == null) return false;
if (world != null && !world.equals("")) {
return user.isInGroup(group1, "global", world);
} else {
return user.isInGroup(group1);
}
}
@Override
public boolean playerAddGroup(String world, @NonNull String player, @NonNull String groupName) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) return false;
try {
if (world != null && !world.equals("")) {
user.addGroup(group, "global", world);
} else {
user.addGroup(group);
}
} catch (ObjectAlreadyHasException ignored) {}
objectSave(user);
return true;
}
@Override
public boolean playerRemoveGroup(String world, @NonNull String player, @NonNull String groupName) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) return false;
try {
if (world != null && !world.equals("")) {
user.removeGroup(group, "global", world);
} else {
user.removeGroup(group);
}
} catch (ObjectLacksException ignored) {}
objectSave(user);
return true;
}
@Override
public String[] getPlayerGroups(String world, @NonNull String player) {
final User user = plugin.getUserManager().getUser(player);
return (user == null) ? new String[0] :
world != null && !world.equals("") ? user.getLocalGroups("global", world).toArray(new String[0]) :
user.getGroupNames().toArray(new String[0]);
}
@Override
public String getPrimaryGroup(String world, @NonNull String player) {
final User user = plugin.getUserManager().getUser(player);
return (user == null) ? null : user.getPrimaryGroup();
}
@Override
public String[] getGroups() {
return plugin.getGroupManager().getGroups().keySet().toArray(new String[0]);
}
@Override
public boolean hasGroupSupport() {
return true;
}
}
@@ -1,5 +1,8 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -20,46 +23,47 @@
* SOFTWARE.
*/
package me.lucko.luckperms;
package me.lucko.luckperms.bukkit;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.commands.CommandManager;
import me.lucko.luckperms.commands.SenderFactory;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import java.util.Arrays;
import java.util.List;
class BukkitCommand extends CommandManager implements CommandExecutor, TabExecutor {
private static final Factory FACTORY = new Factory();
public class BukkitCommandExecutor extends CommandManager implements CommandExecutor, TabExecutor {
private static final Splitter ARGUMENT_SPLITTER = Splitter.on(COMMAND_SEPARATOR_PATTERN).omitEmptyStrings();
private static final Joiner ARGUMENT_JOINER = Joiner.on(' ');
BukkitCommand(LuckPermsPlugin plugin) {
private final LPBukkitPlugin plugin;
BukkitCommandExecutor(LPBukkitPlugin plugin) {
super(plugin);
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
return onCommand(FACTORY.wrap(sender), label, Arrays.asList(args));
}
Sender lpSender = plugin.getSenderFactory().wrap(sender);
List<String> arguments = Util.stripQuotes(ARGUMENT_SPLITTER.splitToList(ARGUMENT_JOINER.join(args)));
onCommand(lpSender, label, arguments);
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
return onTabComplete(FACTORY.wrap(sender), Arrays.asList(args));
}
Sender lpSender = plugin.getSenderFactory().wrap(sender);
List<String> arguments = Util.stripQuotes(ARGUMENT_SPLITTER.splitToList(ARGUMENT_JOINER.join(args)));
private static class Factory extends SenderFactory<CommandSender> {
@Override
protected void sendMessage(CommandSender sender, String s) {
sender.sendMessage(s);
}
@Override
protected boolean hasPermission(CommandSender sender, String node) {
return sender.hasPermission(node);
}
return onTabComplete(lpSender, arguments);
}
}
@@ -0,0 +1,114 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.bukkit;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.config.ConfigurationAdapter;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@RequiredArgsConstructor
public class BukkitConfigAdapter implements ConfigurationAdapter {
@Getter
private final LPBukkitPlugin plugin;
private YamlConfiguration configuration;
@Override
public void init() {
File configFile = new File(plugin.getDataFolder(), "config.yml");
if (!configFile.exists()) {
configFile.getParentFile().mkdirs();
plugin.saveResource("config.yml", false);
}
configuration = YamlConfiguration.loadConfiguration(configFile);
}
@Override
public boolean contains(String path) {
return configuration.contains(path);
}
@Override
public String getString(String path, String def) {
return configuration.getString(path, def);
}
@Override
public int getInt(String path, int def) {
return configuration.getInt(path, def);
}
@Override
public boolean getBoolean(String path, boolean def) {
return configuration.getBoolean(path, def);
}
@Override
public List<String> getList(String path, List<String> def) {
List<String> ret = configuration.getStringList(path);
return ret == null ? def : ret;
}
@Override
public List<String> getObjectList(String path, List<String> def) {
ConfigurationSection section = configuration.getConfigurationSection(path);
if (section == null) {
return def;
}
Set<String> keys = section.getKeys(false);
return keys == null ? def : new ArrayList<>(keys);
}
@Override
public Map<String, String> getMap(String path, Map<String, String> def) {
Map<String, String> map = new HashMap<>();
ConfigurationSection section = configuration.getConfigurationSection(path);
if (section == null) {
return def;
}
for (String key : section.getKeys(false)) {
map.put(key, section.getString(key));
}
return map;
}
}
@@ -0,0 +1,121 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.bukkit;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
import org.bukkit.scheduler.BukkitTask;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class BukkitSchedulerAdapter implements SchedulerAdapter {
private final LPBukkitPlugin plugin;
@Getter
@Accessors(fluent = true)
private ExecutorService asyncLp;
@Getter
@Accessors(fluent = true)
private Executor asyncBukkit;
@Getter
@Accessors(fluent = true)
private Executor sync;
@Getter
@Accessors(fluent = true)
private Executor async;
@Getter
@Setter
private boolean useBukkitAsync = false;
private final Set<BukkitTask> tasks = ConcurrentHashMap.newKeySet();
public BukkitSchedulerAdapter(LPBukkitPlugin plugin) {
this.plugin = plugin;
this.asyncLp = Executors.newCachedThreadPool();
this.asyncBukkit = r -> plugin.getServer().getScheduler().runTaskAsynchronously(plugin, r);
this.sync = r -> plugin.getServer().getScheduler().runTask(plugin, r);
this.async = r -> (useBukkitAsync ? asyncBukkit : asyncLp).execute(r);
}
@Override
public void doAsync(Runnable runnable) {
async().execute(runnable);
}
@Override
public void doSync(Runnable runnable) {
sync().execute(runnable);
}
@Override
public void asyncRepeating(Runnable runnable, long intervalTicks) {
BukkitTask task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, runnable, intervalTicks, intervalTicks);
tasks.add(task);
}
@Override
public void syncRepeating(Runnable runnable, long intervalTicks) {
BukkitTask task = plugin.getServer().getScheduler().runTaskTimer(plugin, runnable, intervalTicks, intervalTicks);
tasks.add(task);
}
@Override
public void asyncLater(Runnable runnable, long delayTicks) {
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, runnable, delayTicks);
}
@Override
public void syncLater(Runnable runnable, long delayTicks) {
plugin.getServer().getScheduler().runTaskLater(plugin, runnable, delayTicks);
}
@Override
public void shutdown() {
tasks.forEach(BukkitTask::cancel);
// wait for executor
asyncLp.shutdown();
try {
asyncLp.awaitTermination(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,109 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.bukkit;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.bukkit.compat.MessageHandler;
import me.lucko.luckperms.common.commands.sender.SenderFactory;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.kyori.text.Component;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.UUID;
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
private final MessageHandler messageHandler;
public BukkitSenderFactory(LuckPermsPlugin plugin) {
super(plugin);
messageHandler = new MessageHandler();
}
@Override
protected String getName(CommandSender sender) {
if (sender instanceof Player) {
return sender.getName();
}
return Constants.CONSOLE_NAME;
}
@Override
protected UUID getUuid(CommandSender sender) {
if (sender instanceof Player) {
return ((Player) sender).getUniqueId();
}
return Constants.CONSOLE_UUID;
}
@Override
protected void sendMessage(CommandSender sender, String s) {
// send sync if command block
if (sender instanceof BlockCommandSender) {
getPlugin().getScheduler().doSync(new BlockMessageAgent(((BlockCommandSender) sender), s));
return;
}
sender.sendMessage(s);
}
@Override
protected void sendMessage(CommandSender sender, Component message) {
messageHandler.sendJsonMessage(sender, message);
}
@Override
protected Tristate getPermissionValue(CommandSender sender, String node) {
boolean isSet = sender.isPermissionSet(node);
boolean val = sender.hasPermission(node);
return !isSet ? val ? Tristate.TRUE : Tristate.UNDEFINED : Tristate.fromBoolean(val);
}
@Override
protected boolean hasPermission(CommandSender sender, String node) {
return sender.hasPermission(node);
}
@AllArgsConstructor
private static final class BlockMessageAgent implements Runnable {
private final BlockCommandSender block;
private final String message;
@Override
public void run() {
block.sendMessage(message);
}
}
}
Loaded 100 of 650 files, more files were not shown because too many files have changed in this diff. Show more