Browse Source

Merge pull request #284 from Glitchfinder/master

Attempting to resolve various issues in the issue tracker.
Grant 12 năm trước cách đây
mục cha
commit
b57cc7bd59
37 tập tin đã thay đổi với 362 bổ sung13 xóa
  1. 16 0
      src/main/java/com/gmail/nossr50/commands/CommandHelper.java
  2. 5 0
      src/main/java/com/gmail/nossr50/commands/SkillCommand.java
  3. 5 0
      src/main/java/com/gmail/nossr50/commands/general/AddlevelsCommand.java
  4. 5 0
      src/main/java/com/gmail/nossr50/commands/general/AddxpCommand.java
  5. 5 0
      src/main/java/com/gmail/nossr50/commands/general/InspectCommand.java
  6. 10 0
      src/main/java/com/gmail/nossr50/commands/general/MmoeditCommand.java
  7. 6 0
      src/main/java/com/gmail/nossr50/commands/general/SkillResetCommand.java
  8. 5 0
      src/main/java/com/gmail/nossr50/commands/mc/McabilityCommand.java
  9. 5 0
      src/main/java/com/gmail/nossr50/commands/mc/McgodCommand.java
  10. 5 0
      src/main/java/com/gmail/nossr50/commands/mc/McrefreshCommand.java
  11. 1 0
      src/main/java/com/gmail/nossr50/commands/party/PtpCommand.java
  12. 3 3
      src/main/java/com/gmail/nossr50/config/Config.java
  13. 4 0
      src/main/java/com/gmail/nossr50/config/mods/CustomArmorConfig.java
  14. 4 0
      src/main/java/com/gmail/nossr50/config/mods/CustomBlocksConfig.java
  15. 4 0
      src/main/java/com/gmail/nossr50/config/mods/CustomToolsConfig.java
  16. 3 3
      src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java
  17. 3 0
      src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsEventHandler.java
  18. 6 0
      src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java
  19. 6 0
      src/main/java/com/gmail/nossr50/skills/acrobatics/DodgeEventHandler.java
  20. 9 0
      src/main/java/com/gmail/nossr50/skills/acrobatics/RollEventHandler.java
  21. 18 0
      src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java
  22. 14 0
      src/main/java/com/gmail/nossr50/skills/combat/Axes.java
  23. 12 0
      src/main/java/com/gmail/nossr50/skills/gathering/BlastMining.java
  24. 6 0
      src/main/java/com/gmail/nossr50/skills/gathering/Excavation.java
  25. 15 7
      src/main/java/com/gmail/nossr50/skills/gathering/Fishing.java
  26. 40 0
      src/main/java/com/gmail/nossr50/skills/gathering/WoodCutting.java
  27. 6 0
      src/main/java/com/gmail/nossr50/skills/swords/CounterAttackEventHandler.java
  28. 3 0
      src/main/java/com/gmail/nossr50/skills/swords/SerratedStrikesEventHandler.java
  29. 18 0
      src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java
  30. 3 0
      src/main/java/com/gmail/nossr50/skills/taming/BeastLoreEventHandler.java
  31. 18 0
      src/main/java/com/gmail/nossr50/skills/taming/CallOfTheWildEventHandler.java
  32. 6 0
      src/main/java/com/gmail/nossr50/skills/taming/EnvironmentallyAwareEventHandler.java
  33. 48 0
      src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
  34. 24 0
      src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java
  35. 11 0
      src/main/java/com/gmail/nossr50/util/ItemChecks.java
  36. 6 0
      src/main/java/com/gmail/nossr50/util/Skills.java
  37. 4 0
      src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkletManager.java

+ 16 - 0
src/main/java/com/gmail/nossr50/commands/CommandHelper.java

@@ -51,6 +51,11 @@ public class CommandHelper {
         if (Skills.hasGatheringSkills(inspect)) {
             PlayerProfile profile = Users.getProfile(inspect);
 
+            if (profile == null) {
+                display.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return;
+            }
+
             display.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
 
             if (Permissions.getInstance().excavation(inspect)) {
@@ -89,6 +94,11 @@ public class CommandHelper {
         if (Skills.hasCombatSkills(inspect)) {
             PlayerProfile profile = Users.getProfile(inspect);
 
+            if (profile == null) {
+                display.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return;
+            }
+
             display.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
 
             if (Permissions.getInstance().axes(inspect)) {
@@ -126,6 +136,12 @@ public class CommandHelper {
     public static void printMiscSkills(Player inspect, CommandSender display) {
         if (Skills.hasMiscSkills(inspect)) {
             PlayerProfile profile = Users.getProfile(inspect);
+
+            if (profile == null) {
+                display.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return;
+            }
+
             display.sendMessage(LocaleLoader.getString("Stats.Header.Misc"));
 
             if (Permissions.getInstance().acrobatics(inspect)) {

+ 5 - 0
src/main/java/com/gmail/nossr50/commands/SkillCommand.java

@@ -46,6 +46,11 @@ public abstract class SkillCommand implements CommandExecutor {
         player = (Player) sender;
         profile = Users.getProfile(player);
 
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         skillValue = profile.getSkillLevel(skill);
         dataCalculations();
         permissionsCheck();

+ 5 - 0
src/main/java/com/gmail/nossr50/commands/general/AddlevelsCommand.java

@@ -72,6 +72,11 @@ public class AddlevelsCommand implements CommandExecutor{
             String playerName = modifiedPlayer.getName();
             profile = Users.getProfile(modifiedPlayer);
 
+            if (profile == null) {
+                sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return true;
+            }
+
             if (!profile.isLoaded()) {
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                 return true;

+ 5 - 0
src/main/java/com/gmail/nossr50/commands/general/AddxpCommand.java

@@ -84,6 +84,11 @@ public class AddxpCommand implements CommandExecutor {
             String playerName = modifiedPlayer.getName();
             McMMOPlayer mcMMOPlayer = Users.getPlayer(modifiedPlayer);
             PlayerProfile profile = Users.getProfile(modifiedPlayer);
+	    
+            if (profile == null) {
+                sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return true;
+            }
 
             if (!profile.isLoaded()) {
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));

+ 5 - 0
src/main/java/com/gmail/nossr50/commands/general/InspectCommand.java

@@ -51,6 +51,11 @@ public class InspectCommand implements CommandExecutor {
 
                 PlayerProfile profile = new PlayerProfile(args[0], false); //Temporary Profile
 
+                if (profile == null) {
+                    sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                    return true;
+                }
+
                 if (!profile.isLoaded()) {
                     sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                     return true;

+ 10 - 0
src/main/java/com/gmail/nossr50/commands/general/MmoeditCommand.java

@@ -88,6 +88,11 @@ public class MmoeditCommand implements CommandExecutor {
             if (mcmmoPlayer != null) {
                 profile = mcmmoPlayer.getProfile();
 
+                if (profile == null) {
+                    sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                    return true;
+                }
+
                 profile.modifySkill(skill, newValue);
                 mcmmoPlayer.getPlayer().sendMessage(ChatColor.GREEN + "Your level in " + skillName + " was set to " + newValue + "!"); //TODO: Needs more locale.
                 sender.sendMessage(ChatColor.RED + skillName + " has been modified for " + args[0] + "."); //TODO: Use locale
@@ -95,6 +100,11 @@ public class MmoeditCommand implements CommandExecutor {
             else {
                 profile = new PlayerProfile(args[0], false); //Temporary Profile
 
+                if (profile == null) {
+                    sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                    return true;
+                }
+
                 if (!profile.isLoaded()) {
                     sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                     return true;

+ 6 - 0
src/main/java/com/gmail/nossr50/commands/general/SkillResetCommand.java

@@ -45,6 +45,12 @@ public class SkillResetCommand implements CommandExecutor {
         
         //reset the values in the hash table and persist them
         PlayerProfile profile = Users.getProfile((Player)sender);
+
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         profile.resetSkill(skillType);
         profile.save();
         

+ 5 - 0
src/main/java/com/gmail/nossr50/commands/mc/McabilityCommand.java

@@ -24,6 +24,11 @@ public class McabilityCommand implements CommandExecutor {
 
         PlayerProfile profile = Users.getProfile((Player) sender);
 
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         if (profile.getAbilityUse()) {
             sender.sendMessage(LocaleLoader.getString("Commands.Ability.Off"));
         }

+ 5 - 0
src/main/java/com/gmail/nossr50/commands/mc/McgodCommand.java

@@ -24,6 +24,11 @@ public class McgodCommand implements CommandExecutor {
 
         PlayerProfile profile = Users.getProfile((Player) sender);
 
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         if (profile.getGodMode()) {
             sender.sendMessage(LocaleLoader.getString("Commands.GodMode.Disabled"));
         }

+ 5 - 0
src/main/java/com/gmail/nossr50/commands/mc/McrefreshCommand.java

@@ -47,6 +47,11 @@ public class McrefreshCommand implements CommandExecutor {
             profile = Users.getProfile(player);
             String playerName = player.getName();
 
+            if (profile == null) {
+                sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return true;
+            }
+
             if (!profile.isLoaded()) {
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                 return true;

+ 1 - 0
src/main/java/com/gmail/nossr50/commands/party/PtpCommand.java

@@ -72,6 +72,7 @@ public class PtpCommand implements CommandExecutor {
                 player.teleport(target);
                 player.sendMessage(LocaleLoader.getString("Party.Teleport.Player", new Object[] { target.getName() }));
                 target.sendMessage(LocaleLoader.getString("Party.Teleport.Target", new Object[] { player.getName() }));
+                profile.setRecentlyHurt(System.currentTimeMillis());
             }
             else {
                 player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", new Object[] { target.getName() }));

+ 3 - 3
src/main/java/com/gmail/nossr50/config/Config.java

@@ -164,9 +164,9 @@ public class Config extends ConfigLoader {
     public int getHerbalismXPNetherWart() { return config.getInt("Experience.Herbalism.Nether_Wart", 50); }
     public int getHerbalismXPLilyPads() { return config.getInt("Experience.Herbalism.Lily_Pads", 100); }
     public int getHerbalismXPVines() { return config.getInt("Experience.Herbalism.Vines", 10); }
-    public int getHerbalismXPCocoa() { return config.getInt("Experience.Herbalism.Cocoa",30); }
-    public int getHerbalismXPCarrot() { return config.getInt("Experience.Herbalism.Carrot",30); }
-    public int getHerbalismXPPotato() { return config.getInt("Experience.Herbalism.Potato",30); }
+    public int getHerbalismXPCocoa() { return config.getInt("Experience.Herbalism.Cocoa", 30); }
+    public int getHerbalismXPCarrot() { return config.getInt("Experience.Herbalism.Carrot", 50); }
+    public int getHerbalismXPPotato() { return config.getInt("Experience.Herbalism.Potato", 50); }
 
     public boolean getHerbalismGreenThumbCobbleToMossy() { return config.getBoolean("Skills.Herbalism.Green_Thumb.Cobble_To_Mossy", true); }
     public boolean getHerbalismGreenThumbSmoothbrickToMossy() { return config.getBoolean("Skills.Herbalism.Green_Thumb.SmoothBrick_To_MossyBrick", true); }

+ 4 - 0
src/main/java/com/gmail/nossr50/config/mods/CustomArmorConfig.java

@@ -49,6 +49,10 @@ public class CustomArmorConfig extends ConfigLoader{
 
     private void loadArmor(String armorType, List<Integer> idList) {
         ConfigurationSection armorSection = config.getConfigurationSection(armorType);
+
+        if(armorSection == null)
+            return;
+
         Set<String> armorConfigSet = armorSection.getKeys(false);
         Iterator<String> iterator = armorConfigSet.iterator();
 

+ 4 - 0
src/main/java/com/gmail/nossr50/config/mods/CustomBlocksConfig.java

@@ -48,6 +48,10 @@ public class CustomBlocksConfig extends ConfigLoader {
 
     private void loadBlocks(String skillType, List<ItemStack> blockList) {
         ConfigurationSection skillSection = config.getConfigurationSection(skillType);
+
+        if(skillSection == null)
+            return;
+
         Set<String> skillConfigSet = skillSection.getKeys(false);
         Iterator<String> iterator = skillConfigSet.iterator();
 

+ 4 - 0
src/main/java/com/gmail/nossr50/config/mods/CustomToolsConfig.java

@@ -53,6 +53,10 @@ public class CustomToolsConfig extends ConfigLoader {
 
     private void loadTool(String toolType, List<Integer> idList) {
         ConfigurationSection toolSection = config.getConfigurationSection(toolType);
+
+        if(toolSection == null)
+            return;
+
         Set<String> toolConfigSet = toolSection.getKeys(false);
         Iterator<String> iterator = toolConfigSet.iterator();
 

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

@@ -41,7 +41,7 @@ public class PlayerProfile {
     private boolean abilityUse = true;
 
     /* Timestamps */
-    private int recentlyHurt;
+    private long recentlyHurt;
     private int respawnATS;
 
     /* mySQL STUFF */
@@ -826,11 +826,11 @@ public class PlayerProfile {
      * Recently Hurt
      */
 
-    public int getRecentlyHurt() {
+    public long getRecentlyHurt() {
         return recentlyHurt;
     }
 
-    public void setRecentlyHurt(int value) {
+    public void setRecentlyHurt(long value) {
         recentlyHurt = value;
     }
 

+ 3 - 0
src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsEventHandler.java

@@ -51,6 +51,9 @@ public abstract class AcrobaticsEventHandler {
      * @return true if the damage is fatal, false otherwise
      */
     protected boolean isFatal(int damage) {
+        if(player == null)
+            return true;
+
         if (player.getHealth() - damage < 1) {
             return true;
         }

+ 6 - 0
src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java

@@ -26,6 +26,9 @@ public class AcrobaticsManager {
      * @param event The event to check
      */
     public void rollCheck(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
         if (!permissionInstance.roll(player)) {
             return;
         }
@@ -54,6 +57,9 @@ public class AcrobaticsManager {
      * @param event The event to check
      */
     public void dodgeCheck(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
         if (!permissionInstance.dodge(player)) {
             return;
         }

+ 6 - 0
src/main/java/com/gmail/nossr50/skills/acrobatics/DodgeEventHandler.java

@@ -39,11 +39,17 @@ public class DodgeEventHandler extends AcrobaticsEventHandler {
 
     @Override
     protected void sendAbilityMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Acrobatics.Combat.Proc"));
     }
 
     @Override
     protected void processXPGain(int xp) {
+        if(player == null)
+            return;
+
         PlayerProfile profile = manager.getProfile();
 
         if (System.currentTimeMillis() >= profile.getRespawnATS() + 5) {

+ 9 - 0
src/main/java/com/gmail/nossr50/skills/acrobatics/RollEventHandler.java

@@ -56,6 +56,9 @@ public class RollEventHandler extends AcrobaticsEventHandler {
 
     @Override
     protected void sendAbilityMessage() {
+        if(player == null)
+            return;
+
         if (isGraceful) {
             player.sendMessage(LocaleLoader.getString("Acrobatics.Ability.Proc"));
         }
@@ -67,6 +70,9 @@ public class RollEventHandler extends AcrobaticsEventHandler {
 
     @Override
     protected void processXPGain(int xpGain) {
+        if(player == null)
+            return;
+
         Skills.xpProcessing(player, manager.getProfile(), SkillType.ACROBATICS, xpGain);
     }
 
@@ -74,6 +80,9 @@ public class RollEventHandler extends AcrobaticsEventHandler {
      * Check if this is a graceful roll.
      */
     private void isGracefulRoll() {
+        if(player == null)
+            return;
+
         if (Permissions.getInstance().gracefulRoll(player)) {
             this.isGraceful = player.isSneaking();
         }

+ 18 - 0
src/main/java/com/gmail/nossr50/skills/archery/ArcheryManager.java

@@ -33,6 +33,12 @@ public class ArcheryManager {
      * @param livingEntity Entity damaged by the arrow
      */
     public void trackArrows(LivingEntity livingEntity) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.trackArrows(player)) {
             return;
         }
@@ -57,6 +63,12 @@ public class ArcheryManager {
      * @param event The event to modify
      */
     public void dazeCheck(Player defender, EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.daze(player)) {
             return;
         }
@@ -81,6 +93,12 @@ public class ArcheryManager {
      * @param event The event to modify.
      */
     public void bonusDamage(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.archeryBonus(player)) {
             return;
         }

+ 14 - 0
src/main/java/com/gmail/nossr50/skills/combat/Axes.java

@@ -30,6 +30,9 @@ public class Axes {
      * @param event The event to modify
      */
     public static void axesBonus(Player attacker, EntityDamageByEntityEvent event) {
+        if(attacker == null)
+            return;
+
         final int MAX_BONUS = 4;
 
         /* Add 1 DMG for every 50 skill levels */
@@ -49,6 +52,9 @@ public class Axes {
      * @param event The event to modify
      */
     public static void axeCriticalCheck(Player attacker, EntityDamageByEntityEvent event) {
+        if(attacker == null)
+            return;
+
         Entity entity = event.getEntity();
 
         if (entity instanceof Tameable) {
@@ -104,6 +110,8 @@ public class Axes {
      */
     @SuppressWarnings("deprecation")
     public static void impact(Player attacker, LivingEntity target, EntityDamageByEntityEvent event) {
+        if(attacker == null)
+            return;
 
         /*
          * TODO: Finish this skill. The idea is you will greatly damage an opponents armor.
@@ -140,6 +148,9 @@ public class Axes {
      * @param event The event to modify
      */
     private static void applyGreaterImpact(Player attacker, LivingEntity target, EntityDamageByEntityEvent event) {
+        if(attacker == null)
+            return;
+
         final int GREATER_IMPACT_CHANCE = 25;
         final double GREATER_IMPACT_MULTIPLIER = 1.5;
 
@@ -167,6 +178,9 @@ public class Axes {
      * @return true if the player has armor, false otherwise
      */
     private static boolean hasArmor(Player player) {
+        if(player == null)
+            return false;
+
         PlayerInventory inventory = player.getInventory();
 
         if (inventory.getBoots() != null || inventory.getChestplate() != null || inventory.getHelmet() != null || inventory.getLeggings() != null) {

+ 12 - 0
src/main/java/com/gmail/nossr50/skills/gathering/BlastMining.java

@@ -82,6 +82,9 @@ public class BlastMining {
      * @param event Event whose explosion is being processed
      */
     public static void dropProcessing(Player player, EntityExplodeEvent event) {
+        if(player == null)
+            return;
+
         final int RANK_1_LEVEL = 125;
         final int RANK_2_LEVEL = 250;
         final int RANK_3_LEVEL = 375;
@@ -172,6 +175,9 @@ public class BlastMining {
      * @param event Event whose explosion radius is being changed
      */
     public static void biggerBombs(Player player, ExplosionPrimeEvent event) {
+        if(player == null)
+            return;
+
         final int RANK_1_LEVEL = 250;
         final int RANK_2_LEVEL = 500;
         final int RANK_3_LEVEL = 750;
@@ -210,6 +216,9 @@ public class BlastMining {
      * @param event Event whose explosion damage is being reduced
      */
     public static void demolitionsExpertise(Player player, EntityDamageEvent event) {
+        if(player == null)
+            return;
+
         final int RANK_1_LEVEL = 500;
         final int RANK_2_LEVEL = 750;
         final int RANK_3_LEVEL = 1000;
@@ -242,6 +251,9 @@ public class BlastMining {
      * @param plugin mcMMO plugin instance
      */
     public static void detonate(PlayerInteractEvent event, Player player, mcMMO plugin) {
+        if(player == null)
+            return;
+
         PlayerProfile profile = Users.getProfile(player);
 
         if (profile.getSkillLevel(SkillType.MINING) < 125)

+ 6 - 0
src/main/java/com/gmail/nossr50/skills/gathering/Excavation.java

@@ -37,6 +37,9 @@ public class Excavation {
      * @param player The player who broke the block
      */
     public static void excavationProcCheck(Block block, Player player) {
+        if(player == null)
+            return;
+
         Material type = block.getType();
         Location location = block.getLocation();
 
@@ -122,6 +125,9 @@ public class Excavation {
      * @param block The block to check
      */
     public static void gigaDrillBreaker(Player player, Block block) {
+        if(player == null)
+            return;
+
         Skills.abilityDurabilityLoss(player.getItemInHand(), Config.getInstance().getAbilityToolDamage());
 
         if (!mcMMO.placeStore.isTrue(block) && !Misc.blockBreakSimulate(block, player, true)) {

+ 15 - 7
src/main/java/com/gmail/nossr50/skills/gathering/Fishing.java

@@ -72,6 +72,9 @@ public class Fishing {
      * @param event The event to modify
      */
     private static void getFishingResults(Player player, PlayerFishEvent event) {
+        if(player == null)
+            return;
+
         PlayerProfile profile = Users.getProfile(player);
         List<FishingTreasure> rewards = new ArrayList<FishingTreasure>();
         Item theCatch = (Item) event.getCaught();
@@ -135,6 +138,9 @@ public class Fishing {
      */
     public static void processResults(PlayerFishEvent event) {
         Player player = event.getPlayer();
+        if(player == null)
+            return;
+
         PlayerProfile profile = Users.getProfile(player);
 
         getFishingResults(player, event);
@@ -147,11 +153,11 @@ public class Fishing {
 
             player.sendMessage(LocaleLoader.getString("Fishing.ItemFound"));
 
-            if (ItemChecks.isArmor(fishingResults) || ItemChecks.isTool(fishingResults)) {
+            if (ItemChecks.isEnchantable(fishingResults)) {
                 int randomChance = 100;
 
                 if (player.hasPermission("mcmmo.perks.lucky.fishing")) {
-                    randomChance = (int) (randomChance * 0.75);
+                    randomChance = (int) (randomChance * 1.25);
                 }
 
                 if (random.nextInt(randomChance) <= ENCHANTMENT_CHANCE && Permissions.getInstance().fishingMagic(player)) {
@@ -160,9 +166,8 @@ public class Fishing {
                             Map<Enchantment, Integer> resultEnchantments = fishingResults.getEnchantments();
 
                             for (Enchantment oldEnchant : resultEnchantments.keySet()) {
-                                if (oldEnchant.conflictsWith(newEnchant)) {
-                                    return;
-                                }
+                                if (oldEnchant.conflictsWith(newEnchant))
+                                    continue;
                             }
 
                             /* Actual chance to have an enchantment is related to your fishing skill */
@@ -174,6 +179,9 @@ public class Fishing {
                                     randomEnchantLevel = newEnchant.getStartLevel();
                                 }
 
+                                if(randomEnchantLevel >= 1000)
+                                    continue;
+
                                 fishingResults.addEnchantment(newEnchant, randomEnchantLevel);
                             }
                         }
@@ -199,7 +207,7 @@ public class Fishing {
             randomChance = (int) (randomChance * 0.75);
         }
 
-        final int DROP_NUMBER = random.nextInt(randomChance);
+        final int DROP_NUMBER = random.nextInt(randomChance) + 1;
 
         LivingEntity le = (LivingEntity) event.getCaught();
         EntityType type = le.getType();
@@ -379,7 +387,7 @@ public class Fishing {
             break;
 
         case WITCH:
-            final int DROP_NUMBER_2 = random.nextInt(randomChance);
+            final int DROP_NUMBER_2 = random.nextInt(randomChance) + 1;
             if (DROP_NUMBER > 97) {
                 if(DROP_NUMBER_2 > 66) {
                     Misc.dropItem(location, new ItemStack(Material.POTION, 1, (short) 8197));

+ 40 - 0
src/main/java/com/gmail/nossr50/skills/gathering/WoodCutting.java

@@ -261,6 +261,39 @@ public class WoodCutting {
             }
         }
 
+        byte data = currentBlock.getData();
+
+        if((data & 0x4) == 0x4)
+            data ^= 0x4;
+
+        if((data & 0x8) == 0x8)
+            data ^= 0x8;
+
+        if(TreeSpecies.getByData(data) == TreeSpecies.JUNGLE) {
+            Block corner1 = currentBlock.getRelative(1, 0, 1);
+            Block corner2 = currentBlock.getRelative(1, 0, -1);
+            Block corner3 = currentBlock.getRelative(-1, 0, 1);
+            Block corner4 = currentBlock.getRelative(-1, 0, -1);
+
+            if (!mcMMO.placeStore.isTrue(currentBlock)) {
+                if (!isTooAggressive(currentBlock, corner1) && BlockChecks.treeFellerCompatible(corner1) && !toBeFelled.contains(corner1)) {
+                    processTreeFelling(corner1, toBeFelled);
+                }
+
+                if (!isTooAggressive(currentBlock, corner2) && BlockChecks.treeFellerCompatible(corner2) && !toBeFelled.contains(corner2)) {
+                    processTreeFelling(corner2, toBeFelled);
+                }
+
+                if (!isTooAggressive(currentBlock, corner3) && BlockChecks.treeFellerCompatible(corner3) && !toBeFelled.contains(corner3)) {
+                    processTreeFelling(corner3, toBeFelled);
+                }
+
+                if (!isTooAggressive(currentBlock, corner4) && BlockChecks.treeFellerCompatible(corner4) && !toBeFelled.contains(corner4)) {
+                    processTreeFelling(corner4, toBeFelled);
+                }
+            }
+        }
+
         if (BlockChecks.treeFellerCompatible(yPositive)) {
             if(!mcMMO.placeStore.isTrue(currentBlock) && !toBeFelled.contains(yPositive)) {
                 processTreeFelling(yPositive, toBeFelled);
@@ -298,6 +331,13 @@ public class WoodCutting {
 
         int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.WOODCUTTING);
         byte type = block.getData();
+
+        if((type & 0x4) == 0x4)
+            type ^= 0x4;
+
+        if((type & 0x8) == 0x8)
+            type ^= 0x8;
+
         Material mat = Material.getMaterial(block.getTypeId());
 
         int randomChance = 1000;

+ 6 - 0
src/main/java/com/gmail/nossr50/skills/swords/CounterAttackEventHandler.java

@@ -24,6 +24,9 @@ public class CounterAttackEventHandler {
     }
 
     protected boolean isHoldingSword() {
+        if(player == null)
+            return false;
+
         return ItemChecks.isSword(player.getItemInHand());
     }
 
@@ -36,6 +39,9 @@ public class CounterAttackEventHandler {
     }
 
     protected void sendAbilityMessages() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Swords.Combat.Countered"));
 
         if (attacker instanceof Player) {

+ 3 - 0
src/main/java/com/gmail/nossr50/skills/swords/SerratedStrikesEventHandler.java

@@ -19,6 +19,9 @@ public class SerratedStrikesEventHandler {
     }
 
     protected void applyAbilityEffects() {
+        if(player == null)
+            return;
+
         Combat.applyAbilityAoE(player, target, damage / Swords.SERRATED_STRIKES_MODIFIER, SkillType.SWORDS);
         BleedTimer.add(target, Swords.SERRATED_STRIKES_BLEED_TICKS);
     }

+ 18 - 0
src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java

@@ -28,6 +28,12 @@ public class SwordsManager {
      * @param defender The defending entity
      */
     public void bleedCheck(LivingEntity defender) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.swordsBleed(player)) {
             return;
         }
@@ -49,6 +55,12 @@ public class SwordsManager {
     }
 
     public void counterAttackChecks(LivingEntity attacker, int damage) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.counterAttack(player)) {
             return;
         }
@@ -72,6 +84,12 @@ public class SwordsManager {
     }
 
     public void serratedStrikes(LivingEntity target, int damage) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.serratedStrikes(player)) {
             return;
         }

+ 3 - 0
src/main/java/com/gmail/nossr50/skills/taming/BeastLoreEventHandler.java

@@ -19,6 +19,9 @@ public class BeastLoreEventHandler {
     }
 
     protected void sendInspectMessage() {
+        if(player == null)
+            return;
+
         String message = LocaleLoader.getString("Combat.BeastLore") + " ";
 
         if (beast.isTamed()) {

+ 18 - 0
src/main/java/com/gmail/nossr50/skills/taming/CallOfTheWildEventHandler.java

@@ -29,10 +29,16 @@ public class CallOfTheWildEventHandler {
     }
 
     protected void sendInsufficientAmountMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.GRAY + Misc.prettyItemString(inHand.getTypeId()));
     }
 
     protected boolean nearbyEntityExists() {
+        if(player == null)
+            return false;
+
         boolean entityExists = false;
 
         for (Entity entity : player.getNearbyEntities(40, 40, 40)) {
@@ -46,6 +52,9 @@ public class CallOfTheWildEventHandler {
     }
 
     protected void sendFailureMessage() {
+        if(player == null)
+            return;
+
         if (type == EntityType.OCELOT) {
             player.sendMessage(LocaleLoader.getString("Taming.Summon.Fail.Ocelot"));
         }
@@ -55,6 +64,9 @@ public class CallOfTheWildEventHandler {
     }
 
     protected void spawnCreature() {
+        if(player == null)
+            return;
+
         LivingEntity entity = (LivingEntity) player.getWorld().spawnEntity(player.getLocation(), type);
         entity.setMetadata("mcmmoSummoned", new FixedMetadataValue(mcMMO.p, true));
 
@@ -69,6 +81,9 @@ public class CallOfTheWildEventHandler {
     }
 
     protected void processResourceCost() {
+        if(player == null)
+            return;
+
         int newAmount = inHand.getAmount() - summonAmount;
 
         if (newAmount == 0) {
@@ -80,6 +95,9 @@ public class CallOfTheWildEventHandler {
     }
 
     protected void sendSuccessMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Taming.Summon.Complete"));
     }
 }

+ 6 - 0
src/main/java/com/gmail/nossr50/skills/taming/EnvironmentallyAwareEventHandler.java

@@ -18,6 +18,9 @@ public class EnvironmentallyAwareEventHandler {
     }
 
     protected void teleportWolf() {
+        if(player == null)
+            return;
+
         if (event.getDamage() > wolf.getHealth()) {
             return;
         }
@@ -26,6 +29,9 @@ public class EnvironmentallyAwareEventHandler {
     }
 
     protected void sendAbilityMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Taming.Listener.Wolf"));
     }
 

+ 48 - 0
src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java

@@ -36,6 +36,12 @@ public class TamingManager {
      * @param damage The damage being absorbed by the wolf
      */
     public void fastFoodService(Wolf wolf, int damage) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.fastFoodService(player)) {
             return;
         }
@@ -61,6 +67,12 @@ public class TamingManager {
      * @param event The event to modify
      */
     public void sharpenedClaws(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.sharpenedClaws(player)) {
             return;
         }
@@ -78,6 +90,12 @@ public class TamingManager {
      * @param event The event to modify
      */
     public void gore(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.gore(player)) {
             return;
         }
@@ -150,6 +168,12 @@ public class TamingManager {
      * @param livingEntity The entity to examine
      */
     public void beastLore(LivingEntity livingEntity) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.beastLore(player)) {
             return;
         }
@@ -166,6 +190,12 @@ public class TamingManager {
      * @param summonAmount The amount of material needed to summon the entity
      */
     private void callOfTheWild(EntityType type, int summonAmount) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.callOfTheWild(player)) {
             return;
         }
@@ -198,6 +228,12 @@ public class TamingManager {
      * @param cause The damage cause of the event
      */
     private void environmentallyAware(EntityDamageEvent event, DamageCause cause) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.environmentallyAware(player)) {
             return;
         }
@@ -230,6 +266,12 @@ public class TamingManager {
      * @param cause The damage cause of the event
      */
     private void thickFur(EntityDamageEvent event, DamageCause cause) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.thickFur(player)) {
             return;
         }
@@ -247,6 +289,12 @@ public class TamingManager {
      * @param event The event to modify
      */
     private void shockProof(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.shockProof(player)) {
             return;
         }

+ 24 - 0
src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java

@@ -27,6 +27,12 @@ public class UnarmedManager {
      * @param defender The defending player
      */
     public void disarmCheck(Player defender) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.disarm(player)) {
             return;
         }
@@ -58,6 +64,12 @@ public class UnarmedManager {
      * @param event The event to modify
      */
     public void deflectCheck(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.deflect(player)) {
             return;
         }
@@ -82,6 +94,12 @@ public class UnarmedManager {
      * @param event The event to modify.
      */
     public void bonusDamage(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.unarmedBonus(player)) {
             return;
         }
@@ -99,6 +117,12 @@ public class UnarmedManager {
      * @return true if the defender was not disarmed, false otherwise
      */
     private boolean hasIronGrip(Player defender) {
+        if(defender == null)
+            return false;
+
+        if(permissionsInstance == null)
+            return false;
+
         if (!permissionsInstance.ironGrip(defender)) {
             return false;
         }

+ 11 - 0
src/main/java/com/gmail/nossr50/util/ItemChecks.java

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.util;
 
 import org.bukkit.inventory.ItemStack;
+import org.bukkit.Material;
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.api.SpoutToolsAPI;
@@ -463,4 +464,14 @@ public class ItemChecks {
             return false;
         }
     }
+
+    /**
+     * Checks to see if an item is enchantable.
+     *
+     * @param is Item to check
+     * @return true if the item is enchantable, false otherwise
+     */
+    public static boolean isEnchantable(ItemStack is) {
+        return isArmor(is) || isSword(is) || isAxe(is) || isShovel(is) || isPickaxe(is) || (is.getType() == Material.BOW);
+    }
 }

+ 6 - 0
src/main/java/com/gmail/nossr50/util/Skills.java

@@ -507,7 +507,13 @@ public class Skills {
      * @param xp the amount of XP to gain
      */
     public static void xpProcessing(Player player, PlayerProfile profile, SkillType type, int xp) {
+        if(player == null)
+            return;
+
         if (type.getPermissions(player)) {
+	    if(Users.getPlayer(player) == null)
+                return;
+
             Users.getPlayer(player).addXP(type, xp);
             xpCheckSkill(type, player, profile);
         }

+ 4 - 0
src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkletManager.java

@@ -107,6 +107,8 @@ public class HashChunkletManager implements ChunkletManager {
     public void saveWorld(World world) {
         String worldName = world.getName();
         File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
+        if(!dataDir.exists())
+            dataDir.mkdirs();
 
         for(String key : store.keySet()) {
             String[] info = key.split(",");
@@ -280,6 +282,8 @@ public class HashChunkletManager implements ChunkletManager {
         ObjectOutputStream objOut = null;
 
         try {
+            if(!location.exists())
+                location.createNewFile();
             fileOut = new FileOutputStream(location);
             objOut = new ObjectOutputStream(fileOut);
             objOut.writeObject(cStore);