浏览代码

Update SQL schema when missing columns

nossr50 1 年之前
父节点
当前提交
3fbb4827ca

+ 76 - 21
src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java

@@ -567,8 +567,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
         try {
             statement = connection.prepareStatement(
                     "UPDATE `" + tablePrefix + "users` "
-                            + "SET \"USER\" = ? "
-                            + "WHERE \"USER\" = ?");
+                            + "SET `USER` = ? "
+                            + "WHERE `USER` = ?");
             statement.setString(1, "_INVALID_OLD_USERNAME_");
             statement.setString(2, playerName);
             statement.executeUpdate();
@@ -650,9 +650,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
             statement = connection.prepareStatement(
                     "SELECT " +
                             "S.TAMING, S.MINING, S.REPAIR, S.WOODCUTTING, S.UNARMED, S.HERBALISM, S.EXCAVATION, S.ARCHERY, S.SWORDS, S.AXES, S.ACROBATICS, S.FISHING, S.ALCHEMY, S.CROSSBOWS, S.TRIDENTS, " +
-                            "E.TAMING, E.MINING, E.REPAIR, E.WOODCUTTING, E.UNARMED, E.HERBALISM, E.EXCAVATION, E.ARCHERY, E.SWORDS, E.AXES, E.ACROBATICS, E.FISHING, E.ALCHEMY, S.CROSSBOWS, S.TRIDENTS, " +
+                            "E.TAMING, E.MINING, E.REPAIR, E.WOODCUTTING, E.UNARMED, E.HERBALISM, E.EXCAVATION, E.ARCHERY, E.SWORDS, E.AXES, E.ACROBATICS, E.FISHING, E.ALCHEMY, E.CROSSBOWS, E.TRIDENTS, " +
                             "C.TAMING, C.MINING, C.REPAIR, C.WOODCUTTING, C.UNARMED, C.HERBALISM, C.EXCAVATION, C.ARCHERY, C.SWORDS, C.AXES, C.ACROBATICS, C.BLAST_MINING, C.CHIMAERA_WING, C.CROSSBOWS, C.TRIDENTS, " +
-                            "H.MOBHEALTHBAR, H.SCOREBOARDTIPS, U.UUID, U.\"USER\" " +
+                            "H.MOBHEALTHBAR, H.SCOREBOARDTIPS, U.UUID, U.`USER` " +
                             "FROM " + tablePrefix + "USERS U " +
                             "JOIN " + tablePrefix + "SKILLS S ON U.ID = S.USER_ID " +
                             "JOIN " + tablePrefix + "EXPERIENCE E ON U.ID = E.USER_ID " +
@@ -664,6 +664,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
 
             resultSet = statement.executeQuery();
 
+
             if (resultSet.next()) {
                 try {
                     PlayerProfile profile = loadFromResult(playerName, resultSet);
@@ -677,15 +678,15 @@ public final class SQLDatabaseManager implements DatabaseManager {
                             && uuid != null) {
                         statement = connection.prepareStatement(
                                 "UPDATE `" + tablePrefix + "users` "
-                                        + "SET \"USER\" = ? "
-                                        + "WHERE \"USER\" = ?");
+                                        + "SET `USER` = ? "
+                                        + "WHERE `USER` = ?");
                         statement.setString(1, "_INVALID_OLD_USERNAME_");
                         statement.setString(2, name);
                         statement.executeUpdate();
                         statement.close();
                         statement = connection.prepareStatement(
                                 "UPDATE `" + tablePrefix + "users` "
-                                        + "SET \"USER\" = ?, uuid = ? "
+                                        + "SET `USER` = ?, uuid = ? "
                                         + "WHERE id = ?");
                         statement.setString(1, playerName);
                         statement.setString(2, uuid.toString());
@@ -859,7 +860,6 @@ public final class SQLDatabaseManager implements DatabaseManager {
      * Checks that the database structure is present and correct
      */
     private void checkStructure() {
-
         PreparedStatement statement = null;
         Statement createStatement = null;
         ResultSet resultSet = null;
@@ -1019,6 +1019,68 @@ public final class SQLDatabaseManager implements DatabaseManager {
             tryClose(connection);
         }
 
+        updateStructure("SKILLS", "CROSSBOWS", String.valueOf(32));
+        updateStructure("SKILLS", "TRIDENTS", String.valueOf(32));
+
+        updateStructure("EXPERIENCE", "CROSSBOWS", String.valueOf(10));
+        updateStructure("EXPERIENCE", "TRIDENTS", String.valueOf(10));
+
+        updateStructure("COOLDOWNS", "CROSSBOWS", String.valueOf(10));
+        updateStructure("COOLDOWNS", "TRIDENTS", String.valueOf(10));
+    }
+
+    private void updateStructure(String tableName, String columnName, String columnSize) {
+        boolean columnExists = false;
+        DatabaseMetaData metaData = null;
+
+        try(Connection connection = getConnection(PoolIdentifier.MISC)) {
+            metaData = connection.getMetaData();
+            ResultSet rs = null;
+
+            try {
+                // Replace "YOUR_SCHEMA" with your database schema name if necessary, or use null to not filter by schema.
+                // Replace "YOUR_TABLE" with the actual table name, and "YOUR_COLUMN" with the column you're checking for.
+                rs = metaData.getColumns(null, null, tablePrefix + tableName, columnName);
+
+                if (rs.next()) {
+                    // If the result set is not empty, the column exists
+                    columnExists = true;
+                }
+            } catch (SQLException e) {
+                e.printStackTrace(); // Handle the exception appropriately
+            } finally {
+                if (rs != null) {
+                    try {
+                        rs.close();
+                    } catch (SQLException e) {
+                        e.printStackTrace(); // Handle the exception appropriately
+                    }
+                }
+            }
+
+            if (!columnExists) {
+                // Alter the table to add the column
+                Statement createStatement = null;
+                try {
+                    createStatement = connection.createStatement();
+                    String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'";
+                    createStatement.executeUpdate("ALTER TABLE `" + tablePrefix + tableName + "` "
+                            + "ADD COLUMN `" + columnName + "` int(" + columnSize + ") unsigned NOT NULL DEFAULT " + startingLevel);
+                } catch (SQLException e) {
+                    e.printStackTrace(); // Handle the exception appropriately
+                } finally {
+                    if (createStatement != null) {
+                        try {
+                            createStatement.close();
+                        } catch (SQLException e) {
+                            e.printStackTrace(); // Handle the exception appropriately
+                        }
+                    }
+                }
+            }
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     private void setStatementQuery(PreparedStatement statement, String tableName) throws SQLException {
@@ -1032,19 +1094,12 @@ public final class SQLDatabaseManager implements DatabaseManager {
         }
     }
 
-    protected Connection getConnection(PoolIdentifier identifier) throws SQLException {
-        Connection connection = null;
-        switch (identifier) {
-            case LOAD:
-                connection = loadPool.getConnection();
-                break;
-            case MISC:
-                connection = miscPool.getConnection();
-                break;
-            case SAVE:
-                connection = savePool.getConnection();
-                break;
-        }
+    Connection getConnection(PoolIdentifier identifier) throws SQLException {
+        Connection connection = switch (identifier) {
+            case LOAD -> loadPool.getConnection();
+            case MISC -> miscPool.getConnection();
+            case SAVE -> savePool.getConnection();
+        };
         if (connection == null) {
             throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase(Locale.ENGLISH) + " pool timed out.  Increase max connections settings.");
         }

+ 30 - 5
src/main/java/com/gmail/nossr50/skills/crossbows/CrossbowsManager.java

@@ -2,8 +2,12 @@ package com.gmail.nossr50.skills.crossbows;
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.skills.SkillManager;
 import com.gmail.nossr50.util.MetadataConstants;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.random.ProbabilityUtil;
+import com.gmail.nossr50.util.skills.RankUtils;
 import org.bukkit.Location;
 import org.bukkit.entity.Arrow;
 import org.bukkit.metadata.FixedMetadataValue;
@@ -12,19 +16,34 @@ import org.bukkit.projectiles.ProjectileSource;
 import org.bukkit.util.Vector;
 import org.jetbrains.annotations.NotNull;
 
+import static com.gmail.nossr50.util.random.ProbabilityUtil.isStaticSkillRNGSuccessful;
+
 public class CrossbowsManager extends SkillManager {
     public CrossbowsManager(McMMOPlayer mmoPlayer) {
         super(mmoPlayer, PrimarySkillType.CROSSBOWS);
     }
 
     public void handleRicochet(@NotNull Plugin pluginRef, @NotNull Arrow originalArrow, @NotNull Vector hitBlockNormal) {
-        // Reflect arrow in new direction
-        // cleanup metadata on original arrow
+        // Check player permission
+        if (!Permissions.trickShot(mmoPlayer.getPlayer())) {
+            return;
+        }
+
         // TODO: Add an event for this for plugins to hook into
         spawnReflectedArrow(pluginRef, originalArrow, originalArrow.getLocation(), hitBlockNormal);
     }
 
-    public void spawnReflectedArrow(@NotNull Plugin pluginRef, @NotNull Arrow originalArrow, @NotNull Location origin, @NotNull Vector normal) {
+    public void spawnReflectedArrow(@NotNull Plugin pluginRef, @NotNull Arrow originalArrow,
+                                    @NotNull Location origin, @NotNull Vector normal) {
+        int bounceCount = 0;
+
+        if (originalArrow.hasMetadata(MetadataConstants.METADATA_KEY_BOUNCE_COUNT)) {
+            bounceCount = originalArrow.getMetadata(MetadataConstants.METADATA_KEY_BOUNCE_COUNT).get(0).asInt();
+            if (bounceCount >= getTrickShotMaxBounceCount()) {
+                return;
+            }
+        }
+
         final ProjectileSource originalArrowShooter = originalArrow.getShooter();
         final Vector arrowInBlockVector = originalArrow.getVelocity();
         final Vector reflectedDirection = arrowInBlockVector.subtract(normal.multiply(2 * arrowInBlockVector.dot(normal)));
@@ -40,12 +59,18 @@ public class CrossbowsManager extends SkillManager {
         Arrow arrow = originalArrow.getWorld().spawnArrow(origin,
                 reflectedDirection, 1, 1);
         arrow.setShooter(originalArrowShooter);
+        arrow.setMetadata(MetadataConstants.METADATA_KEY_BOUNCE_COUNT,
+                new FixedMetadataValue(pluginRef, bounceCount + 1));
         arrow.setMetadata(MetadataConstants.METADATA_KEY_SPAWNED_ARROW,
                 new FixedMetadataValue(pluginRef, originalArrowShooter));
-
-        // TODO: This metadata needs to get cleaned up at some point
         arrow.setMetadata(MetadataConstants.METADATA_KEY_BOW_TYPE,
                 new FixedMetadataValue(pluginRef, originalArrow.getMetadata(
                         MetadataConstants.METADATA_KEY_BOW_TYPE).get(0)));
+
+        originalArrow.remove();
+    }
+
+    public int getTrickShotMaxBounceCount() {
+        return RankUtils.getRank(mmoPlayer, SubSkillType.CROSSBOWS_TRICK_SHOT);
     }
 }

+ 1 - 0
src/main/java/com/gmail/nossr50/util/MetadataConstants.java

@@ -15,6 +15,7 @@ public class MetadataConstants {
      */
     public static final @NotNull String METADATA_KEY_REPLANT = "mcMMO: Recently Replanted";
     public static final @NotNull String METADATA_KEY_SPAWNED_ARROW = "mcMMO: Spawned Arrow";
+    public static final @NotNull String METADATA_KEY_BOUNCE_COUNT = "mcMMO: Arrow Bounce Count";
     public static final @NotNull String METADATA_KEY_BOW_TYPE = "mcMMO: Bow Type";
     public static final @NotNull String METADATA_KEY_EXPLOSION_FROM_RUPTURE = "mcMMO: Rupture Explosion";
     public static final @NotNull String METADATA_KEY_FISH_HOOK_REF = "mcMMO: Fish Hook Tracker";

+ 3 - 0
src/main/java/com/gmail/nossr50/util/Permissions.java

@@ -228,6 +228,9 @@ public final class Permissions {
     public static boolean treeFeller(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.woodcutting.treefeller"); }
     /* CROSSBOWS */
     public static boolean superShotgun(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.crossbows.supershotgun"); }
+    public static boolean trickShot(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.crossbows.trickshot"); }
+
+    /* TRIDENTS */
     public static boolean tridentsSuper(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); }
     public static boolean tridentsLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); }