mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-24 03:25:19 +01:00
Add flatfile storage support
This commit is contained in:
parent
85989aeb7c
commit
0781637617
@ -10,10 +10,10 @@ A (fairly bad) permissions implementation for Bukkit/BungeeCord.
|
|||||||
* **Easy and simple setup and configuration using commands** - no editing yml files, yuck
|
* **Easy and simple setup and configuration using commands** - no editing yml files, yuck
|
||||||
* **Efficient/lightweight** - maybe? Who knows, it might be.
|
* **Efficient/lightweight** - maybe? Who knows, it might be.
|
||||||
* **BungeeCord compatible** - permissions, users and groups are synced across Bukkit/BungeeCord instances
|
* **BungeeCord compatible** - permissions, users and groups are synced across Bukkit/BungeeCord instances
|
||||||
* **Support for MySQL and SQLite** - other storage methods coming soon (maybe)
|
* **Support for MySQL, SQLite & Flatfile (JSON)** - other storage methods coming soon (maybe)
|
||||||
|
|
||||||
===== Possible Caveats
|
===== Possible Caveats
|
||||||
* Currently only supports MySQL and SQLite (support for more methods might come in the future)
|
* Currently only supports MySQL, SQLite & Flatfile (JSON) (support for more methods might come in the future)
|
||||||
* Not at all tested and could produce unexpected/buggy results and errors
|
* Not at all tested and could produce unexpected/buggy results and errors
|
||||||
|
|
||||||
=== Setup
|
=== Setup
|
||||||
|
@ -3,6 +3,7 @@ package me.lucko.luckperms;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import me.lucko.luckperms.data.Datastore;
|
import me.lucko.luckperms.data.Datastore;
|
||||||
import me.lucko.luckperms.data.MySQLConfiguration;
|
import me.lucko.luckperms.data.MySQLConfiguration;
|
||||||
|
import me.lucko.luckperms.data.methods.FlatfileDatastore;
|
||||||
import me.lucko.luckperms.data.methods.MySQLDatastore;
|
import me.lucko.luckperms.data.methods.MySQLDatastore;
|
||||||
import me.lucko.luckperms.data.methods.SQLiteDatastore;
|
import me.lucko.luckperms.data.methods.SQLiteDatastore;
|
||||||
import me.lucko.luckperms.groups.GroupManager;
|
import me.lucko.luckperms.groups.GroupManager;
|
||||||
@ -58,6 +59,9 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
|
|||||||
} else if (storageMethod.equalsIgnoreCase("sqlite")) {
|
} else if (storageMethod.equalsIgnoreCase("sqlite")) {
|
||||||
getLogger().info("Using SQLite as storage method.");
|
getLogger().info("Using SQLite as storage method.");
|
||||||
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
||||||
|
} else if (storageMethod.equalsIgnoreCase("flatfile")) {
|
||||||
|
getLogger().info("Using Flatfile (JSON) as storage method.");
|
||||||
|
datastore = new FlatfileDatastore(this, getDataFolder());
|
||||||
} else {
|
} else {
|
||||||
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
|
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
|
||||||
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
||||||
|
@ -12,7 +12,7 @@ include-global: true
|
|||||||
prefix: '&7&l[&b&lL&a&lP&7&l] &c'
|
prefix: '&7&l[&b&lL&a&lP&7&l] &c'
|
||||||
|
|
||||||
# Which storage method the plugin should use.
|
# Which storage method the plugin should use.
|
||||||
# Currently supported: mysql, sqlite
|
# Currently supported: mysql, sqlite, flatfile
|
||||||
# Fill out connection info below if you're using MySQL
|
# Fill out connection info below if you're using MySQL
|
||||||
storage-method: sqlite
|
storage-method: sqlite
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import lombok.Getter;
|
|||||||
import me.lucko.luckperms.commands.CommandManager;
|
import me.lucko.luckperms.commands.CommandManager;
|
||||||
import me.lucko.luckperms.data.Datastore;
|
import me.lucko.luckperms.data.Datastore;
|
||||||
import me.lucko.luckperms.data.MySQLConfiguration;
|
import me.lucko.luckperms.data.MySQLConfiguration;
|
||||||
|
import me.lucko.luckperms.data.methods.FlatfileDatastore;
|
||||||
import me.lucko.luckperms.data.methods.MySQLDatastore;
|
import me.lucko.luckperms.data.methods.MySQLDatastore;
|
||||||
import me.lucko.luckperms.data.methods.SQLiteDatastore;
|
import me.lucko.luckperms.data.methods.SQLiteDatastore;
|
||||||
import me.lucko.luckperms.groups.GroupManager;
|
import me.lucko.luckperms.groups.GroupManager;
|
||||||
@ -50,6 +51,9 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
|||||||
} else if (storageMethod.equalsIgnoreCase("sqlite")) {
|
} else if (storageMethod.equalsIgnoreCase("sqlite")) {
|
||||||
getLogger().info("Using SQLite as storage method.");
|
getLogger().info("Using SQLite as storage method.");
|
||||||
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
||||||
|
} else if (storageMethod.equalsIgnoreCase("flatfile")) {
|
||||||
|
getLogger().info("Using Flatfile (JSON) as storage method.");
|
||||||
|
datastore = new FlatfileDatastore(this, getDataFolder());
|
||||||
} else {
|
} else {
|
||||||
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
|
getLogger().warning("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback.");
|
||||||
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
datastore = new SQLiteDatastore(this, new File(getDataFolder(), "luckperms.sqlite"));
|
||||||
|
@ -12,7 +12,7 @@ include-global: false
|
|||||||
prefix: '&7&l[&b&lL&a&lP&7&l] &c'
|
prefix: '&7&l[&b&lL&a&lP&7&l] &c'
|
||||||
|
|
||||||
# Which storage method the plugin should use.
|
# Which storage method the plugin should use.
|
||||||
# Currently supported: mysql, sqlite
|
# Currently supported: mysql, sqlite, flatfile
|
||||||
# Fill out connection info below if you're using MySQL
|
# Fill out connection info below if you're using MySQL
|
||||||
storage-method: sqlite
|
storage-method: sqlite
|
||||||
|
|
||||||
|
@ -0,0 +1,425 @@
|
|||||||
|
package me.lucko.luckperms.data.methods;
|
||||||
|
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import me.lucko.luckperms.LuckPermsPlugin;
|
||||||
|
import me.lucko.luckperms.data.Datastore;
|
||||||
|
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
|
||||||
|
import me.lucko.luckperms.groups.Group;
|
||||||
|
import me.lucko.luckperms.users.User;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@SuppressWarnings({"ResultOfMethodCallIgnored", "UnnecessaryLocalVariable"})
|
||||||
|
public class FlatfileDatastore extends Datastore {
|
||||||
|
|
||||||
|
private Map<String, String> uuidCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final File pluginDir;
|
||||||
|
private File usersDir;
|
||||||
|
private File groupsDir;
|
||||||
|
private File uuidData;
|
||||||
|
|
||||||
|
public FlatfileDatastore(LuckPermsPlugin plugin, File pluginDir) {
|
||||||
|
super(plugin, "Flatfile - JSON");
|
||||||
|
this.pluginDir = pluginDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doWrite(File file, WriteOperation writeOperation) {
|
||||||
|
boolean success = false;
|
||||||
|
|
||||||
|
FileWriter fileWriter = null;
|
||||||
|
BufferedWriter bufferedWriter = null;
|
||||||
|
JsonWriter jsonWriter = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fileWriter = new FileWriter(file);
|
||||||
|
bufferedWriter = new BufferedWriter(fileWriter);
|
||||||
|
jsonWriter = new JsonWriter(bufferedWriter);
|
||||||
|
jsonWriter.setIndent(" ");
|
||||||
|
success = writeOperation.onRun(jsonWriter);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
close(jsonWriter);
|
||||||
|
close(bufferedWriter);
|
||||||
|
close(fileWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doRead(File file, ReadOperation readOperation) {
|
||||||
|
boolean success = false;
|
||||||
|
|
||||||
|
FileReader fileReader = null;
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
JsonReader jsonReader = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fileReader = new FileReader(file);
|
||||||
|
bufferedReader = new BufferedReader(fileReader);
|
||||||
|
jsonReader = new JsonReader(bufferedReader);
|
||||||
|
success = readOperation.onRun(jsonReader);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
close(jsonReader);
|
||||||
|
close(bufferedReader);
|
||||||
|
close(fileReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close(AutoCloseable closeable) {
|
||||||
|
if (closeable == null) return;
|
||||||
|
try {
|
||||||
|
closeable.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
try {
|
||||||
|
makeFiles();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO catch here or something
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uuidCache.putAll(getUUIDCache());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeFiles() throws IOException {
|
||||||
|
File data = new File(pluginDir, "data");
|
||||||
|
data.mkdirs();
|
||||||
|
|
||||||
|
usersDir = new File(data, "users");
|
||||||
|
usersDir.mkdir();
|
||||||
|
|
||||||
|
groupsDir = new File(data, "groups");
|
||||||
|
groupsDir.mkdir();
|
||||||
|
|
||||||
|
uuidData = new File(data, "uuidcache.txt");
|
||||||
|
uuidData.createNewFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
|
saveUUIDCache(uuidCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean loadOrCreateUser(UUID uuid, String username) {
|
||||||
|
User user = plugin.getUserManager().makeUser(uuid, username);
|
||||||
|
try {
|
||||||
|
user.setPermission(plugin.getConfiguration().getDefaultGroupNode(), true);
|
||||||
|
} catch (ObjectAlreadyHasException ignored) {}
|
||||||
|
|
||||||
|
File userFile = new File(usersDir, uuid.toString() + ".json");
|
||||||
|
if (!userFile.exists()) {
|
||||||
|
try {
|
||||||
|
userFile.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doWrite(userFile, writer -> {
|
||||||
|
writer.beginObject();
|
||||||
|
writer.name("uuid").value(user.getUuid().toString());
|
||||||
|
writer.name("name").value(user.getName());
|
||||||
|
writer.name("perms");
|
||||||
|
writer.beginObject();
|
||||||
|
for (Map.Entry<String, Boolean> e : user.getNodes().entrySet()) {
|
||||||
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
|
}
|
||||||
|
writer.endObject();
|
||||||
|
writer.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!success) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doRead(userFile, reader -> {
|
||||||
|
reader.beginObject();
|
||||||
|
reader.nextName(); // uuid record
|
||||||
|
reader.nextString(); // uuid
|
||||||
|
reader.nextName(); // name record
|
||||||
|
reader.nextString(); // name
|
||||||
|
reader.nextName(); //perms
|
||||||
|
reader.beginObject();
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
String node = reader.nextName();
|
||||||
|
boolean b = reader.nextBoolean();
|
||||||
|
user.getNodes().put(node, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.endObject();
|
||||||
|
reader.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// User updating and loading should be done sync as permission attachments are updated
|
||||||
|
if (success) plugin.doSync(() -> plugin.getUserManager().updateOrSetUser(user));
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean loadUser(UUID uuid) {
|
||||||
|
User user = plugin.getUserManager().makeUser(uuid);
|
||||||
|
|
||||||
|
File userFile = new File(usersDir, uuid.toString() + ".json");
|
||||||
|
if (!userFile.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doRead(userFile, reader -> {
|
||||||
|
reader.beginObject();
|
||||||
|
reader.nextName(); // uuid record
|
||||||
|
reader.nextString(); // uuid
|
||||||
|
reader.nextName(); // name record
|
||||||
|
user.setName(reader.nextString()); // name
|
||||||
|
reader.nextName(); //perms
|
||||||
|
reader.beginObject();
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
String node = reader.nextName();
|
||||||
|
boolean b = reader.nextBoolean();
|
||||||
|
user.getNodes().put(node, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.endObject();
|
||||||
|
reader.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// User updating and loading should be done sync as permission attachments are updated
|
||||||
|
if (success) plugin.doSync(() -> plugin.getUserManager().updateOrSetUser(user));
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean saveUser(User user) {
|
||||||
|
File userFile = new File(usersDir, user.getUuid().toString() + ".json");
|
||||||
|
if (!userFile.exists()) {
|
||||||
|
try {
|
||||||
|
userFile.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doWrite(userFile, writer -> {
|
||||||
|
writer.beginObject();
|
||||||
|
writer.name("uuid").value(user.getUuid().toString());
|
||||||
|
writer.name("name").value(user.getName());
|
||||||
|
writer.name("perms");
|
||||||
|
writer.beginObject();
|
||||||
|
for (Map.Entry<String, Boolean> e : user.getNodes().entrySet()) {
|
||||||
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
|
}
|
||||||
|
writer.endObject();
|
||||||
|
writer.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean createAndLoadGroup(String name) {
|
||||||
|
Group group = plugin.getGroupManager().makeGroup(name);
|
||||||
|
|
||||||
|
File groupFile = new File(groupsDir, name + ".json");
|
||||||
|
if (!groupFile.exists()) {
|
||||||
|
try {
|
||||||
|
groupFile.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doWrite(groupFile, writer -> {
|
||||||
|
writer.beginObject();
|
||||||
|
writer.name("name").value(group.getName());
|
||||||
|
writer.name("perms");
|
||||||
|
writer.beginObject();
|
||||||
|
for (Map.Entry<String, Boolean> e : group.getNodes().entrySet()) {
|
||||||
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
|
}
|
||||||
|
writer.endObject();
|
||||||
|
writer.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!success) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doRead(groupFile, reader -> {
|
||||||
|
reader.beginObject();
|
||||||
|
reader.nextName(); // name record
|
||||||
|
reader.nextString(); // name
|
||||||
|
reader.nextName(); //perms
|
||||||
|
reader.beginObject();
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
String node = reader.nextName();
|
||||||
|
boolean b = reader.nextBoolean();
|
||||||
|
group.getNodes().put(node, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.endObject();
|
||||||
|
reader.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (success) plugin.getGroupManager().updateOrSetGroup(group);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean loadGroup(String name) {
|
||||||
|
Group group = plugin.getGroupManager().makeGroup(name);
|
||||||
|
|
||||||
|
File groupFile = new File(groupsDir, name + ".json");
|
||||||
|
if (!groupFile.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doRead(groupFile, reader -> {
|
||||||
|
reader.beginObject();
|
||||||
|
reader.nextName(); // name record
|
||||||
|
reader.nextString(); // name
|
||||||
|
reader.nextName(); //perms
|
||||||
|
reader.beginObject();
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
String node = reader.nextName();
|
||||||
|
boolean b = reader.nextBoolean();
|
||||||
|
group.getNodes().put(node, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.endObject();
|
||||||
|
reader.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (success) plugin.getGroupManager().updateOrSetGroup(group);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean loadAllGroups() {
|
||||||
|
List<String> groups = Arrays.asList(groupsDir.list((dir, name1) -> name1.endsWith(".json")));
|
||||||
|
groups.forEach(this::loadGroup);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean saveGroup(Group group) {
|
||||||
|
File groupFile = new File(groupsDir, group.getName() + ".json");
|
||||||
|
if (!groupFile.exists()) {
|
||||||
|
try {
|
||||||
|
groupFile.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = doWrite(groupFile, writer -> {
|
||||||
|
writer.beginObject();
|
||||||
|
writer.name("name").value(group.getName());
|
||||||
|
writer.name("perms");
|
||||||
|
writer.beginObject();
|
||||||
|
for (Map.Entry<String, Boolean> e : group.getNodes().entrySet()) {
|
||||||
|
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||||
|
}
|
||||||
|
writer.endObject();
|
||||||
|
writer.endObject();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteGroup(Group group) {
|
||||||
|
File groupFile = new File(groupsDir, group.getName() + ".json");
|
||||||
|
if (groupFile.exists()) {
|
||||||
|
groupFile.delete();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getUUIDCache() {
|
||||||
|
Map<String, String> cache = new HashMap<>();
|
||||||
|
|
||||||
|
FileReader fileReader = null;
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fileReader = new FileReader(uuidData);
|
||||||
|
bufferedReader = new BufferedReader(fileReader);
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.load(bufferedReader);
|
||||||
|
for (String key : props.stringPropertyNames()) {
|
||||||
|
cache.put(key, props.getProperty(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
close(bufferedReader);
|
||||||
|
close(fileReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveUUIDCache(Map<String, String> cache) {
|
||||||
|
FileWriter fileWriter = null;
|
||||||
|
BufferedWriter bufferedWriter = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fileWriter = new FileWriter(uuidData);
|
||||||
|
bufferedWriter = new BufferedWriter(fileWriter);
|
||||||
|
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.putAll(cache);
|
||||||
|
properties.store(bufferedWriter, null);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
close(bufferedWriter);
|
||||||
|
close(fileWriter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean saveUUIDData(String username, UUID uuid) {
|
||||||
|
uuidCache.put(username, uuid.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID getUUID(String username) {
|
||||||
|
if (uuidCache.get(username) == null) return null;
|
||||||
|
return UUID.fromString(uuidCache.get(username));
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WriteOperation {
|
||||||
|
boolean onRun(JsonWriter writer) throws IOException;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReadOperation {
|
||||||
|
boolean onRun(JsonReader reader) throws IOException;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user