Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abc1c164cf | ||
|
|
dc801464ef | ||
|
|
99c6fe20c2 | ||
|
|
9d780ae24a | ||
|
|
a44dec0402 | ||
|
|
a081152baa | ||
|
|
9b50d48f46 | ||
|
|
5121fc6b1f | ||
|
|
d4ac261e85 | ||
|
|
2e9561371d | ||
|
|
942fd3c4ce | ||
|
|
8cf32752e9 | ||
|
|
b240ca9939 | ||
|
|
e25d99129c | ||
|
|
1fee47e087 | ||
|
|
e835b31277 | ||
|
|
6817945e12 | ||
|
|
030fb1262e | ||
|
|
fae49096f3 | ||
|
|
afd491ecea | ||
|
|
09bc100ad9 | ||
|
|
037f18ac56 | ||
|
|
a5746dfa21 | ||
|
|
cedc5108fc | ||
|
|
65af3d0f54 | ||
|
|
6c4fa65f91 | ||
|
|
4731ad8061 | ||
|
|
7dc41e15d3 | ||
|
|
8326539d40 | ||
|
|
163e6e0f2a | ||
|
|
f56bb251e9 | ||
|
|
152ca99276 | ||
|
|
7c398d2c67 | ||
|
|
a526c942ca | ||
|
|
af8fd15929 | ||
|
|
7bfd5d4bc8 | ||
|
|
4382d5c56d | ||
|
|
f43b9c96de | ||
|
|
c64f72e394 | ||
|
|
3d54f832c5 | ||
|
|
867ba24c6c | ||
|
|
9715c5394c | ||
|
|
67b5c72520 | ||
|
|
43450f6cc7 | ||
|
|
a3737d4f35 | ||
|
|
3314e94a9a | ||
|
|
a27436b086 | ||
|
|
fe5554ffb1 | ||
|
|
f305f8d822 | ||
|
|
1f54bc41cc | ||
|
|
c82d028429 | ||
|
|
be2a8b7b07 | ||
|
|
261fc82016 | ||
|
|
37b940f3a5 | ||
|
|
0504e904a2 | ||
|
|
71bfdd9bfd | ||
|
|
c7305f6b06 |
No files matched your search
+28
-37
@@ -25,10 +25,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,20 +36,21 @@ 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:"
|
||||
@@ -131,23 +130,15 @@ listparents: >
|
||||
listparents-temp: >
|
||||
&b{0}'s Temporary Parent Groups:\n
|
||||
{1}
|
||||
listgroups: >
|
||||
&b{0}'s Groups:\n
|
||||
{1}
|
||||
listgroups-temp: >
|
||||
&b{0}'s Temporary Groups:\n
|
||||
{1}
|
||||
list-tracks: >
|
||||
&b{0}'s Tracks:\n
|
||||
{1}
|
||||
list-tracks-empty: "{0} 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 +146,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 +175,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 +205,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
|
||||
|
||||
+106
-141
@@ -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: "Произошла непредвиденная ошибка при чтении лога."
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
+11
-1
@@ -5,13 +5,23 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>3.1-SNAPSHOT</version>
|
||||
<version>3.2-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>
|
||||
|
||||
@@ -49,7 +49,7 @@ 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}.
|
||||
@@ -60,10 +60,12 @@ public final class LuckPerms {
|
||||
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,102 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a type of chat meta
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
public enum ChatMetaType {
|
||||
|
||||
/**
|
||||
* Represents a prefix
|
||||
*/
|
||||
PREFIX {
|
||||
@Override
|
||||
public boolean matches(Node node) {
|
||||
return node.isPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIgnore(Node node) {
|
||||
return !node.isPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map.Entry<Integer, String> getEntry(Node node) {
|
||||
return node.getPrefix();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Represents a suffix
|
||||
*/
|
||||
SUFFIX {
|
||||
@Override
|
||||
public boolean matches(Node node) {
|
||||
return node.isSuffix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIgnore(Node node) {
|
||||
return !node.isSuffix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map.Entry<Integer, String> getEntry(Node node) {
|
||||
return 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(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(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
|
||||
*/
|
||||
public abstract Map.Entry<Integer, String> getEntry(Node node);
|
||||
|
||||
}
|
||||
@@ -165,6 +165,7 @@ public class Contexts {
|
||||
return this.applyGlobalWorldGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Contexts(" +
|
||||
"context=" + this.getContexts() + ", " +
|
||||
@@ -181,18 +182,12 @@ 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 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,12 +196,7 @@ 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;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
|
||||
@@ -41,7 +42,7 @@ public interface Group extends PermissionHolder {
|
||||
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
|
||||
@@ -50,6 +51,26 @@ public interface Group extends PermissionHolder {
|
||||
*/
|
||||
boolean inheritsGroup(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(Group group, ContextSet contextSet);
|
||||
|
||||
/**
|
||||
* Gets the weight of this group, if present.
|
||||
*
|
||||
* @return the group weight
|
||||
* @since 2.17
|
||||
*/
|
||||
OptionalInt getWeight();
|
||||
|
||||
/**
|
||||
* Check to see if the group inherits a group on a specific server
|
||||
*
|
||||
@@ -59,7 +80,9 @@ 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsGroup(Group group, String server);
|
||||
|
||||
/**
|
||||
@@ -72,7 +95,9 @@ 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsGroup(Group group, String server, String world);
|
||||
|
||||
/**
|
||||
@@ -250,7 +275,9 @@ public interface Group extends PermissionHolder {
|
||||
* 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
|
||||
List<String> getGroupNames();
|
||||
|
||||
/**
|
||||
@@ -260,7 +287,9 @@ 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
|
||||
*/
|
||||
@Deprecated
|
||||
List<String> getLocalGroups(String server);
|
||||
|
||||
|
||||
@@ -272,15 +301,9 @@ 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
|
||||
*/
|
||||
@Deprecated
|
||||
List<String> getLocalGroups(String server, String world);
|
||||
|
||||
/**
|
||||
* Gets the weight of this group, is present.
|
||||
*
|
||||
* @return the group weight
|
||||
* @since 2.17
|
||||
*/
|
||||
OptionalInt getWeight();
|
||||
|
||||
}
|
||||
@@ -92,7 +92,7 @@ public class LogEntry implements Comparable<LogEntry> {
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
package me.lucko.luckperms.api;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ 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;
|
||||
@@ -42,6 +43,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets the API version
|
||||
*
|
||||
* @return the version of the API running on the platform
|
||||
* @since 2.6
|
||||
*/
|
||||
@@ -49,12 +51,14 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets the plugin version
|
||||
*
|
||||
* @return the version of the plugin running on the platform
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Gets the platform LuckPerms is running on
|
||||
*
|
||||
* @return the platform LuckPerms is running on
|
||||
* @since 2.7
|
||||
*/
|
||||
@@ -62,6 +66,7 @@ public interface LuckPermsApi {
|
||||
|
||||
/**
|
||||
* Gets the event bus, used for subscribing to events
|
||||
*
|
||||
* @return the event bus
|
||||
* @since 3.0
|
||||
*/
|
||||
@@ -247,6 +252,14 @@ public interface LuckPermsApi {
|
||||
*/
|
||||
NodeFactory getNodeFactory();
|
||||
|
||||
/**
|
||||
* Gets the MetaStackFactory, used for creating MetaStacks.
|
||||
*
|
||||
* @return the meta stack factory
|
||||
* @since 3.2
|
||||
*/
|
||||
MetaStackFactory getMetaStackFactory();
|
||||
|
||||
/**
|
||||
* Returns a permission builder instance
|
||||
*
|
||||
|
||||
@@ -40,12 +40,14 @@ import java.util.Set;
|
||||
public interface Node extends Map.Entry<String, Boolean> {
|
||||
|
||||
/**
|
||||
* Returns the actual permission string
|
||||
*
|
||||
* @return the actual permission node
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@@ -53,14 +55,22 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
Boolean getValue();
|
||||
|
||||
/**
|
||||
* Returns the value of this node as a tristate
|
||||
*
|
||||
* @return the value of this node as a Tristate
|
||||
*/
|
||||
Tristate getTristate();
|
||||
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.
|
||||
@@ -201,28 +211,40 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@@ -307,6 +329,8 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
Map.Entry<String, String> getMeta();
|
||||
|
||||
/**
|
||||
* Returns if this node is a prefix node
|
||||
*
|
||||
* @return true if this node is a prefix node
|
||||
*/
|
||||
boolean isPrefix();
|
||||
@@ -320,6 +344,8 @@ public interface Node extends Map.Entry<String, Boolean> {
|
||||
Map.Entry<Integer, String> getPrefix();
|
||||
|
||||
/**
|
||||
* Returns if this node is a suffix node
|
||||
*
|
||||
* @return true if this node is a suffix node
|
||||
*/
|
||||
boolean isSuffix();
|
||||
|
||||
@@ -36,7 +36,10 @@ 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()
|
||||
*/
|
||||
@Deprecated
|
||||
Node fromSerialisedNode(String serialisedPermission, boolean value);
|
||||
|
||||
|
||||
@@ -65,7 +68,10 @@ 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()
|
||||
*/
|
||||
@Deprecated
|
||||
Node.Builder newBuilderFromSerialisedNode(String serialisedPermission, boolean value);
|
||||
|
||||
|
||||
@@ -90,6 +96,17 @@ public interface NodeFactory {
|
||||
*/
|
||||
Node.Builder makeMetaNode(String key, 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
|
||||
*/
|
||||
Node.Builder makeChatMetaNode(ChatMetaType type, int priority, String value);
|
||||
|
||||
/**
|
||||
* Creates a node builder from a prefix string and priority
|
||||
*
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
|
||||
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.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An object capable of holding permissions
|
||||
@@ -46,6 +48,17 @@ public interface PermissionHolder {
|
||||
*/
|
||||
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
|
||||
*/
|
||||
String getFriendlyName();
|
||||
|
||||
/**
|
||||
* Gets a sorted set of all held permissions.
|
||||
*
|
||||
@@ -57,21 +70,39 @@ public interface PermissionHolder {
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
Set<? extends Node> getTransientPermissions();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Gets a mutable sorted set of the nodes that this object has and inherits, filtered by context
|
||||
*
|
||||
@@ -80,7 +111,7 @@ 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
|
||||
@@ -134,81 +165,6 @@ public interface PermissionHolder {
|
||||
*/
|
||||
Tristate hasTransientPermission(Node node);
|
||||
|
||||
/**
|
||||
* Checks to see if the object has a certain permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server, String world);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
* @param world The world to check on
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object has the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world is invalid
|
||||
*/
|
||||
boolean hasPermission(String node, boolean b, String server, String world, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a certain permission
|
||||
*
|
||||
@@ -219,81 +175,6 @@ public interface PermissionHolder {
|
||||
*/
|
||||
Tristate inheritsPermission(Node node);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a certain permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b);
|
||||
|
||||
/**
|
||||
* Checks to see the the object inherits a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node or server is null
|
||||
* @throws IllegalArgumentException if the node or server is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server);
|
||||
|
||||
/**
|
||||
* Checks to see the the object inherits a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node server or world is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server, String world);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node is null
|
||||
* @throws IllegalArgumentException if the node is invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param temporary if the permission is temporary
|
||||
* @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
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the object inherits the permission
|
||||
* @throws NullPointerException if the node, server or world is null
|
||||
* @throws IllegalArgumentException if the node, server or world if invalid
|
||||
*/
|
||||
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
|
||||
|
||||
/**
|
||||
* Sets a permission for the object
|
||||
*
|
||||
@@ -352,6 +233,286 @@ public interface PermissionHolder {
|
||||
*/
|
||||
DataMutateResult setTransientPermissionUnchecked(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(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);
|
||||
|
||||
/**
|
||||
* 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(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(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(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(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(ContextSet contextSet);
|
||||
|
||||
/**
|
||||
* Clears all transient permissions the holder has.
|
||||
*/
|
||||
void clearTransientNodes();
|
||||
|
||||
/**
|
||||
* Checks to see if the object has a certain permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasPermission(String node, boolean b);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasPermission(String node, boolean b, String server);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasPermission(String node, boolean b, String server, String world);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasPermission(String node, boolean b, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasPermission(String node, boolean b, String server, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see the the object has a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server to check on
|
||||
* @param world The world to check on
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
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 permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsPermission(String node, boolean b);
|
||||
|
||||
/**
|
||||
* Checks to see the the object inherits a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsPermission(String node, boolean b, String server);
|
||||
|
||||
/**
|
||||
* Checks to see the the object inherits a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsPermission(String node, boolean b, String server, String world);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsPermission(String node, boolean b, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission on a certain server
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param temporary if the permission is temporary
|
||||
* @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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsPermission(String node, boolean b, String server, boolean temporary);
|
||||
|
||||
/**
|
||||
* Checks to see if the object inherits a permission on a certain server and world
|
||||
*
|
||||
* @param node The permission node
|
||||
* @param b If the node is true/false(negated)
|
||||
* @param server The server
|
||||
* @param world The world
|
||||
* @param temporary if the permission is temporary
|
||||
* @return true if the 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
|
||||
|
||||
/**
|
||||
* Sets a permission for the object
|
||||
*
|
||||
@@ -439,46 +600,6 @@ public interface PermissionHolder {
|
||||
@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);
|
||||
|
||||
/**
|
||||
* Unsets a permission for the object
|
||||
*
|
||||
@@ -560,19 +681,14 @@ public interface PermissionHolder {
|
||||
@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();
|
||||
|
||||
/**
|
||||
* 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
void clearNodes(String server);
|
||||
|
||||
/**
|
||||
@@ -581,22 +697,19 @@ 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
void clearNodes(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all parent groups
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearParents();
|
||||
|
||||
/**
|
||||
* 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
void clearParents(String server);
|
||||
|
||||
/**
|
||||
@@ -605,22 +718,19 @@ 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
void clearParents(String server, String world);
|
||||
|
||||
/**
|
||||
* Clears all meta held by the object
|
||||
*
|
||||
* @since 2.17
|
||||
*/
|
||||
void clearMeta();
|
||||
|
||||
/**
|
||||
* 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
void clearMeta(String server);
|
||||
|
||||
/**
|
||||
@@ -629,7 +739,9 @@ 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
void clearMeta(String server, String world);
|
||||
|
||||
/**
|
||||
@@ -639,28 +751,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 #removeIf(Predicate)}
|
||||
*/
|
||||
@Deprecated
|
||||
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();
|
||||
|
||||
}
|
||||
@@ -93,13 +93,23 @@ public interface Storage {
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
default CompletableFuture<Boolean> loadUser(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.
|
||||
*
|
||||
|
||||
@@ -25,8 +25,8 @@ package me.lucko.luckperms.api;
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
|
||||
@@ -23,6 +23,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;
|
||||
|
||||
@@ -43,21 +44,24 @@ public interface User extends PermissionHolder {
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
@@ -69,35 +73,59 @@ public interface User extends PermissionHolder {
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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(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(Group group, 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
|
||||
Optional<UserData> getUserDataCache();
|
||||
|
||||
/**
|
||||
* Sets up the users data cache, if the don't have one setup already.
|
||||
*
|
||||
* @since 2.17
|
||||
* @deprecated in version 3.2, as this cache is now always loaded.
|
||||
*/
|
||||
@Deprecated
|
||||
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,7 +134,9 @@ 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isInGroup(Group group, String server);
|
||||
|
||||
/**
|
||||
@@ -118,7 +148,9 @@ 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isInGroup(Group group, String server, String world);
|
||||
|
||||
/**
|
||||
@@ -296,7 +328,9 @@ public interface User extends PermissionHolder {
|
||||
* 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
|
||||
List<String> getGroupNames();
|
||||
|
||||
/**
|
||||
@@ -307,7 +341,9 @@ 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
|
||||
*/
|
||||
@Deprecated
|
||||
List<String> getLocalGroups(String server, String world);
|
||||
|
||||
/**
|
||||
@@ -317,7 +353,9 @@ 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
|
||||
*/
|
||||
@Deprecated
|
||||
List<String> getLocalGroups(String server);
|
||||
|
||||
}
|
||||
@@ -30,10 +30,10 @@ import java.util.UUID;
|
||||
* <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>
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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(Contexts contexts, MetaStackDefinition prefixStackDefinition, 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(Contexts contexts, MetaStackDefinition prefixStackDefinition, MetaStackDefinition suffixStackDefinition) {
|
||||
this.contexts = Preconditions.checkNotNull(contexts, "contexts");
|
||||
this.prefixStackDefinition = Preconditions.checkNotNull(prefixStackDefinition, "prefixStackDefinition");
|
||||
this.suffixStackDefinition = Preconditions.checkNotNull(suffixStackDefinition, "suffixStackDefinition");
|
||||
}
|
||||
|
||||
public Contexts getContexts() {
|
||||
return this.contexts;
|
||||
}
|
||||
|
||||
public MetaStackDefinition getPrefixStackDefinition() {
|
||||
return this.prefixStackDefinition;
|
||||
}
|
||||
|
||||
public MetaStackDefinition getSuffixStackDefinition() {
|
||||
return this.suffixStackDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
package me.lucko.luckperms.api.caching;
|
||||
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
|
||||
@@ -69,4 +71,20 @@ public interface MetaData {
|
||||
*/
|
||||
String getSuffix();
|
||||
|
||||
/**
|
||||
* Gets the definition used for the prefix stack
|
||||
*
|
||||
* @return the definition used for the prefix stack
|
||||
* @since 3.2
|
||||
*/
|
||||
MetaStackDefinition getPrefixStackDefinition();
|
||||
|
||||
/**
|
||||
* Gets the definition used for the suffix stack
|
||||
*
|
||||
* @return the definition used for the suffix stack
|
||||
* @since 3.2
|
||||
*/
|
||||
MetaStackDefinition getSuffixStackDefinition();
|
||||
|
||||
}
|
||||
@@ -32,6 +32,10 @@ import java.util.Set;
|
||||
* <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 {
|
||||
@@ -47,6 +51,18 @@ public interface UserData {
|
||||
*/
|
||||
PermissionData getPermissionData(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
|
||||
*/
|
||||
MetaData getMetaData(MetaContexts contexts);
|
||||
|
||||
/**
|
||||
* Gets MetaData from the cache, given a specified context.
|
||||
*
|
||||
@@ -67,6 +83,16 @@ public interface UserData {
|
||||
*/
|
||||
PermissionData calculatePermissions(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
|
||||
*/
|
||||
MetaData calculateMeta(MetaContexts contexts);
|
||||
|
||||
/**
|
||||
* Calculates meta data, bypassing the cache.
|
||||
*
|
||||
@@ -87,6 +113,18 @@ public interface UserData {
|
||||
*/
|
||||
void recalculatePermissions(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(MetaContexts contexts);
|
||||
|
||||
/**
|
||||
* Calculates meta data and stores it in the cache.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
List<MetaStackElement> getElements();
|
||||
|
||||
/**
|
||||
* Gets the spacer string added before any stack elements
|
||||
*
|
||||
* @return the start spacer
|
||||
*/
|
||||
String getStartSpacer();
|
||||
|
||||
/**
|
||||
* Gets the spacer added between stack elements
|
||||
*
|
||||
* @return the middle spacer
|
||||
*/
|
||||
String getMiddleSpacer();
|
||||
|
||||
/**
|
||||
* Gets the spacer added after any stack elements
|
||||
*
|
||||
* @return the end spacer
|
||||
*/
|
||||
String getEndSpacer();
|
||||
|
||||
}
|
||||
+26
-15
@@ -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,23 +23,31 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.utils;
|
||||
package me.lucko.luckperms.api.metastacking;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
|
||||
import me.lucko.luckperms.common.core.model.Group;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class WeightComparator implements Comparator<Map.Entry<Integer, ? extends Group>> {
|
||||
public static final WeightComparator INSTANCE = new WeightComparator();
|
||||
/**
|
||||
* 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(LocalizedNode node, ChatMetaType type, Map.Entry<Integer, String> current);
|
||||
|
||||
@Override
|
||||
public int compare(Map.Entry<Integer, ? extends Group> o1, Map.Entry<Integer, ? extends Group> o2) {
|
||||
int result = Integer.compare(o1.getKey(), o2.getKey());
|
||||
return result != 0 ? result : 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
Optional<MetaStackElement> fromString(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
|
||||
*/
|
||||
List<MetaStackElement> fromStrings(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
|
||||
*/
|
||||
MetaStackDefinition createDefinition(List<MetaStackElement> elements, String startSpacer, String middleSpacer, String endSpacer);
|
||||
|
||||
}
|
||||
+3
-11
@@ -5,23 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>3.1-SNAPSHOT</version>
|
||||
<version>3.2-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>
|
||||
|
||||
+34
-13
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>3.1-SNAPSHOT</version>
|
||||
<version>3.2-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>
|
||||
@@ -79,6 +71,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 +99,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 +129,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,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
|
||||
@@ -49,23 +52,34 @@ public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
|
||||
|
||||
@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.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());
|
||||
}
|
||||
processors.add(new DefaultsProcessor(contexts.isOp(), plugin.getDefaultsProvider()));
|
||||
|
||||
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
|
||||
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()));
|
||||
}
|
||||
}
|
||||
@@ -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,7 +29,6 @@ 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;
|
||||
@@ -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,6 +63,14 @@ 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) */
|
||||
|
||||
/* 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();
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
@@ -68,7 +79,7 @@ public class BukkitListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
@@ -93,7 +104,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();
|
||||
|
||||
@@ -142,7 +153,7 @@ public class BukkitListener implements Listener {
|
||||
}
|
||||
|
||||
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 +181,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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -39,7 +42,6 @@ import me.lucko.luckperms.bukkit.model.LPPermissible;
|
||||
import me.lucko.luckperms.bukkit.vault.VaultHook;
|
||||
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.caching.handlers.CachedStateManager;
|
||||
import me.lucko.luckperms.common.calculators.CalculatorFactory;
|
||||
import me.lucko.luckperms.common.commands.sender.Sender;
|
||||
@@ -74,8 +76,8 @@ 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.SenderLogger;
|
||||
import me.lucko.luckperms.common.verbose.VerboseHandler;
|
||||
|
||||
import org.bukkit.World;
|
||||
@@ -99,6 +101,7 @@ 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
|
||||
@@ -127,6 +130,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,13 +141,24 @@ 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(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() {
|
||||
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
|
||||
|
||||
ignoringLogs = ConcurrentHashMap.newKeySet();
|
||||
@@ -163,7 +178,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();
|
||||
|
||||
@@ -183,7 +198,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
|
||||
fileWatcher = new FileWatcher(this);
|
||||
getScheduler().doAsyncRepeating(fileWatcher, 30L);
|
||||
getScheduler().asyncRepeating(fileWatcher, 30L);
|
||||
}
|
||||
|
||||
// initialise datastore
|
||||
@@ -259,7 +274,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
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...");
|
||||
@@ -273,7 +289,10 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
contextManager = new ContextManager<>();
|
||||
worldCalculator = new WorldCalculator(this);
|
||||
contextManager.registerCalculator(worldCalculator);
|
||||
contextManager.registerCalculator(new StaticCalculator<>(getConfiguration()));
|
||||
|
||||
StaticCalculator<Player> staticCalculator = new StaticCalculator<>(getConfiguration());
|
||||
contextManager.registerCalculator(staticCalculator);
|
||||
contextManager.registerStaticCalculator(staticCalculator);
|
||||
|
||||
// Provide vault support
|
||||
tryVaultHook(false);
|
||||
@@ -289,16 +308,16 @@ 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.
|
||||
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 +336,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,7 +351,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
});
|
||||
}
|
||||
|
||||
started = true;
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
|
||||
@@ -353,7 +371,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
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);
|
||||
@@ -415,17 +433,17 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
||||
|
||||
public void tryVaultHook(boolean force) {
|
||||
if (vaultHook != null) {
|
||||
return;
|
||||
return; // already hooked
|
||||
}
|
||||
|
||||
getLog().info("Attempting to hook with Vault...");
|
||||
if (force) {
|
||||
getLog().info("Attempting to hook with Vault...");
|
||||
}
|
||||
try {
|
||||
if (force || getServer().getPluginManager().isPluginEnabled("Vault")) {
|
||||
vaultHook = new VaultHook();
|
||||
vaultHook.hook(this);
|
||||
getLog().info("Registered Vault permission & chat hook.");
|
||||
} else {
|
||||
getLog().info("Vault not found.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
vaultHook = null;
|
||||
@@ -455,12 +473,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) {}
|
||||
@@ -565,7 +578,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 +593,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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,8 +27,6 @@ package me.lucko.luckperms.bukkit;
|
||||
|
||||
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
|
||||
@@ -24,6 +27,8 @@ package me.lucko.luckperms.bukkit.calculators;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.bukkit.model.ChildPermissionProvider;
|
||||
import me.lucko.luckperms.common.calculators.PermissionProcessor;
|
||||
@@ -46,7 +51,7 @@ public class ChildProcessor implements PermissionProcessor {
|
||||
public void updateBacking(Map<String, Boolean> map) {
|
||||
childPermissions.clear();
|
||||
for (Map.Entry<String, Boolean> e : map.entrySet()) {
|
||||
Map<String, Boolean> children = provider.getPermissions().get(e);
|
||||
Map<String, Boolean> children = provider.getPermissions().get(Maps.immutableEntry(e.getKey(), e.getValue()));
|
||||
if (children != null) {
|
||||
childPermissions.putAll(children);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+4
-1
@@ -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
|
||||
|
||||
+4
-1
@@ -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,6 +32,7 @@ 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;
|
||||
@@ -169,7 +173,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 +225,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;
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -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.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.event.cause.CreationCause;
|
||||
import me.lucko.luckperms.common.commands.Arg;
|
||||
@@ -169,7 +173,8 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
if (key.equals("prefix") || key.equals("suffix")) {
|
||||
groups.get(groupName).add(NodeFactory.makeChatMetaNode(key.equals("prefix"), 50, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
|
||||
groups.get(groupName).add(NodeFactory.makeChatMetaNode(type, 50, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||
} else {
|
||||
groups.get(groupName).add(NodeFactory.makeMetaNode(key, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||
}
|
||||
@@ -225,7 +230,8 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
if (key.equals("prefix") || key.equals("suffix")) {
|
||||
users.get(uuid).add(NodeFactory.makeChatMetaNode(key.equals("prefix"), 100, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
|
||||
users.get(uuid).add(NodeFactory.makeChatMetaNode(type, 100, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||
} else {
|
||||
users.get(uuid).add(NodeFactory.makeMetaNode(key, value).setWorld(worldMappingFunc.apply(world)).build());
|
||||
}
|
||||
@@ -258,7 +264,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
for (Map.Entry<UUID, Set<Node>> e : users.entrySet()) {
|
||||
plugin.getStorage().loadUser(e.getKey(), "null").join();
|
||||
me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(e.getKey());
|
||||
me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().getIfLoaded(e.getKey());
|
||||
|
||||
for (Node node : e.getValue()) {
|
||||
user.setPermission(node);
|
||||
|
||||
+5
-2
@@ -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
|
||||
@@ -188,7 +191,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
|
||||
}
|
||||
|
||||
plugin.getStorage().loadUser(u, user.getName()).join();
|
||||
User lpUser = plugin.getUserManager().get(u);
|
||||
User lpUser = plugin.getUserManager().getIfLoaded(u);
|
||||
|
||||
try {
|
||||
for (String node : user.getOwnPermissions(null)) {
|
||||
|
||||
+5
-2
@@ -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
|
||||
@@ -227,7 +230,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
|
||||
|
||||
// Create a LuckPerms user for the UUID
|
||||
plugin.getStorage().loadUser(uuid, "null").join();
|
||||
User user = plugin.getUserManager().get(uuid);
|
||||
User user = plugin.getUserManager().getIfLoaded(uuid);
|
||||
|
||||
List<Permission> permissions = joinFuture(pm.getPlayerOwnPermissions(uuid));
|
||||
|
||||
|
||||
+68
-24
@@ -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.bukkit.migration;
|
||||
|
||||
import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
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.commands.utils.Util;
|
||||
import me.lucko.luckperms.common.constants.Permission;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.model.Group;
|
||||
@@ -43,12 +49,15 @@ import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.dao.PermissionService;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.EntityMetadata;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Entry;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Inheritance;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.Membership;
|
||||
import org.tyrannyofheaven.bukkit.zPermissions.model.PermissionEntity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -89,15 +98,37 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
||||
|
||||
// Migrate all groups
|
||||
log.log("Starting group migration.");
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
for (String g : service.getAllGroups()) {
|
||||
String groupName = MigrationUtils.standardizeName(g);
|
||||
|
||||
Map<UUID, Set<Node>> userParents = new HashMap<>();
|
||||
|
||||
AtomicInteger groupCount = new AtomicInteger(0);
|
||||
int maxWeight = 0;
|
||||
for (PermissionEntity entity : internalService.getEntities(true)) {
|
||||
String groupName = MigrationUtils.standardizeName(entity.getDisplayName());
|
||||
plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join();
|
||||
Group group = plugin.getGroupManager().getIfLoaded(groupName);
|
||||
|
||||
PermissionEntity entity = internalService.getEntity(g, null, true);
|
||||
migrateEntity(group, entity, null);
|
||||
int weight = entity.getPriority();
|
||||
maxWeight = Math.max(maxWeight, weight);
|
||||
migrateEntity(group, entity, weight);
|
||||
MigrationUtils.setGroupWeight(group, weight);
|
||||
|
||||
// store user data for later
|
||||
Set<Membership> members = entity.getMemberships();
|
||||
for (Membership membership : members) {
|
||||
UUID uuid = Util.parseUuid(membership.getMember());
|
||||
if (uuid == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<Node> nodes = userParents.computeIfAbsent(uuid, u -> new HashSet<>());
|
||||
if (membership.getExpiration() == null) {
|
||||
nodes.add(NodeFactory.make("group." + groupName));
|
||||
} else {
|
||||
long expiry = membership.getExpiration().toInstant().getEpochSecond();
|
||||
nodes.add(NodeFactory.newBuilder("group." + groupName).setExpiry(expiry).build());
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getStorage().saveGroup(group);
|
||||
log.logAllProgress("Migrated {} groups so far.", groupCount.incrementAndGet());
|
||||
@@ -121,17 +152,34 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
||||
|
||||
// Migrate all users.
|
||||
log.log("Starting user migration.");
|
||||
maxWeight += 10;
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
for (UUID u : service.getAllPlayersUUID()) {
|
||||
|
||||
Set<UUID> usersToMigrate = new HashSet<>(userParents.keySet());
|
||||
usersToMigrate.addAll(service.getAllPlayersUUID());
|
||||
|
||||
for (UUID u : usersToMigrate) {
|
||||
PermissionEntity entity = internalService.getEntity(null, u, false);
|
||||
|
||||
String username = null;
|
||||
if (!entity.isGroup()) {
|
||||
if (entity != null) {
|
||||
username = entity.getDisplayName();
|
||||
}
|
||||
|
||||
plugin.getStorage().loadUser(u, username).join();
|
||||
User user = plugin.getUserManager().get(u);
|
||||
migrateEntity(user, entity, internalService.getGroups(u));
|
||||
User user = plugin.getUserManager().getIfLoaded(u);
|
||||
|
||||
// migrate permissions & meta
|
||||
if (entity != null) {
|
||||
migrateEntity(user, entity, maxWeight);
|
||||
}
|
||||
|
||||
// migrate groups
|
||||
Set<Node> parents = userParents.get(u);
|
||||
if (parents != null) {
|
||||
parents.forEach(user::setPermission);
|
||||
}
|
||||
|
||||
user.getPrimaryGroup().setStoredValue(MigrationUtils.standardizeName(service.getPlayerPrimaryGroup(u)));
|
||||
|
||||
plugin.getUserManager().cleanup(user);
|
||||
@@ -144,34 +192,30 @@ public class MigrationZPermissions extends SubCommand<Object> {
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
||||
private void migrateEntity(PermissionHolder holder, PermissionEntity entity, List<Membership> memberships) {
|
||||
private void migrateEntity(PermissionHolder holder, PermissionEntity entity, int weight) {
|
||||
for (Entry e : entity.getPermissions()) {
|
||||
if (e.getWorld() != null && !e.getWorld().getName().equals("")) {
|
||||
holder.setPermission(MigrationUtils.parseNode(e.getPermission(), true).setWorld(e.getWorld().getName()).build());
|
||||
holder.setPermission(NodeFactory.newBuilder(e.getPermission()).setValue(e.isValue()).setWorld(e.getWorld().getName()).build());
|
||||
} else {
|
||||
holder.setPermission(MigrationUtils.parseNode(e.getPermission(), true).build());
|
||||
holder.setPermission(NodeFactory.newBuilder(e.getPermission()).setValue(e.isValue()).build());
|
||||
}
|
||||
}
|
||||
|
||||
// only migrate inheritances for groups
|
||||
if (entity.isGroup()) {
|
||||
// entity.getMemberships() doesn't work for groups (always returns 0 records)
|
||||
for (Inheritance inheritance : entity.getInheritancesAsChild()) {
|
||||
if (!inheritance.getParent().getName().equals(holder.getObjectName())) {
|
||||
holder.setPermission(NodeFactory.make("group." + MigrationUtils.standardizeName(inheritance.getParent().getName())));
|
||||
for (PermissionEntity inheritance : entity.getParents()) {
|
||||
if (!inheritance.getDisplayName().equals(holder.getObjectName())) {
|
||||
holder.setPermission(NodeFactory.make("group." + MigrationUtils.standardizeName(inheritance.getDisplayName())));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Membership membership : memberships) {
|
||||
holder.setPermission(NodeFactory.make("group." + MigrationUtils.standardizeName(membership.getGroup().getDisplayName())));
|
||||
}
|
||||
}
|
||||
|
||||
int weight = entity.isGroup() ? 50 : 100;
|
||||
for (EntityMetadata metadata : entity.getMetadata()) {
|
||||
String key = metadata.getName().toLowerCase();
|
||||
|
||||
if (key.equals("prefix") || key.equals("suffix")) {
|
||||
holder.setPermission(NodeFactory.makeChatMetaNode(key.equals("prefix"), weight, metadata.getStringValue()).build());
|
||||
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
|
||||
holder.setPermission(NodeFactory.makeChatMetaNode(type, weight, metadata.getStringValue()).build());
|
||||
} else {
|
||||
holder.setPermission(NodeFactory.makeMetaNode(key, metadata.getStringValue()).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
|
||||
|
||||
@@ -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
|
||||
@@ -24,7 +27,8 @@ package me.lucko.luckperms.bukkit.model;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import me.lucko.luckperms.bukkit.compat.ReflectionUtil;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
@@ -43,32 +47,46 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class Injector {
|
||||
private static final Map<UUID, LPPermissible> INJECTED_PERMISSIBLES = new ConcurrentHashMap<>();
|
||||
|
||||
private static Field HUMAN_ENTITY_FIELD;
|
||||
private static Field PERMISSIBLEBASE_ATTACHMENTS;
|
||||
private static Field humanEntityField;
|
||||
private static Field permissibleAttachmentsField;
|
||||
private static Throwable cachedThrowable = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
HUMAN_ENTITY_FIELD = Class.forName(getVersionedClassName("entity.CraftHumanEntity")).getDeclaredField("perm");
|
||||
HUMAN_ENTITY_FIELD.setAccessible(true);
|
||||
try {
|
||||
// craftbukkit
|
||||
humanEntityField = ReflectionUtil.obcClass("entity.CraftHumanEntity").getDeclaredField("perm");
|
||||
humanEntityField.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
// glowstone
|
||||
humanEntityField = Class.forName("net.glowstone.entity.GlowHumanEntity").getDeclaredField("permissions");
|
||||
humanEntityField.setAccessible(true);
|
||||
}
|
||||
|
||||
PERMISSIBLEBASE_ATTACHMENTS = PermissibleBase.class.getDeclaredField("attachments");
|
||||
PERMISSIBLEBASE_ATTACHMENTS.setAccessible(true);
|
||||
permissibleAttachmentsField = PermissibleBase.class.getDeclaredField("attachments");
|
||||
permissibleAttachmentsField.setAccessible(true);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (Throwable t) {
|
||||
cachedThrowable = t;
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean inject(Player player, LPPermissible lpPermissible) {
|
||||
if (cachedThrowable != null) {
|
||||
cachedThrowable.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
PermissibleBase existing = (PermissibleBase) HUMAN_ENTITY_FIELD.get(player);
|
||||
PermissibleBase existing = (PermissibleBase) humanEntityField.get(player);
|
||||
if (existing instanceof LPPermissible) {
|
||||
// uh oh
|
||||
throw new IllegalStateException("LPPermissible already injected into player " + player.toString());
|
||||
}
|
||||
|
||||
// Move attachments over from the old permissible.
|
||||
List<PermissionAttachment> attachments = (List<PermissionAttachment>) PERMISSIBLEBASE_ATTACHMENTS.get(existing);
|
||||
List<PermissionAttachment> attachments = (List<PermissionAttachment>) permissibleAttachmentsField.get(existing);
|
||||
lpPermissible.addAttachments(attachments);
|
||||
attachments.clear();
|
||||
existing.clearPermissions();
|
||||
@@ -79,7 +97,7 @@ public class Injector {
|
||||
|
||||
lpPermissible.updateSubscriptionsAsync();
|
||||
|
||||
HUMAN_ENTITY_FIELD.set(player, lpPermissible);
|
||||
humanEntityField.set(player, lpPermissible);
|
||||
INJECTED_PERMISSIBLES.put(player.getUniqueId(), lpPermissible);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
@@ -89,8 +107,13 @@ public class Injector {
|
||||
}
|
||||
|
||||
public static boolean unInject(Player player, boolean dummy, boolean unsubscribe) {
|
||||
if (cachedThrowable != null) {
|
||||
cachedThrowable.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
PermissibleBase permissible = (PermissibleBase) HUMAN_ENTITY_FIELD.get(player);
|
||||
PermissibleBase permissible = (PermissibleBase) humanEntityField.get(player);
|
||||
if (permissible instanceof LPPermissible) {
|
||||
|
||||
permissible.clearPermissions();
|
||||
@@ -102,7 +125,7 @@ public class Injector {
|
||||
((LPPermissible) permissible).getActive().set(false);
|
||||
|
||||
if (dummy) {
|
||||
HUMAN_ENTITY_FIELD.set(player, new DummyPermissibleBase());
|
||||
humanEntityField.set(player, new DummyPermissibleBase());
|
||||
} else {
|
||||
LPPermissible lpp = ((LPPermissible) permissible);
|
||||
List<PermissionAttachment> attachments = lpp.getAttachments();
|
||||
@@ -112,11 +135,11 @@ public class Injector {
|
||||
newPb = new PermissibleBase(player);
|
||||
}
|
||||
|
||||
List<PermissionAttachment> newAttachments = (List<PermissionAttachment>) PERMISSIBLEBASE_ATTACHMENTS.get(newPb);
|
||||
List<PermissionAttachment> newAttachments = (List<PermissionAttachment>) permissibleAttachmentsField.get(newPb);
|
||||
newAttachments.addAll(attachments);
|
||||
attachments.clear();
|
||||
|
||||
HUMAN_ENTITY_FIELD.set(player, newPb);
|
||||
humanEntityField.set(player, newPb);
|
||||
}
|
||||
}
|
||||
INJECTED_PERMISSIBLES.remove(player.getUniqueId());
|
||||
@@ -131,22 +154,4 @@ public class Injector {
|
||||
return INJECTED_PERMISSIBLES.get(uuid);
|
||||
}
|
||||
|
||||
private static String getVersionedClassName(String className) {
|
||||
Class server = Bukkit.getServer().getClass();
|
||||
if (!server.getSimpleName().equals("CraftServer")) {
|
||||
throw new RuntimeException("Couldn't inject into server " + server);
|
||||
}
|
||||
|
||||
String version;
|
||||
if (server.getName().equals("org.bukkit.craftbukkit.CraftServer")) {
|
||||
// Non versioned class
|
||||
version = ".";
|
||||
} else {
|
||||
version = server.getName().substring("org.bukkit.craftbukkit".length());
|
||||
version = version.substring(0, version.length() - "CraftServer".length());
|
||||
}
|
||||
|
||||
return "org.bukkit.craftbukkit" + version + className;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -73,7 +76,7 @@ public class LPPermissible extends PermissibleBase {
|
||||
private final Map<String, PermissionAttachmentInfo> attachmentPermissions = new ConcurrentHashMap<>();
|
||||
private final List<PermissionAttachment> attachments = Collections.synchronizedList(new LinkedList<>());
|
||||
|
||||
public LPPermissible(@NonNull Player parent, User user, LPBukkitPlugin plugin) {
|
||||
public LPPermissible(@NonNull Player parent, @NonNull User user, @NonNull LPBukkitPlugin plugin) {
|
||||
super(parent);
|
||||
this.user = user;
|
||||
this.parent = parent;
|
||||
@@ -136,10 +139,6 @@ public class LPPermissible extends PermissibleBase {
|
||||
);
|
||||
}
|
||||
|
||||
private boolean hasData() {
|
||||
return user != null && user.getUserData() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOp(boolean value) {
|
||||
parent.setOp(value);
|
||||
@@ -147,7 +146,7 @@ public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(@NonNull String name) {
|
||||
return hasData() && user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(name) != Tristate.UNDEFINED;
|
||||
return user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(name) != Tristate.UNDEFINED;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,11 +156,9 @@ public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull String name) {
|
||||
if (hasData()) {
|
||||
Tristate ts = user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(name);
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
Tristate ts = user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(name);
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
|
||||
return Permission.DEFAULT_PERMISSION.getValue(isOp());
|
||||
@@ -169,11 +166,9 @@ public class LPPermissible extends PermissibleBase {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull Permission perm) {
|
||||
if (hasData()) {
|
||||
Tristate ts = user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(perm.getName());
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
Tristate ts = user.getUserData().getPermissionData(calculateContexts()).getPermissionValue(perm.getName());
|
||||
if (ts != Tristate.UNDEFINED) {
|
||||
return ts.asBoolean();
|
||||
}
|
||||
|
||||
return perm.getDefault().getValue(isOp());
|
||||
@@ -184,13 +179,11 @@ public class LPPermissible extends PermissibleBase {
|
||||
Set<PermissionAttachmentInfo> perms = new HashSet<>();
|
||||
perms.addAll(attachmentPermissions.values());
|
||||
|
||||
if (hasData()) {
|
||||
perms.addAll(
|
||||
user.getUserData().getPermissionData(calculateContexts()).getImmutableBacking().entrySet().stream()
|
||||
.map(e -> new PermissionAttachmentInfo(parent, e.getKey(), null, e.getValue()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
perms.addAll(
|
||||
user.getUserData().getPermissionData(calculateContexts()).getImmutableBacking().entrySet().stream()
|
||||
.map(e -> new PermissionAttachmentInfo(parent, e.getKey(), null, e.getValue()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
return perms;
|
||||
}
|
||||
@@ -285,7 +278,7 @@ public class LPPermissible extends PermissibleBase {
|
||||
calculateChildPermissions(attachment.getPermissions(), false, attachment);
|
||||
}
|
||||
|
||||
if (hasData() && invalidate) {
|
||||
if (invalidate) {
|
||||
user.getUserData().invalidatePermissionCalculators();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -24,10 +27,10 @@ package me.lucko.luckperms.bukkit.vault;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.caching.MetaAccumulator;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.model.Group;
|
||||
@@ -37,12 +40,8 @@ import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
|
||||
import net.milkbowl.vault.chat.Chat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static me.lucko.luckperms.api.MetaUtils.escapeCharacters;
|
||||
import static me.lucko.luckperms.api.MetaUtils.unescapeCharacters;
|
||||
|
||||
/**
|
||||
* LuckPerms Vault Chat implementation
|
||||
* All user lookups are cached.
|
||||
@@ -65,8 +64,7 @@ public class VaultChatHook extends Chat {
|
||||
|
||||
private void setMeta(PermissionHolder holder, String world, String node, String value) {
|
||||
String finalWorld = perms.isIgnoreWorld() ? null : world;
|
||||
if (holder == null) return;
|
||||
if (node.equals("")) return;
|
||||
if (holder == null || node.equals("")) return;
|
||||
|
||||
perms.log("Setting meta: '" + node + "' for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
@@ -86,24 +84,23 @@ public class VaultChatHook extends Chat {
|
||||
});
|
||||
}
|
||||
|
||||
private void setChatMeta(boolean prefix, PermissionHolder holder, String value, String world) {
|
||||
private void setChatMeta(ChatMetaType type, PermissionHolder holder, String value, String world) {
|
||||
String finalWorld = perms.isIgnoreWorld() ? null : world;
|
||||
if (holder == null) return;
|
||||
if (value.equals("")) return;
|
||||
|
||||
perms.log("Setting " + (prefix ? "prefix" : "suffix") + " for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
perms.log("Setting " + type.name().toLowerCase() + " for " + holder.getObjectName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
perms.getScheduler().execute(() -> {
|
||||
|
||||
// remove all prefixes/suffixes directly set on the user/group
|
||||
holder.removeIf(n -> prefix ? n.isPrefix() : n.isSuffix());
|
||||
holder.removeIf(type::matches);
|
||||
|
||||
// find the max inherited priority & add 10
|
||||
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, ExtractedContexts.generate(perms.createContextForWorld(finalWorld)));
|
||||
int priority = (prefix ? metaAccumulator.getPrefixes() : metaAccumulator.getSuffixes()).keySet().stream()
|
||||
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, null, ExtractedContexts.generate(perms.createContextForWorldSet(finalWorld)));
|
||||
int priority = (type == ChatMetaType.PREFIX ? metaAccumulator.getPrefixes() : metaAccumulator.getSuffixes()).keySet().stream()
|
||||
.mapToInt(e -> e).max().orElse(0) + 10;
|
||||
|
||||
Node.Builder chatMetaNode = NodeFactory.makeChatMetaNode(prefix, priority, value);
|
||||
Node.Builder chatMetaNode = NodeFactory.makeChatMetaNode(type, priority, value);
|
||||
if (!perms.getServer().equalsIgnoreCase("global")) {
|
||||
chatMetaNode.setServer(perms.getServer());
|
||||
}
|
||||
@@ -119,138 +116,115 @@ public class VaultChatHook extends Chat {
|
||||
private String getUserMeta(User user, String world, String node, String defaultValue) {
|
||||
if (user == null) return defaultValue;
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
node = escapeCharacters(node);
|
||||
|
||||
perms.log("Getting meta: '" + node + "' for user " + user.getName() + " on world " + world + ", server " + perms.getServer());
|
||||
perms.log("Getting meta: '" + node + "' for user " + user.getFriendlyName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
if (user.getUserData() == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
String ret = user.getUserData().getMetaData(perms.createContextForWorld(world)).getMeta().get(node);
|
||||
if (ret == null) {
|
||||
return defaultValue;
|
||||
} else {
|
||||
return unescapeCharacters(ret);
|
||||
}
|
||||
String ret = user.getUserData().getMetaData(perms.createContextForWorldLookup(perms.getPlugin().getPlayer(user), world)).getMeta().get(node);
|
||||
return ret != null ? ret : defaultValue;
|
||||
}
|
||||
|
||||
private String getUserChatMeta(boolean prefix, User user, String world) {
|
||||
private String getUserChatMeta(ChatMetaType type, User user, String world) {
|
||||
if (user == null) return "";
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
|
||||
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for user " + user.getName() + " on world " + world + ", server " + perms.getServer());
|
||||
perms.log("Getting " + type.name().toLowerCase() + " for user " + user.getFriendlyName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
if (user.getUserData() == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
MetaData data = user.getUserData().getMetaData(perms.createContextForWorld(world));
|
||||
String v = prefix ? data.getPrefix() : data.getSuffix();
|
||||
return v == null ? "" : unescapeCharacters(v);
|
||||
MetaData data = user.getUserData().getMetaData(perms.createContextForWorldLookup(perms.getPlugin().getPlayer(user), world));
|
||||
String ret = type == ChatMetaType.PREFIX ? data.getPrefix() : data.getSuffix();
|
||||
return ret != null ? ret : "";
|
||||
}
|
||||
|
||||
private String getGroupMeta(Group group, String world, String node, String defaultValue) {
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
if (group == null) return defaultValue;
|
||||
if (node.equals("")) return defaultValue;
|
||||
node = escapeCharacters(node);
|
||||
if (group == null || node.equals("")) return defaultValue;
|
||||
|
||||
perms.log("Getting meta: '" + node + "' for group " + group.getName() + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
for (Node n : group.mergePermissionsToList()) {
|
||||
if (!n.getValue()) continue;
|
||||
if (!n.isMeta()) continue;
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) continue;
|
||||
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) continue;
|
||||
if (!n.shouldApplyWithContext(perms.createContextForWorldLookup(world).getContexts())) continue;
|
||||
|
||||
Map.Entry<String, String> meta = n.getMeta();
|
||||
if (meta.getKey().equalsIgnoreCase(node)) {
|
||||
return unescapeCharacters(meta.getValue());
|
||||
return meta.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private String getGroupChatMeta(boolean prefix, Group group, String world) {
|
||||
private String getGroupChatMeta(ChatMetaType type, Group group, String world) {
|
||||
world = perms.isIgnoreWorld() ? null : world;
|
||||
if (group == null) return "";
|
||||
|
||||
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for group " + group + " on world " + world + ", server " + perms.getServer());
|
||||
perms.log("Getting " + type.name().toLowerCase() + " for group " + group + " on world " + world + ", server " + perms.getServer());
|
||||
|
||||
int priority = Integer.MIN_VALUE;
|
||||
String meta = null;
|
||||
|
||||
Map<String, String> context = new HashMap<>();
|
||||
context.put("server", perms.getServer());
|
||||
if (world != null) {
|
||||
context.put("world", world);
|
||||
}
|
||||
|
||||
ExtractedContexts ec = ExtractedContexts.generate(new Contexts(ContextSet.fromMap(context), perms.isIncludeGlobal(), true, true, true, true, false));
|
||||
ExtractedContexts ec = ExtractedContexts.generate(Contexts.of(perms.createContextForWorldLookup(world).getContexts(), perms.isIncludeGlobal(), true, true, true, true, false));
|
||||
for (Node n : group.getAllNodes(ec)) {
|
||||
if (!n.getValue()) continue;
|
||||
if (prefix ? !n.isPrefix() : !n.isSuffix()) continue;
|
||||
if (!n.shouldApplyOnServer(perms.getServer(), perms.isIncludeGlobal(), false)) continue;
|
||||
if (!n.shouldApplyOnWorld(world, perms.isIncludeGlobal(), false)) continue;
|
||||
if (type.shouldIgnore(n)) continue;
|
||||
if (!n.shouldApplyWithContext(perms.createContextForWorldLookup(world).getContexts())) continue;
|
||||
|
||||
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
|
||||
Map.Entry<Integer, String> value = type.getEntry(n);
|
||||
if (value.getKey() > priority) {
|
||||
meta = value.getValue();
|
||||
priority = value.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return meta == null ? "" : unescapeCharacters(meta);
|
||||
return meta != null ? meta : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayerPrefix(String world, @NonNull String player) {
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
return getUserChatMeta(true, user, world);
|
||||
return getUserChatMeta(ChatMetaType.PREFIX, user, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerPrefix(String world, @NonNull String player, @NonNull String prefix) {
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setChatMeta(true, user, prefix, world);
|
||||
setChatMeta(ChatMetaType.PREFIX, user, prefix, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayerSuffix(String world, @NonNull String player) {
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
return getUserChatMeta(false, user, world);
|
||||
return getUserChatMeta(ChatMetaType.SUFFIX, user, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerSuffix(String world, @NonNull String player, @NonNull String suffix) {
|
||||
final User user = perms.getPlugin().getUserManager().getByUsername(player);
|
||||
setChatMeta(false, user, suffix, world);
|
||||
setChatMeta(ChatMetaType.SUFFIX, user, suffix, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroupPrefix(String world, @NonNull String group) {
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
return getGroupChatMeta(true, g, world);
|
||||
return getGroupChatMeta(ChatMetaType.PREFIX, g, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGroupPrefix(String world, @NonNull String group, @NonNull String prefix) {
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setChatMeta(true, g, prefix, world);
|
||||
setChatMeta(ChatMetaType.PREFIX, g, prefix, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroupSuffix(String world, @NonNull String group) {
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
return getGroupChatMeta(false, g, world);
|
||||
return getGroupChatMeta(ChatMetaType.SUFFIX, g, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGroupSuffix(String world, @NonNull String group, @NonNull String suffix) {
|
||||
final Group g = perms.getPlugin().getGroupManager().getIfLoaded(group);
|
||||
setChatMeta(false, g, suffix, world);
|
||||
setChatMeta(ChatMetaType.SUFFIX, g, suffix, world);
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -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,8 +33,8 @@ import me.lucko.luckperms.api.DataMutateResult;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.caching.PermissionData;
|
||||
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.LPBukkitPlugin;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
@@ -42,7 +45,8 @@ import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
import java.util.HashMap;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -136,21 +140,56 @@ public class VaultPermissionHook extends Permission {
|
||||
public void save(PermissionHolder holder) {
|
||||
if (holder instanceof User) {
|
||||
User u = (User) holder;
|
||||
plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), plugin.getScheduler().getAsyncExecutor());
|
||||
plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), plugin.getScheduler().async());
|
||||
}
|
||||
if (holder instanceof Group) {
|
||||
Group g = (Group) holder;
|
||||
plugin.getStorage().saveGroup(g).thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getScheduler().getAsyncExecutor());
|
||||
plugin.getStorage().saveGroup(g).thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getScheduler().async());
|
||||
}
|
||||
}
|
||||
|
||||
public Contexts createContextForWorld(String world) {
|
||||
Map<String, String> context = new HashMap<>();
|
||||
public Contexts createContextForWorldSet(String world) {
|
||||
MutableContextSet context = MutableContextSet.create();
|
||||
if (world != null && !world.equals("") && !world.equalsIgnoreCase("global")) {
|
||||
context.put("world", world);
|
||||
context.add("world", world);
|
||||
}
|
||||
context.put("server", getServer());
|
||||
return new Contexts(ContextSet.fromMap(context), isIncludeGlobal(), true, true, true, true, false);
|
||||
context.add("server", getServer());
|
||||
return new Contexts(context, isIncludeGlobal(), true, true, true, true, false);
|
||||
}
|
||||
|
||||
public Contexts createContextForWorldLookup(String world) {
|
||||
MutableContextSet context = MutableContextSet.create();
|
||||
if (world != null && !world.equals("") && !world.equalsIgnoreCase("global")) {
|
||||
context.add("world", world);
|
||||
}
|
||||
context.add("server", getServer());
|
||||
context.addAll(plugin.getConfiguration().getContextsFile().getStaticContexts());
|
||||
return new Contexts(context, isIncludeGlobal(), true, true, true, true, false);
|
||||
}
|
||||
|
||||
public Contexts createContextForWorldLookup(Player player, String world) {
|
||||
MutableContextSet context = MutableContextSet.create();
|
||||
|
||||
// use player context
|
||||
if (player != null) {
|
||||
ImmutableContextSet applicableContext = plugin.getContextManager().getApplicableContext(player);
|
||||
context.addAll(applicableContext);
|
||||
} else {
|
||||
// at least given them the static context defined for this instance
|
||||
context.addAll(plugin.getConfiguration().getContextsFile().getStaticContexts());
|
||||
}
|
||||
|
||||
// worlds & servers get set depending on the config setting
|
||||
context.removeAll("world");
|
||||
context.removeAll("server");
|
||||
|
||||
// add the vault settings
|
||||
if (world != null && !world.equals("") && !world.equalsIgnoreCase("global")) {
|
||||
context.add("world", world);
|
||||
}
|
||||
context.add("server", getServer());
|
||||
|
||||
return new Contexts(context, isIncludeGlobal(), true, true, true, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,12 +200,8 @@ public class VaultPermissionHook extends Permission {
|
||||
User user = plugin.getUserManager().getByUsername(player);
|
||||
if (user == null) return false;
|
||||
|
||||
if (user.getUserData() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Effectively fallback to the standard Bukkit #hasPermission check.
|
||||
return user.getUserData().getPermissionData(createContextForWorld(world)).getPermissionValue(permission).asBoolean();
|
||||
return user.getUserData().getPermissionData(createContextForWorldLookup(plugin.getPlayer(user), world)).getPermissionValue(permission).asBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -202,7 +237,7 @@ public class VaultPermissionHook extends Permission {
|
||||
if (group == null) return false;
|
||||
|
||||
// This is a nasty call. Groups aren't cached. :(
|
||||
Map<String, Boolean> permissions = group.exportNodes(ExtractedContexts.generate(createContextForWorld(world)), true);
|
||||
Map<String, Boolean> permissions = group.exportNodes(ExtractedContexts.generate(createContextForWorldLookup(world)), true);
|
||||
return permissions.containsKey(permission.toLowerCase()) && permissions.get(permission.toLowerCase());
|
||||
}
|
||||
|
||||
@@ -241,8 +276,7 @@ public class VaultPermissionHook extends Permission {
|
||||
String w = world; // screw effectively final
|
||||
return user.getNodes().values().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(getServer(), isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(w, true, false))
|
||||
.filter(n -> n.shouldApplyWithContext(createContextForWorldLookup(plugin.getPlayer(user), w).getContexts()))
|
||||
.map(Node::getGroupName)
|
||||
.anyMatch(s -> s.equalsIgnoreCase(group));
|
||||
}
|
||||
@@ -312,8 +346,7 @@ public class VaultPermissionHook extends Permission {
|
||||
String w = world; // screw effectively final
|
||||
return user.getNodes().values().stream()
|
||||
.filter(Node::isGroupNode)
|
||||
.filter(n -> n.shouldApplyOnServer(getServer(), isIncludeGlobal(), false))
|
||||
.filter(n -> n.shouldApplyOnWorld(w, true, false))
|
||||
.filter(n -> n.shouldApplyWithContext(createContextForWorldLookup(plugin.getPlayer(user), w).getContexts()))
|
||||
.map(Node::getGroupName)
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
@@ -337,7 +370,7 @@ public class VaultPermissionHook extends Permission {
|
||||
// we need to do the complex PGO checking. (it's been enabled in the config.)
|
||||
if (isPgoCheckInherited()) {
|
||||
// we can just check the cached data
|
||||
PermissionData data = user.getUserData().getPermissionData(createContextForWorld(world));
|
||||
PermissionData data = user.getUserData().getPermissionData(createContextForWorldLookup(plugin.getPlayer(user), world));
|
||||
for (Map.Entry<String, Boolean> e : data.getImmutableBacking().entrySet()) {
|
||||
if (!e.getValue()) continue;
|
||||
if (!e.getKey().toLowerCase().startsWith("vault.primarygroup.")) continue;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -71,7 +71,7 @@ temporary-add-behaviour: deny
|
||||
# Available Options:
|
||||
# -> stored use the value stored against the users record in the file/database
|
||||
# -> parents-by-weight just use the users most highly weighted parent
|
||||
# -> all-parents-by-weight same as above, but calculates based upon all parents inherits from both directly and indirectly
|
||||
# -> all-parents-by-weight same as above, but calculates based upon all parents inherited from both directly and indirectly
|
||||
primary-group-calculation: stored
|
||||
|
||||
|
||||
@@ -95,6 +95,24 @@ apply-regex: true
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# If the plugin should apply Bukkit child permissions.
|
||||
# Plugin authors can define custom permissions structures for their plugin, which will be resolved and used
|
||||
# by LuckPerms if this setting is enabled.
|
||||
apply-bukkit-child-permissions: true
|
||||
|
||||
# If the plugin should apply Bukkit default permissions.
|
||||
# Plugin authors can define permissions which should be given to all users by default, or setup permissions
|
||||
# which should/shouldn't be given to opped players.
|
||||
# If this option is set to false, LuckPerms will ignore these defaults.
|
||||
apply-bukkit-default-permissions: true
|
||||
|
||||
# If the plugin should apply attachment permissions.
|
||||
# Other plugins on the server are able to add their own "permission attachments" to players. This allows
|
||||
# them to grant players additional permissions which last until the end of the session, or until they're removed.
|
||||
# If this option is set to false, LuckPerms will not include these attachment permissions when considering if a
|
||||
# player should have access to a certain permission.
|
||||
apply-bukkit-attachment-permissions: true
|
||||
|
||||
# Define special group weights for this server.
|
||||
# Default is just 0.
|
||||
group-weight:
|
||||
@@ -116,6 +134,8 @@ group-weight:
|
||||
# - lowest_own
|
||||
# - highest_on_track_<track>
|
||||
# - lowest_on_track_<track>
|
||||
# - highest_not_on_track_<track>
|
||||
# - lowest_not_on_track_<track>
|
||||
#
|
||||
# Each element is added in the order listed.
|
||||
meta-formatting:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: LuckPerms
|
||||
version: ${release.version}.${patch.version}
|
||||
version: ${full.version}
|
||||
description: A permissions plugin
|
||||
author: Luck
|
||||
website: https://github.com/lucko/LuckPerms
|
||||
@@ -16,8 +16,8 @@ softdepend: [LilyPad-Connect]
|
||||
commands:
|
||||
luckperms:
|
||||
description: Manage permissions
|
||||
aliases: [perms, permissions, lp, perm]
|
||||
aliases: [lp, perm, perms, permission, permissions]
|
||||
|
||||
|
||||
# Permissions are registered programmatically instead of here.
|
||||
# See: the last method in me.lucko.luckperms.bukkit.LPBukkitPlugin
|
||||
# See the last method in me.lucko.luckperms.bukkit.LPBukkitPlugin
|
||||
+32
-13
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>3.1-SNAPSHOT</version>
|
||||
<version>3.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,20 +14,12 @@
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>LuckPerms-Bungee-${release.version}.${patch.version}</finalName>
|
||||
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||
<finalName>LuckPerms-Bungee-${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>
|
||||
@@ -66,7 +58,7 @@
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<!-- BungeeCord API -->
|
||||
<!-- BungeeCord -->
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
@@ -94,12 +86,39 @@
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- **************Migration Plugins************** -->
|
||||
<!-- ************** Migration Plugins ************** -->
|
||||
<!-- BungeePerms -->
|
||||
<dependency>
|
||||
<groupId>net.alpenblock</groupId>
|
||||
<artifactId>BungeePerms</artifactId>
|
||||
<version>3.0-dev-52</version>
|
||||
<version>3.0</version>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldedit</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>Vault</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>Essentials</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -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,13 +25,16 @@
|
||||
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BackendServerCalculator implements ContextCalculator<ProxiedPlayer> {
|
||||
private static final String WORLD_KEY = "world";
|
||||
|
||||
@@ -36,12 +42,14 @@ public class BackendServerCalculator implements ContextCalculator<ProxiedPlayer>
|
||||
return player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
|
||||
}
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
@Override
|
||||
public MutableContextSet giveApplicableContext(ProxiedPlayer subject, MutableContextSet accumulator) {
|
||||
String server = getServer(subject);
|
||||
|
||||
if (server != null) {
|
||||
accumulator.add(Maps.immutableEntry(WORLD_KEY, server.toLowerCase()));
|
||||
while (server != null && !accumulator.has(WORLD_KEY, server)) {
|
||||
accumulator.add(WORLD_KEY, server);
|
||||
server = plugin.getConfiguration().get(ConfigKeys.WORLD_REWRITES).getOrDefault(server, server);
|
||||
}
|
||||
|
||||
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
|
||||
@@ -43,14 +46,17 @@ public class BungeeCalculatorFactory extends AbstractCalculatorFactory {
|
||||
@Override
|
||||
public PermissionCalculator build(Contexts contexts, User user) {
|
||||
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
|
||||
|
||||
processors.add(new MapProcessor());
|
||||
|
||||
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_REGEX)) {
|
||||
processors.add(new RegexProcessor());
|
||||
}
|
||||
|
||||
if (plugin.getConfiguration().get(ConfigKeys.APPLYING_WILDCARDS)) {
|
||||
processors.add(new WildcardProcessor());
|
||||
}
|
||||
|
||||
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
|
||||
return registerCalculator(new PermissionCalculator(plugin, user.getFriendlyName(), 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 net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
@@ -40,7 +42,7 @@ class BungeeCommand extends Command implements TabExecutor {
|
||||
private final CommandManager manager;
|
||||
|
||||
BungeeCommand(LPBungeePlugin plugin, CommandManager manager) {
|
||||
super("luckpermsbungee", null, "bperms", "lpb", "bpermissions", "bperm");
|
||||
super("luckpermsbungee", null, "lpb", "bperm", "bperms", "bpermission", "bpermissions");
|
||||
this.plugin = plugin;
|
||||
this.manager = manager;
|
||||
}
|
||||
@@ -50,7 +52,7 @@ class BungeeCommand extends Command implements TabExecutor {
|
||||
manager.onCommand(
|
||||
plugin.getSenderFactory().wrap(sender),
|
||||
"lpb",
|
||||
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
|
||||
Util.stripQuotes(Splitter.on(CommandManager.COMMAND_SEPARATOR_PATTERN).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,13 +28,12 @@ package me.lucko.luckperms.bungee;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.constants.Message;
|
||||
import me.lucko.luckperms.common.core.UuidCache;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.common.defaults.Rule;
|
||||
import me.lucko.luckperms.common.utils.LoginHelper;
|
||||
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
@@ -66,94 +68,58 @@ public class BungeeListener implements Listener {
|
||||
This means that a player will have the same UUID across the network, even if parts of the network are running in
|
||||
Offline mode. */
|
||||
|
||||
// registers the plugins intent to modify this events state going forward.
|
||||
// this will prevent the event from completing until we're finished handling.
|
||||
/* registers the plugins intent to modify this events state going forward.
|
||||
this will prevent the event from completing until we're finished handling. */
|
||||
e.registerIntent(plugin);
|
||||
|
||||
final long startTime = System.currentTimeMillis();
|
||||
final PendingConnection c = e.getConnection();
|
||||
|
||||
/* either the plugin hasn't finished starting yet, or there was an issue connecting to the DB, performing file i/o, etc.
|
||||
as this is bungeecord, we will still allow the login, as players can't really do much harm without permissions data.
|
||||
the proxy will just fallback to using the config file perms. */
|
||||
if (!plugin.getStorage().isAcceptingLogins()) {
|
||||
// log that the user tried to login, but was denied at this stage.
|
||||
deniedLogin.add(c.getUniqueId());
|
||||
return;
|
||||
}
|
||||
|
||||
/* another plugin (or the proxy itself) has cancelled this connection already */
|
||||
if (e.isCancelled()) {
|
||||
|
||||
// log that we are not loading any data
|
||||
plugin.getLog().warn("Connection from " + c.getUniqueId() + " was already denied. No permissions data will be loaded.");
|
||||
deniedLogin.add(c.getUniqueId());
|
||||
|
||||
e.completeIntent(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
/* there was an issue connecting to the DB, performing file i/o, etc.
|
||||
as this is bungeecord, we will still allow the login, as players can't really do much harm without permissions data.
|
||||
the proxy will just fallback to using the config file perms. */
|
||||
if (!plugin.getStorage().isAcceptingLogins()) {
|
||||
|
||||
// log that the user tried to login, but was denied at this stage.
|
||||
plugin.getLog().warn("Permissions storage is not loaded yet. No permissions data will be loaded for: " + c.getUniqueId() + " - " + c.getName());
|
||||
deniedLogin.add(c.getUniqueId());
|
||||
|
||||
e.completeIntent(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
||||
This includes:
|
||||
- loading uuid data
|
||||
- loading permissions
|
||||
- creating a user instance in the UserManager for this connection.
|
||||
- setting up cached data. */
|
||||
plugin.doAsync(() -> {
|
||||
final UuidCache cache = plugin.getUuidCache();
|
||||
/* 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.
|
||||
|
||||
if (!plugin.getConfiguration().get(ConfigKeys.USE_SERVER_UUIDS)) {
|
||||
UUID uuid = plugin.getStorage().getUUID(c.getName()).join();
|
||||
if (uuid != null) {
|
||||
cache.addToCache(c.getUniqueId(), uuid);
|
||||
} else {
|
||||
// No previous data for this player
|
||||
plugin.getApiProvider().getEventFactory().handleUserFirstLogin(c.getUniqueId(), c.getName());
|
||||
cache.addToCache(c.getUniqueId(), c.getUniqueId());
|
||||
This includes:
|
||||
- loading uuid data
|
||||
- loading permissions
|
||||
- creating a user instance in the UserManager for this connection.
|
||||
- setting up cached data. */
|
||||
try {
|
||||
LoginHelper.loadUser(plugin, c.getUniqueId(), c.getName(), true);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
||||
// Join this call, as we want this to be set for when the player connects to the backend.
|
||||
plugin.getStorage().force().saveUUIDData(c.getName(), c.getUniqueId()).join();
|
||||
}
|
||||
} else {
|
||||
String name = plugin.getStorage().getName(c.getUniqueId()).join();
|
||||
if (name == null) {
|
||||
plugin.getApiProvider().getEventFactory().handleUserFirstLogin(c.getUniqueId(), c.getName());
|
||||
}
|
||||
|
||||
// Online mode, no cache needed. This is just for name -> uuid lookup.
|
||||
// Again, join this call so the data is available for the backend.
|
||||
plugin.getStorage().force().saveUUIDData(c.getName(), c.getUniqueId()).join();
|
||||
// there was some error loading
|
||||
plugin.getLog().warn("Error loading data. No permissions data will be loaded for: " + c.getUniqueId() + " - " + c.getName());
|
||||
deniedLogin.add(c.getUniqueId());
|
||||
}
|
||||
|
||||
/* We have to make a new user on this thread whilst the connection is being held, or we get concurrency issues
|
||||
as the Bukkit server and the BungeeCord server try to make a new user at the same time. */
|
||||
plugin.getStorage().force().loadUser(cache.getUUID(c.getUniqueId()), c.getName()).join();
|
||||
|
||||
User user = plugin.getUserManager().get(cache.getUUID(c.getUniqueId()));
|
||||
if (user == null) {
|
||||
plugin.getLog().warn("Failed to load user: " + c.getName());
|
||||
} else {
|
||||
// Setup defaults for the user
|
||||
boolean save = false;
|
||||
for (Rule rule : plugin.getConfiguration().get(ConfigKeys.DEFAULT_ASSIGNMENTS)) {
|
||||
if (rule.apply(user)) {
|
||||
save = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If they were given a default, persist the new assignments back to the storage.
|
||||
if (save) {
|
||||
plugin.getStorage().force().saveUser(user).join();
|
||||
}
|
||||
|
||||
user.setupData(false); // Pretty nasty calculation call. Sets up the caching system so data is ready when the user joins.
|
||||
}
|
||||
|
||||
final long time = System.currentTimeMillis() - startTime;
|
||||
if (time >= 1000) {
|
||||
plugin.getLog().warn("Processing login for " + c.getName() + " took " + time + "ms.");
|
||||
}
|
||||
|
||||
// finally, complete out intent to modify state, so the proxy can continue handling the connection.
|
||||
// finally, complete our intent to modify state, so the proxy can continue handling the connection.
|
||||
e.completeIntent(plugin);
|
||||
|
||||
// schedule a cleanup of the users data in a few seconds.
|
||||
@@ -165,7 +131,7 @@ public class BungeeListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerPostLogin(PostLoginEvent e) {
|
||||
final ProxiedPlayer player = e.getPlayer();
|
||||
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
final User user = plugin.getUserManager().getIfLoaded(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
|
||||
|
||||
if (user == null) {
|
||||
plugin.getProxy().getScheduler().schedule(plugin, () -> {
|
||||
@@ -193,15 +159,9 @@ public class BungeeListener implements Listener {
|
||||
|
||||
final ProxiedPlayer player = ((ProxiedPlayer) e.getSender());
|
||||
|
||||
User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
User user = plugin.getUserManager().getIfLoaded(plugin.getUuidCache().getUUID(player.getUniqueId()));
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserData userData = user.getUserData();
|
||||
if (userData == null) {
|
||||
plugin.getLog().warn("Player " + player.getName() + " does not have any user data setup.");
|
||||
plugin.doAsync(() -> user.setupData(false));
|
||||
e.setHasPermission(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -215,7 +175,12 @@ public class BungeeListener implements Listener {
|
||||
false
|
||||
);
|
||||
|
||||
e.setHasPermission(userData.getPermissionData(contexts).getPermissionValue(e.getPermission()).asBoolean());
|
||||
Tristate result = user.getUserData().getPermissionData(contexts).getPermissionValue(e.getPermission());
|
||||
if (result == Tristate.UNDEFINED && plugin.getConfiguration().get(ConfigKeys.APPLY_BUNGEE_CONFIG_PERMISSIONS)) {
|
||||
return; // just use the result provided by the proxy when the event was created
|
||||
}
|
||||
|
||||
e.setHasPermission(result.asBoolean());
|
||||
}
|
||||
|
||||
// We don't pre-process all servers, so we have to do it here.
|
||||
@@ -229,14 +194,10 @@ public class BungeeListener implements Listener {
|
||||
set.add("server", plugin.getConfiguration().get(ConfigKeys.SERVER));
|
||||
set.add("world", serverName);
|
||||
|
||||
User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(uuid));
|
||||
User user = plugin.getUserManager().getIfLoaded(plugin.getUuidCache().getUUID(uuid));
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
UserData userData = user.getUserData();
|
||||
if (userData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Contexts contexts = new Contexts(
|
||||
set.makeImmutable(),
|
||||
@@ -248,7 +209,7 @@ public class BungeeListener implements Listener {
|
||||
false
|
||||
);
|
||||
|
||||
userData.preCalculate(contexts);
|
||||
user.getUserData().preCalculate(contexts);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -66,7 +69,7 @@ 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.SenderLogger;
|
||||
import me.lucko.luckperms.common.verbose.VerboseHandler;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
@@ -112,7 +115,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
scheduler = new LPBungeeScheduler(this);
|
||||
localeManager = new NoopLocaleManager();
|
||||
senderFactory = new BungeeSenderFactory(this);
|
||||
log = new LoggerImpl(getConsoleSender());
|
||||
log = new SenderLogger(getConsoleSender());
|
||||
|
||||
DependencyManager.loadDependencies(this, Collections.singletonList(Dependency.CAFFEINE));
|
||||
}
|
||||
@@ -120,8 +123,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
|
||||
verboseHandler = new VerboseHandler(scheduler.getAsyncExecutor(), getVersion());
|
||||
permissionVault = new PermissionVault(scheduler.getAsyncExecutor());
|
||||
verboseHandler = new VerboseHandler(scheduler.async(), getVersion());
|
||||
permissionVault = new PermissionVault(scheduler.async());
|
||||
|
||||
getLog().info("Loading configuration...");
|
||||
configuration = new BungeeConfig(this);
|
||||
@@ -136,7 +139,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
|
||||
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
|
||||
fileWatcher = new FileWatcher(this);
|
||||
getScheduler().doAsyncRepeating(fileWatcher, 30L);
|
||||
getScheduler().asyncRepeating(fileWatcher, 30L);
|
||||
}
|
||||
|
||||
// initialise datastore
|
||||
@@ -215,9 +218,12 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
cachedStateManager = new CachedStateManager(this);
|
||||
|
||||
contextManager = new ContextManager<>();
|
||||
BackendServerCalculator serverCalculator = new BackendServerCalculator();
|
||||
BackendServerCalculator serverCalculator = new BackendServerCalculator(this);
|
||||
contextManager.registerCalculator(serverCalculator);
|
||||
contextManager.registerCalculator(new StaticCalculator<>(configuration));
|
||||
|
||||
StaticCalculator<ProxiedPlayer> staticCalculator = new StaticCalculator<>(getConfiguration());
|
||||
contextManager.registerCalculator(staticCalculator);
|
||||
contextManager.registerStaticCalculator(staticCalculator);
|
||||
|
||||
// register with the LP API
|
||||
getLog().info("Registering API...");
|
||||
@@ -228,16 +234,16 @@ public class LPBungeePlugin extends Plugin 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.
|
||||
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);
|
||||
|
||||
getLog().info("Successfully loaded.");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -43,46 +46,46 @@ public class LPBungeeScheduler implements LuckPermsScheduler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
public Executor async() {
|
||||
return asyncExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getSyncExecutor() {
|
||||
public Executor sync() {
|
||||
return asyncExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsync(Runnable r) {
|
||||
asyncExecutor.execute(r);
|
||||
public void doAsync(Runnable runnable) {
|
||||
asyncExecutor.execute(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSync(Runnable r) {
|
||||
doAsync(r);
|
||||
public void doSync(Runnable runnable) {
|
||||
doAsync(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsyncRepeating(Runnable r, long interval) {
|
||||
long millis = interval * 50L; // convert from ticks to milliseconds
|
||||
ScheduledTask task = plugin.getProxy().getScheduler().schedule(plugin, r, millis, millis, TimeUnit.MILLISECONDS);
|
||||
public void asyncRepeating(Runnable runnable, long intervalTicks) {
|
||||
long millis = intervalTicks * 50L; // convert from ticks to milliseconds
|
||||
ScheduledTask task = plugin.getProxy().getScheduler().schedule(plugin, runnable, millis, millis, TimeUnit.MILLISECONDS);
|
||||
tasks.add(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSyncRepeating(Runnable r, long interval) {
|
||||
doAsyncRepeating(r, interval);
|
||||
public void syncRepeating(Runnable runnable, long intervalTicks) {
|
||||
asyncRepeating(runnable, intervalTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAsyncLater(Runnable r, long delay) {
|
||||
long millis = delay * 50L; // convert from ticks to milliseconds
|
||||
plugin.getProxy().getScheduler().schedule(plugin, r, millis, TimeUnit.MILLISECONDS);
|
||||
public void asyncLater(Runnable runnable, long delayTicks) {
|
||||
long millis = delayTicks * 50L; // convert from ticks to milliseconds
|
||||
plugin.getProxy().getScheduler().schedule(plugin, runnable, millis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSyncLater(Runnable r, long delay) {
|
||||
doAsyncLater(r, delay);
|
||||
public void syncLater(Runnable runnable, long delayTicks) {
|
||||
asyncLater(runnable, delayTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-1
@@ -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
|
||||
@@ -157,7 +160,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
|
||||
|
||||
// Make a LuckPerms user for the one being migrated.
|
||||
plugin.getStorage().loadUser(u.getUUID(), u.getName()).join();
|
||||
me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(u.getUUID());
|
||||
me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().getIfLoaded(u.getUUID());
|
||||
|
||||
// Migrate global perms
|
||||
for (String perm : u.getPerms()) {
|
||||
|
||||
@@ -14,7 +14,7 @@ server: bungee
|
||||
|
||||
# If users on this server should have their global permissions applied.
|
||||
# If set to false, only server specific permissions will apply for users on this server
|
||||
include-global: false
|
||||
include-global: true
|
||||
|
||||
# If users on this server should have their global world permissions applied.
|
||||
# If set to false, only world specific permissions will apply for users on this server
|
||||
@@ -71,7 +71,7 @@ temporary-add-behaviour: deny
|
||||
# Available Options:
|
||||
# -> stored use the value stored against the users record in the file/database
|
||||
# -> parents-by-weight just use the users most highly weighted parent
|
||||
# -> all-parents-by-weight same as above, but calculates based upon all parents inherits from both directly and indirectly
|
||||
# -> all-parents-by-weight same as above, but calculates based upon all parents inherited from both directly and indirectly
|
||||
primary-group-calculation: stored
|
||||
|
||||
|
||||
@@ -95,6 +95,10 @@ apply-regex: true
|
||||
# If set to true, LuckPerms will detect and expand shorthand node patterns.
|
||||
apply-shorthand: true
|
||||
|
||||
# If the plugin should apply the permissions & groups defined in the BungeeCord config.yml
|
||||
# If set to false, LuckPerms will ignore these values.
|
||||
apply-bungee-config-permissions: false
|
||||
|
||||
# Define special group weights for this server.
|
||||
# Default is just 0.
|
||||
group-weight:
|
||||
@@ -116,6 +120,8 @@ group-weight:
|
||||
# - lowest_own
|
||||
# - highest_on_track_<track>
|
||||
# - lowest_on_track_<track>
|
||||
# - highest_not_on_track_<track>
|
||||
# - lowest_not_on_track_<track>
|
||||
#
|
||||
# Each element is added in the order listed.
|
||||
meta-formatting:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: LuckPerms
|
||||
version: ${release.version}.${patch.version}
|
||||
version: ${full.version}
|
||||
description: A permissions plugin
|
||||
author: Luck
|
||||
main: me.lucko.luckperms.bungee.LPBungeePlugin
|
||||
+2
-37
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>luckperms</artifactId>
|
||||
<groupId>me.lucko.luckperms</groupId>
|
||||
<version>3.1-SNAPSHOT</version>
|
||||
<version>3.2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<build>
|
||||
<finalName>LuckPerms-Common-${release.version}.${patch.version}</finalName>
|
||||
<finalName>LuckPerms-Common-${full.version}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -42,13 +42,6 @@
|
||||
<version>1.2.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- MySQL -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.40</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- HikariCP -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
@@ -63,27 +56,6 @@
|
||||
<version>2.9.1-shaded</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- SQLite -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.8.11.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- H2 -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.192</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- PostgreSQL -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>9.4.1212</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- MongoDB -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
@@ -91,13 +63,6 @@
|
||||
<version>3.3.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- SnakeYAML -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
|
||||
@@ -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
|
||||
@@ -40,6 +43,7 @@ import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.UuidCache;
|
||||
import me.lucko.luckperms.api.context.ContextCalculator;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.api.delegates.MetaStackFactoryDelegate;
|
||||
import me.lucko.luckperms.common.api.delegates.NodeFactoryDelegate;
|
||||
import me.lucko.luckperms.common.api.delegates.UserDelegate;
|
||||
import me.lucko.luckperms.common.core.UserIdentifier;
|
||||
@@ -66,10 +70,14 @@ public class ApiProvider implements LuckPermsApi {
|
||||
@Getter
|
||||
private final EventFactory eventFactory;
|
||||
|
||||
@Getter
|
||||
private final MetaStackFactoryDelegate metaStackFactory;
|
||||
|
||||
public ApiProvider(LuckPermsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.eventBus = new LuckPermsEventBus(plugin);
|
||||
this.eventFactory = new EventFactory(eventBus);
|
||||
this.metaStackFactory = new MetaStackFactoryDelegate(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +87,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public double getApiVersion() {
|
||||
return 3.1;
|
||||
return 3.2;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,7 +128,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public User getUser(@NonNull UUID uuid) {
|
||||
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().get(uuid);
|
||||
final me.lucko.luckperms.common.core.model.User user = plugin.getUserManager().getIfLoaded(uuid);
|
||||
return user == null ? null : user.getDelegate();
|
||||
}
|
||||
|
||||
|
||||
@@ -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,14 +29,14 @@ import lombok.experimental.UtilityClass;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||
import me.lucko.luckperms.common.constants.DataConstraints;
|
||||
|
||||
@UtilityClass
|
||||
public class ApiUtils {
|
||||
|
||||
public static String checkUsername(String s) {
|
||||
Preconditions.checkArgument(
|
||||
!ArgumentChecker.checkUsername(s),
|
||||
DataConstraints.PLAYER_USERNAME_TEST.test(s),
|
||||
"Invalid username entry '" + s + "'. Usernames must be less than 16 chars and only contain 'a-z A-Z 1-9 _'."
|
||||
);
|
||||
return s;
|
||||
@@ -41,14 +44,14 @@ public class ApiUtils {
|
||||
|
||||
public static String checkName(String s) {
|
||||
Preconditions.checkArgument(
|
||||
!ArgumentChecker.checkName(s),
|
||||
DataConstraints.GROUP_NAME_TEST.test(s),
|
||||
"Invalid name entry '" + s + "'. Names must be less than 37 chars and only contain 'a-z A-Z 1-9'."
|
||||
);
|
||||
return s.toLowerCase();
|
||||
}
|
||||
|
||||
public static long checkTime(long l) {
|
||||
Preconditions.checkArgument(!ArgumentChecker.checkTime(l), "Unix time '" + l + "' is invalid, as it has already passed.");
|
||||
Preconditions.checkArgument(DataConstraints.TIME_TEST.test(l), "Unix time '" + l + "' is invalid, as it has already passed.");
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,7 @@ import com.google.common.base.Preconditions;
|
||||
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -67,9 +71,14 @@ public final class GroupDelegate extends PermissionHolderDelegate implements Gro
|
||||
return handle.inheritsGroup(cast(group));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group, @NonNull ContextSet contextSet) {
|
||||
return handle.inheritsGroup(cast(group), contextSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inheritsGroup(@NonNull Group group, @NonNull String server) {
|
||||
return handle.inheritsGroup(((GroupDelegate) group).getHandle(), server);
|
||||
return handle.inheritsGroup(cast(group), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-1
@@ -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
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.api.delegates;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackElement;
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackFactory;
|
||||
import me.lucko.luckperms.common.metastacking.definition.SimpleMetaStackDefinition;
|
||||
import me.lucko.luckperms.common.metastacking.definition.StandardStackElements;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class MetaStackFactoryDelegate implements MetaStackFactory {
|
||||
public final LuckPermsPlugin plugin;
|
||||
|
||||
@Override
|
||||
public Optional<MetaStackElement> fromString(@NonNull String definition) {
|
||||
return StandardStackElements.parseFromString(plugin, definition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetaStackElement> fromStrings(@NonNull List<String> definitions) {
|
||||
if (definitions.isEmpty()) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
return StandardStackElements.parseList(plugin, definitions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaStackDefinition createDefinition(List<MetaStackElement> elements, String startSpacer, String middleSpacer, String endSpacer) {
|
||||
return new SimpleMetaStackDefinition(elements, startSpacer, middleSpacer, endSpacer);
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -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,7 @@ package me.lucko.luckperms.common.api.delegates;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
@@ -61,6 +65,11 @@ public class NodeFactoryDelegate implements me.lucko.luckperms.api.NodeFactory {
|
||||
return NodeFactory.makeMetaNode(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder makeChatMetaNode(@NonNull ChatMetaType type, int priority, @NonNull String value) {
|
||||
return NodeFactory.makeChatMetaNode(type, priority, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node.Builder makePrefixNode(int priority, @NonNull String prefix) {
|
||||
return NodeFactory.makePrefixNode(priority, prefix);
|
||||
|
||||
+40
-1
@@ -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
|
||||
@@ -34,8 +37,10 @@ import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.PermissionHolder;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.api.context.MutableContextSet;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.common.core.model.User;
|
||||
import me.lucko.luckperms.common.utils.ExtractedContexts;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -46,6 +51,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
|
||||
|
||||
@@ -61,6 +67,11 @@ public class PermissionHolderDelegate implements PermissionHolder {
|
||||
return handle.getObjectName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFriendlyName() {
|
||||
return handle.getFriendlyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<? extends Node> getPermissions() {
|
||||
return ImmutableSortedSet.copyOfSorted(handle.mergePermissionsToSortedSet());
|
||||
@@ -236,6 +247,19 @@ public class PermissionHolderDelegate implements PermissionHolder {
|
||||
return handle.unsetTransientPermission(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMatching(Predicate<Node> test) {
|
||||
handle.removeIf(test);
|
||||
if (handle instanceof User) {
|
||||
handle.getPlugin().getUserManager().giveDefaultIfNeeded((User) handle, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMatchingTransient(Predicate<Node> test) {
|
||||
handle.removeIfTransient(test);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsetPermission(@NonNull String node, @NonNull boolean temporary) throws ObjectLacksException {
|
||||
handle.unsetPermission(NodeFactory.make(node, temporary)).throwException();
|
||||
@@ -271,6 +295,11 @@ public class PermissionHolderDelegate implements PermissionHolder {
|
||||
handle.clearNodes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearNodes(@NonNull ContextSet contextSet) {
|
||||
handle.clearNodes(contextSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearNodes(String server) {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
@@ -299,6 +328,11 @@ public class PermissionHolderDelegate implements PermissionHolder {
|
||||
handle.clearParents(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearParents(@NonNull ContextSet contextSet) {
|
||||
handle.clearParents(contextSet, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearParents(String server) {
|
||||
MutableContextSet set = new MutableContextSet();
|
||||
@@ -327,6 +361,11 @@ public class PermissionHolderDelegate implements PermissionHolder {
|
||||
handle.clearMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMeta(@NonNull ContextSet contextSet) {
|
||||
handle.clearMeta(contextSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearMeta(String server) {
|
||||
MutableContextSet set = 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
|
||||
@@ -66,12 +69,12 @@ public class StorageDelegate implements Storage {
|
||||
|
||||
@Override
|
||||
public Executor getSyncExecutor() {
|
||||
return plugin.getScheduler().getSyncExecutor();
|
||||
return plugin.getScheduler().sync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
return plugin.getScheduler().getAsyncExecutor();
|
||||
return plugin.getScheduler().async();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,12 +88,12 @@ public class StorageDelegate implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadUser(UUID uuid, String username) {
|
||||
return handle.force().loadUser(uuid, checkUsername(username));
|
||||
public CompletableFuture<Boolean> loadUser(@NonNull UUID uuid, String username) {
|
||||
return handle.force().loadUser(uuid, username == null ? null : checkUsername(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveUser(User user) {
|
||||
public CompletableFuture<Boolean> saveUser(@NonNull User user) {
|
||||
return handle.force().saveUser(UserDelegate.cast(user));
|
||||
}
|
||||
|
||||
@@ -110,12 +113,12 @@ public class StorageDelegate implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> createAndLoadGroup(String name) {
|
||||
public CompletableFuture<Boolean> createAndLoadGroup(@NonNull String name) {
|
||||
return handle.force().createAndLoadGroup(checkName(name), CreationCause.API);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadGroup(String name) {
|
||||
public CompletableFuture<Boolean> loadGroup(@NonNull String name) {
|
||||
return handle.force().loadGroup(checkName(name));
|
||||
}
|
||||
|
||||
@@ -125,12 +128,12 @@ public class StorageDelegate implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveGroup(Group group) {
|
||||
public CompletableFuture<Boolean> saveGroup(@NonNull Group group) {
|
||||
return handle.force().saveGroup(GroupDelegate.cast(group));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> deleteGroup(Group group) {
|
||||
public CompletableFuture<Boolean> deleteGroup(@NonNull Group group) {
|
||||
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().get(ConfigKeys.DEFAULT_GROUP_NAME))) {
|
||||
throw new IllegalArgumentException("Cannot delete the default group.");
|
||||
}
|
||||
@@ -143,12 +146,12 @@ public class StorageDelegate implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> createAndLoadTrack(String name) {
|
||||
public CompletableFuture<Boolean> createAndLoadTrack(@NonNull String name) {
|
||||
return handle.force().createAndLoadTrack(checkName(name), CreationCause.API);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> loadTrack(String name) {
|
||||
public CompletableFuture<Boolean> loadTrack(@NonNull String name) {
|
||||
return handle.force().loadTrack(checkName(name));
|
||||
}
|
||||
|
||||
@@ -158,22 +161,22 @@ public class StorageDelegate implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveTrack(Track track) {
|
||||
public CompletableFuture<Boolean> saveTrack(@NonNull Track track) {
|
||||
return handle.force().saveTrack(TrackDelegate.cast(track));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> deleteTrack(Track track) {
|
||||
public CompletableFuture<Boolean> deleteTrack(@NonNull Track track) {
|
||||
return handle.force().deleteTrack(TrackDelegate.cast(track), DeletionCause.API);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid) {
|
||||
public CompletableFuture<Boolean> saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
|
||||
return handle.force().saveUUIDData(checkUsername(username), uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<UUID> getUUID(String username) {
|
||||
public CompletableFuture<UUID> getUUID(@NonNull String username) {
|
||||
return handle.force().getUUID(checkUsername(username));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -31,6 +34,7 @@ import me.lucko.luckperms.api.Group;
|
||||
import me.lucko.luckperms.api.Node;
|
||||
import me.lucko.luckperms.api.User;
|
||||
import me.lucko.luckperms.api.caching.UserData;
|
||||
import me.lucko.luckperms.api.context.ContextSet;
|
||||
import me.lucko.luckperms.common.core.NodeFactory;
|
||||
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||
import me.lucko.luckperms.exceptions.ObjectLacksException;
|
||||
@@ -46,9 +50,9 @@ import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
|
||||
* Provides a link between {@link User} and {@link me.lucko.luckperms.common.core.model.User}
|
||||
*/
|
||||
public final class UserDelegate extends PermissionHolderDelegate implements User {
|
||||
public static me.lucko.luckperms.common.core.model.User cast(User g) {
|
||||
Preconditions.checkState(g instanceof UserDelegate, "Illegal instance " + g.getClass() + " cannot be handled by this implementation.");
|
||||
return ((UserDelegate) g).getHandle();
|
||||
public static me.lucko.luckperms.common.core.model.User cast(User u) {
|
||||
Preconditions.checkState(u instanceof UserDelegate, "Illegal instance " + u.getClass() + " cannot be handled by this implementation.");
|
||||
return ((UserDelegate) u).getHandle();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@@ -66,7 +70,7 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return handle.getName();
|
||||
return handle.getName().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,14 +96,19 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
|
||||
handle.getRefreshBuffer().requestDirectly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserData getCachedData() {
|
||||
return handle.getUserData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserData> getUserDataCache() {
|
||||
return Optional.ofNullable(handle.getUserData());
|
||||
return Optional.of(handle.getUserData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupDataCache() {
|
||||
handle.setupData(false);
|
||||
handle.preCalculateData(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,14 +116,19 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
|
||||
return handle.inheritsGroup(GroupDelegate.cast(group));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group, @NonNull ContextSet contextSet) {
|
||||
return handle.inheritsGroup(GroupDelegate.cast(group), contextSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group, @NonNull String server) {
|
||||
return handle.inheritsGroup(((GroupDelegate) group).getHandle(), server);
|
||||
return handle.inheritsGroup(GroupDelegate.cast(group), server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
|
||||
return handle.inheritsGroup(((GroupDelegate) group).getHandle(), server, world);
|
||||
return handle.inheritsGroup(GroupDelegate.cast(group), server, world);
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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) 2017 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) 2017 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) 2017 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) 2017 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) 2017 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
|
||||
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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
|
||||
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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
|
||||
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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
|
||||
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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
|
||||
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2017 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
|
||||
|
||||
Loaded 100 of 450 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user