mirror of
https://github.com/BG-Software-LLC/WildLoaders.git
synced 2024-11-21 11:46:46 +01:00
Implemented a database for chunk busters & npcs
This commit is contained in:
parent
50d0f2b85a
commit
689f049a8b
@ -2,6 +2,7 @@ package com.bgsoftware.wildloaders;
|
|||||||
|
|
||||||
import com.bgsoftware.wildloaders.api.WildLoaders;
|
import com.bgsoftware.wildloaders.api.WildLoaders;
|
||||||
import com.bgsoftware.wildloaders.command.CommandsHandler;
|
import com.bgsoftware.wildloaders.command.CommandsHandler;
|
||||||
|
import com.bgsoftware.wildloaders.handlers.DataHandler;
|
||||||
import com.bgsoftware.wildloaders.handlers.LoadersHandler;
|
import com.bgsoftware.wildloaders.handlers.LoadersHandler;
|
||||||
import com.bgsoftware.wildloaders.handlers.NPCHandler;
|
import com.bgsoftware.wildloaders.handlers.NPCHandler;
|
||||||
import com.bgsoftware.wildloaders.handlers.SettingsHandler;
|
import com.bgsoftware.wildloaders.handlers.SettingsHandler;
|
||||||
@ -18,6 +19,7 @@ public final class WildLoadersPlugin extends JavaPlugin implements WildLoaders {
|
|||||||
private SettingsHandler settingsHandler;
|
private SettingsHandler settingsHandler;
|
||||||
private LoadersHandler loadersHandler;
|
private LoadersHandler loadersHandler;
|
||||||
private NPCHandler npcHandler;
|
private NPCHandler npcHandler;
|
||||||
|
private DataHandler dataHandler;
|
||||||
|
|
||||||
private NMSAdapter nmsAdapter;
|
private NMSAdapter nmsAdapter;
|
||||||
|
|
||||||
@ -30,6 +32,7 @@ public final class WildLoadersPlugin extends JavaPlugin implements WildLoaders {
|
|||||||
|
|
||||||
loadNMSAdapter();
|
loadNMSAdapter();
|
||||||
|
|
||||||
|
dataHandler = new DataHandler(this);
|
||||||
loadersHandler = new LoadersHandler(this);
|
loadersHandler = new LoadersHandler(this);
|
||||||
npcHandler = new NPCHandler(this);
|
npcHandler = new NPCHandler(this);
|
||||||
settingsHandler = new SettingsHandler(this);
|
settingsHandler = new SettingsHandler(this);
|
||||||
@ -55,6 +58,7 @@ public final class WildLoadersPlugin extends JavaPlugin implements WildLoaders {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
dataHandler.saveDatabase();
|
||||||
loadersHandler.removeChunkLoaders();
|
loadersHandler.removeChunkLoaders();
|
||||||
npcHandler.killAllNPCs();
|
npcHandler.killAllNPCs();
|
||||||
}
|
}
|
||||||
@ -86,6 +90,10 @@ public final class WildLoadersPlugin extends JavaPlugin implements WildLoaders {
|
|||||||
return nmsAdapter;
|
return nmsAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataHandler getDataHandler() {
|
||||||
|
return dataHandler;
|
||||||
|
}
|
||||||
|
|
||||||
public static void log(String message){
|
public static void log(String message){
|
||||||
plugin.getLogger().info(message);
|
plugin.getLogger().info(message);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.bgsoftware.wildloaders.command;
|
|||||||
import com.bgsoftware.wildloaders.Locale;
|
import com.bgsoftware.wildloaders.Locale;
|
||||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||||
import com.bgsoftware.wildloaders.command.commands.CmdGive;
|
import com.bgsoftware.wildloaders.command.commands.CmdGive;
|
||||||
|
import com.bgsoftware.wildloaders.command.commands.CmdSave;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabCompleter;
|
import org.bukkit.command.TabCompleter;
|
||||||
@ -18,6 +19,7 @@ public final class CommandsHandler implements CommandExecutor, TabCompleter {
|
|||||||
public CommandsHandler(WildLoadersPlugin plugin){
|
public CommandsHandler(WildLoadersPlugin plugin){
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
subCommands.add(new CmdGive());
|
subCommands.add(new CmdGive());
|
||||||
|
subCommands.add(new CmdSave());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.bgsoftware.wildloaders.command.commands;
|
||||||
|
|
||||||
|
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||||
|
import com.bgsoftware.wildloaders.command.ICommand;
|
||||||
|
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class CmdSave implements ICommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return "save";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "loader save";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPermission() {
|
||||||
|
return "wildloaders.save";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Save all the chunk-loaders into the database.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinArgs() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxArgs() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform(WildLoadersPlugin plugin, CommandSender sender, String[] args) {
|
||||||
|
Executor.data(() -> {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "Saving all chunk loaders...");
|
||||||
|
plugin.getDataHandler().saveDatabase();
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "Saving chunk loaders done! (Took " + (System.currentTimeMillis() - startTime) + "ms)");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> tabComplete(WildLoadersPlugin plugin, CommandSender sender, String[] args) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
package com.bgsoftware.wildloaders.handlers;
|
||||||
|
|
||||||
|
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||||
|
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||||
|
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
|
||||||
|
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||||
|
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
|
||||||
|
import com.bgsoftware.wildloaders.npc.NPCIdentifier;
|
||||||
|
import com.bgsoftware.wildloaders.utils.database.Query;
|
||||||
|
import com.bgsoftware.wildloaders.utils.database.SQLHelper;
|
||||||
|
import com.bgsoftware.wildloaders.utils.database.StatementHolder;
|
||||||
|
import com.bgsoftware.wildloaders.utils.locations.LocationUtils;
|
||||||
|
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public final class DataHandler {
|
||||||
|
|
||||||
|
private final WildLoadersPlugin plugin;
|
||||||
|
|
||||||
|
public DataHandler(WildLoadersPlugin plugin){
|
||||||
|
this.plugin = plugin;
|
||||||
|
Executor.sync(() -> {
|
||||||
|
try {
|
||||||
|
SQLHelper.init(new File(plugin.getDataFolder(), "database.db"));
|
||||||
|
loadDatabase();
|
||||||
|
}catch (Exception ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
Bukkit.getPluginManager().disablePlugin(plugin);
|
||||||
|
}
|
||||||
|
}, 2L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadDatabase(){
|
||||||
|
SQLHelper.executeUpdate("CREATE TABLE IF NOT EXISTS npc_identifiers (location TEXT NOT NULL PRIMARY KEY, uuid TEXT NOT NULL);");
|
||||||
|
SQLHelper.executeQuery("SELECT * FROM npc_identifiers;", resultSet -> {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
Location location = LocationUtils.getLocation(resultSet.getString("location"));
|
||||||
|
UUID uuid = UUID.fromString(resultSet.getString("uuid"));
|
||||||
|
plugin.getNPCs().registerUUID(location, uuid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SQLHelper.executeUpdate("CREATE TABLE IF NOT EXISTS chunk_loaders (location TEXT NOT NULL PRIMARY KEY, placer TEXT NOT NULL, loader_data TEXT NOT NULL, timeLeft BIGINT NOT NULL);");
|
||||||
|
SQLHelper.executeQuery("SELECT * FROM chunk_loaders;", resultSet -> {
|
||||||
|
while(resultSet.next()){
|
||||||
|
Location location = LocationUtils.getLocation(resultSet.getString("location"));
|
||||||
|
UUID placer = UUID.fromString(resultSet.getString("placer"));
|
||||||
|
Optional<LoaderData> loaderData = plugin.getLoaders().getLoaderData(resultSet.getString("loader_data"));
|
||||||
|
long timeLeft = resultSet.getLong("timeLeft");
|
||||||
|
|
||||||
|
if(!loaderData.isPresent())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(location.getBlock().getType() != loaderData.get().getLoaderItem().getType()){
|
||||||
|
WildLoadersPlugin.log("The chunk-loader at " + LocationUtils.getLocation(location) + " is invalid.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.getLoaders().addChunkLoader(loaderData.get(), placer, location, timeLeft);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveDatabase(){
|
||||||
|
List<ChunkLoader> chunkLoaderList = plugin.getLoaders().getChunkLoaders();
|
||||||
|
Map<NPCIdentifier, ChunkLoaderNPC> chunkLoaderNPCList = plugin.getNPCs().getNPCs();
|
||||||
|
|
||||||
|
{
|
||||||
|
StatementHolder chunkLoadersHolder = Query.INSERT_CHUNK_LOADER.getStatementHolder();
|
||||||
|
chunkLoadersHolder.prepareBatch();
|
||||||
|
chunkLoaderList.stream().filter(chunkLoader -> chunkLoader.getTimeLeft() > 0).forEach(chunkLoader ->
|
||||||
|
((WChunkLoader) chunkLoader).updateInsertStatement(chunkLoadersHolder).addBatch());
|
||||||
|
chunkLoadersHolder.execute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StatementHolder chunkLoadersHolder = Query.DELETE_CHUNK_LOADER.getStatementHolder();
|
||||||
|
chunkLoadersHolder.prepareBatch();
|
||||||
|
chunkLoaderList.stream().filter(chunkLoader -> chunkLoader.getTimeLeft() <= 0).forEach(chunkLoader ->
|
||||||
|
chunkLoadersHolder.setLocation(chunkLoader.getLocation()).addBatch());
|
||||||
|
chunkLoadersHolder.execute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StatementHolder npcIdentifierHolder = Query.INSERT_NPC_IDENTIFIER.getStatementHolder();
|
||||||
|
npcIdentifierHolder.prepareBatch();
|
||||||
|
chunkLoaderNPCList.forEach((identifier, npc) -> npcIdentifierHolder
|
||||||
|
.setLocation(identifier.getSpawnLocation()).setString(npc.getUniqueId().toString()).addBatch());
|
||||||
|
npcIdentifierHolder.execute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveChunkLoadersTimes(){
|
||||||
|
List<ChunkLoader> chunkLoaderList = plugin.getLoaders().getChunkLoaders();
|
||||||
|
|
||||||
|
{
|
||||||
|
StatementHolder chunkLoadersHolder = Query.UPDATE_CHUNK_LOADER_TIME_LEFT.getStatementHolder();
|
||||||
|
chunkLoadersHolder.prepareBatch();
|
||||||
|
chunkLoaderList.stream().filter(chunkLoader -> chunkLoader.getTimeLeft() > 0).forEach(chunkLoader ->
|
||||||
|
chunkLoadersHolder.setLong(chunkLoader.getTimeLeft()).setLocation(chunkLoader.getLocation()).addBatch());
|
||||||
|
chunkLoadersHolder.execute(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StatementHolder chunkLoadersHolder = Query.DELETE_CHUNK_LOADER.getStatementHolder();
|
||||||
|
chunkLoadersHolder.prepareBatch();
|
||||||
|
chunkLoaderList.stream().filter(chunkLoader -> chunkLoader.getTimeLeft() <= 0).forEach(chunkLoader ->
|
||||||
|
chunkLoadersHolder.setLocation(chunkLoader.getLocation()).addBatch());
|
||||||
|
chunkLoadersHolder.execute(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -7,7 +7,9 @@ import com.bgsoftware.wildloaders.api.loaders.LoaderData;
|
|||||||
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
|
import com.bgsoftware.wildloaders.loaders.WChunkLoader;
|
||||||
import com.bgsoftware.wildloaders.loaders.WLoaderData;
|
import com.bgsoftware.wildloaders.loaders.WLoaderData;
|
||||||
import com.bgsoftware.wildloaders.utils.chunks.ChunkPosition;
|
import com.bgsoftware.wildloaders.utils.chunks.ChunkPosition;
|
||||||
|
import com.bgsoftware.wildloaders.utils.database.Query;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -18,9 +20,12 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public final class LoadersHandler implements LoadersManager {
|
public final class LoadersHandler implements LoadersManager {
|
||||||
|
|
||||||
|
private static final long TIMERS_UPDATE_INTERVAL = 300L;
|
||||||
|
|
||||||
private final Map<Location, ChunkLoader> chunkLoaders = Maps.newConcurrentMap();
|
private final Map<Location, ChunkLoader> chunkLoaders = Maps.newConcurrentMap();
|
||||||
private final Map<ChunkPosition, ChunkLoader> chunkLoadersByChunks = Maps.newConcurrentMap();
|
private final Map<ChunkPosition, ChunkLoader> chunkLoadersByChunks = Maps.newConcurrentMap();
|
||||||
private final Map<String, LoaderData> loadersData = Maps.newConcurrentMap();
|
private final Map<String, LoaderData> loadersData = Maps.newConcurrentMap();
|
||||||
@ -28,6 +33,8 @@ public final class LoadersHandler implements LoadersManager {
|
|||||||
|
|
||||||
public LoadersHandler(WildLoadersPlugin plugin){
|
public LoadersHandler(WildLoadersPlugin plugin){
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskTimer(plugin, plugin.getDataHandler()::saveChunkLoadersTimes, TIMERS_UPDATE_INTERVAL, TIMERS_UPDATE_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,10 +64,17 @@ public final class LoadersHandler implements LoadersManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChunkLoader addChunkLoader(LoaderData loaderData, Player whoPlaced, Location location, long timeLeft) {
|
public ChunkLoader addChunkLoader(LoaderData loaderData, Player whoPlaced, Location location, long timeLeft) {
|
||||||
ChunkLoader chunkLoader = new WChunkLoader(loaderData.getName(), whoPlaced, location, timeLeft);
|
WChunkLoader chunkLoader = addChunkLoader(loaderData, whoPlaced.getUniqueId(), location, timeLeft);
|
||||||
|
chunkLoader.updateInsertStatement(Query.INSERT_CHUNK_LOADER.getStatementHolder()).execute(true);
|
||||||
|
return chunkLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WChunkLoader addChunkLoader(LoaderData loaderData, UUID placer, Location location, long timeLeft){
|
||||||
|
WChunkLoader chunkLoader = new WChunkLoader(loaderData.getName(), placer, location, timeLeft);
|
||||||
chunkLoaders.put(location, chunkLoader);
|
chunkLoaders.put(location, chunkLoader);
|
||||||
chunkLoadersByChunks.put(ChunkPosition.of(location), chunkLoader);
|
chunkLoadersByChunks.put(ChunkPosition.of(location), chunkLoader);
|
||||||
plugin.getNPCs().createNPC(location);
|
plugin.getNPCs().createNPC(location);
|
||||||
|
System.out.println("Adding chunk loader for " + location);
|
||||||
return chunkLoader;
|
return chunkLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +84,10 @@ public final class LoadersHandler implements LoadersManager {
|
|||||||
chunkLoaders.remove(location);
|
chunkLoaders.remove(location);
|
||||||
chunkLoadersByChunks.remove(ChunkPosition.of(location));
|
chunkLoadersByChunks.remove(ChunkPosition.of(location));
|
||||||
chunkLoader.getNPC().ifPresent(npc -> plugin.getNPCs().killNPC(npc));
|
chunkLoader.getNPC().ifPresent(npc -> plugin.getNPCs().killNPC(npc));
|
||||||
|
|
||||||
|
Query.DELETE_CHUNK_LOADER.getStatementHolder()
|
||||||
|
.setLocation(location)
|
||||||
|
.execute(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -85,6 +103,7 @@ public final class LoadersHandler implements LoadersManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeChunkLoaders() {
|
public void removeChunkLoaders() {
|
||||||
|
chunkLoaders.values().forEach(chunkLoader -> plugin.getNMSAdapter().removeLoader(chunkLoader, false));
|
||||||
chunkLoaders.clear();
|
chunkLoaders.clear();
|
||||||
chunkLoadersByChunks.clear();
|
chunkLoadersByChunks.clear();
|
||||||
}
|
}
|
||||||
|
@ -3,19 +3,15 @@ package com.bgsoftware.wildloaders.handlers;
|
|||||||
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||||
import com.bgsoftware.wildloaders.api.managers.NPCManager;
|
import com.bgsoftware.wildloaders.api.managers.NPCManager;
|
||||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||||
|
import com.bgsoftware.wildloaders.npc.NPCIdentifier;
|
||||||
import com.bgsoftware.wildloaders.utils.ServerVersion;
|
import com.bgsoftware.wildloaders.utils.ServerVersion;
|
||||||
import com.bgsoftware.wildloaders.utils.locations.LocationUtils;
|
import com.bgsoftware.wildloaders.utils.database.Query;
|
||||||
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
|
||||||
import java.io.File;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -29,7 +25,6 @@ public final class NPCHandler implements NPCManager {
|
|||||||
|
|
||||||
public NPCHandler(WildLoadersPlugin plugin){
|
public NPCHandler(WildLoadersPlugin plugin){
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
loadUUIDs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -55,7 +50,10 @@ public final class NPCHandler implements NPCManager {
|
|||||||
npcs.remove(identifier);
|
npcs.remove(identifier);
|
||||||
|
|
||||||
npcUUIDs.remove(identifier);
|
npcUUIDs.remove(identifier);
|
||||||
saveUUIDs();
|
|
||||||
|
Query.DELETE_NPC_IDENTIFIER.getStatementHolder()
|
||||||
|
.setLocation(identifier.getSpawnLocation())
|
||||||
|
.execute(true);
|
||||||
|
|
||||||
npc.die();
|
npc.die();
|
||||||
}
|
}
|
||||||
@ -70,20 +68,12 @@ public final class NPCHandler implements NPCManager {
|
|||||||
npcs.clear();
|
npcs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadUUIDs(){
|
public Map<NPCIdentifier, ChunkLoaderNPC> getNPCs() {
|
||||||
File file = new File(plugin.getDataFolder(), "uuids.yml");
|
return Collections.unmodifiableMap(npcs);
|
||||||
|
}
|
||||||
|
|
||||||
if(!file.exists())
|
public void registerUUID(Location location, UUID uuid){
|
||||||
return;
|
npcUUIDs.put(new NPCIdentifier(location), uuid);
|
||||||
|
|
||||||
YamlConfiguration cfg = YamlConfiguration.loadConfiguration(file);
|
|
||||||
|
|
||||||
for(String location : cfg.getConfigurationSection("").getKeys(false)){
|
|
||||||
try{
|
|
||||||
Location _location = LocationUtils.getLocation(location);
|
|
||||||
npcUUIDs.put(new NPCIdentifier(_location), UUID.fromString(cfg.getString(location)));
|
|
||||||
}catch(Exception ignored){}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID getUUID(NPCIdentifier identifier){
|
private UUID getUUID(NPCIdentifier identifier){
|
||||||
@ -98,67 +88,12 @@ public final class NPCHandler implements NPCManager {
|
|||||||
|
|
||||||
npcUUIDs.put(identifier, uuid);
|
npcUUIDs.put(identifier, uuid);
|
||||||
|
|
||||||
saveUUIDs();
|
Query.INSERT_NPC_IDENTIFIER.getStatementHolder()
|
||||||
|
.setLocation(identifier.getSpawnLocation())
|
||||||
|
.setString(uuid.toString())
|
||||||
|
.execute(true);
|
||||||
|
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
|
||||||
private void saveUUIDs(){
|
|
||||||
if(Bukkit.isPrimaryThread()){
|
|
||||||
Executor.async(this::saveUUIDs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File file = new File(plugin.getDataFolder(), "uuids.yml");
|
|
||||||
|
|
||||||
if(!file.exists())
|
|
||||||
file.delete();
|
|
||||||
|
|
||||||
YamlConfiguration cfg = new YamlConfiguration();
|
|
||||||
|
|
||||||
for(Map.Entry<NPCIdentifier, UUID> entry : npcUUIDs.entrySet())
|
|
||||||
cfg.set(LocationUtils.getLocation(entry.getKey().getSpawnLocation()), entry.getValue() + "");
|
|
||||||
|
|
||||||
try{
|
|
||||||
file.getParentFile().mkdirs();
|
|
||||||
file.createNewFile();
|
|
||||||
cfg.save(file);
|
|
||||||
}catch(Exception ex){
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class NPCIdentifier{
|
|
||||||
|
|
||||||
private final Object identifier;
|
|
||||||
|
|
||||||
NPCIdentifier(Location location){
|
|
||||||
this.identifier = PER_WORLD_NPCS ? location.getWorld() : location;
|
|
||||||
}
|
|
||||||
|
|
||||||
Location getSpawnLocation(){
|
|
||||||
return PER_WORLD_NPCS ? ((World) identifier).getSpawnLocation() : (Location) identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return PER_WORLD_NPCS ? ((World) identifier).getName() : identifier.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
NPCIdentifier that = (NPCIdentifier) o;
|
|
||||||
return Objects.equals(identifier, that.identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
|||||||
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
import com.bgsoftware.wildloaders.api.loaders.ChunkLoader;
|
||||||
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
|
import com.bgsoftware.wildloaders.api.loaders.LoaderData;
|
||||||
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
import com.bgsoftware.wildloaders.api.npc.ChunkLoaderNPC;
|
||||||
|
import com.bgsoftware.wildloaders.utils.database.StatementHolder;
|
||||||
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -26,9 +26,9 @@ public final class WChunkLoader implements ChunkLoader {
|
|||||||
private boolean active = true;
|
private boolean active = true;
|
||||||
private long timeLeft;
|
private long timeLeft;
|
||||||
|
|
||||||
public WChunkLoader(String loaderName, Player whoPlaced, Location location, long timeLeft){
|
public WChunkLoader(String loaderName, UUID whoPlaced, Location location, long timeLeft){
|
||||||
this.loaderName = loaderName;
|
this.loaderName = loaderName;
|
||||||
this.whoPlaced = whoPlaced.getUniqueId();
|
this.whoPlaced = whoPlaced;
|
||||||
this.location = location.clone();
|
this.location = location.clone();
|
||||||
this.timeLeft = timeLeft;
|
this.timeLeft = timeLeft;
|
||||||
plugin.getNMSAdapter().createLoader(this);
|
plugin.getNMSAdapter().createLoader(this);
|
||||||
@ -91,4 +91,13 @@ public final class WChunkLoader implements ChunkLoader {
|
|||||||
return plugin.getNMSAdapter().setTag(itemStack, "loader-time", getTimeLeft());
|
return plugin.getNMSAdapter().setTag(itemStack, "loader-time", getTimeLeft());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public StatementHolder updateInsertStatement(StatementHolder statementHolder){
|
||||||
|
statementHolder.setLocation(getLocation())
|
||||||
|
.setString(whoPlaced.toString())
|
||||||
|
.setString(getLoaderData().getName())
|
||||||
|
.setLong(getTimeLeft());
|
||||||
|
|
||||||
|
return statementHolder;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.bgsoftware.wildloaders.npc;
|
||||||
|
|
||||||
|
import com.bgsoftware.wildloaders.utils.ServerVersion;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class NPCIdentifier {
|
||||||
|
|
||||||
|
private static final boolean PER_WORLD_NPCS = ServerVersion.isLessThan(ServerVersion.v1_14);
|
||||||
|
|
||||||
|
private final Object identifier;
|
||||||
|
|
||||||
|
public NPCIdentifier(Location location){
|
||||||
|
this.identifier = PER_WORLD_NPCS ? location.getWorld() : location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getSpawnLocation(){
|
||||||
|
return PER_WORLD_NPCS ? new Location((World) identifier, 0, 1, 0) : (Location) identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return PER_WORLD_NPCS ? ((World) identifier).getName() : identifier.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
NPCIdentifier that = (NPCIdentifier) o;
|
||||||
|
return Objects.equals(identifier, that.identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.bgsoftware.wildloaders.utils.database;
|
||||||
|
|
||||||
|
public enum Query {
|
||||||
|
|
||||||
|
UPDATE_CHUNK_LOADER_TIME_LEFT("UPDATE chunk_loaders SET timeLeft=? WHERE location=?;"),
|
||||||
|
INSERT_CHUNK_LOADER("REPLACE INTO chunk_loaders(location, placer, loader_data, timeLeft) VALUES(?,?,?,?);"),
|
||||||
|
DELETE_CHUNK_LOADER("DELETE FROM chunk_loaders WHERE location=?;"),
|
||||||
|
|
||||||
|
INSERT_NPC_IDENTIFIER("REPLACE INTO npc_identifiers(location, uuid) VALUES(?,?);"),
|
||||||
|
DELETE_NPC_IDENTIFIER("DELETE FROM npc_identifiers WHERE location=?;");
|
||||||
|
|
||||||
|
private final String query;
|
||||||
|
|
||||||
|
Query(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatement(){
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementHolder getStatementHolder(){
|
||||||
|
return new StatementHolder(this);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.bgsoftware.wildloaders.utils.database;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public final class SQLHelper {
|
||||||
|
|
||||||
|
private static final Object mutex = new Object();
|
||||||
|
private static Connection conn;
|
||||||
|
|
||||||
|
private SQLHelper(){}
|
||||||
|
|
||||||
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
|
public static void init(File file) throws ClassNotFoundException, SQLException {
|
||||||
|
if(!file.exists()){
|
||||||
|
try {
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
file.createNewFile();
|
||||||
|
}catch(Exception ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Class.forName("org.sqlite.JDBC");
|
||||||
|
String sqlURL = "jdbc:sqlite:" + file.getAbsolutePath().replace("\\", "/");
|
||||||
|
conn = DriverManager.getConnection(sqlURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getMutex(){
|
||||||
|
return mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void executeUpdate(String statement){
|
||||||
|
try(PreparedStatement preparedStatement = conn.prepareStatement(statement)){
|
||||||
|
preparedStatement.executeUpdate();
|
||||||
|
}catch(SQLException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean doesConditionExist(StatementHolder statementHolder){
|
||||||
|
boolean ret = false;
|
||||||
|
|
||||||
|
try(PreparedStatement preparedStatement = statementHolder.getStatement(); ResultSet resultSet = preparedStatement.executeQuery()){
|
||||||
|
ret = resultSet.next();
|
||||||
|
}catch(SQLException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void executeQuery(String statement, QueryCallback callback){
|
||||||
|
executeQuery(statement, callback, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void executeQuery(String statement, QueryCallback callback, Consumer<SQLException> onFailure){
|
||||||
|
try(PreparedStatement preparedStatement = conn.prepareStatement(statement); ResultSet resultSet = preparedStatement.executeQuery()){
|
||||||
|
callback.run(resultSet);
|
||||||
|
}catch(SQLException ex){
|
||||||
|
if(onFailure == null)
|
||||||
|
ex.printStackTrace();
|
||||||
|
else
|
||||||
|
onFailure.accept(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAutoCommit(boolean autoCommit){
|
||||||
|
try {
|
||||||
|
conn.setAutoCommit(autoCommit);
|
||||||
|
}catch(SQLException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void commit(){
|
||||||
|
try {
|
||||||
|
conn.commit();
|
||||||
|
}catch(SQLException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(){
|
||||||
|
try{
|
||||||
|
conn.close();
|
||||||
|
}catch(SQLException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PreparedStatement buildStatement(String query) throws SQLException {
|
||||||
|
return conn.prepareStatement(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface QueryCallback{
|
||||||
|
|
||||||
|
void run(ResultSet resultSet) throws SQLException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
|||||||
|
package com.bgsoftware.wildloaders.utils.database;
|
||||||
|
|
||||||
|
import com.bgsoftware.wildloaders.WildLoadersPlugin;
|
||||||
|
import com.bgsoftware.wildloaders.utils.locations.LocationUtils;
|
||||||
|
import com.bgsoftware.wildloaders.utils.threads.Executor;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public class StatementHolder {
|
||||||
|
|
||||||
|
private final List<Map<Integer, Object>> batches = new ArrayList<>();
|
||||||
|
private boolean batchStatus = false;
|
||||||
|
|
||||||
|
private final String query;
|
||||||
|
private final Map<Integer, Object> values = new HashMap<>();
|
||||||
|
private int currentIndex = 1;
|
||||||
|
|
||||||
|
StatementHolder(Query query){
|
||||||
|
this.query = query.getStatement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementHolder setString(String value){
|
||||||
|
values.put(currentIndex++, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementHolder setInt(int value){
|
||||||
|
values.put(currentIndex++, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementHolder setDouble(double value){
|
||||||
|
values.put(currentIndex++, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementHolder setLong(long value){
|
||||||
|
values.put(currentIndex++, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementHolder setBoolean(boolean value){
|
||||||
|
values.put(currentIndex++, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementHolder setLocation(Location loc){
|
||||||
|
values.put(currentIndex++, loc == null ? "" : LocationUtils.getLocation(loc));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void prepareBatch(){
|
||||||
|
batchStatus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBatch(){
|
||||||
|
batches.add(new HashMap<>(values));
|
||||||
|
values.clear();
|
||||||
|
currentIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatement getStatement() throws SQLException {
|
||||||
|
PreparedStatement preparedStatement = SQLHelper.buildStatement(query);
|
||||||
|
for(Map.Entry<Integer, Object> entry : values.entrySet()) {
|
||||||
|
preparedStatement.setObject(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return preparedStatement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(boolean async) {
|
||||||
|
if(async){
|
||||||
|
Executor.data(() -> execute(false));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (SQLHelper.getMutex()) {
|
||||||
|
String errorQuery = query;
|
||||||
|
try (PreparedStatement preparedStatement = SQLHelper.buildStatement(query)) {
|
||||||
|
if (!batches.isEmpty()) {
|
||||||
|
SQLHelper.setAutoCommit(false);
|
||||||
|
for (Map<Integer, Object> values : batches) {
|
||||||
|
for (Map.Entry<Integer, Object> entry : values.entrySet()) {
|
||||||
|
preparedStatement.setObject(entry.getKey(), entry.getValue());
|
||||||
|
errorQuery = errorQuery.replaceFirst("\\?", entry.getValue() + "");
|
||||||
|
}
|
||||||
|
preparedStatement.addBatch();
|
||||||
|
}
|
||||||
|
preparedStatement.executeBatch();
|
||||||
|
SQLHelper.commit();
|
||||||
|
SQLHelper.setAutoCommit(true);
|
||||||
|
} else if (!batchStatus) {
|
||||||
|
for (Map.Entry<Integer, Object> entry : values.entrySet()) {
|
||||||
|
preparedStatement.setObject(entry.getKey(), entry.getValue());
|
||||||
|
errorQuery = errorQuery.replaceFirst("\\?", entry.getValue() + "");
|
||||||
|
}
|
||||||
|
preparedStatement.executeUpdate();
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
WildLoadersPlugin.log("Failed to execute query " + errorQuery);
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
batchStatus = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,7 +8,12 @@ public final class LocationUtils {
|
|||||||
private LocationUtils(){}
|
private LocationUtils(){}
|
||||||
|
|
||||||
public static String getLocation(Location location){
|
public static String getLocation(Location location){
|
||||||
return location.getWorld().getName() + "," + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ();
|
try {
|
||||||
|
return location.getWorld().getName() + "," + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ();
|
||||||
|
}catch (Exception ex){
|
||||||
|
System.out.println(location);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Location getLocation(String location){
|
public static Location getLocation(String location){
|
||||||
|
Loading…
Reference in New Issue
Block a user