Compare commits

...
128 Commits
Author SHA1 Message Date
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
531 changed files with 19661 additions and 9086 deletions

No files matched your search

+486 -47
View File
@@ -13,6 +13,7 @@ loading-error: "Permissions data could not be loaded. Please try again later."
op-disabled: "&bThe vanilla OP system is disabled on this server."
op-disabled-sponge: "&2Server Operator status has no effect when a permission plugin is installed. Please edit user data directly."
log: "&3LOG &3&l> {0}"
verbose-log: "&3VERBOSE &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}"
@@ -25,10 +26,8 @@ already-has-temp-permission: "{0} already has this permission set temporarily!"
does-not-have-temp-permission: "{0} does not have this permission set temporarily."
user-not-found: "&bUser could not be found."
user-not-online: "&bUser &a{0}&b is not online."
user-no-data: "&bUser &a{0}&b does not have any data loaded."
user-save-success: "&7(User data was saved to storage)"
user-save-error: "There was an error whilst saving the user."
user-create-fail: "There was an error whilst creating a new user."
group-not-found: "&bGroup could not be found."
group-save-success: "&7(Group data was saved to storage)"
group-save-error: "There was an error whilst saving the group."
@@ -38,25 +37,36 @@ track-save-error: "There was an error whilst saving the track."
user-invalid-entry: "&d{0}&c is not a valid username/uuid."
group-invalid-entry: "Group names can only contain alphanumeric characters."
track-invalid-entry: "Track names can only contain alphanumeric characters."
server-invalid-entry: "Server names can only contain alphanumeric characters."
server-world-invalid-entry: "Server/world names can only contain alphanumeric characters and cannot exceed 36 characters in length."
use-inherit-command: "Use the 'parent add' and 'parent remove' commands instead of specifying the node."
verbose-invalid-filter: "&cInvalid verbose filter: &f{0}"
verbose-on: "&bVerbose checking output set to &aTRUE &bfor all permissions."
verbose-on-query: "&bVerbose checking output set to &aTRUE &bfor permissions matching the following filters: &f{0}"
verbose-on-query: "&bVerbose checking output set to &aTRUE &bfor permissions matching filter: &f{0}"
verbose-off: "&bVerbose checking output set to &cFALSE&b."
verbose-recording-on: "&bVerbose recording set to &aTRUE &bfor all permissions."
verbose-recording-on-query: "&bVerbose recording set to &aTRUE &bfor permissions matching the following filters: &f{0}"
verbose-recording-on-query: "&bVerbose recording set to &aTRUE &bfor permissions matching filter: &f{0}"
verbose-recording-upload-start: "&bVerbose recording was disabled. Uploading results..."
verbose-recording-url: "&aVerbose results URL:"
tree-upload-start: "&bGenerating permission tree..."
tree-empty: "&aUnable 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: "&aInvalid code. &7({0})"
apply-edits-unable-to-read: "&aUnable to read data using the given code. &7({0})"
apply-edits-no-target: "&aUnable to parse the target of the edit. Please supply it as an extra argument."
apply-edits-target-group-not-exists: "&aTarget group &b{0}&a does not exist."
apply-edits-target-user-not-uuid: "&aTarget user &b{0}&a is not a valid uuid."
apply-edits-target-user-unable-to-load: "&aUnable to load target user &b{0}&a."
apply-edits-target-unknown: "&aInvalid 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."
@@ -116,38 +126,27 @@ info: >
create-group-error: "There was an error whilst creating the group."
delete-group-error: "There was an error whilst deleting the group."
delete-group-error-default: "You cannot delete the default group."
groups-list: "&aGroups: {0}"
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]"
create-track-error: "There was an error whilst creating the track."
delete-track-error: "There was an error whilst deleting the track."
tracks-list: "&aTracks: {0}"
listnodes: "&b{0}'s Nodes:"
listnodes-with-page: "&b{0}'s Nodes: {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}
listnodes-temp: "&b{0}'s Temporary Nodes:"
listnodes-temp-with-page: "&b{0}'s Temporary Nodes: {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: "{0} is not on any tracks."
context-pair-inline: "&3{0}=&b{1}"
context-pair--global-inline: "&eglobal"
context-pair-end: "&a."
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-permission-inherited: "&b{0}&a has permission &b{1}&a set to {2}&a in context {3}&a, inherited from &b{4}&a."
setpermission-success: "&aSet &b{0}&a to &b{1}&a for &b{2}&a in context {3}&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."
unsetpermission-success: "&aUnset &b{0}&a for &b{1}&a in context {2}&a."
@@ -155,14 +154,17 @@ unset-temp-permission-success: "&aUnset temporary permission &b{0}&a for &b{1}&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. (&b{1}&a nodes were removed.)"
clear-success-singular: "&b{0}&a's permissions were cleared. (&b{1}&a node was removed.)"
parent-clear-success: "&b{0}&a's parents were cleared. (&b{1}&a nodes were removed.)"
parent-clear-success-singular: "&b{0}&a's parents were cleared. (&b{1}&a node was removed.)"
meta-clear-success: "&b{0}&a's meta was cleared. (&b{1}&a nodes were removed.)"
meta-clear-success-singular: "&b{0}&a's meta was cleared. (&b{1}&a node was removed.)"
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 was cleared in context {1}&a. &b{2}&a nodes were removed.)"
meta-clear-success-singular: "&b{0}&a's meta was cleared in context {1}&a. &b{2}&a node was removed.)"
illegal-date-error: "Could not parse date '{0}'."
past-date-error: "You cannot set a date in the past!"
chat-meta-prefix-header: "&b{0}'s Prefixes"
@@ -181,16 +183,23 @@ does-not-have-chat-meta: "{0} doesn't have that {1} set."
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{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{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: "{0} already has that meta key value pair set."
set-meta-success: "&aSet meta value for key &f\"{0}&f\"&a to &f\"{1}&f\"&a for &b{2}&a in context {3}&a."
set-meta-temp-success: "&aSet meta value for 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 value with key &f\"{0}&f\"&a for &b{1}&a in context {2}&a."
unset-meta-temp-success: "&aUnset temporary meta value with key &f\"{0}&f\"&a for &b{1}&a in context {2}&a."
bulk-change-type-error: "Invalid type. Was expecting 'server' or 'world'."
bulk-change-success: "&aApplied bulk change successfully. {0} records were changed."
bulk-update-invalid-data-type: "Invalid type. Was expecting 'all', 'users' or 'groups'."
bulk-update-invalid-constraint: "Invalid constraint &4{0}&c. Constraints should be in the format '&f<field> <comparison operator> <value>&c'."
bulk-update-invalid-comparison: "Invalid 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
@@ -204,39 +213,29 @@ user-info-general: >
{PREFIX}&f- &3Meta: &a{8}
user-info-data: >
{PREFIX}&f- &aCached Data:\n
{PREFIX}&f- &3Is Loaded: {0}\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-getuuid: "&bThe UUID of &b{0}&b is &b{1}&b."
user-removegroup-error-primary: "You 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: "&cWarning: The primary group calculation method being used by this server &7({0}) &cmay not reflect this change."
user-primarygroup-error-alreadyhas: "The user already has this group 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: "The user specified isn't already in any groups on this track."
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."
user-track-added-to-first-server: "&b{0}&a isn't in any groups on this track, so they were added to the first group, &b{1}&a, on server &b{2}&a."
user-track-added-to-first-server-world: "&b{0}&a isn't in any groups on this track, so they were added to the first group, &b{1}&a, on server &b{2}&a, world &b{3}&a."
user-promote-success: "&aPromoting user along track &b{0}&a from &b{1}&a to &b{2}&a."
user-promote-success-server: "&aPromoting user along track &b{0}&a from &b{1}&a to &b{2}&a on server &b{3}&a."
user-promote-success-server-world: "&aPromoting user along track &b{0}&a from &b{1}&a to &b{2}&a on server &b{3}&a, world &b{4}&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 user along track &b{0}&a from &b{1}&a to &b{2}&a in context {3}&a."
user-promote-error-endoftrack: "The end of track &4{0}&c was reached. Unable to promote user."
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: "&aDemoting user along track &b{0}&a from &b{1}&a to &b{2}&a."
user-demote-success-server: "&aDemoting user along track &b{0}&a from &b{1}&a to &b{2}&a on server &b{3}&a."
user-demote-success-server-world: "&aDemoting user along track &b{0}&a from &b{1}&a to &b{2}&a on server &b{3}&a, world &b{4}&a."
user-demote-success: "&aDemoting user along track &b{0}&a from &b{1}&a to &b{2}&a in context {3}&a."
user-demote-endoftrack: "The end of track &4{0}&c was reached, so &4{1}&c was removed from &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
@@ -297,3 +296,443 @@ import-end-error-header: >
{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"
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 chat meta"
args:
"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"
+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<------------------------------------------>"
+106 -141
View File
@@ -4,14 +4,14 @@
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[WARN] {0}"
log-error: "&7&l[&bLuck&3Perms&7&l] &4[ERROR] {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: "Не удалось загрузить данные разрешений (пермов). Пожалуйста обратитесь к администратору."
loading-error: "Не удалось загрузить данные разрешений. Пожалуйста обратитесь к Администратору."
op-disabled: "&bНа этом сервере отключена ванильная система OP."
op-disabled-sponge: "&2Статус оператора сервера не влияет на установленный плагин разрешений (пермов). Пожалуйста отредактируйте данные пользователя напрямую."
op-disabled-sponge: "&2Статус Оператора Сервера не влияет на установленный плагин разрешений. Пожалуйста, отредактируйте данные пользователя напрямую."
log: "&3LOG &3&l> {0}"
export-log: "&3ЭКСПОРТ &3&l> &f{0}"
export-log-progress: "&3ЭКСПОРТ &3&l> &7{0}"
@@ -19,10 +19,10 @@ 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} не имеет этого набора временных разрешений (пермов)."
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 не имеет загруженных данных."
@@ -32,32 +32,33 @@ user-create-fail: "При создании нового пользователя
group-not-found: "&bНе удалось найти группу."
group-save-success: "&7(Групповые данные были сохранены на хранение)"
group-save-error: "При сохранении группы произошла ошибка."
track-not-found: "&bНе удалось найти путь (track)."
track-save-success: "&7(Данные о путе (track) сохранены на хранение)"
track-save-error: "При сохранении пути (track) произошла ошибка."
track-not-found: "&bНе удалось найти путь."
track-save-success: "&7(Данные о путе сохранены на хранение)"
track-save-error: "При сохранении пути произошла ошибка."
user-invalid-entry: "&d{0}&c не является допустимым именем пользователя/uuid."
group-invalid-entry: "Имена групп могут содержать только буквенно-цифровые символы."
track-invalid-entry: "Имена путей (track) могут содержать только буквенно-цифровые символы."
track-invalid-entry: "Имена путей могут содержать только буквенно-цифровые символы."
server-invalid-entry: "Имена серверов могут содержать только буквенно-цифровые символы."
use-inherit-command: "Используйте команды «parent add» и «parent remove» вместо указания узла (node)."
verbose-invalid-filter: "&cНедопустимый подробный (verbose) фильтр: &f{0}"
verbose-on: "&Запись подробной проверки установлена на &aВЕРНЫЙ &bдля всех разрешений (пермов)."
verbose-on-query: "&Запись подробной проверки установлена на &aВЕРНЫЙ &bДля разрешений, соответствующих следующим фильтрам: &f{0}"
verbose-off: "&Запись подробной проверки установлена на &cНЕВЕРНЫЙ&b."
verbose-recording-on: "&Запись подробной записи установлена ​​на &aВЕРНЫЙ &bдля всех разрешений."
verbose-recording-on-query: "&Запись подробной записи установлена ​​на &aВЕРНЫЙ &bДля разрешений, соответствующих следующим фильтрам: &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}"
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."
@@ -66,22 +67,22 @@ already-inherits: "{0} уже наследует '{1}'."
does-not-inherit: "{0} не наследует '{1}'."
already-temp-inherits: "{0} уже временно наследует '{1}'."
does-not-temp-inherit: "{0} временно не наследует '{1}'."
track-already-contains: "Путь (Track) {0} уже содержит группу '{1}'."
track-does-not-contain: "Путь (Track) {0} не содержит группу '{1}'."
track-ambiguous-call: "Указанный пользователь является членом нескольких групп на этом пути (track). Невозможно определить их местоположение."
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) уже существует!"
track-does-not-exist: "Этот путь (track) не существует!"
track-load-error: "Произошла непредвиденная ошибка. Путь (track) не загружен."
tracks-load-error: "Произошла непредвиденная ошибка. Не удалось загрузить все пути (tracks)."
track-empty: "Путь (track) нельзя использовать, так как он пуст или содержит только одну группу."
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} Сообщения и удаленный доступ."
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(Некоторые параметры будут применяться только после перезапуска сервера.)"
@@ -96,16 +97,16 @@ info: >
{PREFIX}&f- &3Игроки Онлайн: &a{6}\n
{PREFIX}&f- &3Загруженные пользователи: &a{7}\n
{PREFIX}&f- &3Загруженные группы: &a{8}\n
{PREFIX}&f- &3Загруженные пути (tracks): &a{9}\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- &3Уникальные разрешения: &a{15}\n
{PREFIX}&f- &bКонфигурация:\n
{PREFIX}&f- &3Использует сервер UUIDs: {16}\n
{PREFIX}&f- &bСчетчик разрешений (Пермов):\n
{PREFIX}&f- &bСчетчик разрешений:\n
{PREFIX}&f- &3Включая глобальные: {17}\n
{PREFIX}&f- &3Включая глобальный мир: {18}\n
{PREFIX}&f- &3Применения глобальных групп: {19}\n
@@ -117,9 +118,9 @@ create-group-error: "При создании группы произошла о
delete-group-error: "При удалении группы произошла ошибка."
delete-group-error-default: "Вы не можете удалить группу по умолчанию."
groups-list: "&aГруппы: {0}"
create-track-error: "При создании пути (track) произошла ошибка."
delete-track-error: "При удалении пути (Track) произошла ошибка."
tracks-list: "&aGenb (Tracks): {0}"
create-track-error: "При создании пути произошла ошибка."
delete-track-error: "При удалении пути произошла ошибка."
tracks-list: "&aГенеральные пути: {0}"
listnodes: "&b{0}'s Узлы:"
listnodes-with-page: "&b{0}'s Узлы: {1}"
listnodes-temp: >
@@ -138,97 +139,67 @@ listgroups-temp: >
&b{0}'s Временные группы:\n
{1}
list-tracks: >
&b{0}'s Пути (Tracks):\n
&b{0}'s Пути:\n
{1}
list-tracks-empty: "{0} Не на каких-либо путях (tracks)."
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-server-success: "&aУстановить &b{0}&a к &b{1}&a для &b{2}&a на сервер &b{3}&a."
setpermission-server-world-success: "&aУстановить &b{0}&a к &b{1}&a для &b{2}&a на сервер &b{3}&a, мир &b{4}&a."
setpermission-temp-success: "&aУстановить &b{0}&a к &b{1}&a для &b{2}&a На срок &b{3}&a."
setpermission-temp-server-success: "&aУстановить &b{0}&a к &b{1}&a для &b{2}&a на сервер &b{3}&a на срок &b{4}&a."
setpermission-temp-server-world-success: "&aУстановить &b{0}&a к &b{1}&a для &b{2}&a на сервер &b{3}&a, мир &b{4}&a, на срок &b{5}&a."
unsetpermission-success: "&aСбросить &b{0}&a для &b{1}&a."
unsetpermission-server-success: "&aСбросить &b{0}&a для &b{1}&a on server &b{2}&a."
unsetpermission-server-world-success: "&aСбросить &b{0}&a для &b{1}&a on server &b{2}&a, world &b{3}&a."
unset-temp-permission-success: "&aСбросить временное разрешение &b{0}&a для &b{1}&a."
unset-temp-permission-server-success: "&aСбросить временное разрешение &b{0}&a для &b{1}&a на сервере &b{2}&a."
unset-temp-permission-server-world-success: "&aСбросить временное разрешение &b{0}&a для &b{1}&a на сервере &b{2}&a, мире &b{3}&a."
set-inherit-success: "&b{0}&a теперь наследует разрешения от &b{1}&a."
set-inherit-server-success: "&b{0}&a теперь наследует разрешения от &b{1}&a на сервере &b{2}&a."
set-inherit-server-world-success: "&b{0}&a теперь наследует разрешения от &b{1}&a на сервере &b{2}&a, мире &b{3}&a."
set-parent-success: "&b{0}&a их существующие родительские группы очищены, и теперь только наследуют &b{1}&a."
set-parent-server-success: "&b{0}&a их существующие родительские группы очищены, и теперь только наследуют &b{1}&a на сервере &b{2}&a."
set-parent-server-world-success: "&b{0}&a их существующие родительские группы очищены, и теперь только наследуют &b{1}&a на сервере &b{2}&a, мире &b{3}&a."
set-temp-inherit-success: "&b{0}&a теперь наследует разрешения (пермы) от &b{1}&a на срок &b{2}&a."
set-temp-inherit-server-success: "&b{0}&a теперь наследует разрешения (пермы) от &b{1}&a на сервере &b{2}&a for a duration of &b{3}&a."
set-temp-inherit-server-world-success: "&b{0}&a теперь наследует разрешения (пермы) от &b{1}&a на сервере &b{2}&a, мире &b{3}&a, на срок &b{4}&a."
unset-inherit-success: "&b{0}&a больше не наследует разрешения (пермы) от &b{1}&a."
unset-inherit-server-success: "&b{0}&a больше не наследует разрешения (пермы) &b{1}&a на сервере &b{2}&a."
unset-inherit-server-world-success: "&b{0}&a больше не наследует разрешения (пермы) &b{1}&a на сервере &b{2}&a, мире &b{3}&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."
unset-temp-inherit-server-success: "&b{0}&a больше не наследует временные разрешения (пермы) &b{1}&a на сервере &b{2}&a."
unset-temp-inherit-server-world-success: "&b{0}&a больше не наследует временные разрешения (пермы) &b{1}&a на сервере &b{2}&a, мире &b{3}&a."
clear-success: "&b{0}&a's разрешения (пермы) были очищены. (&b{1}&a узлы были удалены.)"
clear-success-singular: "&b{0}&a's разрешения (пермы) были очищены. (&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 Meta очищена. (&b{1}&a узлы были удалены.)"
meta-clear-success-singular: "&b{0}&a's Meta очищена. (&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 Meta"
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."
meta-none: "&b{0} не имеет мету."
meta-invalid-priority: "Недопустимый приоритет '{0}'. Ожидается число."
already-has-prefix: "{0} Уже имеет этот набор префиксов."
already-has-suffix: "{0} Уже имеет этот набор суффиксов."
does-not-have-prefix: "{0} Не имеет этого набора префиксов."
does-not-have-suffix: "{0} Не имеет этого набора суффиксов."
addprefix-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a."
addprefix-server-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a на сервере &b{3}&a."
addprefix-server-world-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a на сервере &b{3}&a, мире &b{4}&a."
removeprefix-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено."
removeprefix-server-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a."
removeprefix-server-world-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a, мире &b{4}&a."
addsuffix-success: "&b{0}&a имеет суффикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a."
addsuffix-server-success: "&b{0}&a имеет суффикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a на сервере &b{3}&a."
addsuffix-server-world-success: "&b{0}&a имеет суффикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a on server &b{3}&a, мире &b{4}&a."
removesuffix-success: "&b{0}&a имеет суффикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено."
removesuffix-server-success: "&b{0}&a имеет суффикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a."
removesuffix-server-world-success: "&b{0}&a имеет суффикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a, мире &b{4}&a."
add-temp-prefix-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a на срок &b{3}&a."
add-temp-prefix-server-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a установленный в приоритете of &b{2}&a на сервере &b{3}&a, на срок &b{4}&a."
add-temp-prefix-server-world-success: "&b{0}&a имеет префикс &f\"{1}&f\"&a установленный в приоритете of &b{2}&a на сервере &b{3}&a, мире &b{4}&a, на срок &b{5}&a."
remove-temp-prefix-success: "&b{0}&a Имел временный префикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено."
remove-temp-prefix-server-success: "&b{0}&a Имел временный префикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a."
remove-temp-prefix-server-world-success: "&b{0}&a Имел временный префикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a, мире &b{4}&a."
add-temp-suffix-success: "&b{0}&a имел суффикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a на срок &b{3}&a."
add-temp-suffix-server-success: "&b{0}&a имел суффикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a на сервере &b{3}&a, на срок &b{4}&a."
add-temp-suffix-server-world-success: "&b{0}&a имел суффикс &f\"{1}&f\"&a установленный в приоритете &b{2}&a на сервере &b{3}&a, мире &b{4}&a, на срок &b{5}&a."
remove-temp-suffix-success: "&b{0}&a Имел временный суффикс &f\"{1}&f\"&a в приоритете &b{1}&a удалено."
remove-temp-suffix-server-success: "&b{0}&a Имел временный суффикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a."
remove-temp-suffix-server-world-success: "&b{0}&a Имел временный суффикс &f\"{1}&f\"&a в приоритете &b{2}&a удалено на сервере &b{3}&a, мире &b{4}&a."
already-has-meta: "{0} Уже установлено, что установлена ​​пара мета-значения ключа."
set-meta-success: "&aУстановить метазначение для ключа &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a."
set-meta-server-success: "&aУстановить метазначение для ключа &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a на сервере &b{3}&a."
set-meta-server-world-success: "&aУстановить метазначение для ключа &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a на сервере &b{3}&a, мире &b{4}&a."
set-meta-temp-success: "&aУстановить метазначение для ключа &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a на срок &b{3}&a."
set-meta-temp-server-success: "&aУстановить метазначение для ключа &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a на сервере &b{3}&a на срок &b{4}&a."
set-meta-temp-server-world-success: "&aУстановить метазначение для ключа &f\"{0}&f\"&a к &f\"{1}&f\"&a для &b{2}&a на сервере &b{3}&a, мире &b{4}&a, на срок &b{5}&a."
unset-meta-success: "&aСбросить метазначение с помощью ключа &f\"{0}&f\"&a для &b{1}&a."
unset-meta-server-success: "&aСбросить метазначение с помощью ключа &f\"{0}&f\"&a для &b{1}&a на сервере &b{2}&a."
unset-meta-server-world-success: "&aСбросить метазначение с помощью ключа &f\"{0}&f\"&a для &b{1}&a на сервере &b{2}&a, мире &b{3}&a."
unset-meta-temp-success: "&aUnset temporary meta value with key &f\"{0}&f\"&a для &b{1}&a."
unset-meta-temp-server-success: "&aСбросить временное мета-значение с помощью ключа &f\"{0}&f\"&a для &b{1}&a на сервере &b{2}&a."
unset-meta-temp-server-world-success: "&aСбросить временное мета-значение с помощью ключа &f\"{0}&f\"&a для &b{1}&a на сервере &b{2}&a, мире &b{3}&a."
bulk-change-type-error: "Недопустимый тип. ожидание 'server' или 'world'."
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
@@ -236,11 +207,11 @@ user-info-general: >
{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{4}\n
{PREFIX}&f- &3Временные разрешения: &a{5}\n
{PREFIX}&f- &3Префиксы: &a{6}\n
{PREFIX}&f- &3Суффиксы: &a{7}\n
{PREFIX}&f- &3Meta: &a{8}
{PREFIX}&f- &3Мета: &a{8}
user-info-data: >
{PREFIX}&f- &aКэшированные данные:\n
{PREFIX}&f- &3Загружается: {0}\n
@@ -255,70 +226,64 @@ user-primarygroup-success: "&b{0}&a's для основной группы ус
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: "Указанный пользователь не находится ни в каких группах на этом пути (track)."
user-track-added-to-first: "&b{0}&a Не находится ни в каких группах на этом пути (track), поэтому они были добавлены в первую группу, &b{1}&a."
user-track-added-to-first-server: "&b{0}&a Не находится ни в каких группах на этом пути (track), поэтому они были добавлены в первую группу, &b{1}&a, на сервере &b{2}&a."
user-track-added-to-first-server-world: "&b{0}&a Не находится ни в каких группах на этом пути (track), поэтому они были добавлены в первую группу, &b{1}&a, на сервере &b{2}&a, мире &b{3}&a."
user-promote-success: "&aПродвижение пользователя по пути (track) &b{0}&a от &b{1}&a к &b{2}&a."
user-promote-success-server: "&aПродвижение пользователя по пути (track) &b{0}&a от &b{1}&a к &b{2}&a на сервере &b{3}&a."
user-promote-success-server-world: "&aПродвижение пользователя по пути (track) &b{0}&a от &b{1}&a к &b{2}&a на сервере &b{3}&a, мире &b{4}&a."
user-promote-error-endoftrack: "Конец пути (track) &4{0}&c ,был достигнут. Не удалось продвинуть пользователя."
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}Следующая группа на пути (track), {0}, более не существует. Не удалось продвинуть пользователя.\n
{PREFIX}Создайте группу или удалите ее с пути (track) и повторите попытку.
user-demote-success: "&aПонижение пользователя по пути (track) &b{0}&a от &b{1}&a к &b{2}&a."
user-demote-success-server: "&aПонижение пользователя по пути (track) &b{0}&a от &b{1}&a к &b{2}&a на сервере &b{3}&a."
user-demote-success-server-world: "&aПонижение пользователя по пути (track) &b{0}&a от &b{1}&a к &b{2}&a на сервере &b{3}&a, мире &b{4}&a."
user-demote-endoftrack: "Конец пути (track) &4{0}&c был достингут, поэтому &4{1}&c был удален из &4{2}&c."
{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}Предыдущая группа на пути (track), {0}, более не существуют. Невозможно понизить рейтинг пользователя.\n
{PREFIX}Создайте группу или удалите ее с пути (track) и повторите попытку.
{PREFIX}Предыдущая группа на пути, {0}, более не существуют. Невозможно понизить рейтинг пользователя.\n
{PREFIX}Создайте группу или удалите ее с пути и повторите попытку.
user-showpos: >
&aпоказывает &b{0}&a's позицию на пути (track) &b{1}&a.\n
&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{3}\n
{PREFIX}&f- &3Временные разрешения: &a{4}\n
{PREFIX}&f- &3Префиксы: &a{5}\n
{PREFIX}&f- &3Суффиксы: &a{6}\n
{PREFIX}&f- &3Meta: &a{7}
{PREFIX}&f- &3Мета: &a{7}
group-set-weight: "&aУстановить значение &b{0}&a для группы &b{1}&a."
track-info: >
{PREFIX}&b&l> &bпоказать путь (track): &f{0}\n
{PREFIX}&b&l> &bПоказать путь: &f{0}\n
{PREFIX}&f- &7Путь: &f{1}
track-clear: "&b{0}&a's путь (track) групп был очищен."
track-append-success: "&aГруппа &b{0}&a успешно добавлен в путь (track) &b{1}&a."
track-insert-success: "&aГруппа &b{0}&a был успешно добавлен в путь (track) &b{1}&a на позиции &b{2}&a."
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 Успешно удален с пути (track) &b{1}&a."
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} ago&8) {2}"
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(page &f{1}&a of &f{2}&a)"
log-recent-header: "&aПоследние действия (page &f{0}&a of &f{1}&a)"
log-recent-by-header: "&aПоказывать последние действия &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-user-header: "&aОтображение истории для пользователя &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-group-header: "&aОтображение истории для группы &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-track-header: "&aОтображение истории для пути (track) &b{0} &a(page &f{1}&a of &f{2}&a)"
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-empty: "Логи пусты и поэтому не могут быть экспортированы."
log-export-failure: "Произошла непредвиденная ошибка во время записи в файл."
log-export-success: "&aФайл журнала успешно экспортирован в &b{0}&a."
log-export-success: "&aФайл логов успешно экспортирован в &b{0}&a."
import-already-running: "Другой процесс импорта уже запущен. Дождитесь завершения и повторите попытку."
export-already-running: "Еще один процесс экспорта уже запущен. Дождитесь завершения и повторите попытку."
export-already-running: "Другой процесс экспорта уже запущен. Дождитесь завершения и повторите попытку."
import-log-doesnt-exist: "Ошибка: файл {0} не существует."
import-log-not-readable: "Ошибка: файл {0} не читается."
import-log-failure: "Произошла непредвиденная ошибка при чтении лога."
+303
View File
@@ -0,0 +1,303 @@
# LuckPerms Language File
# Locale: zh-CN (Simplified Chinese)
# Author: EuropeJing
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此服务器上禁用了vanilla OP系统."
op-disabled-sponge: "&2服务器管理员状态在安装权限插件时无效,请直接编辑用户数据."
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: "命令未被识别."
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'命令,而不是指定节点."
verbose-invalid-filter: "&c无效的详细过滤器: &f{0}"
verbose-on: "&b所有权限的详细输出设置为&a开&b."
verbose-on-query: "&b将匹配过滤器:&f{0}&b的权限详细输出设置为&a开&b."
verbose-off: "&b所有权限的详细输出设置为&c关&b."
verbose-recording-on: "&b所有权限的详细记录设置为&a开&b."
verbose-recording-on-query: "&b将匹配过滤器:&f{0}&b的权限详细记录设置为&a开&b."
verbose-recording-upload-start: "&b详细记录被禁用. 正在上传结果..."
verbose-recording-url: "&a详细结果的网址:"
tree-upload-start: "&b生成权限树..."
tree-empty: "&a无法生成树,没有找到结果."
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}"
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: "{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}成功通知."
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应用通配符: {21}\n
{PREFIX}&f- &3应用正则表达式: {22}\n
{PREFIX}&f- &3应用速记: {23}
create-group-error: "创建组时出错."
delete-group-error: "删除组时出错."
delete-group-error-default: "您不能删除默认组."
groups-list: "&aGroups: {0}"
create-track-error: "创建轨道时出错."
delete-track-error: "删除轨道时出错."
tracks-list: "&a轨道: {0}"
listnodes: "&b{0}的节点:"
listnodes-with-page: "&b{0}的节点: {1}"
listnodes-temp: >
&b{0}的临时节点:\n
{1}
listparents: >
&b{0}的父组:\n
{1}
listparents-temp: >
&b{0}的临时父组:\n
{1}
listgroups: >
&b{0}的组:\n
{1}
listgroups-temp: >
&b{0}的临时组:\n
{1}
list-tracks: >
&b{0}的轨道:\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在环境&b{3}&b中,&b{0}&b的权限&b{1}&b被设置为&b{2}&b."
check-permission-inherited: "&b{0}&a在环境&b{3}&a中的&b{1}&a被设置为&b{2}&a,继承自&b{4}&a."
setpermission-success: "&a在&b{3}&a中为&b{2}&a设置&b{0}&a为&b{1}&a."
setpermission-temp-success: "&a在环境&b{4}&a将&b{0}&a的&b{2}&a设为&b{1}&a,持续时间&b{3}&a."
unsetpermission-success: "&a在环境&b{2}&a中取消&b{1}&a的&b{0}&a."
unset-temp-permission-success: "&a在环境&b{2}&a中取消设置&b{1}&a的临时许可&b{0}&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."
unset-inherit-success: "&b{0}&a不再继承环境&b{2}&a中的&b{1}&a权限."
unset-temp-inherit-success: "&b{0}&a在环境{2}中不再临时从&b{1}&a继承权限."
clear-success: "&b{0}&a的权限被清除. (&b{1}&a节点被删除.)"
clear-success-singular: "&b{0}&a的权限被清除. (&b{1}&a节点已被删除.)"
parent-clear-success: "&b{0}&a的组被清除. (&b{1}&a节点被删除.)"
parent-clear-success-singular: "&b{0}&a的组被清除. (&b{1}&a节点已被删除.)"
meta-clear-success: "&b{0}&a的父组被清除. (&b{1}&a节点被删除.)"
meta-clear-success-singular: "已经清除了这个&b{0}&a的元数据. (&b{1}&a节点已被删除.)"
illegal-date-error: "无法解析日期'{0}'."
past-date-error: "您不能设定一个过去的日期!"
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: "优先级'{0}'无效. 应该是一个数字."
already-has-chat-meta: "{0}已经设置了{1}."
does-not-have-chat-meta: "{0}没有设置{1}."
add-chatmeta-success: "&b{0}&a在环境&b{4}&a中将优先级&b{3}&a设置为 {1} &f\"{2}&f\"."
add-temp-chatmeta-success: "&b{0}&a在环境&b{5}&a中,设置为优先级&b{3}&a的{1} &f\"{2}&f\"&a,持续时间为&b{4}&a."
remove-chatmeta-success: "&b{0}&a在&b{3}&a中删除了优先级&b{3}&a的{1} &f\"{2}&f\"&a."
bulk-remove-chatmeta-success: "&b{0}&a had all {1}es at priority &b{3}&a removed in context {4}&a."
remove-temp-chatmeta-success: "&b{0}&a在环境&b{4}&a中删除了优先级&b{3}&a的临时{1} &f\"{2}&f\"&a."
bulk-remove-temp-chatmeta-success: "&b{0}&a在环境&b{4}&a中移除了优先级&b{3}&a的所有临时&b{1}&a.."
already-has-meta: "{0}已经有了这个元信息集."
set-meta-success: "将环境&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: "Invalid type. Was expecting 'all', 'users' or 'groups'."
bulk-update-invalid-constraint: "无效的约束&4{0}&c.约束的格式应该是'&f<field> <comparison operator> <value>&c'."
bulk-update-invalid-comparison: "比较运算符无效'&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: "&cBulk update failed. Check the console for errors."
bulk-change-type-error: "类型无效. 应该是 'server' 或 'world'."
bulk-change-success: "&a应用批量更改成功. {0}记录已更改."
user-info-general: >
{PREFIX}&b&l> &bUser Info: &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- &aCached Data:\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: "&b{0}&b的UUID是&b{1}&b."
user-removegroup-error-primary: "您不能从其主组中删除用户."
user-primarygroup-success: "&b{0}&的主组已设为&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{2}&a中将其添加到第一组&b{2}&a."
user-promote-success: "&a在环境&b{3}&a中将用户沿轨道&b{0}&a从&b{1}&a提升到&b{2}&a."
user-promote-error-endoftrack: "已达到轨道&4{0}&c的结尾,所以无法提升用户."
user-promote-error-malformed: >
{PREFIX}轨道上的下一个组{0}不存在. 无法提升用户.\n
{PREFIX}创建组,或将其从轨道中删除,然后重试.
user-demote-success: "&a在环境&b{3}&a中将用户沿轨道&b{0}&a从&b{1}&a转移到&b{2}&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在轨道&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{1}&a的权重设置为&b{0}&a."
track-info: >
{PREFIX}&b&l> &b显示轨道: &f{0}\n
{PREFIX}&f- &7路径: &f{1}
track-clear: "&b{0}&a's groups track was cleared."
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: "&aGroup &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} ago&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(page &f{1}&a of &f{2}&a)"
log-recent-header: "&a显示最近操作 (page &f{0}&a of &f{1}&a)"
log-recent-by-header: "&a显示&b{0}&a的最近操作 (page &f{1}&a of &f{2}&a)"
log-history-user-header: "&a显示用户的历史记录&b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-group-header: "&a显示组的历史记录 &b{0} &a(page &f{1}&a of &f{2}&a)"
log-history-track-header: "&a显示轨道的历史记录 &b{0} &a(page &f{1}&a of &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}完成 &7- &b{1}&f/&b{2} &f完成 &c{3}&f错误."
import-progress-sin: "&b(导入) &b-> &f百分之{0}完成 &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执行时: &3Command #{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<------------------------------------------>"
+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
+19
View File
@@ -18,15 +18,34 @@ LuckPerms also includes an extensive API for developers, and support for a varie
LuckPerms uses Maven to handle dependencies.
#### Requirements
* Java 8 JDK
* Maven 3.3.x (the older versions will not work.)
* Git
#### Then run
```sh
git clone https://github.com/lucko/LuckPerms.git
cd LuckPerms/
mvn clean package
```
You can find the output jars in the `target` directories.
## 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.
#### 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!)
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.
#### Project Layout
The project is split up into 5 seperate modules.
* **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
LuckPerms is licensed under the permissive MIT license. Please see [`LICENSE.txt`](https://github.com/lucko/LuckPerms/blob/master/LICENSE.txt) for more info.
+79 -1
View File
@@ -5,13 +5,23 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>3.1-SNAPSHOT</version>
<version>3.3-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>
@@ -25,6 +35,68 @@
</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>
@@ -33,6 +105,12 @@
<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
@@ -26,6 +29,8 @@ import me.lucko.luckperms.api.LuckPermsApi;
import java.util.Optional;
import javax.annotation.Nonnull;
/**
* Singleton for the {@link LuckPermsApi}.
*
@@ -41,6 +46,7 @@ public final class LuckPerms {
* @return an api instance
* @throws IllegalStateException if the api is not loaded
*/
@Nonnull
public static LuckPermsApi getApi() {
if (api == null) {
throw new IllegalStateException("API is not loaded.");
@@ -49,21 +55,24 @@ public final class LuckPerms {
}
/**
* Gets an instance of {@link LuckPermsApi} safely.
* Gets an instance of {@link LuckPermsApi}, if it is loaded.
*
* <p> Unlike {@link LuckPerms#getApi}, this method will not throw an {@link IllegalStateException} if the API is
* not loaded, rather return an empty {@link Optional}.
*
* @return an optional api instance
*/
@Nonnull
public static Optional<LuckPermsApi> getApiSafe() {
return Optional.ofNullable(api);
}
/* method used by the implementation to set the singleton instance */
static void registerProvider(LuckPermsApi luckPermsApi) {
api = luckPermsApi;
}
/* method used by the implementation to remove any previous instance */
static void unregisterProvider() {
api = null;
}
@@ -0,0 +1,107 @@
/*
* 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 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);
}
@@ -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,6 +27,8 @@ package me.lucko.luckperms.api;
import me.lucko.luckperms.api.context.ContextSet;
import javax.annotation.Nonnull;
/**
* Context and options for a permission lookup.
*
@@ -34,18 +39,31 @@ import me.lucko.luckperms.api.context.ContextSet;
public class Contexts {
public static final String SERVER_KEY = "server";
public static final String WORLD_KEY = "world";
private static final Contexts ALLOW_ALL = new Contexts(ContextSet.empty(), true, true, true, true, true, true);
private static final Contexts GLOBAL = new Contexts(ContextSet.empty(), true, true, true, true, true, false);
/**
* Gets a context that will allow all nodes
* Gets the {@link FullySatisfiedContexts} instance.
*
* @return a context that will not apply any filters
* @return a context that will satisfy all contextual requirements.
*/
@Nonnull
public static Contexts allowAll() {
return ALLOW_ALL;
return FullySatisfiedContexts.getInstance();
}
public static Contexts of(ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
/**
* 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);
}
@@ -87,7 +105,7 @@ public class Contexts {
*/
private final boolean applyGlobalWorldGroups;
public Contexts(ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
public Contexts(@Nonnull ContextSet context, boolean includeGlobal, boolean includeGlobalWorld, boolean applyGroups, boolean applyGlobalGroups, boolean applyGlobalWorldGroups, boolean op) {
if (context == null) {
throw new NullPointerException("context");
}
@@ -107,6 +125,7 @@ public class Contexts {
* @return an immutable set of context key value pairs
* @since 2.13
*/
@Nonnull
public ContextSet getContexts() {
return this.context;
}
@@ -165,6 +184,8 @@ public class Contexts {
return this.applyGlobalWorldGroups;
}
@Override
@Nonnull
public String toString() {
return "Contexts(" +
"context=" + this.getContexts() + ", " +
@@ -181,18 +202,14 @@ public class Contexts {
* Ugly auto-generated lombok code
*/
/**
* Check for equality
*
* @param o the other
* @return true if equal
* @since 2.12
*/
@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() == null ? other.getContexts() == null : this.getContexts().equals(other.getContexts())) &&
return this.getContexts().equals(other.getContexts()) &&
this.isOp() == other.isOp() &&
this.isIncludeGlobal() == other.isIncludeGlobal() &&
this.isIncludeGlobalWorld() == other.isIncludeGlobalWorld() &&
@@ -201,17 +218,12 @@ public class Contexts {
this.isApplyGlobalWorldGroups() == other.isApplyGlobalWorldGroups();
}
/**
* Gets the hashcode
*
* @return the hashcode
* @since 2.12
*/
@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object contexts = this.getContexts();
result = result * PRIME + (contexts == null ? 43 : contexts.hashCode());
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);
@@ -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
@@ -0,0 +1,51 @@
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><ul>
* <li>{@link UserData#getPermissionData(Contexts)}</li>
* <li>{@link UserData#getMetaData(Contexts)}</li>
* <li>{@link UserData#getMetaData(MetaContexts)}</li>
* </ul></p>
*
* <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 {
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) {
return o == this;
}
@Override
public int hashCode() {
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,12 +25,15 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.OptionalInt;
import javax.annotation.Nonnull;
/**
* A group which holds permission data.
*/
@@ -38,17 +44,39 @@ public interface Group extends PermissionHolder {
*
* @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 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 a group inherits another group directly
*
* @param group The group to check membership of
* @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(@Nonnull Group group, @Nonnull ContextSet contextSet);
/**
* Gets the weight of this group, if present.
*
* @return the group weight
* @since 2.17
*/
@Nonnull
OptionalInt getWeight();
/**
* Check to see if the group inherits a group on a specific server
@@ -59,8 +87,10 @@ public interface Group extends PermissionHolder {
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of {@link #inheritsGroup(Group, ContextSet)}
*/
boolean inheritsGroup(Group group, String server);
@Deprecated
boolean inheritsGroup(@Nonnull Group group, @Nonnull String server);
/**
* Check to see if the group inherits a group on a specific server and world
@@ -72,8 +102,10 @@ public interface Group extends PermissionHolder {
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link #inheritsGroup(Group, ContextSet)}
*/
boolean inheritsGroup(Group group, String server, String world);
@Deprecated
boolean inheritsGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world);
/**
* Make this group inherit another group
@@ -85,7 +117,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(Group group) throws ObjectAlreadyHasException;
void setInheritGroup(@Nonnull Group group) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
@@ -99,7 +131,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(Group group, String server) throws ObjectAlreadyHasException;
void setInheritGroup(@Nonnull Group group, @Nonnull String server) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server and world
@@ -114,7 +146,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
void setInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group temporarily
@@ -128,7 +160,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
void setInheritGroup(@Nonnull Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server temporarily
@@ -143,7 +175,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
void setInheritGroup(@Nonnull Group group, @Nonnull String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server and world temporarily
@@ -159,7 +191,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
void setInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove a previously set inheritance rule
@@ -171,7 +203,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(Group group) throws ObjectLacksException;
void unsetInheritGroup(@Nonnull Group group) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule
@@ -184,7 +216,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(Group group, boolean temporary) throws ObjectLacksException;
void unsetInheritGroup(@Nonnull Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server
@@ -198,7 +230,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(Group group, String server) throws ObjectLacksException;
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server and world
@@ -213,7 +245,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(Group group, String server, String world) throws ObjectLacksException;
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server
@@ -228,7 +260,7 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server and world
@@ -244,13 +276,16 @@ public interface Group extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, boolean temporary) throws ObjectLacksException;
/**
* Get a {@link List} of all of the groups the group inherits, on all servers
*
* @return a {@link List} of group names
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getGroupNames();
/**
@@ -260,8 +295,11 @@ public interface Group extends PermissionHolder {
* @return a {@link List} of group names
* @throws NullPointerException if the server is null
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of just querying a users permissions
*/
List<String> getLocalGroups(String server);
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server);
/**
@@ -272,15 +310,10 @@ public interface Group extends PermissionHolder {
* @return a {@link List} of group names
* @throws NullPointerException if the server or world is null
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of just querying a users permissions
*/
List<String> getLocalGroups(String server, String world);
/**
* Gets the weight of this group, is present.
*
* @return the group weight
* @since 2.17
*/
OptionalInt getWeight();
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server, @Nonnull String world);
}
@@ -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
@@ -27,6 +30,8 @@ import com.google.common.collect.Multimap;
import java.util.Optional;
import java.util.OptionalLong;
import javax.annotation.Nonnull;
/**
* A relationship between a Holder and a permission
*
@@ -40,6 +45,7 @@ public interface HeldPermission<T> {
*
* @return the holder
*/
@Nonnull
T getHolder();
/**
@@ -47,6 +53,7 @@ public interface HeldPermission<T> {
*
* @return the permission
*/
@Nonnull
String getPermission();
/**
@@ -61,6 +68,7 @@ public interface HeldPermission<T> {
*
* @return the server
*/
@Nonnull
Optional<String> getServer();
/**
@@ -68,6 +76,7 @@ public interface HeldPermission<T> {
*
* @return the world
*/
@Nonnull
Optional<String> getWorld();
/**
@@ -82,6 +91,7 @@ public interface HeldPermission<T> {
*
* @return the context
*/
@Nonnull
Multimap<String, String> getContext();
/**
@@ -89,6 +99,7 @@ public interface HeldPermission<T> {
*
* @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
@@ -26,6 +29,8 @@ import me.lucko.luckperms.api.data.DatastoreConfiguration;
import java.util.Map;
import javax.annotation.Nonnull;
/**
* Read-only access to the LuckPerms configuration settings
*/
@@ -35,6 +40,7 @@ public interface LPConfiguration {
* Returns the name of this server
* @return the name of this server
*/
@Nonnull
String getServer();
/**
@@ -127,6 +133,7 @@ public interface LPConfiguration {
* @return the name of the server used within Vault operations
* @since 2.7
*/
@Nonnull
String getVaultServer();
/**
@@ -140,12 +147,14 @@ public interface LPConfiguration {
* Returns the values set for data storage in the configuration
* @return the values set for data storage in the configuration
*/
@Nonnull
DatastoreConfiguration getDatastoreConfig();
/**
* Returns the storage method string from the configuration
* @return the storage method string from the configuration
*/
@Nonnull
String getStorageMethod();
/**
@@ -161,6 +170,27 @@ public interface LPConfiguration {
* 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 parameter 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);
}
}
@@ -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,6 +25,8 @@
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* A node with a traceable origin
*
@@ -34,6 +39,7 @@ public interface LocalizedNode extends Node {
*
* @return the node this instance is representing
*/
@Nonnull
Node getNode();
/**
@@ -42,6 +48,7 @@ public interface LocalizedNode extends Node {
* @return where the node was inherited from. Will not return null.
* @see PermissionHolder#getObjectName()
*/
@Nonnull
String getLocation();
}
@@ -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
@@ -26,6 +29,8 @@ import java.util.SortedMap;
import java.util.SortedSet;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Represents the internal LuckPerms log.
*
@@ -37,11 +42,13 @@ public interface Log {
/**
* @return a {@link SortedSet} of all of the {@link LogEntry} objects in this {@link Log}
*/
@Nonnull
SortedSet<LogEntry> getContent();
/**
* @return all content in this log
*/
@Nonnull
SortedSet<LogEntry> getRecent();
/**
@@ -52,6 +59,7 @@ public interface Log {
* @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);
/**
@@ -64,7 +72,8 @@ public interface Log {
* @param actor the uuid of the actor to filter by
* @return all content in this log where is actor = uuid
*/
SortedSet<LogEntry> getRecent(UUID actor);
@Nonnull
SortedSet<LogEntry> getRecent(@Nonnull UUID actor);
/**
* Gets the recent content for the uuid, separated into pages
@@ -75,20 +84,22 @@ public interface Log {
* @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)}}
*/
SortedMap<Integer, LogEntry> getRecent(int pageNo, UUID actor);
@Nonnull
SortedMap<Integer, LogEntry> getRecent(int pageNo, @Nonnull UUID actor);
/**
* @param actor the actor to filter by
* @return the max page number allowed in the {@link #getRecent(int, UUID)} method
*/
int getRecentMaxPages(UUID actor);
int getRecentMaxPages(@Nonnull UUID actor);
/**
* @param uuid the uuid to filter by
* @return all content in this log where the user = uuid
*/
SortedSet<LogEntry> getUserHistory(UUID uuid);
@Nonnull
SortedSet<LogEntry> getUserHistory(@Nonnull UUID uuid);
/**
* Gets the user history content, separated by pages
@@ -99,20 +110,22 @@ public interface Log {
* @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)}}
*/
SortedMap<Integer, LogEntry> getUserHistory(int pageNo, UUID uuid);
@Nonnull
SortedMap<Integer, LogEntry> getUserHistory(int pageNo, @Nonnull UUID uuid);
/**
* @param uuid the uuid to filter by
* @return the max page number allowed in the {@link #getUserHistory(int, UUID)} method
*/
int getUserHistoryMaxPages(UUID uuid);
int getUserHistoryMaxPages(@Nonnull UUID uuid);
/**
* @param name the name to filter by
* @return all content in this log where the group = name
*/
SortedSet<LogEntry> getGroupHistory(String name);
@Nonnull
SortedSet<LogEntry> getGroupHistory(@Nonnull String name);
/**
* Gets the group history content, separated by pages
@@ -123,20 +136,22 @@ public interface Log {
* @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)}}
*/
SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, String name);
@Nonnull
SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, @Nonnull String name);
/**
* @param name the name to filter by
* @return the max page number allowed in the {@link #getGroupHistory(int, String)} method
*/
int getGroupHistoryMaxPages(String name);
int getGroupHistoryMaxPages(@Nonnull String name);
/**
* @param name the name to filter by
* @return all content in this log where the track = name
*/
SortedSet<LogEntry> getTrackHistory(String name);
@Nonnull
SortedSet<LogEntry> getTrackHistory(@Nonnull String name);
/**
* Gets the track history content, separated by pages
@@ -145,7 +160,8 @@ public interface Log {
* @param name the name of the acted track to filter by
* @return the page content
*/
SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, String name);
@Nonnull
SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, @Nonnull String name);
/**
* @param name the name to filter by
@@ -153,14 +169,15 @@ public interface Log {
* @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)}}
*/
int getTrackHistoryMaxPages(String name);
int getTrackHistoryMaxPages(@Nonnull String name);
/**
* @param query the query to filter by
* @return all content in this log where the content matches query
*/
SortedSet<LogEntry> getSearch(String query);
@Nonnull
SortedSet<LogEntry> getSearch(@Nonnull String query);
/**
* Gets the search content, separated by pages
@@ -171,11 +188,12 @@ public interface Log {
* @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)}}
*/
SortedMap<Integer, LogEntry> getSearch(int pageNo, String query);
@Nonnull
SortedMap<Integer, LogEntry> getSearch(int pageNo, @Nonnull String query);
/**
* @param query the query to filter by
* @return the max page number allowed in the {@link #getSearch(int, String)} method
*/
int getSearchMaxPages(String query);
int getSearchMaxPages(@Nonnull String query);
}
@@ -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,6 +27,9 @@ package me.lucko.luckperms.api;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A single entry in the log
*
@@ -32,6 +38,7 @@ import java.util.UUID;
public class LogEntry implements Comparable<LogEntry> {
private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
@Nonnull
public static LogEntryBuilder builder() {
return new LogEntryBuilder();
}
@@ -44,7 +51,7 @@ public class LogEntry implements Comparable<LogEntry> {
private String actedName;
private String action;
public LogEntry(long timestamp, UUID actor, String actorName, char type, UUID acted, String actedName, String action) {
public LogEntry(long timestamp, @Nonnull UUID actor, @Nonnull String actorName, char type, @Nullable UUID acted, @Nonnull String actedName, @Nonnull String action) {
if (actor == null) {
throw new NullPointerException("actor");
}
@@ -82,17 +89,18 @@ public class LogEntry implements Comparable<LogEntry> {
return equals(o) ? 0 : (Long.compare(timestamp, o.getTimestamp()) == 0 ? 1 : Long.compare(timestamp, o.getTimestamp()));
}
public boolean matchesSearch(String query) {
public boolean matchesSearch(@Nonnull String query) {
query = query.toLowerCase();
return actorName.toLowerCase().contains(query) || actedName.toLowerCase().contains(query)
|| action.toLowerCase().contains(query);
}
@Nonnull
public String getFormatted() {
return String.format(FORMAT,
String.valueOf(actorName).equals("null") ? actor.toString() : actorName,
Character.toString(type),
actedName,
String.valueOf(actedName).equals("null") && acted != null ? acted.toString() : actedName,
action
);
}
@@ -105,19 +113,21 @@ public class LogEntry implements Comparable<LogEntry> {
this.timestamp = timestamp;
}
@Nonnull
public UUID getActor() {
return actor;
}
void setActor(UUID actor) {
void setActor(@Nonnull UUID actor) {
this.actor = actor;
}
@Nonnull
public String getActorName() {
return actorName;
}
void setActorName(String actorName) {
void setActorName(@Nonnull String actorName) {
this.actorName = actorName;
}
@@ -129,27 +139,30 @@ public class LogEntry implements Comparable<LogEntry> {
this.type = type;
}
@Nullable
public UUID getActed() {
return acted;
}
void setActed(UUID acted) {
void setActed(@Nullable UUID acted) {
this.acted = acted;
}
@Nonnull
public String getActedName() {
return actedName;
}
void setActedName(String actedName) {
void setActedName(@Nonnull String actedName) {
this.actedName = actedName;
}
@Nonnull
public String getAction() {
return action;
}
void setAction(String action) {
void setAction(@Nonnull String action) {
this.action = action;
}
@@ -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,18 +25,20 @@
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* A wrapper interface for platform logger instances
* Represents the logger instance being used by LuckPerms on the platform.
*
* <p>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.</p>
* <p>Messages sent using the logger are sent prefixed with the LuckPerms tag, and on some implementations will be colored
* depending on the message type.</p>
*/
public interface Logger {
void info(String s);
void info(@Nonnull String s);
void warn(String s);
void warn(@Nonnull String s);
void severe(String s);
void severe(@Nonnull String s);
}
@@ -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
@@ -25,11 +28,15 @@ package me.lucko.luckperms.api;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.event.EventBus;
import me.lucko.luckperms.api.metastacking.MetaStackFactory;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* The root API interface for LuckPerms
*/
@@ -42,6 +49,7 @@ public interface LuckPermsApi {
/**
* Gets the API version
*
* @return the version of the API running on the platform
* @since 2.6
*/
@@ -49,22 +57,28 @@ public interface LuckPermsApi {
/**
* Gets the plugin version
*
* @return the version of the plugin running on the platform
*/
@Nonnull
String getVersion();
/**
* Gets the platform LuckPerms is running on
*
* @return the platform LuckPerms is running on
* @since 2.7
*/
@Nonnull
PlatformType getPlatformType();
/**
* Gets the event bus, used for subscribing to events
*
* @return the event bus
* @since 3.0
*/
@Nonnull
EventBus getEventBus();
/**
@@ -72,6 +86,7 @@ public interface LuckPermsApi {
*
* @return a configuration instance
*/
@Nonnull
LPConfiguration getConfiguration();
/**
@@ -80,6 +95,7 @@ public interface LuckPermsApi {
* @return a storage instance
* @since 2.14
*/
@Nonnull
Storage getStorage();
/**
@@ -87,6 +103,7 @@ public interface LuckPermsApi {
*
* @return an optional that may contain a messaging service instance.
*/
@Nonnull
Optional<MessagingService> getMessagingService();
/**
@@ -94,6 +111,7 @@ public interface LuckPermsApi {
*
* @return the logger instance
*/
@Nonnull
Logger getLogger();
/**
@@ -101,6 +119,7 @@ public interface LuckPermsApi {
*
* @return a uuid cache instance
*/
@Nonnull
UuidCache getUuidCache();
/**
@@ -110,7 +129,8 @@ public interface LuckPermsApi {
* @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
User getUser(@Nonnull UUID uuid);
/**
* Gets a wrapped user object from the user storage.
@@ -121,7 +141,8 @@ public interface LuckPermsApi {
* @return an optional {@link User} object
* @throws NullPointerException if the uuid is null
*/
Optional<User> getUserSafe(UUID uuid);
@Nonnull
Optional<User> getUserSafe(@Nonnull UUID uuid);
/**
* Gets a wrapped user object from the user storage
@@ -130,7 +151,8 @@ public interface LuckPermsApi {
* @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
User getUser(@Nonnull String name);
/**
* Gets a wrapped user object from the user storage.
@@ -141,13 +163,15 @@ public interface LuckPermsApi {
* @return an optional {@link User} object
* @throws NullPointerException if the name is null
*/
Optional<User> getUserSafe(String name);
@Nonnull
Optional<User> getUserSafe(@Nonnull String name);
/**
* Gets a set of all loaded users.
*
* @return a {@link Set} of {@link User} objects
*/
@Nonnull
Set<User> getUsers();
/**
@@ -157,7 +181,7 @@ public interface LuckPermsApi {
* @return true if the user is loaded
* @throws NullPointerException if the uuid is null
*/
boolean isUserLoaded(UUID uuid);
boolean isUserLoaded(@Nonnull UUID uuid);
/**
* Unload a user from the internal storage, if they're not currently online.
@@ -166,7 +190,7 @@ public interface LuckPermsApi {
* @throws NullPointerException if the user is null
* @since 2.6
*/
void cleanupUser(User user);
void cleanupUser(@Nonnull User user);
/**
* Gets a wrapped group object from the group storage
@@ -175,7 +199,8 @@ public interface LuckPermsApi {
* @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
Group getGroup(@Nonnull String name);
/**
* Gets a wrapped group object from the group storage.
@@ -186,13 +211,15 @@ public interface LuckPermsApi {
* @return an optional {@link Group} object
* @throws NullPointerException if the name is null
*/
Optional<Group> getGroupSafe(String name);
@Nonnull
Optional<Group> getGroupSafe(@Nonnull String name);
/**
* Gets a set of all loaded groups.
*
* @return a {@link Set} of {@link Group} objects
*/
@Nonnull
Set<Group> getGroups();
/**
@@ -202,7 +229,7 @@ public interface LuckPermsApi {
* @return true if the group is loaded
* @throws NullPointerException if the name is null
*/
boolean isGroupLoaded(String name);
boolean isGroupLoaded(@Nonnull String name);
/**
* Gets a wrapped track object from the track storage
@@ -211,7 +238,8 @@ public interface LuckPermsApi {
* @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
Track getTrack(@Nonnull String name);
/**
* Gets a wrapped track object from the track storage.
@@ -222,13 +250,15 @@ public interface LuckPermsApi {
* @return an optional {@link Track} object
* @throws NullPointerException if the name is null
*/
Optional<Track> getTrackSafe(String name);
@Nonnull
Optional<Track> getTrackSafe(@Nonnull String name);
/**
* Gets a set of all loaded tracks.
*
* @return a {@link Set} of {@link Track} objects
*/
@Nonnull
Set<Track> getTracks();
/**
@@ -238,15 +268,25 @@ public interface LuckPermsApi {
* @return true if the track is loaded
* @throws NullPointerException if the name is null
*/
boolean isTrackLoaded(String name);
boolean isTrackLoaded(@Nonnull String name);
/**
* Gets the node factory instance for the platform
*
* @return the node factory
*/
@Nonnull
NodeFactory getNodeFactory();
/**
* Gets the MetaStackFactory, used for creating MetaStacks.
*
* @return the meta stack factory
* @since 3.2
*/
@Nonnull
MetaStackFactory getMetaStackFactory();
/**
* Returns a permission builder instance
*
@@ -256,7 +296,8 @@ public interface LuckPermsApi {
* @throws NullPointerException if the permission is null
* @since 2.6
*/
Node.Builder buildNode(String permission) throws IllegalArgumentException;
@Nonnull
Node.Builder buildNode(@Nonnull String permission) throws IllegalArgumentException;
/**
* Register a custom context calculator to the server
@@ -264,7 +305,7 @@ public interface LuckPermsApi {
* @param contextCalculator 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.
*/
void registerContextCalculator(ContextCalculator<?> contextCalculator);
void registerContextCalculator(@Nonnull ContextCalculator<?> contextCalculator);
/**
* Gets a calculated context instance for the user using the rules of the platform.
@@ -274,7 +315,8 @@ public interface LuckPermsApi {
* @param user the user to get contexts for
* @return an optional containing contexts. Will return empty if the user is not online.
*/
Optional<Contexts> getContextForUser(User user);
@Nonnull
Optional<Contexts> getContextForUser(@Nonnull User user);
/**
* Gets set of contexts applicable to a player using the platforms {@link ContextCalculator}s.
@@ -283,6 +325,34 @@ public interface LuckPermsApi {
* @return a set of contexts.
* @since 2.17
*/
ContextSet getContextForPlayer(Object player);
@Nonnull
ContextSet getContextForPlayer(@Nonnull Object 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
Contexts getContextsForPlayer(@Nonnull Object player);
/**
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
* @since 3.3
*/
@Nonnull
Set<UUID> getUniqueConnections();
/**
* Gets the time when the plugin first started in milliseconds.
*
* @return the enable time
* @since 3.3
*/
long getStartTime();
}
@@ -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
@@ -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
@@ -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
@@ -30,6 +33,9 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* An immutable permission node
*
@@ -40,27 +46,40 @@ import java.util.Set;
public interface Node extends Map.Entry<String, Boolean> {
/**
* Returns the actual permission string
*
* @return the actual permission node
*/
@Nonnull
String getPermission();
/**
* Get what value the permission is set to. A negated node would return <code>false</code>.
* Gets what value the permission is set to. A negated node would return <code>false</code>.
*
* @return the permission's value
*/
@Override
@Nonnull
Boolean getValue();
/**
* Returns the value of this node as a tristate
*
* @return the value of this node as a Tristate
*/
Tristate getTristate();
@Nonnull
default Tristate getTristate() {
return Tristate.fromBoolean(getValue());
}
/**
* Returns if the node is negated
*
* @return true if the node is negated
*/
boolean isNegated();
default boolean isNegated() {
return !getValue();
}
/**
* If this node is set to override explicitly.
@@ -75,6 +94,7 @@ public interface Node extends Map.Entry<String, Boolean> {
*
* @return an {@link Optional} containing the server, if one is defined
*/
@Nonnull
Optional<String> getServer();
/**
@@ -82,6 +102,7 @@ public interface Node extends Map.Entry<String, Boolean> {
*
* @return an {@link Optional} containing the world, if one is defined
*/
@Nonnull
Optional<String> getWorld();
/**
@@ -126,7 +147,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return true if the node should apply, otherwise false
* @since 3.1
*/
boolean shouldApply(boolean includeGlobal, boolean includeGlobalWorld, String server, String world, ContextSet context, boolean applyRegex);
boolean shouldApply(boolean includeGlobal, boolean includeGlobalWorld, @Nullable String server, @Nullable String world, @Nullable ContextSet context, boolean applyRegex);
/**
* If this node should apply on a specific server
@@ -136,7 +157,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @param applyRegex if regex should be applied
* @return true if the node should apply
*/
boolean shouldApplyOnServer(String server, boolean includeGlobal, boolean applyRegex);
boolean shouldApplyOnServer(@Nullable String server, boolean includeGlobal, boolean applyRegex);
/**
* If this node should apply on a specific world
@@ -146,7 +167,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @param applyRegex if regex should be applied
* @return true if the node should apply
*/
boolean shouldApplyOnWorld(String world, boolean includeGlobal, boolean applyRegex);
boolean shouldApplyOnWorld(@Nullable String world, boolean includeGlobal, boolean applyRegex);
/**
* If this node should apply in the given context
@@ -156,7 +177,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return true if the node should apply
* @since 2.13
*/
boolean shouldApplyWithContext(ContextSet context, boolean worldAndServer);
boolean shouldApplyWithContext(@Nonnull ContextSet context, boolean worldAndServer);
/**
* If this node should apply in the given context
@@ -165,7 +186,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return true if the node should apply
* @since 2.13
*/
boolean shouldApplyWithContext(ContextSet context);
boolean shouldApplyWithContext(@Nonnull ContextSet context);
/**
* Similar to {@link #shouldApplyOnServer(String, boolean, boolean)}, except this method accepts a List
@@ -174,7 +195,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @param includeGlobal if global permissions should apply
* @return true if the node should apply
*/
boolean shouldApplyOnAnyServers(List<String> servers, boolean includeGlobal);
boolean shouldApplyOnAnyServers(@Nonnull List<String> servers, boolean includeGlobal);
/**
* Similar to {@link #shouldApplyOnWorld(String, boolean, boolean)}, except this method accepts a List
@@ -183,7 +204,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @param includeGlobal if global permissions should apply
* @return true if the node should apply
*/
boolean shouldApplyOnAnyWorlds(List<String> worlds, boolean includeGlobal);
boolean shouldApplyOnAnyWorlds(@Nonnull List<String> worlds, boolean includeGlobal);
/**
* Resolves a list of wildcards that match this node
@@ -191,42 +212,57 @@ public interface Node extends Map.Entry<String, Boolean> {
* @param possibleNodes a list of possible permission nodes
* @return a list of permissions that match this wildcard
*/
List<String> resolveWildcard(List<String> possibleNodes);
@Nonnull
List<String> resolveWildcard(@Nonnull List<String> possibleNodes);
/**
* Resolves any shorthand parts of this node and returns the full list
*
* @return a list of full nodes
*/
@Nonnull
List<String> resolveShorthand();
/**
* Returns if this node will expire in the future
*
* @return true if this node will expire in the future
*/
boolean isTemporary();
/**
* Returns if this node will not expire
*
* @return true if this node will not expire
*/
boolean isPermanent();
default boolean isPermanent() {
return !isTemporary();
}
/**
* Returns 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();
long getExpiryUnixTime() throws IllegalStateException;
/**
* Returns the date when this node will expire
*
* @return the {@link Date} when this node will expire
* @throws IllegalStateException if the node is not temporary
*/
Date getExpiry();
@Nonnull
Date getExpiry() throws IllegalStateException;
/**
* Return 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();
long getSecondsTilExpiry() throws IllegalStateException;
/**
* Return true if the node has expired.
@@ -242,6 +278,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return the extra contexts required for this node to apply
* @since 2.13
*/
@Nonnull
ContextSet getContexts();
/**
@@ -250,6 +287,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return the full contexts required for this node to apply
* @since 3.1
*/
@Nonnull
ContextSet getFullContexts();
/**
@@ -259,6 +297,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @deprecated because this serialized form is no longer used by the implementation.
*/
@Deprecated
@Nonnull
String toSerializedNode();
/**
@@ -274,7 +313,8 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return the name of the group
* @throws IllegalStateException if this is not a group node. See {@link #isGroupNode()}
*/
String getGroupName();
@Nonnull
String getGroupName() throws IllegalStateException;
/**
* Returns if this node is a wildcard node
@@ -289,7 +329,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return the wildcard level
* @throws IllegalStateException if this is not a wildcard
*/
int getWildcardLevel();
int getWildcardLevel() throws IllegalStateException;
/**
* Returns if this node is a meta node
@@ -304,9 +344,12 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return the meta value
* @throws IllegalStateException if this node is not a meta node
*/
Map.Entry<String, String> getMeta();
@Nonnull
Map.Entry<String, String> getMeta() throws IllegalStateException;
/**
* Returns if this node is a prefix node
*
* @return true if this node is a prefix node
*/
boolean isPrefix();
@@ -317,9 +360,12 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return the prefix value
* @throws IllegalStateException if this node is a not a prefix node
*/
Map.Entry<Integer, String> getPrefix();
@Nonnull
Map.Entry<Integer, String> getPrefix() throws IllegalStateException;
/**
* Returns if this node is a suffix node
*
* @return true if this node is a suffix node
*/
boolean isSuffix();
@@ -330,7 +376,8 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return the suffix value
* @throws IllegalStateException if this node is a not a suffix node
*/
Map.Entry<Integer, String> getSuffix();
@Nonnull
Map.Entry<Integer, String> getSuffix() throws IllegalStateException;
/**
* Checks if this Node is equal to another node
@@ -339,6 +386,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @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);
/**
@@ -347,7 +395,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @param other the other node
* @return true if the two nodes are almost equal
*/
boolean equalsIgnoringValue(Node other);
boolean equalsIgnoringValue(@Nonnull Node other);
/**
* Similar to {@link Node#equals(Object)}, except doesn't take note of the expiry time or value
@@ -355,7 +403,7 @@ public interface Node extends Map.Entry<String, Boolean> {
* @param other the other node
* @return true if the two nodes are almost equal
*/
boolean almostEquals(Node other);
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
@@ -364,38 +412,51 @@ public interface Node extends Map.Entry<String, Boolean> {
* @return true if the two nodes are almost equal
* @since 2.8
*/
boolean equalsIgnoringValueOrTemp(Node other);
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);
Builder setWorld(String world);
@Nonnull
Builder setWorld(@Nonnull String world);
Builder setServer(String server) throws IllegalArgumentException;
@Nonnull
Builder setServer(@Nonnull String server) throws IllegalArgumentException;
Builder withExtraContext(String key, String value);
@Nonnull
Builder withExtraContext(@Nonnull String key, @Nonnull String value);
Builder withExtraContext(Map<String, String> map);
@Nonnull
Builder withExtraContext(@Nonnull Map<String, String> map);
Builder withExtraContext(Set<Map.Entry<String, String>> context);
@Nonnull
Builder withExtraContext(@Nonnull Set<Map.Entry<String, String>> context);
Builder withExtraContext(Map.Entry<String, String> entry);
@Nonnull
Builder withExtraContext(@Nonnull Map.Entry<String, String> entry);
Builder withExtraContext(ContextSet set);
@Nonnull
Builder withExtraContext(@Nonnull ContextSet set);
@Nonnull
Node 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,6 +25,8 @@
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* Builds {@link Node} instances
*
@@ -36,8 +41,12 @@ public interface NodeFactory {
* @param value the value of the node
* @return a node instance
* @throws NullPointerException if the permission is null
* @deprecated since this format isn't used internally for permissions anymore
* @see Node#toSerializedNode()
*/
Node fromSerialisedNode(String serialisedPermission, boolean value);
@Deprecated
@Nonnull
Node fromSerialisedNode(@Nonnull String serialisedPermission, boolean value);
/**
@@ -47,7 +56,8 @@ public interface NodeFactory {
* @return a node builder instance
* @throws NullPointerException if the permission is null
*/
Node.Builder newBuilder(String permission);
@Nonnull
Node.Builder newBuilder(@Nonnull String permission);
/**
* Creates a node builder instance from an existing node
@@ -56,7 +66,8 @@ public interface NodeFactory {
* @return a node builder instance
* @throws NullPointerException if the other node is null
*/
Node.Builder newBuilderFromExisting(Node other);
@Nonnull
Node.Builder newBuilderFromExisting(@Nonnull Node other);
/**
* Creates a node builder from a serialised node string
@@ -65,8 +76,12 @@ public interface NodeFactory {
* @param value the value of the node
* @return a node builder instance
* @throws NullPointerException if the permission is null
* @deprecated since this format isn't used internally for permissions anymore
* @see Node#toSerializedNode()
*/
Node.Builder newBuilderFromSerialisedNode(String serialisedPermission, boolean value);
@Deprecated
@Nonnull
Node.Builder newBuilderFromSerialisedNode(@Nonnull String serialisedPermission, boolean value);
/**
@@ -78,7 +93,8 @@ public interface NodeFactory {
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @since 3.1
*/
Node.Builder makeGroupNode(Group group);
@Nonnull
Node.Builder makeGroupNode(@Nonnull Group group);
/**
* Creates a node builder from a key value pair
@@ -88,7 +104,20 @@ public interface NodeFactory {
* @return a node builder instance
* @throws NullPointerException if the key or value is null
*/
Node.Builder makeMetaNode(String key, String value);
@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
@@ -98,7 +127,8 @@ public interface NodeFactory {
* @return a node builder instance
* @throws NullPointerException if the prefix is null
*/
Node.Builder makePrefixNode(int priority, String prefix);
@Nonnull
Node.Builder makePrefixNode(int priority, @Nonnull String prefix);
/**
* Creates a node builder from a prefix string and priority
@@ -108,6 +138,7 @@ public interface NodeFactory {
* @return a node builder instance
* @throws NullPointerException if the suffix is null
*/
Node.Builder makeSuffixNode(int priority, String suffix);
@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,12 +25,22 @@
package me.lucko.luckperms.api;
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 me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
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;
import javax.annotation.Nullable;
/**
* An object capable of holding permissions
@@ -44,34 +57,143 @@ public interface PermissionHolder {
*
* @return the identifier for this object. Either a uuid string or name.
*/
@Nonnull
String getObjectName();
/**
* 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();
/**
* 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
*/
@Nonnull
ImmutableSetMultimap<ImmutableContextSet, Node> getNodes();
/**
* 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
*/
@Nonnull
ImmutableSetMultimap<ImmutableContextSet, Node> getTransientNodes();
/**
* 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
*/
@Nonnull
List<Node> getOwnNodes();
/**
* Gets a sorted set of all held permissions.
*
* @return an immutable set of permissions in priority order
* @since 2.6
*/
@Nonnull
SortedSet<? extends Node> getPermissions();
/**
* 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
*/
@Nonnull
Set<? extends Node> getEnduringPermissions();
/**
* Gets an immutable set of all transiently held permissions.
* Similar to {@link #getPermissions()}, except without enduring permissions
*
* <p> Transient permissions only exist for the duration of the session.
* <p>Transient permissions only exist for the duration of the session.</p>
*
* @return a set of nodes
* @since 2.6
*/
@Nonnull
Set<? extends Node> getTransientPermissions();
/**
* Processes the nodes and returns the non-temporary ones.
*
* @return a set of permanent nodes
* @since 2.6
*/
@Nonnull
Set<Node> getPermanentPermissionNodes();
/**
* Processes the nodes and returns the temporary ones.
*
* @return a set of temporary nodes
* @since 2.6
*/
@Nonnull
Set<Node> getTemporaryPermissionNodes();
/**
* 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
*/
@Nonnull
List<LocalizedNode> resolveInheritances(Contexts contexts);
/**
* 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
*/
@Nonnull
List<LocalizedNode> resolveInheritances();
/**
* Gets a mutable sorted set of the nodes that this object has and inherits, filtered by context
*
@@ -80,12 +202,27 @@ public interface PermissionHolder {
*
* <p>Nodes are sorted into priority order.</p>
*
* @param contexts the context for the lookup,
* @param contexts the context for the lookup
* @return a mutable sorted set of permissions
* @throws NullPointerException if the context is null
* @since 2.11
*/
SortedSet<LocalizedNode> getAllNodes(Contexts contexts);
@Nonnull
SortedSet<LocalizedNode> getAllNodes(@Nonnull Contexts contexts);
/**
* 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
*/
@Nonnull
SortedSet<LocalizedNode> getAllNodes();
/**
* Gets a mutable set of the nodes that this object has and inherits, filtered by context.
@@ -98,7 +235,8 @@ public interface PermissionHolder {
* @throws NullPointerException if the context is null
* @since 2.11
*/
Set<LocalizedNode> getAllNodesFiltered(Contexts contexts);
@Nonnull
Set<LocalizedNode> getAllNodesFiltered(@Nonnull Contexts contexts);
/**
* Converts the output of {@link #getAllNodesFiltered(Contexts)}, and expands shorthand permissions.
@@ -107,7 +245,8 @@ public interface PermissionHolder {
* @param lowerCase if the keys should be made lowercase whilst being exported
* @return a mutable map of permissions
*/
Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase);
@Nonnull
Map<String, Boolean> exportNodes(@Nonnull Contexts contexts, boolean lowerCase);
/**
* Removes temporary permissions that have expired
@@ -122,7 +261,8 @@ public interface PermissionHolder {
* @throws NullPointerException if the node is null
* @since 2.6
*/
Tristate hasPermission(Node node);
@Nonnull
Tristate hasPermission(@Nonnull Node node);
/**
* Checks to see if the object has a certain permission
@@ -132,7 +272,187 @@ public interface PermissionHolder {
* @throws NullPointerException if the node is null
* @since 2.6
*/
Tristate hasTransientPermission(Node node);
@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
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null
* @since 2.6
*/
void setPermission(@Nonnull Node node) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
*
* @param node The node to be set
* @throws NullPointerException if the node is null
* @return the result of the operation
* @since 3.1
*/
@Nonnull
DataMutateResult setPermissionUnchecked(@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
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null
* @since 2.6
*/
void setTransientPermission(@Nonnull Node node) throws ObjectAlreadyHasException;
/**
* 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
* @throws NullPointerException if the node is null
* @return the result of the operation
* @since 3.1
*/
@Nonnull
DataMutateResult setTransientPermissionUnchecked(@Nonnull Node node);
/**
* Unsets a permission for the object
*
* @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null
* @since 2.6
*/
void unsetPermission(@Nonnull Node node) throws ObjectLacksException;
/**
* 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
*/
@Nonnull
DataMutateResult unsetPermissionUnchecked(@Nonnull Node node);
/**
* Unsets a transient permission for the object
*
* @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null
* @since 2.6
*/
void unsetTransientPermission(@Nonnull Node node) throws ObjectLacksException;
/**
* 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
*/
@Nonnull
DataMutateResult unsetTransientPermissionUnchecked(@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();
/**
* Checks to see if the object has a certain permission
@@ -142,8 +462,10 @@ public interface PermissionHolder {
* @return true if the object has the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean hasPermission(String node, boolean b);
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b);
/**
* Checks to see the the object has a permission on a certain server
@@ -154,8 +476,10 @@ public interface PermissionHolder {
* @return true if the object has the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean hasPermission(String node, boolean b, String server);
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server);
/**
* Checks to see the the object has a permission on a certain server and world
@@ -167,8 +491,10 @@ public interface PermissionHolder {
* @return true if the object has the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean hasPermission(String node, boolean b, String server, String world);
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world);
/**
* Checks to see the the object has a permission
@@ -179,8 +505,10 @@ public interface PermissionHolder {
* @return true if the object has the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean hasPermission(String node, boolean b, boolean temporary);
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, boolean temporary);
/**
* Checks to see the the object has a permission on a certain server
@@ -192,8 +520,10 @@ public interface PermissionHolder {
* @return true if the object has the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean hasPermission(String node, boolean b, String server, boolean temporary);
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server, boolean temporary);
/**
* Checks to see the the object has a permission on a certain server and world
@@ -206,18 +536,10 @@ public interface PermissionHolder {
* @return true if the object has the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean hasPermission(String node, boolean b, String server, String world, boolean temporary);
/**
* 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
*/
Tristate inheritsPermission(Node node);
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world, boolean temporary);
/**
* Checks to see if the object inherits a certain permission
@@ -227,8 +549,10 @@ public interface PermissionHolder {
* @return true if the object inherits the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean inheritsPermission(String node, boolean b);
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b);
/**
* Checks to see the the object inherits a permission on a certain server
@@ -239,8 +563,10 @@ public interface PermissionHolder {
* @return true if the object inherits the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean inheritsPermission(String node, boolean b, String server);
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server);
/**
* Checks to see the the object inherits a permission on a certain server and world
@@ -252,8 +578,10 @@ public interface PermissionHolder {
* @return true if the object inherits the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node server or world is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean inheritsPermission(String node, boolean b, String server, String world);
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world);
/**
* Checks to see if the object inherits a permission
@@ -264,8 +592,10 @@ public interface PermissionHolder {
* @return true if the object inherits the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean inheritsPermission(String node, boolean b, boolean temporary);
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, boolean temporary);
/**
* Checks to see if the object inherits a permission on a certain server
@@ -277,8 +607,10 @@ public interface PermissionHolder {
* @return true if the object inherits the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean inheritsPermission(String node, boolean b, String server, boolean temporary);
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server, boolean temporary);
/**
* Checks to see if the object inherits a permission on a certain server and world
@@ -291,66 +623,10 @@ public interface PermissionHolder {
* @return true if the object inherits the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world if invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
/**
* Sets a permission for the object
*
* @param node The node to be set
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null
* @since 2.6
*/
void setPermission(Node node) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
*
* @param node The node to be set
* @throws NullPointerException if the node is null
* @return the result of the operation
* @since 3.1
*/
DataMutateResult setPermissionUnchecked(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
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null
* @since 2.6
*/
void setTransientPermission(Node node) throws ObjectAlreadyHasException;
/**
* 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
* @throws NullPointerException if the node is null
* @return the result of the operation
* @since 3.1
*/
DataMutateResult setTransientPermissionUnchecked(Node node);
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world, boolean temporary);
/**
* Sets a permission for the object
@@ -363,7 +639,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(String node, boolean value) throws ObjectAlreadyHasException;
void setPermission(@Nonnull String node, boolean value) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object on a specific server
@@ -377,7 +653,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(String node, boolean value, String server) throws ObjectAlreadyHasException;
void setPermission(@Nonnull String node, boolean value, @Nonnull String server) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object on a specific server and world
@@ -392,7 +668,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(String node, boolean value, String server, String world) throws ObjectAlreadyHasException;
void setPermission(@Nonnull String node, boolean value, @Nonnull String server, @Nonnull String world) throws ObjectAlreadyHasException;
/**
* Sets a temporary permission for the object
@@ -406,7 +682,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(String node, boolean value, long expireAt) throws ObjectAlreadyHasException;
void setPermission(@Nonnull String node, boolean value, long expireAt) throws ObjectAlreadyHasException;
/**
* Sets a temporary permission for the object on a specific server
@@ -421,7 +697,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(String node, boolean value, String server, long expireAt) throws ObjectAlreadyHasException;
void setPermission(@Nonnull String node, boolean value, @Nonnull String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Sets a temporary permission for the object on a specific server and world
@@ -437,47 +713,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
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
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null
* @since 2.6
*/
void unsetPermission(Node node) throws ObjectLacksException;
/**
* 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
*/
DataMutateResult unsetPermissionUnchecked(Node node);
/**
* Unsets a transient permission for the object
*
* @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null
* @since 2.6
*/
void unsetTransientPermission(Node node) throws ObjectLacksException;
/**
* 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
*/
DataMutateResult unsetTransientPermissionUnchecked(Node node);
void setPermission(String node, boolean value, @Nonnull String server, @Nonnull String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Unsets a permission for the object
@@ -490,7 +726,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(String node, boolean temporary) throws ObjectLacksException;
void unsetPermission(@Nonnull String node, boolean temporary) throws ObjectLacksException;
/**
* Unsets a permission for the object
@@ -502,7 +738,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(String node) throws ObjectLacksException;
void unsetPermission(@Nonnull String node) throws ObjectLacksException;
/**
* Unsets a permission for the object on a specific server
@@ -515,7 +751,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(String node, String server) throws ObjectLacksException;
void unsetPermission(@Nonnull String node, @Nonnull String server) throws ObjectLacksException;
/**
* Unsets a permission for the object on a specific server and world
@@ -529,7 +765,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(String node, String server, String world) throws ObjectLacksException;
void unsetPermission(@Nonnull String node, @Nonnull String server, @Nonnull String world) throws ObjectLacksException;
/**
* Unsets a permission for the object on a specific server
@@ -543,7 +779,7 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(String node, String server, boolean temporary) throws ObjectLacksException;
void unsetPermission(@Nonnull String node, @Nonnull String server, boolean temporary) throws ObjectLacksException;
/**
* Unsets a permission for the object on a specific server and world
@@ -558,22 +794,17 @@ public interface PermissionHolder {
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(String node, String server, String world, boolean temporary) throws ObjectLacksException;
/**
* Clears all nodes held by the object
*
* @since 2.17
*/
void clearNodes();
void unsetPermission(@Nonnull String node, @Nonnull String server, @Nonnull String world, boolean temporary) throws ObjectLacksException;
/**
* Clears all nodes held by the object on a specific server
*
* @param server the server to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearNodes(ContextSet)}
*/
void clearNodes(String server);
@Deprecated
void clearNodes(@Nullable String server);
/**
* Clears all nodes held by the object on a specific server and world
@@ -581,23 +812,20 @@ public interface PermissionHolder {
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearNodes(ContextSet)}
*/
void clearNodes(String server, String world);
/**
* Clears all parent groups
*
* @since 2.17
*/
void clearParents();
@Deprecated
void clearNodes(@Nullable String server, @Nullable String world);
/**
* Clears all parents on a specific server
*
* @param server the server to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearParents(ContextSet)}
*/
void clearParents(String server);
@Deprecated
void clearParents(@Nullable String server);
/**
* Clears all parents on a specific server and world
@@ -605,23 +833,20 @@ public interface PermissionHolder {
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearParents(ContextSet)}
*/
void clearParents(String server, String world);
/**
* Clears all meta held by the object
*
* @since 2.17
*/
void clearMeta();
@Deprecated
void clearParents(@Nullable String server, @Nullable String world);
/**
* Clears all meta held by the object on a specific server
*
* @param server the server to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearMeta(ContextSet)}
*/
void clearMeta(String server);
@Deprecated
void clearMeta(@Nullable String server);
/**
* Clears all meta held by the object on a specific server and world
@@ -629,8 +854,10 @@ public interface PermissionHolder {
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearMeta(ContextSet)}
*/
void clearMeta(String server, String world);
@Deprecated
void clearMeta(@Nullable String server, @Nullable String world);
/**
* Clears all meta for a given key.
@@ -639,28 +866,9 @@ public interface PermissionHolder {
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @param temporary whether the query is for temporary nodes or not.
* @deprecated in favour of {@link #clearMatching(Predicate)}
*/
void clearMetaKeys(String key, String server, String world, boolean temporary);
/**
* Clears all transient permissions the holder has.
*/
void clearTransientNodes();
/**
* Processes the nodes and returns the non-temporary ones.
*
* @return a set of permanent nodes
* @since 2.6
*/
Set<Node> getPermanentPermissionNodes();
/**
* Processes the nodes and returns the temporary ones.
*
* @return a set of temporary nodes
* @since 2.6
*/
Set<Node> getTemporaryPermissionNodes();
@Deprecated
void clearMetaKeys(@Nonnull String key, @Nullable String server, @Nullable String world, boolean temporary);
}
@@ -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,6 +25,8 @@
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* The platforms which LuckPerms can run on
*
@@ -39,6 +44,7 @@ public enum PlatformType {
this.friendlyName = friendlyName;
}
@Nonnull
public String getFriendlyName() {
return friendlyName;
}
@@ -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
@@ -29,6 +32,9 @@ 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 data to/from the Storage provider.
*
@@ -49,6 +55,7 @@ public interface Storage {
*
* @return the name of the implementation
*/
@Nonnull
String getName();
/**
@@ -63,6 +70,7 @@ public interface Storage {
*
* @return an executor instance
*/
@Nonnull
Executor getSyncExecutor();
/**
@@ -71,6 +79,7 @@ public interface Storage {
*
* @return an executor instance
*/
@Nonnull
Executor getAsyncExecutor();
/**
@@ -80,25 +89,39 @@ public interface Storage {
* @return true if the operation completed successfully.
* @throws NullPointerException if entry is null
*/
CompletableFuture<Boolean> logAction(LogEntry entry);
@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. (if you want to specify <code>null</code> here, just input "null" as a
* string.)
* @param username the users username, or null if it is not known.
* @return if the operation completed successfully
* @throws NullPointerException if uuid or username is null
* @throws NullPointerException if uuid is null
*/
CompletableFuture<Boolean> loadUser(UUID uuid, String username);
@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.
@@ -108,13 +131,15 @@ public interface Storage {
* @throws NullPointerException if user is null
* @throws IllegalStateException if the user instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> saveUser(User user);
@Nonnull
CompletableFuture<Boolean> saveUser(@Nonnull User user);
/**
* Removes users from the main storage who are "default". This is called every time the plugin loads.
*
* @return true if the operation completed successfully
*/
@Nonnull
CompletableFuture<Boolean> cleanupUsers();
/**
@@ -123,6 +148,7 @@ public interface Storage {
*
* @return a set of uuids, or null if the operation failed.
*/
@Nonnull
CompletableFuture<Set<UUID>> getUniqueUsers();
/**
@@ -133,7 +159,8 @@ public interface Storage {
* @throws NullPointerException if the permission is null
* @since 2.17
*/
CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(String permission);
@Nonnull
CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(@Nonnull String permission);
/**
* Creates and loads a group into the plugins local storage
@@ -143,7 +170,8 @@ public interface Storage {
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> createAndLoadGroup(String name);
@Nonnull
CompletableFuture<Boolean> createAndLoadGroup(@Nonnull String name);
/**
* Loads a group into the plugins local storage.
@@ -153,13 +181,15 @@ public interface Storage {
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> loadGroup(String name);
@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();
/**
@@ -170,7 +200,8 @@ public interface Storage {
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> saveGroup(Group group);
@Nonnull
CompletableFuture<Boolean> saveGroup(@Nonnull Group group);
/**
* Permanently deletes a group from storage.
@@ -180,7 +211,8 @@ public interface Storage {
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> deleteGroup(Group group);
@Nonnull
CompletableFuture<Boolean> deleteGroup(@Nonnull Group group);
/**
* Searches for a list of groups with a given permission.
@@ -190,7 +222,8 @@ public interface Storage {
* @throws NullPointerException if the permission is null
* @since 2.17
*/
CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(String permission);
@Nonnull
CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(@Nonnull String permission);
/**
* Creates and loads a track into the plugins local storage
@@ -200,7 +233,8 @@ public interface Storage {
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> createAndLoadTrack(String name);
@Nonnull
CompletableFuture<Boolean> createAndLoadTrack(@Nonnull String name);
/**
* Loads a track into the plugins local storage.
@@ -210,13 +244,15 @@ public interface Storage {
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> loadTrack(String name);
@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();
/**
@@ -227,7 +263,8 @@ public interface Storage {
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> saveTrack(Track track);
@Nonnull
CompletableFuture<Boolean> saveTrack(@Nonnull Track track);
/**
* Permanently deletes a track from storage
@@ -237,7 +274,8 @@ public interface Storage {
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> deleteTrack(Track track);
@Nonnull
CompletableFuture<Boolean> deleteTrack(@Nonnull Track track);
/**
* Saves UUID caching data to the global cache
@@ -248,7 +286,8 @@ public interface Storage {
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid);
@Nonnull
CompletableFuture<Boolean> saveUUIDData(@Nonnull String username, @Nonnull UUID uuid);
/**
* Gets a UUID from a username
@@ -258,7 +297,8 @@ public interface Storage {
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
CompletableFuture<UUID> getUUID(String username);
@Nonnull
CompletableFuture<UUID> getUUID(@Nonnull String username);
/**
* Gets a username from a UUID
@@ -268,6 +308,7 @@ public interface Storage {
* @throws NullPointerException if either parameters are null
* @since 2.17
*/
CompletableFuture<String> getName(UUID uuid);
@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
@@ -27,6 +30,9 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* An ordered collection of groups for easy promotions and demotions
*/
@@ -36,6 +42,7 @@ public interface Track {
* Gets the name of this track
* @return the name of this track
*/
@Nonnull
String getName();
/**
@@ -45,6 +52,7 @@ public interface Track {
*
* @return an ordered {@link List} of the groups on this track
*/
@Nonnull
List<String> getGroups();
/**
@@ -63,7 +71,8 @@ public interface Track {
* @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) throws ObjectLacksException;
/**
* Gets the previous group on the track, before the one provided
@@ -74,7 +83,8 @@ public interface Track {
* @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) throws ObjectLacksException;
/**
* Appends a group to the end of this track
@@ -84,7 +94,7 @@ public interface Track {
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
void appendGroup(Group group) throws ObjectAlreadyHasException;
void appendGroup(@Nonnull Group group) throws ObjectAlreadyHasException;
/**
* Inserts a group at a certain position on this track
@@ -96,7 +106,7 @@ public interface 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;
void insertGroup(@Nonnull Group group, int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException;
/**
* Removes a group from this track
@@ -106,7 +116,7 @@ public interface Track {
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
void removeGroup(Group group) throws ObjectLacksException;
void removeGroup(@Nonnull Group group) throws ObjectLacksException;
/**
* Removes a group from this track
@@ -115,7 +125,7 @@ public interface Track {
* @throws ObjectLacksException if the group is not on this track
* @throws NullPointerException if the group is null
*/
void removeGroup(String group) throws ObjectLacksException;
void removeGroup(@Nonnull String group) throws ObjectLacksException;
/**
* Checks if a group features on this track
@@ -125,7 +135,7 @@ public interface 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
@@ -134,7 +144,7 @@ public interface Track {
* @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 from this track
@@ -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,11 +25,13 @@
package me.lucko.luckperms.api;
import javax.annotation.Nonnull;
/**
* Represents a permission setting.
*
* <p>Consider a value of {@link #FALSE} to be a "negated" setting, and a value of {@link #UNDEFINED} to be a
* non-existent value.</p>
* <p>Consider a value of {@link #TRUE} to be a positive setting, {@link #FALSE} to be a "negated" setting,
* and a value of {@link #UNDEFINED} to be a non-existent value.</p>
*/
public enum Tristate {
@@ -51,6 +56,7 @@ public enum Tristate {
* @param b the boolean
* @return {@link #TRUE} or {@link #FALSE}, depending on the value of the boolean.
*/
@Nonnull
public static Tristate fromBoolean(boolean b) {
return b ? TRUE : FALSE;
}
@@ -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
@@ -23,6 +26,7 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
@@ -30,6 +34,9 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A player holding permission data
*/
@@ -40,64 +47,97 @@ public interface User extends PermissionHolder {
*
* @return the users Mojang assigned unique id
*/
@Nonnull
UUID getUuid();
/**
* Gets the users username
* Gets the users username, or null if no username is associated with this user
*
* @return the Users Username
* @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
* Sets a users primary group. This will only take effect if platform is using stored primary groups.
*
* @param group the new primary group
* @throws ObjectAlreadyHasException if the user already has this set as their primary group
* @throws IllegalStateException if the user is not a member of that group
* @throws NullPointerException if the group is null
*/
void setPrimaryGroup(String group) throws ObjectAlreadyHasException;
void setPrimaryGroup(@Nonnull String group) throws ObjectAlreadyHasException;
/**
* Refresh and re-assign the users permissions.
*
* <p>This request is not buffered, and the refresh call will be ran directly. This should ideally be called on
* an asynchronous thread.</p>
* <p>This request is not buffered, and the refresh call will be ran directly. This should be called on an
* asynchronous thread.</p>
*/
void refreshPermissions();
/**
* Gets the user's {@link UserData} cache.
*
* @return the users cached data.
* @since 3.2
*/
@Nonnull
UserData getCachedData();
/**
* 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);
/**
* Gets the user's {@link UserData} cache, if they have one setup.
*
* @return an optional, possibly containing the user's cached lookup data.
* @since 2.13
* @deprecated in version 3.2, as this cache is now always loaded
*/
@Deprecated
@Nonnull
Optional<UserData> getUserDataCache();
/**
* Sets up the users data cache, if the don't have one setup already.
* 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
*/
void setupDataCache();
/**
* 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
* @throws NullPointerException if the group is null
*/
boolean isInGroup(Group group);
/**
* Check to see if a user is a member of a group on a specific server
*
@@ -106,8 +146,10 @@ public interface User extends PermissionHolder {
* @return true if the user is a member of the group
* @throws NullPointerException if the group or server is null
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of {@link #isInGroup(Group, ContextSet)}
*/
boolean isInGroup(Group group, String server);
@Deprecated
boolean isInGroup(@Nonnull Group group, @Nonnull String server);
/**
* Check to see if a user is a member of a group on a specific server and world
@@ -118,8 +160,10 @@ public interface User extends PermissionHolder {
* @return true if the user is a member of the group
* @throws NullPointerException if the group, server or world is null
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link #isInGroup(Group, ContextSet)}
*/
boolean isInGroup(Group group, String server, String world);
@Deprecated
boolean isInGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world);
/**
* Add a user to a group
@@ -131,7 +175,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(Group group) throws ObjectAlreadyHasException;
void addGroup(@Nonnull Group group) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
@@ -145,7 +189,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(Group group, String server) throws ObjectAlreadyHasException;
void addGroup(@Nonnull Group group, @Nonnull String server) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server and world
@@ -160,7 +204,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
void addGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectAlreadyHasException;
/**
* Add a user to a group temporarily on a specific server
@@ -174,7 +218,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
void addGroup(@Nonnull Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group temporarily on a specific server
@@ -189,7 +233,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
void addGroup(@Nonnull Group group, @Nonnull String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group temporarily on a specific server and world
@@ -205,7 +249,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
void addGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove the user from a group
@@ -217,7 +261,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(Group group) throws ObjectLacksException;
void removeGroup(@Nonnull Group group) throws ObjectLacksException;
/**
* Remove the user from a group
@@ -230,7 +274,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(Group group, boolean temporary) throws ObjectLacksException;
void removeGroup(@Nonnull Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server
@@ -244,7 +288,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(Group group, String server) throws ObjectLacksException;
void removeGroup(@Nonnull Group group, @Nonnull String server) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server and world
@@ -259,7 +303,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(Group group, String server, String world) throws ObjectLacksException;
void removeGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server
@@ -274,7 +318,7 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
void removeGroup(@Nonnull Group group, @Nonnull String server, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server and world
@@ -290,13 +334,16 @@ public interface User extends PermissionHolder {
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
void removeGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, boolean temporary) throws ObjectLacksException;
/**
* 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
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getGroupNames();
/**
@@ -307,8 +354,11 @@ public interface User extends PermissionHolder {
* @return a {@link List} of group names
* @throws NullPointerException if the server or world is null
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of just querying a users permissions
*/
List<String> getLocalGroups(String server, String world);
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server, @Nonnull String world);
/**
* Get a {@link List} of the groups the user is a member of on a specific server
@@ -317,7 +367,10 @@ public interface User extends PermissionHolder {
* @return a {@link List} of group names
* @throws NullPointerException if the server is null
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of just querying a users permissions
*/
List<String> getLocalGroups(String server);
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server);
}
@@ -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,16 +27,18 @@ package me.lucko.luckperms.api;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* A UUID cache for online users, between external Mojang UUIDs, and internal LuckPerms UUIDs.
*
* <p>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 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.
* instead check the datastore cache, to get a UUID for a user that is consistent across an entire network.</p>
*
* <p>If you want to get a user object from the Storage using the api on a server in offline mode, you will need to use
* this cache, OR use Storage#getUUID, for users that are not online.
* this cache, OR use Storage#getUUID, for users that are not online.</p>
*
* <p><strong>This is only effective for online players. Use {@link Storage#getUUID(String)} for offline players.</strong></p>
*/
@@ -45,7 +50,8 @@ public interface UuidCache {
* @param external the UUID assigned by the server, through Player#getUniqueId or ProxiedPlayer#getUniqueId
* @return the corresponding internal UUID
*/
UUID getUUID(UUID external);
@Nonnull
UUID getUUID(@Nonnull UUID external);
/**
* Gets a users external, server assigned or Mojang assigned unique id, from the internal one used within LuckPerms.
@@ -53,6 +59,7 @@ public interface UuidCache {
* @param internal the UUID used within LuckPerms, through User#getUuid
* @return the corresponding external UUID
*/
UUID getExternalUUID(UUID internal);
@Nonnull
UUID getExternalUUID(@Nonnull UUID internal);
}
@@ -0,0 +1,116 @@
/*
* 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, consisting of a standard {@link Contexts} element, plus options to define how
* the meta stack should be constructed.
*
* @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;
/**
* 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");
}
@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());
}
@Override
public int hashCode() {
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;
}
}
@@ -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,9 +25,16 @@
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
*
@@ -33,10 +43,29 @@ import java.util.SortedMap;
public interface MetaData {
/**
* Gets an immutable copy of the meta this user has
* 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();
/**
@@ -45,6 +74,7 @@ public interface MetaData {
*
* @return a sorted map of prefixes
*/
@Nonnull
SortedMap<Integer, String> getPrefixes();
/**
@@ -53,6 +83,7 @@ public interface MetaData {
*
* @return a sorted map of suffixes
*/
@Nonnull
SortedMap<Integer, String> getSuffixes();
/**
@@ -60,6 +91,7 @@ public interface MetaData {
*
* @return a prefix string, or null
*/
@Nullable
String getPrefix();
/**
@@ -67,6 +99,25 @@ public interface MetaData {
*
* @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();
}
@@ -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
@@ -26,6 +29,8 @@ 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
*
@@ -40,7 +45,8 @@ public interface PermissionData {
* @return a tristate result
* @throws NullPointerException if permission is null
*/
Tristate getPermissionValue(String permission);
@Nonnull
Tristate getPermissionValue(@Nonnull String permission);
/**
* Invalidates the underlying permission calculator cache.
@@ -54,6 +60,7 @@ public interface PermissionData {
*
* @return an immutable set of permissions
*/
@Nonnull
Map<String, Boolean> getImmutableBacking();
}
@@ -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
@@ -26,12 +29,18 @@ 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 {
@@ -45,7 +54,21 @@ public interface UserData {
* @return a permission data instance
* @throws NullPointerException if contexts is null
*/
PermissionData getPermissionData(Contexts contexts);
@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.
@@ -56,7 +79,8 @@ public interface UserData {
* @return a meta data instance
* @throws NullPointerException if contexts is null
*/
MetaData getMetaData(Contexts contexts);
@Nonnull
MetaData getMetaData(@Nonnull Contexts contexts);
/**
* Calculates permission data, bypassing the cache.
@@ -65,7 +89,19 @@ public interface UserData {
* @return a permission data instance
* @throws NullPointerException if contexts is null
*/
PermissionData calculatePermissions(Contexts contexts);
@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.
@@ -74,7 +110,8 @@ public interface UserData {
* @return a meta data instance
* @throws NullPointerException if contexts is null
*/
MetaData calculateMeta(Contexts contexts);
@Nonnull
MetaData calculateMeta(@Nonnull Contexts contexts);
/**
* Calculates permission data and stores it in the cache.
@@ -85,7 +122,19 @@ public interface UserData {
* @param contexts the contexts to recalculate in.
* @throws NullPointerException if contexts is null
*/
void recalculatePermissions(Contexts contexts);
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.
@@ -96,7 +145,7 @@ public interface UserData {
* @param contexts the contexts to recalculate in.
* @throws NullPointerException if contexts is null
*/
void recalculateMeta(Contexts contexts);
void recalculateMeta(@Nonnull Contexts contexts);
/**
* Calls {@link #recalculatePermissions(Contexts)} for all current loaded contexts
@@ -114,7 +163,7 @@ public interface UserData {
* @param contexts a set of contexts
* @throws NullPointerException if contexts is null
*/
void preCalculate(Set<Contexts> contexts);
void preCalculate(@Nonnull Set<Contexts> contexts);
/**
* Ensures that PermissionData and MetaData is cached for a context.
@@ -124,7 +173,7 @@ public interface UserData {
* @param contexts the contexts to pre-calculate for
* @throws NullPointerException if contexts is null
*/
void preCalculate(Contexts contexts);
void preCalculate(@Nonnull Contexts contexts);
/**
* Invalidates all of the underlying Permission calculators.
@@ -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,6 +25,8 @@
package me.lucko.luckperms.api.context;
import javax.annotation.Nonnull;
/**
* Calculates whether contexts are applicable to {@link T}
*
@@ -38,6 +43,7 @@ public interface ContextCalculator<T> {
* @return the map
* @since 2.13
*/
MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator);
@Nonnull
MutableContextSet giveApplicableContext(@Nonnull T subject, @Nonnull MutableContextSet accumulator);
}
@@ -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,12 +25,15 @@
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;
/**
* Holder of contexts.
*
@@ -45,7 +51,8 @@ public interface ContextSet {
* @return a new ImmutableContextSet containing one KV pair
* @throws NullPointerException if key or value is null
*/
static ImmutableContextSet singleton(String key, String value) {
@Nonnull
static ImmutableContextSet singleton(@Nonnull String key, @Nonnull String value) {
return ImmutableContextSet.singleton(key, value);
}
@@ -60,7 +67,8 @@ public interface ContextSet {
* @throws NullPointerException if any of the keys or values are null
* @since 3.1
*/
static ImmutableContextSet of(String key1, String value1, String key2, String value2) {
@Nonnull
static ImmutableContextSet of(@Nonnull String key1, @Nonnull String value1, @Nonnull String key2, @Nonnull String value2) {
return ImmutableContextSet.of(key1, value1, key2, value2);
}
@@ -71,7 +79,8 @@ public interface ContextSet {
* @return a new ImmutableContextSet representing the pairs from the map
* @throws NullPointerException if the map is null
*/
static ImmutableContextSet fromMap(Map<String, String> map) {
@Nonnull
static ImmutableContextSet fromMap(@Nonnull Map<String, String> map) {
return ImmutableContextSet.fromMap(map);
}
@@ -82,7 +91,8 @@ public interface ContextSet {
* @return a new ImmutableContextSet representing the pairs in the iterable
* @throws NullPointerException if the iterable is null
*/
static ImmutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
@Nonnull
static ImmutableContextSet fromEntries(@Nonnull Iterable<? extends Map.Entry<String, String>> iterable) {
return ImmutableContextSet.fromEntries(iterable);
}
@@ -94,7 +104,8 @@ public interface ContextSet {
* @throws NullPointerException if the multimap is null
* @since 2.16
*/
static ImmutableContextSet fromMultimap(Multimap<String, String> multimap) {
@Nonnull
static ImmutableContextSet fromMultimap(@Nonnull Multimap<String, String> multimap) {
return ImmutableContextSet.fromMultimap(multimap);
}
@@ -106,7 +117,8 @@ public interface ContextSet {
* @return a new ImmutableContextSet with the same content and the one provided
* @throws NullPointerException if contextSet is null
*/
static ImmutableContextSet fromSet(ContextSet contextSet) {
@Nonnull
static ImmutableContextSet fromSet(@Nonnull ContextSet contextSet) {
return ImmutableContextSet.fromSet(contextSet);
}
@@ -115,6 +127,7 @@ public interface ContextSet {
*
* @return a new ImmutableContextSet
*/
@Nonnull
static ImmutableContextSet empty() {
return ImmutableContextSet.empty();
}
@@ -131,6 +144,7 @@ public interface ContextSet {
*
* @return an immutable ContextSet
*/
@Nonnull
ImmutableContextSet makeImmutable();
/**
@@ -139,6 +153,7 @@ public interface ContextSet {
* @return a mutable ContextSet
* @since 2.16
*/
@Nonnull
MutableContextSet mutableCopy();
/**
@@ -146,6 +161,7 @@ public interface ContextSet {
*
* @return an immutable set
*/
@Nonnull
Set<Map.Entry<String, String>> toSet();
/**
@@ -156,6 +172,7 @@ public interface ContextSet {
*
* @return an immutable map
*/
@Nonnull
Map<String, String> toMap();
/**
@@ -164,6 +181,7 @@ public interface ContextSet {
* @return a multimap
* @since 2.16
*/
@Nonnull
Multimap<String, String> toMultimap();
/**
@@ -173,7 +191,7 @@ public interface ContextSet {
* @return true if the set contains a value for the key
* @throws NullPointerException if the key is null
*/
boolean containsKey(String key);
boolean containsKey(@Nonnull String key);
/**
* Gets a set of all of the values mapped to the given key
@@ -182,7 +200,8 @@ public interface ContextSet {
* @return a set of values
* @throws NullPointerException if the key is null
*/
Set<String> getValues(String key);
@Nonnull
Set<String> getValues(@Nonnull String key);
/**
* Returns any value from this set matching the key, if present.
@@ -191,7 +210,8 @@ public interface ContextSet {
* @return an optional containing any match
* @since 3.1
*/
default Optional<String> getAnyValue(String key) {
@Nonnull
default Optional<String> getAnyValue(@Nonnull String key) {
return getValues(key).stream().findAny();
}
@@ -203,7 +223,7 @@ public interface ContextSet {
* @return true if the set contains the KV pair
* @throws NullPointerException if the key or value is null
*/
boolean has(String key, String value);
boolean has(@Nonnull String key, @Nonnull String value);
/**
* Same as {@link #has(String, String)}, except ignores the case of the value.
@@ -213,7 +233,7 @@ public interface ContextSet {
* @return true if the set contains the KV pair
* @throws NullPointerException if the key or value is null
*/
boolean hasIgnoreCase(String key, String value);
boolean hasIgnoreCase(@Nonnull String key, @Nonnull String value);
/**
* Checks to see if all entries in this context set are also included in another set.
@@ -222,7 +242,8 @@ public interface ContextSet {
* @return true if all entries in this set are also in the other set
* @since 3.1
*/
default boolean isSatisfiedBy(ContextSet other) {
default boolean isSatisfiedBy(@Nonnull ContextSet other) {
Preconditions.checkNotNull(other, "other");
if (this.isEmpty()) {
// this is empty, so is therefore always satisfied.
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
@@ -22,6 +25,7 @@
package me.lucko.luckperms.api.context;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
@@ -32,6 +36,8 @@ import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* An immutable implementation of {@link ContextSet}.
*
@@ -48,14 +54,10 @@ public final class ImmutableContextSet implements ContextSet {
* @return a new ImmutableContextSet containing one KV pair
* @throws NullPointerException if key or value is null
*/
public static ImmutableContextSet singleton(String key, String value) {
if (key == null) {
throw new NullPointerException("key");
}
if (value == null) {
throw new NullPointerException("value");
}
@Nonnull
public static ImmutableContextSet singleton(@Nonnull String key, @Nonnull String value) {
Preconditions.checkNotNull(key, "key");
Preconditions.checkNotNull(value, "value");
return new ImmutableContextSet(ImmutableSetMultimap.of(key.toLowerCase(), value));
}
@@ -70,20 +72,12 @@ public final class ImmutableContextSet implements ContextSet {
* @throws NullPointerException if any of the keys or values are null
* @since 3.1
*/
public static ImmutableContextSet of(String key1, String value1, String key2, String value2) {
if (key1 == null) {
throw new NullPointerException("key1");
}
if (value1 == null) {
throw new NullPointerException("value1");
}
if (key2 == null) {
throw new NullPointerException("key2");
}
if (value2 == null) {
throw new NullPointerException("value2");
}
@Nonnull
public static ImmutableContextSet of(@Nonnull String key1, @Nonnull String value1, @Nonnull String key2, @Nonnull String value2) {
Preconditions.checkNotNull(key1, "key1");
Preconditions.checkNotNull(value1, "value1");
Preconditions.checkNotNull(key2, "key2");
Preconditions.checkNotNull(value2, "value2");
return new ImmutableContextSet(ImmutableSetMultimap.of(key1.toLowerCase(), value1, key2.toLowerCase(), value2));
}
@@ -94,10 +88,9 @@ public final class ImmutableContextSet implements ContextSet {
* @return a new ImmutableContextSet representing the pairs from the map
* @throws NullPointerException if the map is null
*/
public static ImmutableContextSet fromMap(Map<String, String> map) {
if (map == null) {
throw new NullPointerException("map");
}
@Nonnull
public static ImmutableContextSet fromMap(@Nonnull Map<String, String> map) {
Preconditions.checkNotNull(map, "map");
ImmutableSetMultimap.Builder<String, String> b = ImmutableSetMultimap.builder();
for (Map.Entry<String, String> e : map.entrySet()) {
@@ -114,11 +107,9 @@ public final class ImmutableContextSet implements ContextSet {
* @return a new ImmutableContextSet representing the pairs in the iterable
* @throws NullPointerException if the iterable is null
*/
public static ImmutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
if (iterable == null) {
throw new NullPointerException("iterable");
}
@Nonnull
public static ImmutableContextSet fromEntries(@Nonnull Iterable<? extends Map.Entry<String, String>> iterable) {
Preconditions.checkNotNull(iterable, "iterable");
return MutableContextSet.fromEntries(iterable).makeImmutable();
}
@@ -129,11 +120,9 @@ public final class ImmutableContextSet implements ContextSet {
* @return a new ImmutableContextSet representing the pairs in the multimap
* @throws NullPointerException if the multimap is null
*/
public static ImmutableContextSet fromMultimap(Multimap<String, String> multimap) {
if (multimap == null) {
throw new NullPointerException("multimap");
}
@Nonnull
public static ImmutableContextSet fromMultimap(@Nonnull Multimap<String, String> multimap) {
Preconditions.checkNotNull(multimap, "multimap");
return MutableContextSet.fromMultimap(multimap).makeImmutable();
}
@@ -145,8 +134,9 @@ public final class ImmutableContextSet implements ContextSet {
* @return a new ImmutableContextSet with the same content and the one provided
* @throws NullPointerException if contextSet is null
*/
public static ImmutableContextSet fromSet(ContextSet contextSet) {
return contextSet.makeImmutable();
@Nonnull
public static ImmutableContextSet fromSet(@Nonnull ContextSet contextSet) {
return Preconditions.checkNotNull(contextSet, "contextSet").makeImmutable();
}
/**
@@ -154,6 +144,7 @@ public final class ImmutableContextSet implements ContextSet {
*
* @return a new ContextSet
*/
@Nonnull
public static ImmutableContextSet empty() {
return EMPTY;
}
@@ -171,21 +162,25 @@ public final class ImmutableContextSet implements ContextSet {
@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 ImmutableSet.copyOf(map.entries());
}
@Override
@Nonnull
public Map<String, String> toMap() {
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
for (Map.Entry<String, String> e : map.entries()) {
@@ -196,49 +191,35 @@ public final class ImmutableContextSet implements ContextSet {
}
@Override
@Nonnull
public Multimap<String, String> toMultimap() {
return map;
}
@Override
public boolean containsKey(String key) {
if (key == null) {
throw new NullPointerException("key");
}
public boolean containsKey(@Nonnull String key) {
Preconditions.checkNotNull(key, "key");
return map.containsKey(key);
}
@Override
public Set<String> getValues(String key) {
if (key == null) {
throw new NullPointerException("key");
}
public Set<String> getValues(@Nonnull String key) {
Preconditions.checkNotNull(key, "key");
Collection<String> c = map.get(key);
return c != null && !c.isEmpty() ? ImmutableSet.copyOf(c) : ImmutableSet.of();
}
@Override
public boolean has(String key, String value) {
if (key == null) {
throw new NullPointerException("key");
}
if (value == null) {
throw new NullPointerException("value");
}
public boolean has(@Nonnull String key, @Nonnull String value) {
Preconditions.checkNotNull(key, "key");
Preconditions.checkNotNull(value, "value");
return map.containsEntry(key, value);
}
@Override
public boolean hasIgnoreCase(String key, String value) {
if (key == null) {
throw new NullPointerException("key");
}
if (value == null) {
throw new NullPointerException("value");
}
public boolean hasIgnoreCase(@Nonnull String key, @Nonnull String value) {
Preconditions.checkNotNull(key, "key");
Preconditions.checkNotNull(value, "value");
Collection<String> c = map.get(key);
if (c == null || c.isEmpty()) {
@@ -271,7 +252,7 @@ public final class ImmutableContextSet implements ContextSet {
final Multimap<String, String> thisContexts = this.toMultimap();
final Multimap<String, String> otherContexts = other.toMultimap();
return thisContexts == null ? otherContexts == null : thisContexts.equals(otherContexts);
return thisContexts.equals(otherContexts);
}
@Override
@@ -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,6 +25,7 @@
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;
@@ -34,6 +38,8 @@ import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* A mutable implementation of {@link ContextSet}.
*
@@ -49,14 +55,10 @@ public final class MutableContextSet implements ContextSet {
* @return a new MutableContextSet containing one KV pair
* @throws NullPointerException if key or value is null
*/
public static MutableContextSet singleton(String key, String value) {
if (key == null) {
throw new NullPointerException("key");
}
if (value == null) {
throw new NullPointerException("value");
}
@Nonnull
public static MutableContextSet singleton(@Nonnull String key, @Nonnull String value) {
Preconditions.checkNotNull(key, "key");
Preconditions.checkNotNull(value, "value");
MutableContextSet set = new MutableContextSet();
set.add(key, value);
return set;
@@ -73,20 +75,12 @@ public final class MutableContextSet implements ContextSet {
* @throws NullPointerException if any of the keys or values are null
* @since 3.1
*/
public static MutableContextSet of(String key1, String value1, String key2, String value2) {
if (key1 == null) {
throw new NullPointerException("key1");
}
if (value1 == null) {
throw new NullPointerException("value1");
}
if (key2 == null) {
throw new NullPointerException("key2");
}
if (value2 == null) {
throw new NullPointerException("value2");
}
@Nonnull
public static MutableContextSet of(@Nonnull String key1, @Nonnull String value1, @Nonnull String key2, @Nonnull String value2) {
Preconditions.checkNotNull(key1, "key1");
Preconditions.checkNotNull(value1, "value1");
Preconditions.checkNotNull(key2, "key2");
Preconditions.checkNotNull(value2, "value2");
MutableContextSet ret = singleton(key1, value1);
ret.add(key2, value2);
return ret;
@@ -99,11 +93,9 @@ public final class MutableContextSet implements ContextSet {
* @return a new MutableContextSet representing the pairs from the map
* @throws NullPointerException if the map is null
*/
public static MutableContextSet fromMap(Map<String, String> map) {
if (map == null) {
throw new NullPointerException("map");
}
@Nonnull
public static MutableContextSet fromMap(@Nonnull Map<String, String> map) {
Preconditions.checkNotNull(map, "map");
MutableContextSet set = new MutableContextSet();
set.addAll(map);
return set;
@@ -116,11 +108,9 @@ public final class MutableContextSet implements ContextSet {
* @return a new MutableContextSet representing the pairs in the iterable
* @throws NullPointerException if the iterable is null
*/
public static MutableContextSet fromEntries(Iterable<? extends Map.Entry<String, String>> iterable) {
if (iterable == null) {
throw new NullPointerException("iterable");
}
@Nonnull
public static MutableContextSet fromEntries(@Nonnull Iterable<? extends Map.Entry<String, String>> iterable) {
Preconditions.checkNotNull(iterable, "iterable");
MutableContextSet set = new MutableContextSet();
set.addAll(iterable);
return set;
@@ -133,11 +123,9 @@ public final class MutableContextSet implements ContextSet {
* @return a new MutableContextSet representing the pairs in the multimap
* @throws NullPointerException if the multimap is null
*/
public static MutableContextSet fromMultimap(Multimap<String, String> multimap) {
if (multimap == null) {
throw new NullPointerException("multimap");
}
@Nonnull
public static MutableContextSet fromMultimap(@Nonnull Multimap<String, String> multimap) {
Preconditions.checkNotNull(multimap, "multimap");
return fromEntries(multimap.entries());
}
@@ -149,11 +137,9 @@ public final class MutableContextSet implements ContextSet {
* @return a new MutableContextSet with the same content and the one provided
* @throws NullPointerException if contextSet is null
*/
public static MutableContextSet fromSet(ContextSet contextSet) {
if (contextSet == null) {
throw new NullPointerException("contextSet");
}
@Nonnull
public static MutableContextSet fromSet(@Nonnull ContextSet contextSet) {
Preconditions.checkNotNull(contextSet, "contextSet");
MutableContextSet set = new MutableContextSet();
set.addAll(contextSet.toSet());
return set;
@@ -164,6 +150,7 @@ public final class MutableContextSet implements ContextSet {
*
* @return a new MutableContextSet
*/
@Nonnull
public static MutableContextSet create() {
return new MutableContextSet();
}
@@ -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,18 +25,24 @@
package me.lucko.luckperms.api.data;
import javax.annotation.Nullable;
/**
* Represents the data section of the main LuckPerms configuration.
* All methods could return null.
*/
public interface DatastoreConfiguration {
@Nullable
String getAddress();
@Nullable
String getDatabase();
@Nullable
String getUsername();
@Nullable
String getPassword();
}
@@ -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,6 +27,8 @@ package me.lucko.luckperms.api.event;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nonnull;
/**
* Represents an event that can be cancelled
*/
@@ -34,6 +39,7 @@ public interface Cancellable {
*
* @return the cancellation
*/
@Nonnull
AtomicBoolean getCancellationState();
}
@@ -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
@@ -25,6 +28,8 @@ 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.
*
@@ -40,7 +45,8 @@ public interface EventBus {
* @param <T> the event class
* @return an event handler instance representing this subscription
*/
<T extends LuckPermsEvent> EventHandler<T> subscribe(Class<T> eventClass, Consumer<T> handler);
@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
@@ -49,6 +55,7 @@ public interface EventBus {
* @param <T> the event class
* @return an immutable set of event handlers
*/
<T extends LuckPermsEvent> Set<EventHandler<T>> getHandlers(Class<T> eventClass);
@Nonnull
<T extends LuckPermsEvent> Set<EventHandler<T>> getHandlers(@Nonnull Class<T> eventClass);
}
@@ -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,6 +27,8 @@ package me.lucko.luckperms.api.event;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
/**
* Represents a handler for a LuckPerms event
*
@@ -36,6 +41,7 @@ public interface EventHandler<T extends LuckPermsEvent> {
*
* @return the event class
*/
@Nonnull
Class<T> getEventClass();
/**
@@ -57,6 +63,7 @@ public interface EventHandler<T extends LuckPermsEvent> {
*
* @return the event consumer
*/
@Nonnull
Consumer<T> getConsumer();
/**
@@ -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,6 +27,8 @@ package me.lucko.luckperms.api.event;
import me.lucko.luckperms.api.LuckPermsApi;
import javax.annotation.Nonnull;
/**
* The base event interface
*
@@ -36,6 +41,7 @@ public interface LuckPermsEvent {
*
* @return the api instance
*/
@Nonnull
LuckPermsApi getApi();
}
@@ -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
@@ -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
@@ -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
@@ -26,6 +29,8 @@ 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
*/
@@ -36,6 +41,7 @@ public interface GroupCreateEvent extends LuckPermsEvent {
*
* @return the new group
*/
@Nonnull
Group getGroup();
/**
@@ -43,6 +49,7 @@ public interface GroupCreateEvent extends LuckPermsEvent {
*
* @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
@@ -28,6 +31,8 @@ import me.lucko.luckperms.api.event.cause.DeletionCause;
import java.util.Set;
import javax.annotation.Nonnull;
/**
* Called when a group is deleted
*/
@@ -38,6 +43,7 @@ public interface GroupDeleteEvent extends LuckPermsEvent {
*
* @return the name of the deleted group
*/
@Nonnull
String getGroupName();
/**
@@ -45,6 +51,7 @@ public interface GroupDeleteEvent extends LuckPermsEvent {
*
* @return a copy of the groups existing data
*/
@Nonnull
Set<Node> getExistingData();
/**
@@ -52,6 +59,7 @@ public interface GroupDeleteEvent extends LuckPermsEvent {
*
* @return the cause of the deletion
*/
@Nonnull
DeletionCause 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
@@ -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
@@ -25,6 +28,8 @@ 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.
*
@@ -37,6 +42,7 @@ public interface GroupLoadEvent extends LuckPermsEvent {
*
* @return the group that was loaded
*/
@Nonnull
Group 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
@@ -26,6 +29,8 @@ 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
*/
@@ -36,6 +41,7 @@ public interface LogBroadcastEvent extends LuckPermsEvent, Cancellable {
*
* @return the log entry to be broadcasted
*/
@Nonnull
LogEntry getEntry();
}
@@ -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
@@ -26,6 +29,8 @@ 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
*/
@@ -36,6 +41,7 @@ public interface LogPublishEvent extends LuckPermsEvent, Cancellable {
*
* @return the log entry to be published
*/
@Nonnull
LogEntry getEntry();
}
@@ -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,6 +27,8 @@ 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
*/
@@ -34,6 +39,7 @@ public interface NodeAddEvent extends NodeMutateEvent {
*
* @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
@@ -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
@@ -28,6 +31,8 @@ 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
*/
@@ -38,6 +43,7 @@ public interface NodeMutateEvent extends LuckPermsEvent {
*
* @return the event target
*/
@Nonnull
PermissionHolder getTarget();
/**
@@ -45,6 +51,7 @@ public interface NodeMutateEvent extends LuckPermsEvent {
*
* @return the data before the change
*/
@Nonnull
Set<Node> getDataBefore();
/**
@@ -52,6 +59,7 @@ public interface NodeMutateEvent extends LuckPermsEvent {
*
* @return the data after the change
*/
@Nonnull
Set<Node> getDataAfter();
/**
@@ -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,6 +27,8 @@ 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
*/
@@ -34,6 +39,7 @@ public interface NodeRemoveEvent extends NodeMutateEvent {
*
* @return the node that was removed
*/
@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
@@ -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
@@ -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
@@ -27,6 +30,8 @@ import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Called before a network sync task runs
*/
@@ -37,6 +42,7 @@ public interface PreNetworkSyncEvent extends LuckPermsEvent, Cancellable {
*
* @return the id of the sync request
*/
@Nonnull
UUID getSyncId();
}
@@ -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
@@ -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
@@ -26,6 +29,8 @@ 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
*/
@@ -36,6 +41,7 @@ public interface TrackCreateEvent extends LuckPermsEvent {
*
* @return the new track
*/
@Nonnull
Track getTrack();
/**
@@ -43,6 +49,7 @@ public interface TrackCreateEvent extends LuckPermsEvent {
*
* @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
@@ -27,6 +30,8 @@ import me.lucko.luckperms.api.event.cause.DeletionCause;
import java.util.List;
import javax.annotation.Nonnull;
/**
* Called when a track is deleted
*/
@@ -37,6 +42,7 @@ public interface TrackDeleteEvent extends LuckPermsEvent {
*
* @return the name of the deleted track
*/
@Nonnull
String getTrackName();
/**
@@ -44,6 +50,7 @@ public interface TrackDeleteEvent extends LuckPermsEvent {
*
* @return a copy of the tracks existing data
*/
@Nonnull
List<String> getExistingData();
/**
@@ -51,6 +58,7 @@ public interface TrackDeleteEvent extends LuckPermsEvent {
*
* @return the cause of the deletion
*/
@Nonnull
DeletionCause 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
@@ -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
@@ -25,6 +28,8 @@ 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.
*
@@ -37,6 +42,7 @@ public interface TrackLoadEvent extends LuckPermsEvent {
*
* @return the track that was loaded
*/
@Nonnull
Track getTrack();
}
@@ -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,6 +25,8 @@
package me.lucko.luckperms.api.event.track.mutate;
import javax.annotation.Nonnull;
/**
* Called when a group is added to a track
*/
@@ -32,6 +37,7 @@ public interface TrackAddGroupEvent extends TrackMutateEvent {
*
* @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
@@ -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
@@ -27,6 +30,8 @@ import me.lucko.luckperms.api.event.LuckPermsEvent;
import java.util.List;
import javax.annotation.Nonnull;
/**
* Called when a track is changed
*/
@@ -37,6 +42,7 @@ public interface TrackMutateEvent extends LuckPermsEvent {
*
* @return the track that was mutated
*/
@Nonnull
Track getTrack();
/**
@@ -44,6 +50,7 @@ public interface TrackMutateEvent extends LuckPermsEvent {
*
* @return the data before the change
*/
@Nonnull
List<String> getDataBefore();
/**
@@ -51,6 +58,7 @@ public interface TrackMutateEvent extends LuckPermsEvent {
*
* @return the data after the change
*/
@Nonnull
List<String> getDataAfter();
}
@@ -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,6 +25,8 @@
package me.lucko.luckperms.api.event.track.mutate;
import javax.annotation.Nonnull;
/**
* Called when a group is removed from a track
*/
@@ -32,6 +37,7 @@ public interface TrackRemoveGroupEvent extends TrackMutateEvent {
*
* @return the group that was removed
*/
@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
@@ -26,6 +29,8 @@ 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.
*/
@@ -36,6 +41,7 @@ public interface UserCacheLoadEvent extends LuckPermsEvent {
*
* @return the user
*/
@Nonnull
User getUser();
/**
@@ -43,6 +49,7 @@ public interface UserCacheLoadEvent extends LuckPermsEvent {
*
* @return the loaded data
*/
@Nonnull
UserData getLoadedData();
}
@@ -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
@@ -26,6 +29,8 @@ 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
*/
@@ -36,6 +41,7 @@ public interface UserDataRecalculateEvent extends LuckPermsEvent {
*
* @return the user
*/
@Nonnull
User getUser();
/**
@@ -43,6 +49,7 @@ public interface UserDataRecalculateEvent extends LuckPermsEvent {
*
* @return the data
*/
@Nonnull
UserData getData();
}
@@ -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
@@ -26,6 +29,8 @@ 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.
*
@@ -44,6 +49,7 @@ public interface UserFirstLoginEvent extends LuckPermsEvent {
*
* @return the uuid of the user
*/
@Nonnull
UUID getUuid();
/**
@@ -51,6 +57,7 @@ public interface UserFirstLoginEvent extends LuckPermsEvent {
*
* @return the username of the user
*/
@Nonnull
String getUsername();
}
@@ -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
@@ -25,6 +28,8 @@ 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.
*/
@@ -35,6 +40,7 @@ public interface UserLoadEvent extends LuckPermsEvent {
*
* @return the user that was loaded
*/
@Nonnull
User getUser();
}
@@ -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
@@ -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
@@ -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
@@ -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
@@ -28,6 +31,8 @@ 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
*/
@@ -38,6 +43,7 @@ public interface UserTrackEvent extends LuckPermsEvent {
*
* @return the track involved in the event
*/
@Nonnull
Track getTrack();
/**
@@ -45,6 +51,7 @@ public interface UserTrackEvent extends LuckPermsEvent {
*
* @return the user involved in the event
*/
@Nonnull
User getUser();
/**
@@ -52,6 +59,7 @@ public interface UserTrackEvent extends LuckPermsEvent {
*
* @return the action performed
*/
@Nonnull
TrackAction getAction();
/**
@@ -61,6 +69,7 @@ public interface UserTrackEvent extends LuckPermsEvent {
*
* @return the group the user was promoted/demoted from
*/
@Nonnull
Optional<String> getGroupFrom();
/**
@@ -68,6 +77,7 @@ public interface UserTrackEvent extends LuckPermsEvent {
*
* @return the group the user was promoted/demoted to
*/
@Nonnull
Optional<String> getGroupTo();
}
@@ -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);
}
@@ -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
@@ -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
@@ -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
+29 -13
View File
@@ -5,23 +5,15 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>3.1-SNAPSHOT</version>
<version>3.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luckperms-bukkit-legacy</artifactId>
<build>
<defaultGoal>clean package</defaultGoal>
<finalName>LuckPerms-Bukkit-Legacy-${release.version}.${patch.version}</finalName>
<resources>
<resource>
<directory>../</directory>
<filtering>false</filtering>
<includes>
<include>LICENSE.txt</include>
</includes>
</resource>
</resources>
<finalName>LuckPerms-Bukkit-Legacy-${full.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -55,8 +47,8 @@
<shadedPattern>me.lucko.luckperms.lib.gson</shadedPattern>
</relocation>
<relocation>
<pattern>io.github.mkremins.fanciful</pattern>
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
<pattern>net.kyori.text</pattern>
<shadedPattern>me.lucko.luckperms.lib.text</shadedPattern>
</relocation>
</relocations>
</configuration>
@@ -66,6 +58,30 @@
</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>
+61 -16
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>3.1-SNAPSHOT</version>
<version>3.3-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,20 +14,12 @@
<build>
<defaultGoal>clean package</defaultGoal>
<finalName>LuckPerms-Bukkit-${release.version}.${patch.version}</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<finalName>LuckPerms-Bukkit-${full.version}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>../</directory>
<filtering>false</filtering>
<includes>
<include>LICENSE.txt</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
@@ -54,8 +46,8 @@
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>io.github.mkremins.fanciful</pattern>
<shadedPattern>me.lucko.luckperms.lib.fanciful</shadedPattern>
<pattern>net.kyori.text</pattern>
<shadedPattern>me.lucko.luckperms.lib.text</shadedPattern>
</relocation>
</relocations>
</configuration>
@@ -65,12 +57,36 @@
</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>
<!-- Spigot API -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.11.2-R0.1-SNAPSHOT</version>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- Vault -->
@@ -79,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>
@@ -101,24 +123,26 @@
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- LilyPad - used as a messaging service -->
<!-- LilyPad -->
<dependency>
<groupId>lilypad.client.connect</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- **************Migration Plugins************** -->
<!-- ************** 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</version>
<version>1.23.5</version>
<scope>provided</scope>
<exclusions>
<exclusion>
@@ -129,20 +153,41 @@
<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>
@@ -1,71 +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.bukkit;
import lombok.AllArgsConstructor;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.bukkit.calculators.AttachmentProcessor;
import me.lucko.luckperms.bukkit.calculators.ChildProcessor;
import me.lucko.luckperms.bukkit.calculators.DefaultsProcessor;
import me.lucko.luckperms.bukkit.model.Injector;
import me.lucko.luckperms.bukkit.model.LPPermissible;
import me.lucko.luckperms.common.calculators.AbstractCalculatorFactory;
import me.lucko.luckperms.common.calculators.PermissionCalculator;
import me.lucko.luckperms.common.calculators.PermissionProcessor;
import me.lucko.luckperms.common.calculators.processors.MapProcessor;
import me.lucko.luckperms.common.calculators.processors.RegexProcessor;
import me.lucko.luckperms.common.calculators.processors.WildcardProcessor;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.core.model.User;
import java.util.UUID;
@AllArgsConstructor
public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
private final LPBukkitPlugin plugin;
@Override
public PermissionCalculator build(Contexts contexts, User user) {
UUID uuid = plugin.getUuidCache().getExternalUUID(user.getUuid());
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
processors.add(new MapProcessor());
processors.add(new ChildProcessor(plugin.getChildPermissionProvider()));
processors.add(new AttachmentProcessor(() -> {
LPPermissible permissible = Injector.getPermissible(uuid);
return permissible == null ? null : permissible.getAttachmentPermissions();
}));
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) {
processors.add(new RegexProcessor());
}
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_WILDCARDS)) {
processors.add(new WildcardProcessor());
}
processors.add(new DefaultsProcessor(contexts.isOp(), plugin.getDefaultsProvider()));
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.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
@@ -27,7 +30,6 @@ import com.google.common.base.Splitter;
import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.constants.Patterns;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -50,7 +52,7 @@ public class BukkitCommand extends CommandManager implements CommandExecutor, Ta
onCommand(
plugin.getSenderFactory().wrap(sender),
label,
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
Util.stripQuotes(Splitter.on(COMMAND_SEPARATOR_PATTERN).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
);
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
@@ -31,11 +34,11 @@ 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.Optional;
import java.util.stream.Collectors;
import java.util.Set;
@RequiredArgsConstructor
public class BukkitConfig extends AbstractConfiguration {
@@ -79,7 +82,8 @@ public class BukkitConfig extends AbstractConfiguration {
@Override
public List<String> getList(String path, List<String> def) {
return Optional.ofNullable(configuration.getStringList(path)).orElse(def);
List<String> ret = configuration.getStringList(path);
return ret == null ? def : ret;
}
@Override
@@ -89,7 +93,8 @@ public class BukkitConfig extends AbstractConfiguration {
return def;
}
return Optional.ofNullable(section.getKeys(false).stream().collect(Collectors.toList())).orElse(def);
Set<String> keys = section.getKeys(false);
return keys == null ? def : new ArrayList<>(keys);
}
@Override
@@ -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
@@ -26,10 +29,9 @@ import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.bukkit.model.Injector;
import me.lucko.luckperms.bukkit.model.LPPermissible;
import me.lucko.luckperms.common.caching.UserCache;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.utils.LoginHelper;
import org.bukkit.entity.Player;
@@ -47,6 +49,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor
public class BukkitListener implements Listener {
@@ -60,15 +63,15 @@ public class BukkitListener implements Listener {
/* Called when the player first attempts a connection with the server.
Listening on LOW priority to allow plugins to modify username / UUID data here. (auth plugins) */
/* the player was denied entry to the server before this priority.
log this, so we can handle appropriately later. */
if (e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
plugin.getLog().warn("Connection from " + e.getUniqueId() + " was already denied. No permissions data will be loaded.");
deniedAsyncLogin.add(e.getUniqueId());
return;
/* wait for the plugin to enable. because these events are fired async, they can be called before
the plugin has enabled. */
try {
plugin.getEnableLatch().await(30, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
/* either the plugin hasn't finished starting yet, or there was an issue connecting to the DB, performing file i/o, etc.
/* there was an issue connecting to the DB, performing file i/o, etc.
we don't let players join in this case, because it means they can connect to the server without their permissions data.
some server admins rely on negating perms to stop users from causing damage etc, so it's really important that
this data is loaded. */
@@ -78,11 +81,13 @@ public class BukkitListener implements Listener {
deniedAsyncLogin.add(e.getUniqueId());
// actually deny the connection.
plugin.getLog().warn("Permissions storage is not loaded yet. Denying connection from: " + e.getUniqueId() + " - " + e.getName());
plugin.getLog().warn("Permissions storage is not loaded. Denying connection from: " + e.getUniqueId() + " - " + e.getName());
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.asString(plugin.getLocaleManager()));
return;
}
plugin.getUniqueConnections().add(e.getUniqueId());
/* Actually process the login for the connection.
We do this here to delay the login until the data is ready.
If the login gets cancelled later on, then this will be cleaned up.
@@ -93,7 +98,7 @@ public class BukkitListener implements Listener {
- creating a user instance in the UserManager for this connection.
- setting up cached data. */
try {
LoginHelper.loadUser(plugin, e.getUniqueId(), e.getName());
LoginHelper.loadUser(plugin, e.getUniqueId(), e.getName(), false);
} catch (Exception ex) {
ex.printStackTrace();
@@ -110,6 +115,7 @@ public class BukkitListener implements Listener {
// Check to see if this connection was denied at LOW.
if (deniedAsyncLogin.remove(e.getUniqueId())) {
// their data was never loaded at LOW priority, now check to see if they have been magically allowed since then.
// This is a problem, as they were denied at low priority, but are now being allowed.
if (e.getLoginResult() == AsyncPlayerPreLoginEvent.Result.ALLOWED) {
@@ -120,29 +126,20 @@ public class BukkitListener implements Listener {
return;
}
// Login event was cancelled by another plugin
// Login event was cancelled by another plugin, but it wasn't cancelled when we handled it at LOW
if (e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
// Schedule cleanup of this user.
plugin.getUserManager().scheduleUnload(e.getUniqueId());
}
}
@EventHandler(priority = EventPriority.LOW)
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerLogin(PlayerLoginEvent e) {
/* Called when the player starts logging into the server.
At this point, the users data should be present and loaded.
Listening on LOW priority to allow plugins to further modify data here. (auth plugins, etc.) */
/* the player was denied entry to the server before this priority.
log this, so we can handle appropriately later. */
if (e.getResult() != PlayerLoginEvent.Result.ALLOWED) {
plugin.getLog().warn("Login from " + e.getPlayer().getUniqueId() + " was denied before an attachment could be injected.");
deniedLogin.add(e.getPlayer().getUniqueId());
return;
}
At this point, the users data should be present and loaded. */
final Player player = e.getPlayer();
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
final User user = plugin.getUserManager().getIfLoaded(plugin.getUuidCache().getUUID(player.getUniqueId()));
/* User instance is null for whatever reason. Could be that it was unloaded between asyncpre and now. */
if (user == null) {
@@ -170,14 +167,7 @@ public class BukkitListener implements Listener {
// We assume all users are not op, but those who are need extra calculation.
if (player.isOp()) {
plugin.doAsync(() -> {
UserCache userData = user.getUserData();
if (userData == null) {
return;
}
userData.preCalculate(plugin.getPreProcessContexts(true));
});
plugin.doAsync(() -> user.getUserData().preCalculate(plugin.getPreProcessContexts(true)));
}
}
@@ -186,20 +176,20 @@ public class BukkitListener implements Listener {
/* Listen to see if the event was cancelled after we initially handled the login
If the connection was cancelled here, we need to do something to clean up the data that was loaded. */
// Check to see if this connection was denied at LOW.
// Check to see if this connection was denied at LOW. Even if it was denied at LOW, their data will still be present.
boolean denied = false;
if (deniedLogin.remove(e.getPlayer().getUniqueId())) {
denied = true;
// This is a problem, as they were denied at low priority, but are now being allowed.
if (e.getResult() == PlayerLoginEvent.Result.ALLOWED) {
plugin.getLog().severe("Player connection was re-allowed for " + e.getPlayer().getUniqueId());
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, "");
}
return;
}
// Login event was cancelled by another plugin
if (e.getResult() != PlayerLoginEvent.Result.ALLOWED) {
// Login event was cancelled by another plugin since we first loaded their data
if (denied || e.getResult() != PlayerLoginEvent.Result.ALLOWED) {
// Schedule cleanup of this user.
plugin.getUserManager().scheduleUnload(e.getPlayer().getUniqueId());
return;
@@ -215,7 +205,11 @@ public class BukkitListener implements Listener {
final Player player = e.getPlayer();
// Remove the custom permissible
Injector.unInject(player, true, true);
try {
Injector.unInject(player, true, true);
} catch (Exception ex) {
ex.printStackTrace();
}
// Handle auto op
if (plugin.getConfiguration().get(ConfigKeys.AUTO_OP)) {
@@ -232,8 +226,7 @@ public class BukkitListener implements Listener {
return;
}
String s = e.getMessage().toLowerCase()
.replace("/", "")
String s = e.getMessage().substring(1).toLowerCase()
.replace("bukkit:", "")
.replace("spigot:", "")
.replace("minecraft:", "");
@@ -251,8 +244,9 @@ public class BukkitListener implements Listener {
}
}
@EventHandler
@EventHandler(priority = EventPriority.LOWEST)
public void onWorldChange(PlayerChangedWorldEvent e) {
plugin.getContextManager().invalidateCache(e.getPlayer());
plugin.refreshAutoOp(e.getPlayer());
}
}
@@ -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,16 +25,18 @@
package me.lucko.luckperms.bukkit;
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 io.github.mkremins.fanciful.FancyMessage;
import java.util.UUID;
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
@@ -60,14 +65,29 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
@Override
protected void sendMessage(CommandSender sender, String s) {
// send sync if command block
if (sender instanceof BlockCommandSender) {
getPlugin().getScheduler().doSync(() -> sender.sendMessage(s));
return;
}
sender.sendMessage(s);
}
@Override
protected void sendMessage(CommandSender sender, FancyMessage message) {
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);
@@ -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
@@ -29,53 +32,55 @@ import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.bukkit.calculators.BukkitCalculatorFactory;
import me.lucko.luckperms.bukkit.contexts.WorldCalculator;
import me.lucko.luckperms.bukkit.messaging.BungeeMessagingService;
import me.lucko.luckperms.bukkit.messaging.LilyPadMessagingService;
import me.lucko.luckperms.bukkit.model.ChildPermissionProvider;
import me.lucko.luckperms.bukkit.model.DefaultsProvider;
import me.lucko.luckperms.bukkit.model.Injector;
import me.lucko.luckperms.bukkit.model.LPPermissible;
import me.lucko.luckperms.bukkit.vault.VaultHook;
import me.lucko.luckperms.bukkit.processors.ChildPermissionProvider;
import me.lucko.luckperms.bukkit.processors.DefaultsProvider;
import me.lucko.luckperms.bukkit.vault.VaultHookManager;
import me.lucko.luckperms.common.api.ApiHandler;
import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.caching.UserCache;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.constants.CommandPermission;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.StaticCalculator;
import me.lucko.luckperms.common.core.UuidCache;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator;
import me.lucko.luckperms.common.dependencies.Dependency;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.managers.GenericGroupManager;
import me.lucko.luckperms.common.managers.GenericTrackManager;
import me.lucko.luckperms.common.managers.GenericUserManager;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.UserManager;
import me.lucko.luckperms.common.managers.impl.GenericGroupManager;
import me.lucko.luckperms.common.managers.impl.GenericTrackManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import me.lucko.luckperms.common.messaging.InternalMessagingService;
import me.lucko.luckperms.common.messaging.NoopMessagingService;
import me.lucko.luckperms.common.messaging.RedisMessaging;
import me.lucko.luckperms.common.messaging.RedisMessagingService;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.storage.StorageType;
import me.lucko.luckperms.common.storage.backing.file.FileWatcher;
import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.utils.BufferedRequest;
import me.lucko.luckperms.common.utils.FileWatcher;
import me.lucko.luckperms.common.utils.LoggerImpl;
import me.lucko.luckperms.common.utils.LoginHelper;
import me.lucko.luckperms.common.utils.UuidCache;
import me.lucko.luckperms.common.verbose.VerboseHandler;
import org.bukkit.World;
@@ -99,14 +104,17 @@ import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
@Getter
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private Set<UUID> ignoringLogs;
private Set<UUID> uniqueConnections;
private long startTime;
private LPBukkitScheduler scheduler;
private BukkitCommand commandManager;
private VaultHook vaultHook = null;
private VaultHookManager vaultHookManager = null;
private LuckPermsConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
@@ -127,6 +135,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
private boolean started = false;
private CountDownLatch enableLatch = new CountDownLatch(1);
private VerboseHandler verboseHandler;
private BukkitSenderFactory senderFactory;
private PermissionVault permissionVault;
@@ -137,16 +146,29 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
scheduler = new LPBukkitScheduler(this);
localeManager = new NoopLocaleManager();
senderFactory = new BukkitSenderFactory(this);
log = new LoggerImpl(getConsoleSender());
log = new SenderLogger(this, getConsoleSender());
DependencyManager.loadDependencies(this, Collections.singletonList(Dependency.CAFFEINE));
}
@Override
public void onEnable() {
try {
enable();
started = true;
} finally {
// count down the latch when onEnable has been called
// we don't care about the result here
enableLatch.countDown();
}
}
private void enable() {
startTime = System.currentTimeMillis();
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
ignoringLogs = ConcurrentHashMap.newKeySet();
uniqueConnections = ConcurrentHashMap.newKeySet();
verboseHandler = new VerboseHandler(scheduler.getAsyncBukkitExecutor(), getVersion());
permissionVault = new PermissionVault(scheduler.getAsyncBukkitExecutor());
@@ -163,7 +185,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
childPermissionProvider = new ChildPermissionProvider();
// give all plugins a chance to load their permissions, then refresh.
scheduler.doSyncLater(() -> {
scheduler.syncLater(() -> {
defaultsProvider.refresh();
childPermissionProvider.setup();
@@ -177,13 +199,12 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}, 1L);
// register events
PluginManager pm = getServer().getPluginManager();
listener = new BukkitListener(this);
pm.registerEvents(listener, this);
getServer().getPluginManager().registerEvents(listener, this);
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
fileWatcher = new FileWatcher(this);
getScheduler().doAsyncRepeating(fileWatcher, 30L);
getScheduler().asyncRepeating(fileWatcher, 30L);
}
// initialise datastore
@@ -194,14 +215,16 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
if (messagingType.equals("none") && getConfiguration().get(ConfigKeys.REDIS_ENABLED)) {
messagingType = "redis";
}
if (!messagingType.equals("none")) {
getLog().info("Loading messaging service... [" + messagingType.toUpperCase() + "]");
}
if (messagingType.equals("redis")) {
getLog().info("Loading redis...");
if (getConfiguration().get(ConfigKeys.REDIS_ENABLED)) {
RedisMessaging redis = new RedisMessaging(this);
RedisMessagingService redis = new RedisMessagingService(this);
try {
redis.init(getConfiguration().get(ConfigKeys.REDIS_ADDRESS), getConfiguration().get(ConfigKeys.REDIS_PASSWORD));
getLog().info("Loaded redis successfully...");
messagingService = redis;
} catch (Exception e) {
getLog().warn("Couldn't load redis...");
@@ -211,12 +234,10 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
getLog().warn("Messaging Service was set to redis, but redis is not enabled!");
}
} else if (messagingType.equals("bungee")) {
getLog().info("Loading bungee messaging service...");
BungeeMessagingService bungeeMessaging = new BungeeMessagingService(this);
bungeeMessaging.init();
messagingService = bungeeMessaging;
} else if (messagingType.equals("lilypad")) {
getLog().info("Loading LilyPad messaging service...");
if (getServer().getPluginManager().getPlugin("LilyPad-Connect") == null) {
getLog().warn("LilyPad-Connect plugin not present.");
} else {
@@ -245,7 +266,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
localeManager = new SimpleLocaleManager();
File locale = new File(getDataFolder(), "lang.yml");
if (locale.exists()) {
getLog().info("Found locale file. Attempting to load from it.");
getLog().info("Found lang.yml - loading messages...");
try {
localeManager.loadFromFile(locale);
} catch (Exception e) {
@@ -254,12 +275,12 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
// register commands
getLog().info("Registering commands...");
commandManager = new BukkitCommand(this);
PluginCommand main = getServer().getPluginCommand("luckperms");
main.setExecutor(commandManager);
main.setTabCompleter(commandManager);
main.setAliases(Arrays.asList("perms", "lp", "permissions", "perm"));
main.setDescription("Manage permissions");
main.setAliases(Arrays.asList("lp", "perm", "perms", "permission", "permissions"));
// load internal managers
getLog().info("Loading internal permission managers...");
@@ -268,18 +289,33 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
groupManager = new GenericGroupManager(this);
trackManager = new GenericTrackManager(this);
calculatorFactory = new BukkitCalculatorFactory(this);
cachedStateManager = new CachedStateManager(this);
cachedStateManager = new CachedStateManager();
contextManager = new ContextManager<Player>() {
@Override
public Contexts formContexts(Player player, ImmutableContextSet contextSet) {
return new Contexts(
contextSet,
getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_PERMS),
getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_WORLD_PERMS),
true,
getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_GROUPS),
getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS),
player.isOp()
);
}
};
contextManager = new ContextManager<>();
worldCalculator = new WorldCalculator(this);
contextManager.registerCalculator(worldCalculator);
contextManager.registerCalculator(new StaticCalculator<>(getConfiguration()));
LuckPermsCalculator<Player> staticCalculator = new LuckPermsCalculator<>(getConfiguration());
contextManager.registerCalculator(staticCalculator, true);
// Provide vault support
tryVaultHook(false);
// register with the LP API
getLog().info("Registering API...");
apiProvider = new ApiProvider(this);
ApiHandler.registerProvider(apiProvider);
getServer().getServicesManager().register(LuckPermsApi.class, apiProvider, this, ServicePriority.Normal);
@@ -289,16 +325,17 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
int mins = getConfiguration().get(ConfigKeys.SYNC_TIME);
if (mins > 0) {
long ticks = mins * 60 * 20;
scheduler.doAsyncRepeating(() -> updateTaskBuffer.request(), ticks);
scheduler.asyncRepeating(() -> updateTaskBuffer.request(), ticks);
}
scheduler.doAsyncLater(() -> updateTaskBuffer.request(), 40L);
scheduler.asyncLater(() -> updateTaskBuffer.request(), 40L);
// run an update instantly.
getLog().info("Performing initial data load...");
updateTaskBuffer.requestDirectly();
// register tasks
scheduler.doAsyncRepeating(new ExpireTemporaryTask(this), 60L);
scheduler.doAsyncRepeating(new CacheHousekeepingTask(this), 2400L);
scheduler.asyncRepeating(new ExpireTemporaryTask(this), 60L);
scheduler.asyncRepeating(new CacheHousekeepingTask(this), 2400L);
// register permissions
try {
@@ -317,8 +354,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// Load any online users (in the case of a reload)
for (Player player : getServer().getOnlinePlayers()) {
scheduler.doAsync(() -> {
LoginHelper.loadUser(this, player.getUniqueId(), player.getName());
User user = getUserManager().get(getUuidCache().getUUID(player.getUniqueId()));
LoginHelper.loadUser(this, player.getUniqueId(), player.getName(), false);
User user = getUserManager().getIfLoaded(getUuidCache().getUUID(player.getUniqueId()));
if (user != null) {
scheduler.doSync(() -> {
try {
@@ -332,8 +369,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
});
}
started = true;
getLog().info("Successfully loaded.");
getLog().info("Successfully enabled. (took " + (System.currentTimeMillis() - startTime) + "ms)");
}
@Override
@@ -348,19 +384,24 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
verboseHandler.setShutdown(true);
for (Player player : getServer().getOnlinePlayers()) {
Injector.unInject(player, false, false);
try {
Injector.unInject(player, false, false);
} catch (Exception e) {
e.printStackTrace();
}
if (getConfiguration().get(ConfigKeys.AUTO_OP)) {
player.setOp(false);
}
final User user = getUserManager().get(getUuidCache().getUUID(player.getUniqueId()));
final User user = getUserManager().getIfLoaded(getUuidCache().getUUID(player.getUniqueId()));
if (user != null) {
user.unregisterData();
getUserManager().unload(user);
}
}
getLog().info("Closing datastore...");
getLog().info("Closing storage...");
storage.shutdown();
if (fileWatcher != null) {
@@ -372,14 +413,14 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
messagingService.close();
}
getLog().info("Unregistering API...");
ApiHandler.unregisterProvider();
getServer().getServicesManager().unregisterAll(this);
if (vaultHook != null) {
vaultHook.unhook(this);
if (vaultHookManager != null) {
vaultHookManager.unhook(this);
}
getLog().info("Shutting down internal scheduler...");
scheduler.shutdown();
// Bukkit will do this again when #onDisable completes, but we do it early to prevent NPEs elsewhere.
@@ -388,7 +429,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// Null everything
ignoringLogs = null;
vaultHook = null;
vaultHookManager = null;
configuration = null;
userManager = null;
groupManager = null;
@@ -414,21 +455,18 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
public void tryVaultHook(boolean force) {
if (vaultHook != null) {
return;
if (vaultHookManager != null) {
return; // already hooked
}
getLog().info("Attempting to hook with Vault...");
try {
if (force || getServer().getPluginManager().isPluginEnabled("Vault")) {
vaultHook = new VaultHook();
vaultHook.hook(this);
vaultHookManager = new VaultHookManager();
vaultHookManager.hook(this);
getLog().info("Registered Vault permission & chat hook.");
} else {
getLog().info("Vault not found.");
}
} catch (Exception e) {
vaultHook = null;
vaultHookManager = null;
getLog().severe("Error occurred whilst hooking into Vault.");
e.printStackTrace();
}
@@ -455,12 +493,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
return;
}
UserCache userData = user.getUserData();
if (userData == null) {
return;
}
Map<String, Boolean> backing = userData.getPermissionData(permissible.calculateContexts()).getImmutableBacking();
Map<String, Boolean> backing = user.getUserData().getPermissionData(permissible.calculateContexts()).getImmutableBacking();
boolean op = Optional.ofNullable(backing.get("luckperms.autoop")).orElse(false);
player.setOp(op);
} catch (Exception ignored) {}
@@ -502,21 +535,24 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
return getServer().getPlayer(uuidCache.getExternalUUID(user.getUuid()));
}
@Override
public Optional<UUID> lookupUuid(String username) {
try {
//noinspection deprecation
return Optional.ofNullable(getServer().getOfflinePlayer(username)).flatMap(p -> Optional.ofNullable(p.getUniqueId()));
} catch (Exception e) {
e.printStackTrace();
return Optional.empty();
}
}
@Override
public Contexts getContextForUser(User user) {
Player player = getPlayer(user);
if (player == null) {
return null;
}
return new Contexts(
getContextManager().getApplicableContext(player),
getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_PERMS),
getConfiguration().get(ConfigKeys.INCLUDING_GLOBAL_WORLD_PERMS),
true,
getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_GROUPS),
getConfiguration().get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS),
player.isOp()
);
return contextManager.getApplicableContexts(player);
}
@Override
@@ -565,7 +601,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
MutableContextSet set = MutableContextSet.create();
set.add("server", getConfiguration().get(ConfigKeys.SERVER));
set.add("world", s);
set.addAll(configuration.getStaticContexts().getContextSet());
set.addAll(configuration.getContextsFile().getStaticContexts());
return set.makeImmutable();
})
.collect(Collectors.toList())
@@ -580,7 +616,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
MutableContextSet set = MutableContextSet.create();
set.add("server", getConfiguration().get(ConfigKeys.VAULT_SERVER));
set.add("world", s);
set.addAll(configuration.getStaticContexts().getContextSet());
set.addAll(configuration.getContextsFile().getStaticContexts());
return set.makeImmutable();
})
.collect(Collectors.toList())
@@ -622,27 +658,17 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
@Override
public LinkedHashMap<String, Object> getExtraInfo() {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put("Vault Enabled", vaultHook != null);
map.put("Vault Server", configuration.get(ConfigKeys.VAULT_SERVER));
map.put("Vault Enabled", vaultHookManager != null);
map.put("Bukkit Defaults count", defaultsProvider.size());
map.put("Bukkit Child Permissions count", childPermissionProvider.getPermissions().size());
map.put("Vault Including Global", configuration.get(ConfigKeys.VAULT_INCLUDING_GLOBAL));
map.put("Vault Ignoring World", configuration.get(ConfigKeys.VAULT_IGNORE_WORLD));
map.put("Vault Primary Group Overrides", configuration.get(ConfigKeys.VAULT_PRIMARY_GROUP_OVERRIDES));
map.put("Vault Debug", configuration.get(ConfigKeys.VAULT_DEBUG));
map.put("OPs Enabled", configuration.get(ConfigKeys.OPS_ENABLED));
map.put("Auto OP", configuration.get(ConfigKeys.AUTO_OP));
map.put("Commands Allow OPs", configuration.get(ConfigKeys.COMMANDS_ALLOW_OP));
return map;
}
private void registerPermissions(PermissionDefault def) {
PluginManager pm = getServer().getPluginManager();
for (Permission p : Permission.values()) {
for (String node : p.getNodes()) {
pm.addPermission(new org.bukkit.permissions.Permission(node, def));
}
for (CommandPermission p : CommandPermission.values()) {
pm.addPermission(new org.bukkit.permissions.Permission(p.getPermission(), def));
}
}
}
@@ -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
@@ -60,45 +63,45 @@ public class LPBukkitScheduler implements LuckPermsScheduler {
}
@Override
public Executor getAsyncExecutor() {
public Executor async() {
return useBukkitAsync ? asyncBukkitExecutor : asyncLpExecutor;
}
@Override
public Executor getSyncExecutor() {
public Executor sync() {
return syncExecutor;
}
@Override
public void doAsync(Runnable r) {
getAsyncExecutor().execute(r);
public void doAsync(Runnable runnable) {
async().execute(runnable);
}
@Override
public void doSync(Runnable r) {
getSyncExecutor().execute(r);
public void doSync(Runnable runnable) {
sync().execute(runnable);
}
@Override
public void doAsyncRepeating(Runnable r, long interval) {
BukkitTask task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, r, interval, interval);
public void asyncRepeating(Runnable runnable, long intervalTicks) {
BukkitTask task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, runnable, intervalTicks, intervalTicks);
tasks.add(task);
}
@Override
public void doSyncRepeating(Runnable r, long interval) {
BukkitTask task = plugin.getServer().getScheduler().runTaskTimer(plugin, r, interval, interval);
public void syncRepeating(Runnable runnable, long intervalTicks) {
BukkitTask task = plugin.getServer().getScheduler().runTaskTimer(plugin, runnable, intervalTicks, intervalTicks);
tasks.add(task);
}
@Override
public void doAsyncLater(Runnable r, long delay) {
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, r, delay);
public void asyncLater(Runnable runnable, long delayTicks) {
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, runnable, delayTicks);
}
@Override
public void doSyncLater(Runnable r, long delay) {
plugin.getServer().getScheduler().runTaskLater(plugin, r, delay);
public void syncLater(Runnable runnable, long delayTicks) {
plugin.getServer().getScheduler().runTaskLater(plugin, runnable, delayTicks);
}
@Override
@@ -0,0 +1,99 @@
/*
* 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.calculators;
import lombok.AllArgsConstructor;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.model.Injector;
import me.lucko.luckperms.bukkit.model.LPPermissible;
import me.lucko.luckperms.bukkit.processors.AttachmentProcessor;
import me.lucko.luckperms.bukkit.processors.ChildProcessor;
import me.lucko.luckperms.bukkit.processors.DefaultsProcessor;
import me.lucko.luckperms.common.calculators.AbstractCalculatorFactory;
import me.lucko.luckperms.common.calculators.PermissionCalculator;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.processors.MapProcessor;
import me.lucko.luckperms.common.processors.PermissionProcessor;
import me.lucko.luckperms.common.processors.RegexProcessor;
import me.lucko.luckperms.common.processors.WildcardProcessor;
import java.util.List;
import java.util.UUID;
@AllArgsConstructor
public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
private final LPBukkitPlugin plugin;
@Override
public PermissionCalculator build(Contexts contexts, User user) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
processors.add(new MapProcessor());
if (plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_CHILD_PERMISSIONS)) {
processors.add(new ChildProcessor(plugin.getChildPermissionProvider()));
}
if (plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_ATTACHMENT_PERMISSIONS)) {
final UUID uuid = plugin.getUuidCache().getExternalUUID(user.getUuid());
processors.add(new AttachmentProcessor(() -> {
LPPermissible permissible = Injector.getPermissible(uuid);
return permissible == null ? null : permissible.getAttachmentPermissions();
}));
}
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) {
processors.add(new RegexProcessor());
}
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_WILDCARDS)) {
processors.add(new WildcardProcessor());
}
if (plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) {
processors.add(new DefaultsProcessor(contexts.isOp(), plugin.getDefaultsProvider()));
}
return registerCalculator(new PermissionCalculator(plugin, user.getFriendlyName(), processors.build()));
}
@Override
public List<String> getActiveProcessors() {
ImmutableList.Builder<String> ret = ImmutableList.builder();
ret.add("Map");
if (plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_CHILD_PERMISSIONS)) ret.add("Child");
if (plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_ATTACHMENT_PERMISSIONS)) ret.add("Attachment");
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) ret.add("Regex");
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_WILDCARDS)) ret.add("Wildcard");
if (plugin.getConfiguration().get(ConfigKeys.APPLY_BUKKIT_DEFAULT_PERMISSIONS)) ret.add("Defaults");
return ret.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
@@ -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,11 +25,17 @@
package me.lucko.luckperms.bukkit.compat;
import me.lucko.luckperms.common.constants.Constants;
import net.kyori.text.Component;
import net.kyori.text.serializer.ComponentSerializer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import io.github.mkremins.fanciful.FancyMessage;
/**
* Sends a json message to a command sender.
*/
public class MessageHandler {
private final BukkitJsonMessageHandler bukkitHandler;
private final SpigotJsonMessageHandler spigotHandler;
@@ -36,10 +45,10 @@ public class MessageHandler {
spigotHandler = isSpigot() ? new SpigotJsonMessageHandler() : null;
}
public void sendJsonMessage(CommandSender sender, FancyMessage message) {
public void sendJsonMessage(CommandSender sender, Component message) {
if (ReflectionUtil.isChatCompatible() && sender instanceof Player) {
Player player = (Player) sender;
String json = message.exportToJson();
String json = ComponentSerializer.serialize(message);
// Try Bukkit.
if (bukkitHandler.sendJsonMessage(player, json)) {
@@ -53,7 +62,7 @@ public class MessageHandler {
}
// Fallback to Bukkit
sender.sendMessage(message.toOldMessageFormat());
sender.sendMessage(ComponentSerializer.toLegacy(message, Constants.COLOR_CHAR));
}
private static boolean isSpigot() {
@@ -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
@@ -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
@@ -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,12 +23,10 @@
* SOFTWARE.
*/
package me.lucko.luckperms.bukkit;
package me.lucko.luckperms.bukkit.contexts;
import lombok.RequiredArgsConstructor;
import com.google.common.collect.Maps;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.config.ConfigKeys;
@@ -41,11 +42,10 @@ public class WorldCalculator implements ContextCalculator<Player> {
@Override
public MutableContextSet giveApplicableContext(Player subject, MutableContextSet accumulator) {
String world = subject.getWorld().getName();
world = plugin.getConfiguration().get(ConfigKeys.WORLD_REWRITES).getOrDefault(world, world);
if (world != null) {
accumulator.add(Maps.immutableEntry(WORLD_KEY, world.toLowerCase()));
String world = subject.getWorld().getName().toLowerCase();
while (!accumulator.has(WORLD_KEY, world)) {
accumulator.add(WORLD_KEY, world);
world = plugin.getConfiguration().get(ConfigKeys.WORLD_REWRITES).getOrDefault(world, world).toLowerCase();
}
return accumulator;
@@ -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
@@ -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
@@ -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
@@ -29,18 +32,21 @@ import de.bananaco.bpermissions.api.Permission;
import de.bananaco.bpermissions.api.World;
import de.bananaco.bpermissions.api.WorldManager;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.abstraction.SubCommand;
import me.lucko.luckperms.common.commands.impl.migration.MigrationUtils;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.core.NodeFactory;
import me.lucko.luckperms.common.core.model.PermissionHolder;
import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.locale.CommandSpec;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.logging.ProgressLogger;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.common.utils.ProgressLogger;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
@@ -53,7 +59,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import static me.lucko.luckperms.common.constants.Permission.MIGRATION;
import static me.lucko.luckperms.common.constants.CommandPermission.MIGRATION;
public class MigrationBPermissions extends SubCommand<Object> {
private static Field uConfigField;
@@ -66,8 +72,8 @@ public class MigrationBPermissions extends SubCommand<Object> {
}
}
public MigrationBPermissions() {
super("bpermissions", "Migration from bPermissions", MIGRATION, Predicates.alwaysFalse(), null);
public MigrationBPermissions(LocaleManager locale) {
super(CommandSpec.MIGRATION_COMMAND.spec(locale), "bpermissions", MIGRATION, Predicates.alwaysFalse());
}
@Override
@@ -133,7 +139,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
// Make a LuckPerms group for the one being migrated.
plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
me.lucko.luckperms.common.core.model.Group lpGroup = plugin.getGroupManager().getIfLoaded(groupName);
me.lucko.luckperms.common.model.Group lpGroup = plugin.getGroupManager().getIfLoaded(groupName);
MigrationUtils.setGroupWeight(lpGroup, group.getPriority());
migrateHolder(world, group, lpGroup);
@@ -169,7 +175,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
// Make a LuckPerms user for the one being migrated.
plugin.getStorage().loadUser(uuid, "null").join();
User lpUser = plugin.getUserManager().get(uuid);
User lpUser = plugin.getUserManager().getIfLoaded(uuid);
migrateHolder(world, user, lpUser);
@@ -221,7 +227,8 @@ public class MigrationBPermissions extends SubCommand<Object> {
}
if (meta.getKey().equalsIgnoreCase("prefix") || meta.getKey().equalsIgnoreCase("suffix")) {
holder.setPermission(NodeFactory.makeChatMetaNode(meta.getKey().equalsIgnoreCase("prefix"), c.getPriority(), meta.getValue()).setWorld(world.getName()).build());
ChatMetaType type = ChatMetaType.valueOf(meta.getKey().toUpperCase());
holder.setPermission(NodeFactory.makeChatMetaNode(type, c.getPriority(), meta.getValue()).setWorld(world.getName()).build());
continue;
}
Loaded 100 of 531 files, more files were not shown because too many files have changed in this diff. Show more