Improve the persistence system

This commit is contained in:
Sam 2017-03-23 19:18:16 +00:00
parent f630f50f47
commit ca1b185ba2
7 changed files with 151 additions and 164 deletions

View File

@ -10,20 +10,27 @@ public class QuitNPCDespawnEvent extends Event implements Cancellable
{
private static final HandlerList HANDLERS = new HandlerList();
private final QuitNPC _npc;
private final boolean _pluginRemove;
private boolean _cancel;
public QuitNPCDespawnEvent(QuitNPC npc)
public QuitNPCDespawnEvent(QuitNPC npc, boolean pluginRemove)
{
_npc = npc;
_pluginRemove = pluginRemove;
}
public QuitNPC getNpc()
{
return _npc;
}
public boolean isPluginRemove()
{
return _pluginRemove;
}
public HandlerList getHandlers()
{
return HANDLERS;
@ -45,5 +52,5 @@ public class QuitNPCDespawnEvent extends Event implements Cancellable
{
_cancel = cancel;
}
}

View File

@ -52,7 +52,7 @@ public class QuitNPC implements Listener
// Unlocked Slots
private final int _slotsUnlocked;
// Gems
private final int _gems;
@ -94,7 +94,7 @@ public class QuitNPC implements Listener
// Unlocked Slots
_slotsUnlocked = Managers.get(InventoryModule.class).getSlotsUnlocked(player);
// Gems
_gems = Managers.get(EconomyModule.class).Get(player);
@ -118,11 +118,11 @@ public class QuitNPC implements Listener
player.getInventory().setItem(i++, itemStack);
}
player.getInventory().setArmorContents(_inventory.getArmorContents());
player.getInventory().setArmorContents(_inventory.getArmorContents());
// Unlocked Slots
Managers.get(InventoryModule.class).setSlotsUnlocked(player, _slotsUnlocked);
// Gems
// Subtract GEM_START_COST (100 by default) because EconomyModule adds
// this value on join regardless if they have an NPC.
@ -132,12 +132,12 @@ public class QuitNPC implements Listener
Managers.require(QuestModule.class).setPlayerData(player, _questPlayerData);
}
public void despawn()
public void despawn(boolean pluginRemove)
{
QuitNPCDespawnEvent event = new QuitNPCDespawnEvent(this);
QuitNPCDespawnEvent event = new QuitNPCDespawnEvent(this, pluginRemove);
UtilServer.CallEvent(event);
if (event.isCancelled())
{
return;
@ -153,24 +153,24 @@ public class QuitNPC implements Listener
public void dropItems()
{
Location location = _entity.getLocation().add(0, 1, 0);
for (ItemStack itemStack : _inventory.getContents())
{
if (itemStack == null || itemStack.getType() == Material.AIR)
{
continue;
}
location.getWorld().dropItemNaturally(location, itemStack);
}
for (ItemStack itemStack : _inventory.getArmorContents())
{
if (itemStack == null || itemStack.getType() == Material.AIR)
{
continue;
}
location.getWorld().dropItemNaturally(location, itemStack);
}
}
@ -185,7 +185,7 @@ public class QuitNPC implements Listener
if (UtilTime.elapsed(_start, _quitMills))
{
despawn();
despawn(true);
}
else
{
@ -200,21 +200,21 @@ public class QuitNPC implements Listener
{
return;
}
Player killer = event.getEntity().getKiller();
if (killer != null)
{
_npc.setKilledBy(_uuid, killer.getName());
Managers.get(EconomyModule.class).addToStore(killer, "Killing " + F.name(_name + "'s") + " NPC", (int) (_gems * EconomyModule.GEM_KILL_FACTOR));
}
event.getDrops().clear();
_entity.setHealth(_entity.getMaxHealth());
dropItems();
despawn();
despawn(false);
}
@EventHandler
public void entityCombust(EntityCombustEvent event)
{
@ -226,6 +226,11 @@ public class QuitNPC implements Listener
event.setCancelled(true);
}
public String getName()
{
return _name;
}
public UUID getUniqueId()
{
return _uuid;

View File

@ -101,7 +101,7 @@ public class QuitNPCModule extends MiniPlugin
@EventHandler
public void npcDespawn(QuitNPCDespawnEvent event)
{
log("Despawning npc for " + _npcs.remove(event.getNpc().getUniqueId()).getUniqueId());
log("Despawning npc for " + _npcs.remove(event.getNpc().getUniqueId()).getName());
}
@EventHandler

View File

@ -1,17 +1,20 @@
package mineplex.gemhunters.persistence;
import mineplex.gemhunters.quest.QuestPlayerData;
import org.bukkit.Location;
public class PersistenceData
{
private int _gems;
private Location _location;
private final int _gems;
private final Location _location;
private final QuestPlayerData _questData;
public PersistenceData(int gems, Location location)
public PersistenceData(int gems, Location location, QuestPlayerData questData)
{
_gems = gems;
_location = location;
_questData = questData;
}
public int getGems()
@ -24,4 +27,9 @@ public class PersistenceData
return _location;
}
public QuestPlayerData getQuestData()
{
return _questData;
}
}

View File

@ -2,73 +2,78 @@ package mineplex.gemhunters.persistence;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.CoreClient;
import mineplex.core.account.CoreClientManager;
import mineplex.gemhunters.death.event.QuitNPCDespawnEvent;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.serverdata.database.DBPool;
import org.bukkit.Location;
import mineplex.gemhunters.quest.QuestModule;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@ReflectivelyCreateMiniPlugin
public class PersistenceModule extends MiniPlugin
{
private final CoreClientManager _client;
private final EconomyModule _economy;
private final QuestModule _quest;
private final PersistenceRepository _repository;
private final Map<UUID, Location> _toTeleport;
public PersistenceModule()
{
super("Persistence");
_client = require(CoreClientManager.class);
_quest = require(QuestModule.class);
_economy = require(EconomyModule.class);
_repository = new PersistenceRepository(DBPool.getAccount());
_toTeleport = new HashMap<>();
_client.addStoredProcedureLoginProcessor(_repository.buildPersistenceDataLoginProcessor((uuid, data) ->
{
_economy.setStore(uuid, data.getGems());
_toTeleport.put(uuid, data.getLocation());
}));
_repository = new PersistenceRepository();
}
@EventHandler(priority = EventPriority.HIGHEST)
public void playerJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();
CoreClient client = _client.Get(player);
if (_toTeleport.containsKey(player.getUniqueId()))
runAsync(() -> _repository.getPersistenceData(response ->
{
player.teleport(_toTeleport.get(player.getUniqueId()));
}
_economy.setStore(player, response.getGems());
player.teleport(response.getLocation());
_quest.setPlayerData(player, response.getQuestData());
}, client));
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
_repository.savePersistence(event.getPlayer(), new PersistenceData(_economy.Get(player), player.getLocation()));
CoreClient client = _client.Get(player);
PersistenceData data = new PersistenceData(_economy.Get(player), player.getLocation(), _quest.Get(player));
runAsync(() -> _repository.savePersistence(client, data));
}
@EventHandler
public void playerDeath(PlayerDeathEvent event)
{
Player player = event.getEntity();
_repository.deletePersistence(player);
CoreClient client = _client.Get(player);
runAsync(() -> _repository.deletePersistence(client));
}
@EventHandler
public void npcDespawn(QuitNPCDespawnEvent event)
{
if (!event.isPluginRemove())
{
runAsync(() -> _client.getOrLoadClient(event.getNpc().getName(), _repository::deletePersistence));
}
}
}

View File

@ -1,153 +1,115 @@
package mineplex.gemhunters.persistence;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.account.ILoginProcessor;
import mineplex.core.common.util.UtilServer;
import mineplex.gemhunters.world.WorldDataModule;
import com.google.gson.Gson;
import mineplex.core.account.CoreClient;
import mineplex.gemhunters.quest.QuestPlayerData;
import mineplex.serverdata.database.DBPool;
import mineplex.serverdata.database.RepositoryBase;
import mineplex.serverdata.database.ResultSetCallable;
import mineplex.serverdata.database.column.ColumnInt;
import mineplex.serverdata.database.column.ColumnVarChar;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class PersistenceRepository
public class PersistenceRepository extends RepositoryBase
{
private static final String INSERT_PERSISTENCE = "INSERT INTO gemHunters VALUES (?,?,?);";
private static final String UPDATE_PERSISTENCE = "UPDATE gemHunters SET gems=?,location=? WHERE accountId=?;";
private static final String DELETE_PERSISTENCE = "DELETE FROM gemHunters WHERE accountId=?;";
private static final String GET_DATA = "SELECT * FROM gemHunters WHERE accountId=?;";
private static final String INSERT_DATA = "INSERT INTO gemHunters VALUES (?,?,?,?,?,?,?,?);";
private static final String UPDATE_DATA = "UPDATE gemHunters SET gems=?,x=?,y=?,z=?,yaw=?,pitch=?,quests=? WHERE accountId=?;";
private static final String DELETE_DATA = "DELETE FROM gemHunters WHERE accountId=?;";
private static final Gson GSON;
private final CoreClientManager _client;
private final WorldDataModule _worldData;
private final DataSource _dataSource;
static
{
GSON = new Gson();
}
private final List<Integer> _exists;
public PersistenceRepository(DataSource source)
public PersistenceRepository()
{
_dataSource = source;
_client = Managers.require(CoreClientManager.class);
_worldData = Managers.require(WorldDataModule.class);
super(DBPool.getAccount());
_exists = new ArrayList<>();
}
public ILoginProcessor buildPersistenceDataLoginProcessor(BiConsumer<UUID, PersistenceData> consumer)
public void getPersistenceData(Consumer<PersistenceData> response, CoreClient client)
{
return new ILoginProcessor()
int accountId = client.getAccountId();
executeQuery(GET_DATA, resultSet ->
{
@Override
public String getName()
if (resultSet.next())
{
return "Gem Hunters Persistence";
}
int gems = resultSet.getInt("gems");
int x = resultSet.getInt("x");
int y = resultSet.getInt("y");
int z = resultSet.getInt("z");
int yaw = resultSet.getInt("yaw");
int pitch = resultSet.getInt("pitch");
String quests = resultSet.getString("quests");
QuestPlayerData questData = GSON.fromJson(quests, QuestPlayerData.class);
@Override
public void processLoginResultSet(String playerName, UUID uuid, int accountId, ResultSet resultSet) throws SQLException
{
if (resultSet.next())
{
_exists.add(accountId);
consumer.accept(uuid, fromResultSet(resultSet));
}
_exists.add(accountId);
PersistenceData data = new PersistenceData(gems, new Location(Bukkit.getWorlds().get(0), x, y, z, yaw, pitch), questData);
response.accept(data);
}
@Override
public String getQuery(int accountId, String uuid, String name)
{
return "SELECT * FROM gemHunters WHERE accountId=" + accountId + ";";
}
};
}, new ColumnInt("accountId", accountId));
}
public void savePersistence(Player player, PersistenceData data)
public void savePersistence(CoreClient client, PersistenceData data)
{
int accountId = _client.Get(player).getAccountId();
int accountId = client.getAccountId();
UtilServer.runAsync(() ->
int gems = data.getGems();
int x = data.getLocation().getBlockX();
int y = data.getLocation().getBlockY();
int z = data.getLocation().getBlockZ();
int yaw = (int) data.getLocation().getYaw();
int pitch = (int) data.getLocation().getPitch();
if (_exists.contains(accountId))
{
try (Connection connection = _dataSource.getConnection())
{
boolean update = _exists.contains(accountId);
PreparedStatement statement = connection.prepareStatement(update ? UPDATE_PERSISTENCE : INSERT_PERSISTENCE);
if (update)
{
statement.setInt(1, data.getGems());
statement.setString(2, locationToString(data.getLocation()));
statement.setInt(3, accountId);
}
else
{
statement.setInt(1, accountId);
statement.setInt(2, data.getGems());
statement.setString(3, locationToString(data.getLocation()));
}
_exists.remove(Integer.valueOf(accountId));
statement.executeUpdate();
}
catch (SQLException e)
{
throw new CompletionException(e);
}
});
}
public void deletePersistence(Player player)
{
int accountId = _client.Get(player).getAccountId();
if (!_exists.contains(accountId))
executeUpdate(UPDATE_DATA,
new ColumnInt("gems", gems),
new ColumnInt("x", x),
new ColumnInt("y", y),
new ColumnInt("z", z),
new ColumnInt("yaw", yaw),
new ColumnInt("pitch", pitch),
new ColumnVarChar("quests", 500, GSON.toJson(data.getQuestData())),
new ColumnInt("accountId", accountId)
);
}
else
{
return;
executeInsert(INSERT_DATA, null,
new ColumnInt("accountId", accountId),
new ColumnInt("gems", gems),
new ColumnInt("x", x),
new ColumnInt("y", y),
new ColumnInt("z", z),
new ColumnInt("yaw", yaw),
new ColumnInt("pitch", pitch),
new ColumnVarChar("quests", 500, GSON.toJson(data.getQuestData()))
);
}
UtilServer.runAsync(() ->
{
try (Connection connection = _dataSource.getConnection())
{
PreparedStatement statement = connection.prepareStatement(DELETE_PERSISTENCE);
statement.setInt(1, accountId);
statement.executeUpdate();
}
catch (SQLException e)
{
throw new CompletionException(e);
}
});
}
private PersistenceData fromResultSet(ResultSet set) throws SQLException
{
int gems = set.getInt(2);
Location location = stringToLocation(set.getString(3));
return new PersistenceData(gems, location);
_exists.remove(Integer.valueOf(accountId));
}
private Location stringToLocation(String loc)
public void deletePersistence(CoreClient client)
{
String[] coords = loc.split(",");
int accountId = client.getAccountId();
return new Location(_worldData.World, Integer.valueOf(coords[0]) + 0.5, Integer.valueOf(coords[1]), Integer.valueOf(coords[2]) + 0.5, Float.valueOf(coords[3]), Float.valueOf(coords[4]));
}
private String locationToString(Location loc)
{
return loc.getBlockX() + "," + loc.getBlockY() + "," + loc.getBlockZ() + "," + loc.getYaw() + "," + loc.getPitch();
executeUpdate(DELETE_DATA, new ColumnInt("accountId", accountId));
}
}

View File

@ -82,7 +82,7 @@ public class SpawnModule extends MiniPlugin
{
QuitNPC npc = _npc.getNPC(player);
npc.despawn();
npc.despawn(true);
npc.restore(player);
return;
}