Update SQL schema when missing columns

This commit is contained in:
nossr50 2024-01-03 00:19:57 -08:00
parent 8cc4798752
commit 3fbb4827ca
4 changed files with 110 additions and 26 deletions

View File

@ -567,8 +567,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
try { try {
statement = connection.prepareStatement( statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` " "UPDATE `" + tablePrefix + "users` "
+ "SET \"USER\" = ? " + "SET `USER` = ? "
+ "WHERE \"USER\" = ?"); + "WHERE `USER` = ?");
statement.setString(1, "_INVALID_OLD_USERNAME_"); statement.setString(1, "_INVALID_OLD_USERNAME_");
statement.setString(2, playerName); statement.setString(2, playerName);
statement.executeUpdate(); statement.executeUpdate();
@ -650,9 +650,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement = connection.prepareStatement( statement = connection.prepareStatement(
"SELECT " + "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, " + "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, " + "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 " + "FROM " + tablePrefix + "USERS U " +
"JOIN " + tablePrefix + "SKILLS S ON U.ID = S.USER_ID " + "JOIN " + tablePrefix + "SKILLS S ON U.ID = S.USER_ID " +
"JOIN " + tablePrefix + "EXPERIENCE E ON U.ID = E.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(); resultSet = statement.executeQuery();
if (resultSet.next()) { if (resultSet.next()) {
try { try {
PlayerProfile profile = loadFromResult(playerName, resultSet); PlayerProfile profile = loadFromResult(playerName, resultSet);
@ -677,15 +678,15 @@ public final class SQLDatabaseManager implements DatabaseManager {
&& uuid != null) { && uuid != null) {
statement = connection.prepareStatement( statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` " "UPDATE `" + tablePrefix + "users` "
+ "SET \"USER\" = ? " + "SET `USER` = ? "
+ "WHERE \"USER\" = ?"); + "WHERE `USER` = ?");
statement.setString(1, "_INVALID_OLD_USERNAME_"); statement.setString(1, "_INVALID_OLD_USERNAME_");
statement.setString(2, name); statement.setString(2, name);
statement.executeUpdate(); statement.executeUpdate();
statement.close(); statement.close();
statement = connection.prepareStatement( statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` " "UPDATE `" + tablePrefix + "users` "
+ "SET \"USER\" = ?, uuid = ? " + "SET `USER` = ?, uuid = ? "
+ "WHERE id = ?"); + "WHERE id = ?");
statement.setString(1, playerName); statement.setString(1, playerName);
statement.setString(2, uuid.toString()); statement.setString(2, uuid.toString());
@ -859,7 +860,6 @@ public final class SQLDatabaseManager implements DatabaseManager {
* Checks that the database structure is present and correct * Checks that the database structure is present and correct
*/ */
private void checkStructure() { private void checkStructure() {
PreparedStatement statement = null; PreparedStatement statement = null;
Statement createStatement = null; Statement createStatement = null;
ResultSet resultSet = null; ResultSet resultSet = null;
@ -1019,6 +1019,68 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(connection); 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 { 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 getConnection(PoolIdentifier identifier) throws SQLException {
Connection connection = null; Connection connection = switch (identifier) {
switch (identifier) { case LOAD -> loadPool.getConnection();
case LOAD: case MISC -> miscPool.getConnection();
connection = loadPool.getConnection(); case SAVE -> savePool.getConnection();
break; };
case MISC:
connection = miscPool.getConnection();
break;
case SAVE:
connection = savePool.getConnection();
break;
}
if (connection == null) { if (connection == null) {
throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase(Locale.ENGLISH) + " pool timed out. Increase max connections settings."); throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase(Locale.ENGLISH) + " pool timed out. Increase max connections settings.");
} }

View File

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

View File

@ -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_REPLANT = "mcMMO: Recently Replanted";
public static final @NotNull String METADATA_KEY_SPAWNED_ARROW = "mcMMO: Spawned Arrow"; 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_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_EXPLOSION_FROM_RUPTURE = "mcMMO: Rupture Explosion";
public static final @NotNull String METADATA_KEY_FISH_HOOK_REF = "mcMMO: Fish Hook Tracker"; public static final @NotNull String METADATA_KEY_FISH_HOOK_REF = "mcMMO: Fish Hook Tracker";

View File

@ -228,6 +228,9 @@ public final class Permissions {
public static boolean treeFeller(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.woodcutting.treefeller"); } public static boolean treeFeller(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.woodcutting.treefeller"); }
/* CROSSBOWS */ /* CROSSBOWS */
public static boolean superShotgun(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.crossbows.supershotgun"); } 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 tridentsSuper(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); }
public static boolean tridentsLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); } public static boolean tridentsLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); }