瀏覽代碼

Chimaera Wing exploit fix

nossr50 6 年之前
父節點
當前提交
626890ed95

+ 2 - 1
Changelog.txt

@@ -25,6 +25,7 @@ Version 2.1.0
  + (API) Added many missing SubSkills to SubSkillType class
  + (Permissions) Added permission node mcmmo.commands.mcchatspy & mcmmo.commands.mcchatspy.others
  + (Permissions) Added permission nodes for Harvest Lumber, Splinter, Nature's Bounty, and Bark Surgeon
+ + (Permissions) Added mcmmo.commands.mmoinfo for the new mmoinfo/mcinfo command
  + (Locale) Added locale strings for new Woodcutting abilities
  + (Locale) Added locale strings for mcchatspy command
  + (Locale) Added locale strings for JSON integration
@@ -33,6 +34,7 @@ Version 2.1.0
  - (Locale) Removed localizations with the following codes for being almost empty: id, HR_hr, et_EE, lv, lt, no, pl_PL, pt_PT, tr_TR
  - (Config) Removed SkillShot's IncreaseLevel & IncreasePercentage (replaced by RankDamageMultiplier)
  - (Config) Removed AxeMastery's MaxBonus & MaxBonusLevel (replaced by RankDamageMultiplier)
+ = (Items) Chimaera Wing now tracks cooldowns between sessions for players (no more disconnect abuse)
  = (Skills) Added missing mushroom blocks to experience.yml defaults
  = (Skills) Tridents will no longer be considered unarmed
  = (MySQL) You can now inspect offline players
@@ -51,7 +53,6 @@ Version 2.1.0
  ! (Config) Axes.CriticalHit in advanced.yml is now Axes.CriticalStrikes
  ! (Config) Archery's Skill Shot now uses RankDamageMultiplier for its damage bonus calculations
  ! (Config) Axe's Axe mastery now uses RankDamageMultiplier for its damage bonus calculations
- + (Permissions) Added mcmmo.commands.mmoinfo for the new mmoinfo/mcinfo command
  ! (Permissions) Replaced the old Double Drop permission node for woodcutting with a new Harvest Lumber permission node
  ! (Permissions) Fast Food Service permission node renamed to mcmmo.ability.taming.fastfoodservice
  ! (Permissions) Counter Attack permission node renamed to mcmmo.ability.swords.counterattack

+ 12 - 1
src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java

@@ -17,6 +17,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
+import com.gmail.nossr50.datatypes.player.UniqueDataType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 import com.gmail.nossr50.datatypes.skills.SuperAbility;
 import org.bukkit.OfflinePlayer;
@@ -320,6 +321,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
                         writer.append(profile.getSkillXpLevel(PrimarySkill.ALCHEMY)).append(":");
                         writer.append(uuid != null ? uuid.toString() : "NULL").append(":");
                         writer.append(profile.getScoreboardTipsShown()).append(":");
+                        writer.append(profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS)).append(":");
                         writer.append("\r\n");
                     }
                 }
@@ -1130,6 +1132,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
         Map<PrimarySkill, Integer>   skills     = getSkillMapFromLine(character);      // Skill levels
         Map<PrimarySkill, Float>     skillsXp   = new EnumMap<PrimarySkill, Float>(PrimarySkill.class);     // Skill & XP
         Map<SuperAbility, Integer> skillsDATS = new EnumMap<SuperAbility, Integer>(SuperAbility.class); // Ability & Cooldown
+        Map<UniqueDataType, Integer> uniquePlayerDataMap = new EnumMap<UniqueDataType, Integer>(UniqueDataType.class);
         MobHealthbarType mobHealthbarType;
         int scoreboardTipsShown;
 
@@ -1184,7 +1187,14 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
             scoreboardTipsShown = 0;
         }
 
-        return new PlayerProfile(character[USERNAME], uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown);
+        try {
+            uniquePlayerDataMap.put(UniqueDataType.CHIMAERA_WING_DATS, Integer.valueOf(character[COOLDOWN_CHIMAERA_WING]));
+        }
+        catch (Exception e) {
+            uniquePlayerDataMap.put(UniqueDataType.CHIMAERA_WING_DATS, 0);
+        }
+
+        return new PlayerProfile(character[USERNAME], uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown, uniquePlayerDataMap);
     }
 
     private Map<PrimarySkill, Integer> getSkillMapFromLine(String[] character) {
@@ -1287,6 +1297,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
     public static int EXP_ALCHEMY = 40;
     public static int UUID_INDEX = 41;
     public static int SCOREBOARD_TIPS = 42;
+    public static int COOLDOWN_CHIMAERA_WING = 43;
 
     public void resetMobHealthSettings() {
         BufferedReader in = null;

+ 25 - 6
src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java

@@ -6,6 +6,7 @@ import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
 import com.gmail.nossr50.datatypes.database.UpgradeType;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
+import com.gmail.nossr50.datatypes.player.UniqueDataType;
 import com.gmail.nossr50.datatypes.skills.SuperAbility;
 import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 import com.gmail.nossr50.mcMMO;
@@ -280,7 +281,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
             statement = connection.prepareStatement("UPDATE " + tablePrefix + "cooldowns SET "
                     + "  mining = ?, woodcutting = ?, unarmed = ?"
                     + ", herbalism = ?, excavation = ?, swords = ?"
-                    + ", axes = ?, blast_mining = ? WHERE user_id = ?");
+                    + ", axes = ?, blast_mining = ?, chimaera_wing = ? WHERE user_id = ?");
             statement.setLong(1, profile.getAbilityDATS(SuperAbility.SUPER_BREAKER));
             statement.setLong(2, profile.getAbilityDATS(SuperAbility.TREE_FELLER));
             statement.setLong(3, profile.getAbilityDATS(SuperAbility.BERSERK));
@@ -289,7 +290,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
             statement.setLong(6, profile.getAbilityDATS(SuperAbility.SERRATED_STRIKES));
             statement.setLong(7, profile.getAbilityDATS(SuperAbility.SKULL_SPLITTER));
             statement.setLong(8, profile.getAbilityDATS(SuperAbility.BLAST_MINING));
-            statement.setInt(9, id);
+            statement.setLong(9, profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS));
+            statement.setInt(10, id);
             success = (statement.executeUpdate() != 0);
             statement.close();
             if (!success) {
@@ -546,7 +548,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                     "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, "
                             + "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, "
-                            + "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.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, "
                             + "h.mobhealthbar, h.scoreboardtips, u.uuid, u.user "
                             + "FROM " + tablePrefix + "users u "
                             + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
@@ -624,7 +626,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                     "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, "
                             + "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, "
-                            + "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.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, "
                             + "h.mobhealthbar, h.scoreboardtips, u.uuid "
                             + "FROM " + tablePrefix + "users u "
                             + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
@@ -817,6 +819,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                         + "`axes` int(32) unsigned NOT NULL DEFAULT '0',"
                         + "`acrobatics` int(32) unsigned NOT NULL DEFAULT '0',"
                         + "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
+                        + "`chimaera_wing` int(32) unsigned NOT NULL DEFAULT '0',"
                         + "PRIMARY KEY (`user_id`)) "
                         + "DEFAULT CHARSET=latin1;");
                 tryClose(createStatement);
@@ -988,6 +991,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 case ADD_SKILL_TOTAL:
                     checkUpgradeSkillTotal(connection);
                     break;
+                case ADD_UNIQUE_PLAYER_DATA:
+                    checkUpgradeAddUniqueChimaeraWing(statement);
+                    break;
 
                 default:
                     break;
@@ -1042,6 +1048,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
         Map<PrimarySkill, Integer> skills = new EnumMap<PrimarySkill, Integer>(PrimarySkill.class); // Skill & Level
         Map<PrimarySkill, Float> skillsXp = new EnumMap<PrimarySkill, Float>(PrimarySkill.class); // Skill & XP
         Map<SuperAbility, Integer> skillsDATS = new EnumMap<SuperAbility, Integer>(SuperAbility.class); // Ability & Cooldown
+        Map<UniqueDataType, Integer> uniqueData = new EnumMap<UniqueDataType, Integer>(UniqueDataType.class); //Chimaera wing cooldown and other misc info
         MobHealthbarType mobHealthbarType;
         UUID uuid;
         int scoreboardTipsShown;
@@ -1050,7 +1057,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
         // changes (a new skill is added)
         final int OFFSET_XP = 13;
         final int OFFSET_DATS = 26;
-        final int OFFSET_OTHER = 38;
+        final int OFFSET_OTHER = 39;
 
         skills.put(PrimarySkill.TAMING, result.getInt(OFFSET_SKILLS + 1));
         skills.put(PrimarySkill.MINING, result.getInt(OFFSET_SKILLS + 2));
@@ -1092,6 +1099,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
         skillsDATS.put(SuperAbility.SKULL_SPLITTER, result.getInt(OFFSET_DATS + 10));
         // Acrobatics - Unused - result.getInt(OFFSET_DATS + 11)
         skillsDATS.put(SuperAbility.BLAST_MINING, result.getInt(OFFSET_DATS + 12));
+        uniqueData.put(UniqueDataType.CHIMAERA_WING_DATS, result.getInt(OFFSET_DATS + 13));
+
 
         try {
             mobHealthbarType = MobHealthbarType.valueOf(result.getString(OFFSET_OTHER + 1));
@@ -1114,7 +1123,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
             uuid = null;
         }
 
-        return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown);
+        return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown, uniqueData);
     }
 
     private void printErrors(SQLException ex) {
@@ -1171,6 +1180,16 @@ public final class SQLDatabaseManager implements DatabaseManager {
         }
     }
 
+    private void checkUpgradeAddUniqueChimaeraWing(final Statement statement) throws SQLException {
+        try {
+            statement.executeQuery("SELECT `chimaera_wing` FROM `" + tablePrefix + "cooldowns` LIMIT 1");
+        }
+        catch (SQLException ex) {
+            mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Chimaera Wing...");
+            statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `chimaera_wing` int(32) NOT NULL DEFAULT '0'");
+        }
+    }
+
     private void checkUpgradeAddFishing(final Statement statement) throws SQLException {
         try {
             statement.executeQuery("SELECT `fishing` FROM `" + tablePrefix + "skills` LIMIT 1");

+ 1 - 0
src/main/java/com/gmail/nossr50/datatypes/database/UpgradeType.java

@@ -13,4 +13,5 @@ public enum UpgradeType {
     ADD_SCOREBOARD_TIPS,
     DROP_NAME_UNIQUENESS,
     ADD_SKILL_TOTAL,
+    ADD_UNIQUE_PLAYER_DATA,
 }

+ 3 - 3
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -87,7 +87,7 @@ public class McMMOPlayer {
     private int respawnATS;
     private int teleportATS;
     private long databaseATS;
-    private int chimeraWingLastUse;
+    //private int chimeraWingLastUse;
     private Location teleportCommence;
 
     private boolean isUsingUnarmed;
@@ -306,11 +306,11 @@ public class McMMOPlayer {
      */
 
     public int getChimeraWingLastUse() {
-        return chimeraWingLastUse;
+        return profile.getChimaerWingDATS();
     }
 
     public void actualizeChimeraWingLastUse() {
-        chimeraWingLastUse = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
+        profile.setChimaeraWingDATS((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR));
     }
 
     public Location getTeleportCommenceLocation() {

+ 21 - 2
src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java

@@ -34,6 +34,7 @@ public class PlayerProfile {
     private final Map<PrimarySkill, Integer>   skills     = new HashMap<PrimarySkill, Integer>();   // Skill & Level
     private final Map<PrimarySkill, Float>     skillsXp   = new HashMap<PrimarySkill, Float>();     // Skill & XP
     private final Map<SuperAbility, Integer> abilityDATS = new HashMap<SuperAbility, Integer>(); // Ability & Cooldown
+    private final Map<UniqueDataType, Integer> uniquePlayerData = new HashMap<>(); //Misc data that doesn't fit into other categories (chimaera wing, etc..)
 
     // Store previous XP gains for deminished returns
     private DelayQueue<SkillXpGain> gainedSkillsXp = new DelayQueue<SkillXpGain>();
@@ -59,6 +60,9 @@ public class PlayerProfile {
             skills.put(primarySkill, 0);
             skillsXp.put(primarySkill, 0F);
         }
+
+        //Misc Cooldowns
+        uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, 0); //Chimaera wing
     }
 
     @Deprecated
@@ -72,7 +76,7 @@ public class PlayerProfile {
         this.loaded = isLoaded;
     }
 
-    public PlayerProfile(String playerName, UUID uuid, Map<PrimarySkill, Integer> levelData, Map<PrimarySkill, Float> xpData, Map<SuperAbility, Integer> cooldownData, MobHealthbarType mobHealthbarType, int scoreboardTipsShown) {
+    public PlayerProfile(String playerName, UUID uuid, Map<PrimarySkill, Integer> levelData, Map<PrimarySkill, Float> xpData, Map<SuperAbility, Integer> cooldownData, MobHealthbarType mobHealthbarType, int scoreboardTipsShown, Map<UniqueDataType, Integer> uniqueProfileData) {
         this.playerName = playerName;
         this.uuid = uuid;
         this.mobHealthbarType = mobHealthbarType;
@@ -81,6 +85,7 @@ public class PlayerProfile {
         skills.putAll(levelData);
         skillsXp.putAll(xpData);
         abilityDATS.putAll(cooldownData);
+        uniquePlayerData.putAll(uniqueProfileData);
 
         loaded = true;
     }
@@ -95,7 +100,7 @@ public class PlayerProfile {
         }
 
         // TODO should this part be synchronized?
-        PlayerProfile profileCopy = new PlayerProfile(playerName, uuid, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType, scoreboardTipsShown);
+        PlayerProfile profileCopy = new PlayerProfile(playerName, uuid, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType, scoreboardTipsShown, ImmutableMap.copyOf(uniquePlayerData));
         changed = !mcMMO.getDatabaseManager().saveUser(profileCopy);
 
         if (changed) {
@@ -153,6 +158,20 @@ public class PlayerProfile {
      * Cooldowns
      */
 
+    public int getChimaerWingDATS() { return uniquePlayerData.get(UniqueDataType.CHIMAERA_WING_DATS);}
+
+    protected void setChimaeraWingDATS(int DATS) {
+        changed = true;
+        uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, DATS);
+    }
+
+    public void setUniqueData(UniqueDataType uniqueDataType, int newData) {
+        changed = true;
+        uniquePlayerData.put(uniqueDataType, newData);
+    }
+
+    public long getUniqueData(UniqueDataType uniqueDataType) { return uniquePlayerData.get(uniqueDataType); }
+
     /**
      * Get the current deactivation timestamp of an ability.
      *

+ 5 - 0
src/main/java/com/gmail/nossr50/datatypes/player/UniqueDataType.java

@@ -0,0 +1,5 @@
+package com.gmail.nossr50.datatypes.player;
+
+public enum UniqueDataType {
+    CHIMAERA_WING_DATS
+}