mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2026-01-03 14:22:10 +00:00
added import command
This commit is contained in:
@@ -1,23 +1,25 @@
|
||||
package net.momirealms.customfishing.command.sub;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import dev.jorel.commandapi.CommandAPICommand;
|
||||
import dev.jorel.commandapi.arguments.ArgumentSuggestions;
|
||||
import dev.jorel.commandapi.arguments.StringArgument;
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.data.DataStorageInterface;
|
||||
import net.momirealms.customfishing.api.data.LegacyDataStorageInterface;
|
||||
import net.momirealms.customfishing.api.data.PlayerData;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.storage.method.database.sql.MariaDBImpl;
|
||||
import net.momirealms.customfishing.storage.method.database.sql.MySQLImpl;
|
||||
import net.momirealms.customfishing.storage.method.file.YAMLImpl;
|
||||
import net.momirealms.customfishing.util.CompletableFutures;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -27,6 +29,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class DataCommand {
|
||||
@@ -36,10 +39,13 @@ public class DataCommand {
|
||||
public CommandAPICommand getDataCommand() {
|
||||
return new CommandAPICommand("data")
|
||||
.withSubcommands(
|
||||
getExportLegacyCommand()
|
||||
getExportLegacyCommand(),
|
||||
getExportCommand(),
|
||||
getImportCommand()
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public CommandAPICommand getExportLegacyCommand() {
|
||||
return new CommandAPICommand("export-legacy")
|
||||
.withArguments(new StringArgument("method")
|
||||
@@ -49,6 +55,9 @@ public class DataCommand {
|
||||
if (arg == null) return;
|
||||
CustomFishingPlugin plugin = CustomFishingPlugin.get();
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Starting <aqua>export</aqua>.");
|
||||
|
||||
LegacyDataStorageInterface dataStorageInterface;
|
||||
switch (arg) {
|
||||
case "MySQL" -> dataStorageInterface = new MySQLImpl(plugin);
|
||||
@@ -103,9 +112,143 @@ public class DataCommand {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
plugin.getScheduler().runTaskAsyncLater(dataStorageInterface::disable, 1, TimeUnit.SECONDS);
|
||||
dataStorageInterface.disable();
|
||||
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Finished.");
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Completed.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public CommandAPICommand getExportCommand() {
|
||||
return new CommandAPICommand("export")
|
||||
.executesConsole((sender, args) -> {
|
||||
if (Bukkit.getOnlinePlayers().size() != 0) {
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Please kick all the players before exporting. Otherwise the cache will be inconsistent with data, resulting in the backup file not being up to date.");
|
||||
return;
|
||||
}
|
||||
|
||||
CustomFishingPlugin plugin = CustomFishingPlugin.get();
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Starting <aqua>export</aqua>.");
|
||||
DataStorageInterface dataStorageInterface = plugin.getStorageManager().getDataSource();
|
||||
|
||||
Set<UUID> uuids = dataStorageInterface.getUniqueUsers(true);
|
||||
Set<CompletableFuture<Void>> futures = new HashSet<>();
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
Map<UUID, String> out = Collections.synchronizedMap(new TreeMap<>());
|
||||
|
||||
int amount = uuids.size();
|
||||
for (UUID uuid : uuids) {
|
||||
futures.add(dataStorageInterface.getPlayerData(uuid, false).thenAccept(it -> {
|
||||
if (it.isPresent()) {
|
||||
out.put(uuid, plugin.getStorageManager().toJson(it.get()));
|
||||
userCount.incrementAndGet();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
CompletableFuture<Void> overallFuture = CompletableFutures.allOf(futures);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
overallFuture.get(3, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
} catch (TimeoutException e) {
|
||||
LogUtils.info("Progress: " + userCount.get() + "/" + amount);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
JsonObject outJson = new JsonObject();
|
||||
for (Map.Entry<UUID, String> entry : out.entrySet()) {
|
||||
outJson.addProperty(entry.getKey().toString(), entry.getValue());
|
||||
}
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
|
||||
String formattedDate = formatter.format(new Date());
|
||||
File outFile = new File(plugin.getDataFolder(), "exported-" + formattedDate + ".json.gz");
|
||||
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(Files.newOutputStream(outFile.toPath())), StandardCharsets.UTF_8))) {
|
||||
new GsonBuilder().disableHtmlEscaping().create().toJson(outJson, writer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Completed.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public CommandAPICommand getImportCommand() {
|
||||
return new CommandAPICommand("import")
|
||||
.withArguments(new StringArgument("file"))
|
||||
.executesConsole((sender, args) -> {
|
||||
if (Bukkit.getOnlinePlayers().size() != 0) {
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Please kick all the players before importing. Otherwise the cache will be inconsistent with data.");
|
||||
return;
|
||||
}
|
||||
|
||||
String fileName = (String) args.get("file");
|
||||
if (fileName == null) return;
|
||||
CustomFishingPlugin plugin = CustomFishingPlugin.get();
|
||||
|
||||
File file = new File(plugin.getDataFolder(), fileName);
|
||||
if (!file.exists()) {
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "File not exists.");
|
||||
return;
|
||||
}
|
||||
if (!file.getName().endsWith(".json.gz")) {
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Invalid file.");
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Starting <aqua>import</aqua>.");
|
||||
|
||||
JsonObject data;
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(Files.newInputStream(file.toPath())), StandardCharsets.UTF_8))) {
|
||||
data = new GsonBuilder().disableHtmlEscaping().create().fromJson(reader, JsonObject.class);
|
||||
} catch (IOException e) {
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Error occurred when reading the backup file.");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
DataStorageInterface dataStorageInterface = plugin.getStorageManager().getDataSource();
|
||||
var entrySet = data.entrySet();
|
||||
int amount = entrySet.size();
|
||||
AtomicInteger userCount = new AtomicInteger(0);
|
||||
Set<CompletableFuture<Void>> futures = new HashSet<>();
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : entrySet) {
|
||||
UUID uuid = UUID.fromString(entry.getKey());
|
||||
if (entry.getValue() instanceof JsonPrimitive primitive) {
|
||||
PlayerData playerData = plugin.getStorageManager().fromJson(primitive.getAsString());
|
||||
futures.add(dataStorageInterface.updateOrInsertPlayerData(uuid, playerData, true).thenAccept(it -> userCount.incrementAndGet()));
|
||||
}
|
||||
}
|
||||
|
||||
CompletableFuture<Void> overallFuture = CompletableFutures.allOf(futures);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
overallFuture.get(3, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
} catch (TimeoutException e) {
|
||||
LogUtils.info("Progress: " + userCount.get() + "/" + amount);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, "Completed.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class BagManagerImpl implements BagManager, Listener {
|
||||
|
||||
public void disable() {
|
||||
unload();
|
||||
plugin.getStorageManager().getDataSource().savePlayersData(tempEditMap.values(), true);
|
||||
plugin.getStorageManager().getDataSource().updateManyPlayersData(tempEditMap.values(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -293,7 +293,7 @@ public class MarketManagerImpl implements MarketManager, Listener {
|
||||
if (current.getAmount() <= left) {
|
||||
itemStack.setAmount(itemStack.getAmount() + current.getAmount());
|
||||
current.setAmount(0);
|
||||
return;
|
||||
break;
|
||||
} else {
|
||||
current.setAmount(current.getAmount() - left);
|
||||
itemStack.setAmount(itemStack.getType().getMaxStackSize());
|
||||
@@ -302,7 +302,7 @@ public class MarketManagerImpl implements MarketManager, Listener {
|
||||
} else {
|
||||
gui.getInventory().setItem(slot, current.clone());
|
||||
current.setAmount(0);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package net.momirealms.customfishing.storage;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import net.momirealms.customfishing.CustomFishingPluginImpl;
|
||||
@@ -70,11 +71,13 @@ public class StorageManagerImpl implements StorageManager, Listener {
|
||||
private RedisManager redisManager;
|
||||
private String uniqueID;
|
||||
private CancellableTask timerSaveTask;
|
||||
private Gson gson;
|
||||
|
||||
public StorageManagerImpl(CustomFishingPluginImpl plugin) {
|
||||
this.plugin = plugin;
|
||||
this.locked = new HashSet<>();
|
||||
this.onlineUserMap = new ConcurrentHashMap<>();
|
||||
this.gson = new GsonBuilder().create();
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@@ -113,7 +116,7 @@ public class StorageManagerImpl implements StorageManager, Listener {
|
||||
this.timerSaveTask = this.plugin.getScheduler().runTaskAsyncTimer(
|
||||
() -> {
|
||||
long time1 = System.currentTimeMillis();
|
||||
this.dataSource.savePlayersData(this.onlineUserMap.values(), !CFConfig.lockData);
|
||||
this.dataSource.updateManyPlayersData(this.onlineUserMap.values(), !CFConfig.lockData);
|
||||
LogUtils.info("Data Saved for online players. Took " + (System.currentTimeMillis() - time1) + "ms.");
|
||||
},
|
||||
CFConfig.dataSaveInterval,
|
||||
@@ -124,7 +127,7 @@ public class StorageManagerImpl implements StorageManager, Listener {
|
||||
|
||||
public void disable() {
|
||||
HandlerList.unregisterAll(this);
|
||||
this.dataSource.savePlayersData(onlineUserMap.values(), true);
|
||||
this.dataSource.updateManyPlayersData(onlineUserMap.values(), true);
|
||||
this.onlineUserMap.clear();
|
||||
if (this.dataSource != null)
|
||||
this.dataSource.disable();
|
||||
@@ -162,7 +165,7 @@ public class StorageManagerImpl implements StorageManager, Listener {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> saveUserData(OfflineUser offlineUser, boolean unlock) {
|
||||
return dataSource.savePlayerData(offlineUser.getUUID(), offlineUser.getPlayerData(), unlock);
|
||||
return dataSource.updatePlayerData(offlineUser.getUUID(), offlineUser.getPlayerData(), unlock);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,13 +203,13 @@ public class StorageManagerImpl implements StorageManager, Listener {
|
||||
|
||||
if (hasRedis) {
|
||||
redisManager.setChangeServer(uuid).thenRun(
|
||||
() -> redisManager.savePlayerData(uuid, data, true).thenRun(
|
||||
() -> dataSource.savePlayerData(uuid, data, true).thenAccept(
|
||||
() -> redisManager.updatePlayerData(uuid, data, true).thenRun(
|
||||
() -> dataSource.updatePlayerData(uuid, data, true).thenAccept(
|
||||
result -> {
|
||||
if (result) locked.remove(uuid);
|
||||
})));
|
||||
} else {
|
||||
dataSource.savePlayerData(uuid, data, true).thenAccept(
|
||||
dataSource.updatePlayerData(uuid, data, true).thenAccept(
|
||||
result -> {
|
||||
if (result) locked.remove(uuid);
|
||||
});
|
||||
@@ -302,14 +305,19 @@ public class StorageManagerImpl implements StorageManager, Listener {
|
||||
@Override
|
||||
@NotNull
|
||||
public String toJson(@NotNull PlayerData data) {
|
||||
return new GsonBuilder().create().toJson(data);
|
||||
return gson.toJson(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerData fromJson(String json) {
|
||||
return gson.fromJson(json, PlayerData.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PlayerData fromBytes(byte[] data) {
|
||||
try {
|
||||
return new GsonBuilder().create().fromJson(new String(data, StandardCharsets.UTF_8), PlayerData.class);
|
||||
return gson.fromJson(new String(data, StandardCharsets.UTF_8), PlayerData.class);
|
||||
} catch (JsonSyntaxException e) {
|
||||
throw new DataSerializationException("Failed to get PlayerData from bytes", e);
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@ package net.momirealms.customfishing.storage.method;
|
||||
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.data.DataStorageInterface;
|
||||
import net.momirealms.customfishing.api.data.PlayerData;
|
||||
import net.momirealms.customfishing.api.data.user.OfflineUser;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class AbstractStorage implements DataStorageInterface {
|
||||
|
||||
@@ -48,13 +50,18 @@ public abstract class AbstractStorage implements DataStorageInterface {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void savePlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
public void updateManyPlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
for (OfflineUser user : users) {
|
||||
this.savePlayerData(user.getUUID(), user.getPlayerData(), unlock);
|
||||
this.updatePlayerData(user.getUUID(), user.getPlayerData(), unlock);
|
||||
}
|
||||
}
|
||||
|
||||
public void lockPlayerData(UUID uuid, boolean lock) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> updateOrInsertPlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
return updatePlayerData(uuid, playerData, unlock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public class MongoDBImpl extends AbstractStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> savePlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
public CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
var future = new CompletableFuture<Boolean>();
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
MongoCollection<Document> collection = database.getCollection(getCollectionName("data"));
|
||||
@@ -150,7 +150,7 @@ public class MongoDBImpl extends AbstractStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void savePlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
public void updateManyPlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
MongoCollection<Document> collection = database.getCollection(getCollectionName("data"));
|
||||
try {
|
||||
int lock = unlock ? 0 : getCurrentSeconds();
|
||||
|
||||
@@ -251,7 +251,7 @@ public class RedisManager extends AbstractStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> savePlayerData(UUID uuid, PlayerData playerData, boolean ignore) {
|
||||
public CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData, boolean ignore) {
|
||||
var future = new CompletableFuture<Boolean>();
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
try (Jedis jedis = jedisPool.getResource()) {
|
||||
|
||||
@@ -116,7 +116,7 @@ public abstract class AbstractSQLDatabase extends AbstractStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> savePlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
public CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
var future = new CompletableFuture<Boolean>();
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
try (
|
||||
@@ -138,7 +138,7 @@ public abstract class AbstractSQLDatabase extends AbstractStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void savePlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
public void updateManyPlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
String sql = String.format(SqlConstants.SQL_UPDATE_BY_UUID, getTableName("data"));
|
||||
try (Connection connection = getConnection()) {
|
||||
connection.setAutoCommit(false);
|
||||
@@ -188,6 +188,29 @@ public abstract class AbstractSQLDatabase extends AbstractStorage {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> updateOrInsertPlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
var future = new CompletableFuture<Boolean>();
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
try (
|
||||
Connection connection = getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(String.format(SqlConstants.SQL_SELECT_BY_UUID, getTableName("data")))
|
||||
) {
|
||||
statement.setString(1, uuid.toString());
|
||||
ResultSet rs = statement.executeQuery();
|
||||
if (rs.next()) {
|
||||
updatePlayerData(uuid, playerData, unlock).thenRun(() -> future.complete(true));
|
||||
} else {
|
||||
insertPlayerData(uuid, playerData, !unlock);
|
||||
future.complete(true);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogUtils.warn("Failed to get " + uuid + "'s data.", e);
|
||||
}
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getUniqueUsers(boolean legacy) {
|
||||
Set<UUID> uuids = new HashSet<>();
|
||||
|
||||
@@ -112,7 +112,7 @@ public class SQLiteImpl extends AbstractSQLDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> savePlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
public CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData, boolean unlock) {
|
||||
var future = new CompletableFuture<Boolean>();
|
||||
plugin.getScheduler().runTaskAsync(() -> {
|
||||
try (
|
||||
@@ -133,7 +133,7 @@ public class SQLiteImpl extends AbstractSQLDatabase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void savePlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
public void updateManyPlayersData(Collection<? extends OfflineUser> users, boolean unlock) {
|
||||
String sql = String.format(SqlConstants.SQL_UPDATE_BY_UUID, getTableName("data"));
|
||||
try (Connection connection = getConnection()) {
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class JsonImpl extends AbstractStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> savePlayerData(UUID uuid, PlayerData playerData, boolean ignore) {
|
||||
public CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData, boolean ignore) {
|
||||
this.saveToJsonFile(playerData, getPlayerDataFile(uuid));
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class YAMLImpl extends AbstractStorage implements LegacyDataStorageInterf
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> savePlayerData(UUID uuid, PlayerData playerData, boolean ignore) {
|
||||
public CompletableFuture<Boolean> updatePlayerData(UUID uuid, PlayerData playerData, boolean ignore) {
|
||||
YamlConfiguration data = new YamlConfiguration();
|
||||
data.set("name", playerData.getName());
|
||||
data.set("bag", playerData.getBagData().serialized);
|
||||
|
||||
@@ -116,6 +116,16 @@ rubbish:
|
||||
disable-game: true
|
||||
instant-game: false
|
||||
prevent-grabbing: false
|
||||
rainbow_fish:
|
||||
material: cod
|
||||
nick: <Rainbow>Rainbow Fish</Rainbow>
|
||||
display:
|
||||
name: <Rainbow>Rainbow Fish</Rainbow>
|
||||
lore:
|
||||
- <gray>Bringing a good mood for the day
|
||||
custom-model-data: 50100
|
||||
price:
|
||||
base: 100
|
||||
# Enchantments
|
||||
sharpness_book:
|
||||
tag: false
|
||||
|
||||
@@ -80,6 +80,7 @@ global-group:
|
||||
- minecraft:warm_ocean
|
||||
list:
|
||||
- vanilla:+30
|
||||
- rainbow_fish:+5
|
||||
- stick:+15
|
||||
- gold_fish:+15
|
||||
- gold_fish_silver_star:+3
|
||||
|
||||
Reference in New Issue
Block a user