diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index bd422a5d..c7596ecc 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -51,5 +51,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 5aa6906b..6f175827 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,6 +14,7 @@ repositories {
maven { url = 'https://jitpack.io' }
maven { url = 'https://repo.dmulloy2.net/repository/public/' }
maven { url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/' }
+ maven { url = 'https://mvnrepository.com/artifact/com.zaxxer/HikariCP' }
}
dependencies {
@@ -30,6 +31,7 @@ dependencies {
implementation 'me.mattstudios.utils:matt-framework:1.4.6'
implementation 'org.spongepowered:configurate-yaml:4.1.2'
implementation 'org.bstats:bstats-bukkit:2.2.1'
+ implementation 'com.zaxxer:HikariCP:5.0.0'
}
test {
@@ -43,6 +45,7 @@ shadowJar {
relocate 'net.kyori.adventure.platform', 'io.github.fisher2911.hmccosmetics.adventure.platform'
relocate 'org.spongepowered.configurate', 'io.github.fisher2911.hmccosmetics.configurate'
relocate 'org.bstats', 'io.github.fisher2911.hmccosmetics.bstats'
+ relocate 'com.zaxxer.hikaricp', 'io.github.fisher2911.hmccosmetics.hikaricp'
}
shadowJar {
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java b/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java
index a78ec4f9..acf83cca 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/HMCCosmetics.java
@@ -5,6 +5,8 @@ import com.comphenix.protocol.ProtocolManager;
import io.github.fisher2911.hmccosmetics.command.CosmeticsCommand;
import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
+import io.github.fisher2911.hmccosmetics.database.Database;
+import io.github.fisher2911.hmccosmetics.database.DatabaseFactory;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.gui.CosmeticsMenu;
import io.github.fisher2911.hmccosmetics.listener.ClickListener;
@@ -34,6 +36,7 @@ public class HMCCosmetics extends JavaPlugin {
private CosmeticsMenu cosmeticsMenu;
private CommandManager commandManager;
private boolean papiEnabled;
+ private Database database;
@Override
public void onEnable() {
@@ -47,12 +50,16 @@ public class HMCCosmetics extends JavaPlugin {
this.cosmeticsMenu = new CosmeticsMenu(this);
this.messageHandler.load();
this.cosmeticsMenu.load();
- this.registerCommands();
- this.registerListeners();
this.userManager.startTeleportTask();
+ this.database = DatabaseFactory.create(this);
+ this.database.load();
+
this.papiEnabled = Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null;
+
+ this.registerCommands();
+ this.registerListeners();
}
@Override
@@ -116,6 +123,10 @@ public class HMCCosmetics extends JavaPlugin {
return protocolManager;
}
+ public Database getDatabase() {
+ return database;
+ }
+
public boolean isPapiEnabled() {
return papiEnabled;
}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java b/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java
index cb36113a..a371941e 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/command/CosmeticsCommand.java
@@ -125,7 +125,7 @@ public class CosmeticsCommand extends CommandBase {
switch (armorItem.getType()) {
case BACKPACK -> {
- user.setBackpack(armorItem);
+ user.setBackpack(armorItem, this.plugin);
this.messageHandler.sendMessage(
player,
Messages.SET_BACKPACK
@@ -138,7 +138,7 @@ public class CosmeticsCommand extends CommandBase {
);
}
case HAT -> {
- user.setHat(armorItem, this.userManager);
+ user.setHat(armorItem, this.plugin);
this.messageHandler.sendMessage(
player,
Messages.SET_HAT
@@ -173,7 +173,7 @@ public class CosmeticsCommand extends CommandBase {
switch (type) {
case HAT -> {
- user.removeHat(this.userManager);
+ user.removeHat(this.plugin);
this.messageHandler.sendMessage(
player,
Messages.REMOVED_HAT
@@ -186,7 +186,7 @@ public class CosmeticsCommand extends CommandBase {
);
}
case BACKPACK -> {
- user.removeBackpack();
+ user.removeBackpack(this.plugin);
this.messageHandler.sendMessage(
player,
Messages.REMOVED_BACKPACK
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java b/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java
new file mode 100644
index 00000000..efc92579
--- /dev/null
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/database/Database.java
@@ -0,0 +1,126 @@
+package io.github.fisher2911.hmccosmetics.database;
+
+import io.github.fisher2911.hmccosmetics.HMCCosmetics;
+import io.github.fisher2911.hmccosmetics.cosmetic.CosmeticManager;
+import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
+import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
+import io.github.fisher2911.hmccosmetics.user.User;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public abstract class Database {
+
+ AtomicInteger ARMOR_STAND_ID = new AtomicInteger(Integer.MAX_VALUE);
+
+ String TABLE_NAME = "user";
+ String PLAYER_UUID_COLUMN = "uuid";
+ String BACKPACK_COLUMN = "backpack";
+ String HAT_COLUMN = "hat";
+ String DYE_COLOR_COLUMN = "dye";
+ String CREATE_TABLE_STATEMENT =
+ "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
+ PLAYER_UUID_COLUMN + " CHAR(36), " +
+ BACKPACK_COLUMN + " VARCHAR, " +
+ HAT_COLUMN + " VARCHAR, " +
+ DYE_COLOR_COLUMN + " SMALLINT, " +
+ "UNIQUE (" +
+ PLAYER_UUID_COLUMN +
+ "))";
+
+ protected final HMCCosmetics plugin;
+
+ public Database(final HMCCosmetics plugin) {
+ this.plugin = plugin;
+ }
+
+ public abstract Connection getConnection();
+
+ public void load() {
+ try (final PreparedStatement statement = this.getConnection().prepareStatement(CREATE_TABLE_STATEMENT)) {
+ statement.executeUpdate();
+ } catch (final SQLException exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ public void saveUser(final User user) {
+ try (final PreparedStatement statement = this.getConnection().prepareStatement(this.getSaveStatement())) {
+ final PlayerArmor playerArmor = user.getPlayerArmor();
+ final String hat = playerArmor.getHat().getId();
+ final String backpack = playerArmor.getBackpack().getId();
+
+ final int dye = user.getDye();
+
+ statement.setString(1, user.getUuid().toString());
+ statement.setString(2, backpack);
+ statement.setString(3, hat);
+ statement.setInt(4, dye);
+ statement.setString(5, backpack);
+ statement.setString(6, hat);
+ statement.setInt(7, dye);
+
+ statement.executeUpdate();
+ } catch (final SQLException exception) {
+ this.plugin.getLogger().severe("There was in issue saving the player!");
+ exception.printStackTrace();
+ }
+ }
+
+ public User loadUser(final UUID uuid) {
+ final int armorStandId = ARMOR_STAND_ID.getAndDecrement();
+
+ final User blankUser = new User(
+ uuid,
+ PlayerArmor.empty(),
+ armorStandId
+ );
+
+ try (final PreparedStatement statement = this.getConnection().prepareStatement(this.getLoadStatement())) {
+ statement.setString(1, uuid.toString());
+
+ final ResultSet results = statement.executeQuery();
+
+ if (!results.next()) {
+ return blankUser;
+ }
+
+ final String backpackId = results.getString(1);
+ final String hatId = results.getString(2);
+ final int dye = results.getInt(3);
+
+ final CosmeticManager manager = this.plugin.getCosmeticManager();
+
+ ArmorItem backpack = manager.getArmorItem(backpackId);
+ ArmorItem hat = manager.getArmorItem(hatId);
+
+ if (backpack == null) backpack = ArmorItem.empty(ArmorItem.Type.BACKPACK);
+ if (hat == null) hat = ArmorItem.empty(ArmorItem.Type.HAT);
+
+ return new User(
+ uuid,
+ new PlayerArmor(
+ hat,
+ backpack,
+ dye
+ ),
+ armorStandId
+ );
+
+ } catch (final SQLException exception) {
+ exception.printStackTrace();
+ return blankUser;
+ }
+ }
+
+
+ public abstract void close();
+
+ public abstract String getSaveStatement();
+
+ public abstract String getLoadStatement();
+}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/database/DatabaseFactory.java b/src/main/java/io/github/fisher2911/hmccosmetics/database/DatabaseFactory.java
new file mode 100644
index 00000000..b4d7eda9
--- /dev/null
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/database/DatabaseFactory.java
@@ -0,0 +1,69 @@
+package io.github.fisher2911.hmccosmetics.database;
+
+import io.github.fisher2911.hmccosmetics.HMCCosmetics;
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.logging.Logger;
+
+public class DatabaseFactory {
+
+ private static final String FILE_NAME = "database.yml";
+ private static final String TYPE_PATH = "type";
+ private static final String NAME_PATH = "name";
+ private static final String USERNAME_PATH = "username";
+ private static final String PASSWORD_PATH = "password";
+ private static final String IP_PATH = "ip";
+ private static final String PORT_PATH = "port";
+
+ public static Database create(final HMCCosmetics plugin) {
+ final File file = Path.of(plugin.getDataFolder().getPath(), FILE_NAME).toFile();
+
+ if (!file.exists()) {
+ plugin.saveResource(FILE_NAME, false);
+ }
+
+ final FileConfiguration config = YamlConfiguration.loadConfiguration(file);
+
+ final String type = config.getString(TYPE_PATH);
+
+ final Logger logger = plugin.getLogger();
+
+ if (type == null) {
+ Bukkit.getPluginManager().disablePlugin(plugin);
+ throw new NullPointerException();
+ }
+
+ final Database database = switch (type.toLowerCase()) {
+ case "mysql" -> {
+ final String name = config.getString(NAME_PATH);
+ final String username = config.getString(USERNAME_PATH);
+ final String password = config.getString(PASSWORD_PATH);
+ final String ip = config.getString(IP_PATH);
+ final String port = config.getString(PORT_PATH);
+
+ yield new MySQLDatabase(
+ plugin,
+ name,
+ username,
+ password,
+ ip,
+ port
+ );
+ }
+ case "sqlite" -> new SQLiteDatabase(plugin);
+ default -> null;
+ };
+
+ if (database == null) {
+ logger.severe("Error loading database, type " + type + " is invalid!");
+ Bukkit.getPluginManager().disablePlugin(plugin);
+ }
+
+ return database;
+ }
+
+}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/database/MySQLDatabase.java b/src/main/java/io/github/fisher2911/hmccosmetics/database/MySQLDatabase.java
new file mode 100644
index 00000000..62117767
--- /dev/null
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/database/MySQLDatabase.java
@@ -0,0 +1,76 @@
+package io.github.fisher2911.hmccosmetics.database;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import io.github.fisher2911.hmccosmetics.HMCCosmetics;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class MySQLDatabase extends Database {
+
+ String SAVE_STATEMENT =
+ "INSERT INTO " + TABLE_NAME + "(" +
+ PLAYER_UUID_COLUMN + ", " +
+ BACKPACK_COLUMN + ", " +
+ HAT_COLUMN + ", " +
+ DYE_COLOR_COLUMN + ", " +
+ "VALUES (?,?,?) " +
+ "ON DUPLICATE KEY UPDATE " +
+ BACKPACK_COLUMN + "=?, " +
+ HAT_COLUMN + "=?, " +
+ DYE_COLOR_COLUMN + "=?";
+
+ String LOAD_STATEMENT =
+ "SELECT " +
+ BACKPACK_COLUMN + ", " +
+ HAT_COLUMN + ", " +
+ DYE_COLOR_COLUMN + ", " +
+ "FROM " + TABLE_NAME + " " +
+ "WHERE " +
+ PLAYER_UUID_COLUMN + "=?";
+
+ private final HikariDataSource dataSource;
+
+ MySQLDatabase(
+ final HMCCosmetics plugin,
+ final String name,
+ final String username,
+ final String password,
+ final String ip,
+ final String port) {
+ super(plugin);
+ final HikariConfig config = new HikariConfig();
+
+ config.setJdbcUrl("jdbc:mysql://" + ip + ":" + port + "/" + name);
+ config.setUsername(username);
+ config.setPassword(password);
+ config.setConnectionTimeout(1000000000);
+
+ this.dataSource = new HikariDataSource(config);
+ }
+
+ @Override
+ public Connection getConnection() {
+ try {
+ return this.dataSource.getConnection();
+ } catch (final SQLException exception) {
+ return null;
+ }
+ }
+
+ @Override
+ public void close() {
+ this.dataSource.close();
+ }
+
+ @Override
+ public String getSaveStatement() {
+ return SAVE_STATEMENT;
+ }
+
+ @Override
+ public String getLoadStatement() {
+ return LOAD_STATEMENT;
+ }
+}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/database/SQLiteDatabase.java b/src/main/java/io/github/fisher2911/hmccosmetics/database/SQLiteDatabase.java
new file mode 100644
index 00000000..e3b7171b
--- /dev/null
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/database/SQLiteDatabase.java
@@ -0,0 +1,91 @@
+package io.github.fisher2911.hmccosmetics.database;
+
+import io.github.fisher2911.hmccosmetics.HMCCosmetics;
+import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
+import io.github.fisher2911.hmccosmetics.user.User;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public class SQLiteDatabase extends Database {
+
+ private Connection conn;
+
+ public SQLiteDatabase(final HMCCosmetics plugin) {
+ super(plugin);
+ }
+
+ String SAVE_STATEMENT =
+ "INSERT INTO " + TABLE_NAME + "(" +
+ PLAYER_UUID_COLUMN + ", " +
+ BACKPACK_COLUMN + ", " +
+ HAT_COLUMN + ", " +
+ DYE_COLOR_COLUMN +
+ ") " +
+ "VALUES (?,?,?,?) " +
+ "ON CONFLICT (" +
+ PLAYER_UUID_COLUMN + ") " +
+ "DO UPDATE SET " +
+ BACKPACK_COLUMN + "=?," +
+ HAT_COLUMN + "=?, " +
+ DYE_COLOR_COLUMN + "=?";
+
+ String LOAD_STATEMENT =
+ "SELECT " +
+ BACKPACK_COLUMN + ", " +
+ HAT_COLUMN + ", " +
+ DYE_COLOR_COLUMN + " " +
+ "FROM " + TABLE_NAME + " " +
+ "WHERE " +
+ PLAYER_UUID_COLUMN + "=? ";
+
+ @Override
+ public Connection getConnection() {
+ if (this.conn != null) {
+ return this.conn;
+ }
+ try {
+ final File folder = Path.of(
+ this.plugin.getDataFolder().getPath(),
+ "database"
+ ).toFile();
+
+ folder.mkdirs();
+
+ final File file = Path.of(
+ folder.getPath(),
+ "users.db"
+ ).toFile();
+
+ this.conn = DriverManager.getConnection("jdbc:sqlite:" +
+ file.getPath());
+ return this.conn;
+ } catch (final SQLException exception) {
+ exception.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public void close() {
+ try {
+ this.conn.close();
+ } catch (final SQLException exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ @Override
+ public String getSaveStatement() {
+ return SAVE_STATEMENT;
+ }
+
+ @Override
+ public String getLoadStatement() {
+ return LOAD_STATEMENT;
+ }
+}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java b/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java
index 2c69b743..fb3dd37e 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticGui.java
@@ -142,13 +142,13 @@ public class CosmeticGui {
switch (type) {
case HAT -> {
- final boolean set = user.setOrUnsetHat(armorItem, this.messageHandler, this.plugin.getUserManager());
+ final boolean set = user.setOrUnsetHat(armorItem, this.messageHandler, this.plugin);
if (set) {
actionIfSet.execute(event);
}
}
case BACKPACK -> {
- final boolean set = user.setOrUnsetBackpack(armorItem, this.messageHandler);
+ final boolean set = user.setOrUnsetBackpack(armorItem, this.messageHandler, this.plugin);
if (set) {
actionIfSet.execute(event);
}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java b/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java
index 11cfa72f..83ce8ae6 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/gui/CosmeticsMenu.java
@@ -120,8 +120,7 @@ public class CosmeticsMenu {
final ConfigurationNode source = loader.load();
if (id.equals(DYE_MENU)) {
- this.guiMap.put(id, DyeGuiSerializer.INSTANCE.deserialize(DyeSelectorGui.class,
- source));
+ this.guiMap.put(id, DyeGuiSerializer.INSTANCE.deserialize(DyeSelectorGui.class, source));
this.plugin.getLogger().info("Loaded dye gui: " + id);
continue;
}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java b/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java
index c116d8b6..c2facd3f 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/gui/DyeSelectorGui.java
@@ -94,9 +94,6 @@ public class DyeSelectorGui extends CosmeticGui {
return;
}
- final ColorBuilder colorBuilder =
- ColorBuilder.from(itemStack);
-
final GuiItem guiItem = this.guiItemMap.get(event.getSlot());
if (!(guiItem instanceof final ColorItem colorItem)) {
@@ -104,22 +101,11 @@ public class DyeSelectorGui extends CosmeticGui {
}
final Color color = colorItem.getColor();
-
- colorBuilder.color(color);
-
- final ArmorItem newArmorItem = new ArmorItem(
- colorBuilder.build(),
- armorItem.getAction(),
- armorItem.getId(),
- armorItem.getLockedLore(),
- armorItem.getPermission(),
- armorItem.getType(),
- armorItem.isDyeable()
- );
+ user.setDye(color.asRGB());
switch (type) {
- case HAT -> user.setHat(newArmorItem, plugin.getUserManager());
- case BACKPACK -> user.setBackpack(newArmorItem);
+ case HAT -> user.setHat(armorItem, this.plugin);
+ case BACKPACK -> user.setBackpack(armorItem, this.plugin);
}
});
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java b/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java
index e99324c3..30a102a4 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/inventory/PlayerArmor.java
@@ -1,6 +1,8 @@
package io.github.fisher2911.hmccosmetics.inventory;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
+import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
+import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@@ -10,9 +12,11 @@ public class PlayerArmor {
private ArmorItem hat;
private ArmorItem backpack;
+ private int dye;
- public PlayerArmor(final ArmorItem hat, final ArmorItem backpack) {
- this.hat = hat;
+ public PlayerArmor(ArmorItem hat, final ArmorItem backpack, final int dye) {
+ this.dye = dye;
+ this.setHat(hat);
this.backpack = backpack;
}
@@ -31,7 +35,8 @@ public class PlayerArmor {
new ArrayList<>(),
"",
ArmorItem.Type.BACKPACK
- ));
+ ),
+ -1);
}
public ArmorItem getHat() {
@@ -39,7 +44,23 @@ public class PlayerArmor {
}
public void setHat(final ArmorItem hat) {
- this.hat = hat;
+ if (dye == -1 || !ColorBuilder.canBeColored(hat.getItemStack())) {
+ this.hat = hat;
+ return;
+ }
+
+ final ColorBuilder colorBuilder =
+ ColorBuilder.from(hat.getItemStack()).
+ color(Color.fromRGB(this.dye));
+ this.hat = new ArmorItem(
+ colorBuilder.build(),
+ hat.getAction(),
+ hat.getId(),
+ hat.getLockedLore(),
+ hat.getPermission(),
+ hat.getType(),
+ hat.isDyeable()
+ );
}
public ArmorItem getBackpack() {
@@ -49,4 +70,12 @@ public class PlayerArmor {
public void setBackpack(final ArmorItem backpack) {
this.backpack = backpack;
}
+
+ public int getDye() {
+ return this.dye;
+ }
+
+ public void setDye(final int dye) {
+ this.dye = dye;
+ }
}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java b/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java
index 84750221..ea8af4c9 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/listener/JoinListener.java
@@ -1,9 +1,12 @@
package io.github.fisher2911.hmccosmetics.listener;
import io.github.fisher2911.hmccosmetics.HMCCosmetics;
+import io.github.fisher2911.hmccosmetics.database.Database;
+import io.github.fisher2911.hmccosmetics.user.User;
import io.github.fisher2911.hmccosmetics.user.UserManager;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
@@ -12,16 +15,25 @@ import org.bukkit.event.player.PlayerQuitEvent;
public class JoinListener implements Listener {
private final HMCCosmetics plugin;
+ private final Database database;
private final UserManager userManager;
public JoinListener(final HMCCosmetics plugin) {
this.plugin = plugin;
+ this.database = this.plugin.getDatabase();
this.userManager = this.plugin.getUserManager();
}
@EventHandler
public void onJoin(final PlayerJoinEvent event) {
- this.userManager.add(event.getPlayer());
+ final Player player = event.getPlayer();
+ Bukkit.getScheduler().runTaskAsynchronously(this.plugin,
+ () -> {
+ final User user = this.database.loadUser(player.getUniqueId());
+ Bukkit.getScheduler().runTask(this.plugin,
+ () -> this.userManager.add(user));
+ });
+ this.userManager.resendCosmetics(player);
}
@EventHandler
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/listener/RespawnListener.java b/src/main/java/io/github/fisher2911/hmccosmetics/listener/RespawnListener.java
index cc6581e4..e80e6be6 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/listener/RespawnListener.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/listener/RespawnListener.java
@@ -27,7 +27,7 @@ public class RespawnListener implements Listener {
final Player player = event.getPlayer();
final Optional optionalUser = this.userManager.get(player.getUniqueId());
- optionalUser.ifPresent(user -> user.setHat(user.getPlayerArmor().getHat(), this.userManager));
+ optionalUser.ifPresent(user -> user.setHat(user.getPlayerArmor().getHat(), this.plugin));
}, 1);
}
}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java b/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java
index 349a06ce..e0375121 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/user/User.java
@@ -7,14 +7,17 @@ import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.Pair;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
+import io.github.fisher2911.hmccosmetics.HMCCosmetics;
import io.github.fisher2911.hmccosmetics.gui.ArmorItem;
import io.github.fisher2911.hmccosmetics.inventory.PlayerArmor;
import io.github.fisher2911.hmccosmetics.message.MessageHandler;
import io.github.fisher2911.hmccosmetics.message.Messages;
import io.github.fisher2911.hmccosmetics.message.Placeholder;
+import io.github.fisher2911.hmccosmetics.util.builder.ColorBuilder;
import io.github.fisher2911.hmccosmetics.util.builder.ItemBuilder;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import org.bukkit.Bukkit;
+import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
@@ -41,6 +44,7 @@ public class User {
this.uuid = uuid;
this.playerArmor = playerArmor;
this.armorStandId = armorStandId;
+ this.lastSetItem = playerArmor.getHat();
}
public @Nullable Player getPlayer() {
@@ -64,27 +68,30 @@ public class User {
this.setPlayerArmor(PlayerArmor.empty());
}
- public void removeHat(final UserManager userManager) {
- this.setHat(ArmorItem.empty(ArmorItem.Type.HAT), userManager);
+ public void removeHat(final HMCCosmetics plugin) {
+ this.setHat(ArmorItem.empty(ArmorItem.Type.HAT), plugin);
}
- public void removeBackpack() {
- this.setBackpack(ArmorItem.empty(ArmorItem.Type.BACKPACK));
+ public void removeBackpack(final HMCCosmetics plugin) {
+ this.setBackpack(ArmorItem.empty(ArmorItem.Type.BACKPACK), plugin);
}
public int getArmorStandId() {
return armorStandId;
}
- public void setBackpack(final ArmorItem backpack) {
+ public void setBackpack(final ArmorItem backpack, final HMCCosmetics plugin) {
this.playerArmor.setBackpack(backpack);
this.lastSetItem = backpack;
+ Bukkit.getScheduler().runTaskAsynchronously(plugin,
+ () -> plugin.getDatabase().saveUser(this));
}
// return true if backpack was set
public boolean setOrUnsetBackpack(
final ArmorItem backpack,
- final MessageHandler messageHandler) {
+ final MessageHandler messageHandler,
+ final HMCCosmetics plugin) {
final Player player = this.getPlayer();
@@ -93,7 +100,7 @@ public class User {
}
if (backpack.getId().equals(this.playerArmor.getBackpack().getId())) {
- this.setBackpack(ArmorItem.empty(ArmorItem.Type.BACKPACK));
+ this.setBackpack(ArmorItem.empty(ArmorItem.Type.BACKPACK), plugin);
messageHandler.sendMessage(
player,
@@ -103,7 +110,7 @@ public class User {
return false;
}
- this.setBackpack(backpack);
+ this.setBackpack(backpack, plugin);
messageHandler.sendMessage(
player,
Messages.SET_BACKPACK
@@ -113,17 +120,19 @@ public class User {
}
- public void setHat(final ArmorItem hat, final UserManager userManager) {
+ public void setHat(ArmorItem hat, final HMCCosmetics plugin) {
this.playerArmor.setHat(hat);
this.lastSetItem = hat;
- userManager.updateHat(this);
+ plugin.getUserManager().updateHat(this);
+ Bukkit.getScheduler().runTaskAsynchronously(plugin,
+ () -> plugin.getDatabase().saveUser(this));
}
// return true if hat was set
public boolean setOrUnsetHat(
final ArmorItem hat,
final MessageHandler messageHandler,
- final UserManager userManager) {
+ final HMCCosmetics plugin) {
final Player player = this.getPlayer();
@@ -132,7 +141,7 @@ public class User {
}
if (hat.getId().equals(this.playerArmor.getHat().getId())) {
- this.setHat(ArmorItem.empty(ArmorItem.Type.BACKPACK), userManager);
+ this.setHat(ArmorItem.empty(ArmorItem.Type.BACKPACK), plugin);
messageHandler.sendMessage(
player,
@@ -142,7 +151,7 @@ public class User {
return false;
}
- this.setHat(hat, userManager);
+ this.setHat(hat, plugin);
messageHandler.sendMessage(
player,
Messages.SET_HAT
@@ -291,4 +300,12 @@ public class User {
public ArmorItem getLastSetItem() {
return lastSetItem;
}
+
+ public int getDye() {
+ return this.playerArmor.getDye();
+ }
+
+ public void setDye(final int dye) {
+ this.playerArmor.setDye(dye);
+ }
}
diff --git a/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java b/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java
index 2b85542b..2048e2c6 100644
--- a/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java
+++ b/src/main/java/io/github/fisher2911/hmccosmetics/user/UserManager.java
@@ -30,11 +30,9 @@ import java.util.UUID;
public class UserManager {
- private int currentArmorStandId = Integer.MAX_VALUE;
private final HMCCosmetics plugin;
private final Map userMap = new HashMap<>();
- private final Map armorStandIdMap = new HashMap<>();
private BukkitTask teleportTask;
@@ -43,16 +41,9 @@ public class UserManager {
this.registerPacketListener();
}
- public void add(final Player player) {
- final UUID uuid = player.getUniqueId();
- final int armorStandId = this.currentArmorStandId;
- final User user = new User(
- uuid,
- PlayerArmor.empty(),
- armorStandId);
- this.userMap.put(uuid, user);
- this.armorStandIdMap.put(armorStandId, user);
- this.currentArmorStandId--;
+ public void add(final User user) {
+ this.userMap.put(user.getUuid(), user);
+ this.setFakeHelmet(user);
}
public Optional get(final UUID uuid) {
@@ -71,8 +62,6 @@ public class UserManager {
user.removeAllCosmetics();
this.setFakeHelmet(user);
user.despawnAttached();
-
- this.armorStandIdMap.remove(user.getArmorStandId());
}
public void startTeleportTask() {
diff --git a/src/main/resources/database.yml b/src/main/resources/database.yml
new file mode 100644
index 00000000..363d95aa
--- /dev/null
+++ b/src/main/resources/database.yml
@@ -0,0 +1,8 @@
+# SQLite or MySQL (case-insensitive)
+type: "sqlite"
+# The rest of these are only required for MySQL
+name: "name"
+username: "username"
+password: "password"
+ip: "ip"
+port: 3306
\ No newline at end of file