Changes for & release of API 2.14

This commit is contained in:
Luck 2016-11-12 14:10:42 +00:00
parent e9131f729a
commit 563dd4683d
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
88 changed files with 872 additions and 850 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -29,226 +29,50 @@ import java.util.UUID;
/**
* Interface for the internal Datastore instance
* @deprecated as of version 2.14 in favour of {@link Storage}.
*/
@SuppressWarnings("unused")
@Deprecated
public interface Datastore {
String getName();
boolean isAcceptingLogins();
/**
* Gets the {@link Sync} interface.
*
* All operations through this interface are called immediately and in the same thread as they are called.
* Datastore operations are thread blocking, and Sync operations should not be called on the main server thread.
* @return the sync interface
*/
@Deprecated
Sync sync();
/**
* Gets the {@link Async} interface.
*
* All operations through this interface are called in a new, separate asynchronous thread.
* When the operation is complete, the provided callback method is called, in applicable, in the main server thread.
* @return the async interface
*/
@Deprecated
Async async();
/**
* Gets the {@link Future} interface.
*
* All operations through this interface are called in a new, separate asynchronous thread, similar to {@link Async}.
* The only difference is that instead of providing a callback, a {@link java.util.concurrent.Future} is returned.
* See the Oracle JavaDocs for usage of the Future class.
* @return the future interface
*/
@Deprecated
Future future();
/**
* All operations through this interface are called immediately and in the same thread as they are called.
* Datastore operations are thread blocking, and Sync operations should not be called on the main server thread.
*/
@Deprecated
interface Sync {
/**
* Saves an action to the datastore
* @param entry the log entry to be saved
* @return true if the operation completed successfully.
* @throws NullPointerException if entry is null
*/
boolean logAction(LogEntry entry);
/**
* Loads and returns the log from the datastore
* @return a log instance, could be null
*/
Log getLog();
/**
* Either loads or creates a user object, and loads it into the plugins internal storage
* @param uuid the uuid of the user
* @param username the users username. (if you want to specify <code>null</code> here, just input "null" as a string.)
* @return true if the operation completed successfully.
* @throws NullPointerException if uuid or username is null
* @throws IllegalArgumentException if either of the parameters are invalid
* @deprecated functionality of this method is taken on by {@link #loadUser(UUID, String)}
*/
@Deprecated
boolean loadOrCreateUser(UUID uuid, String username);
/**
* Loads a user from the datastore into the plugins internal storage.
* @param uuid the uuid of the user to load
* @return true if the user exists, and was loaded correctly.
* @throws NullPointerException if uuid is null
* @deprecated replaced by {@link #loadUser(UUID, String)}
*/
@Deprecated
boolean loadUser(UUID uuid);
/**
* Loads a user's data into the plugins internal storage.
* @param uuid the uuid of the user to load
* @param username the users username. (if you want to specify <code>null</code> here, just input "null" as a string.)
* @return if the operation was performed successfully
* @throws NullPointerException if uuid or username is null
* @since 2.6
*/
boolean loadUser(UUID uuid, String username);
/**
* Saves a user object into the datastore. You should call this after you make any changes to a user.
* @param user the user to save
* @return true if the operation completed successfully.
* @throws NullPointerException if user is null
* @throws IllegalStateException if the user instance was not obtained from LuckPerms.
*/
boolean saveUser(User user);
/**
* Removes users from the datastore who are "default". This is called every time the plugin loads.
* @return true if the operation completed successfully
* @since 2.6
*/
boolean cleanupUsers();
/**
* Gets a set all user's UUIDs who are "unique", and aren't just a member of the "default" group.
* @return a set of uuids, or null if the operation failed.
* @since 2.6
*/
Set<UUID> getUniqueUsers();
/**
* Creates and loads a group into the plugins internal storage
* @param name the name of the group
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
boolean createAndLoadGroup(String name);
/**
* Loads a group into the plugins internal storage.
* @param name the name of the group
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
boolean loadGroup(String name);
/**
* Loads all groups from the datastore into the plugins internal storage
* @return true if the operation completed successfully.
*/
boolean loadAllGroups();
/**
* Saves a group back to the datastore. You should call this after you make any changes to a group.
* @param group the group to save
* @return true if the operation completed successfully.
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
boolean saveGroup(Group group);
/**
* Permanently deletes a group from the datastore
* @param group the group to delete
* @return true if the operation completed successfully.
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
boolean deleteGroup(Group group);
/**
* Creates and loads a track into the plugins internal storage
* @param name the name of the track
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
boolean createAndLoadTrack(String name);
/**
* Loads a track into the plugins internal storage.
* @param name the name of the track
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
boolean loadTrack(String name);
/**
* Loads all tracks from the datastore into the plugins internal storage
* @return true if the operation completed successfully.
*/
boolean loadAllTracks();
/**
* Saves a track back to the datastore. You should call this after you make any changes to a track.
* @param track the track to save
* @return true if the operation completed successfully.
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
boolean saveTrack(Track track);
/**
* Permanently deletes a track from the datastore
* @param track the track to delete
* @return true if the operation completed successfully.
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
boolean deleteTrack(Track track);
/**
* Saves UUID caching data to the datastore
* @param username the users username
* @param uuid the users mojang unique id
* @return true if the operation completed successfully.
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
boolean saveUUIDData(String username, UUID uuid);
/**
* Gets a UUID from a username
* @param username the corresponding username
* @return a uuid object, could be null
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
UUID getUUID(String username);
}
/**
* All operations through this interface are called in a new, separate asynchronous thread.
* When the operation is complete, the provided callback method is called, in applicable, in the main server thread.
*
* See {@link Sync} for method documentation.
*/
@Deprecated
interface Async {
void logAction(LogEntry entry, Callback<Boolean> callback);
void getLog(Callback<Log> callback);
@ -274,13 +98,7 @@ public interface Datastore {
void getUUID(String username, Callback<UUID> callback);
}
/**
* All operations through this interface are called in a new, separate asynchronous thread, similar to {@link Async}.
* The only difference is that instead of providing a callback, a {@link java.util.concurrent.Future} is returned.
* See the Oracle JavaDocs for usage of the Future class.
*
* See {@link Sync} for method documentation.
*/
@Deprecated
interface Future {
java.util.concurrent.Future<Boolean> logAction(LogEntry entry);
java.util.concurrent.Future<Log> getLog();

View File

@ -109,7 +109,9 @@ public interface LPConfiguration {
/**
* @return true if permission checks are being recorded / debugged
* @since 2.9
* @deprecated as this value is now always false. Functionality was replaced by the verbose command.
*/
@Deprecated
boolean getDebugPermissionChecks();
/**

View File

@ -79,11 +79,27 @@ public interface LuckPermsApi {
LPConfiguration getConfiguration();
/**
* Gets a wrapped {@link Datastore} instance, with somewhat limited access
* @return a datastore instance
* Gets a wrapped {@link Storage} instance.
* @return a storage instance
* @since 2.14
*/
Storage getStorage();
/**
* Gets a wrapped Datastore instance.
* @return a datastore instance
* @deprecated in favour of {@link #getStorage()}
*/
@SuppressWarnings("deprecation")
@Deprecated
Datastore getDatastore();
/**
* Gets the messaging service in use on the platform, if present.
* @return an optional that may contain a messaging service instance.
*/
Optional<MessagingService> getMessagingService();
/**
* Gets the {@link Logger} wrapping used by the platform
* @return the logger instance
@ -92,7 +108,7 @@ public interface LuckPermsApi {
/**
* Gets a wrapped {@link UuidCache} instance, providing read access to the LuckPerms internal uuid caching system
* @return a uuidcache instance
* @return a uuid cache instance
*/
UuidCache getUuidCache();

View File

@ -20,16 +20,18 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.utils;
package me.lucko.luckperms.api;
import com.google.common.util.concurrent.Futures;
/**
* Exposes any networking provider being used on the platform. e.g. Redis
* @since 2.14
*/
public interface MessagingService {
import java.util.concurrent.Future;
public interface LPFuture<T> extends Future<T> {
default T getUnchecked() {
return Futures.getUnchecked(this);
}
/**
* Uses the messaging service to inform other servers about changes.
* This will push the update asynchronously, and this method will return almost immediately.
*/
void pushUpdate();
}

View File

@ -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;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
* Interface for the internal Storage instance
*
* All methods return {@link CompletableFuture}s, which will be populated with the result once the data has been loaded
* asynchronously. Care should be taken when using the methods to ensure that the main server thread is not blocked.
*
* Methods such as {@link CompletableFuture#get()} and equivalent should <strong>not</strong> be called on the main server thread.
* If you need to use the result of these operations on the main server thread, please register a callback using
* {@link CompletableFuture#thenAcceptAsync(Consumer, Executor)} and {@link #getSyncExecutor()}.
*
* @since 2.14
*/
public interface Storage {
/**
* Get the name of the storage implementation.
* @return the name of the implementation
*/
String getName();
/**
* Return whether the storage instance is allowing logins on the platform.
* @return true if logins are enabled
*/
boolean isAcceptingLogins();
/**
* Returns an executor which will run all passed runnables on the main server thread.
* @return an executor instance
*/
Executor getSyncExecutor();
/**
* Returns an executor which will run all passed runnables asynchronously using the platforms scheduler & thread pools.
* @return an executor instance
*/
Executor getAsyncExecutor();
/**
* Saves an action to storage
* @param entry the log entry to be saved
* @return true if the operation completed successfully.
* @throws NullPointerException if entry is null
*/
CompletableFuture<Boolean> logAction(LogEntry entry);
/**
* Loads and returns the entire log from storage
* @return a log instance, could be null if loading failed
*/
CompletableFuture<Log> getLog();
/**
* Loads a user's data from the main storage into the plugins local storage.
* @param uuid the uuid of the user to load
* @param username the users username. (if you want to specify <code>null</code> here, just input "null" as a string.)
* @return if the operation completed successfully
* @throws NullPointerException if uuid or username is null
*/
CompletableFuture<Boolean> loadUser(UUID uuid, String username);
/**
* Saves a user object back to storage. You should call this after you make any changes to a user.
* @param user the user to save
* @return true if the operation completed successfully.
* @throws NullPointerException if user is null
* @throws IllegalStateException if the user instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> saveUser(User user);
/**
* Removes users from the main storage who are "default". This is called every time the plugin loads.
* @return true if the operation completed successfully
*/
CompletableFuture<Boolean> cleanupUsers();
/**
* Gets a set all "unique" user UUIDs.
* "Unique" meaning the user isn't just a member of the "default" group.
* @return a set of uuids, or null if the operation failed.
*/
CompletableFuture<Set<UUID>> getUniqueUsers();
/**
* Creates and loads a group into the plugins local storage
* @param name the name of the group
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> createAndLoadGroup(String name);
/**
* Loads a group into the plugins local storage.
* @param name the name of the group
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> loadGroup(String name);
/**
* Loads all groups from the storage into memory
* @return true if the operation completed successfully.
*/
CompletableFuture<Boolean> loadAllGroups();
/**
* Saves a group back to storage. You should call this after you make any changes to a group.
* @param group the group to save
* @return true if the operation completed successfully.
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> saveGroup(Group group);
/**
* Permanently deletes a group from storage.
* @param group the group to delete
* @return true if the operation completed successfully.
* @throws NullPointerException if group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> deleteGroup(Group group);
/**
* Creates and loads a track into the plugins local storage
* @param name the name of the track
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> createAndLoadTrack(String name);
/**
* Loads a track into the plugins local storage.
* @param name the name of the track
* @return true if the operation completed successfully
* @throws NullPointerException if name is null
* @throws IllegalArgumentException if the name is invalid
*/
CompletableFuture<Boolean> loadTrack(String name);
/**
* Loads all tracks from the storage into memory
* @return true if the operation completed successfully.
*/
CompletableFuture<Boolean> loadAllTracks();
/**
* Saves a track back to storage. You should call this after you make any changes to a track.
* @param track the track to save
* @return true if the operation completed successfully.
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> saveTrack(Track track);
/**
* Permanently deletes a track from storage
* @param track the track to delete
* @return true if the operation completed successfully.
* @throws NullPointerException if track is null
* @throws IllegalStateException if the track instance was not obtained from LuckPerms.
*/
CompletableFuture<Boolean> deleteTrack(Track track);
/**
* Saves UUID caching data to the global cache
* @param username the users username
* @param uuid the users mojang unique id
* @return true if the operation completed successfully.
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid);
/**
* Gets a UUID from a username
* @param username the corresponding username
* @return a uuid object, could be null
* @throws NullPointerException if either parameters are null
* @throws IllegalArgumentException if the username is invalid
*/
CompletableFuture<UUID> getUUID(String username);
}

View File

@ -32,8 +32,8 @@ import java.util.UUID;
* 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> If you want to get a user object from the Storage using the api on a server in offline mode, you will need to use this cache,
* OR use Storage#getUUID, for users that are not online.
*
* <p> WARNING: THIS IS ONLY EFFECTIVE FOR ONLINE PLAYERS. USE THE DATASTORE METHODS FOR OFFLINE PLAYERS.
*/

View File

@ -28,7 +28,9 @@ import java.util.function.Consumer;
* A callback used to wait for the completion of asynchronous operations.
* All callbacks are ran on the main server thread.
* @param <T> the return type
* @deprecated in favour of {@link Consumer}
*/
@Deprecated
public interface Callback<T> {
/**
@ -55,4 +57,17 @@ public interface Callback<T> {
return consumer::accept;
}
/**
* Helper method for converting old {@link Callback}s to use the new {@link me.lucko.luckperms.api.Storage} interface.
* @param callback the callback to convert
* @param <T> the return type
* @return a consumer instance
* @since 2.14
* @deprecated in favour of just using {@link Consumer}s.
*/
@Deprecated
static <T> Consumer<T> convertToConsumer(Callback<T> callback) {
return callback::onComplete;
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -48,7 +48,7 @@ class BukkitListener extends AbstractListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent e) {
if (!plugin.isStarted() || !plugin.getDatastore().isAcceptingLogins()) {
if (!plugin.isStarted() || !plugin.getStorage().isAcceptingLogins()) {
// The datastore is disabled, prevent players from joining the server
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.toString());
@ -61,7 +61,7 @@ class BukkitListener extends AbstractListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerPreLoginMonitor(AsyncPlayerPreLoginEvent e) {
if (plugin.isStarted() && plugin.getDatastore().isAcceptingLogins() && e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
if (plugin.isStarted() && plugin.getStorage().isAcceptingLogins() && e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
// Login event was cancelled by another plugin
onLeave(e.getUniqueId());

View File

@ -49,7 +49,7 @@ import me.lucko.luckperms.common.groups.GroupManager;
import me.lucko.luckperms.common.messaging.RedisMessaging;
import me.lucko.luckperms.common.runnables.ExpireTemporaryTask;
import me.lucko.luckperms.common.runnables.UpdateTask;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.tracks.TrackManager;
import me.lucko.luckperms.common.users.UserManager;
@ -68,12 +68,16 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@Getter
public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private ExecutorService executorService;
private Executor syncExecutor;
private Executor asyncExecutor;
private VaultHook vaultHook = null;
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
@ -81,7 +85,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
private Storage storage;
private RedisMessaging redisMessaging = null;
private UuidCache uuidCache;
private ApiProvider apiProvider;
@ -99,13 +103,12 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private DebugHandler debugHandler;
private BukkitSenderFactory senderFactory;
private ExecutorService executorService;
private boolean schedulerAvailable = false;
@Override
public void onEnable() {
// Used whilst the server is still starting
executorService = Executors.newCachedThreadPool();
asyncExecutor = executorService;
syncExecutor = r -> getServer().getScheduler().runTask(this, r);
log = LogFactory.wrap(getLogger());
debugHandler = new DebugHandler();
@ -129,7 +132,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
pm.registerEvents(new BukkitListener(this), this);
// initialise datastore
datastore = StorageFactory.getDatastore(this, "h2");
storage = StorageFactory.getInstance(this, "h2");
// initialise redis
if (getConfiguration().isRedisEnabled()) {
@ -236,10 +239,9 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
getServer().getOperators().forEach(o -> o.setOp(false));
}
// shutdown the temporary executor when the Bukkit one starts
// replace the temporary executor when the Bukkit one starts
getServer().getScheduler().runTaskAsynchronously(this, () -> {
schedulerAvailable = true;
executorService.shutdown();
asyncExecutor = r -> getServer().getScheduler().runTaskAsynchronously(this, r);
});
started = true;
@ -250,7 +252,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
public void onDisable() {
started = false;
getLog().info("Closing datastore...");
datastore.shutdown();
storage.shutdown();
if (redisMessaging != null) {
getLog().info("Closing redis...");
@ -268,16 +270,12 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
@Override
public void doAsync(Runnable r) {
if (!schedulerAvailable) {
executorService.submit(r);
} else {
getServer().getScheduler().runTaskAsynchronously(this, r);
}
asyncExecutor.execute(r);
}
@Override
public void doSync(Runnable r) {
getServer().getScheduler().runTask(this, r);
syncExecutor.execute(r);
}
@Override

View File

@ -122,7 +122,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
}
// Make a LuckPerms group for the one being migrated.
plugin.getDatastore().createAndLoadGroup(groupName).getUnchecked();
plugin.getStorage().createAndLoadGroup(groupName).join();
me.lucko.luckperms.common.groups.Group lpGroup = plugin.getGroupManager().get(groupName);
try {
LogEntry.build()
@ -134,7 +134,7 @@ public class MigrationBPermissions extends SubCommand<Object> {
}
migrateHolder(plugin, world, group, lpGroup);
plugin.getDatastore().saveGroup(lpGroup);
plugin.getStorage().saveGroup(lpGroup);
}
log.info("bPermissions Migration: Migrated " + groupCount + " groups in world " + world.getName() + ".");
@ -158,12 +158,12 @@ public class MigrationBPermissions extends SubCommand<Object> {
}
// Make a LuckPerms user for the one being migrated.
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
plugin.getStorage().loadUser(uuid, "null").join();
me.lucko.luckperms.common.users.User lpUser = plugin.getUserManager().get(uuid);
migrateHolder(plugin, world, user, lpUser);
plugin.getDatastore().saveUser(lpUser);
plugin.getStorage().saveUser(lpUser);
plugin.getUserManager().cleanup(lpUser);
}

View File

@ -72,7 +72,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
GlobalGroups gg = GroupManager.getGlobalGroups();
for (Group g : gg.getGroupList()) {
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
try {
LogEntry.build()
@ -120,7 +120,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
}
}
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
}
Map<UUID, Map<Map.Entry<String, String>, Boolean>> users = new HashMap<>();
@ -195,7 +195,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
log.info("GroupManager Migration: Found a total of " + users.size() + " users and " + groups.size() + " groups.");
for (Map.Entry<String, Map<Map.Entry<String, String>, Boolean>> e : groups.entrySet()) {
plugin.getDatastore().createAndLoadGroup(e.getKey()).getUnchecked();
plugin.getStorage().createAndLoadGroup(e.getKey()).join();
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(e.getKey());
try {
LogEntry.build()
@ -234,11 +234,11 @@ public class MigrationGroupManager extends SubCommand<Object> {
}
}
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
}
for (Map.Entry<UUID, Map<Map.Entry<String, String>, Boolean>> e : users.entrySet()) {
plugin.getDatastore().loadUser(e.getKey(), "null").getUnchecked();
plugin.getStorage().loadUser(e.getKey(), "null").join();
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(e.getKey());
for (Map.Entry<Map.Entry<String, String>, Boolean> n : e.getValue().entrySet()) {
@ -279,7 +279,7 @@ public class MigrationGroupManager extends SubCommand<Object> {
} catch (ObjectLacksException ignored) {}
}
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}

View File

@ -100,7 +100,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
maxGroupWeight = Math.max(maxGroupWeight, groupWeight);
final String name = group.getName().toLowerCase();
plugin.getDatastore().createAndLoadGroup(name).getUnchecked();
plugin.getStorage().createAndLoadGroup(name).join();
Group lpGroup = plugin.getGroupManager().get(name);
try {
LogEntry.build()
@ -224,7 +224,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
}
}
plugin.getDatastore().saveGroup(lpGroup);
plugin.getStorage().saveGroup(lpGroup);
}
@ -252,7 +252,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
}
userCount++;
plugin.getDatastore().loadUser(u, "null").getUnchecked();
plugin.getStorage().loadUser(u, "null").join();
User lpUser = plugin.getUserManager().get(u);
try {
@ -385,7 +385,7 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
}
plugin.getUserManager().cleanup(lpUser);
plugin.getDatastore().saveUser(lpUser);
plugin.getStorage().saveUser(lpUser);
}
log.info("PermissionsEx Migration: Migrated " + userCount + " users.");

View File

@ -251,7 +251,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
log.info("PowerfulPerms Migration: Starting group migration.");
Map<Integer, Group> groups = pm.getGroups(); // All versions
for (Group g : groups.values()) {
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
final me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
try {
LogEntry.build()
@ -280,7 +280,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
}
}
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
}
log.info("PowerfulPerms Migration: Group migration complete.");
@ -293,7 +293,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
progress.put(uuid, new CountDownLatch(2));
// Create a LuckPerms user for the UUID
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
plugin.getStorage().loadUser(uuid, "null").join();
User user = plugin.getUserManager().get(uuid);
// Get a list of Permissions held by the user from the PP API.
@ -304,7 +304,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
synchronized (progress) {
progress.get(uuid).countDown();
if (progress.get(uuid).getCount() == 0) {
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}
}
@ -427,7 +427,7 @@ public class MigrationPowerfulPerms extends SubCommand<Object> {
synchronized (progress) {
progress.get(uuid).countDown();
if (progress.get(uuid).getCount() == 0) {
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}
}

View File

@ -73,7 +73,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
// Migrate all groups
log.info("zPermissions Migration: Starting group migration.");
for (String g : service.getAllGroups()) {
plugin.getDatastore().createAndLoadGroup(g.toLowerCase()).getUnchecked();
plugin.getStorage().createAndLoadGroup(g.toLowerCase()).join();
Group group = plugin.getGroupManager().get(g.toLowerCase());
try {
LogEntry.build()
@ -116,13 +116,13 @@ public class MigrationZPermissions extends SubCommand<Object> {
}
}
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
}
// Migrate all tracks
log.info("zPermissions Migration: Starting track migration.");
for (String t : service.getAllTracks()) {
plugin.getDatastore().createAndLoadTrack(t.toLowerCase()).getUnchecked();
plugin.getStorage().createAndLoadTrack(t.toLowerCase()).join();
Track track = plugin.getTrackManager().get(t.toLowerCase());
try {
LogEntry.build()
@ -145,13 +145,13 @@ public class MigrationZPermissions extends SubCommand<Object> {
}
}
plugin.getDatastore().saveTrack(track);
plugin.getStorage().saveTrack(track);
}
// Migrate all users.
log.info("zPermissions Migration: Starting user migration.");
for (UUID u : service.getAllPlayersUUID()) {
plugin.getDatastore().loadUser(u, "null").getUnchecked();
plugin.getStorage().loadUser(u, "null").join();
User user = plugin.getUserManager().get(u);
for (Map.Entry<String, Boolean> e : service.getPlayerPermissions(null, null, u).entrySet()) {
@ -244,7 +244,7 @@ public class MigrationZPermissions extends SubCommand<Object> {
}
plugin.getUserManager().cleanup(user);
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
}
log.info("zPermissions Migration: Success! Completed without any errors.");

View File

@ -82,7 +82,7 @@ public class VaultPermissionHook extends Permission {
@Override
public boolean isEnabled() {
return plugin.getDatastore().isAcceptingLogins();
return plugin.getStorage().isAcceptingLogins();
}
@Override
@ -132,13 +132,12 @@ public class VaultPermissionHook extends Permission {
*/
void save(PermissionHolder holder) {
if (holder instanceof User) {
plugin.getDatastore().saveUser(((User) holder), b -> {
((User) holder).getRefreshBuffer().request();
});
plugin.getStorage().saveUser(((User) holder))
.thenRunAsync(() -> ((User) holder).getRefreshBuffer().request(), plugin.getAsyncExecutor());
}
if (holder instanceof Group) {
plugin.getDatastore().saveGroup(((Group) holder), b -> plugin.getUpdateTaskBuffer().request());
plugin.getStorage().saveGroup(((Group) holder))
.thenRunAsync(() -> plugin.getUpdateTaskBuffer().request(), plugin.getAsyncExecutor());
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -96,28 +96,28 @@ public class BungeeListener extends AbstractListener implements Listener {
final PendingConnection c = e.getConnection();
if (!cache.isOnlineMode()) {
UUID uuid = plugin.getDatastore().getUUID(c.getName()).getUnchecked();
UUID uuid = plugin.getStorage().getUUID(c.getName()).join();
if (uuid != null) {
cache.addToCache(c.getUniqueId(), uuid);
} else {
// No previous data for this player
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(c.getUniqueId(), c.getName()));
cache.addToCache(c.getUniqueId(), c.getUniqueId());
plugin.getDatastore().force().saveUUIDData(c.getName(), c.getUniqueId()).getUnchecked();
plugin.getStorage().force().saveUUIDData(c.getName(), c.getUniqueId()).join();
}
} else {
UUID uuid = plugin.getDatastore().getUUID(c.getName()).getUnchecked();
UUID uuid = plugin.getStorage().getUUID(c.getName()).join();
if (uuid == null) {
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(c.getUniqueId(), c.getName()));
}
// Online mode, no cache needed. This is just for name -> uuid lookup.
plugin.getDatastore().force().saveUUIDData(c.getName(), c.getUniqueId()).getUnchecked();
plugin.getStorage().force().saveUUIDData(c.getName(), c.getUniqueId()).join();
}
// 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().force().loadUser(cache.getUUID(c.getUniqueId()), c.getName()).getUnchecked();
plugin.getStorage().force().loadUser(cache.getUUID(c.getUniqueId()), c.getName()).join();
User user = plugin.getUserManager().get(cache.getUUID(c.getUniqueId()));
if (user == null) {
plugin.getLog().warn("Failed to load user: " + c.getName());

View File

@ -44,7 +44,7 @@ import me.lucko.luckperms.common.groups.GroupManager;
import me.lucko.luckperms.common.messaging.RedisMessaging;
import me.lucko.luckperms.common.runnables.ExpireTemporaryTask;
import me.lucko.luckperms.common.runnables.UpdateTask;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.tracks.TrackManager;
import me.lucko.luckperms.common.users.UserManager;
@ -62,17 +62,20 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Getter
public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
private Executor executor;
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
private LPConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
private Storage storage;
private RedisMessaging redisMessaging = null;
private UuidCache uuidCache;
private ApiProvider apiProvider;
@ -88,6 +91,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
@Override
public void onEnable() {
executor = r -> getProxy().getScheduler().runAsync(this, r);
log = LogFactory.wrap(getLogger());
debugHandler = new DebugHandler();
senderFactory = new BungeeSenderFactory(this);
@ -99,7 +103,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
getProxy().getPluginManager().registerListener(this, new BungeeListener(this));
// initialise datastore
datastore = StorageFactory.getDatastore(this, "h2");
storage = StorageFactory.getInstance(this, "h2");
// initialise redis
if (getConfiguration().isRedisEnabled()) {
@ -183,7 +187,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
@Override
public void onDisable() {
getLog().info("Closing datastore...");
datastore.shutdown();
storage.shutdown();
if (redisMessaging != null) {
getLog().info("Closing redis...");
@ -300,7 +304,17 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
@Override
public void doSync(Runnable r) {
r.run();
doAsync(r);
}
@Override
public Executor getSyncExecutor() {
return executor;
}
@Override
public Executor getAsyncExecutor() {
return executor;
}
@Override

View File

@ -64,7 +64,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
groupCount++;
// Make a LuckPerms group for the one being migrated
plugin.getDatastore().createAndLoadGroup(g.getName().toLowerCase()).getUnchecked();
plugin.getStorage().createAndLoadGroup(g.getName().toLowerCase()).join();
me.lucko.luckperms.common.groups.Group group = plugin.getGroupManager().get(g.getName().toLowerCase());
try {
LogEntry.build()
@ -174,7 +174,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
}
}
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
}
log.info("BungeePerms Migration: Migrated " + groupCount + " groups");
@ -188,7 +188,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
userCount++;
// Make a LuckPerms user for the one being migrated.
plugin.getDatastore().loadUser(u.getUUID(), "null").getUnchecked();
plugin.getStorage().loadUser(u.getUUID(), "null").join();
me.lucko.luckperms.common.users.User user = plugin.getUserManager().get(u.getUUID());
// Migrate global perms
@ -289,7 +289,7 @@ public class MigrationBungeePerms extends SubCommand<Object> {
}
}
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -36,7 +36,7 @@ import me.lucko.luckperms.common.core.UuidCache;
import me.lucko.luckperms.common.data.Importer;
import me.lucko.luckperms.common.groups.GroupManager;
import me.lucko.luckperms.common.messaging.RedisMessaging;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.tracks.TrackManager;
import me.lucko.luckperms.common.users.UserManager;
import me.lucko.luckperms.common.utils.BufferedRequest;
@ -47,6 +47,7 @@ import java.io.File;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
/**
* Main internal interface for LuckPerms plugins, providing the base for abstraction throughout the project.
@ -80,10 +81,10 @@ public interface LuckPermsPlugin {
LPConfiguration getConfiguration();
/**
* Gets the primary datastore instance. This is likely to be wrapped with extra layers for caching, etc.
* @return the datastore
* Gets the primary data storage instance. This is likely to be wrapped with extra layers for caching, etc.
* @return the storage handler instance
*/
Datastore getDatastore();
Storage getStorage();
/**
* Gets the redis messaging instance if present. Could return null if redis is not enabled.
@ -158,6 +159,9 @@ public interface LuckPermsPlugin {
*/
void doSync(Runnable r);
Executor getSyncExecutor();
Executor getAsyncExecutor();
/**
* Execute a runnable asynchronously on a loop
* @param r the task to run

View File

@ -71,7 +71,7 @@ public class ApiProvider implements LuckPermsApi {
@Override
public double getApiVersion() {
return 2.13;
return 2.14;
}
@Override
@ -99,9 +99,20 @@ public class ApiProvider implements LuckPermsApi {
return new LPConfigurationLink(plugin.getConfiguration());
}
@Override
public Storage getStorage() {
return new StorageLink(plugin, plugin.getStorage());
}
@SuppressWarnings("deprecation")
@Override
public Datastore getDatastore() {
return new DatastoreLink(plugin, plugin.getDatastore());
return new DatastoreLink(plugin, plugin.getStorage());
}
@Override
public Optional<MessagingService> getMessagingService() {
return Optional.ofNullable(plugin.getRedisMessaging());
}
@Override

View File

@ -27,26 +27,29 @@ import lombok.NonNull;
import me.lucko.luckperms.api.*;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.AbstractFuture;
import me.lucko.luckperms.common.storage.Storage;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import static me.lucko.luckperms.common.api.internal.Utils.*;
/**
* Provides a link between {@link Datastore} and {@link me.lucko.luckperms.common.storage.Datastore}
* Provides a link between {@link Datastore} and {@link Storage}
*
* Note that this class only provides for the old deprecated interface, see {@link StorageLink} for the new one.
*/
@SuppressWarnings({"unused", "WeakerAccess"})
@SuppressWarnings({"unused", "WeakerAccess", "deprecation"})
public class DatastoreLink implements Datastore {
private final LuckPermsPlugin plugin;
private final me.lucko.luckperms.common.storage.Datastore master;
private final Storage master;
private final Async async;
private final Sync sync;
private final Future future;
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull me.lucko.luckperms.common.storage.Datastore master) {
public DatastoreLink(@NonNull LuckPermsPlugin plugin, @NonNull Storage master) {
this.plugin = plugin;
this.master = master;
this.async = new Async(master);
@ -54,12 +57,10 @@ public class DatastoreLink implements Datastore {
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();
private <T> void registerCallback(CompletableFuture<T> fut, Callback<T> c) {
if (c != null) {
fut.thenAcceptAsync(Callback.convertToConsumer(c), plugin.getSyncExecutor());
}
return c;
}
@Override
@ -89,68 +90,68 @@ public class DatastoreLink implements Datastore {
@AllArgsConstructor
public class Async implements Datastore.Async {
private final me.lucko.luckperms.common.storage.Datastore master;
private final me.lucko.luckperms.common.storage.Storage master;
@Override
public void logAction(@NonNull LogEntry entry, Callback<Boolean> callback) {
master.force().logAction(entry, checkCallback(callback));
registerCallback(master.force().logAction(entry), callback);
}
@Override
public void getLog(Callback<Log> callback) {
master.force().getLog(log -> callback.onComplete(new LogLink(log)));
public void getLog(@NonNull Callback<Log> callback) {
master.force().getLog().thenAcceptAsync(log -> callback.onComplete(new LogLink(log)), plugin.getSyncExecutor());
}
@Override
public void loadOrCreateUser(@NonNull UUID uuid, @NonNull String username, Callback<Boolean> callback) {
master.force().loadUser(uuid, checkUsername(username), checkCallback(callback));
registerCallback(master.force().loadUser(uuid, checkUsername(username)) , callback);
}
@Override
public void loadUser(@NonNull UUID uuid, Callback<Boolean> callback) {
master.force().loadUser(uuid, "null", checkCallback(callback));
registerCallback(master.force().loadUser(uuid, "null"), callback);
}
@Override
public void loadUser(@NonNull UUID uuid, @NonNull String username, Callback<Boolean> callback) {
master.force().loadUser(uuid, checkUsername(username), checkCallback(callback));
registerCallback(master.force().loadUser(uuid, checkUsername(username)), callback);
}
@Override
public void saveUser(@NonNull User user, Callback<Boolean> callback) {
checkUser(user);
master.force().saveUser(((UserLink) user).getMaster(), checkCallback(callback));
registerCallback(master.force().saveUser(((UserLink) user).getMaster()), callback);
}
@Override
public void cleanupUsers(Callback<Boolean> callback) {
master.force().cleanupUsers(checkCallback(callback));
registerCallback(master.force().cleanupUsers(), callback);
}
@Override
public void getUniqueUsers(Callback<Set<UUID>> callback) {
master.force().getUniqueUsers(checkCallback(callback));
registerCallback(master.force().getUniqueUsers(), callback);
}
@Override
public void createAndLoadGroup(@NonNull String name, Callback<Boolean> callback) {
master.force().createAndLoadGroup(checkName(name), checkCallback(callback));
registerCallback(master.force().createAndLoadGroup(checkName(name)), callback);
}
@Override
public void loadGroup(@NonNull String name, Callback<Boolean> callback) {
master.force().loadGroup(checkName(name), checkCallback(callback));
registerCallback(master.force().loadGroup(checkName(name)), callback);
}
@Override
public void loadAllGroups(Callback<Boolean> callback) {
master.force().loadAllGroups(checkCallback(callback));
registerCallback(master.force().loadAllGroups(), callback);
}
@Override
public void saveGroup(@NonNull Group group, Callback<Boolean> callback) {
checkGroup(group);
master.force().saveGroup(((GroupLink) group).getMaster(), checkCallback(callback));
registerCallback(master.force().saveGroup(((GroupLink) group).getMaster()), callback);
}
@Override
@ -159,59 +160,59 @@ public class DatastoreLink implements Datastore {
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
master.force().deleteGroup(((GroupLink) group).getMaster(), checkCallback(callback));
registerCallback(master.force().deleteGroup(((GroupLink) group).getMaster()), callback);
}
@Override
public void createAndLoadTrack(@NonNull String name, Callback<Boolean> callback) {
master.force().createAndLoadTrack(checkName(name), checkCallback(callback));
registerCallback(master.force().createAndLoadTrack(checkName(name)), callback);
}
@Override
public void loadTrack(@NonNull String name, Callback<Boolean> callback) {
master.force().loadTrack(checkName(name), checkCallback(callback));
registerCallback(master.force().loadTrack(checkName(name)), callback);
}
@Override
public void loadAllTracks(Callback<Boolean> callback) {
master.force().loadAllTracks(checkCallback(callback));
registerCallback(master.force().loadAllTracks(), callback);
}
@Override
public void saveTrack(@NonNull Track track, Callback<Boolean> callback) {
checkTrack(track);
master.force().saveTrack(((TrackLink) track).getMaster(), checkCallback(callback));
registerCallback(master.force().saveTrack(((TrackLink) track).getMaster()), callback);
}
@Override
public void deleteTrack(@NonNull Track track, Callback<Boolean> callback) {
checkTrack(track);
master.force().deleteTrack(((TrackLink) track).getMaster(), checkCallback(callback));
registerCallback(master.force().deleteTrack(((TrackLink) track).getMaster()), callback);
}
@Override
public void saveUUIDData(@NonNull String username, @NonNull UUID uuid, Callback<Boolean> callback) {
master.force().saveUUIDData(checkUsername(username), uuid, checkCallback(callback));
registerCallback(master.force().saveUUIDData(checkUsername(username), uuid), callback);
}
@Override
public void getUUID(@NonNull String username, Callback<UUID> callback) {
master.force().getUUID(checkUsername(username), checkCallback(callback));
registerCallback(master.force().getUUID(checkUsername(username)), callback);
}
}
@AllArgsConstructor
public class Sync implements Datastore.Sync {
private final me.lucko.luckperms.common.storage.Datastore master;
private final Storage master;
@Override
public boolean logAction(@NonNull LogEntry entry) {
return master.force().logAction(entry).getUnchecked();
return master.force().logAction(entry).join();
}
@Override
public Log getLog() {
me.lucko.luckperms.common.data.Log log = master.force().getLog().getUnchecked();
me.lucko.luckperms.common.data.Log log = master.force().getLog().join();
if (log == null) {
return null;
}
@ -220,54 +221,54 @@ public class DatastoreLink implements Datastore {
@Override
public boolean loadOrCreateUser(@NonNull UUID uuid, @NonNull String username) {
return master.force().loadUser(uuid, checkUsername(username)).getUnchecked();
return master.force().loadUser(uuid, checkUsername(username)).join();
}
@Override
public boolean loadUser(@NonNull UUID uuid) {
return master.force().loadUser(uuid, "null").getUnchecked();
return master.force().loadUser(uuid, "null").join();
}
@Override
public boolean loadUser(@NonNull UUID uuid, @NonNull String username) {
return master.force().loadUser(uuid, checkUsername(username)).getUnchecked();
return master.force().loadUser(uuid, checkUsername(username)).join();
}
@Override
public boolean saveUser(@NonNull User user) {
checkUser(user);
return master.force().saveUser(((UserLink) user).getMaster()).getUnchecked();
return master.force().saveUser(((UserLink) user).getMaster()).join();
}
@Override
public boolean cleanupUsers() {
return master.force().cleanupUsers().getUnchecked();
return master.force().cleanupUsers().join();
}
@Override
public Set<UUID> getUniqueUsers() {
return master.force().getUniqueUsers().getUnchecked();
return master.force().getUniqueUsers().join();
}
@Override
public boolean createAndLoadGroup(@NonNull String name) {
return master.force().createAndLoadGroup(checkName(name)).getUnchecked();
return master.force().createAndLoadGroup(checkName(name)).join();
}
@Override
public boolean loadGroup(@NonNull String name) {
return master.force().loadGroup(checkName(name)).getUnchecked();
return master.force().loadGroup(checkName(name)).join();
}
@Override
public boolean loadAllGroups() {
return master.force().loadAllGroups().getUnchecked();
return master.force().loadAllGroups().join();
}
@Override
public boolean saveGroup(@NonNull Group group) {
checkGroup(group);
return master.force().saveGroup(((GroupLink) group).getMaster()).getUnchecked();
return master.force().saveGroup(((GroupLink) group).getMaster()).join();
}
@Override
@ -276,50 +277,50 @@ public class DatastoreLink implements Datastore {
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
return master.force().deleteGroup(((GroupLink) group).getMaster()).getUnchecked();
return master.force().deleteGroup(((GroupLink) group).getMaster()).join();
}
@Override
public boolean createAndLoadTrack(@NonNull String name) {
return master.force().createAndLoadTrack(checkName(name)).getUnchecked();
return master.force().createAndLoadTrack(checkName(name)).join();
}
@Override
public boolean loadTrack(@NonNull String name) {
return master.force().loadTrack(checkName(name)).getUnchecked();
return master.force().loadTrack(checkName(name)).join();
}
@Override
public boolean loadAllTracks() {
return master.force().loadAllTracks().getUnchecked();
return master.force().loadAllTracks().join();
}
@Override
public boolean saveTrack(@NonNull Track track) {
checkTrack(track);
return master.force().saveTrack(((TrackLink) track).getMaster()).getUnchecked();
return master.force().saveTrack(((TrackLink) track).getMaster()).join();
}
@Override
public boolean deleteTrack(@NonNull Track track) {
checkTrack(track);
return master.force().deleteTrack(((TrackLink) track).getMaster()).getUnchecked();
return master.force().deleteTrack(((TrackLink) track).getMaster()).join();
}
@Override
public boolean saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
return master.force().saveUUIDData(checkUsername(username), uuid).getUnchecked();
return master.force().saveUUIDData(checkUsername(username), uuid).join();
}
@Override
public UUID getUUID(@NonNull String username) {
return master.force().getUUID(checkUsername(username)).getUnchecked();
return master.force().getUUID(checkUsername(username)).join();
}
}
@AllArgsConstructor
public class Future implements Datastore.Future {
private final me.lucko.luckperms.common.storage.Datastore master;
private final Storage master;
@Override
public java.util.concurrent.Future<Boolean> logAction(@NonNull LogEntry entry) {
@ -328,9 +329,7 @@ public class DatastoreLink implements Datastore {
@Override
public java.util.concurrent.Future<Log> getLog() {
AbstractFuture<Log> fut = new AbstractFuture<>();
master.force().getLog(log -> fut.complete(new LogLink(log)));
return fut;
return master.force().getLog().thenApply(log -> log == null ? null : new LogLink(log));
}
@Override

View File

@ -103,7 +103,7 @@ public class LPConfigurationLink implements LPConfiguration {
@Override
public boolean getDebugPermissionChecks() {
return false; // Constant TODO depreciate this
return false;
}
@Override

View File

@ -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.common.api.internal;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.*;
import me.lucko.luckperms.common.LuckPermsPlugin;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import static me.lucko.luckperms.common.api.internal.Utils.*;
/**
* Provides a link between {@link Storage} and {@link me.lucko.luckperms.common.storage.Storage}
*/
@AllArgsConstructor
public class StorageLink implements Storage {
private final LuckPermsPlugin plugin;
private final me.lucko.luckperms.common.storage.Storage master;
@Override
public String getName() {
return master.getName();
}
@Override
public boolean isAcceptingLogins() {
return master.isAcceptingLogins();
}
@Override
public Executor getSyncExecutor() {
return plugin.getSyncExecutor();
}
@Override
public Executor getAsyncExecutor() {
return plugin.getAsyncExecutor();
}
@Override
public CompletableFuture<Boolean> logAction(@NonNull LogEntry entry) {
return master.force().logAction(entry);
}
@Override
public CompletableFuture<Log> getLog() {
return master.force().getLog().thenApply(log -> log == null ? null : new LogLink(log));
}
@Override
public CompletableFuture<Boolean> loadUser(UUID uuid, String username) {
return master.force().loadUser(uuid, checkUsername(username));
}
@Override
public CompletableFuture<Boolean> saveUser(User user) {
checkUser(user);
return master.force().saveUser(((UserLink) user).getMaster());
}
@Override
public CompletableFuture<Boolean> cleanupUsers() {
return master.force().cleanupUsers();
}
@Override
public CompletableFuture<Set<UUID>> getUniqueUsers() {
return master.force().getUniqueUsers();
}
@Override
public CompletableFuture<Boolean> createAndLoadGroup(String name) {
return master.force().createAndLoadGroup(checkName(name));
}
@Override
public CompletableFuture<Boolean> loadGroup(String name) {
return master.force().loadGroup(checkName(name));
}
@Override
public CompletableFuture<Boolean> loadAllGroups() {
return master.force().loadAllGroups();
}
@Override
public CompletableFuture<Boolean> saveGroup(Group group) {
checkGroup(group);
return master.force().saveGroup(((GroupLink) group).getMaster());
}
@Override
public CompletableFuture<Boolean> deleteGroup(Group group) {
checkGroup(group);
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().getDefaultGroupName())) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
return master.force().deleteGroup(((GroupLink) group).getMaster());
}
@Override
public CompletableFuture<Boolean> createAndLoadTrack(String name) {
return master.force().createAndLoadTrack(checkName(name));
}
@Override
public CompletableFuture<Boolean> loadTrack(String name) {
return master.force().loadTrack(checkName(name));
}
@Override
public CompletableFuture<Boolean> loadAllTracks() {
return master.force().loadAllTracks();
}
@Override
public CompletableFuture<Boolean> saveTrack(Track track) {
checkTrack(track);
return master.force().saveTrack(((TrackLink) track).getMaster());
}
@Override
public CompletableFuture<Boolean> deleteTrack(Track track) {
checkTrack(track);
return master.force().deleteTrack(((TrackLink) track).getMaster());
}
@Override
public CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid) {
return master.force().saveUUIDData(checkUsername(username), uuid);
}
@Override
public CompletableFuture<UUID> getUUID(String username) {
return master.force().getUUID(checkUsername(username));
}
}

View File

@ -114,7 +114,7 @@ public abstract class SubCommand<T> extends Command<T, Void> {
}
public static void save(User user, Sender sender, LuckPermsPlugin plugin) {
boolean success = plugin.getDatastore().force().saveUser(user).getUnchecked();
boolean success = plugin.getStorage().force().saveUser(user).join();
user.getRefreshBuffer().requestDirectly();
if (success) {
@ -125,7 +125,7 @@ public abstract class SubCommand<T> extends Command<T, Void> {
}
public static void save(Group group, Sender sender, LuckPermsPlugin plugin) {
boolean success = plugin.getDatastore().force().saveGroup(group).getUnchecked();
boolean success = plugin.getStorage().force().saveGroup(group).join();
plugin.getUpdateTaskBuffer().requestDirectly();
if (success) {
@ -136,7 +136,7 @@ public abstract class SubCommand<T> extends Command<T, Void> {
}
public static void save(Track track, Sender sender, LuckPermsPlugin plugin) {
boolean success = plugin.getDatastore().force().saveTrack(track).getUnchecked();
boolean success = plugin.getStorage().force().saveTrack(track).join();
plugin.getUpdateTaskBuffer().requestDirectly();
if (success) {

View File

@ -46,7 +46,7 @@ public class HolderShowTracks<T extends PermissionHolder> extends SubCommand<T>
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, T holder, List<String> args, String label) throws CommandException {
if (!plugin.getDatastore().loadAllTracks().getUnchecked()) {
if (!plugin.getStorage().loadAllTracks().join()) {
Message.TRACKS_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}

View File

@ -61,7 +61,7 @@ public class ParentAdd extends SharedSubCommand {
String server = ArgumentUtils.handleServer(1, args);
String world = ArgumentUtils.handleWorld(2, args);
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
if (!plugin.getStorage().loadGroup(groupName).join()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}

View File

@ -64,7 +64,7 @@ public class ParentAddTemp extends SharedSubCommand {
String server = ArgumentUtils.handleServer(2, args);
String world = ArgumentUtils.handleWorld(3, args);
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
if (!plugin.getStorage().loadGroup(groupName).join()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}

View File

@ -62,7 +62,7 @@ public class ParentSet extends SharedSubCommand {
String server = ArgumentUtils.handleServer(1, args);
String world = ArgumentUtils.handleWorld(2, args);
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
if (!plugin.getStorage().loadGroup(groupName).join()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}

View File

@ -57,12 +57,12 @@ public class CreateGroup extends SingleCommand {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
if (plugin.getStorage().loadGroup(groupName).join()) {
Message.GROUP_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadGroup(groupName).getUnchecked()) {
if (!plugin.getStorage().createAndLoadGroup(groupName).join()) {
Message.CREATE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -61,7 +61,7 @@ public class DeleteGroup extends SingleCommand {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
if (!plugin.getStorage().loadGroup(groupName).join()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
@ -72,7 +72,7 @@ public class DeleteGroup extends SingleCommand {
return CommandResult.LOADING_ERROR;
}
if (!plugin.getDatastore().deleteGroup(group).getUnchecked()) {
if (!plugin.getStorage().deleteGroup(group).join()) {
Message.DELETE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -52,12 +52,12 @@ public class GroupClone extends SubCommand<Group> {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadGroup(newGroupName).getUnchecked()) {
if (plugin.getStorage().loadGroup(newGroupName).join()) {
Message.GROUP_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadGroup(newGroupName).getUnchecked()) {
if (!plugin.getStorage().createAndLoadGroup(newGroupName).join()) {
Message.CREATE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -55,7 +55,7 @@ public class GroupMainCommand extends MainCommand<Group> {
@Override
protected Group getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
if (!plugin.getDatastore().loadGroup(target).getUnchecked()) {
if (!plugin.getStorage().loadGroup(target).join()) {
Message.GROUP_NOT_FOUND.send(sender);
return null;
}

View File

@ -52,12 +52,12 @@ public class GroupRename extends SubCommand<Group> {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadGroup(newGroupName).getUnchecked()) {
if (plugin.getStorage().loadGroup(newGroupName).join()) {
Message.GROUP_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadGroup(newGroupName).getUnchecked()) {
if (!plugin.getStorage().createAndLoadGroup(newGroupName).join()) {
Message.CREATE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}
@ -68,7 +68,7 @@ public class GroupRename extends SubCommand<Group> {
return CommandResult.LOADING_ERROR;
}
if (!plugin.getDatastore().deleteGroup(group).getUnchecked()) {
if (!plugin.getStorage().deleteGroup(group).join()) {
Message.DELETE_GROUP_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -43,7 +43,7 @@ public class ListGroups extends SingleCommand {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (!plugin.getDatastore().loadAllGroups().getUnchecked()) {
if (!plugin.getStorage().loadAllGroups().join()) {
Message.GROUPS_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}

View File

@ -52,7 +52,7 @@ public class LogMainCommand extends MainCommand<Log> {
@Override
protected Log getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
Log log = plugin.getDatastore().getLog().getUnchecked();
Log log = plugin.getStorage().getLog().join();
if (log == null) {
Message.LOG_LOAD_ERROR.send(sender);

View File

@ -80,7 +80,7 @@ public class LogRecent extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
UUID uuid = plugin.getDatastore().getUUID(s).getUnchecked();
UUID uuid = plugin.getStorage().getUUID(s).join();
if (uuid == null) {
Message.USER_NOT_FOUND.send(sender);

View File

@ -82,7 +82,7 @@ public class LogUserHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
UUID uuid1 = plugin.getDatastore().getUUID(user).getUnchecked();
UUID uuid1 = plugin.getStorage().getUUID(user).join();
if (uuid1 == null) {
Message.USER_NOT_FOUND.send(sender);

View File

@ -33,7 +33,7 @@ import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.tracks.Track;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.Predicates;
@ -123,14 +123,14 @@ public class ExportCommand extends SingleCommand {
// Export users
log.info("Export: Exporting all users. Finding a list of unique users to export.");
Datastore ds = plugin.getDatastore();
Set<UUID> users = ds.getUniqueUsers().getUnchecked();
Storage ds = plugin.getStorage();
Set<UUID> users = ds.getUniqueUsers().join();
log.info("Export: Found " + users.size() + " unique users to export.");
int userCount = 0;
for (UUID uuid : users) {
userCount++;
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
plugin.getStorage().loadUser(uuid, "null").join();
User user = plugin.getUserManager().get(uuid);
boolean inDefault = false;

View File

@ -46,7 +46,7 @@ public class InfoCommand extends SingleCommand {
Message.INFO.send(sender,
plugin.getVersion(),
plugin.getType().getFriendlyName(),
plugin.getDatastore().getName(),
plugin.getStorage().getName(),
c.getServer(),
c.getSyncTime(),
formatBoolean(c.isIncludingGlobalPerms()),

View File

@ -41,7 +41,7 @@ public class NetworkSyncCommand extends SingleCommand {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
Message.UPDATE_TASK_REQUEST.send(sender);
plugin.getUpdateTaskBuffer().request().getUnchecked();
plugin.getUpdateTaskBuffer().request().join();
Message.UPDATE_TASK_COMPLETE_NETWORK.send(sender);
if (plugin.getRedisMessaging() != null) {

View File

@ -40,7 +40,7 @@ public class SyncCommand extends SingleCommand {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
Message.UPDATE_TASK_REQUEST.send(sender);
plugin.getUpdateTaskBuffer().request().getUnchecked();
plugin.getUpdateTaskBuffer().request().join();
Message.UPDATE_TASK_COMPLETE.send(sender);
return CommandResult.SUCCESS;
}

View File

@ -57,12 +57,12 @@ public class CreateTrack extends SingleCommand {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadTrack(trackName).getUnchecked()) {
if (plugin.getStorage().loadTrack(trackName).join()) {
Message.TRACK_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadTrack(trackName).getUnchecked()) {
if (!plugin.getStorage().createAndLoadTrack(trackName).join()) {
Message.CREATE_TRACK_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -55,7 +55,7 @@ public class DeleteTrack extends SingleCommand {
}
String trackName = args.get(0).toLowerCase();
if (!plugin.getDatastore().loadTrack(trackName).getUnchecked()) {
if (!plugin.getStorage().loadTrack(trackName).join()) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
@ -66,7 +66,7 @@ public class DeleteTrack extends SingleCommand {
return CommandResult.LOADING_ERROR;
}
if (!plugin.getDatastore().deleteTrack(track).getUnchecked()) {
if (!plugin.getStorage().deleteTrack(track).join()) {
Message.DELETE_TRACK_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -41,7 +41,7 @@ public class ListTracks extends SingleCommand {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (!plugin.getDatastore().loadAllTracks().getUnchecked()) {
if (!plugin.getStorage().loadAllTracks().join()) {
Message.TRACKS_LOAD_ERROR.send(sender);
return CommandResult.LOADING_ERROR;
}

View File

@ -56,7 +56,7 @@ public class TrackAppend extends SubCommand<Track> {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
if (!plugin.getStorage().loadGroup(groupName).join()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}

View File

@ -52,12 +52,12 @@ public class TrackClone extends SubCommand<Track> {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadTrack(newTrackName).getUnchecked()) {
if (plugin.getStorage().loadTrack(newTrackName).join()) {
Message.TRACK_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadTrack(newTrackName).getUnchecked()) {
if (!plugin.getStorage().createAndLoadTrack(newTrackName).join()) {
Message.CREATE_TRACK_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -67,7 +67,7 @@ public class TrackInsert extends SubCommand<Track> {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadGroup(groupName).getUnchecked()) {
if (!plugin.getStorage().loadGroup(groupName).join()) {
Message.GROUP_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}

View File

@ -49,7 +49,7 @@ public class TrackMainCommand extends MainCommand<Track> {
@Override
protected Track getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
if (!plugin.getDatastore().loadTrack(target).getUnchecked()) {
if (!plugin.getStorage().loadTrack(target).join()) {
Message.TRACK_NOT_FOUND.send(sender);
return null;
}

View File

@ -52,12 +52,12 @@ public class TrackRename extends SubCommand<Track> {
return CommandResult.INVALID_ARGS;
}
if (plugin.getDatastore().loadTrack(newTrackName).getUnchecked()) {
if (plugin.getStorage().loadTrack(newTrackName).join()) {
Message.TRACK_ALREADY_EXISTS.send(sender);
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().createAndLoadTrack(newTrackName).getUnchecked()) {
if (!plugin.getStorage().createAndLoadTrack(newTrackName).join()) {
Message.CREATE_TRACK_ERROR.send(sender);
return CommandResult.FAILURE;
}
@ -68,7 +68,7 @@ public class TrackRename extends SubCommand<Track> {
return CommandResult.LOADING_ERROR;
}
if (!plugin.getDatastore().deleteTrack(track).getUnchecked()) {
if (!plugin.getStorage().deleteTrack(track).join()) {
Message.DELETE_TRACK_ERROR.send(sender);
return CommandResult.FAILURE;
}

View File

@ -72,7 +72,7 @@ public class UserDemote extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadTrack(trackName).getUnchecked()) {
if (!plugin.getStorage().loadTrack(trackName).join()) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
@ -147,7 +147,7 @@ public class UserDemote extends SubCommand<User> {
return CommandResult.STATE_ERROR;
}
if (!plugin.getDatastore().loadGroup(previous).getUnchecked()) {
if (!plugin.getStorage().loadGroup(previous).join()) {
Message.USER_DEMOTE_ERROR_MALFORMED.send(sender, previous);
return CommandResult.STATE_ERROR;
}

View File

@ -67,7 +67,7 @@ public class UserMainCommand extends MainCommand<User> {
return null;
}
u = plugin.getDatastore().getUUID(target).getUnchecked();
u = plugin.getStorage().getUUID(target).join();
if (u == null) {
Message.USER_NOT_FOUND.send(sender);
return null;
@ -77,10 +77,10 @@ public class UserMainCommand extends MainCommand<User> {
}
}
String name = plugin.getDatastore().getName(u).getUnchecked();
String name = plugin.getStorage().getName(u).join();
if (name == null) name = "null";
if (!plugin.getDatastore().loadUser(u, name).getUnchecked()) {
if (!plugin.getStorage().loadUser(u, name).join()) {
Message.LOADING_ERROR.send(sender);
}

View File

@ -72,7 +72,7 @@ public class UserPromote extends SubCommand<User> {
return CommandResult.INVALID_ARGS;
}
if (!plugin.getDatastore().loadTrack(trackName).getUnchecked()) {
if (!plugin.getStorage().loadTrack(trackName).join()) {
Message.TRACK_DOES_NOT_EXIST.send(sender);
return CommandResult.INVALID_ARGS;
}
@ -147,7 +147,7 @@ public class UserPromote extends SubCommand<User> {
return CommandResult.STATE_ERROR;
}
if (!plugin.getDatastore().loadGroup(next).getUnchecked()) {
if (!plugin.getStorage().loadGroup(next).join()) {
Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, next);
return CommandResult.STATE_ERROR;
}

View File

@ -32,7 +32,7 @@ import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.NodeFactory;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
@ -40,7 +40,7 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.*;
public class BulkEditGroup extends SubCommand<Datastore> {
public class BulkEditGroup extends SubCommand<Storage> {
public BulkEditGroup() {
super("group", "Bulk edit group memberships", Permission.USER_BULKCHANGE, Predicates.not(4),
Arg.list(
@ -53,7 +53,7 @@ public class BulkEditGroup extends SubCommand<Datastore> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Datastore datastore, List<String> args, String label) throws CommandException {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Storage storage, List<String> args, String label) throws CommandException {
String group = args.get(0);
String type = args.get(1).toLowerCase();
String from = args.get(2);
@ -67,10 +67,10 @@ public class BulkEditGroup extends SubCommand<Datastore> {
return CommandResult.FAILURE;
}
Set<UUID> uuids = datastore.getUniqueUsers().getUnchecked();
Set<UUID> uuids = storage.getUniqueUsers().join();
for (UUID u : uuids) {
plugin.getDatastore().loadUser(u, "null").getUnchecked();
plugin.getStorage().loadUser(u, "null").join();
User user = plugin.getUserManager().get(u);
if (user == null) {
continue;
@ -143,7 +143,7 @@ public class BulkEditGroup extends SubCommand<Datastore> {
} catch (ObjectAlreadyHasException ignored) {}
});
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}

View File

@ -32,7 +32,7 @@ import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.constants.Message;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.core.NodeFactory;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.Predicates;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
@ -40,7 +40,7 @@ import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.*;
public class BulkEditPermission extends SubCommand<Datastore> {
public class BulkEditPermission extends SubCommand<Storage> {
public BulkEditPermission() {
super("permission", "Bulk edit permissions", Permission.USER_BULKCHANGE, Predicates.not(4),
Arg.list(
@ -53,7 +53,7 @@ public class BulkEditPermission extends SubCommand<Datastore> {
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Datastore datastore, List<String> args, String label) throws CommandException {
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Storage storage, List<String> args, String label) throws CommandException {
String node = args.get(0);
String type = args.get(1).toLowerCase();
String from = args.get(2);
@ -67,10 +67,10 @@ public class BulkEditPermission extends SubCommand<Datastore> {
return CommandResult.FAILURE;
}
Set<UUID> uuids = datastore.getUniqueUsers().getUnchecked();
Set<UUID> uuids = storage.getUniqueUsers().join();
for (UUID u : uuids) {
plugin.getDatastore().loadUser(u, "null").getUnchecked();
plugin.getStorage().loadUser(u, "null").join();
User user = plugin.getUserManager().get(u);
if (user == null) {
continue;
@ -133,7 +133,7 @@ public class BulkEditPermission extends SubCommand<Datastore> {
} catch (ObjectAlreadyHasException ignored) {}
});
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}

View File

@ -27,17 +27,17 @@ import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Command;
import me.lucko.luckperms.common.commands.MainCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class UsersBulkEditMainCommand extends MainCommand<Datastore> {
public class UsersBulkEditMainCommand extends MainCommand<Storage> {
public UsersBulkEditMainCommand() {
super("UsersBulkEdit", "User bulk edit commands", "/%s usersbulkedit", 1, ImmutableList.<Command<Datastore, ?>>builder()
super("UsersBulkEdit", "User bulk edit commands", "/%s usersbulkedit", 1, ImmutableList.<Command<Storage, ?>>builder()
.add(new BulkEditGroup())
.add(new BulkEditPermission())
.build()
@ -45,12 +45,12 @@ public class UsersBulkEditMainCommand extends MainCommand<Datastore> {
}
@Override
protected Datastore getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
return plugin.getDatastore();
protected Storage getTarget(String target, LuckPermsPlugin plugin, Sender sender) {
return plugin.getStorage();
}
@Override
protected void cleanup(Datastore datastore, LuckPermsPlugin plugin) {
protected void cleanup(Storage storage, LuckPermsPlugin plugin) {
}
@ -61,7 +61,7 @@ public class UsersBulkEditMainCommand extends MainCommand<Datastore> {
@Override
public List<String> tabComplete(LuckPermsPlugin plugin, Sender sender, List<String> args) {
final List<Command<Datastore, ?>> subs = getSubCommands().stream()
final List<Command<Storage, ?>> subs = getSubCommands().stream()
.filter(s -> s.isAuthorized(sender))
.collect(Collectors.toList());
@ -78,7 +78,7 @@ public class UsersBulkEditMainCommand extends MainCommand<Datastore> {
.collect(Collectors.toList());
}
Optional<Command<Datastore, ?>> o = subs.stream()
Optional<Command<Storage, ?>> o = subs.stream()
.filter(s -> s.getName().equalsIgnoreCase(args.get(0)))
.limit(1)
.findAny();

View File

@ -56,16 +56,16 @@ public enum Message {
* Loading / Saving
*/
USER_NOT_FOUND("&bUser could not be found.", true),
USER_SAVE_SUCCESS("&7(User data was saved to the datastore)", true),
USER_SAVE_SUCCESS("&7(User data was saved to storage)", true),
USER_SAVE_ERROR("There was an error whilst saving the user.", true),
USER_CREATE_FAIL("There was an error whilst creating a new user.", true),
GROUP_NOT_FOUND("&bGroup could not be found.", true),
GROUP_SAVE_SUCCESS("&7(Group data was saved to the datastore)", true),
GROUP_SAVE_SUCCESS("&7(Group data was saved to storage)", true),
GROUP_SAVE_ERROR("There was an error whilst saving the group.", true),
TRACK_NOT_FOUND("&bTrack could not be found.", true),
TRACK_SAVE_SUCCESS("&7(Track data was saved to the datastore)", true),
TRACK_SAVE_SUCCESS("&7(Track data was saved to storage)", true),
TRACK_SAVE_ERROR("There was an error whilst saving the track.", true),

View File

@ -48,7 +48,7 @@ public class LogEntry extends me.lucko.luckperms.api.LogEntry {
}
public void submit(LuckPermsPlugin plugin, Sender sender) {
plugin.getDatastore().logAction(this);
plugin.getStorage().logAction(this);
LogNotifyEvent event = new LogNotifyEvent(this);
event.setCancelled(!plugin.getConfiguration().isLogNotify());

View File

@ -23,6 +23,7 @@
package me.lucko.luckperms.common.messaging;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.MessagingService;
import me.lucko.luckperms.common.LuckPermsPlugin;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
@ -38,7 +39,7 @@ import java.util.UUID;
* Uses Redis to push/receive changes to/from other servers
*/
@RequiredArgsConstructor
public class RedisMessaging {
public class RedisMessaging implements MessagingService {
private static final String CHANNEL = "luckperms";
private final LuckPermsPlugin plugin;
@ -70,6 +71,7 @@ public class RedisMessaging {
jedisPool.destroy();
}
@Override
public void pushUpdate() {
plugin.doAsync(() -> {
UUID id = sub.generateId();

View File

@ -36,14 +36,14 @@ public class ExpireTemporaryTask implements Runnable {
boolean groupChanges = false;
for (Group group : plugin.getGroupManager().getAll().values()) {
if (group.auditTemporaryPermissions()) {
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
groupChanges = true;
}
}
for (User user : plugin.getUserManager().getAll().values()) {
if (user.auditTemporaryPermissions()) {
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
if (!groupChanges) {
user.getRefreshBuffer().request();
}

View File

@ -41,14 +41,14 @@ public class UpdateTask implements Runnable {
if (event.isCancelled()) return;
// Reload all groups
plugin.getDatastore().loadAllGroups().getUnchecked();
plugin.getStorage().loadAllGroups().join();
String defaultGroup = plugin.getConfiguration().getDefaultGroupName();
if (!plugin.getGroupManager().isLoaded(defaultGroup)) {
plugin.getDatastore().createAndLoadGroup(defaultGroup).getUnchecked();
plugin.getStorage().createAndLoadGroup(defaultGroup).join();
}
// Reload all tracks
plugin.getDatastore().loadAllTracks().getUnchecked();
plugin.getStorage().loadAllTracks().join();
// Refresh all online users.
plugin.getUserManager().updateAllUsers();

View File

@ -32,21 +32,19 @@ import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.storage.backing.AbstractBacking;
import me.lucko.luckperms.common.tracks.Track;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.AbstractFuture;
import me.lucko.luckperms.common.utils.LPFuture;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Future;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
/**
* Converts a {@link AbstractBacking} to use {@link Future}s
* Converts a {@link AbstractBacking} to use {@link CompletableFuture}s
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class AbstractDatastore implements Datastore {
public static Datastore wrap(LuckPermsPlugin plugin, AbstractBacking backing) {
BufferedOutputDatastore bufferedDs = BufferedOutputDatastore.wrap(TolerantDatastore.wrap(new AbstractDatastore(backing)), 1000L);
public class AbstractStorage implements Storage {
public static Storage wrap(LuckPermsPlugin plugin, AbstractBacking backing) {
BufferedOutputStorage bufferedDs = BufferedOutputStorage.wrap(TolerantStorage.wrap(new AbstractStorage(backing)), 1000L);
plugin.doAsyncRepeating(bufferedDs, 10L);
return bufferedDs;
}
@ -54,112 +52,107 @@ public class AbstractDatastore implements Datastore {
@Delegate(types = Delegated.class)
private final AbstractBacking backing;
private <T> LPFuture<T> makeFuture(Supplier<T> supplier) {
AbstractFuture<T> future = new AbstractFuture<>();
backing.doAsync(() -> {
T result = supplier.get();
future.complete(result);
});
return future;
private <T> CompletableFuture<T> makeFuture(Supplier<T> supplier) {
return CompletableFuture.supplyAsync(supplier, backing.getPlugin().getAsyncExecutor());
}
@Override
public Datastore force() {
public Storage force() {
return this;
}
@Override
public LPFuture<Boolean> logAction(LogEntry entry) {
public CompletableFuture<Boolean> logAction(LogEntry entry) {
return makeFuture(() -> backing.logAction(entry));
}
@Override
public LPFuture<Log> getLog() {
public CompletableFuture<Log> getLog() {
return makeFuture(backing::getLog);
}
@Override
public LPFuture<Boolean> loadUser(UUID uuid, String username) {
public CompletableFuture<Boolean> loadUser(UUID uuid, String username) {
return makeFuture(() -> backing.loadUser(uuid, username));
}
@Override
public LPFuture<Boolean> saveUser(User user) {
public CompletableFuture<Boolean> saveUser(User user) {
return makeFuture(() -> backing.saveUser(user));
}
@Override
public LPFuture<Boolean> cleanupUsers() {
public CompletableFuture<Boolean> cleanupUsers() {
return makeFuture(backing::cleanupUsers);
}
@Override
public LPFuture<Set<UUID>> getUniqueUsers() {
public CompletableFuture<Set<UUID>> getUniqueUsers() {
return makeFuture(backing::getUniqueUsers);
}
@Override
public LPFuture<Boolean> createAndLoadGroup(String name) {
public CompletableFuture<Boolean> createAndLoadGroup(String name) {
return makeFuture(() -> backing.createAndLoadGroup(name));
}
@Override
public LPFuture<Boolean> loadGroup(String name) {
public CompletableFuture<Boolean> loadGroup(String name) {
return makeFuture(() -> backing.loadGroup(name));
}
@Override
public LPFuture<Boolean> loadAllGroups() {
public CompletableFuture<Boolean> loadAllGroups() {
return makeFuture(backing::loadAllGroups);
}
@Override
public LPFuture<Boolean> saveGroup(Group group) {
public CompletableFuture<Boolean> saveGroup(Group group) {
return makeFuture(() -> backing.saveGroup(group));
}
@Override
public LPFuture<Boolean> deleteGroup(Group group) {
public CompletableFuture<Boolean> deleteGroup(Group group) {
return makeFuture(() -> backing.deleteGroup(group));
}
@Override
public LPFuture<Boolean> createAndLoadTrack(String name) {
public CompletableFuture<Boolean> createAndLoadTrack(String name) {
return makeFuture(() -> backing.createAndLoadTrack(name));
}
@Override
public LPFuture<Boolean> loadTrack(String name) {
public CompletableFuture<Boolean> loadTrack(String name) {
return makeFuture(() -> backing.loadTrack(name));
}
@Override
public LPFuture<Boolean> loadAllTracks() {
public CompletableFuture<Boolean> loadAllTracks() {
return makeFuture(backing::loadAllTracks);
}
@Override
public LPFuture<Boolean> saveTrack(Track track) {
public CompletableFuture<Boolean> saveTrack(Track track) {
return makeFuture(() -> backing.saveTrack(track));
}
@Override
public LPFuture<Boolean> deleteTrack(Track track) {
public CompletableFuture<Boolean> deleteTrack(Track track) {
return makeFuture(() -> backing.deleteTrack(track));
}
@Override
public LPFuture<Boolean> saveUUIDData(String username, UUID uuid) {
public CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid) {
return makeFuture(() -> backing.saveUUIDData(username, uuid));
}
@Override
public LPFuture<UUID> getUUID(String username) {
public CompletableFuture<UUID> getUUID(String username) {
return makeFuture(() -> backing.getUUID(username));
}
@Override
public LPFuture<String> getName(UUID uuid) {
public CompletableFuture<String> getName(UUID uuid) {
return makeFuture(() -> backing.getName(uuid));
}
@ -167,8 +160,6 @@ public class AbstractDatastore implements Datastore {
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean b);
void doAsync(Runnable r);
void doSync(Runnable r);
void init();
void shutdown();
}

View File

@ -31,47 +31,47 @@ import me.lucko.luckperms.common.tracks.Track;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.users.UserIdentifier;
import me.lucko.luckperms.common.utils.Buffer;
import me.lucko.luckperms.common.utils.LPFuture;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class BufferedOutputDatastore implements Datastore, Runnable {
public static BufferedOutputDatastore wrap(Datastore datastore, long flushTime) {
return new BufferedOutputDatastore(datastore, flushTime);
public class BufferedOutputStorage implements Storage, Runnable {
public static BufferedOutputStorage wrap(Storage storage, long flushTime) {
return new BufferedOutputStorage(storage, flushTime);
}
@Getter
@Delegate(excludes = Exclude.class)
private final Datastore backing;
private final Storage backing;
private final long flushTime;
private final Buffer<User, Boolean> userOutputBuffer = new Buffer<User, Boolean>() {
@Override
public Boolean dequeue(User user) {
return backing.saveUser(user).getUnchecked();
return backing.saveUser(user).join();
}
};
private final Buffer<Group, Boolean> groupOutputBuffer = new Buffer<Group, Boolean>() {
@Override
public Boolean dequeue(Group group) {
return backing.saveGroup(group).getUnchecked();
return backing.saveGroup(group).join();
}
};
private final Buffer<Track, Boolean> trackOutputBuffer = new Buffer<Track, Boolean>() {
@Override
public Boolean dequeue(Track track) {
return backing.saveTrack(track).getUnchecked();
return backing.saveTrack(track).join();
}
};
private final Buffer<UserIdentifier, Boolean> uuidDataOutputBuffer = new Buffer<UserIdentifier, Boolean>() {
@Override
protected Boolean dequeue(UserIdentifier userIdentifier) {
return backing.saveUUIDData(userIdentifier.getUsername(), userIdentifier.getUuid()).getUnchecked();
return backing.saveUUIDData(userIdentifier.getUsername(), userIdentifier.getUuid()).join();
}
};
@ -92,7 +92,7 @@ public class BufferedOutputDatastore implements Datastore, Runnable {
}
@Override
public Datastore force() {
public Storage force() {
return backing;
}
@ -103,31 +103,31 @@ public class BufferedOutputDatastore implements Datastore, Runnable {
}
@Override
public LPFuture<Boolean> saveUser(User user) {
public CompletableFuture<Boolean> saveUser(User user) {
return userOutputBuffer.enqueue(user);
}
@Override
public LPFuture<Boolean> saveGroup(Group group) {
public CompletableFuture<Boolean> saveGroup(Group group) {
return groupOutputBuffer.enqueue(group);
}
@Override
public LPFuture<Boolean> saveTrack(Track track) {
public CompletableFuture<Boolean> saveTrack(Track track) {
return trackOutputBuffer.enqueue(track);
}
@Override
public LPFuture<Boolean> saveUUIDData(String username, UUID uuid) {
public CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid) {
return uuidDataOutputBuffer.enqueue(UserIdentifier.of(uuid, username));
}
private interface Exclude {
Datastore force();
LPFuture<Void> shutdown();
LPFuture<Boolean> saveUser(User user);
LPFuture<Boolean> saveGroup(Group group);
LPFuture<Boolean> saveTrack(Track track);
LPFuture<Boolean> saveUUIDData(String username, UUID uuid);
Storage force();
CompletableFuture<Void> shutdown();
CompletableFuture<Boolean> saveUser(User user);
CompletableFuture<Boolean> saveGroup(Group group);
CompletableFuture<Boolean> saveTrack(Track track);
CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid);
}
}

View File

@ -1,211 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.storage;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.tracks.Track;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.LPFuture;
import java.util.Set;
import java.util.UUID;
public interface Datastore {
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean acceptingLogins);
/**
* Execute a runnable asynchronously
* @param r the task to run
*/
void doAsync(Runnable r);
/**
* Execute a runnable synchronously
* @param r the task to run
*/
void doSync(Runnable r);
Datastore force();
void init();
void shutdown();
LPFuture<Boolean> logAction(LogEntry entry);
LPFuture<Log> getLog();
LPFuture<Boolean> loadUser(UUID uuid, String username);
LPFuture<Boolean> saveUser(User user);
LPFuture<Boolean> cleanupUsers();
LPFuture<Set<UUID>> getUniqueUsers();
LPFuture<Boolean> createAndLoadGroup(String name);
LPFuture<Boolean> loadGroup(String name);
LPFuture<Boolean> loadAllGroups();
LPFuture<Boolean> saveGroup(Group group);
LPFuture<Boolean> deleteGroup(Group group);
LPFuture<Boolean> createAndLoadTrack(String name);
LPFuture<Boolean> loadTrack(String name);
LPFuture<Boolean> loadAllTracks();
LPFuture<Boolean> saveTrack(Track track);
LPFuture<Boolean> deleteTrack(Track track);
LPFuture<Boolean> saveUUIDData(String username, UUID uuid);
LPFuture<UUID> getUUID(String username);
LPFuture<String> getName(UUID uuid);
default void logAction(LogEntry entry, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = logAction(entry).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void getLog(Callback<Log> callback) {
doAsync(() -> {
Log result = getLog().getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void loadUser(UUID uuid, String username, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = loadUser(uuid, username).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void saveUser(User user, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = saveUser(user).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void cleanupUsers(Callback<Boolean> callback) {
doAsync(() -> {
boolean result = cleanupUsers().getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void getUniqueUsers(Callback<Set<UUID>> callback) {
doAsync(() -> {
Set<UUID> result = getUniqueUsers().getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void createAndLoadGroup(String name, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = createAndLoadGroup(name).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void loadGroup(String name, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = loadGroup(name).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void loadAllGroups(Callback<Boolean> callback) {
doAsync(() -> {
boolean result = loadAllGroups().getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void saveGroup(Group group, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = saveGroup(group).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void deleteGroup(Group group, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = deleteGroup(group).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void createAndLoadTrack(String name, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = createAndLoadTrack(name).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void loadTrack(String name, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = loadTrack(name).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void loadAllTracks(Callback<Boolean> callback) {
doAsync(() -> {
boolean result = loadAllTracks().getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void saveTrack(Track track, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = saveTrack(track).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void deleteTrack(Track track, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = deleteTrack(track).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void saveUUIDData(String username, UUID uuid, Callback<Boolean> callback) {
doAsync(() -> {
boolean result = saveUUIDData(username, uuid).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void getUUID(String username, Callback<UUID> callback) {
doAsync(() -> {
UUID result = getUUID(username).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
default void getName(UUID uuid, Callback<String> callback) {
doAsync(() -> {
String result = getName(uuid).getUnchecked();
doSync(() -> callback.onComplete(result));
});
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.common.storage;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.tracks.Track;
import me.lucko.luckperms.common.users.User;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
/**
* Main interface for all Storage providers.
*/
public interface Storage {
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean acceptingLogins);
Storage force();
void init();
void shutdown();
CompletableFuture<Boolean> logAction(LogEntry entry);
CompletableFuture<Log> getLog();
CompletableFuture<Boolean> loadUser(UUID uuid, String username);
CompletableFuture<Boolean> saveUser(User user);
CompletableFuture<Boolean> cleanupUsers();
CompletableFuture<Set<UUID>> getUniqueUsers();
CompletableFuture<Boolean> createAndLoadGroup(String name);
CompletableFuture<Boolean> loadGroup(String name);
CompletableFuture<Boolean> loadAllGroups();
CompletableFuture<Boolean> saveGroup(Group group);
CompletableFuture<Boolean> deleteGroup(Group group);
CompletableFuture<Boolean> createAndLoadTrack(String name);
CompletableFuture<Boolean> loadTrack(String name);
CompletableFuture<Boolean> loadAllTracks();
CompletableFuture<Boolean> saveTrack(Track track);
CompletableFuture<Boolean> deleteTrack(Track track);
CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid);
CompletableFuture<UUID> getUUID(String username);
CompletableFuture<String> getName(UUID uuid);
}

View File

@ -37,8 +37,8 @@ import java.util.Set;
public class StorageFactory {
private static final Set<String> TYPES = ImmutableSet.of("json", "yaml", "flatfile", "mongodb", "mysql", "sqlite", "h2");
public static Datastore getDatastore(LuckPermsPlugin plugin, String defaultMethod) {
Datastore datastore;
public static Storage getInstance(LuckPermsPlugin plugin, String defaultMethod) {
Storage storage;
plugin.getLog().info("Detecting storage method...");
if (plugin.getConfiguration().isSplitStorage()) {
@ -63,7 +63,7 @@ public class StorageFactory {
backing.put(type, backingFromString(type, plugin));
}
datastore = AbstractDatastore.wrap(plugin, new SplitBacking(plugin, backing, types));
storage = AbstractStorage.wrap(plugin, new SplitBacking(plugin, backing, types));
} else {
String storageMethod = plugin.getConfiguration().getStorageMethod().toLowerCase();
@ -72,17 +72,17 @@ public class StorageFactory {
storageMethod = defaultMethod;
}
datastore = fromString(storageMethod, plugin);
plugin.getLog().info("Using " + datastore.getName() + " as storage method.");
storage = fromString(storageMethod, plugin);
plugin.getLog().info("Using " + storage.getName() + " as storage method.");
}
plugin.getLog().info("Initialising datastore...");
datastore.init();
return datastore;
storage.init();
return storage;
}
private static Datastore fromString(String storageMethod, LuckPermsPlugin plugin) {
return AbstractDatastore.wrap(plugin, backingFromString(storageMethod, plugin));
private static Storage fromString(String storageMethod, LuckPermsPlugin plugin) {
return AbstractStorage.wrap(plugin, backingFromString(storageMethod, plugin));
}
private static AbstractBacking backingFromString(String method, LuckPermsPlugin plugin) {

View File

@ -30,30 +30,30 @@ import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.groups.Group;
import me.lucko.luckperms.common.tracks.Track;
import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.utils.LPFuture;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* A Datastore wrapping that ensures all tasks are completed before {@link Datastore#shutdown()} is called.
* A Datastore wrapping that ensures all tasks are completed before {@link Storage#shutdown()} is called.
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class TolerantDatastore implements Datastore {
public static TolerantDatastore wrap(Datastore datastore) {
return new TolerantDatastore(datastore);
public class TolerantStorage implements Storage {
public static TolerantStorage wrap(Storage storage) {
return new TolerantStorage(storage);
}
@Delegate(types = Delegated.class)
private final Datastore backing;
private final Storage backing;
private final Phaser phaser = new Phaser();
@Override
public Datastore force() {
public Storage force() {
return this;
}
@ -70,7 +70,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> logAction(LogEntry entry) {
public CompletableFuture<Boolean> logAction(LogEntry entry) {
phaser.register();
try {
return backing.logAction(entry);
@ -80,7 +80,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Log> getLog() {
public CompletableFuture<Log> getLog() {
phaser.register();
try {
return backing.getLog();
@ -90,7 +90,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> loadUser(UUID uuid, String username) {
public CompletableFuture<Boolean> loadUser(UUID uuid, String username) {
phaser.register();
try {
return backing.loadUser(uuid, username);
@ -100,7 +100,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> saveUser(User user) {
public CompletableFuture<Boolean> saveUser(User user) {
phaser.register();
try {
return backing.saveUser(user);
@ -110,7 +110,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> cleanupUsers() {
public CompletableFuture<Boolean> cleanupUsers() {
phaser.register();
try {
return backing.cleanupUsers();
@ -120,7 +120,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Set<UUID>> getUniqueUsers() {
public CompletableFuture<Set<UUID>> getUniqueUsers() {
phaser.register();
try {
return backing.getUniqueUsers();
@ -130,7 +130,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> createAndLoadGroup(String name) {
public CompletableFuture<Boolean> createAndLoadGroup(String name) {
phaser.register();
try {
return backing.createAndLoadGroup(name);
@ -140,7 +140,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> loadGroup(String name) {
public CompletableFuture<Boolean> loadGroup(String name) {
phaser.register();
try {
return backing.loadGroup(name);
@ -150,7 +150,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> loadAllGroups() {
public CompletableFuture<Boolean> loadAllGroups() {
phaser.register();
try {
return backing.loadAllGroups();
@ -160,7 +160,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> saveGroup(Group group) {
public CompletableFuture<Boolean> saveGroup(Group group) {
phaser.register();
try {
return backing.saveGroup(group);
@ -170,7 +170,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> deleteGroup(Group group) {
public CompletableFuture<Boolean> deleteGroup(Group group) {
phaser.register();
try {
return backing.deleteGroup(group);
@ -180,7 +180,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> createAndLoadTrack(String name) {
public CompletableFuture<Boolean> createAndLoadTrack(String name) {
phaser.register();
try {
return backing.createAndLoadTrack(name);
@ -190,7 +190,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> loadTrack(String name) {
public CompletableFuture<Boolean> loadTrack(String name) {
phaser.register();
try {
return backing.loadTrack(name);
@ -200,7 +200,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> loadAllTracks() {
public CompletableFuture<Boolean> loadAllTracks() {
phaser.register();
try {
return backing.loadAllTracks();
@ -210,7 +210,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> saveTrack(Track track) {
public CompletableFuture<Boolean> saveTrack(Track track) {
phaser.register();
try {
return backing.saveTrack(track);
@ -220,7 +220,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> deleteTrack(Track track) {
public CompletableFuture<Boolean> deleteTrack(Track track) {
phaser.register();
try {
return backing.deleteTrack(track);
@ -230,7 +230,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<Boolean> saveUUIDData(String username, UUID uuid) {
public CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid) {
phaser.register();
try {
return backing.saveUUIDData(username, uuid);
@ -240,7 +240,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<UUID> getUUID(String username) {
public CompletableFuture<UUID> getUUID(String username) {
phaser.register();
try {
return backing.getUUID(username);
@ -250,7 +250,7 @@ public class TolerantDatastore implements Datastore {
}
@Override
public LPFuture<String> getName(UUID uuid) {
public CompletableFuture<String> getName(UUID uuid) {
phaser.register();
try {
return backing.getName(uuid);
@ -263,8 +263,6 @@ public class TolerantDatastore implements Datastore {
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean b);
void doAsync(Runnable r);
void doSync(Runnable r);
void init();
}
}

View File

@ -38,6 +38,8 @@ import java.util.UUID;
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class AbstractBacking {
@Getter
protected final LuckPermsPlugin plugin;
@Getter
@ -47,22 +49,6 @@ public abstract class AbstractBacking {
@Setter
private boolean acceptingLogins = false;
/**
* Execute a runnable asynchronously
* @param r the task to run
*/
public void doAsync(Runnable r) {
plugin.doAsync(r);
}
/**
* Execute a runnable synchronously
* @param r the task to run
*/
public void doSync(Runnable r) {
plugin.doSync(r);
}
public abstract void init();
public abstract void shutdown();
public abstract boolean logAction(LogEntry entry);

View File

@ -24,7 +24,6 @@ package me.lucko.luckperms.common.users;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.AbstractManager;
import me.lucko.luckperms.common.utils.Identifiable;
@ -81,7 +80,7 @@ public class UserManager extends AbstractManager<UserIdentifier, User> {
} catch (ObjectAlreadyHasException ignored) {}
if (save) {
plugin.getDatastore().saveUser(user, Callback.empty());
plugin.getStorage().saveUser(user);
}
return true;
@ -134,7 +133,7 @@ public class UserManager extends AbstractManager<UserIdentifier, User> {
plugin.doAsync(() -> {
for (UUID uuid : players) {
UUID internal = plugin.getUuidCache().getUUID(uuid);
plugin.getDatastore().loadUser(internal, "null").getUnchecked();
plugin.getStorage().loadUser(internal, "null").join();
User user = get(internal);
user.getRefreshBuffer().request();
}

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.utils;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Basic Future implementation
* @param <R> the return type
*/
public class AbstractFuture<R> implements LPFuture<R> {
private final CountDownLatch latch = new CountDownLatch(1);
private R value;
public void complete(R r) {
value = r;
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 R get() throws InterruptedException {
latch.await();
return value;
}
@Override
public R get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
if (latch.await(timeout, unit)) {
return value;
} else {
throw new TimeoutException();
}
}
}

View File

@ -23,7 +23,6 @@
package me.lucko.luckperms.common.utils;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.api.data.Callback;
import me.lucko.luckperms.api.event.events.UserFirstLoginEvent;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.core.UuidCache;
@ -44,26 +43,26 @@ public class AbstractListener {
final UuidCache cache = plugin.getUuidCache();
if (!cache.isOnlineMode()) {
UUID uuid = plugin.getDatastore().force().getUUID(username).getUnchecked();
UUID uuid = plugin.getStorage().force().getUUID(username).join();
if (uuid != null) {
cache.addToCache(u, uuid);
} else {
// No previous data for this player
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(u, username));
cache.addToCache(u, u);
plugin.getDatastore().force().saveUUIDData(username, u, Callback.empty());
plugin.getStorage().force().saveUUIDData(username, u);
}
} else {
UUID uuid = plugin.getDatastore().force().getUUID(username).getUnchecked();
UUID uuid = plugin.getStorage().force().getUUID(username).join();
if (uuid == null) {
plugin.getApiProvider().fireEventAsync(new UserFirstLoginEvent(u, username));
}
// Online mode, no cache needed. This is just for name -> uuid lookup.
plugin.getDatastore().force().saveUUIDData(username, u, Callback.empty());
plugin.getStorage().force().saveUUIDData(username, u);
}
plugin.getDatastore().force().loadUser(cache.getUUID(u), username).getUnchecked();
plugin.getStorage().force().loadUser(cache.getUUID(u), username).join();
User user = plugin.getUserManager().get(cache.getUUID(u));
if (user == null) {
plugin.getLog().warn("Failed to load user: " + username);
@ -78,7 +77,7 @@ public class AbstractListener {
// If they were given a default, persist the new assignments back to the storage.
if (save) {
plugin.getDatastore().force().saveUser(user).getUnchecked();
plugin.getStorage().force().saveUser(user).join();
}
user.setupData(false); // Pretty nasty calculation call. Sets up the caching system so data is ready when the user joins.

View File

@ -27,6 +27,7 @@ import lombok.*;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.locks.ReentrantLock;
/**
@ -42,7 +43,7 @@ public abstract class Buffer<T, R> implements Runnable {
private final ReentrantLock lock = new ReentrantLock();
private final List<BufferedObject<T, R>> buffer = new LinkedList<>();
public LPFuture<R> enqueue(@NonNull T t) {
public CompletableFuture<R> enqueue(@NonNull T t) {
lock.lock();
try {
ListIterator<BufferedObject<T, R>> it = buffer.listIterator();
@ -60,7 +61,7 @@ public abstract class Buffer<T, R> implements Runnable {
}
if (o == null) {
o = new BufferedObject<>(System.currentTimeMillis(), t, new AbstractFuture<R>());
o = new BufferedObject<>(System.currentTimeMillis(), t, new CompletableFuture<R>());
} else {
o.setBufferTime(System.currentTimeMillis());
}
@ -111,7 +112,7 @@ public abstract class Buffer<T, R> implements Runnable {
@Setter
private long bufferTime;
private final T object;
private final AbstractFuture<R> future;
private final CompletableFuture<R> future;
}
}

View File

@ -26,8 +26,9 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.lang.ref.WeakReference;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@ -41,12 +42,12 @@ import java.util.function.Supplier;
@RequiredArgsConstructor
public abstract class BufferedRequest<T> {
private final long bufferTimeMillis;
private final Consumer<Runnable> executor;
private final Executor executor;
private WeakReference<Processor<T>> processor = null;
private ReentrantLock lock = new ReentrantLock();
public LPFuture<T> request() {
public CompletableFuture<T> request() {
lock.lock();
try {
if (processor != null) {
@ -57,7 +58,7 @@ public abstract class BufferedRequest<T> {
}
Processor<T> p = new Processor<>(bufferTimeMillis, this::perform);
executor.accept(p);
executor.execute(p);
processor = new WeakReference<>(p);
return p.get();
@ -82,7 +83,7 @@ public abstract class BufferedRequest<T> {
private final ReentrantLock lock = new ReentrantLock();
private long executionTime;
private final AbstractFuture<R> future = new AbstractFuture<>();
private final CompletableFuture<R> future = new CompletableFuture<R>();
@Override
public void run() {
@ -116,11 +117,11 @@ public abstract class BufferedRequest<T> {
future.complete(result);
}
public LPFuture<R> get() {
public CompletableFuture<R> get() {
return future;
}
public LPFuture<R> getAndExtend() {
public CompletableFuture<R> getAndExtend() {
lock.lock();
try {
executionTime = System.currentTimeMillis() + delayMillis;

View File

@ -21,16 +21,16 @@ does-not-have-temp-permission: "{0} does not have this permission set temporaril
user-not-found: "&bUser could not be found."
user-save-success: "&7(User data was saved to the datastore)"
user-save-success: "&7(User data was saved to storage)"
user-save-error: "There was an error whilst saving the user."
user-create-fail: "There was an error whilst creating a new user."
group-not-found: "&bGroup could not be found."
group-save-success: "&7(Group data was saved to the datastore)"
group-save-success: "&7(Group data was saved to storage)"
group-save-error: "There was an error whilst saving the group."
track-not-found: "&bTrack could not be found."
track-save-success: "&7(Track data was saved to the datastore)"
track-save-success: "&7(Track data was saved to storage)"
track-save-error: "There was an error whilst saving the track."

View File

@ -6,7 +6,7 @@
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms</artifactId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
<modules>
<module>common</module>
<module>api</module>
@ -38,7 +38,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<release.version>2.13</release.version>
<release.version>2.14</release.version>
</properties>
<distributionManagement>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId>
<version>2.13-SNAPSHOT</version>
<version>2.14-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -43,7 +43,7 @@ import me.lucko.luckperms.common.groups.GroupManager;
import me.lucko.luckperms.common.messaging.RedisMessaging;
import me.lucko.luckperms.common.runnables.ExpireTemporaryTask;
import me.lucko.luckperms.common.runnables.UpdateTask;
import me.lucko.luckperms.common.storage.Datastore;
import me.lucko.luckperms.common.storage.Storage;
import me.lucko.luckperms.common.storage.StorageFactory;
import me.lucko.luckperms.common.tracks.TrackManager;
import me.lucko.luckperms.common.users.UserManager;
@ -77,6 +77,7 @@ import java.io.File;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@ -105,6 +106,8 @@ public class LPSpongePlugin implements LuckPermsPlugin {
private Path configDir;
private Scheduler scheduler = Sponge.getScheduler();
private Executor syncExecutor = Sponge.getScheduler().createSyncExecutor(this);
private Executor asyncExecutor = Sponge.getScheduler().createAsyncExecutor(this);
private LPTimings timings;
private final Set<UUID> ignoringLogs = ConcurrentHashMap.newKeySet();
@ -112,7 +115,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private Datastore datastore;
private Storage storage;
private RedisMessaging redisMessaging = null;
private UuidCache uuidCache;
private ApiProvider apiProvider;
@ -141,7 +144,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
Sponge.getEventManager().registerListeners(this, new SpongeListener(this));
// initialise datastore
datastore = StorageFactory.getDatastore(this, "h2");
storage = StorageFactory.getInstance(this, "h2");
// initialise redis
if (getConfiguration().isRedisEnabled()) {
@ -228,7 +231,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
@Listener
public void onDisable(GameStoppingServerEvent event) {
getLog().info("Closing datastore...");
datastore.shutdown();
storage.shutdown();
if (redisMessaging != null) {
getLog().info("Closing redis...");

View File

@ -52,7 +52,7 @@ public class SpongeListener extends AbstractListener {
@Listener(order = Order.EARLY)
public void onClientAuth(ClientConnectionEvent.Auth e) {
if (!plugin.getDatastore().isAcceptingLogins()) {
if (!plugin.getStorage().isAcceptingLogins()) {
/* Datastore is disabled, prevent players from joining the server
Just don't load their data, they will be kicked at login */
return;

View File

@ -89,10 +89,10 @@ public class MigrationPermissionManager extends SubCommand<Object> {
groupCount++;
// Make a LuckPerms group for the one being migrated
plugin.getDatastore().createAndLoadGroup(pmGroup.getIdentifier().toLowerCase()).getUnchecked();
plugin.getStorage().createAndLoadGroup(pmGroup.getIdentifier().toLowerCase()).join();
Group group = plugin.getGroupManager().get(pmGroup.getIdentifier().toLowerCase());
migrateSubject(pmGroup, group);
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
}
log.info("PermissionManager Migration: Migrated " + groupCount + " groups");
@ -117,10 +117,10 @@ public class MigrationPermissionManager extends SubCommand<Object> {
}
// Make a LuckPerms user for the one being migrated
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
plugin.getStorage().loadUser(uuid, "null").join();
User user = plugin.getUserManager().get(uuid);
migrateSubject(pmUser, user);
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}

View File

@ -69,10 +69,10 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
groupCount++;
// Make a LuckPerms group for the one being migrated
plugin.getDatastore().createAndLoadGroup(pexGroup.getIdentifier().toLowerCase()).getUnchecked();
plugin.getStorage().createAndLoadGroup(pexGroup.getIdentifier().toLowerCase()).join();
Group group = plugin.getGroupManager().get(pexGroup.getIdentifier().toLowerCase());
migrateSubject(pexGroup, group);
plugin.getDatastore().saveGroup(group);
plugin.getStorage().saveGroup(group);
}
log.info("PermissionsEx Migration: Migrated " + groupCount + " groups");
@ -88,10 +88,10 @@ public class MigrationPermissionsEx extends SubCommand<Object> {
}
// Make a LuckPerms user for the one being migrated
plugin.getDatastore().loadUser(uuid, "null").getUnchecked();
plugin.getStorage().loadUser(uuid, "null").join();
User user = plugin.getUserManager().get(uuid);
migrateSubject(pexUser, user);
plugin.getDatastore().saveUser(user);
plugin.getStorage().saveUser(user);
plugin.getUserManager().cleanup(user);
}

View File

@ -59,10 +59,12 @@ public class LuckPermsSubjectData implements SubjectData {
private void objectSave(PermissionHolder t) {
if (t instanceof User) {
service.getPlugin().getDatastore().saveUser(((User) t), b -> ((User) t).getRefreshBuffer().request());
service.getPlugin().getStorage().saveUser(((User) t))
.thenRunAsync(() -> ((User) t).getRefreshBuffer().request(), service.getPlugin().getAsyncExecutor());
}
if (t instanceof Group) {
service.getPlugin().getDatastore().saveGroup(((Group) t), b -> service.getPlugin().getUpdateTaskBuffer().request());
service.getPlugin().getStorage().saveGroup((Group) t)
.thenRunAsync(() -> service.getPlugin().getUpdateTaskBuffer().request(), service.getPlugin().getAsyncExecutor());
}
}

View File

@ -97,7 +97,7 @@ public class GroupCollection implements SubjectCollection {
if (!manager.isLoaded(id)) {
service.getPlugin().getLog().warn("Group Subject '" + id + "' was requested, but is not loaded in memory. Loading it from storage now.");
long startTime = System.currentTimeMillis();
service.getPlugin().getDatastore().createAndLoadGroup(id).getUnchecked();
service.getPlugin().getStorage().createAndLoadGroup(id).join();
service.getPlugin().getLog().warn("Loading '" + id + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
}

View File

@ -109,7 +109,7 @@ public class UserCollection implements SubjectCollection {
if (!manager.isLoaded(UserIdentifier.of(u, null))) {
service.getPlugin().getLog().warn("User Subject '" + u + "' was requested, but is not loaded in memory. Loading them from storage now.");
long startTime = System.currentTimeMillis();
service.getPlugin().getDatastore().loadUser(u, "null").getUnchecked();
service.getPlugin().getStorage().loadUser(u, "null").join();
service.getPlugin().getLog().warn("Loading '" + u + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
}