Save Inventorys on Leave

This commit is contained in:
Tyler Murphy 2022-07-21 13:02:20 -04:00
parent c506030cba
commit 72314cabf8
13 changed files with 159 additions and 19 deletions

View file

@ -1,7 +1,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion>
<groupId>net.tylermurphy</groupId>
<artifactId>KenshinsHideAndSeek</artifactId>
<version>1.5.0</version>
<version>1.5.1</version>
<name>Hide and Seek Plugin</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View file

@ -62,7 +62,6 @@ public class Main extends JavaPlugin implements Listener {
public Main() {
super();
onConstructed();
board = new Board();
database = new Database();
}
@ -70,7 +69,6 @@ public class Main extends JavaPlugin implements Listener {
protected Main(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
super(loader, description, dataFolder, file);
onConstructed();
board = new Board();
database = new Database();
}
@ -89,7 +87,6 @@ public class Main extends JavaPlugin implements Listener {
Config.loadConfig();
Localization.loadLocalization();
Items.loadItems();
}
public void onEnable() {

View file

@ -26,7 +26,7 @@ public class About implements ICommand {
public void execute(Player sender, String[] args) {
sender.sendMessage(
String.format("%s%sHide and Seek %s(%s1.5.0%s)\n", ChatColor.AQUA, ChatColor.BOLD, ChatColor.GRAY,ChatColor.WHITE,ChatColor.GRAY) +
String.format("%s%sHide and Seek %s(%s1.5.1%s)\n", ChatColor.AQUA, ChatColor.BOLD, ChatColor.GRAY,ChatColor.WHITE,ChatColor.GRAY) +
String.format("%sAuthor: %s[KenshinEto]\n", ChatColor.GRAY, ChatColor.WHITE) +
String.format("%sHelp Command: %s/hs %shelp", ChatColor.GRAY, ChatColor.AQUA, ChatColor.WHITE)
);

View file

@ -89,7 +89,8 @@ public class Config {
lobbyItemStartAdmin,
leaveOnEnd,
mapSaveEnabled,
allowNaturalCauses;
allowNaturalCauses,
saveInventory;
public static int
minPlayers,
@ -267,6 +268,7 @@ public class Config {
leaveOnEnd = config.getBoolean("leaveOnEnd");
placeholderError = config.getString("placeholder.incorrect");
placeholderNoData = config.getString("placeholder.noData");
saveInventory = config.getBoolean("saveInventory");
try {
countdownDisplay = CountdownDisplay.valueOf(config.getString("hideCountdownDisplay"));
} catch (IllegalArgumentException e) {

View file

@ -39,6 +39,7 @@ public class Database {
private final GameDataTable playerInfo;
private final NameDataTable nameInfo;
private final InventoryTable inventoryInfo;
private final DatabaseConnection connection;
public Database(){
@ -53,6 +54,8 @@ public class Database {
nameInfo = new NameDataTable(this);
inventoryInfo = new InventoryTable(this);
LegacyTable legacyTable = new LegacyTable(this);
if(legacyTable.exists()){
if(legacyTable.copyData()){
@ -69,6 +72,8 @@ public class Database {
public NameDataTable getNameData() { return nameInfo; }
public InventoryTable getInventoryData() { return inventoryInfo; }
protected Connection connect() {
Connection conn = null;
try {

View file

@ -23,6 +23,7 @@ import net.tylermurphy.hideAndSeek.Main;
import net.tylermurphy.hideAndSeek.database.util.PlayerInfo;
import net.tylermurphy.hideAndSeek.game.Board;
import net.tylermurphy.hideAndSeek.game.util.WinType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.*;
@ -91,7 +92,7 @@ public class GameDataTable {
}
@Nullable
public PlayerInfo getInfoRanking(String order, int place) {
public PlayerInfo getInfoRanking(@NotNull String order, int place) {
String sql = "SELECT * FROM hs_data ORDER BY "+order+" DESC LIMIT 1 OFFSET ?;";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setInt(1, place-1);
@ -154,7 +155,7 @@ public class GameDataTable {
}
@Nullable
public Integer getRanking(String order, UUID uuid) {
public Integer getRanking(@NotNull String order, @NotNull UUID uuid) {
String sql = "SELECT count(*) AS total FROM hs_data WHERE "+order+" >= (SELECT "+order+" FROM hs_data WHERE uuid = ?) AND "+order+" > 0;";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setBytes(1, database.encodeUUID(uuid));
@ -170,7 +171,16 @@ public class GameDataTable {
return null;
}
public void addWins(Board board, List<UUID> uuids, List<UUID> winners, Map<String,Integer> hider_kills, Map<String,Integer> hider_deaths, Map<String,Integer> seeker_kills, Map<String,Integer> seeker_deaths, WinType type) {
public void addWins(
@NotNull Board board,
@NotNull List<UUID> uuids,
@NotNull List<UUID> winners,
@NotNull Map<String,Integer> hider_kills,
@NotNull Map<String,Integer> hider_deaths,
@NotNull Map<String,Integer> seeker_kills,
@NotNull Map<String,Integer> seeker_deaths,
@NotNull WinType type
) {
for(UUID uuid : uuids) {
PlayerInfo info = getInfo(uuid);
if(info == null){
@ -190,7 +200,7 @@ public class GameDataTable {
}
}
protected boolean updateInfo(byte[] uuid, int hider_wins, int seeker_wins, int hider_games, int seeker_games, int hider_kills, int seeker_kills, int hider_deaths, int seeker_deaths){
protected boolean updateInfo(@NotNull byte[] uuid, int hider_wins, int seeker_wins, int hider_games, int seeker_games, int hider_kills, int seeker_kills, int hider_deaths, int seeker_deaths){
boolean success;
String sql = "INSERT OR REPLACE INTO hs_data (uuid, hider_wins, seeker_wins, hider_games, seeker_games, hider_kills, seeker_kills, hider_deaths, seeker_deaths) VALUES (?,?,?,?,?,?,?,?,?)";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
@ -211,7 +221,7 @@ public class GameDataTable {
e.printStackTrace();
success = false;
} finally {
CACHE.remove(uuid);
CACHE.remove(database.decodeUUID(uuid));
}
return success;
}

View file

@ -0,0 +1,106 @@
package net.tylermurphy.hideAndSeek.database;
import net.tylermurphy.hideAndSeek.Main;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.*;
import java.util.UUID;
public class InventoryTable {
private final Database database;
protected InventoryTable(Database database) {
String sql = "CREATE TABLE IF NOT EXISTS hs_inventory (\n"
+ " uuid BINARY(16) NOT NULL,\n"
+ " inventory TEXT NOT NULL,\n"
+ " PRIMARY KEY (uuid)\n"
+ ");";
try(Connection connection = database.connect(); Statement statement = connection.createStatement()) {
statement.executeUpdate(sql);
} catch (SQLException e) {
Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage());
e.printStackTrace();
}
this.database = database;
}
@Nullable
public ItemStack[] getInventory(@NotNull UUID uuid) {
String sql = "SELECT * FROM hs_inventory WHERE uuid = ?;";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setBytes(1, database.encodeUUID(uuid));
ResultSet rs = statement.executeQuery();
if (rs.next()) {
String data = rs.getString("inventory");
if(data == null) return null;
return itemStackArrayFromBase64(data);
}
rs.close();
} catch (SQLException e) {
Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Main.getInstance().getLogger().severe("IO Error: " + e.getMessage());
e.printStackTrace();
}
return null;
}
public boolean saveInventory(@NotNull UUID uuid, @NotNull ItemStack[] itemArray) {
String sql = "INSERT OR REPLACE INTO hs_inventory (uuid, inventory) VALUES (?,?)";
String data = itemStackArrayToBase64(itemArray);
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setBytes(1, database.encodeUUID(uuid));
statement.setString(2, data);
statement.execute();
statement.close();
return true;
} catch (SQLException e) {
Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage());
e.printStackTrace();
return false;
}
}
private String itemStackArrayToBase64(ItemStack[] itemArray) throws IllegalStateException {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
dataOutput.writeObject(itemArray);
dataOutput.close();
return Base64Coder.encodeLines(outputStream.toByteArray());
} catch (Exception e) {
throw new IllegalStateException("Error whilst saving items, Please contact the developer", e);
}
}
private ItemStack[] itemStackArrayFromBase64(String data) throws IOException {
try {
ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data));
BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream);
ItemStack[] itemArray = (ItemStack[]) dataInput.readObject();
dataInput.close();
return itemArray;
} catch (ClassNotFoundException e) {
throw new IOException("Error whilst loading items, Please contact the developer", e);
}
}
}

View file

@ -22,6 +22,7 @@ package net.tylermurphy.hideAndSeek.database;
import net.tylermurphy.hideAndSeek.Main;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.management.BufferPoolMXBean;
@ -51,7 +52,7 @@ public class NameDataTable {
}
@Nullable
public String getName(UUID uuid) {
public String getName(@NotNull UUID uuid) {
String sql = "SELECT * FROM hs_names WHERE uuid = ?;";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setBytes(1, database.encodeUUID(uuid));
@ -73,7 +74,7 @@ public class NameDataTable {
}
@Nullable
public UUID getUUID(String name) {
public UUID getUUID(@NotNull String name) {
String sql = "SELECT * FROM hs_names WHERE name = ?;";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setString(1, name);
@ -94,7 +95,7 @@ public class NameDataTable {
return null;
}
public boolean update(UUID uuid, String name){
public boolean update(@NotNull UUID uuid, @NotNull String name){
String sql = "INSERT OR REPLACE INTO hs_names (uuid, name) VALUES (?,?)";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setBytes(1, database.encodeUUID(uuid));

View file

@ -33,6 +33,7 @@ import net.tylermurphy.hideAndSeek.world.WorldLoader;
import org.bukkit.*;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.util.*;
@ -169,6 +170,10 @@ public class Game {
public void join(Player player) {
if (status != Status.STARTING && status != Status.PLAYING) {
if(saveInventory) {
ItemStack[] data = player.getInventory().getContents();
Main.getInstance().getDatabase().getInventoryData().saveInventory(player.getUniqueId(), data);
}
PlayerLoader.joinPlayer(player);
board.addHider(player);
board.createLobbyBoard(player);
@ -185,6 +190,10 @@ public class Game {
public void leave(Player player) {
PlayerLoader.unloadPlayer(player);
if(saveInventory) {
ItemStack[] data = Main.getInstance().getDatabase().getInventoryData().getInventory(player.getUniqueId());
player.getInventory().setContents(data);
}
if (announceMessagesToNonPlayers) Bukkit.broadcastMessage(messagePrefix + message("GAME_LEAVE").addPlayer(player));
else broadcastMessage(messagePrefix + message("GAME_LEAVE").addPlayer(player));
if (board.isHider(player) && status != Status.ENDING && status != Status.STANDBY) {

View file

@ -19,6 +19,7 @@
package net.tylermurphy.hideAndSeek.game;
import com.cryptomorin.xseries.XItemStack;
import com.cryptomorin.xseries.messages.Titles;
import net.md_5.bungee.api.ChatColor;
import net.tylermurphy.hideAndSeek.Main;

View file

@ -2,6 +2,7 @@ package net.tylermurphy.hideAndSeek.game.listener;
import net.tylermurphy.hideAndSeek.Main;
import net.tylermurphy.hideAndSeek.configuration.Items;
import net.tylermurphy.hideAndSeek.game.PlayerLoader;
import net.tylermurphy.hideAndSeek.game.util.Status;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
@ -59,16 +60,18 @@ public class JoinLeaveHandler implements Listener {
}
private void handleLeave(Player player) {
if(!Main.getInstance().getBoard().contains(player)) return;
PlayerLoader.unloadPlayer(player);
Main.getInstance().getBoard().remove(player);
if(saveInventory) {
ItemStack[] data = Main.getInstance().getDatabase().getInventoryData().getInventory(player.getUniqueId());
player.getInventory().setContents(data);
}
if (Main.getInstance().getGame().getStatus() == Status.STANDBY) {
Main.getInstance().getBoard().reloadLobbyBoards();
} else {
Main.getInstance().getBoard().reloadGameBoards();
}
for(PotionEffect effect : player.getActivePotionEffects()) {
player.removePotionEffect(effect.getType());
}
removeItems(player);
}
private void removeItems(Player player) {

View file

@ -94,6 +94,12 @@ leaveServer: hub
# default: true
mapSaveEnabled: true
# By default, the plugin clears your inventory when joining the game. This is something it will always do. But you don't get what you used to have
# in your inventory back after you leave the game. You can allow the plugin to save a players inventory before joining the lobby, and give it back
# after leaving the game.
# default: false
saveInventory: false
# How you want to store game data. If you are running a single server, sqlite is fine, as no setup is necessary.
# But if you want the data to go across multiple servers, you can switch it to mysql.
# WARNING: Data is not saved across databases. You have to migrate the data yourself!

View file

@ -1,6 +1,6 @@
name: KenshinsHideAndSeek
main: net.tylermurphy.hideAndSeek.Main
version: 1.5.0
version: 1.5.1
author: KenshinEto
load: STARTUP
api-version: 1.13