diff --git a/src/com/projectkorra/projectkorra/ability/AbilityManager.java b/src/com/projectkorra/projectkorra/ability/AbilityManager.java new file mode 100644 index 00000000..7884cbca --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/AbilityManager.java @@ -0,0 +1,139 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; +import com.projectkorra.projectkorra.module.DatabaseModule; +import com.projectkorra.projectkorra.module.ModuleManager; +import com.projectkorra.projectkorra.player.BendingPlayer; +import com.projectkorra.projectkorra.player.BendingPlayerLoadedEvent; +import com.projectkorra.projectkorra.player.BendingPlayerManager; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +import java.sql.SQLException; + +public class AbilityManager extends DatabaseModule +{ + private final BendingPlayerManager _bendingPlayerManager; + + private AbilityManager() + { + super("Ability", new AbilityRepository()); + + _bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class); + + runAsync(() -> + { + try + { + getRepository().createTables(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + + runSync(() -> + { + log("Created database tables."); + }); + }); + } + + @EventHandler + public void onBendingPlayerLoaded(BendingPlayerLoadedEvent event) + { + BendingPlayer bendingPlayer = event.getBendingPlayer(); + + runAsync(() -> + { + try + { + String[] abilities = getRepository().selectPlayerAbilities(bendingPlayer.getId()); + + bendingPlayer.setAbilities(abilities); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + + public boolean bindAbility(Player player, String abilityName, int slot) + { + // TODO Call event, let MultiAbilityManager cancel + if (MultiAbilityManager.playerAbilities.containsKey(player)) + { + GeneralMethods.sendBrandingMessage(player, ChatColor.RED + "You can't edit your binds right now!"); + return false; + } + + BendingPlayer bendingPlayer = _bendingPlayerManager.getBendingPlayer(player); + + bendingPlayer.setAbility(slot, abilityName); + + runAsync(() -> + { + try + { + getRepository().insertPlayerAbility(bendingPlayer.getId(), abilityName, slot); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + + return true; + } + + public boolean unbindAbility(Player player, int slot) + { + BendingPlayer bendingPlayer = _bendingPlayerManager.getBendingPlayer(player); + + String abilityName = bendingPlayer.getAbility(slot); + + if (abilityName == null) + { + player.sendMessage("No ability bound"); + return false; + } + + bendingPlayer.setAbility(slot, null); + + runAsync(() -> + { + try + { + getRepository().deletePlayerAbility(bendingPlayer.getId(), abilityName); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + + return true; + } + + public void clearBinds(Player player) + { + BendingPlayer bendingPlayer = _bendingPlayerManager.getBendingPlayer(player); + + bendingPlayer.setAbilities(new String[9]); + + runAsync(() -> + { + try + { + getRepository().deletePlayerAbilities(bendingPlayer.getId()); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } +} diff --git a/src/com/projectkorra/projectkorra/ability/AbilityRepository.java b/src/com/projectkorra/projectkorra/ability/AbilityRepository.java new file mode 100644 index 00000000..347fee74 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/AbilityRepository.java @@ -0,0 +1,113 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.database.DatabaseQuery; +import com.projectkorra.projectkorra.database.DatabaseRepository; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class AbilityRepository extends DatabaseRepository +{ + private static final DatabaseQuery CREATE_TABLE_PLAYER_ABILITIES = DatabaseQuery.newBuilder() + .mysql("CREATE TABLE IF NOT EXISTS pk_player_abilities (player_id INTEGER REFERENCES pk_bending_players (player_id), ability_name VARCHAR(50) NOT NULL, slot TINYINT NOT NULL, PRIMARY KEY (player_id, ability_name), INDEX player_index (player_id), INDEX ability_index (ability_name));") + .sqlite("CREATE TABLE IF NOT EXISTS pk_player_abilities (player_id INTEGER REFERENCES pk_bending_players (player_id), ability_name VARCHAR(50) NOT NULL, slot TINYINT NOT NULL, PRIMARY KEY (player_id, ability_name)); CREATE INDEX player_index ON pk_player_abilities (player_id); CREATE INDEX ability_index ON pk_player_abilities (ability_name);") + .build(); + + private static final DatabaseQuery SELECT_PLAYER_ABILITIES = DatabaseQuery.newBuilder() + .query("SELECT ability_name, slot FROM pk_player_abilities WHERE player_id = ?;") + .build(); + + private static final DatabaseQuery INSERT_PLAYER_ABILITY = DatabaseQuery.newBuilder() + .query("INSERT INTO pk_player_abilities VALUES (?, ?, ?);") + .build(); + + private static final DatabaseQuery DELETE_PLAYER_ABILITIES = DatabaseQuery.newBuilder() + .query("DELETE FROM pk_player_abilities WHERE player_id = ?") + .build(); + + private static final DatabaseQuery DELETE_PLAYER_ABILITY = DatabaseQuery.newBuilder() + .query("DELETE FROM pk_player_abilities WHERE player_id = ? AND ability_name = ?;") + .build(); + + protected void createTables() throws SQLException + { + Connection connection = getDatabase().getConnection(); + + try (PreparedStatement statement = connection.prepareStatement(CREATE_TABLE_PLAYER_ABILITIES.getQuery())) + { + statement.executeUpdate(); + } + } + + protected String[] selectPlayerAbilities(int playerId) throws SQLException + { + Connection connection = getDatabase().getConnection(); + + try (PreparedStatement statement = connection.prepareStatement(SELECT_PLAYER_ABILITIES.getQuery())) + { + statement.setInt(1, playerId); + + String[] abilities = new String[9]; + + try (ResultSet rs = statement.executeQuery()) + { + while (rs.next()) + { + String abilityName = rs.getString("ability_name"); + int slot = rs.getInt("slot"); + + if (slot < 0 || slot >= abilities.length) + { + // TODO Log illegal slot + continue; + } + + abilities[slot] = abilityName; + } + + return abilities; + } + } + } + + protected void insertPlayerAbility(int playerId, String abilityName, int slot) throws SQLException + { + Connection connection = getDatabase().getConnection(); + + try (PreparedStatement statement = connection.prepareStatement(INSERT_PLAYER_ABILITY.getQuery())) + { + statement.setInt(1, playerId); + statement.setString(2, abilityName); + statement.setInt(3, slot); + + statement.executeUpdate(); + } + } + + protected void deletePlayerAbilities(int playerId) throws SQLException + { + Connection connection = getDatabase().getConnection(); + + try (PreparedStatement statement = connection.prepareStatement(DELETE_PLAYER_ABILITIES.getQuery())) + { + statement.setInt(1, playerId); + + statement.executeUpdate(); + } + } + + protected void deletePlayerAbility(int playerId, String abilityName) throws SQLException + { + Connection connection = getDatabase().getConnection(); + + try (PreparedStatement statement = connection.prepareStatement(DELETE_PLAYER_ABILITY.getQuery())) + { + statement.setInt(1, playerId); + statement.setString(2, abilityName); + + statement.executeUpdate(); + } + } +} diff --git a/src/com/projectkorra/projectkorra/element/ElementManager.java b/src/com/projectkorra/projectkorra/element/ElementManager.java index 3d3efd4e..a5ba11b5 100644 --- a/src/com/projectkorra/projectkorra/element/ElementManager.java +++ b/src/com/projectkorra/projectkorra/element/ElementManager.java @@ -2,8 +2,10 @@ package com.projectkorra.projectkorra.element; import com.google.common.base.Preconditions; import com.projectkorra.projectkorra.module.DatabaseModule; +import com.projectkorra.projectkorra.module.ModuleManager; import com.projectkorra.projectkorra.player.BendingPlayer; import com.projectkorra.projectkorra.player.BendingPlayerLoadedEvent; +import com.projectkorra.projectkorra.player.BendingPlayerManager; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -23,7 +25,10 @@ public class ElementManager extends DatabaseModule private static final String COMBUSTION = "combustion", LIGHTNING = "lightning"; private static final String FLIGHT = "flight", SPIRITUAL = "spiritual"; + private final BendingPlayerManager _bendingPlayerManager; + private final Map _elements = new HashMap<>(); + private final Map _names = new HashMap<>(); private final String _nameRegex = "[a-zA-Z]+"; @@ -37,6 +42,8 @@ public class ElementManager extends DatabaseModule { super("Element", new ElementRepository()); + _bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class); + runAsync(() -> { try @@ -87,7 +94,6 @@ public class ElementManager extends DatabaseModule @EventHandler public void onBendingPlayerLoaded(BendingPlayerLoadedEvent event) { - Player player = event.getPlayer(); BendingPlayer bendingPlayer = event.getBendingPlayer(); runAsync(() -> @@ -107,6 +113,94 @@ public class ElementManager extends DatabaseModule }); } + public boolean addElement(Player player, Element element) + { + BendingPlayer bendingPlayer = _bendingPlayerManager.getBendingPlayer(player); + + if (!bendingPlayer.addElement(element)) + { + return false; + } + + runAsync(() -> + { + try + { + getRepository().insertPlayerElement(bendingPlayer.getId(), element.getId()); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + + return true; + } + + public void setElement(Player player, Element element) + { + BendingPlayer bendingPlayer = _bendingPlayerManager.getBendingPlayer(player); + + bendingPlayer.clearElements(); + bendingPlayer.addElement(element); + + runAsync(() -> + { + try + { + getRepository().deletePlayerElements(bendingPlayer.getId()); + getRepository().insertPlayerElement(bendingPlayer.getId(), element.getId()); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + + public boolean removeElement(Player player, Element element) + { + BendingPlayer bendingPlayer = _bendingPlayerManager.getBendingPlayer(player); + + if (!bendingPlayer.removeElement(element)) + { + return false; + } + + runAsync(() -> + { + try + { + getRepository().deletePlayerElement(bendingPlayer.getId(), element.getId()); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + + return true; + } + + public void clearElements(Player player) + { + BendingPlayer bendingPlayer = _bendingPlayerManager.getBendingPlayer(player); + + bendingPlayer.clearElements(); + + runAsync(() -> + { + try + { + getRepository().deletePlayerElements(bendingPlayer.getId()); + } + catch (SQLException e) + { + e.printStackTrace(); + } + }); + } + private Element addElement(String elementName, String displayName, ChatColor color) { int elementId = registerElement(elementName); @@ -114,6 +208,7 @@ public class ElementManager extends DatabaseModule Element element = new Element(elementId, elementName, displayName, color); _elements.put(elementId, element); + _names.put(elementName, element); return element; } @@ -125,6 +220,7 @@ public class ElementManager extends DatabaseModule SubElement element = new SubElement(elementId, elementName, displayName, color, parent); _elements.put(elementId, element); + _names.put(elementName, element); return element; } diff --git a/src/com/projectkorra/projectkorra/element/ElementRepository.java b/src/com/projectkorra/projectkorra/element/ElementRepository.java index b658381a..1d592389 100644 --- a/src/com/projectkorra/projectkorra/element/ElementRepository.java +++ b/src/com/projectkorra/projectkorra/element/ElementRepository.java @@ -18,7 +18,7 @@ public class ElementRepository extends DatabaseRepository .sqlite("CREATE TABLE IF NOT EXISTS pk_elements (element_id INTEGER PRIMARY KEY AUTOINCREMENT, element_name VARCHAR(50) NOT NULL); CREATE UNIQUE INDEX name_index ON pk_elements (element_name);") .build(); private static final DatabaseQuery CREATE_TABLE_PLAYER_ELEMENTS = DatabaseQuery.newBuilder() - .mysql("CREATE TABLE IF NOT EXISTS pk_player_elements (player_id INTEGER REFERENCES pk_bending_players (player_id), element_id INTEGER REFERENCES pk_elements (element_id), PRIMARY KEY (player_id, element_id)), INDEX player_index (player_id), INDEX element_index (element_id));") + .mysql("CREATE TABLE IF NOT EXISTS pk_player_elements (player_id INTEGER REFERENCES pk_bending_players (player_id), element_id INTEGER REFERENCES pk_elements (element_id), PRIMARY KEY (player_id, element_id), INDEX player_index (player_id), INDEX element_index (element_id));") .sqlite("CREATE TABLE IF NOT EXISTS pk_player_elements (player_id INTEGER REFERENCES pk_bending_players (player_id), element_id INTEGER REFERENCES pk_elements (element_id), PRIMARY KEY (player_id, element_id)); CREATE INDEX player_index ON pk_player_elements (player_id); CREATE INDEX element_index ON pk_player_elements (element_id);") .build(); @@ -38,6 +38,10 @@ public class ElementRepository extends DatabaseRepository .query("INSERT INTO pk_player_elements VALUES (?, ?);") .build(); + private static final DatabaseQuery DELETE_PLAYER_ELEMENTS = DatabaseQuery.newBuilder() + .query("DELETE FROM pk_player_elements WHERE player_id = ?;") + .build(); + private static final DatabaseQuery DELETE_PLAYER_ELEMENT = DatabaseQuery.newBuilder() .query("DELETE FROM pk_player_elements WHERE player_id = ? AND element_id = ?;") .build(); @@ -47,10 +51,10 @@ public class ElementRepository extends DatabaseRepository Connection connection = getDatabase().getConnection(); try - ( - PreparedStatement elements = connection.prepareStatement(CREATE_TABLE_ELEMENTS.getQuery()); - PreparedStatement playerElements = connection.prepareStatement(CREATE_TABLE_PLAYER_ELEMENTS.getQuery()) - ) + ( + PreparedStatement elements = connection.prepareStatement(CREATE_TABLE_ELEMENTS.getQuery()); + PreparedStatement playerElements = connection.prepareStatement(CREATE_TABLE_PLAYER_ELEMENTS.getQuery()) + ) { elements.executeUpdate(); playerElements.executeUpdate(); @@ -131,6 +135,18 @@ public class ElementRepository extends DatabaseRepository } } + protected void deletePlayerElements(int playerId) throws SQLException + { + Connection connection = getDatabase().getConnection(); + + try (PreparedStatement statement = connection.prepareStatement(DELETE_PLAYER_ELEMENTS.getQuery())) + { + statement.setInt(1, playerId); + + statement.executeUpdate(); + } + } + protected void deletePlayerElement(int playerId, int elementId) throws SQLException { Connection connection = getDatabase().getConnection(); diff --git a/src/com/projectkorra/projectkorra/module/ModuleManager.java b/src/com/projectkorra/projectkorra/module/ModuleManager.java index 6f867f92..f8f0dd97 100644 --- a/src/com/projectkorra/projectkorra/module/ModuleManager.java +++ b/src/com/projectkorra/projectkorra/module/ModuleManager.java @@ -1,6 +1,7 @@ package com.projectkorra.projectkorra.module; import com.google.common.base.Preconditions; +import com.projectkorra.projectkorra.ability.AbilityManager; import com.projectkorra.projectkorra.cooldown.CooldownManager; import com.projectkorra.projectkorra.database.DatabaseManager; import com.projectkorra.projectkorra.element.ElementManager; @@ -64,6 +65,7 @@ public class ModuleManager { registerModule(DatabaseManager.class); registerModule(BendingPlayerManager.class); registerModule(ElementManager.class); + registerModule(AbilityManager.class); registerModule(CooldownManager.class); } @@ -72,6 +74,7 @@ public class ModuleManager { */ public static void shutdown() { registerModule(CooldownManager.class); + registerModule(AbilityManager.class); registerModule(ElementManager.class); getModule(BendingPlayerManager.class).disable(); getModule(DatabaseManager.class).disable(); diff --git a/src/com/projectkorra/projectkorra/player/BendingPlayer.java b/src/com/projectkorra/projectkorra/player/BendingPlayer.java index b072f20c..669be722 100644 --- a/src/com/projectkorra/projectkorra/player/BendingPlayer.java +++ b/src/com/projectkorra/projectkorra/player/BendingPlayer.java @@ -1,6 +1,7 @@ package com.projectkorra.projectkorra.player; import com.projectkorra.projectkorra.ability.Ability; +import com.projectkorra.projectkorra.ability.AbilityManager; import com.projectkorra.projectkorra.ability.ChiAbility; import com.projectkorra.projectkorra.ability.CoreAbility; import com.projectkorra.projectkorra.ability.util.PassiveManager; @@ -10,7 +11,9 @@ import com.projectkorra.projectkorra.element.ElementManager; import com.projectkorra.projectkorra.module.ModuleManager; import org.bukkit.entity.Player; +import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.UUID; @@ -18,6 +21,7 @@ public class BendingPlayer { private final BendingPlayerManager manager; private final ElementManager elementManager; + private final AbilityManager abilityManager; private final CooldownManager cooldownManager; private final int playerId; @@ -42,6 +46,7 @@ public class BendingPlayer { this.manager = ModuleManager.getModule(BendingPlayerManager.class); this.elementManager = ModuleManager.getModule(ElementManager.class); + this.abilityManager = ModuleManager.getModule(AbilityManager.class); this.cooldownManager = ModuleManager.getModule(CooldownManager.class); this.playerId = playerId; @@ -55,15 +60,24 @@ public class BendingPlayer this.abilities = new String[9]; } - public void addElement(Element element) + public Set getElements() { - this.elements.add(element); + return new HashSet<>(this.elements); } - public void setElement(Element element) + public boolean addElement(Element element) + { + return this.elements.add(element); + } + + public boolean removeElement(Element element) + { + return this.elements.remove(element); + } + + public void clearElements() { this.elements.clear(); - this.elements.add(element); } public boolean hasElement(Element element) @@ -159,6 +173,26 @@ public class BendingPlayer return this.abilities[slot]; } + public String getAbility(int slot) + { + return this.abilities[slot]; + } + + public List getAbilities() + { + return Arrays.asList(this.abilities); + } + + public void setAbilities(String[] abilities) + { + System.arraycopy(abilities, 0, this.abilities, 0, 9); + } + + public void setAbility(int slot, String abilityName) + { + this.abilities[slot] = abilityName; + } + public void addCooldown(Ability ability) { addCooldown(ability, ability.getCooldown());