Compare commits

...
42 Commits
Author SHA1 Message Date
Luck e216c235ce Add logging, prepare for import/export system 2016-08-15 01:51:38 +02:00
Luck fbf062933f Fix build 2016-08-09 13:52:25 +02:00
Luck cf85f31da8 Bump minor version 2016-08-09 11:13:01 +02:00
Luck b70b6f8af1 Add support for regex permissions/servers/worlds and shorthand permissions 2016-08-09 11:09:45 +02:00
Luck 90e074d3ab Apply bukkit permissions directly, fix sponge listener, other misc changes/fixes 2016-08-07 17:10:37 +02:00
Luck e14ea73626 Add wildcard permissions 2016-08-07 01:16:05 +02:00
Luck e07b677632 Update readme 2016-08-06 19:47:39 +02:00
Luck 4e7547c92e Add proper versioning, bump to 2.0 2016-08-06 18:28:38 +02:00
Luck 8483e78082 Add license headers 2016-08-06 14:36:56 +02:00
Luck 4ca1e26f0f Set version on build in sponge plugin 2016-08-06 12:25:23 +02:00
Luck d88657f369 Add more stuff to api 2016-08-06 11:04:06 +02:00
Luck caf03379f2 Move stuff into commons, rename PermissionObject, add more javadocs to api 2016-08-06 00:11:00 +02:00
Luck 03450c3339 Sponge support 2016-08-05 12:58:27 +02:00
Luck 56e11b8b85 Various small changes 2016-08-03 12:08:10 +02:00
Luck 5e23b6961e Use generics for sub commands, fix user lookup bugs 2016-08-03 00:54:50 +02:00
Luck 98c5a91beb Update readme 2016-08-02 15:12:06 +02:00
Luck d6cd0b162b Update vault version 2016-08-02 11:17:52 +02:00
Luck 1c064daccb Fix build 2016-08-02 10:56:15 +02:00
Luck 0cfdd8c862 Remove slow vault-repo, fix long build time 2016-08-02 10:54:16 +02:00
Luck a9619bc08c small fix 2016-08-02 00:50:47 +02:00
Luck a7a84952fe Update readme 2016-08-02 00:20:49 +02:00
Luck 9c867dee28 Revert message colorization 2016-07-26 15:53:15 +01:00
Luck db862b38c9 Fix version tags 2016-07-26 10:19:33 +01:00
Luck cba12c3e78 Update readme 2016-07-26 03:39:56 +01:00
Luck 0ecd899ec5 Fix bad javadoc issues 2016-07-26 03:12:27 +01:00
Luck e9805b7532 Remove travis 2016-07-26 02:23:16 +01:00
Luck c000b9c009 Update build 2016-07-26 02:21:51 +01:00
Luck 8f6435b9e8 Try to add travis 2016-07-25 22:08:08 +01:00
Luck a3604c7464 Bump version, and make future version changes easier 2016-07-25 21:05:09 +01:00
Luck 10574748ff Add inheritance methods to Group 2016-07-25 20:44:01 +01:00
Luck c7336dbcad Change Vault hook to use new per-world perms system 2016-07-25 20:20:51 +01:00
Luck ebeb69dd3a Per-world permissions 2016-07-25 18:19:36 +01:00
Luck 9ad40be210 Add complete offline-mode support 2016-07-25 11:18:35 +01:00
Luck df209f6515 Fix possible race condition 2016-07-23 22:34:42 +01:00
Luck d32d6b5474 Generics are cool 2016-07-23 21:57:19 +01:00
Luck 623b7b775c Fix readme markdown 2016-07-22 12:27:50 +01:00
Luck b3b687d9b7 Add Api 2016-07-21 21:40:24 +01:00
Luck a413c0a50a Cleanup & multiple small fixes 2016-07-21 14:15:14 +01:00
Luck 1870893fe1 Fix promotions/demotions 2016-07-19 17:10:40 +01:00
Luck f24562c642 Fix compile 2016-07-19 13:02:54 +01:00
Luck ea358e88e1 Remove test files, bump version 2016-07-19 13:01:58 +01:00
Luck cdf8a4ce18 Add temporary permissions 2016-07-19 12:54:39 +01:00
216 changed files with 15328 additions and 4173 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2016 Luck
Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
-111
View File
@@ -1,111 +0,0 @@
= LuckPerms
A (fairly bad) permissions implementation for Bukkit/BungeeCord.
=== Features
* **Group inheritance** - users can be members of multiple groups, groups can inherit other groups
* **Multi-server support** - data is synced across all servers/platforms
* **Per-server permissions/groups** - define user/group permissions that only apply on certain servers
* **Server-specific groups** - define groups that only apply on certain servers
* **Tracks / paths** - users can be promoted/demoted along multiple group tracks
* **Vault Support** - hooks into Vault to integrate with other plugins
* **Easy and simple setup and configuration using commands** - no editing yml files, yuck
* **Efficient/lightweight** - maybe? Who knows, it might be.
* **BungeeCord compatible** - permissions, users and groups are synced across Bukkit/BungeeCord instances
* **Support for MySQL, SQLite & Flatfile (JSON)** - other storage methods coming soon (maybe)
===== Possible Caveats
* Currently only supports MySQL, SQLite & Flatfile (JSON) (support for more methods might come in the future)
* Not at all tested and could produce unexpected/buggy results and errors
=== Setup
All configuration options are in the **config.yml** file, which is generated automagically when the plugin first starts.
You can define the settings for per-server permissions, the storage method and credentials within this file.
=== Commands
Command usage is printed to the console/chat whenever invalid arguments are provided. Simply typing /perms will list all commands a user has permission to use.
==== Aliases
| Bukkit | /luckperms |
| | /perms |
| | /permissions |
| | /lp |
| | /perm |
| Bungee | /luckpermsbungee |
| | /bperms |
| | /bpermissions |
| | /lpb |
| | /bperm |
Arguments: <required> [optional]
Users with OP have access to all commands.
Additionally, you can use wildcards to grant users access to a selection of commands.
* **All commands** - luckperms.*
* **All user commands** - luckperms.user.*
* **All group commands** - luckperms.group.*
* **All track commands** - luckperms.track.*
| **Command** | **Description** | **Permission** |
| /perms | Sends plugin info and usage | N/A |
| /perms sync | Runs an update task and reloads the data of all online users | luckperms.sync |
| /perms info | Shows information about the plugin | luckperms.info |
| /perms debug | Shows some very brief debug info about the number of users/groups loaded | luckperms.debug |
| | | |
| | | |
| | | |
| /perms creategroup <group> | Creates a new group with the given name | luckperms.creategroup |
| /perms deletegroup <group> | Deletes an existing group | luckperms.deletegroup |
| /perms listgroups | Shows a list of the groups registered within the system | luckperms.listgroups |
| | | |
| | | |
| | | |
| /perms createtrack <track> | Creates a new track with the given name | luckperms.createtrack |
| /perms deletetrack <track> | Deletes an existing track | luckperms.deletetrack |
| /perms listtracks | Shows a list of the tracks registered within the system | luckperms.listtracks |
| | | |
| | | |
| | | |
| /perms user <user> info | Shows info about the user | luckperms.user.info |
| /perms user <user> getuuid | Shows the users Mojang UUID | luckperms.user.getuuid |
| /perms user <user> listnodes | Lists all of the permission nodes the user has | luckperms.user.listnodes |
| /perms user <user> haspermission <node> [server] | Checks if the user has a permission on a certain server | luckperms.user.haspermission |
| /perms user <user> inheritspermission <node> [server] | Checks if the user inherits a permission on a certain server. (This checks all parent groups unlike haspermission) | luckperms.user.inheritspermission |
| /perms user <user> set <node> <true/false> [server]| Sets a permission for the user | luckperms.user.setpermission |
| /perms user <user> unset <node> [server] | Unsets a permission for the user | luckperms.user.unsetpermission |
| /perms user <user> addgroup <group> [server] | Adds the user to a group | luckperms.user.addgroup |
| /perms user <user> removegroup <group> [server] | Removes the user from a group | luckperms.user.removegroup |
| /perms user <user> setprimarygroup <group> | Sets the users primary group | luckperms.user.setprimarygroup |
| /perms user <user> showtracks | Shows a list of the tracks the user can be promoted/demoted on | luckperms.user.showtracks |
| /perms user <user> promote <track> | Promotes the user along a given track | luckperms.user.promote |
| /perms user <user> demote <track> | Demotes the user along a given track | luckperms.user.demote |
| /perms user <user> showpos <track> | Shows the users position on a given track | luckperms.user.showpos |
| /perms user <user> clear | Clears all permissions the user has | luckperms.user.clear |
| | | |
| | | |
| | | |
| /perms group <group> info | Shows info about the group | luckperms.group.info |
| /perms group <group> listnodes | Lists all of the permission nodes the group has | luckperms.group.listnodes |
| /perms group <group> haspermission <node> [server] | Checks if the group has a permission on a certain server | luckperms.group.haspermission |
| /perms group <group> inheritspermission <node> [server] | Checks if the group inherits a permission on a certain server. (This checks all parent groups unlike haspermission) | luckperms.group.inheritspermission |
| /perms group <group> set <node> <true/false> [server]| Sets a permission for the group | luckperms.group.setpermission |
| /perms group <group> unset <node> [server] | Unsets a permission for the group | luckperms.group.unsetpermission |
| /perms group <group> setinherit <group> [server]| Sets the group to inherit all permissions from another group | luckperms.group.setinherit |
| /perms group <group> unsetinherit <group> [server] | Unsets a perviously defined inheritance rule | luckperms.group.unsetinherit |
| /perms group <group> showtracks | Shows a list of the tracks that the users in the group can be promoted/demoted on | luckperms.group.showtracks |
| /perms group <group> clear | Clears all permissions the group has | luckperms.group.clear |
| | | |
| | | |
| | | |
| /perms track <track> info | Shows info about the track | luckperms.track.info |
| /perms track <track> append <group> | Appends a group to the end of the track | luckperms.track.append |
| /perms track <track> insert <group> <position> | Inserts a group at the given position on the track | luckperms.track.insert |
| /perms track <track> remove <group> | Removes a group from the track | luckperms.track.remove |
| /perms track <track> clear | Clears all groups on the track | luckperms.track.clear |
=== License
See LICENSE.md.
+250
View File
@@ -0,0 +1,250 @@
# LuckPerms [![Build Status](https://ci.lucko.me/job/LuckPerms/badge/icon)](https://ci.lucko.me/job/LuckPerms/)
A permissions implementation for Bukkit/Spigot, BungeeCord and Sponge.
## Links
* **Development Builds** - <https://ci.lucko.me/job/LuckPerms>
* **Javadocs** - <https://jd.lucko.me/LuckPerms>
## Features
* **Group inheritance** - users can be members of multiple groups, groups can inherit other groups
* **Temporary permissions** - users/groups can be given permissions that expire after a given time
* **Wildcard permissions** - users/groups can be given wildcard permissions (e.g. "minecraft.command.*"), even when plugins haven't implemented their own wildcards.
* **Temporary groups** - users/groups can be added to/inherit other groups temporarily
* **Multi-server support** - data is synced across all servers/platforms
* **Full offline-mode/mixed-mode support** - player permissions are synced properly over offline-mode or mixed online/offline-mode networks.
* **Per-server permissions/groups** - define user/group permissions that only apply on certain servers
* **Per-world permissions/groups** - define user/group permissions that only apply on certain worlds (on BungeeCord, a connected Bukkit/Spigot instance is treated as a world)
* **Tracks / paths / ladders** - users can be promoted/demoted along multiple group tracks
* **Vault Support** - hooks into Vault to integrate with other plugins
* **Developer API** - easily integrate LuckPerms into your own projects
* **Advanced action logging** - keep track of permission changes over time
* **Easy and simple setup and configuration using commands** - no editing yml files, yuck
* **Negated permissions and groups** - define special rules for certain users/groups
* **Regex permissions** - define special permissions using regex
* **Shorthand nodes** - add nodes using the LuckPerms shorthand system
* **Full support for UUIDs, even in Offline Mode** - users can change their usernames without losing permissions. In offline mode, a single user has the same internal UUID across a network.
* **Permission data stored within MySQL in a json format** - easily integrate the LuckPerms backend into your other projects
* **Well documented** - API methods have comprehensive Java docs, it's clear what each method does.
* **Efficient/lightweight** - maybe? Who knows, it might be.
* **Open Sourced, Free...** - you shouldn't have to pay $10+ for a "powerful" permissions plugin.
* **BungeeCord compatible** - permissions, users and groups are synced across all LuckPerms instances
* **Sponge compatible** - permissions, users and groups are synced across all LuckPerms instances (bukkit --> sponge, for example)
* **Support for MySQL, SQLite & Flatfile (JSON)** - other storage methods coming soon (maybe)
## Setup
All configuration options are in the **config.yml/luckperms.conf** file, which is generated automagically when the plugin first starts.
You can define the settings for per-server permissions, the storage method and credentials within this file.
## Info
### Permission Calculation
#### Permissions are calculated based on a priority system as follows.
* **Non wildcard/regex permissions will be overridden by normal permissions**
Example: if a user has a true permission set for "luckperms.\*", and a false permission set for "luckperms.something", the non-wildcard permission will override the wildcard, and "luckperms.something" will be set to false, despite the wildcard.
* **More specific wildcards override less specific ones**
Example: if a user has "luckperms.\*" set to true, but "luckperms.user.\*" set to false, all of the user permissions will be set to false, despite the more generic wildcard for "luckperms.*".
* **Temporary permissions will override non-temporary permissions.**
Example: if a user has a false permission set for "test.node", and a temporary true permission set for "test.node", the temporary permission will override the permanent one, and the user will be granted the true node.
* **World specific permissions will override generic permissions.**
Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission in the "world_nether" world, the world specific permission will override the globally defined one, and the user will be granted the negated node (provided they're in that world, of course.).
* **Server specific permissions will override generic/global permissions.**
Example: if a user has a global "fly.use" permission, and then has a negated "fly.use" permission on the "factions" server, the server specific permission will override the globally defined one, and the user will be granted the negated node (provided they're on that server).
* **Inherited permissions will be overridden by an objects own permissions.**
Example: A user is a member of the default group, which grants "some.thing.perm", but the users own permissions has "some.thing.perm" set to false. The inherited permission will be overridden by the users own permissions, and the user will be granted the negative node.
### Temporary Permissions
Temporary permissions are checked each time a user/group is loaded, and when the sync task runs. This means if you set a temporary permission to expire after 30 seconds, it won't actually be removed until the sync task runs.
The only way around this is to decrease the sync interval.
### Shorthand Permissions
LuckPerms has it's own system (although it's quite similar to PermissionsEx :P) that allows you to set permissions in a shorthand format.
Using the LuckPerms permission nodes as an example, say for instance, you wanted to let a user set and unset permissions for both groups and users.
Without shorthand, you would have to apply 4 nodes.
```
luckperms.user.setpermission
luckperms.user.unsetpermission
luckperms.group.setpermission
luckperms.group.unsetpermission
```
However, with shorthand, you can just apply the following node:
`luckperms.(user|group).(setpermission|unsetpermission)`
You use brackets to define part of a node as a shorthand group, and then use the vertical bar `|` to separate entries.
There are some limitations, firstly, you cannot use shorthand in the first part of the node. (The "luckperms" part in the example above)
Additionally, you cannot combine shorthand and normal text in the same part of the node.
For example, `luckperms.(user|group).(set|unset)permission` would not work.
### Regex
LuckPerms has support for regex when defining permission nodes and server/world names.
Whenever regex is used, it MUST be prefixed with "R=", so LuckPerms knows to treat it as regex, and not as a normal string.
For example, if you wanted to give all members of the default group, the `essentials.fly` permission on all of your hub servers, where the hub server names are hub1, hub2, hub3, etc.
You would use the command `/perms group default set essentials.fly true R=hub\d+`.
You can also use regex in permission nodes.
Once again using LuckPerms permissions as an example, if you wanted a user to be able to create both groups and tracks, you would normally just add the two permission nodes. However with regex, you can just add one. `luckperms\.create.*` Remember to escape any characters, specifically dots, as the entire node will be parsed.
## API
LuckPerms has an extensive API, allowing for easy integration with other projects. To use the Api, you need to obtain an instance of the `LuckPermsApi` interface. This can be done in a number of ways.
```java
// On all platforms (throws IllegalStateException if the API is not loaded)
final LuckPermsApi api = LuckPerms.getApi();
// Or with Optional
Optional<LuckPermsApi> provider = LuckPerms.getApiSafe();
if (provider.isPresent()) {
final LuckPermsApi api = provider.get();
}
// On Bukkit/Spigot
ServicesManager manager = Bukkit.getServicesManager();
if (manager.isProvidedFor(LuckPermsApi.class)) {
final LuckPermsApi api = manager.getRegistration(LuckPermsApi.class).getProvider();
}
// On Sponge
Optional<LuckPermsApi> provider = Sponge.getServiceManager().provide(LuckPermsApi.class);
if (provider.isPresent()) {
final LuckPermsApi api = provider.get();
}
```
If you want to use LuckPerms in your onEnable method, you need to add the following to your plugins `plugin.yml`.
```yml
depend: [LuckPerms]
```
All of the available methods can be seen in the various interfaces in the `luckperms-api` module.
You can add LuckPerms as a Maven dependency by adding the following to your projects `pom.xml`.
````xml
<repositories>
<repository>
<id>luck-repo</id>
<url>https://repo.lucko.me/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
````
## Versioning
As of version 2.0, LuckPerms roughly follows the standards set out in Semantic Versioning.
The only difference is that the patch number is not included anywhere within the pom, and is calculated each build, based upon how may commits have been made since the last tag. (A new tag is made every minor version)
This means that API versions do not have a patch number (as no API changes are made in patches). API versions will be x.y, and each individual build of LuckPerms will follow x.y.z.
## Commands
Command usage is printed to the console/chat whenever invalid arguments are provided. Simply typing /perms will list all commands a user has permission to use.
### Aliases
| Bukkit | Bungee |
|------------------|------------------|
| /luckperms | /luckpermsbungee |
| /perms | /bperms |
| /permissions | /bpermissions |
| /lp | /lpb |
| /perm | /bperm |
Arguments: \<required\> [optional]
Users with OP have access to all commands.
Additionally, you can use wildcards to grant users access to a selection of commands.
* **All commands** - luckperms.*
* **All user commands** - luckperms.user.*
* **All group commands** - luckperms.group.*
* **All track commands** - luckperms.track.*
### General
* /perms - n/a
* /perms sync - luckperms.sync
* /perms info - luckperms.info
* /perms debug - luckperms.debug
* /perms creategroup \<group\> - luckperms.creategroup
* /perms deletegroup \<group\> - luckperms.deletegroup
* /perms listgroups - luckperms.listgroups
* /perms createtrack \<track\> - luckperms.createtrack
* /perms deletetrack \<track\> - luckperms.deletetrack
* /perms listtracks - luckperms.listtracks
### User
* /perms user \<user\> info - luckperms.user.info
* /perms user \<user\> getuuid - luckperms.user.getuuid
* /perms user \<user\> listnodes - luckperms.user.listnodes
* /perms user \<user\> haspermission \<node\> [server] [world] - luckperms.user.haspermission
* /perms user \<user\> inheritspermission \<node\> [server] [world] - luckperms.user.inheritspermission
* /perms user \<user\> set \<node\> \<true/false\> [server] [world] - luckperms.user.setpermission
* /perms user \<user\> unset \<node\> [server] [world] - luckperms.user.unsetpermission
* /perms user \<user\> addgroup \<group\> [server] [world] - luckperms.user.addgroup
* /perms user \<user\> removegroup \<group\> [server] [world] - luckperms.user.removegroup
* /perms user \<user\> settemp \<node\> \<true/false\> \<duration\> [server] [world] - luckperms.user.settemppermission
* /perms user \<user\> unsettemp \<node\> [server] [world] - luckperms.user.unsettemppermission
* /perms user \<user\> addtempgroup \<group\> \<duration\> [server] [world] - luckperms.user.addtempgroup
* /perms user \<user\> removetempgroup \<group\> [server] [world] - luckperms.user.removetempgroup
* /perms user \<user\> setprimarygroup \<group\> - luckperms.user.setprimarygroup
* /perms user \<user\> showtracks - luckperms.user.showtracks
* /perms user \<user\> promote \<track\> - luckperms.user.promote
* /perms user \<user\> demote \<track\> - luckperms.user.demote
* /perms user \<user\> showpos \<track\> - luckperms.user.showpos
* /perms user \<user\> clear - luckperms.user.clear
### Group
* /perms group \<group\> info - luckperms.group.info
* /perms group \<group\> listnodes - luckperms.group.listnodes
* /perms group \<group\> haspermission \<node\> [server] [world] - luckperms.group.haspermission
* /perms group \<group\> inheritspermission \<node\> [server] [world] - luckperms.group.inheritspermission
* /perms group \<group\> set \<node\> \<true/false\> [server] [world] - luckperms.group.setpermission
* /perms group \<group\> unset \<node\> [server] [world] - luckperms.group.unsetpermission
* /perms group \<group\> setinherit \<group\> [server] [world] - luckperms.group.setinherit
* /perms group \<group\> unsetinherit \<group\> [server] [world] - luckperms.group.unsetinherit
* /perms group \<group\> settemp \<node\> \<true/false\> \<duration\> [server] [world] - settemppermission
* /perms group \<group\> unsettemp \<node\> [server] [world] - luckperms.group.unsettemppermission
* /perms group \<group\> settempinherit \<group\> \<duration\> [server] [world] - luckperms.group.settempinherit
* /perms group \<group\> unsettempinherit \<group\> [server] [world] - luckperms.group.unsettempinherit
* /perms group \<group\> showtracks - luckperms.group.showtracks
* /perms group \<group\> clear - luckperms.group.clear
### Track
* /perms track \<track\> info - luckperms.track.info
* /perms track \<track\> append \<group\> - luckperms.track.append
* /perms track \<track\> insert \<group\> \<position\> - luckperms.track.insert
* /perms track \<track\> remove \<group\> - luckperms.track.remove
* /perms track \<track\> clear - luckperms.track.clear
### Log
* /perms log recent [user] [page] - luckperms.log.recent
* /perms log search \<query\> [page] - luckperms.log.search
* /perms log notify [on|off] - luckperms.log.notify
* /perms log userhistory \<user\> [page] - luckperms.log.userhistory
* /perms log grouphistory \<group\> [page] - luckperms.log.grouphistory
* /perms log trackhistory \<track\> [page] - luckperms.log.trackhistory
## License
See LICENSE.md.
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luckperms-api</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import me.lucko.luckperms.api.LuckPermsApi;
import java.util.Optional;
/**
* Static access to LuckPerms
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class LuckPerms {
private static LuckPermsApi api = null;
/**
* Gets an instance of {@link LuckPermsApi}
* @return an api instance
* @throws IllegalStateException if the api is not loaded
*/
public static LuckPermsApi getApi() {
if (api == null) {
throw new IllegalStateException("API is not loaded.");
}
return api;
}
/**
* Gets an instance of {@link LuckPermsApi} safely. Unlike {@link LuckPerms#getApi}, this method will not throw an
* {@link IllegalStateException} if the api is not loaded, rather return an empty {@link Optional}.
* @return an optional api instance
*/
public static Optional<LuckPermsApi> getApiSafe() {
return Optional.ofNullable(api);
}
static void registerProvider(LuckPermsApi luckPermsApi) {
api = luckPermsApi;
}
static void unregisterProvider() {
api = null;
}
}
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.data.Callback;
import java.util.UUID;
/**
* Wrapper interface for the internal Datastore instance
*
* <p> The implementations of this interface limit access to the datastore and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the plugin.
*/
@SuppressWarnings("unused")
public interface Datastore {
String getName();
boolean isAcceptingLogins();
Async async();
Sync sync();
Future future();
interface Async {
void logAction(LogEntry entry, Callback<Boolean> callback);
void getLog(Callback<Log> callback);
void loadOrCreateUser(UUID uuid, String username, Callback<Boolean> callback);
void loadUser(UUID uuid, Callback<Boolean> callback);
void saveUser(User user, Callback<Boolean> callback);
void createAndLoadGroup(String name, Callback<Boolean> callback);
void loadGroup(String name, Callback<Boolean> callback);
void loadAllGroups(Callback<Boolean> callback);
void saveGroup(Group group, Callback<Boolean> callback);
void deleteGroup(Group group, Callback<Boolean> callback);
void createAndLoadTrack(String name, Callback<Boolean> callback);
void loadTrack(String name, Callback<Boolean> callback);
void loadAllTracks(Callback<Boolean> callback);
void saveTrack(Track track, Callback<Boolean> callback);
void deleteTrack(Track track, Callback<Boolean> callback);
void saveUUIDData(String username, UUID uuid, Callback<Boolean> callback);
void getUUID(String username, Callback<UUID> callback);
}
interface Sync {
boolean logAction(LogEntry entry);
Log getLog();
boolean loadOrCreateUser(UUID uuid, String username);
boolean loadUser(UUID uuid);
boolean saveUser(User user);
boolean createAndLoadGroup(String name);
boolean loadGroup(String name);
boolean loadAllGroups();
boolean saveGroup(Group group);
boolean deleteGroup(Group group);
boolean createAndLoadTrack(String name);
boolean loadTrack(String name);
boolean loadAllTracks();
boolean saveTrack(Track track);
boolean deleteTrack(Track track);
boolean saveUUIDData(String username, UUID uuid);
UUID getUUID(String username);
}
interface Future {
java.util.concurrent.Future<Boolean> logAction(LogEntry entry);
java.util.concurrent.Future<Log> getLog();
java.util.concurrent.Future<Boolean> loadOrCreateUser(UUID uuid, String username);
java.util.concurrent.Future<Boolean> loadUser(UUID uuid);
java.util.concurrent.Future<Boolean> saveUser(User user);
java.util.concurrent.Future<Boolean> createAndLoadGroup(String name);
java.util.concurrent.Future<Boolean> loadGroup(String name);
java.util.concurrent.Future<Boolean> loadAllGroups();
java.util.concurrent.Future<Boolean> saveGroup(Group group);
java.util.concurrent.Future<Boolean> deleteGroup(Group group);
java.util.concurrent.Future<Boolean> createAndLoadTrack(String name);
java.util.concurrent.Future<Boolean> loadTrack(String name);
java.util.concurrent.Future<Boolean> loadAllTracks();
java.util.concurrent.Future<Boolean> saveTrack(Track track);
java.util.concurrent.Future<Boolean> deleteTrack(Track track);
java.util.concurrent.Future<Boolean> saveUUIDData(String username, UUID uuid);
java.util.concurrent.Future<UUID> getUUID(String username);
}
}
@@ -0,0 +1,195 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
/**
* Wrapper interface for internal Group instances
*
* <p> The implementations of this interface limit access to the Group and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the group.
*/
@SuppressWarnings("unused")
public interface Group extends PermissionHolder {
/**
* @return the name of the group
*/
String getName();
/**
* check to see if a group inherits a group
* @param group The group to check membership of
* @return true if the user is a member of the group
*/
boolean inheritsGroup(Group group);
/**
* check to see if the group inherits a group on a specific server
* @param group The group to check membership of
* @param server The server to check on
* @return true if the group inherits the group
*/
boolean inheritsGroup(Group group, String server);
/**
* check to see if the group inherits a group on a specific server
* @param group The group to check membership of
* @param server The server to check on
* @param world The world to check on
* @return true if the group inherits the group
*/
boolean inheritsGroup(Group group, String server, String world);
/**
* Make this group inherit another group
* @param group the group to be inherited
* @throws ObjectAlreadyHasException if the group already inherits the group
*/
void setInheritGroup(Group group) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @param world The world to add the group on
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
* @param group the group to be inherited
* @param server The server to add the group on
* @param world The world to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
*/
void setInheritGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @param world The world to remove the group on
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server, String world) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance
* @param group the group to uninherit
* @param server The server to remove the group on
* @param world The world to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
*/
void unsetInheritGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
/**
* Clear all of the groups permission nodes
*/
void clearNodes();
/**
* Get a {@link List} of all of the groups the group inherits, on all servers
* @return a {@link List} of group names
*/
List<String> getGroupNames();
/**
* Get a {@link List} of the groups the group inherits on a specific server
* @param server the server to check
* @param world the world to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server, String world);
/**
* Get a {@link List} of the groups the group inherits on a specific server
* @param server the server to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server);
}
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.data.MySQLConfiguration;
/**
* A wrapper interface for the internal LuckPerms configuration, providing read only access.
*/
public interface LPConfiguration {
/**
* @return the name of this server
*/
String getServer();
/**
* @return how often a sync task will run in minutes
*/
int getSyncTime();
/**
* @return the default group, in a node representation
*/
String getDefaultGroupNode();
/**
* @return the name of the default group
*/
String getDefaultGroupName();
/**
* @return if the users on this server will have their global permissions applied
*/
boolean getIncludeGlobalPerms();
/**
* @return the online mode setting in the config
*/
boolean getOnlineMode();
/**
* @return if LuckPerms is applying wildcard permissions
*/
boolean getApplyWildcards();
/**
* @return if LuckPerms is resolving and applying regex permissions
*/
boolean getApplyRegex();
/**
* @return if LuckPerms is expanding shorthand permissions
*/
boolean getApplyShorthand();
/**
* @return the database values set in the configuration
*/
MySQLConfiguration getDatabaseValues();
/**
* @return the storage method string from the configuration
*/
String getStorageMethod();
}
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.UUID;
/**
* Represents the internal LuckPerms log.
* All content is immutable. You can add to the log using the {@link Datastore}, and then request an updated copy.
*/
@SuppressWarnings("unused")
public interface Log {
/**
* @return a {@link SortedSet} of all of the {@link LogEntry} objects in this {@link Log}
*/
SortedSet<LogEntry> getContent();
SortedSet<LogEntry> getRecent();
SortedMap<Integer, LogEntry> getRecent(int pageNo);
int getRecentMaxPages();
SortedSet<LogEntry> getRecent(UUID actor);
SortedMap<Integer, LogEntry> getRecent(int pageNo, UUID actor);
int getRecentMaxPages(UUID actor);
SortedSet<LogEntry> getUserHistory(UUID uuid);
SortedMap<Integer, LogEntry> getUserHistory(int pageNo, UUID uuid);
int getUserHistoryMaxPages(UUID uuid);
SortedSet<LogEntry> getGroupHistory(String name);
SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, String name);
int getGroupHistoryMaxPages(String name);
SortedSet<LogEntry> getTrackHistory(String name);
SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, String name);
int getTrackHistoryMaxPages(String name);
SortedSet<LogEntry> getSearch(String query);
SortedMap<Integer, LogEntry> getSearch(int pageNo, String query);
int getSearchMaxPages(String query);
}
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import lombok.*;
import java.util.UUID;
@Getter
@Builder
@ToString
@EqualsAndHashCode
@AllArgsConstructor
public final class LogEntry implements Comparable<LogEntry> {
private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
@NonNull private final long timestamp;
@NonNull private final UUID actor;
@NonNull private final String actorName;
@NonNull private final char type;
private final UUID acted;
@NonNull private final String actedName;
@NonNull private final String action;
@Override
public int compareTo(LogEntry o) {
return Long.compare(timestamp, o.getTimestamp());
}
public boolean matchesSearch(String query) {
query = query.toLowerCase();
return actorName.toLowerCase().contains(query) || actedName.toLowerCase().contains(query)
|| action.toLowerCase().contains(query);
}
public String getFormatted() {
return String.format(FORMAT,
getActorName(),
Character.toString(getType()),
getActedName(),
getAction()
);
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
/**
* A wrapper class for platform logger instances.
*
* <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.
*/
public interface Logger {
void info(String s);
void warn(String s);
void severe(String s);
}
@@ -0,0 +1,164 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
/**
* The root Api interface in LuckPerms
*/
@SuppressWarnings("unused")
public interface LuckPermsApi {
/**
* Schedules an update task to run
*/
void runUpdateTask();
/**
* @return the version of the plugin running on the platform
*/
String getVersion();
/**
* Gets a wrapped {@link LPConfiguration} instance, with read only access
* @return a configuration instance
*/
LPConfiguration getConfiguration();
/**
* Gets a wrapped {@link Datastore} instance, with somewhat limited access
* @return a datastore instance
*/
Datastore getDatastore();
/**
* Gets the {@link Logger} wrapping used by the platform
* @return the logger instance
*/
Logger getLogger();
/**
* Gets a wrapped {@link UuidCache} instance, providing read access to the LuckPerms internal uuid caching system
* @return a uuidcache instance
*/
UuidCache getUuidCache();
/**
* Gets a wrapped user object from the user storage
* @param uuid the uuid of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
*/
User getUser(UUID uuid);
/**
* Gets a wrapped user object from the user storage. This method does not return null, unlike {@link #getUser(UUID)}
* @param uuid the uuid of the user to get
* @return an optional {@link User} object
*/
Optional<User> getUserSafe(UUID uuid);
/**
* Gets a wrapped user object from the user storage
* @param name the username of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
*/
User getUser(String name);
/**
* Gets a wrapped user object from the user storage. This method does not return null, unlike {@link #getUser(String)}
* @param name the username of the user to get
* @return an optional {@link User} object
*/
Optional<User> getUserSafe(String name);
/**
* Gets a set of all loaded users.
* @return a {@link Set} of {@link User} objects
*/
Set<User> getUsers();
/**
* Check if a user is loaded in memory
* @param uuid the uuid to check for
* @return true if the user is loaded
*/
boolean isUserLoaded(UUID uuid);
/**
* Gets a wrapped group object from the group storage
* @param name the name of the group to get
* @return a {@link Group} object, if one matching the name exists, or null if not
*/
Group getGroup(String name);
/**
* Gets a wrapped group object from the group storage. This method does not return null, unlike {@link #getGroup}
* @param name the name of the group to get
* @return an optional {@link Group} object
*/
Optional<Group> getGroupSafe(String name);
/**
* Gets a set of all loaded groups.
* @return a {@link Set} of {@link Group} objects
*/
Set<Group> getGroups();
/**
* Check if a group is loaded in memory
* @param name the name to check for
* @return true if the group is loaded
*/
boolean isGroupLoaded(String name);
/**
* Gets a wrapped track object from the track storage
* @param name the name of the track to get
* @return a {@link Track} object, if one matching the name exists, or null if not
*/
Track getTrack(String name);
/**
* Gets a wrapped tracj object from the track storage. This method does not return null, unlike {@link #getTrack}
* @param name the name of the track to get
* @return an optional {@link Track} object
*/
Optional<Track> getTrackSafe(String name);
/**
* Gets a set of all loaded tracks.
* @return a {@link Set} of {@link Track} objects
*/
Set<Track> getTracks();
/**
* Check if a track is loaded in memory
* @param name the name to check for
* @return true if the track is loaded
*/
boolean isTrackLoaded(String name);
}
@@ -0,0 +1,319 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.Map;
/**
* Wrapper interface for internal PermissionHolder (user/group) instances
*
* <p> The implementations of this interface limit access to the object and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the object.
*/
@SuppressWarnings("unused")
public interface PermissionHolder {
String getObjectName();
Map<String, Boolean> getNodes();
/**
* Checks to see if the object has a certain permission
* @param node The permission node
* @param b If the node is true/false(negated)
* @return true if the user has the permission
*/
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 user has the permission
*/
boolean hasPermission(String node, boolean b, String server);
/**
* Checks to see the the object has a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @return true if the user has the permission
*/
boolean hasPermission(String node, boolean b, String server, String world);
/**
* Checks to see the the object has a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param temporary if the permission is temporary
* @return true if the user has the permission
*/
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 user has the permission
*/
boolean hasPermission(String node, boolean b, String server, 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 world The world to check on
* @param temporary if the permission is temporary
* @return true if the user has the permission
*/
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 user inherits the permission
*/
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 user inherits the permission
*/
boolean inheritsPermission(String node, boolean b, String server);
/**
* Checks to see the the object inherits a permission on a certain server
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @return true if the user inherits the permission
*/
boolean inheritsPermission(String node, boolean b, String server, String world);
/**
* Checks to see if the object inherits a certain permission
* @param node The permission node
* @param b If the node is true/false(negated)
* @param temporary if the permission is temporary
* @return true if the user inherits the permission
*/
boolean inheritsPermission(String node, boolean b, 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)
* @param server The server
* @param temporary if the permission is temporary
* @return true if the user inherits the permission
*/
boolean inheritsPermission(String node, boolean b, String server, 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)
* @param server The server
* @param world The world
* @param temporary if the permission is temporary
* @return true if the user inherits the permission
*/
boolean inheritsPermission(String node, boolean b, String server, String world, boolean temporary);
/**
* Sets a permission for the object
* @param node The node to be set
* @param value What to set the node to - true/false(negated)
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, String server) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param world The world to set the permission on
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, String server, String world) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, long expireAt) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param world The world to set the permission on
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
*/
void setPermission(String node, boolean value, String server, String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param temporary if the permission being removed is temporary
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, boolean temporary) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @param world The world to unset the node on
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server, String world) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @param temporary if the permission being unset is temporary
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server, boolean temporary) throws ObjectLacksException;
/**
* Unsets a permission for the object
* @param node The node to be unset
* @param server The server to unset the node on
* @param world The world to unset the node on
* @param temporary if the permission being unset is temporary
* @throws ObjectLacksException if the node wasn't already set
*/
void unsetPermission(String node, String server, String world, boolean temporary) throws ObjectLacksException;
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param world The world to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes);
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param world The world to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups);
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @param possibleNodes A list of possible permission nodes for wildcard permission handling
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes);
/**
* Gets the permissions and inherited permissions that apply to a specific server
* @param server The server to get nodes for
* @param excludedGroups Groups that shouldn't be inherited (to prevent circular inheritance issues)
* @return a {@link Map} of the permissions
*/
Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups);
/**
* Processes the objects and returns the temporary ones.
* @return a map of temporary nodes
*/
Map<Map.Entry<String, Boolean>, Long> getTemporaryNodes();
/**
* Processes the objects and returns the non-temporary ones.
* @return a map of permanent nodes
*/
Map<String, Boolean> getPermanentNodes();
/**
* Removes temporary permissions that have expired
*/
void auditTemporaryPermissions();
}
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
/**
* Wrapper interface for internal Track instances
*
* <p> The implementations of this interface limit access to the Track and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the track.
*/
@SuppressWarnings("unused")
public interface Track {
String getName();
/**
* Gets an ordered list of the groups on this track
* @return am ordered {@link List} of the groups on this track
*/
List<String> getGroups();
/**
* Gets the number of groups on this track
* @return the number of groups on this track
*/
int getSize();
/**
* Gets the next group on the track, after the one provided
* @param current the group before the group being requested
* @return the group name, or null if the end of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
*/
String getNext(Group current) throws ObjectLacksException;
/**
* Gets the group before the group provided
* @param current the group after the group being requested
* @return the group name, or null if the start of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
*/
String getPrevious(Group current) throws ObjectLacksException;
/**
* Appends a group to the end of this track
* @param group the group to append
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
*/
void appendGroup(Group group) throws ObjectAlreadyHasException;
/**
* Inserts a group at a certain position on this track
* @param group the group to be inserted
* @param position the index position (a value of 0 inserts at the start)
* @throws ObjectAlreadyHasException if the group is already on this track somewhere
* @throws IndexOutOfBoundsException if the position is less than 0 or greater than the size of the track
*/
void insertGroup(Group group, int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException;
/**
* Removes a group from this track
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
*/
void removeGroup(Group group) throws ObjectLacksException;
/**
* Removes a group from this track
* @param group the group to remove
* @throws ObjectLacksException if the group is not on this track
*/
void removeGroup(String group) throws ObjectLacksException;
/**
* Checks if a group features on this track
* @param group the group to check
* @return true if the group is on this track
*/
boolean containsGroup(Group group);
/**
* Checks if a group features on this track
* @param group the group to check
* @return true if the group is on this track
*/
boolean containsGroup(String group);
/**
* Clear all of the groups within this track
*/
void clearGroups();
}
@@ -0,0 +1,220 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.UUID;
/**
* Wrapper interface for internal User instances
*
* <p> The implementations of this interface limit access to the User and add parameter checks to further prevent
* errors and ensure all API interactions to not damage the state of the user.
*/
@SuppressWarnings("unused")
public interface User extends PermissionHolder {
/**
* @return the users Mojang assigned unique id
*/
UUID getUuid();
/**
* @return the Users Username
*/
String getName();
/**
* Gets the users primary group
* @return the users primary group
*/
String getPrimaryGroup();
/**
* Sets a users primary group
* @param s the new primary group
* @throws ObjectAlreadyHasException if the user already has this set as their primary group
*/
void setPrimaryGroup(String s) throws ObjectAlreadyHasException;
/**
* Refresh and re-assign the users permissions
*/
void refreshPermissions();
/**
* Check to see if the user is a member of a group
* @param group The group to check membership of
* @return true if the user is a member of the group
*/
boolean isInGroup(Group group);
/**
* Check to see if a user is a member of a group on a specific server
* @param group The group to check membership of
* @param server The server to check on
* @return true if the user is a member of the group
*/
boolean isInGroup(Group group, String server);
/**
* Check to see if a user is a member of a group on a specific server
* @param group The group to check membership of
* @param server The server to check on
* @param world The world to check on
* @return true if the user is a member of the group
*/
boolean isInGroup(Group group, String server, String world);
/**
* Add a user to a group
* @param group The group to add the user to
* @throws ObjectAlreadyHasException if the user is already a member of the group
*/
void addGroup(Group group) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @param world The world to add the group on
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server, String world) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
* @param group The group to add the user to
* @param server The server to add the group on
* @param world The world to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
*/
void addGroup(Group group, String server, String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove the user from a group
* @param group the group to remove the user from
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group the group to remove the user from
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param world The world to remove the group on
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server, String world) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param world The world to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
*/
void removeGroup(Group group, String server, String world, boolean temporary) throws ObjectLacksException;
/**
* Clear all of the users permission nodes
*/
void clearNodes();
/**
* Get a {@link List} of all of the groups the user is a member of, on all servers
* @return a {@link List} of group names
*/
List<String> getGroupNames();
/**
* Get a {@link List} of the groups the user is a member of on a specific server
* @param server the server to check
* @param world the world to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server, String world);
/**
* Get a {@link List} of the groups the user is a member of on a specific server
* @param server the server to check
* @return a {@link List} of group names
*/
List<String> getLocalGroups(String server);
}
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api;
import java.util.UUID;
/**
* This UuidCache is a means of allowing users to have the same internal UUID across a network of offline mode servers
* or mixed offline mode and online mode servers. Platforms running in offline mode generate a random UUID for a user when
* they first join the server, but this UUID will then not be consistent across the network. LuckPerms will instead check
* the datastore cache, to get a UUID for a user that is consistent across an entire network.
*
* <p> If you want to get a user object from the datastore using the api on a server in offline mode, you will need to use this cache,
* OR use Datastore#getUUID, for users that are not online.
*
* <p> WARNING: THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
*/
public interface UuidCache {
/**
* Gets a users internal "LuckPerms" UUID, from the one given by the server.
* @param external the UUID assigned by the server, through Player#getUniqueId or ProxiedPlayer#getUniqueId
* @return the corresponding internal UUID
*/
UUID getUUID(UUID external);
/**
* Gets a users external, server assigned or Mojang assigned unique id, from the internal one used within LuckPerms.
* @param internal the UUID used within LuckPerms, through User#getUuid
* @return the corresponding external UUID
*/
UUID getExternalUUID(UUID internal);
}
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.data;
import lombok.NonNull;
import java.util.function.Consumer;
public interface Callback<T> {
void onComplete(T t);
static <T> Callback<T> empty() {
return t -> {};
}
static <T> Callback<T> of(@NonNull Runnable runnable) {
return t -> runnable.run();
}
static <T> Callback<T> of(@NonNull Consumer<T> consumer) {
return consumer::accept;
}
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.data;
public interface MySQLConfiguration {
String getAddress();
String getDatabase();
String getUsername();
String getPassword();
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.exceptions;
/**
* Thrown when a permission holding object already has a permission, is already a member of a group, or when a track
* already contains a group.
*/
public class ObjectAlreadyHasException extends Exception {
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.exceptions;
/**
* Thrown when a permission holding object does not already have a permission, is not already a member of a group,
* or when a track doesn't contain a group.
*/
public class ObjectLacksException extends Exception {
}
+53 -9
View File
@@ -4,19 +4,17 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko</groupId>
<version>1.1</version>
<groupId>me.lucko.luckperms</groupId>
<version>2.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luckperms-bukkit</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>LuckPerms</name>
<build>
<defaultGoal>clean package</defaultGoal>
<finalName>LuckPerms</finalName>
<finalName>LuckPerms-${project.version}.${git.closest.tag.commit.count}</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<resources>
<resource>
@@ -46,10 +44,35 @@
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<relocations>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer.hikari</pattern>
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<injectAllReactorProjects>true</injectAllReactorProjects>
</configuration>
</plugin>
</plugins>
</build>
@@ -65,15 +88,36 @@
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.5</version>
<version>1.6</version>
<scope>provided</scope>
</dependency>
<!-- LuckPerms Common -->
<dependency>
<groupId>me.lucko</groupId>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-common</artifactId>
<version>${project.parent.version}</version>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<!-- LuckPerms API -->
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.4.7</version>
<scope>compile</scope>
</dependency>
<!-- slf4j library -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.9</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
</project>
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.commands.CommandManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import java.util.Arrays;
import java.util.List;
class BukkitCommand extends CommandManager implements CommandExecutor, TabExecutor {
BukkitCommand(LuckPermsPlugin plugin) {
super(plugin);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
onCommand(BukkitSenderFactory.get().wrap(sender), label, Arrays.asList(args), Callback.empty());
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
return onTabComplete(BukkitSenderFactory.get().wrap(sender), Arrays.asList(args));
}
}
@@ -1,72 +1,77 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.utils.LPConfiguration;
import me.lucko.luckperms.core.LPConfiguration;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
public class BukkitConfig implements LPConfiguration {
private final LPBukkitPlugin plugin;
class BukkitConfig extends LPConfiguration<LPBukkitPlugin> {
private YamlConfiguration configuration;
public BukkitConfig(LPBukkitPlugin plugin) {
this.plugin = plugin;
create();
BukkitConfig(LPBukkitPlugin plugin) {
super(plugin, "global", true, "sqlite");
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private void create() {
File configFile = new File(plugin.getDataFolder(), "config.yml");
@Override
protected void init() {
File configFile = new File(getPlugin().getDataFolder(), "config.yml");
if (!configFile.exists()) {
configFile.getParentFile().mkdirs();
plugin.saveResource("config.yml", false);
getPlugin().saveResource("config.yml", false);
}
configuration = new YamlConfiguration();
try {
configuration.load(configFile);
} catch (InvalidConfigurationException | IOException e) {
e.printStackTrace();
}
}
@Override
public String getServer() {
return configuration.getString("server", "global");
protected void set(String path, Object value) {
configuration.set(path, value);
}
@Override
public int getSyncTime() {
return configuration.getInt("sql.sync-minutes", 3);
protected String getString(String path, String def) {
return configuration.getString(path, def);
}
@Override
public String getDefaultGroupNode() {
return "group." + configuration.getString("default-group", "default");
protected int getInt(String path, int def) {
return configuration.getInt(path, def);
}
@Override
public String getDefaultGroupName() {
return configuration.getString("default-group", "default");
}
@Override
public boolean getIncludeGlobalPerms() {
return configuration.getBoolean("include-global", true);
}
@Override
public String getDatabaseValue(String value) {
return configuration.getString("sql." + value);
}
@Override
public String getStorageMethod() {
return configuration.getString("storage-method", "sqlite");
protected boolean getBoolean(String path, boolean def) {
return configuration.getBoolean(path, def);
}
}
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.users.BukkitUser;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.AbstractListener;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.*;
class BukkitListener extends AbstractListener implements Listener {
private final LPBukkitPlugin plugin;
BukkitListener(LPBukkitPlugin plugin) {
super(plugin);
this.plugin = plugin;
}
@EventHandler
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
if (!plugin.getDatastore().isAcceptingLogins()) {
// Datastore is disabled, prevent players from joining the server
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
return;
}
onAsyncLogin(e.getUniqueId(), e.getName());
}
@EventHandler
public void onPlayerLogin(PlayerLoginEvent e) {
final Player player = e.getPlayer();
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
if (user == null) {
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
return;
}
if (user instanceof BukkitUser) {
BukkitUser u = (BukkitUser) user;
u.setAttachment(player.addAttachment(plugin));
}
user.refreshPermissions();
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
// Refresh permissions again
refreshPlayer(e.getPlayer().getUniqueId());
}
@EventHandler
public void onPlayerChangedWorld(PlayerChangedWorldEvent e) {
refreshPlayer(e.getPlayer().getUniqueId());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
onLeave(e.getPlayer().getUniqueId());
}
}
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import me.lucko.luckperms.commands.SenderFactory;
import me.lucko.luckperms.constants.Constants;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.UUID;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BukkitSenderFactory extends SenderFactory<CommandSender> {
private static BukkitSenderFactory instance = null;
public static BukkitSenderFactory get() {
if (instance == null){
instance = new BukkitSenderFactory();
}
return instance;
}
@Override
protected String getName(CommandSender sender) {
if (sender instanceof Player) {
return sender.getName();
}
return Constants.getConsoleName();
}
@Override
protected UUID getUuid(CommandSender sender) {
if (sender instanceof Player) {
return ((Player) sender).getUniqueId();
}
return Constants.getConsoleUUID();
}
@Override
protected void sendMessage(CommandSender sender, String s) {
sender.sendMessage(s);
}
@Override
protected boolean hasPermission(CommandSender sender, String node) {
return sender.hasPermission(node);
}
}
@@ -1,49 +0,0 @@
package me.lucko.luckperms;
import me.lucko.luckperms.commands.CommandManager;
import me.lucko.luckperms.commands.Sender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.List;
class CommandManagerBukkit extends CommandManager implements CommandExecutor, TabExecutor {
CommandManagerBukkit(LuckPermsPlugin plugin) {
super(plugin);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
return onCommand(makeSender(sender), label, Arrays.asList(args));
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
return onTabComplete(makeSender(sender), Arrays.asList(args));
}
private static Sender makeSender(CommandSender sender) {
return new Sender() {
final WeakReference<CommandSender> cs = new WeakReference<>(sender);
@Override
public void sendMessage(String s) {
final CommandSender c = cs.get();
if (c != null) {
c.sendMessage(s);
}
}
@Override
public boolean hasPermission(String node) {
final CommandSender c = cs.get();
return c != null && c.hasPermission(node);
}
};
}
}
@@ -1,85 +1,118 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import lombok.Getter;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.data.MySQLConfiguration;
import me.lucko.luckperms.data.methods.FlatfileDatastore;
import me.lucko.luckperms.data.methods.MySQLDatastore;
import me.lucko.luckperms.data.methods.SQLiteDatastore;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.implementation.ApiProvider;
import me.lucko.luckperms.api.vault.VaultHook;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.core.LPConfiguration;
import me.lucko.luckperms.core.UuidCache;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.listeners.PlayerListener;
import me.lucko.luckperms.runnables.UpdateTask;
import me.lucko.luckperms.storage.Datastore;
import me.lucko.luckperms.storage.methods.FlatfileDatastore;
import me.lucko.luckperms.storage.methods.MySQLDatastore;
import me.lucko.luckperms.storage.methods.SQLiteDatastore;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.BukkitUserManager;
import me.lucko.luckperms.users.UserManager;
import me.lucko.luckperms.utils.LPConfiguration;
import me.lucko.luckperms.vaulthooks.VaultHook;
import org.bukkit.Bukkit;
import me.lucko.luckperms.utils.LogFactory;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
@Getter
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
public static final String VERSION = "v1.1";
private final Set<UUID> ignoringLogs = new HashSet<>();
private LPConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
private UuidCache uuidCache;
private Logger log;
@Override
public void onEnable() {
log = LogFactory.wrap(getLogger());
getLog().info("Loading configuration...");
configuration = new BukkitConfig(this);
// register events
PluginManager pm = Bukkit.getPluginManager();
pm.registerEvents(new PlayerListener(this), this);
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(new BukkitListener(this), this);
// register commands
CommandManagerBukkit commandManager = new CommandManagerBukkit(this);
getLog().info("Registering commands...");
BukkitCommand commandManager = new BukkitCommand(this);
PluginCommand main = getServer().getPluginCommand("luckperms");
main.setExecutor(commandManager);
main.setTabCompleter(commandManager);
main.setAliases(Arrays.asList("perms", "lp", "permissions", "p", "perm"));
getLog().info("Detecting storage method...");
final String storageMethod = configuration.getStorageMethod();
if (storageMethod.equalsIgnoreCase("mysql")) {
getLogger().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(this, new MySQLConfiguration(
configuration.getDatabaseValue("address"),
configuration.getDatabaseValue("database"),
configuration.getDatabaseValue("username"),
configuration.getDatabaseValue("password")
));
getLog().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(this, configuration.getDatabaseValues());
} else if (storageMethod.equalsIgnoreCase("sqlite")) {
getLogger().info("Using SQLite as storage method.");
getLog().info("Using SQLite as storage method.");
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
} else if (storageMethod.equalsIgnoreCase("flatfile")) {
getLogger().info("Using Flatfile (JSON) as storage method.");
getLog().info("Using Flatfile (JSON) as storage method.");
datastore = new FlatfileDatastore(this, getDataFolder());
} else {
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
getLog().severe("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
}
getLog().info("Initialising datastore...");
datastore.init();
getLog().info("Loading internal permission managers...");
uuidCache = new UuidCache(getConfiguration().getOnlineMode());
userManager = new BukkitUserManager(this);
groupManager = new GroupManager(this);
trackManager = new TrackManager(this);
trackManager = new TrackManager();
// Run update task to refresh any online users
runUpdateTask();
getLog().info("Scheduling Update Task to refresh any online users.");
try {
new UpdateTask(this).run();
} catch (Exception e) {
e.printStackTrace();
}
int mins = getConfiguration().getSyncTime();
if (mins > 0) {
@@ -87,39 +120,58 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
getServer().getScheduler().runTaskTimerAsynchronously(this, new UpdateTask(this), ticks, ticks);
}
getServer().getScheduler().runTaskTimer(this, BukkitSenderFactory.get(), 1L, 1L);
// Provide vault support
if (getServer().getPluginManager().isPluginEnabled("Vault")) {
VaultHook.hook(this);
getLogger().info("Registered Vault permission & chat hook.");
} else {
getLogger().info("Vault not found.");
getLog().info("Attempting to hook into Vault...");
try {
if (getServer().getPluginManager().isPluginEnabled("Vault")) {
VaultHook.hook(this);
getLog().info("Registered Vault permission & chat hook.");
} else {
getLog().info("Vault not found.");
}
} catch (Exception e) {
getLog().severe("Error occurred whilst hooking into Vault.");
e.printStackTrace();
}
getLog().info("Registering API...");
final ApiProvider provider = new ApiProvider(this);
LuckPerms.registerProvider(provider);
getServer().getServicesManager().register(LuckPermsApi.class, provider, this, ServicePriority.Normal);
getLog().info("Successfully loaded.");
}
@Override
public void onDisable() {
getLog().info("Closing datastore...");
datastore.shutdown();
getLog().info("Unregistering API...");
LuckPerms.unregisterProvider();
getServer().getServicesManager().unregisterAll(this);
}
@Override
public void doAsync(Runnable r) {
Bukkit.getScheduler().runTaskAsynchronously(this, r);
getServer().getScheduler().runTaskAsynchronously(this, r);
}
@Override
public void doSync(Runnable r) {
Bukkit.getScheduler().runTask(this, r);
getServer().getScheduler().runTask(this, r);
}
@Override
public String getVersion() {
return VERSION;
return getDescription().getVersion();
}
@Override
public String getPlayerStatus(UUID uuid) {
return getServer().getPlayer(uuid) != null ? "&aOnline" : "&cOffline";
public Message getPlayerStatus(UUID uuid) {
return getServer().getPlayer(getUuidCache().getExternalUUID(uuid)) != null ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
}
@Override
@@ -132,6 +184,23 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
return getServer().getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
}
@Override
public List<Sender> getSenders() {
return getServer().getOnlinePlayers().stream().map(p -> BukkitSenderFactory.get().wrap(p)).collect(Collectors.toList());
}
@Override
public List<String> getPossiblePermissions() {
final List<String> perms = new ArrayList<>();
getServer().getPluginManager().getPermissions().forEach(p -> {
perms.add(p.getName());
p.getChildren().keySet().forEach(perms::add);
});
return perms;
}
@Override
public void runUpdateTask() {
getServer().getScheduler().runTaskAsynchronously(this, new UpdateTask(this));
@@ -1,4 +1,26 @@
package me.lucko.luckperms.vaulthooks;
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.vault;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission;
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.vault;
import me.lucko.luckperms.LPBukkitPlugin;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.ServicesManager;
public class VaultHook {
private static VaultChatHook chatHook = null;
private static VaultPermissionHook permissionHook = null;
public static void hook(LPBukkitPlugin plugin) {
try {
if (permissionHook == null) {
permissionHook = new VaultPermissionHook();
}
permissionHook.setPlugin(plugin);
if (chatHook == null) {
chatHook = new VaultChatHook(permissionHook);
}
final ServicesManager sm = plugin.getServer().getServicesManager();
sm.unregisterAll(plugin);
sm.register(Permission.class, permissionHook, plugin, ServicePriority.High);
sm.register(Chat.class, chatHook, plugin, ServicePriority.Lowest);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.vault;
import lombok.NonNull;
import lombok.Setter;
import me.lucko.luckperms.LPBukkitPlugin;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.core.PermissionHolder;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.users.User;
import net.milkbowl.vault.permission.Permission;
class VaultPermissionHook extends Permission {
@Setter
private LPBukkitPlugin plugin;
@Override
public String getName() {
return "LuckPerms";
}
@Override
public boolean isEnabled() {
return plugin.getDatastore().isAcceptingLogins();
}
@Override
public boolean hasSuperPermsCompat() {
return true;
}
private boolean objectHas(String world, PermissionHolder object, String permission) {
if (object == null) return false;
if (world != null && !world.equals("")) {
return object.hasPermission(permission, true, "global", world);
} else {
return object.hasPermission(permission, true);
}
}
private boolean objectAdd(String world, PermissionHolder object, String permission) {
if (object == null) return false;
try {
if (world != null && !world.equals("")) {
object.setPermission(permission, true, "global", world);
} else {
object.setPermission(permission, true);
}
} catch (ObjectAlreadyHasException ignored) {}
objectSave(object);
return true;
}
private boolean objectRemove(String world, PermissionHolder object, String permission) {
if (object == null) return false;
try {
if (world != null && !world.equals("")) {
object.unsetPermission(permission, "global", world);
} else {
object.unsetPermission(permission);
}
} catch (ObjectLacksException ignored) {}
objectSave(object);
return true;
}
private void objectSave(PermissionHolder t) {
if (t instanceof User) {
((User) t).refreshPermissions();
plugin.getDatastore().saveUser(((User) t), Callback.empty());
}
if (t instanceof Group) {
plugin.getDatastore().saveGroup(((Group) t), c -> plugin.runUpdateTask());
}
}
@Override
public boolean playerHas(String world, @NonNull String player, @NonNull String permission) {
return objectHas(world, plugin.getUserManager().get(player), permission);
}
@Override
public boolean playerAdd(String world, @NonNull String player, @NonNull String permission) {
final User user = plugin.getUserManager().get(player);
return objectAdd(world, user, permission);
}
@Override
public boolean playerRemove(String world, @NonNull String player, @NonNull String permission) {
final User user = plugin.getUserManager().get(player);
return objectRemove(world, user, permission);
}
@Override
public boolean groupHas(String world, @NonNull String groupName, @NonNull String permission) {
final Group group = plugin.getGroupManager().get(groupName);
return objectHas(world, group, permission);
}
@Override
public boolean groupAdd(String world, @NonNull String groupName, @NonNull String permission) {
final Group group = plugin.getGroupManager().get(groupName);
return objectAdd(world, group, permission);
}
@Override
public boolean groupRemove(String world, @NonNull String groupName, @NonNull String permission) {
final Group group = plugin.getGroupManager().get(groupName);
return objectRemove(world, group, permission);
}
@Override
public boolean playerInGroup(String world, @NonNull String player, @NonNull String group) {
final User user = plugin.getUserManager().get(player);
if (user == null) return false;
final Group group1 = plugin.getGroupManager().get(group);
if (group1 == null) return false;
if (world != null && !world.equals("")) {
return user.isInGroup(group1, "global", world);
} else {
return user.isInGroup(group1);
}
}
@Override
public boolean playerAddGroup(String world, @NonNull String player, @NonNull String groupName) {
final User user = plugin.getUserManager().get(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().get(groupName);
if (group == null) return false;
try {
if (world != null && !world.equals("")) {
user.addGroup(group, "global", world);
} else {
user.addGroup(group);
}
} catch (ObjectAlreadyHasException ignored) {}
objectSave(user);
return true;
}
@Override
public boolean playerRemoveGroup(String world, @NonNull String player, @NonNull String groupName) {
final User user = plugin.getUserManager().get(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().get(groupName);
if (group == null) return false;
try {
if (world != null && !world.equals("")) {
user.removeGroup(group, "global", world);
} else {
user.removeGroup(group);
}
} catch (ObjectLacksException ignored) {}
objectSave(user);
return true;
}
@Override
public String[] getPlayerGroups(String world, @NonNull String player) {
final User user = plugin.getUserManager().get(player);
return (user == null) ? new String[0] :
world != null && !world.equals("") ? user.getLocalGroups("global", world).toArray(new String[0]) :
user.getGroupNames().toArray(new String[0]);
}
@Override
public String getPrimaryGroup(String world, @NonNull String player) {
final User user = plugin.getUserManager().get(player);
return (user == null) ? null : user.getPrimaryGroup();
}
@Override
public String[] getGroups() {
return plugin.getGroupManager().getAll().keySet().toArray(new String[0]);
}
@Override
public boolean hasGroupSupport() {
return true;
}
}
@@ -1,72 +0,0 @@
package me.lucko.luckperms.listeners;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.LPBukkitPlugin;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.users.BukkitUser;
import me.lucko.luckperms.users.User;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
@AllArgsConstructor
public class PlayerListener implements Listener {
private final LPBukkitPlugin plugin;
@EventHandler
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
if (!plugin.getDatastore().isAcceptingLogins()) {
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
Util.color(Message.PREFIX + "Error whilst validating login with the network. \nPlease contact an administrator."));
return;
}
plugin.getDatastore().loadOrCreateUser(e.getUniqueId(), e.getName());
}
@EventHandler
public void onPlayerLogin(PlayerLoginEvent e) {
Player player = e.getPlayer();
User user = plugin.getUserManager().getUser(player.getUniqueId());
if (user == null) {
e.disallow(PlayerLoginEvent.Result.KICK_OTHER,
Util.color(Message.PREFIX + "User data could not be loaded. Please contact an administrator."));
return;
}
if (user instanceof BukkitUser) {
BukkitUser u = (BukkitUser) user;
u.setAttachment(player.addAttachment(plugin));
}
user.refreshPermissions();
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
// Save UUID data for the player
plugin.getDatastore().saveUUIDData(e.getPlayer().getName(), e.getPlayer().getUniqueId(), success -> {});
User user = plugin.getUserManager().getUser(e.getPlayer().getUniqueId());
if (user != null) {
// Refresh permissions again
user.refreshPermissions();
}
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
Player player = e.getPlayer();
// Unload the user from memory when they disconnect
User user = plugin.getUserManager().getUser(player.getUniqueId());
plugin.getUserManager().unloadUser(user);
}
}
@@ -1,16 +1,51 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.users;
import lombok.Getter;
import lombok.Setter;
import me.lucko.luckperms.LPBukkitPlugin;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionAttachment;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.UUID;
public class BukkitUser extends User {
private static Field permissionsField = null;
private static Field getPermissionsField() {
if (permissionsField == null) {
try {
permissionsField = PermissionAttachment.class.getDeclaredField("permissions");
permissionsField.setAccessible(true);
} catch (SecurityException | NoSuchFieldException e) {
e.printStackTrace();
}
}
return permissionsField;
}
private final LPBukkitPlugin plugin;
@@ -28,23 +63,47 @@ public class BukkitUser extends User {
this.plugin = plugin;
}
@SuppressWarnings("unchecked")
@Override
public void refreshPermissions() {
plugin.doSync(() -> {
Player player = Bukkit.getPlayer(getUuid());
final Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(getUuid()));
if (player == null) return;
if (attachment == null) {
getPlugin().getLogger().warning("User " + getName() + " does not have a permissions attachment defined.");
getPlugin().getLog().warn("User " + getName() + " does not have a permissions attachment defined.");
setAttachment(player.addAttachment(plugin));
}
// Clear existing permissions
attachment.getPermissions().keySet().forEach(p -> attachment.setPermission(p, false));
// Calculate the permissions that should be applied
Map<String, Boolean> toApply = getLocalPermissions(getPlugin().getConfiguration().getServer(), player.getWorld().getName(), null);
// Re-add all defined permissions for the user
Map<String, Boolean> local = getLocalPermissions(getPlugin().getConfiguration().getServer(), null);
local.entrySet().forEach(e -> attachment.setPermission(e.getKey(), e.getValue()));
try {
Map<String, Boolean> existing = (Map<String, Boolean>) getPermissionsField().get(attachment);
boolean different = false;
if (toApply.size() != existing.size()) {
different = true;
} else {
for (Map.Entry<String, Boolean> e : existing.entrySet()) {
if (toApply.containsKey(e.getKey()) && toApply.get(e.getKey()) == e.getValue()) {
continue;
}
different = true;
break;
}
}
if (!different) return;
// Faster than recalculating permissions after each PermissionAttachment#setPermission
existing.clear();
existing.putAll(toApply);
attachment.getPermissible().recalculatePermissions();
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
@@ -1,10 +1,33 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.users;
import me.lucko.luckperms.LPBukkitPlugin;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
public class BukkitUserManager extends UserManager {
private final LPBukkitPlugin plugin;
@@ -15,14 +38,14 @@ public class BukkitUserManager extends UserManager {
}
@Override
public void unloadUser(User user) {
public void unload(User user) {
if (user != null) {
if (user instanceof BukkitUser) {
BukkitUser u = (BukkitUser) user;
if (u.getAttachment() != null) {
Player player = Bukkit.getPlayer(u.getUuid());
Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(u.getUuid()));
if (player != null) {
player.removeAttachment(u.getAttachment());
@@ -31,29 +54,35 @@ public class BukkitUserManager extends UserManager {
}
}
getUsers().remove(user.getUuid());
getAll().remove(user.getUuid());
}
}
@Override
public void cleanupUser(User user) {
if (Bukkit.getPlayer(user.getUuid()) == null) {
unloadUser(user);
public void cleanup(User user) {
if (plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(user.getUuid())) == null) {
unload(user);
}
}
@Override
public User makeUser(UUID uuid) {
public User make(UUID uuid) {
return new BukkitUser(uuid, plugin);
}
@Override
public User makeUser(UUID uuid, String username) {
public User make(UUID uuid, String username) {
return new BukkitUser(uuid, username, plugin);
}
@Override
public void updateAllUsers() {
plugin.getServer().getOnlinePlayers().stream().map(Player::getUniqueId).forEach(u -> plugin.getDatastore().loadUser(u));
// Sometimes called async, so we need to get the players on the Bukkit thread.
plugin.doSync(() -> {
Set<UUID> players = plugin.getServer().getOnlinePlayers().stream()
.map(p -> plugin.getUuidCache().getUUID(p.getUniqueId()))
.collect(Collectors.toSet());
plugin.doAsync(() -> players.forEach(u -> plugin.getDatastore().loadUser(u)));
});
}
}
@@ -1,36 +0,0 @@
package me.lucko.luckperms.vaulthooks;
import me.lucko.luckperms.LPBukkitPlugin;
import net.milkbowl.vault.chat.Chat;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.ServicesManager;
public class VaultHook {
private static VaultChatHook chatHook = null;
private static VaultPermissionHook permissionHook = null;
public static void hook(LPBukkitPlugin plugin) {
try {
if (permissionHook == null) {
permissionHook = new VaultPermissionHook();
}
permissionHook.setPlugin(plugin);
if (chatHook == null) {
chatHook = new VaultChatHook(permissionHook);
}
final ServicesManager sm = plugin.getServer().getServicesManager();
sm.unregisterAll(plugin);
sm.register(Permission.class, permissionHook, plugin, ServicePriority.High);
sm.register(Chat.class, chatHook, plugin, ServicePriority.Lowest);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -1,152 +0,0 @@
package me.lucko.luckperms.vaulthooks;
import lombok.Setter;
import me.lucko.luckperms.LPBukkitPlugin;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.users.User;
import net.milkbowl.vault.permission.Permission;
class VaultPermissionHook extends Permission {
@Setter
private LPBukkitPlugin plugin;
@Override
public String getName() {
return "LuckPerms";
}
@Override
public boolean isEnabled() {
return plugin.getDatastore().isAcceptingLogins();
}
@Override
public boolean hasSuperPermsCompat() {
// Idk???
return true;
}
@Override
public boolean playerHas(String world, String player, String permission) {
final User user = plugin.getUserManager().getUser(player);
return user != null && user.hasPermission(permission, true);
}
@Override
public boolean playerAdd(String world, String player, String permission) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
try {
user.setPermission(permission, true);
} catch (ObjectAlreadyHasException ignored) {}
plugin.getUserManager().saveUser(user, plugin.getDatastore());
return true;
}
@Override
public boolean playerRemove(String world, String player, String permission) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
try {
user.unsetPermission(permission);
} catch (ObjectLacksException ignored) {}
plugin.getUserManager().saveUser(user, plugin.getDatastore());
return true;
}
@Override
public boolean groupHas(String world, String groupName, String permission) {
final Group group = plugin.getGroupManager().getGroup(groupName);
return group != null && group.hasPermission(permission, true);
}
@Override
public boolean groupAdd(String world, String groupName, String permission) {
final Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) return false;
try {
group.setPermission(permission, true);
} catch (ObjectAlreadyHasException ignored) {}
plugin.runUpdateTask();
return true;
}
@Override
public boolean groupRemove(String world, String groupName, String permission) {
final Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) return false;
try {
group.unsetPermission(permission);
} catch (ObjectLacksException ignored) {}
plugin.runUpdateTask();
return true;
}
@Override
public boolean playerInGroup(String world, String player, String group) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
final Group group1 = plugin.getGroupManager().getGroup(group);
return group1 != null && user.isInGroup(group1);
}
@Override
public boolean playerAddGroup(String world, String player, String groupName) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) return false;
try {
user.addGroup(group);
} catch (ObjectAlreadyHasException ignored) {}
plugin.getUserManager().saveUser(user, plugin.getDatastore());
return true;
}
@Override
public boolean playerRemoveGroup(String world, String player, String groupName) {
final User user = plugin.getUserManager().getUser(player);
if (user == null) return false;
final Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) return false;
try {
user.removeGroup(group);
} catch (ObjectLacksException ignored) {}
plugin.getUserManager().saveUser(user, plugin.getDatastore());
return true;
}
@Override
public String[] getPlayerGroups(String world, String player) {
final User user = plugin.getUserManager().getUser(player);
return (user == null) ? new String[0] : user.getGroupNames().toArray(new String[0]);
}
@Override
public String getPrimaryGroup(String world, String player) {
final User user = plugin.getUserManager().getUser(player);
return (user == null) ? null : user.getPrimaryGroup();
}
@Override
public String[] getGroups() {
return plugin.getGroupManager().getGroups().keySet().toArray(new String[0]);
}
@Override
public boolean hasGroupSupport() {
return true;
}
}
+28
View File
@@ -9,6 +9,34 @@ default-group: default
# If users on this server should have their global permissions/groups applied.
include-global: true
# If this server is in offline or online mode.
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
# You should generally reflect the setting in server.properties here. Except when...
# 1. You have Spigot servers connected to a BungeeCord proxy, with online-mode set to false, but 'bungeecord' set to true in the spigot.yml
# AND 'ip-forward' set to true in the BungeeCord config.yml
# In this case, set online-mode in LuckPerms to true, despite the server being in offline mode.
# 2. You are only running one server instance using LuckPerms, (not a network)
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
online-mode: true
# If the plugin should apply wildcard permissions.
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
# the wildcard. This will only work for plugins that define all of their permissions to the server.
apply-wildcards: true
# If the plugin should parse regex permissions.
# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve &
# apply all registered permissions matching the regex. This will only work for plugins that define all of their
# permissions to the server.
apply-regex: true
# If the plugin should complete and apply shorthand permissions.
# If set to true, LuckPerms will detect and expand shorthand node patterns.
apply-shorthand: true
# Which storage method the plugin should use.
# Currently supported: mysql, sqlite, flatfile
# Fill out connection info below if you're using MySQL
+117 -2
View File
@@ -1,10 +1,125 @@
name: LuckPerms
author: Luck
version: 1.1
version: ${project.version}.${git.closest.tag.commit.count}
main: me.lucko.luckperms.LPBukkitPlugin
softdepend: [Vault]
description: A permissions plugin
commands:
luckperms:
description: Manage permissions
aliases: [perms, permissions, lp, p, perm]
aliases: [perms, permissions, lp, p, perm]
permissions:
luckperms.*:
description: Gives access to all LuckPerms commands
children:
luckperms.sync: true
luckperms.info: true
luckperms.debug: true
luckperms.creategroup: true
luckperms.deletegroup: true
luckperms.listgroups: true
luckperms.createtrack: true
luckperms.deletetrack: true
luckperms.listtracks: true
luckperms.user.info: true
luckperms.user.getuuid: true
luckperms.user.listnodes: true
luckperms.user.haspermission: true
luckperms.user.inheritspermission: true
luckperms.user.setpermission: true
luckperms.user.unsetpermission: true
luckperms.user.addgroup: true
luckperms.user.removegroup: true
luckperms.user.settemppermission: true
luckperms.user.unsettemppermission: true
luckperms.user.addtempgroup: true
luckperms.user.removetempgroup: true
luckperms.user.setprimarygroup: true
luckperms.user.showtracks: true
luckperms.user.promote: true
luckperms.user.demote: true
luckperms.user.showpos: true
luckperms.user.clear: true
luckperms.group.info: true
luckperms.group.listnodes: true
luckperms.group.haspermission: true
luckperms.group.inheritspermission: true
luckperms.group.setpermission: true
luckperms.group.unsetpermission: true
luckperms.group.setinherit: true
luckperms.group.unsetinherit: true
luckperms.group.settemppermission: true
luckperms.group.unsettemppermission: true
luckperms.group.settempinherit: true
luckperms.group.unsettempinherit: true
luckperms.group.showtracks: true
luckperms.group.clear: true
luckperms.track.info: true
luckperms.track.append: true
luckperms.track.insert: true
luckperms.track.remove: true
luckperms.track.clear: true
luckperms.log.export: true
luckperms.log.userhistory: true
luckperms.log.grouphistory: true
luckperms.log.trackhistory: true
luckperms.log.notify: true
luckperms.log.recent: true
luckperms.log.search: true
luckperms.user.*:
description: Gives access to all LuckPerms user commands
children:
luckperms.user.info: true
luckperms.user.getuuid: true
luckperms.user.listnodes: true
luckperms.user.haspermission: true
luckperms.user.inheritspermission: true
luckperms.user.setpermission: true
luckperms.user.unsetpermission: true
luckperms.user.addgroup: true
luckperms.user.removegroup: true
luckperms.user.settemppermission: true
luckperms.user.unsettemppermission: true
luckperms.user.addtempgroup: true
luckperms.user.removetempgroup: true
luckperms.user.setprimarygroup: true
luckperms.user.showtracks: true
luckperms.user.promote: true
luckperms.user.demote: true
luckperms.user.showpos: true
luckperms.user.clear: true
luckperms.group.*:
description: Gives access to all LuckPerms group commands
children:
luckperms.group.info: true
luckperms.group.listnodes: true
luckperms.group.haspermission: true
luckperms.group.inheritspermission: true
luckperms.group.setpermission: true
luckperms.group.unsetpermission: true
luckperms.group.setinherit: true
luckperms.group.unsetinherit: true
luckperms.group.settemppermission: true
luckperms.group.unsettemppermission: true
luckperms.group.settempinherit: true
luckperms.group.unsettempinherit: true
luckperms.group.showtracks: true
luckperms.group.clear: true
luckperms.track.*:
description: Gives access to all LuckPerms track commands
children:
luckperms.track.info: true
luckperms.track.append: true
luckperms.track.insert: true
luckperms.track.remove: true
luckperms.track.clear: true
luckperms.log.*:
description: Gives access to all LuckPerms log commands
children:
luckperms.log.export: true
luckperms.log.userhistory: true
luckperms.log.grouphistory: true
luckperms.log.trackhistory: true
luckperms.log.notify: true
luckperms.log.recent: true
luckperms.log.search: true
+52 -8
View File
@@ -4,19 +4,17 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko</groupId>
<version>1.1</version>
<groupId>me.lucko.luckperms</groupId>
<version>2.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luckperms-bungee</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>LuckPerms</name>
<build>
<defaultGoal>clean package</defaultGoal>
<finalName>LuckPerms</finalName>
<finalName>LuckPermsBungee-${project.version}.${git.closest.tag.commit.count}</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<resources>
<resource>
@@ -46,10 +44,35 @@
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<relocations>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>me.lucko.luckperms.lib.slf4j</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer.hikari</pattern>
<shadedPattern>me.lucko.luckperms.lib.hikari</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<injectAllReactorProjects>true</injectAllReactorProjects>
</configuration>
</plugin>
</plugins>
</build>
@@ -63,11 +86,32 @@
</dependency>
<!-- LuckPerms Common -->
<dependency>
<groupId>me.lucko</groupId>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-common</artifactId>
<version>${project.parent.version}</version>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<!-- LuckPerms API -->
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.4.7</version>
<scope>compile</scope>
</dependency>
<!-- slf4j library -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.9</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
</project>
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.commands.CommandManager;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
import java.util.Arrays;
class BungeeCommand extends Command implements TabExecutor {
private final CommandManager manager;
BungeeCommand(CommandManager manager) {
super("luckpermsbungee", null, "bperms", "lpb", "bpermissions", "bp", "bperm");
this.manager = manager;
}
@Override
public void execute(CommandSender sender, String[] args) {
manager.onCommand(BungeeSenderFactory.get().wrap(sender), "bperms", Arrays.asList(args), Callback.empty());
}
@Override
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
return manager.onTabComplete(BungeeSenderFactory.get().wrap(sender), Arrays.asList(args));
}
}
@@ -1,6 +1,28 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.utils.LPConfiguration;
import me.lucko.luckperms.core.LPConfiguration;
import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
@@ -10,30 +32,20 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
public class BungeeConfig implements LPConfiguration {
private final LPBungeePlugin plugin;
class BungeeConfig extends LPConfiguration<LPBungeePlugin> {
private Configuration configuration;
public BungeeConfig(LPBungeePlugin plugin) {
this.plugin = plugin;
reload();
}
private void reload() {
try {
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(makeFile("config.yml"));
} catch (IOException e) {
e.printStackTrace();
}
BungeeConfig(LPBungeePlugin plugin) {
super(plugin, "bungee", false, "flatfile");
}
@SuppressWarnings("ResultOfMethodCallIgnored")
private File makeFile(String file) throws IOException {
File cfg = new File(plugin.getDataFolder(), file);
File cfg = new File(getPlugin().getDataFolder(), file);
if (!cfg.exists()) {
plugin.getDataFolder().mkdir();
try (InputStream is = plugin.getResourceAsStream(file)) {
getPlugin().getDataFolder().mkdir();
try (InputStream is = getPlugin().getResourceAsStream(file)) {
Files.copy(is, cfg.toPath());
}
}
@@ -42,37 +54,31 @@ public class BungeeConfig implements LPConfiguration {
}
@Override
public String getServer() {
return configuration.getString("server", "bungee");
protected void init() {
try {
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(makeFile("config.yml"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public int getSyncTime() {
return configuration.getInt("sql.sync-minutes", 3);
protected void set(String path, Object value) {
configuration.set(path, value);
}
@Override
public String getDefaultGroupNode() {
return "group." + configuration.getString("default-group", "default");
protected String getString(String path, String def) {
return configuration.getString(path, def);
}
@Override
public String getDefaultGroupName() {
return configuration.getString("default-group", "default");
protected int getInt(String path, int def) {
return configuration.getInt(path, def);
}
@Override
public boolean getIncludeGlobalPerms() {
return configuration.getBoolean("include-global", false);
}
@Override
public String getDatabaseValue(String value) {
return configuration.getString("sql." + value);
}
@Override
public String getStorageMethod() {
return configuration.getString("storage-method", "sqlite");
protected boolean getBoolean(String path, boolean def) {
return configuration.getBoolean(path, def);
}
}
@@ -0,0 +1,135 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.core.UuidCache;
import me.lucko.luckperms.users.User;
import me.lucko.luckperms.utils.AbstractListener;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.*;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
class BungeeListener extends AbstractListener implements Listener {
private static final TextComponent WARN_MESSAGE = new TextComponent(Message.LOADING_ERROR.toString());
private final LPBungeePlugin plugin;
BungeeListener(LPBungeePlugin plugin) {
super(plugin);
this.plugin = plugin;
}
@EventHandler
public void onPlayerPermissionCheck(PermissionCheckEvent e) {
if (!(e.getSender() instanceof ProxiedPlayer)) {
return;
}
final ProxiedPlayer player = ((ProxiedPlayer) e.getSender());
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(player.getUniqueId()));
if (user == null) return;
final String server = player.getServer() == null ? null : (player.getServer().getInfo() == null ? null : player.getServer().getInfo().getName());
Map<String, Boolean> local = user.getLocalPermissions(plugin.getConfiguration().getServer(), server, null, Collections.singletonList(e.getPermission()));
for (Map.Entry<String, Boolean> en : local.entrySet()) {
if (en.getKey().equalsIgnoreCase(e.getPermission())) {
e.setHasPermission(en.getValue());
return;
}
}
}
@EventHandler
public void onPlayerLogin(LoginEvent e) {
/* Delay the login here, as we want to cache UUID data before the player is connected to a backend bukkit server.
This means that a player will have the same UUID across the network, even if parts of the network are running in
Offline mode. */
e.registerIntent(plugin);
plugin.doAsync(() -> {
final long startTime = System.currentTimeMillis();
final UuidCache cache = plugin.getUuidCache();
final PendingConnection c = e.getConnection();
if (!cache.isOnlineMode()) {
UUID uuid = plugin.getDatastore().getUUID(c.getName());
if (uuid != null) {
cache.addToCache(c.getUniqueId(), uuid);
} else {
// No previous data for this player
cache.addToCache(c.getUniqueId(), c.getUniqueId());
plugin.getDatastore().saveUUIDData(c.getName(), c.getUniqueId());
}
} else {
// Online mode, no cache needed. This is just for name -> uuid lookup.
plugin.getDatastore().saveUUIDData(c.getName(), 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.getDatastore().loadOrCreateUser(cache.getUUID(c.getUniqueId()), c.getName());
final long time = System.currentTimeMillis() - startTime;
if (time >= 1000) {
plugin.getLog().warn("Processing login for " + c.getName() + " took " + time + "ms.");
}
e.completeIntent(plugin);
});
}
@EventHandler
public void onPlayerPostLogin(PostLoginEvent e) {
final ProxiedPlayer player = e.getPlayer();
final WeakReference<ProxiedPlayer> p = new WeakReference<>(player);
final User user = plugin.getUserManager().get(plugin.getUuidCache().getUUID(e.getPlayer().getUniqueId()));
if (user == null) {
plugin.getProxy().getScheduler().schedule(plugin, () -> {
final ProxiedPlayer pl = p.get();
if (pl != null) {
pl.sendMessage(WARN_MESSAGE);
}
}, 3, TimeUnit.SECONDS);
} else {
user.refreshPermissions();
}
}
@EventHandler
public void onPlayerQuit(PlayerDisconnectEvent e) {
onLeave(e.getPlayer().getUniqueId());
}
@EventHandler
public void onPlayerServerSwitch(ServerSwitchEvent e) {
refreshPlayer(e.getPlayer().getUniqueId());
}
}
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import me.lucko.luckperms.commands.SenderFactory;
import me.lucko.luckperms.constants.Constants;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.UUID;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BungeeSenderFactory extends SenderFactory<CommandSender> {
private static BungeeSenderFactory instance = null;
public static BungeeSenderFactory get() {
if (instance == null){
instance = new BungeeSenderFactory();
}
return instance;
}
@Override
protected String getName(CommandSender sender) {
if (sender instanceof ProxiedPlayer) {
return sender.getName();
}
return Constants.getConsoleName();
}
@Override
protected UUID getUuid(CommandSender sender) {
if (sender instanceof ProxiedPlayer) {
return ((ProxiedPlayer) sender).getUniqueId();
}
return Constants.getConsoleUUID();
}
@Override
protected void sendMessage(CommandSender sender, String s) {
sender.sendMessage(new TextComponent(s));
}
@Override
protected boolean hasPermission(CommandSender sender, String node) {
return sender.hasPermission(node);
}
}
@@ -1,92 +1,140 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import lombok.Getter;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.implementation.ApiProvider;
import me.lucko.luckperms.commands.CommandManager;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.data.MySQLConfiguration;
import me.lucko.luckperms.data.methods.FlatfileDatastore;
import me.lucko.luckperms.data.methods.MySQLDatastore;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.core.LPConfiguration;
import me.lucko.luckperms.core.UuidCache;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.listeners.PlayerListener;
import me.lucko.luckperms.runnables.UpdateTask;
import me.lucko.luckperms.storage.Datastore;
import me.lucko.luckperms.storage.methods.FlatfileDatastore;
import me.lucko.luckperms.storage.methods.MySQLDatastore;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.BungeeUserManager;
import me.lucko.luckperms.users.UserManager;
import me.lucko.luckperms.utils.LPConfiguration;
import me.lucko.luckperms.utils.LogFactory;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Plugin;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Getter
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
public static final String VERSION = "v1.1";
private final Set<UUID> ignoringLogs = new HashSet<>();
private LPConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
private UuidCache uuidCache;
private Logger log;
@Override
public void onEnable() {
log = LogFactory.wrap(getLogger());
getLog().info("Loading configuration...");
configuration = new BungeeConfig(this);
// register events
getProxy().getPluginManager().registerListener(this, new PlayerListener(this));
getProxy().getPluginManager().registerListener(this, new BungeeListener(this));
// register commands
getProxy().getPluginManager().registerCommand(this, new MainCommand(new CommandManager(this)));
getLog().info("Registering commands...");
getProxy().getPluginManager().registerCommand(this, new BungeeCommand(new CommandManager(this)));
// disable the default Bungee /perms command so it gets handled by the Bukkit plugin
getProxy().getDisabledCommands().add("perms");
getLog().info("Detecting storage method...");
final String storageMethod = configuration.getStorageMethod();
if (storageMethod.equalsIgnoreCase("mysql")) {
getLogger().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(this, new MySQLConfiguration(
configuration.getDatabaseValue("address"),
configuration.getDatabaseValue("database"),
configuration.getDatabaseValue("username"),
configuration.getDatabaseValue("password")
));
getLog().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(this, configuration.getDatabaseValues());
} else if (storageMethod.equalsIgnoreCase("flatfile")) {
getLogger().info("Using Flatfile (JSON) as storage method.");
getLog().info("Using Flatfile (JSON) as storage method.");
datastore = new FlatfileDatastore(this, getDataFolder());
} else {
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using Flatfile as fallback.");
getLog().severe("Storage method '" + storageMethod + "' was not recognised. Using Flatfile as fallback.");
datastore = new FlatfileDatastore(this, getDataFolder());
}
getLog().info("Initialising datastore...");
datastore.init();
getLog().info("Loading internal permission managers...");
uuidCache = new UuidCache(getConfiguration().getOnlineMode());
userManager = new BungeeUserManager(this);
groupManager = new GroupManager(this);
trackManager = new TrackManager(this);
trackManager = new TrackManager();
// Run update task to refresh any online users
getLog().info("Scheduling Update Task to refresh any online users.");
try {
new UpdateTask(this).run();
} catch (Exception e) {
e.printStackTrace();
}
int mins = getConfiguration().getSyncTime();
if (mins > 0) {
getProxy().getScheduler().schedule(this, new UpdateTask(this), mins, mins, TimeUnit.MINUTES);
}
// 20 times per second (once per "tick")
getProxy().getScheduler().schedule(this, BungeeSenderFactory.get(), 50L, 50L, TimeUnit.MILLISECONDS);
getLog().info("Registering API...");
LuckPerms.registerProvider(new ApiProvider(this));
getLog().info("Successfully loaded.");
}
@Override
public void onDisable() {
getLog().info("Closing datastore...");
datastore.shutdown();
getLog().info("Unregistering API...");
LuckPerms.unregisterProvider();
}
@Override
public String getVersion() {
return VERSION;
return getDescription().getVersion();
}
@Override
public String getPlayerStatus(UUID uuid) {
return getProxy().getPlayer(uuid) != null ? "&aOnline" : "&cOffline";
public Message getPlayerStatus(UUID uuid) {
return getProxy().getPlayer(getUuidCache().getExternalUUID(uuid)) != null ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE;
}
@Override
@@ -99,6 +147,17 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
return getProxy().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList());
}
@Override
public List<Sender> getSenders() {
return getProxy().getPlayers().stream().map(p -> BungeeSenderFactory.get().wrap(p)).collect(Collectors.toList());
}
@Override
public List<String> getPossiblePermissions() {
// No such thing on Bungee. Wildcards are processed in the listener instead.
return Collections.emptyList();
}
@Override
public void runUpdateTask() {
doAsync(new UpdateTask(this));
@@ -1,51 +0,0 @@
package me.lucko.luckperms;
import me.lucko.luckperms.commands.CommandManager;
import me.lucko.luckperms.commands.Sender;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
import java.lang.ref.WeakReference;
import java.util.Arrays;
class MainCommand extends Command implements TabExecutor {
private final CommandManager manager;
public MainCommand(CommandManager manager) {
super("luckpermsbungee", null, "bperms", "lpb", "bpermissions", "bp", "bperm");
this.manager = manager;
}
@Override
public void execute(CommandSender sender, String[] args) {
manager.onCommand(makeSender(sender), "bperms", Arrays.asList(args));
}
@Override
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
return manager.onTabComplete(makeSender(sender), Arrays.asList(args));
}
private static Sender makeSender(CommandSender sender) {
return new Sender() {
final WeakReference<CommandSender> cs = new WeakReference<>(sender);
@Override
public void sendMessage(String s) {
final CommandSender c = cs.get();
if (c != null) {
c.sendMessage(new TextComponent(s));
}
}
@Override
public boolean hasPermission(String node) {
final CommandSender c = cs.get();
return c != null && c.hasPermission(node);
}
};
}
}
@@ -1,57 +0,0 @@
package me.lucko.luckperms.listeners;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.LPBungeePlugin;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.users.User;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import java.lang.ref.WeakReference;
import java.util.concurrent.TimeUnit;
@AllArgsConstructor
public class PlayerListener implements Listener {
private final LPBungeePlugin plugin;
@EventHandler
public void onPlayerPostLogin(PostLoginEvent e) {
final ProxiedPlayer player = e.getPlayer();
final WeakReference<ProxiedPlayer> p = new WeakReference<>(player);
plugin.getDatastore().loadOrCreateUser(player.getUniqueId(), player.getName(), success -> {
if (!success) {
plugin.getProxy().getScheduler().schedule(plugin, () -> {
final ProxiedPlayer pl = p.get();
if (pl != null) {
pl.sendMessage(new TextComponent(Util.color(Message.PREFIX + "Permissions data could not be loaded. Please contact an administrator.")));
}
}, 3, TimeUnit.SECONDS);
} else {
final ProxiedPlayer pl = p.get();
if (pl != null) {
final User user = plugin.getUserManager().getUser(pl.getUniqueId());
user.refreshPermissions();
}
}
});
plugin.getDatastore().saveUUIDData(player.getName(), player.getUniqueId(), success -> {});
}
@EventHandler
public void onPlayerQuit(PlayerDisconnectEvent e) {
ProxiedPlayer player = e.getPlayer();
// Unload the user from memory when they disconnect
User user = plugin.getUserManager().getUser(player.getUniqueId());
plugin.getUserManager().unloadUser(user);
}
}
@@ -1,38 +1,42 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.users;
import me.lucko.luckperms.LPBungeePlugin;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
public class BungeeUser extends User {
private final LPBungeePlugin plugin;
BungeeUser(UUID uuid, LPBungeePlugin plugin) {
super(uuid, plugin);
this.plugin = plugin;
}
BungeeUser(UUID uuid, String username, LPBungeePlugin plugin) {
super(uuid, username, plugin);
this.plugin = plugin;
}
@Override
public void refreshPermissions() {
ProxiedPlayer player = plugin.getProxy().getPlayer(getUuid());
if (player == null) return;
// Clear existing permissions
Collection<String> perms = new ArrayList<>(player.getPermissions());
perms.forEach(p -> player.setPermission(p, false));
// Re-add all defined permissions for the user
Map<String, Boolean> local = getLocalPermissions(getPlugin().getConfiguration().getServer(), null);
local.entrySet().forEach(e -> player.setPermission(e.getKey(), e.getValue()));
// Do nothing. Permissions are applied when needed in a listener.
}
}
@@ -1,7 +1,28 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.users;
import me.lucko.luckperms.LPBungeePlugin;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.UUID;
@@ -14,33 +35,35 @@ public class BungeeUserManager extends UserManager {
}
@Override
public void unloadUser(User user) {
public void unload(User user) {
if (user != null) {
// Cannot clear the ProxiedPlayer's permission map, they're leaving so that will get GCed anyway
// Calling getPermissions.clear() throws an UnsupportedOperationException
getUsers().remove(user.getUuid());
getAll().remove(user.getUuid());
}
}
@Override
public void cleanupUser(User user) {
if (plugin.getProxy().getPlayer(user.getUuid()) == null) {
unloadUser(user);
public void cleanup(User user) {
if (plugin.getProxy().getPlayer(plugin.getUuidCache().getExternalUUID(user.getUuid())) == null) {
unload(user);
}
}
@Override
public User makeUser(UUID uuid) {
public User make(UUID uuid) {
return new BungeeUser(uuid, plugin);
}
@Override
public User makeUser(UUID uuid, String username) {
public User make(UUID uuid, String username) {
return new BungeeUser(uuid, username, plugin);
}
@Override
public void updateAllUsers() {
plugin.getProxy().getPlayers().stream().map(ProxiedPlayer::getUniqueId).forEach(u -> plugin.getDatastore().loadUser(u));
plugin.getProxy().getPlayers().stream()
.map(p -> plugin.getUuidCache().getUUID(p.getUniqueId()))
.forEach(u -> plugin.getDatastore().loadUser(u));
}
}
+28
View File
@@ -9,6 +9,34 @@ default-group: default
# If users on this server should have their global permissions/groups applied.
include-global: false
# If this server is in offline or online mode.
# This setting allows a player to have the same UUID across a network of offline mode/mixed servers.
# You should generally reflect the setting in server.properties here. Except when...
# 1. You have Spigot servers connected to a BungeeCord proxy, with online-mode set to false, but 'bungeecord' set to true in the spigot.yml
# AND 'ip-forward' set to true in the BungeeCord config.yml
# In this case, set online-mode in LuckPerms to true, despite the server being in offline mode.
# 2. You are only running one server instance using LuckPerms, (not a network)
# In this case, set online-mode to true no matter what is set in server.properties. (we can just fallback to the servers uuid cache)
online-mode: true
# If the plugin should apply wildcard permissions.
# If set to true, LuckPerms will detect wildcard permissions, and resolve & apply all registered permissions matching
# the wildcard. This will only work for plugins that define all of their permissions to the server.
apply-wildcards: true
# If the plugin should parse regex permissions.
# If set to true, LuckPerms will detect regex permissions, marked with "r=" at the start of the node, and resolve &
# apply all registered permissions matching the regex. This will only work for plugins that define all of their
# permissions to the server.
apply-regex: true
# If the plugin should complete and apply shorthand permissions.
# If set to true, LuckPerms will detect and expand shorthand node patterns.
apply-shorthand: true
# Which storage method the plugin should use.
# Currently supported: mysql & flatfile
# Fill out connection info below if you're using MySQL
+1 -1
View File
@@ -1,5 +1,5 @@
name: LuckPerms
author: Luck
version: 1.1
version: ${project.version}.${git.closest.tag.commit.count}
main: me.lucko.luckperms.LPBungeePlugin
description: A permissions plugin
+42 -3
View File
@@ -4,8 +4,8 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko</groupId>
<version>1.1</version>
<groupId>me.lucko.luckperms</groupId>
<version>2.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -23,4 +23,43 @@
</plugin>
</plugins>
</build>
</project>
<dependencies>
<!-- LuckPerms API -->
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.4.7</version>
<scope>compile</scope>
</dependency>
<!-- slf4j library -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.9</version>
<scope>compile</scope>
</dependency>
<!-- gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
<scope>provided</scope>
</dependency>
<!-- guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -1,15 +1,45 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms;
import me.lucko.luckperms.data.Datastore;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.core.LPConfiguration;
import me.lucko.luckperms.core.UuidCache;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.storage.Datastore;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.UserManager;
import me.lucko.luckperms.utils.LPConfiguration;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
/**
* Main internal interface for LuckPerms plugins, allowing the luckperms-common module to bind with the plugin instance.
* All plugin platforms implement this interface.
*/
public interface LuckPermsPlugin {
/**
@@ -46,7 +76,13 @@ public interface LuckPermsPlugin {
* Retrieves the {@link Logger} for the plugin
* @return the plugin's {@link Logger}
*/
Logger getLogger();
Logger getLog();
/**
* Retrieves the {@link UuidCache} for the plugin
* @return the plugin's {@link UuidCache}
*/
UuidCache getUuidCache();
/**
* @return the version of the plugin
@@ -58,7 +94,7 @@ public interface LuckPermsPlugin {
* @param uuid The player's uuid
* @return a formatted status string
*/
String getPlayerStatus(UUID uuid);
Message getPlayerStatus(UUID uuid);
/**
* Gets the number of users online on the platform
@@ -72,6 +108,24 @@ public interface LuckPermsPlugin {
*/
List<String> getPlayerList();
/**
* Gets a list of all Senders online on the platform
* @return a {@link List} of senders
*/
List<Sender> getSenders();
/**
* Gets all possible permission nodes, used for resolving wildcards
* @return a {@link List} of permission nodes
*/
List<String> getPossiblePermissions();
/**
* Gets a set of players ignoring logging output
* @return a {@link Set} of uuids
*/
Set<UUID> getIgnoringLogs();
/**
* Runs an update task
*/
@@ -0,0 +1,162 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.api.*;
import me.lucko.luckperms.api.implementation.internal.*;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Provides static access to LuckPerms
*/
@AllArgsConstructor
public class ApiProvider implements LuckPermsApi {
private final LuckPermsPlugin plugin;
@Override
public void runUpdateTask() {
plugin.runUpdateTask();
}
@Override
public String getVersion() {
return plugin.getVersion();
}
@Override
public LPConfiguration getConfiguration() {
return new LPConfigurationLink(plugin.getConfiguration());
}
@Override
public Datastore getDatastore() {
return new DatastoreLink(plugin, plugin.getDatastore());
}
@Override
public UuidCache getUuidCache() {
return new UuidCacheLink(plugin.getUuidCache());
}
@Override
public Logger getLogger() {
return plugin.getLog();
}
@Override
public User getUser(@NonNull UUID uuid) {
final me.lucko.luckperms.users.User user = plugin.getUserManager().get(uuid);
if (user == null) {
return null;
}
return new UserLink(user);
}
@Override
public Optional<User> getUserSafe(UUID uuid) {
return Optional.ofNullable(getUser(uuid));
}
@Override
public User getUser(@NonNull String name) {
final me.lucko.luckperms.users.User user = plugin.getUserManager().get(name);
if (user == null) {
return null;
}
return new UserLink(user);
}
@Override
public Optional<User> getUserSafe(String name) {
return Optional.ofNullable(getUser(name));
}
@Override
public Set<User> getUsers() {
return plugin.getUserManager().getAll().values().stream().map(UserLink::new).collect(Collectors.toSet());
}
@Override
public boolean isUserLoaded(@NonNull UUID uuid) {
return plugin.getUserManager().isLoaded(uuid);
}
@Override
public Group getGroup(@NonNull String name) {
final me.lucko.luckperms.groups.Group group = plugin.getGroupManager().get(name);
if (group == null) {
return null;
}
return new GroupLink(group);
}
@Override
public Optional<Group> getGroupSafe(String name) {
return Optional.ofNullable(getGroup(name));
}
@Override
public Set<Group> getGroups() {
return plugin.getGroupManager().getAll().values().stream().map(GroupLink::new).collect(Collectors.toSet());
}
@Override
public boolean isGroupLoaded(@NonNull String name) {
return plugin.getGroupManager().isLoaded(name);
}
@Override
public Track getTrack(@NonNull String name) {
final me.lucko.luckperms.tracks.Track track = plugin.getTrackManager().get(name);
if (track == null) {
return null;
}
return new TrackLink(track);
}
@Override
public Optional<Track> getTrackSafe(String name) {
return Optional.ofNullable(getTrack(name));
}
@Override
public Set<Track> getTracks() {
return plugin.getTrackManager().getAll().values().stream().map(TrackLink::new).collect(Collectors.toSet());
}
@Override
public boolean isTrackLoaded(@NonNull String name) {
return plugin.getTrackManager().isLoaded(name);
}
}
@@ -0,0 +1,464 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.api.*;
import me.lucko.luckperms.api.data.Callback;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
/**
* Provides a link between {@link Datastore} and {@link me.lucko.luckperms.storage.Datastore}
*/
@SuppressWarnings({"unused", "WeakerAccess"})
public class DatastoreLink implements Datastore {
private final LuckPermsPlugin plugin;
private final me.lucko.luckperms.storage.Datastore master;
private final Async async;
private final Sync sync;
private final Future future;
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull me.lucko.luckperms.storage.Datastore master) {
this.plugin = plugin;
this.master = master;
this.async = new Async(master);
this.sync = new Sync(master);
this.future = new Future(master);
}
private static <T> Callback<T> checkCallback(Callback<T> c) {
// If no callback was given, just send an empty one
if (c == null) {
c = Callback.empty();
}
return c;
}
@Override
public String getName() {
return master.getName();
}
@Override
public boolean isAcceptingLogins() {
return master.isAcceptingLogins();
}
@Override
public Datastore.Async async() {
return async;
}
@Override
public Datastore.Sync sync() {
return sync;
}
@Override
public Datastore.Future future() {
return future;
}
@AllArgsConstructor
public class Async implements Datastore.Async {
private final me.lucko.luckperms.storage.Datastore master;
@Override
public void logAction(@NonNull LogEntry entry, Callback<Boolean> callback) {
master.logAction(entry, checkCallback(callback));
}
@Override
public void getLog(Callback<Log> callback) {
master.getLog(log -> callback.onComplete(new LogLink(log)));
}
@Override
public void loadOrCreateUser(@NonNull UUID uuid, @NonNull String username, Callback<Boolean> callback) {
master.loadOrCreateUser(uuid, checkUsername(username), checkCallback(callback));
}
@Override
public void loadUser(@NonNull UUID uuid, Callback<Boolean> callback) {
master.loadUser(uuid, checkCallback(callback));
}
@Override
public void saveUser(@NonNull User user, Callback<Boolean> callback) {
checkUser(user);
master.saveUser(((UserLink) user).getMaster(), checkCallback(callback));
}
@Override
public void createAndLoadGroup(@NonNull String name, Callback<Boolean> callback) {
master.createAndLoadGroup(checkName(name), checkCallback(callback));
}
@Override
public void loadGroup(@NonNull String name, Callback<Boolean> callback) {
master.loadGroup(checkName(name), checkCallback(callback));
}
@Override
public void loadAllGroups(Callback<Boolean> callback) {
master.loadAllGroups(checkCallback(callback));
}
@Override
public void saveGroup(@NonNull Group group, Callback<Boolean> callback) {
checkGroup(group);
master.saveGroup(((GroupLink) group).getMaster(), checkCallback(callback));
}
@Override
public void deleteGroup(@NonNull Group group, Callback<Boolean> callback) {
checkGroup(group);
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
master.deleteGroup(((GroupLink) group).getMaster(), checkCallback(callback));
}
@Override
public void createAndLoadTrack(@NonNull String name, Callback<Boolean> callback) {
master.createAndLoadTrack(checkName(name), checkCallback(callback));
}
@Override
public void loadTrack(@NonNull String name, Callback<Boolean> callback) {
master.loadTrack(checkName(name), checkCallback(callback));
}
@Override
public void loadAllTracks(Callback<Boolean> callback) {
master.loadAllTracks(checkCallback(callback));
}
@Override
public void saveTrack(@NonNull Track track, Callback<Boolean> callback) {
checkTrack(track);
master.saveTrack(((TrackLink) track).getMaster(), checkCallback(callback));
}
@Override
public void deleteTrack(@NonNull Track track, Callback<Boolean> callback) {
checkTrack(track);
master.deleteTrack(((TrackLink) track).getMaster(), checkCallback(callback));
}
@Override
public void saveUUIDData(@NonNull String username, @NonNull UUID uuid, Callback<Boolean> callback) {
master.saveUUIDData(checkUsername(username), uuid, checkCallback(callback));
}
@Override
public void getUUID(@NonNull String username, Callback<UUID> callback) {
master.getUUID(checkUsername(username), checkCallback(callback));
}
}
@AllArgsConstructor
public class Sync implements Datastore.Sync {
private final me.lucko.luckperms.storage.Datastore master;
@Override
public boolean logAction(@NonNull LogEntry entry) {
return master.logAction(entry);
}
@Override
public Log getLog() {
return new LogLink(master.getLog());
}
@Override
public boolean loadOrCreateUser(@NonNull UUID uuid, @NonNull String username) {
return master.loadOrCreateUser(uuid, checkUsername(username));
}
@Override
public boolean loadUser(@NonNull UUID uuid) {
return master.loadUser(uuid);
}
@Override
public boolean saveUser(@NonNull User user) {
checkUser(user);
return master.saveUser(((UserLink) user).getMaster());
}
@Override
public boolean createAndLoadGroup(@NonNull String name) {
return master.createAndLoadGroup(checkName(name));
}
@Override
public boolean loadGroup(@NonNull String name) {
return master.loadGroup(checkName(name));
}
@Override
public boolean loadAllGroups() {
return master.loadAllGroups();
}
@Override
public boolean saveGroup(@NonNull Group group) {
checkGroup(group);
return master.saveGroup(((GroupLink) group).getMaster());
}
@Override
public boolean deleteGroup(@NonNull Group group) {
checkGroup(group);
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
return master.deleteGroup(((GroupLink) group).getMaster());
}
@Override
public boolean createAndLoadTrack(@NonNull String name) {
return master.createAndLoadTrack(checkName(name));
}
@Override
public boolean loadTrack(@NonNull String name) {
return master.loadTrack(checkName(name));
}
@Override
public boolean loadAllTracks() {
return master.loadAllTracks();
}
@Override
public boolean saveTrack(@NonNull Track track) {
checkTrack(track);
return master.saveTrack(((TrackLink) track).getMaster());
}
@Override
public boolean deleteTrack(@NonNull Track track) {
checkTrack(track);
return master.deleteTrack(((TrackLink) track).getMaster());
}
@Override
public boolean saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
return master.saveUUIDData(checkUsername(username), uuid);
}
@Override
public UUID getUUID(@NonNull String username) {
return master.getUUID(checkUsername(username));
}
}
@AllArgsConstructor
public class Future implements Datastore.Future {
private final me.lucko.luckperms.storage.Datastore master;
@Override
public java.util.concurrent.Future<Boolean> logAction(@NonNull LogEntry entry) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.logAction(entry, lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Log> getLog() {
LPFuture<Log> lpf = new LPFuture<>();
master.getLog(log -> lpf.onComplete(new LogLink(log)));
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> loadOrCreateUser(@NonNull UUID uuid, @NonNull String username) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.loadOrCreateUser(uuid, checkUsername(username), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> loadUser(@NonNull UUID uuid) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.loadUser(uuid, lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> saveUser(@NonNull User user) {
LPFuture<Boolean> lpf = new LPFuture<>();
checkUser(user);
master.saveUser(((UserLink) user).getMaster(), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> createAndLoadGroup(@NonNull String name) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.createAndLoadGroup(checkName(name), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> loadGroup(@NonNull String name) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.loadGroup(checkName(name), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> loadAllGroups() {
LPFuture<Boolean> lpf = new LPFuture<>();
master.loadAllGroups(lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> saveGroup(@NonNull Group group) {
LPFuture<Boolean> lpf = new LPFuture<>();
checkGroup(group);
master.saveGroup(((GroupLink) group).getMaster(), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> deleteGroup(@NonNull Group group) {
LPFuture<Boolean> lpf = new LPFuture<>();
checkGroup(group);
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
master.deleteGroup(((GroupLink) group).getMaster(), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> createAndLoadTrack(@NonNull String name) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.createAndLoadTrack(checkName(name), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> loadTrack(@NonNull String name) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.loadTrack(checkName(name), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> loadAllTracks() {
LPFuture<Boolean> lpf = new LPFuture<>();
master.loadAllTracks(lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> saveTrack(@NonNull Track track) {
LPFuture<Boolean> lpf = new LPFuture<>();
checkTrack(track);
master.saveTrack(((TrackLink) track).getMaster(), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> deleteTrack(@NonNull Track track) {
LPFuture<Boolean> lpf = new LPFuture<>();
checkTrack(track);
master.deleteTrack(((TrackLink) track).getMaster(), lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<Boolean> saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
LPFuture<Boolean> lpf = new LPFuture<>();
master.saveUUIDData(checkUsername(username), uuid, lpf);
return lpf;
}
@Override
public java.util.concurrent.Future<UUID> getUUID(@NonNull String username) {
LPFuture<UUID> lpf = new LPFuture<>();
master.getUUID(checkUsername(username), lpf);
return lpf;
}
}
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class LPFuture<T> implements Callback<T>, java.util.concurrent.Future<T> {
private final CountDownLatch latch = new CountDownLatch(1);
private T value;
@Override
public void onComplete(T t) {
value = t;
latch.countDown();
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
// Not supported
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return latch.getCount() == 0;
}
@Override
public T get() throws InterruptedException {
latch.await();
return value;
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
if (latch.await(timeout, unit)) {
return value;
} else {
throw new TimeoutException();
}
}
}
}
@@ -0,0 +1,165 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
/**
* Provides a link between {@link Group} and {@link me.lucko.luckperms.groups.Group}
*/
@EqualsAndHashCode(of = {"name"}, callSuper = false)
@SuppressWarnings("unused")
public class GroupLink extends PermissionHolderLink implements Group {
@Getter(AccessLevel.PACKAGE)
private final me.lucko.luckperms.groups.Group master;
@Getter
private final String name;
public GroupLink(@NonNull me.lucko.luckperms.groups.Group master) {
super(master);
this.master = master;
this.name = master.getName();
}
@Override
public boolean inheritsGroup(@NonNull Group group) {
checkGroup(group);
return master.inheritsGroup(((GroupLink) group).getMaster());
}
@Override
public boolean inheritsGroup(@NonNull Group group, @NonNull String server) {
checkGroup(group);
return master.inheritsGroup(((GroupLink) group).getMaster(), server);
}
@Override
public boolean inheritsGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
checkGroup(group);
return master.inheritsGroup(((GroupLink) group).getMaster(), server, world);
}
@Override
public void setInheritGroup(@NonNull Group group) throws ObjectAlreadyHasException {
checkGroup(group);
master.setInheritGroup(((GroupLink) group).getMaster());
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
checkGroup(group);
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
checkGroup(group);
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
checkGroup(group);
master.setInheritGroup(((GroupLink) group).getMaster(), checkTime(expireAt));
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
checkGroup(group);
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), checkTime(expireAt));
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
checkGroup(group);
master.setInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, checkTime(expireAt));
}
@Override
public void unsetInheritGroup(@NonNull Group group) throws ObjectLacksException {
checkGroup(group);
master.unsetInheritGroup(((GroupLink) group).getMaster());
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
checkGroup(group);
master.unsetInheritGroup(((GroupLink) group).getMaster(), temporary);
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
checkGroup(group);
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server));
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
checkGroup(group);
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world);
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
checkGroup(group);
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), temporary);
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
checkGroup(group);
master.unsetInheritGroup(((GroupLink) group).getMaster(), checkServer(server), world, temporary);
}
@Override
public void clearNodes() {
master.clearNodes();
}
@Override
public List<String> getGroupNames() {
return master.getGroupNames();
}
@Override
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
return master.getLocalGroups(checkServer(server), world);
}
@Override
public List<String> getLocalGroups(@NonNull String server) {
return master.getLocalGroups(checkServer(server));
}
}
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.api.LPConfiguration;
import me.lucko.luckperms.api.data.MySQLConfiguration;
/**
* Provides a link between {@link LPConfiguration} and {@link me.lucko.luckperms.core.LPConfiguration}
*/
@AllArgsConstructor
public class LPConfigurationLink implements LPConfiguration {
private final me.lucko.luckperms.core.LPConfiguration master;
@Override
public String getServer() {
return master.getServer();
}
@Override
public int getSyncTime() {
return master.getSyncTime();
}
@Override
public String getDefaultGroupNode() {
return master.getDefaultGroupNode();
}
@Override
public String getDefaultGroupName() {
return master.getDefaultGroupName();
}
@Override
public boolean getIncludeGlobalPerms() {
return master.getIncludeGlobalPerms();
}
@Override
public boolean getOnlineMode() {
return master.getOnlineMode();
}
@Override
public boolean getApplyWildcards() {
return master.getApplyWildcards();
}
@Override
public boolean getApplyRegex() {
return master.getApplyRegex();
}
@Override
public boolean getApplyShorthand() {
return master.getApplyShorthand();
}
@Override
public MySQLConfiguration getDatabaseValues() {
return master.getDatabaseValues();
}
@Override
public String getStorageMethod() {
return master.getStorageMethod();
}
}
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.Log;
import me.lucko.luckperms.api.LogEntry;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.UUID;
import static me.lucko.luckperms.api.implementation.internal.Utils.checkName;
/**
* Provides a link between {@link Log} and {@link me.lucko.luckperms.data.Log}
*/
@AllArgsConstructor
public class LogLink implements Log {
private final me.lucko.luckperms.data.Log master;
@Override
public SortedSet<LogEntry> getContent() {
return master.getContent();
}
@Override
public SortedSet<LogEntry> getRecent() {
return master.getRecent();
}
@Override
public SortedMap<Integer, LogEntry> getRecent(int pageNo) {
return master.getRecent(pageNo);
}
@Override
public int getRecentMaxPages() {
return master.getRecentMaxPages();
}
@Override
public SortedSet<LogEntry> getRecent(@NonNull UUID actor) {
return master.getRecent(actor);
}
@Override
public SortedMap<Integer, LogEntry> getRecent(int pageNo, @NonNull UUID actor) {
return master.getRecent(pageNo, actor);
}
@Override
public int getRecentMaxPages(@NonNull UUID actor) {
return master.getRecentMaxPages(actor);
}
@Override
public SortedSet<LogEntry> getUserHistory(@NonNull UUID uuid) {
return master.getUserHistory(uuid);
}
@Override
public SortedMap<Integer, LogEntry> getUserHistory(int pageNo, @NonNull UUID uuid) {
return master.getUserHistory(pageNo, uuid);
}
@Override
public int getUserHistoryMaxPages(@NonNull UUID uuid) {
return master.getUserHistoryMaxPages(uuid);
}
@Override
public SortedSet<LogEntry> getGroupHistory(@NonNull String name) {
return master.getGroupHistory(checkName(name));
}
@Override
public SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, @NonNull String name) {
return master.getGroupHistory(pageNo, checkName(name));
}
@Override
public int getGroupHistoryMaxPages(@NonNull String name) {
return master.getGroupHistoryMaxPages(checkName(name));
}
@Override
public SortedSet<LogEntry> getTrackHistory(@NonNull String name) {
return master.getTrackHistory(checkName(name));
}
@Override
public SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, @NonNull String name) {
return master.getTrackHistory(pageNo, checkName(name));
}
@Override
public int getTrackHistoryMaxPages(@NonNull String name) {
return master.getTrackHistoryMaxPages(checkName(name));
}
@Override
public SortedSet<LogEntry> getSearch(@NonNull String query) {
return master.getSearch(query);
}
@Override
public SortedMap<Integer, LogEntry> getSearch(int pageNo, @NonNull String query) {
return master.getSearch(pageNo, query);
}
@Override
public int getSearchMaxPages(@NonNull String query) {
return master.getSearchMaxPages(query);
}
}
@@ -0,0 +1,213 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.PermissionHolder;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
/**
* Provides a link between {@link PermissionHolder} and {@link me.lucko.luckperms.core.PermissionHolder}
*/
@SuppressWarnings("unused")
@AllArgsConstructor(access = AccessLevel.PACKAGE)
class PermissionHolderLink implements PermissionHolder {
@NonNull
private final me.lucko.luckperms.core.PermissionHolder master;
@Override
public String getObjectName() {
return master.getObjectName();
}
@Override
public Map<String, Boolean> getNodes() {
return Collections.unmodifiableMap(master.getNodes());
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b) {
return master.hasPermission(node, b);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server) {
return master.hasPermission(node, b, checkServer(server));
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world) {
return master.hasPermission(node, b, checkServer(server), world);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull boolean temporary) {
return master.hasPermission(node, b, temporary);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull boolean temporary) {
return master.hasPermission(node, b, checkServer(server), temporary);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world, @NonNull boolean temporary) {
return master.hasPermission(node, b, checkServer(server), world, temporary);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b) {
return master.inheritsPermission(node, b);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server) {
return master.inheritsPermission(node, b, checkServer(server));
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world) {
return master.inheritsPermission(node, b, checkServer(server), world);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull boolean temporary) {
return master.inheritsPermission(node, b, temporary);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull boolean temporary) {
return master.inheritsPermission(node, b, checkServer(server), temporary);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world, @NonNull boolean temporary) {
return master.inheritsPermission(node, b, checkServer(server), world, temporary);
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value) throws ObjectAlreadyHasException {
master.setPermission(checkNode(node), value);
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server) throws ObjectAlreadyHasException {
master.setPermission(checkNode(node), value, checkServer(server));
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
master.setPermission(checkNode(node), value, checkServer(server), world);
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull long expireAt) throws ObjectAlreadyHasException {
master.setPermission(checkNode(node), value, checkTime(expireAt));
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
master.setPermission(checkNode(node), value, checkServer(server), checkTime(expireAt));
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
master.setPermission(checkNode(node), value, checkServer(server), world, checkTime(expireAt));
}
@Override
public void unsetPermission(@NonNull String node, @NonNull boolean temporary) throws ObjectLacksException {
master.unsetPermission(checkNode(node), temporary);
}
@Override
public void unsetPermission(@NonNull String node) throws ObjectLacksException {
master.unsetPermission(checkNode(node));
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server) throws ObjectLacksException {
master.unsetPermission(checkNode(node), checkServer(server));
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull String world) throws ObjectLacksException {
master.unsetPermission(checkNode(node), checkServer(server), world);
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
master.unsetPermission(checkNode(node), checkServer(server), temporary);
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
master.unsetPermission(checkNode(node), checkServer(server), world, temporary);
}
@Override
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups, List<String> possibleNodes) {
return master.getLocalPermissions(server, world, excludedGroups, possibleNodes);
}
@Override
public Map<String, Boolean> getLocalPermissions(String server, String world, List<String> excludedGroups) {
return master.getLocalPermissions(server, world, excludedGroups);
}
@Override
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups, List<String> possibleNodes) {
return master.getLocalPermissions(server, excludedGroups, possibleNodes);
}
@Override
public Map<String, Boolean> getLocalPermissions(String server, List<String> excludedGroups) {
return master.getLocalPermissions(server, excludedGroups);
}
@Override
public Map<Map.Entry<String, Boolean>, Long> getTemporaryNodes() {
return master.getTemporaryNodes();
}
@Override
public Map<String, Boolean> getPermanentNodes() {
return master.getPermanentNodes();
}
@Override
public void auditTemporaryPermissions() {
master.auditTemporaryPermissions();
}
}
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import static me.lucko.luckperms.api.implementation.internal.Utils.checkGroup;
/**
* Provides a link between {@link Track} and {@link me.lucko.luckperms.tracks.Track}
*/
@EqualsAndHashCode(of = {"name"})
@SuppressWarnings("unused")
public class TrackLink implements Track {
@Getter(AccessLevel.PACKAGE)
private final me.lucko.luckperms.tracks.Track master;
@Getter
private final String name;
public TrackLink(@NonNull me.lucko.luckperms.tracks.Track master) {
this.master = master;
this.name = master.getName();
}
@Override
public List<String> getGroups() {
return master.getGroups();
}
@Override
public int getSize() {
return master.getSize();
}
@Override
public String getNext(@NonNull Group current) throws ObjectLacksException {
checkGroup(current);
return master.getNext(((GroupLink) current).getMaster());
}
@Override
public String getPrevious(@NonNull Group current) throws ObjectLacksException {
checkGroup(current);
return master.getPrevious(((GroupLink) current).getMaster());
}
@Override
public void appendGroup(@NonNull Group group) throws ObjectAlreadyHasException {
checkGroup(group);
master.appendGroup(((GroupLink) group).getMaster());
}
@Override
public void insertGroup(@NonNull Group group, @NonNull int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException {
checkGroup(group);
master.insertGroup(((GroupLink) group).getMaster(), position);
}
@Override
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
checkGroup(group);
master.removeGroup(((GroupLink) group).getMaster());
}
@Override
public void removeGroup(@NonNull String group) throws ObjectLacksException {
master.removeGroup(group);
}
@Override
public boolean containsGroup(@NonNull Group group) {
checkGroup(group);
return master.containsGroup(((GroupLink) group).getMaster());
}
@Override
public boolean containsGroup(@NonNull String group) {
return master.containsGroup(group);
}
@Override
public void clearGroups() {
master.clearGroups();
}
}
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.UUID;
import static me.lucko.luckperms.api.implementation.internal.Utils.*;
/**
* Provides a link between {@link User} and {@link me.lucko.luckperms.users.User}
*/
@EqualsAndHashCode(of = {"uuid"}, callSuper = false)
@SuppressWarnings("unused")
public class UserLink extends PermissionHolderLink implements User {
@Getter(AccessLevel.PACKAGE)
private final me.lucko.luckperms.users.User master;
@Getter
private final UUID uuid;
public UserLink(@NonNull me.lucko.luckperms.users.User master) {
super(master);
this.master = master;
this.uuid = master.getUuid();
}
@Override
public String getName() {
return master.getName();
}
@Override
public String getPrimaryGroup() {
return master.getPrimaryGroup();
}
@Override
public void setPrimaryGroup(String s) throws ObjectAlreadyHasException {
if (getPrimaryGroup().equalsIgnoreCase(s)) {
throw new ObjectAlreadyHasException();
}
if (!getGroupNames().contains(s.toLowerCase())) {
throw new IllegalStateException("User is not a member of that group.");
}
master.setPrimaryGroup(s.toLowerCase());
}
@Override
public void refreshPermissions() {
master.refreshPermissions();
}
@Override
public boolean isInGroup(@NonNull Group group) {
checkGroup(group);
return master.isInGroup(((GroupLink) group).getMaster());
}
@Override
public boolean isInGroup(@NonNull Group group, @NonNull String server) {
checkGroup(group);
return master.isInGroup(((GroupLink) group).getMaster(), server);
}
@Override
public boolean isInGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
checkGroup(group);
return master.isInGroup(((GroupLink) group).getMaster(), server, world);
}
@Override
public void addGroup(@NonNull Group group) throws ObjectAlreadyHasException {
checkGroup(group);
master.addGroup(((GroupLink) group).getMaster());
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
checkGroup(group);
master.addGroup(((GroupLink) group).getMaster(), checkServer(server));
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
checkGroup(group);
master.addGroup(((GroupLink) group).getMaster(), checkServer(server), world);
}
@Override
public void addGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
checkGroup(group);
master.addGroup(((GroupLink) group).getMaster(), checkTime(expireAt));
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
checkGroup(group);
master.addGroup(((GroupLink) group).getMaster(), checkServer(server), checkTime(expireAt));
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
checkGroup(group);
master.addGroup(((GroupLink) group).getMaster(), checkServer(server), world, checkTime(expireAt));
}
@Override
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
checkGroup(group);
master.removeGroup(((GroupLink) group).getMaster());
}
@Override
public void removeGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
checkGroup(group);
master.removeGroup(((GroupLink) group).getMaster(), temporary);
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
checkGroup(group);
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server));
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
checkGroup(group);
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server), world);
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
checkGroup(group);
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server), temporary);
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
checkGroup(group);
master.removeGroup(((GroupLink) group).getMaster(), checkServer(server), world, temporary);
}
@Override
public void clearNodes() {
master.clearNodes();
}
@Override
public List<String> getGroupNames() {
return master.getGroupNames();
}
@Override
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
return master.getLocalGroups(checkServer(server), world);
}
@Override
public List<String> getLocalGroups(@NonNull String server) {
return master.getLocalGroups(checkServer(server));
}
}
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.experimental.UtilityClass;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.utils.ArgumentChecker;
@UtilityClass
class Utils {
static void checkUser(User user) {
if (!(user instanceof UserLink)) {
throw new IllegalArgumentException("User instance cannot be handled by this implementation.");
}
}
static void checkGroup(Group group) {
if (!(group instanceof GroupLink)) {
throw new IllegalArgumentException("Group instance cannot be handled by this implementation.");
}
}
static void checkTrack(Track track) {
if (!(track instanceof TrackLink)) {
throw new IllegalArgumentException("Track instance cannot be handled by this implementation.");
}
}
static String checkUsername(String s) {
if (ArgumentChecker.checkUsername(s)) {
throw new IllegalArgumentException("Invalid username entry '" + s + "'. Usernames must be less than 16 chars" +
" and only contain 'a-z A-Z 1-9 _'.");
}
return s;
}
static String checkName(String s) {
if (ArgumentChecker.checkName(s)) {
throw new IllegalArgumentException("Invalid name entry '" + s + "'. Names must be less than 37 chars" +
" and only contain 'a-z A-Z 1-9'.");
}
return s.toLowerCase();
}
static String checkServer(String s) {
if (ArgumentChecker.checkServer(s)) {
throw new IllegalArgumentException("Invalid server entry '" + s + "'. Server names can only contain alphanumeric characters.");
}
return s;
}
static String checkNode(String s) {
if (ArgumentChecker.checkNode(s)) {
throw new IllegalArgumentException("Invalid node entry '" + s + "'. Nodes cannot contain '/' or '$' characters.");
}
return s;
}
static long checkTime(long l) {
if (ArgumentChecker.checkTime(l)) {
throw new IllegalArgumentException("Unix time '" + l + "' is invalid, as it has already passed.");
}
return l;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.api.implementation.internal;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.api.UuidCache;
import java.util.UUID;
/**
* Provides a link between {@link UuidCache} and {@link me.lucko.luckperms.core.UuidCache}
*/
@AllArgsConstructor
public class UuidCacheLink implements UuidCache {
private final me.lucko.luckperms.core.UuidCache master;
@Override
public UUID getUUID(UUID external) {
return master.getUUID(external);
}
@Override
public UUID getExternalUUID(UUID internal) {
return master.getExternalUUID(internal);
}
}
@@ -1,128 +1,139 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import com.google.common.collect.ImmutableList;
import lombok.AllArgsConstructor;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.group.CreateGroupCommand;
import me.lucko.luckperms.commands.group.DeleteGroupCommand;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.commands.group.CreateGroup;
import me.lucko.luckperms.commands.group.DeleteGroup;
import me.lucko.luckperms.commands.group.GroupMainCommand;
import me.lucko.luckperms.commands.group.ListGroupsCommand;
import me.lucko.luckperms.commands.group.subcommands.*;
import me.lucko.luckperms.commands.group.ListGroups;
import me.lucko.luckperms.commands.log.LogMainCommand;
import me.lucko.luckperms.commands.misc.DebugCommand;
import me.lucko.luckperms.commands.misc.InfoCommand;
import me.lucko.luckperms.commands.misc.SyncCommand;
import me.lucko.luckperms.commands.track.CreateTrackCommand;
import me.lucko.luckperms.commands.track.DeleteTrackCommand;
import me.lucko.luckperms.commands.track.ListTracksCommand;
import me.lucko.luckperms.commands.track.CreateTrack;
import me.lucko.luckperms.commands.track.DeleteTrack;
import me.lucko.luckperms.commands.track.ListTracks;
import me.lucko.luckperms.commands.track.TrackMainCommand;
import me.lucko.luckperms.commands.track.subcommands.*;
import me.lucko.luckperms.commands.user.UserMainCommand;
import me.lucko.luckperms.commands.user.subcommands.*;
import me.lucko.luckperms.constants.Message;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.stream.Collectors;
@AllArgsConstructor
public class CommandManager {
private final LuckPermsPlugin plugin;
@Getter
private final List<MainCommand> mainCommands = new ArrayList<>();
private final List<MainCommand> mainCommands = ImmutableList.<MainCommand>builder()
.add(new UserMainCommand())
.add(new GroupMainCommand())
.add(new TrackMainCommand())
.add(new LogMainCommand())
.add(new SyncCommand())
.add(new InfoCommand())
.add(new DebugCommand())
.add(new CreateGroup())
.add(new DeleteGroup())
.add(new ListGroups())
.add(new CreateTrack())
.add(new DeleteTrack())
.add(new ListTracks())
.build();
public CommandManager(LuckPermsPlugin plugin) {
this.plugin = plugin;
UserMainCommand userCommand = new UserMainCommand();
this.registerMainCommand(userCommand);
userCommand.registerSubCommand(new UserAddGroupCommand());
userCommand.registerSubCommand(new UserClearCommand());
userCommand.registerSubCommand(new UserDemoteCommand());
userCommand.registerSubCommand(new UserGetUUIDCommand());
userCommand.registerSubCommand(new UserHasPermCommand());
userCommand.registerSubCommand(new UserInfoCommand());
userCommand.registerSubCommand(new UserInheritsPermCommand());
userCommand.registerSubCommand(new UserListNodesCommand());
userCommand.registerSubCommand(new UserPromoteCommand());
userCommand.registerSubCommand(new UserRemoveGroupCommand());
userCommand.registerSubCommand(new UserSetPermissionCommand());
userCommand.registerSubCommand(new UserSetPrimaryGroupCommand());
userCommand.registerSubCommand(new UserShowPosCommand());
userCommand.registerSubCommand(new UserShowTracksCommand());
userCommand.registerSubCommand(new UserUnSetPermissionCommand());
GroupMainCommand groupCommand = new GroupMainCommand();
this.registerMainCommand(groupCommand);
groupCommand.registerSubCommand(new GroupClearCommand());
groupCommand.registerSubCommand(new GroupHasPermCommand());
groupCommand.registerSubCommand(new GroupInfoCommand());
groupCommand.registerSubCommand(new GroupInheritsPermCommand());
groupCommand.registerSubCommand(new GroupListNodesCommand());
groupCommand.registerSubCommand(new GroupSetInheritCommand());
groupCommand.registerSubCommand(new GroupSetPermissionCommand());
groupCommand.registerSubCommand(new GroupShowTracksCommand());
groupCommand.registerSubCommand(new GroupUnsetInheritCommand());
groupCommand.registerSubCommand(new GroupUnSetPermissionCommand());
TrackMainCommand trackCommand = new TrackMainCommand();
this.registerMainCommand(trackCommand);
trackCommand.registerSubCommand(new TrackAppendCommand());
trackCommand.registerSubCommand(new TrackClearCommand());
trackCommand.registerSubCommand(new TrackInfoCommand());
trackCommand.registerSubCommand(new TrackInsertCommand());
trackCommand.registerSubCommand(new TrackRemoveCommand());
this.registerMainCommand(new CreateGroupCommand());
this.registerMainCommand(new DeleteGroupCommand());
this.registerMainCommand(new ListGroupsCommand());
this.registerMainCommand(new CreateTrackCommand());
this.registerMainCommand(new DeleteTrackCommand());
this.registerMainCommand(new ListTracksCommand());
this.registerMainCommand(new DebugCommand());
this.registerMainCommand(new InfoCommand());
this.registerMainCommand(new SyncCommand());
/**
* Generic on command method to be called from the command executor object of the platform
* Unlike {@link #onCommand(Sender, String, List)}, this method is called in a new thread
* @param sender who sent the command
* @param label the command label used
* @param args the arguments provided
* @param result the callback to be called when the command has fully executed
*/
public void onCommand(Sender sender, String label, List<String> args, Callback<CommandResult> result) {
plugin.doAsync(() -> {
CommandResult r = onCommand(sender, label, args);
plugin.doSync(() -> result.onComplete(r));
});
}
/**
* Generic on command method to be called from the command executor object of the platform
* @param sender who sent the command
* @param label the command label used
* @param args the arguments provided
* @return if the command was successful (hint: it always is :> )
* @return if the command was successful
*/
public boolean onCommand(Sender sender, String label, List<String> args) {
public CommandResult onCommand(Sender sender, String label, List<String> args) {
if (args.size() == 0) {
sendCommandUsage(sender, label);
return true;
return CommandResult.INVALID_ARGS;
}
Optional<MainCommand> o = mainCommands.stream().filter(m -> m.getName().equalsIgnoreCase(args.get(0))).limit(1).findAny();
Optional<MainCommand> o = mainCommands.stream()
.filter(m -> m.getName().equalsIgnoreCase(args.get(0)))
.limit(1)
.findAny();
if (!o.isPresent()) {
sendCommandUsage(sender, label);
return true;
return CommandResult.INVALID_ARGS;
}
final MainCommand main = o.get();
if (!main.canUse(sender)) {
if (!main.isAuthorized(sender)) {
sendCommandUsage(sender, label);
return true;
return CommandResult.NO_PERMISSION;
}
if (main.getRequiredArgsLength() == 0) {
main.execute(plugin, sender, null, label);
return true;
try {
return main.execute(plugin, sender, null, label);
} catch (Exception e) {
e.printStackTrace();
return CommandResult.FAILURE;
}
}
if (args.size() == 1) {
main.sendUsage(sender, label);
return true;
return CommandResult.INVALID_ARGS;
}
main.execute(plugin, sender, new ArrayList<>(args.subList(1, args.size())), label);
return true;
try {
return main.execute(plugin, sender, new ArrayList<>(args.subList(1, args.size())), label);
} catch (Exception e) {
e.printStackTrace();
return CommandResult.FAILURE;
}
}
/**
@@ -131,15 +142,17 @@ public class CommandManager {
* @param args the arguments provided so far
* @return a list of suggestions
*/
@SuppressWarnings("unchecked")
public List<String> onTabComplete(Sender sender, List<String> args) {
final List<MainCommand> mains = mainCommands.stream().filter(m -> m.canUse(sender)).collect(Collectors.toList());
final List<MainCommand> mains = mainCommands.stream().filter(m -> m.isAuthorized(sender)).collect(Collectors.toList());
if (args.size() <= 1) {
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
return mains.stream().map(MainCommand::getName).map(String::toLowerCase).collect(Collectors.toList());
}
return mains.stream().map(MainCommand::getName).map(String::toLowerCase).filter(s -> s.startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
return mains.stream().map(MainCommand::getName).map(String::toLowerCase)
.filter(s -> s.startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
Optional<MainCommand> o = mains.stream().filter(m -> m.getName().equalsIgnoreCase(args.get(0))).limit(1).findAny();
@@ -150,16 +163,11 @@ public class CommandManager {
return o.get().onTabComplete(sender, args.subList(1, args.size()), plugin);
}
private void registerMainCommand(MainCommand command) {
plugin.getLogger().log(Level.INFO, "[CommandManager] Registered main command '" + command.getName() + "'");
mainCommands.add(command);
}
private void sendCommandUsage(Sender sender, String label) {
Message.INFO_BRIEF.send(sender, plugin.getVersion());
mainCommands.stream()
.filter(c -> c.canUse(sender))
.filter(c -> c.isAuthorized(sender))
.forEach(c -> Util.sendPluginMessage(sender, "&e-> &d" + String.format(c.getUsage(), label)));
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum CommandResult {
SUCCESS(true),
FAILURE(false),
LOADING_ERROR(false),
STATE_ERROR(false),
INVALID_ARGS(false),
NO_PERMISSION(false);
private boolean booleanValue;
public boolean booleanValue() {
return booleanValue;
}
static CommandResult of(boolean b) {
return b ? SUCCESS : FAILURE;
}
}
@@ -1,10 +1,34 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import com.google.common.collect.ImmutableList;
import lombok.AllArgsConstructor;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.constants.Message;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@@ -12,16 +36,102 @@ import java.util.stream.Collectors;
@Getter
@AllArgsConstructor
public abstract class MainCommand {
public abstract class MainCommand<T> {
/**
* The name of the main command
*/
private final String name;
/**
* The command usage
*/
private final String usage;
/**
* How many arguments are required for the command to run
*/
private final int requiredArgsLength;
protected abstract void execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label);
protected abstract List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin);
public abstract List<? extends SubCommand> getSubCommands();
/**
* A list of the sub commands under this main command
*/
@Getter
private final List<SubCommand<T>> subCommands;
MainCommand(String name, String usage, int requiredArgsLength) {
this(name, usage, requiredArgsLength, ImmutableList.of());
}
/**
* Called when this main command is ran
* @param plugin a link to the main plugin instance
* @param sender the sender to executed the command
* @param args the stripped arguments given
* @param label the command label used
*/
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (args.size() < requiredArgsLength) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
Optional<SubCommand<T>> o = subCommands.stream().filter(s -> s.getName().equalsIgnoreCase(args.get(requiredArgsLength - 1))).limit(1).findAny();
if (!o.isPresent()) {
Message.COMMAND_NOT_RECOGNISED.send(sender);
return CommandResult.INVALID_ARGS;
}
final SubCommand<T> sub = o.get();
if (!sub.isAuthorized(sender)) {
Message.COMMAND_NO_PERMISSION.send(sender);
return CommandResult.NO_PERMISSION;
}
List<String> strippedArgs = new ArrayList<>();
if (args.size() > requiredArgsLength) {
strippedArgs.addAll(args.subList(requiredArgsLength, args.size()));
}
if (sub.getIsArgumentInvalid().test(strippedArgs.size())) {
sub.sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
final String name = args.get(0).toLowerCase();
T t = getTarget(name, plugin, sender);
if (t != null) {
CommandResult result = sub.execute(plugin, sender, t, strippedArgs, label);
cleanup(t, plugin);
return result;
}
return CommandResult.LOADING_ERROR;
}
/**
* Gets the object the command is acting upon, and runs the callback if successful
* @param target the name of the object to be looked up
* @param plugin a link to the main plugin instance
* @param sender the user who send the command (used to send error messages if the lookup was unsuccessful)
*/
protected abstract T getTarget(String target, LuckPermsPlugin plugin, Sender sender);
protected abstract void cleanup(T t, LuckPermsPlugin plugin);
/**
* Get a list of objects for tab completion
* @param plugin a link to the main plugin instance
* @return a list of strings
*/
protected abstract List<String> getObjects(LuckPermsPlugin plugin);
/**
* Send the command usage to a sender
* @param sender the sender to send the usage to
* @param label the command label used
*/
protected void sendUsage(Sender sender, String label) {
if (getSubCommands().isEmpty()) {
Util.sendPluginMessage(sender, "&e-> &d" + String.format(getUsage(), label));
@@ -41,12 +151,27 @@ public abstract class MainCommand {
}
}
protected boolean canUse(Sender sender) {
/**
* If a sender has permission to use this command
* @param sender the sender trying to use the command
* @return true if the sender can use the command
*/
protected boolean isAuthorized(Sender sender) {
return getSubCommands().stream().filter(sc -> sc.isAuthorized(sender)).count() != 0;
}
protected List<String> onAbstractTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
final List<SubCommand> subs = getSubCommands().stream().filter(s -> s.isAuthorized(sender)).collect(Collectors.toList());
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
final List<String> objects = getObjects(plugin);
if (args.size() <= 1) {
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
return objects;
}
return objects.stream().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
final List<SubCommand<T>> subs = getSubCommands().stream().filter(s -> s.isAuthorized(sender)).collect(Collectors.toList());
if (args.size() == 2) {
if (args.get(1).equalsIgnoreCase("")) {
return subs.stream().map(SubCommand::getName).map(String::toLowerCase).collect(Collectors.toList());
@@ -56,11 +181,11 @@ public abstract class MainCommand {
.filter(s -> s.toLowerCase().startsWith(args.get(1).toLowerCase())).collect(Collectors.toList());
}
Optional<SubCommand> o = subs.stream().filter(s -> s.getName().equalsIgnoreCase(args.get(1))).limit(1).findAny();
Optional<SubCommand<T>> o = subs.stream().filter(s -> s.getName().equalsIgnoreCase(args.get(1))).limit(1).findAny();
if (!o.isPresent()) {
return Collections.emptyList();
}
return o.get().onTabComplete(sender, args.subList(2, args.size()), plugin);
return o.get().onTabComplete(plugin, sender, args.subList(2, args.size()));
}
}
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import lombok.experimental.UtilityClass;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@SuppressWarnings({"WeakerAccess", "unused"})
@UtilityClass
public class Predicate {
public static <T> java.util.function.Predicate<T> alwaysFalse() {
return t -> false;
}
public static <T> java.util.function.Predicate<T> alwaysTrue() {
return t -> true;
}
public static java.util.function.Predicate<Integer> notInRange(Integer start, Integer end) {
return inverse(inRange(start, end));
}
public static java.util.function.Predicate<Integer> inRange(Integer start, Integer end) {
return isOneOf(IntStream.rangeClosed(start, end).boxed().collect(Collectors.toSet()));
}
public static <T> java.util.function.Predicate<T> notOneOf(Set<T> ts) {
return inverse(isOneOf(ts));
}
public static <T> java.util.function.Predicate<T> isOneOf(Set<T> ta) {
return t -> {
for (T i : ta) {
if (i == t) {
return true;
}
}
return false;
};
}
public static <T> java.util.function.Predicate<T> not(T t) {
return inverse(is(t));
}
public static <T> java.util.function.Predicate<T> is(T t) {
return t2 -> t == t2;
}
public static <T> java.util.function.Predicate<T> inverse(java.util.function.Predicate<T> t) {
return t2 -> !t.test(t2);
}
}
@@ -1,8 +1,39 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import me.lucko.luckperms.constants.Permission;
import java.util.UUID;
/**
* Wrapper interface to represent a CommandSender/CommandSource within the luckperms-common command implementations.
*/
public interface Sender {
String getName();
UUID getUuid();
void sendMessage(String s);
boolean hasPermission(String node);
boolean hasPermission(Permission permission);
}
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import lombok.Getter;
import me.lucko.luckperms.constants.Permission;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.stream.Collectors;
/**
* Factory class to make a thread-safe sender instance
* @param <T> the command sender type
*/
public abstract class SenderFactory<T> implements Runnable {
// Ensures messages are sent in order, etc.
private final List<Runnable> tasks = new ArrayList<>();
private final SenderFactory<T> factory = this;
protected abstract String getName(T t);
protected abstract UUID getUuid(T t);
protected abstract void sendMessage(T t, String s);
protected abstract boolean hasPermission(T t, String node);
public final Sender wrap(T t) {
return new Sender() {
final WeakReference<T> tRef = new WeakReference<>(t);
// Cache these permissions, so they can be accessed async
final Map<Permission, Boolean> perms = Arrays.stream(Permission.values())
.map(p -> new AbstractMap.SimpleEntry<>(p, factory.hasPermission(t, p.getNode())))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
@Getter
final String name = factory.getName(t);
@Getter
final UUID uuid = factory.getUuid(t);
@Override
public void sendMessage(String s) {
final T t = tRef.get();
if (t != null) {
synchronized (tasks) {
tasks.add(() -> factory.sendMessage(t, s));
}
}
}
@Override
public boolean hasPermission(Permission permission) {
synchronized (perms) {
return perms.get(permission);
}
}
};
}
@Override
public final void run() {
synchronized (tasks) {
if (!tasks.isEmpty()) {
tasks.forEach(Runnable::run);
tasks.clear();
}
}
}
}
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.constants.Permission;
import java.util.Collections;
import java.util.List;
/**
* An extension of {@link MainCommand} for implementations without any subcommands
*/
public class SingleMainCommand extends MainCommand<Object> {
private final Permission permission;
public SingleMainCommand(String name, String usage, int requiredArgsLength, Permission permission) {
super(name, usage, requiredArgsLength);
this.permission = permission;
}
@Override
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
// Do nothing, allow the implementation to override this
return null;
}
@Override
protected Object getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
return null;
}
@Override
protected void cleanup(Object o, LuckPermsPlugin plugin) {
// Do nothing
}
@Override
protected List<String> getObjects(LuckPermsPlugin plugin) {
return Collections.emptyList();
}
@Override
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return Collections.emptyList();
}
@Override
public List<SubCommand<Object>> getSubCommands() {
return Collections.emptyList();
}
@Override
protected boolean isAuthorized(Sender sender) {
return permission.isAuthorized(sender);
}
}
@@ -1,30 +1,135 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import lombok.AllArgsConstructor;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* Abstract SubCommand class
*/
@Getter
@AllArgsConstructor
public abstract class SubCommand {
public abstract class SubCommand<T> {
/**
* The name of the sub command
*/
private final String name;
/**
* A brief description of what the sub command does
*/
private final String description;
/**
* The command usage
*/
private final String usage;
/**
* The permission needed to use this command
*/
private final Permission permission;
/**
* Predicate to test if the argument length given is invalid
*/
private final Predicate<? super Integer> isArgumentInvalid;
/**
* Called when this sub command is ran
* @param plugin a link to the main plugin instance
* @param sender the sender to executed the command
* @param t the object the command is operating on
* @param args the stripped arguments given
* @param label the command label used
*/
public abstract CommandResult execute(LuckPermsPlugin plugin, Sender sender, T t, List<String> args, String label);
/**
* Returns a list of suggestions, which are empty by default. Sub classes that give tab complete suggestions override
* this method to give their own list.
* @param plugin the plugin instance
* @param sender who is tab completing
* @param args the arguments so far
* @return a list of suggestions
*/
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
return Collections.emptyList();
}
/**
* Send the command usage to a sender
* @param sender the sender to send the usage to
* @param label the command label used
*/
public void sendUsage(Sender sender, String label) {
Util.sendPluginMessage(sender, "&e-> &d" + String.format(getUsage(), label));
}
/**
* If a sender has permission to use this command
* @param sender the sender trying to use the command
* @return true if the sender can use the command
*/
public boolean isAuthorized(Sender sender) {
return permission.isAuthorized(sender);
}
/*
----------------------------------------------------------------------------------
Utility methods used by #onTabComplete and #execute implementations in sub classes
----------------------------------------------------------------------------------
*/
protected static List<String> getGroupTabComplete(List<String> args, LuckPermsPlugin plugin) {
return getTabComplete(new ArrayList<>(plugin.getGroupManager().getGroups().keySet()), args);
return getTabComplete(new ArrayList<>(plugin.getGroupManager().getAll().keySet()), args);
}
protected static List<String> getTrackTabComplete(List<String> args, LuckPermsPlugin plugin) {
return getTabComplete(new ArrayList<>(plugin.getTrackManager().getTracks().keySet()), args);
return getTabComplete(new ArrayList<>(plugin.getTrackManager().getAll().keySet()), args);
}
protected static List<String> getBoolTabComplete(List<String> args) {
if (args.size() == 2) {
return Arrays.asList("true", "false");
} else {
return Collections.emptyList();
}
}
private static List<String> getTabComplete(List<String> options, List<String> args) {
@@ -39,25 +144,39 @@ public abstract class SubCommand {
return Collections.emptyList();
}
protected static List<String> getBoolTabComplete(List<String> args) {
if (args.size() == 2) {
return Arrays.asList("true", "false");
} else {
return Collections.emptyList();
}
protected static void save(User user, Sender sender, LuckPermsPlugin plugin) {
user.refreshPermissions();
plugin.getDatastore().saveUser(user, success -> {
if (success) {
Message.USER_SAVE_SUCCESS.send(sender);
} else {
Message.USER_SAVE_ERROR.send(sender);
}
});
}
public boolean isAuthorized(Sender sender) {
return permission.isAuthorized(sender);
protected static void save(Group group, Sender sender, LuckPermsPlugin plugin) {
plugin.getDatastore().saveGroup(group, success -> {
if (success) {
Message.GROUP_SAVE_SUCCESS.send(sender);
} else {
Message.GROUP_SAVE_ERROR.send(sender);
}
plugin.runUpdateTask();
});
}
public void sendUsage(Sender sender, String label) {
Util.sendPluginMessage(sender, "&e-> &d" + String.format(getUsage(), label));
}
protected static void save(Track track, Sender sender, LuckPermsPlugin plugin) {
plugin.getDatastore().saveTrack(track, success -> {
if (success) {
Message.TRACK_SAVE_SUCCESS.send(sender);
} else {
Message.TRACK_SAVE_ERROR.send(sender);
}
public List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return Collections.emptyList();
plugin.runUpdateTask();
});
}
public abstract boolean isArgLengthInvalid(int argLength);
}
@@ -1,15 +1,39 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands;
import lombok.experimental.UtilityClass;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Patterns;
import me.lucko.luckperms.utils.DateUtil;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@UtilityClass
public class Util {
private Util() {}
public static void sendPluginMessage(Sender sender, String message) {
sender.sendMessage(color(Message.PREFIX + message));
}
@@ -32,12 +56,16 @@ public class Util {
return new String(b);
}
public static String stripColor(String s) {
return s == null ? null : Patterns.STRIP_COLOR_PATTERN.matcher(s).replaceAll("");
}
public static String formatBoolean(boolean b) {
return b ? "&atrue" : "&cfalse";
}
public static void sendBoolean(Sender sender, String node, boolean b) {
if (b) {
sender.sendMessage(Util.color("&b" + node + ": &atrue"));
} else {
sender.sendMessage(Util.color("&b" + node + ": &cfalse"));
}
sender.sendMessage(Util.color("&b" + node + ": " + formatBoolean(b)));
}
public static String listToCommaSep(List<String> strings) {
@@ -86,7 +114,7 @@ public class Util {
return sb.delete(sb.length() - 6, sb.length()).toString();
}
public static String nodesToString(Map<String, Boolean> nodes) {
public static String permNodesToString(Map<String, Boolean> nodes) {
if (nodes.isEmpty()) return "&6None";
StringBuilder sb = new StringBuilder();
@@ -102,6 +130,24 @@ public class Util {
return sb.delete(sb.length() - 2, sb.length()).toString();
}
public static String tempNodesToString(Map<Map.Entry<String, Boolean>, Long> nodes) {
if (nodes.isEmpty()) return "&6None";
StringBuilder sb = new StringBuilder();
for (Map.Entry<Map.Entry<String, Boolean>, Long> e : nodes.entrySet()) {
if (e.getKey().getValue()) {
sb.append("&a").append(e.getKey().getKey()).append("&6 - expires in ")
.append(DateUtil.formatDateDiff(e.getValue())).append("\n");
} else {
sb.append("&c").append(e.getKey().getKey()).append("&6 - expires in ")
.append(DateUtil.formatDateDiff(e.getValue())).append("\n");
}
}
return sb.toString();
}
public static UUID parseUuid(String s) {
try {
return UUID.fromString(s);
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SingleMainCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.List;
public class CreateGroup extends SingleMainCommand {
public CreateGroup() {
super("CreateGroup", "/%s creategroup <group>", 1, Permission.CREATE_GROUP);
}
@Override
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (args.size() == 0) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkName(groupName)) {
Message.GROUP_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadGroup(groupName)) {
Message.GROUP_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadGroup(groupName)) {
Message.CREATE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
Message.CREATE_SUCCESS.send(sender, groupName);
LogEntryBuilder.get().actor(sender).actedName(groupName).type('G').action("create").submit(plugin);
plugin.runUpdateTask();
return CommandResult.SUCCESS;
}
}
@@ -1,68 +0,0 @@
package me.lucko.luckperms.commands.group;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.utils.Patterns;
import java.util.Collections;
import java.util.List;
public class CreateGroupCommand extends MainCommand {
public CreateGroupCommand() {
super("CreateGroup", "/%s creategroup <group>", 1);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (args.size() == 0) {
sendUsage(sender, label);
return;
}
String groupName = args.get(0).toLowerCase();
if (groupName.length() > 36) {
Message.GROUP_NAME_TOO_LONG.send(sender, groupName);
return;
}
if (Patterns.NON_ALPHA_NUMERIC.matcher(groupName).find()) {
Message.GROUP_INVALID_ENTRY.send(sender);
return;
}
plugin.getDatastore().loadGroup(groupName, success -> {
if (success) {
Message.GROUP_ALREADY_EXISTS.send(sender);
} else {
plugin.getDatastore().createAndLoadGroup(groupName, success1 -> {
if (!success1) {
Message.CREATE_GROUP_ERROR.send(sender);
} else {
Message.CREATE_SUCCESS.send(sender, groupName);
plugin.runUpdateTask();
}
});
}
});
}
@Override
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return Collections.emptyList();
}
@Override
public List<SubCommand> getSubCommands() {
return Collections.emptyList();
}
@Override
protected boolean canUse(Sender sender) {
return Permission.CREATE_GROUP.isAuthorized(sender);
}
}
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SingleMainCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class DeleteGroup extends SingleMainCommand {
public DeleteGroup() {
super("DeleteGroup", "/%s deletegroup <group>", 1, Permission.DELETE_GROUP);
}
@Override
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (args.size() == 0) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
String groupName = args.get(0).toLowerCase();
if (groupName.equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
Message.DELETE_GROUP_ERROR_DEFAULT.send(sender);
return CommandResult.INVALID_ARGS;
}
if (ArgumentChecker.checkName(groupName)) {
Message.GROUP_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName)) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
Group group = plugin.getGroupManager().get(groupName);
if (group == null) {
Message.GROUP_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}
if (!plugin.getDatastore().deleteGroup(group)) {
Message.DELETE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
Message.DELETE_SUCCESS.send(sender, groupName);
LogEntryBuilder.get().actor(sender).actedName(groupName).type('G').action("delete").submit(plugin);
plugin.runUpdateTask();
return CommandResult.SUCCESS;
}
@Override
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
final List<String> groups = new ArrayList<>(plugin.getGroupManager().getAll().keySet());
if (args.size() <= 1) {
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
return groups;
}
return groups.stream().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
return Collections.emptyList();
}
}
@@ -1,81 +0,0 @@
package me.lucko.luckperms.commands.group;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class DeleteGroupCommand extends MainCommand {
public DeleteGroupCommand() {
super("DeleteGroup", "/%s deletegroup <group>", 1);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (args.size() == 0) {
sendUsage(sender, label);
return;
}
String groupName = args.get(0).toLowerCase();
if (groupName.equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
Message.DELETE_GROUP_ERROR_DEFAULT.send(sender);
return;
}
plugin.getDatastore().loadGroup(groupName, success -> {
if (!success) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
} else {
Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) {
Message.GROUP_LOAD_ERROR.send(sender);
} else {
plugin.getDatastore().deleteGroup(group, success1 -> {
if (!success1) {
Message.DELETE_GROUP_ERROR.send(sender);
} else {
Message.DELETE_SUCCESS.send(sender, groupName);
plugin.runUpdateTask();
}
});
}
}
});
}
@Override
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
final List<String> groups = new ArrayList<>(plugin.getGroupManager().getGroups().keySet());
if (args.size() <= 1) {
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
return groups;
}
return groups.stream().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
return Collections.emptyList();
}
@Override
public List<SubCommand> getSubCommands() {
return Collections.emptyList();
}
@Override
protected boolean canUse(Sender sender) {
return Permission.DELETE_GROUP.isAuthorized(sender);
}
}
@@ -1,94 +1,89 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.commands.group.subcommands.*;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class GroupMainCommand extends MainCommand {
private final List<GroupSubCommand> subCommands = new ArrayList<>();
public class GroupMainCommand extends MainCommand<Group> {
public GroupMainCommand() {
super("Group", "/%s group <group>", 2);
super("Group", "/%s group <group>", 2, ImmutableList.<SubCommand<Group>>builder()
.add(new GroupInfo())
.add(new GroupListNodes())
.add(new GroupHasPerm())
.add(new GroupInheritsPerm())
.add(new GroupSetPermission())
.add(new GroupUnSetPermission())
.add(new GroupSetInherit())
.add(new GroupUnsetInherit())
.add(new GroupSetTempPermission())
.add(new GroupUnsetTempPermission())
.add(new GroupSetTempInherit())
.add(new GroupUnsetTempInherit())
.add(new GroupShowTracks())
.add(new GroupClear())
.build()
);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (args.size() < 2) {
sendUsage(sender, label);
return;
protected Group getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
if (ArgumentChecker.checkName(target)) {
Message.GROUP_INVALID_ENTRY.send(sender);
return null;
}
Optional<GroupSubCommand> o = subCommands.stream().filter(s -> s.getName().equalsIgnoreCase(args.get(1))).limit(1).findAny();
if (!o.isPresent()) {
Message.COMMAND_NOT_RECOGNISED.send(sender);
return;
if (!plugin.getDatastore().loadGroup(target)) {
Message.GROUP_NOT_FOUND.send(sender);
return null;
}
final GroupSubCommand sub = o.get();
if (!sub.isAuthorized(sender)) {
Message.COMMAND_NO_PERMISSION.send(sender);
return;
Group group = plugin.getGroupManager().get(target);
if (group == null) {
Message.GROUP_NOT_FOUND.send(sender);
}
List<String> strippedArgs = new ArrayList<>();
if (args.size() > 2) {
strippedArgs.addAll(args.subList(2, args.size()));
}
if (sub.isArgLengthInvalid(strippedArgs.size())) {
sub.sendUsage(sender, label);
return;
}
final String groupName = args.get(0).toLowerCase();
plugin.getDatastore().loadGroup(groupName, success -> {
if (!success) {
Message.GROUP_NOT_FOUND.send(sender);
return;
}
Group group = plugin.getGroupManager().getGroup(groupName);
if (group == null) {
Message.GROUP_NOT_FOUND.send(sender);
return;
}
sub.execute(plugin, sender, group, strippedArgs, label);
});
return group;
}
@Override
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
final List<String> groups = new ArrayList<>(plugin.getGroupManager().getGroups().keySet());
protected void cleanup(Group group, LuckPermsPlugin plugin) {
if (args.size() <= 1) {
if (args.isEmpty() || args.get(0).equalsIgnoreCase("")) {
return groups;
}
return groups.stream().filter(s -> s.toLowerCase().startsWith(args.get(0).toLowerCase())).collect(Collectors.toList());
}
return onAbstractTabComplete(sender, args, plugin);
}
@Override
public List<? extends SubCommand> getSubCommands() {
return subCommands;
protected List<String> getObjects(LuckPermsPlugin plugin) {
return new ArrayList<>(plugin.getGroupManager().getAll().keySet());
}
public void registerSubCommand(GroupSubCommand subCommand) {
subCommands.add(subCommand);
}
}
@@ -1,30 +0,0 @@
package me.lucko.luckperms.commands.group;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public abstract class GroupSubCommand extends SubCommand {
protected GroupSubCommand(String name, String description, String usage, Permission permission) {
super(name, description, usage, permission);
}
protected abstract void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label);
protected void saveGroup(Group group, Sender sender, LuckPermsPlugin plugin) {
plugin.getDatastore().saveGroup(group, success -> {
if (success) {
Message.GROUP_SAVE_SUCCESS.send(sender);
} else {
Message.GROUP_SAVE_ERROR.send(sender);
}
plugin.runUpdateTask();
});
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SingleMainCommand;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import java.util.ArrayList;
import java.util.List;
public class ListGroups extends SingleMainCommand {
public ListGroups() {
super("ListGroups", "/%s listgroups", 0, Permission.LIST_GROUPS);
}
@Override
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (!plugin.getDatastore().loadAllGroups()) {
Message.GROUPS_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}
Message.GROUPS_LIST.send(sender, Util.listToCommaSep(new ArrayList<>(plugin.getGroupManager().getAll().keySet())));
return CommandResult.SUCCESS;
}
}
@@ -1,45 +0,0 @@
package me.lucko.luckperms.commands.group;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.MainCommand;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListGroupsCommand extends MainCommand {
public ListGroupsCommand() {
super("ListGroups", "/%s listgroups", 0);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
plugin.getDatastore().loadAllGroups(success -> {
if (!success) {
Message.GROUPS_LOAD_ERROR.send(sender);
} else {
Message.GROUPS_LIST.send(sender, Util.listToCommaSep(new ArrayList<>(plugin.getGroupManager().getGroups().keySet())));
}
});
}
@Override
protected List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return Collections.emptyList();
}
@Override
public List<SubCommand> getSubCommands() {
return Collections.emptyList();
}
@Override
protected boolean canUse(Sender sender) {
return Permission.LIST_GROUPS.isAuthorized(sender);
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupClear extends SubCommand<Group> {
public GroupClear() {
super("clear", "Clears a groups permissions", "/%s group <group> clear", Permission.GROUP_CLEAR,
Predicate.alwaysFalse());
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
group.clearNodes();
Message.CLEAR_SUCCESS.send(sender, group.getName());
LogEntryBuilder.get().actor(sender).acted(group).action("clear").submit(plugin);
save(group, sender, plugin);
return CommandResult.SUCCESS;
}
}
@@ -1,29 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupClearCommand extends GroupSubCommand {
public GroupClearCommand() {
super("clear", "Clears a groups permissions", "/%s group <group> clear", Permission.GROUP_CLEAR);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
group.clearNodes();
Message.CLEAR_SUCCESS.send(sender, group.getName());
saveGroup(group, sender, plugin);
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.*;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.List;
public class GroupHasPerm extends SubCommand<Group> {
public GroupHasPerm() {
super("haspermission", "Checks to see if a group has a certain permission node",
"/%s group <group> haspermission <node> [server] [world]", Permission.GROUP_HASPERMISSION,
Predicate.notInRange(1, 3));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (args.size() >= 2) {
if (ArgumentChecker.checkServer(args.get(1))) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 2) {
Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, args.get(1)));
} else {
Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, args.get(1), args.get(2)));
}
} else {
Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, "global"));
}
return CommandResult.SUCCESS;
}
}
@@ -1,31 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupHasPermCommand extends GroupSubCommand {
public GroupHasPermCommand() {
super("haspermission", "Checks to see if a group has a certain permission node",
"/%s group <group> haspermission <node> [server]", Permission.GROUP_HASPERMISSION);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (args.size() == 2) {
Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, args.get(1).toLowerCase()));
} else {
Util.sendBoolean(sender, args.get(0), group.hasPermission(args.get(0), true, "global"));
}
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1 && argLength != 2;
}
}
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupInfo extends SubCommand<Group> {
public GroupInfo() {
super("info", "Gives info about the group", "/%s group <group> info", Permission.GROUP_INFO,
Predicate.alwaysFalse());
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
Message.GROUP_INFO.send(sender,
group.getName(),
group.getPermanentNodes().keySet().size(),
group.getTemporaryNodes().keySet().size(),
label,
group.getName()
);
return CommandResult.SUCCESS;
}
}
@@ -1,26 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupInfoCommand extends GroupSubCommand {
public GroupInfoCommand() {
super("info", "Gives info about the group", "/%s group <group> info", Permission.GROUP_INFO);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
Message.GROUP_INFO.send(sender, group.getName(), group.getNodes().keySet().size(), label, group.getName());
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.*;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.List;
public class GroupInheritsPerm extends SubCommand<Group> {
public GroupInheritsPerm() {
super("inheritspermission", "Checks to see if a group inherits a certain permission node",
"/%s group <group> inheritspermission <node> [server] [world]", Permission.GROUP_INHERITSPERMISSION,
Predicate.notInRange(1, 3));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (args.size() >= 2) {
if (ArgumentChecker.checkServer(args.get(1))) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 2) {
Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true, args.get(1)));
} else {
Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true, args.get(1), args.get(2)));
}
} else {
Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true));
}
return CommandResult.SUCCESS;
}
}
@@ -1,31 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupInheritsPermCommand extends GroupSubCommand {
public GroupInheritsPermCommand() {
super("inheritspermission", "Checks to see if a group inherits a certain permission node",
"/%s group <group> inheritspermission <node> [server]", Permission.GROUP_INHERITSPERMISSION);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (args.size() == 2) {
Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true, args.get(1).toLowerCase()));
} else {
Util.sendBoolean(sender, args.get(0), group.inheritsPermission(args.get(0), true));
}
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1 && argLength != 2;
}
}
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.*;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupListNodes extends SubCommand<Group> {
public GroupListNodes() {
super("listnodes", "Lists the permission nodes the group has", "/%s group <group> listnodes",
Permission.GROUP_LISTNODES, Predicate.alwaysFalse());
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
Message.LISTNODES.send(sender, group.getName(), Util.permNodesToString(group.getPermanentNodes()));
Message.LISTNODES_TEMP.send(sender, group.getName(), Util.tempNodesToString(group.getTemporaryNodes()));
return CommandResult.SUCCESS;
}
}
@@ -1,28 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupListNodesCommand extends GroupSubCommand {
public GroupListNodesCommand() {
super("listnodes", "Lists the permission nodes the group has", "/%s group <group> listnodes",
Permission.GROUP_LISTNODES);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
Message.LISTNODES.send(sender, group.getName(), Util.nodesToString(group.getNodes()));
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.List;
public class GroupSetInherit extends SubCommand<Group> {
public GroupSetInherit() {
super("setinherit", "Sets another group for this group to inherit permissions from",
"/%s group <group> setinherit <group> [server] [world]", Permission.GROUP_SETINHERIT,
Predicate.notInRange(1, 3));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkNode(groupName)) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName)) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
Group group1 = plugin.getGroupManager().get(groupName);
if (group1 == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.LOADING_ERROR;
}
try {
if (args.size() >= 2) {
final String server = args.get(1).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 2) {
group.setInheritGroup(group1, server);
Message.GROUP_SETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), group1.getName(), server);
LogEntryBuilder.get().actor(sender).acted(group)
.action("setinherit " + group1.getName() + " " + server)
.submit(plugin);
} else {
final String world = args.get(2).toLowerCase();
group.setInheritGroup(group1, server, world);
Message.GROUP_SETINHERIT_SERVER_WORLD_SUCCESS.send(sender, group.getName(), group1.getName(), server, world);
LogEntryBuilder.get().actor(sender).acted(group)
.action("setinherit " + group1.getName() + " " + server + " " + world)
.submit(plugin);
}
} else {
group.setInheritGroup(group1);
Message.GROUP_SETINHERIT_SUCCESS.send(sender, group.getName(), group1.getName());
LogEntryBuilder.get().actor(sender).acted(group)
.action("setinherit " + group1.getName())
.submit(plugin);
}
save(group, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.GROUP_ALREADY_INHERITS.send(sender, group.getName(), group1.getName());
return CommandResult.STATE_ERROR;
}
}
@Override
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
return getGroupTabComplete(args, plugin);
}
}
@@ -1,54 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupSetInheritCommand extends GroupSubCommand {
public GroupSetInheritCommand() {
super("setinherit", "Sets another group for this group to inherit permissions from",
"/%s group <group> setinherit <group> [server]", Permission.GROUP_SETINHERIT);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String groupName = args.get(0).toLowerCase();
plugin.getDatastore().loadGroup(groupName, success -> {
if (!success) {
Message.GROUP_LOAD_ERROR.send(sender);
} else {
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
group.setPermission("group." + groupName, true, server);
Message.GROUP_SETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server);
} else {
group.setPermission("group." + groupName, true);
Message.GROUP_SETINHERIT_SUCCESS.send(sender, group.getName(), groupName);
}
saveGroup(group, sender, plugin);
} catch (ObjectAlreadyHasException e) {
Message.GROUP_ALREADY_INHERITS.send(sender, group.getName(), groupName);
}
}
});
}
@Override
public List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return getGroupTabComplete(args, plugin);
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1 && argLength != 2;
}
}
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Patterns;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.List;
public class GroupSetPermission extends SubCommand<Group> {
public GroupSetPermission() {
super("set", "Sets a permission for a group", "/%s group <group> set <node> <true|false> [server] [world]",
Permission.GROUP_SETPERMISSION, Predicate.notInRange(2, 4));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String node = args.get(0);
String bool = args.get(1).toLowerCase();
if (ArgumentChecker.checkNode(node)) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
Message.GROUP_USE_INHERIT.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
boolean b = Boolean.parseBoolean(bool);
try {
if (args.size() >= 3) {
final String server = args.get(2).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 3) {
group.setPermission(node, b, server);
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, group.getName(), server);
LogEntryBuilder.get().actor(sender).acted(group)
.action("set " + node + " " + b + " " + server)
.submit(plugin);
} else {
final String world = args.get(3).toLowerCase();
group.setPermission(node, b, server, world);
Message.SETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, bool, group.getName(), server, world);
LogEntryBuilder.get().actor(sender).acted(group)
.action("set " + node + " " + b + " " + server + " " + world)
.submit(plugin);
}
} else {
group.setPermission(node, b);
Message.SETPERMISSION_SUCCESS.send(sender, node, bool, group.getName());
LogEntryBuilder.get().actor(sender).acted(group)
.action("set " + node + " " + b)
.submit(plugin);
}
save(group, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.ALREADY_HASPERMISSION.send(sender, group.getName());
return CommandResult.STATE_ERROR;
}
}
@Override
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
return getBoolTabComplete(args);
}
}
@@ -1,67 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
public class GroupSetPermissionCommand extends GroupSubCommand {
public GroupSetPermissionCommand() {
super("set", "Sets a permission for a group", "/%s group <group> set <node> <true|false> [server]",
Permission.GROUP_SETPERMISSION);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String node = args.get(0);
String bool = args.get(1).toLowerCase();
if (node.contains("/")) {
sendUsage(sender, label);
return;
}
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
Message.GROUP_USE_INHERIT.send(sender);
return;
}
if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) {
sendUsage(sender, label);
return;
}
boolean b = Boolean.parseBoolean(bool);
try {
if (args.size() == 3) {
final String server = args.get(2).toLowerCase();
group.setPermission(node, b, server);
Message.SETPERMISSION_SERVER_SUCCESS.send(sender, node, bool, group.getName(), server);
} else {
group.setPermission(node, b);
Message.SETPERMISSION_SUCCESS.send(sender, node, bool, group.getName());
}
saveGroup(group, sender, plugin);
} catch (ObjectAlreadyHasException e) {
Message.ALREADY_HASPERMISSION.send(sender, group.getName());
}
}
@Override
public List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return getBoolTabComplete(args);
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 2 && argLength != 3;
}
}
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import me.lucko.luckperms.utils.DateUtil;
import java.util.List;
public class GroupSetTempInherit extends SubCommand<Group> {
public GroupSetTempInherit() {
super("settempinherit", "Sets another group for this group to inherit permissions from temporarily",
"/%s group <group> settempinherit <group> <duration> [server] [world]",
Permission.GROUP_SET_TEMP_INHERIT, Predicate.notInRange(2, 4));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkNode(groupName)) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
long duration;
try {
duration = DateUtil.parseDateDiff(args.get(1), true);
} catch (DateUtil.IllegalDateException e) {
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(1));
return CommandResult.INVALID_ARGS;
}
if (DateUtil.shouldExpire(duration)) {
Message.PAST_DATE_ERROR.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName)) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
Group group1 = plugin.getGroupManager().get(groupName);
if (group1 == null) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
try {
if (args.size() >= 3) {
final String server = args.get(2).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 3) {
group.setInheritGroup(group1, server, duration);
Message.GROUP_SET_TEMP_INHERIT_SERVER_SUCCESS.send(sender, group.getName(), group1.getName(), server,
DateUtil.formatDateDiff(duration));
LogEntryBuilder.get().actor(sender).acted(group)
.action("settempinherit " + group1.getName() + " " + duration + " " + server)
.submit(plugin);
} else {
final String world = args.get(3).toLowerCase();
group.setInheritGroup(group1, server, world, duration);
Message.GROUP_SET_TEMP_INHERIT_SERVER_WORLD_SUCCESS.send(sender, group.getName(), group1.getName(), server,
world, DateUtil.formatDateDiff(duration));
LogEntryBuilder.get().actor(sender).acted(group)
.action("settempinherit " + group1.getName() + " " + duration + " " + server + " " + world)
.submit(plugin);
}
} else {
group.setInheritGroup(group1, duration);
Message.GROUP_SET_TEMP_INHERIT_SUCCESS.send(sender, group.getName(), group1.getName(), DateUtil.formatDateDiff(duration));
LogEntryBuilder.get().actor(sender).acted(group)
.action("settempinherit " + group1.getName() + " " + duration)
.submit(plugin);
}
save(group, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.USER_ALREADY_TEMP_MEMBER_OF.send(sender, group.getName(), group1.getName());
return CommandResult.STATE_ERROR;
}
}
@Override
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
return getGroupTabComplete(args, plugin);
}
}
@@ -0,0 +1,128 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Patterns;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import me.lucko.luckperms.utils.DateUtil;
import java.util.List;
public class GroupSetTempPermission extends SubCommand<Group> {
public GroupSetTempPermission() {
super("settemp", "Sets a temporary permission for a group",
"/%s group <group> settemp <node> <true|false> <duration> [server] [world]",
Permission.GROUP_SET_TEMP_PERMISSION, Predicate.notInRange(3, 5));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String node = args.get(0);
String bool = args.get(1).toLowerCase();
if (ArgumentChecker.checkNode(node)) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
Message.GROUP_USE_INHERIT.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!bool.equalsIgnoreCase("true") && !bool.equalsIgnoreCase("false")) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
boolean b = Boolean.parseBoolean(bool);
long duration;
try {
duration = DateUtil.parseDateDiff(args.get(2), true);
} catch (DateUtil.IllegalDateException e) {
Message.ILLEGAL_DATE_ERROR.send(sender, args.get(2));
return CommandResult.INVALID_ARGS;
}
if (DateUtil.shouldExpire(duration)) {
Message.PAST_DATE_ERROR.send(sender);
return CommandResult.INVALID_ARGS;
}
try {
if (args.size() >= 4) {
final String server = args.get(3).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 4) {
group.setPermission(node, b, server, duration);
Message.SETPERMISSION_TEMP_SERVER_SUCCESS.send(sender, node, bool, group.getName(), server,
DateUtil.formatDateDiff(duration));
LogEntryBuilder.get().actor(sender).acted(group)
.action("settemp " + node + " " + b + " " + duration + " " + server)
.submit(plugin);
} else {
final String world = args.get(4).toLowerCase();
group.setPermission(node, b, server, world, duration);
Message.SETPERMISSION_TEMP_SERVER_WORLD_SUCCESS.send(sender, node, bool, group.getName(), server,
world, DateUtil.formatDateDiff(duration));
LogEntryBuilder.get().actor(sender).acted(group)
.action("settemp " + node + " " + b + " " + duration + " " + server + " " + world)
.submit(plugin);
}
} else {
group.setPermission(node, b, duration);
Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, bool, group.getName(), DateUtil.formatDateDiff(duration));
LogEntryBuilder.get().actor(sender).acted(group)
.action("settemp " + node + " " + b + " " + duration)
.submit(plugin);
}
save(group, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectAlreadyHasException e) {
Message.ALREADY_HAS_TEMP_PERMISSION.send(sender, group.getName());
return CommandResult.STATE_ERROR;
}
}
@Override
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
return getBoolTabComplete(args);
}
}
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.*;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
import java.util.stream.Collectors;
public class GroupShowTracks extends SubCommand<Group> {
public GroupShowTracks() {
super("showtracks", "Lists the tracks that this group features on", "/%s group <group> showtracks",
Permission.GROUP_SHOWTRACKS, Predicate.alwaysFalse());
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
if (!plugin.getDatastore().loadAllTracks()) {
Message.TRACKS_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}
Message.TRACKS_LIST.send(sender,
Util.listToCommaSep(plugin.getTrackManager().getApplicableTracks(group.getName()).stream()
.map(Track::getName)
.collect(Collectors.toList())
)
);
return CommandResult.SUCCESS;
}
}
@@ -1,37 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.Util;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import java.util.List;
import java.util.stream.Collectors;
public class GroupShowTracksCommand extends GroupSubCommand {
public GroupShowTracksCommand() {
super("showtracks", "Lists the tracks that this group features on", "/%s group <group> showtracks", Permission.GROUP_SHOWTRACKS);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
plugin.getDatastore().loadAllTracks(success -> {
if (!success) {
Message.TRACKS_LOAD_ERROR.send(sender);
return;
}
Message.TRACKS_LIST.send(sender, Util.listToCommaSep(
plugin.getTrackManager().getApplicableTracks(group.getName()).stream().map(Track::getName).collect(Collectors.toList())));
});
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return false;
}
}
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Patterns;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.List;
public class GroupUnSetPermission extends SubCommand<Group> {
public GroupUnSetPermission() {
super("unset", "Unsets a permission for a group", "/%s group <group> unset <node> [server] [world]",
Permission.GROUP_UNSETPERMISSION, Predicate.notInRange(1, 3));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String node = args.get(0);
if (ArgumentChecker.checkNode(node)) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
Message.GROUP_USE_UNINHERIT.send(sender);
return CommandResult.INVALID_ARGS;
}
try {
if (args.size() >= 2) {
final String server = args.get(1).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 2) {
group.unsetPermission(node, server);
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, group.getName(), server);
LogEntryBuilder.get().actor(sender).acted(group)
.action("unset " + node + " " + server)
.submit(plugin);
} else {
final String world = args.get(2).toLowerCase();
group.unsetPermission(node, server, world);
Message.UNSETPERMISSION_SERVER_WORLD_SUCCESS.send(sender, node, group.getName(), server, world);
LogEntryBuilder.get().actor(sender).acted(group)
.action("unset " + node + " " + server + " " + world)
.submit(plugin);
}
} else {
group.unsetPermission(node);
Message.UNSETPERMISSION_SUCCESS.send(sender, node, group.getName());
LogEntryBuilder.get().actor(sender).acted(group)
.action("unset " + node)
.submit(plugin);
}
save(group, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
Message.DOES_NOT_HAVEPERMISSION.send(sender, group.getName());
return CommandResult.STATE_ERROR;
}
}
}
@@ -1,54 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.Patterns;
import java.util.List;
public class GroupUnSetPermissionCommand extends GroupSubCommand {
public GroupUnSetPermissionCommand() {
super("unset", "Unsets a permission for a group",
"/%s group <group> unset <node> [server]", Permission.GROUP_UNSETPERMISSION);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String node = args.get(0);
if (node.contains("/")) {
sendUsage(sender, label);
return;
}
if (Patterns.GROUP_MATCH.matcher(node).matches()) {
Message.GROUP_USE_UNINHERIT.send(sender);
return;
}
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
group.unsetPermission(node, server);
Message.UNSETPERMISSION_SERVER_SUCCESS.send(sender, node, group.getName(), server);
} else {
group.unsetPermission(node);
Message.UNSETPERMISSION_SUCCESS.send(sender, node, group.getName());
}
saveGroup(group, sender, plugin);
} catch (ObjectLacksException e) {
Message.DOES_NOT_HAVEPERMISSION.send(sender, group.getName());
}
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1 && argLength != 2;
}
}
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.CommandResult;
import me.lucko.luckperms.commands.Predicate;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.SubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.data.LogEntryBuilder;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.utils.ArgumentChecker;
import java.util.List;
public class GroupUnsetInherit extends SubCommand<Group> {
public GroupUnsetInherit() {
super("unsetinherit", "Unsets another group for this group to inherit permissions from",
"/%s group <group> unsetinherit <group> [server] [world]", Permission.GROUP_UNSETINHERIT,
Predicate.notInRange(1, 3));
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String groupName = args.get(0).toLowerCase();
if (ArgumentChecker.checkNode(groupName)) {
sendUsage(sender, label);
return CommandResult.INVALID_ARGS;
}
try {
if (args.size() >= 2) {
final String server = args.get(1).toLowerCase();
if (ArgumentChecker.checkServer(server)) {
Message.SERVER_INVALID_ENTRY.send(sender);
return CommandResult.INVALID_ARGS;
}
if (args.size() == 2) {
group.unsetPermission("group." + groupName, server);
Message.GROUP_UNSETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server);
LogEntryBuilder.get().actor(sender).acted(group)
.action("unsetinherit " + groupName + " " + server)
.submit(plugin);
} else {
final String world = args.get(2).toLowerCase();
group.unsetPermission("group." + groupName, server, world);
Message.GROUP_UNSETINHERIT_SERVER_WORLD_SUCCESS.send(sender, group.getName(), groupName, server, world);
LogEntryBuilder.get().actor(sender).acted(group)
.action("unsetinherit " + groupName + " " + server + " " + world)
.submit(plugin);
}
} else {
group.unsetPermission("group." + groupName);
Message.GROUP_UNSETINHERIT_SUCCESS.send(sender, group.getName(), groupName);
LogEntryBuilder.get().actor(sender).acted(group)
.action("unsetinherit " + groupName)
.submit(plugin);
}
save(group, sender, plugin);
return CommandResult.SUCCESS;
} catch (ObjectLacksException e) {
Message.GROUP_DOES_NOT_INHERIT.send(sender, group.getName(), groupName);
return CommandResult.STATE_ERROR;
}
}
@Override
public List<String> onTabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
return getGroupTabComplete(args, plugin);
}
}
@@ -1,48 +0,0 @@
package me.lucko.luckperms.commands.group.subcommands;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.commands.Sender;
import me.lucko.luckperms.commands.group.GroupSubCommand;
import me.lucko.luckperms.constants.Message;
import me.lucko.luckperms.constants.Permission;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import me.lucko.luckperms.groups.Group;
import java.util.List;
public class GroupUnsetInheritCommand extends GroupSubCommand {
public GroupUnsetInheritCommand() {
super("unsetinherit", "Unsets another group for this group to inherit permissions from",
"/%s group <group> unsetinherit <group> [server]", Permission.GROUP_UNSETINHERIT);
}
@Override
protected void execute(LuckPermsPlugin plugin, Sender sender, Group group, List<String> args, String label) {
String groupName = args.get(0).toLowerCase();
try {
if (args.size() == 2) {
final String server = args.get(1).toLowerCase();
group.unsetPermission("group." + groupName, server);
Message.GROUP_UNSETINHERIT_SERVER_SUCCESS.send(sender, group.getName(), groupName, server);
} else {
group.unsetPermission("group." + groupName);
Message.GROUP_UNSETINHERIT_SUCCESS.send(sender, group.getName(), groupName);
}
saveGroup(group, sender, plugin);
} catch (ObjectLacksException e) {
Message.GROUP_DOES_NOT_INHERIT.send(sender, group.getName(), groupName);
}
}
@Override
public List<String> onTabComplete(Sender sender, List<String> args, LuckPermsPlugin plugin) {
return getGroupTabComplete(args, plugin);
}
@Override
public boolean isArgLengthInvalid(int argLength) {
return argLength != 1 && argLength != 2;
}
}
Loaded 100 of 216 files, more files were not shown because too many files have changed in this diff. Show more