Преглед изворни кода

Merge pull request #284 from Glitchfinder/master

Attempting to resolve various issues in the issue tracker.
Grant пре 12 година
родитељ
комит
b57cc7bd59
37 измењених фајлова са 362 додато и 13 уклоњено
  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)) {
         if (Skills.hasGatheringSkills(inspect)) {
             PlayerProfile profile = Users.getProfile(inspect);
             PlayerProfile profile = Users.getProfile(inspect);
 
 
+            if (profile == null) {
+                display.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return;
+            }
+
             display.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
             display.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
 
 
             if (Permissions.getInstance().excavation(inspect)) {
             if (Permissions.getInstance().excavation(inspect)) {
@@ -89,6 +94,11 @@ public class CommandHelper {
         if (Skills.hasCombatSkills(inspect)) {
         if (Skills.hasCombatSkills(inspect)) {
             PlayerProfile profile = Users.getProfile(inspect);
             PlayerProfile profile = Users.getProfile(inspect);
 
 
+            if (profile == null) {
+                display.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return;
+            }
+
             display.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
             display.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
 
 
             if (Permissions.getInstance().axes(inspect)) {
             if (Permissions.getInstance().axes(inspect)) {
@@ -126,6 +136,12 @@ public class CommandHelper {
     public static void printMiscSkills(Player inspect, CommandSender display) {
     public static void printMiscSkills(Player inspect, CommandSender display) {
         if (Skills.hasMiscSkills(inspect)) {
         if (Skills.hasMiscSkills(inspect)) {
             PlayerProfile profile = Users.getProfile(inspect);
             PlayerProfile profile = Users.getProfile(inspect);
+
+            if (profile == null) {
+                display.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return;
+            }
+
             display.sendMessage(LocaleLoader.getString("Stats.Header.Misc"));
             display.sendMessage(LocaleLoader.getString("Stats.Header.Misc"));
 
 
             if (Permissions.getInstance().acrobatics(inspect)) {
             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;
         player = (Player) sender;
         profile = Users.getProfile(player);
         profile = Users.getProfile(player);
 
 
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         skillValue = profile.getSkillLevel(skill);
         skillValue = profile.getSkillLevel(skill);
         dataCalculations();
         dataCalculations();
         permissionsCheck();
         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();
             String playerName = modifiedPlayer.getName();
             profile = Users.getProfile(modifiedPlayer);
             profile = Users.getProfile(modifiedPlayer);
 
 
+            if (profile == null) {
+                sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return true;
+            }
+
             if (!profile.isLoaded()) {
             if (!profile.isLoaded()) {
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                 return true;
                 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();
             String playerName = modifiedPlayer.getName();
             McMMOPlayer mcMMOPlayer = Users.getPlayer(modifiedPlayer);
             McMMOPlayer mcMMOPlayer = Users.getPlayer(modifiedPlayer);
             PlayerProfile profile = Users.getProfile(modifiedPlayer);
             PlayerProfile profile = Users.getProfile(modifiedPlayer);
+	    
+            if (profile == null) {
+                sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return true;
+            }
 
 
             if (!profile.isLoaded()) {
             if (!profile.isLoaded()) {
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                 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
                 PlayerProfile profile = new PlayerProfile(args[0], false); //Temporary Profile
 
 
+                if (profile == null) {
+                    sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                    return true;
+                }
+
                 if (!profile.isLoaded()) {
                 if (!profile.isLoaded()) {
                     sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                     sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                     return true;
                     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) {
             if (mcmmoPlayer != null) {
                 profile = mcmmoPlayer.getProfile();
                 profile = mcmmoPlayer.getProfile();
 
 
+                if (profile == null) {
+                    sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                    return true;
+                }
+
                 profile.modifySkill(skill, newValue);
                 profile.modifySkill(skill, newValue);
                 mcmmoPlayer.getPlayer().sendMessage(ChatColor.GREEN + "Your level in " + skillName + " was set to " + newValue + "!"); //TODO: Needs more locale.
                 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
                 sender.sendMessage(ChatColor.RED + skillName + " has been modified for " + args[0] + "."); //TODO: Use locale
@@ -95,6 +100,11 @@ public class MmoeditCommand implements CommandExecutor {
             else {
             else {
                 profile = new PlayerProfile(args[0], false); //Temporary Profile
                 profile = new PlayerProfile(args[0], false); //Temporary Profile
 
 
+                if (profile == null) {
+                    sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                    return true;
+                }
+
                 if (!profile.isLoaded()) {
                 if (!profile.isLoaded()) {
                     sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                     sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                     return true;
                     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
         //reset the values in the hash table and persist them
         PlayerProfile profile = Users.getProfile((Player)sender);
         PlayerProfile profile = Users.getProfile((Player)sender);
+
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         profile.resetSkill(skillType);
         profile.resetSkill(skillType);
         profile.save();
         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);
         PlayerProfile profile = Users.getProfile((Player) sender);
 
 
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         if (profile.getAbilityUse()) {
         if (profile.getAbilityUse()) {
             sender.sendMessage(LocaleLoader.getString("Commands.Ability.Off"));
             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);
         PlayerProfile profile = Users.getProfile((Player) sender);
 
 
+        if (profile == null) {
+            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+            return true;
+        }
+
         if (profile.getGodMode()) {
         if (profile.getGodMode()) {
             sender.sendMessage(LocaleLoader.getString("Commands.GodMode.Disabled"));
             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);
             profile = Users.getProfile(player);
             String playerName = player.getName();
             String playerName = player.getName();
 
 
+            if (profile == null) {
+                sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                return true;
+            }
+
             if (!profile.isLoaded()) {
             if (!profile.isLoaded()) {
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                 sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
                 return true;
                 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.teleport(target);
                 player.sendMessage(LocaleLoader.getString("Party.Teleport.Player", new Object[] { target.getName() }));
                 player.sendMessage(LocaleLoader.getString("Party.Teleport.Player", new Object[] { target.getName() }));
                 target.sendMessage(LocaleLoader.getString("Party.Teleport.Target", new Object[] { player.getName() }));
                 target.sendMessage(LocaleLoader.getString("Party.Teleport.Target", new Object[] { player.getName() }));
+                profile.setRecentlyHurt(System.currentTimeMillis());
             }
             }
             else {
             else {
                 player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", new Object[] { target.getName() }));
                 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 getHerbalismXPNetherWart() { return config.getInt("Experience.Herbalism.Nether_Wart", 50); }
     public int getHerbalismXPLilyPads() { return config.getInt("Experience.Herbalism.Lily_Pads", 100); }
     public int getHerbalismXPLilyPads() { return config.getInt("Experience.Herbalism.Lily_Pads", 100); }
     public int getHerbalismXPVines() { return config.getInt("Experience.Herbalism.Vines", 10); }
     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 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); }
     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) {
     private void loadArmor(String armorType, List<Integer> idList) {
         ConfigurationSection armorSection = config.getConfigurationSection(armorType);
         ConfigurationSection armorSection = config.getConfigurationSection(armorType);
+
+        if(armorSection == null)
+            return;
+
         Set<String> armorConfigSet = armorSection.getKeys(false);
         Set<String> armorConfigSet = armorSection.getKeys(false);
         Iterator<String> iterator = armorConfigSet.iterator();
         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) {
     private void loadBlocks(String skillType, List<ItemStack> blockList) {
         ConfigurationSection skillSection = config.getConfigurationSection(skillType);
         ConfigurationSection skillSection = config.getConfigurationSection(skillType);
+
+        if(skillSection == null)
+            return;
+
         Set<String> skillConfigSet = skillSection.getKeys(false);
         Set<String> skillConfigSet = skillSection.getKeys(false);
         Iterator<String> iterator = skillConfigSet.iterator();
         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) {
     private void loadTool(String toolType, List<Integer> idList) {
         ConfigurationSection toolSection = config.getConfigurationSection(toolType);
         ConfigurationSection toolSection = config.getConfigurationSection(toolType);
+
+        if(toolSection == null)
+            return;
+
         Set<String> toolConfigSet = toolSection.getKeys(false);
         Set<String> toolConfigSet = toolSection.getKeys(false);
         Iterator<String> iterator = toolConfigSet.iterator();
         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;
     private boolean abilityUse = true;
 
 
     /* Timestamps */
     /* Timestamps */
-    private int recentlyHurt;
+    private long recentlyHurt;
     private int respawnATS;
     private int respawnATS;
 
 
     /* mySQL STUFF */
     /* mySQL STUFF */
@@ -826,11 +826,11 @@ public class PlayerProfile {
      * Recently Hurt
      * Recently Hurt
      */
      */
 
 
-    public int getRecentlyHurt() {
+    public long getRecentlyHurt() {
         return recentlyHurt;
         return recentlyHurt;
     }
     }
 
 
-    public void setRecentlyHurt(int value) {
+    public void setRecentlyHurt(long value) {
         recentlyHurt = 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
      * @return true if the damage is fatal, false otherwise
      */
      */
     protected boolean isFatal(int damage) {
     protected boolean isFatal(int damage) {
+        if(player == null)
+            return true;
+
         if (player.getHealth() - damage < 1) {
         if (player.getHealth() - damage < 1) {
             return true;
             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
      * @param event The event to check
      */
      */
     public void rollCheck(EntityDamageEvent event) {
     public void rollCheck(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
         if (!permissionInstance.roll(player)) {
         if (!permissionInstance.roll(player)) {
             return;
             return;
         }
         }
@@ -54,6 +57,9 @@ public class AcrobaticsManager {
      * @param event The event to check
      * @param event The event to check
      */
      */
     public void dodgeCheck(EntityDamageEvent event) {
     public void dodgeCheck(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
         if (!permissionInstance.dodge(player)) {
         if (!permissionInstance.dodge(player)) {
             return;
             return;
         }
         }

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

@@ -39,11 +39,17 @@ public class DodgeEventHandler extends AcrobaticsEventHandler {
 
 
     @Override
     @Override
     protected void sendAbilityMessage() {
     protected void sendAbilityMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Acrobatics.Combat.Proc"));
         player.sendMessage(LocaleLoader.getString("Acrobatics.Combat.Proc"));
     }
     }
 
 
     @Override
     @Override
     protected void processXPGain(int xp) {
     protected void processXPGain(int xp) {
+        if(player == null)
+            return;
+
         PlayerProfile profile = manager.getProfile();
         PlayerProfile profile = manager.getProfile();
 
 
         if (System.currentTimeMillis() >= profile.getRespawnATS() + 5) {
         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
     @Override
     protected void sendAbilityMessage() {
     protected void sendAbilityMessage() {
+        if(player == null)
+            return;
+
         if (isGraceful) {
         if (isGraceful) {
             player.sendMessage(LocaleLoader.getString("Acrobatics.Ability.Proc"));
             player.sendMessage(LocaleLoader.getString("Acrobatics.Ability.Proc"));
         }
         }
@@ -67,6 +70,9 @@ public class RollEventHandler extends AcrobaticsEventHandler {
 
 
     @Override
     @Override
     protected void processXPGain(int xpGain) {
     protected void processXPGain(int xpGain) {
+        if(player == null)
+            return;
+
         Skills.xpProcessing(player, manager.getProfile(), SkillType.ACROBATICS, xpGain);
         Skills.xpProcessing(player, manager.getProfile(), SkillType.ACROBATICS, xpGain);
     }
     }
 
 
@@ -74,6 +80,9 @@ public class RollEventHandler extends AcrobaticsEventHandler {
      * Check if this is a graceful roll.
      * Check if this is a graceful roll.
      */
      */
     private void isGracefulRoll() {
     private void isGracefulRoll() {
+        if(player == null)
+            return;
+
         if (Permissions.getInstance().gracefulRoll(player)) {
         if (Permissions.getInstance().gracefulRoll(player)) {
             this.isGraceful = player.isSneaking();
             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
      * @param livingEntity Entity damaged by the arrow
      */
      */
     public void trackArrows(LivingEntity livingEntity) {
     public void trackArrows(LivingEntity livingEntity) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.trackArrows(player)) {
         if (!permissionsInstance.trackArrows(player)) {
             return;
             return;
         }
         }
@@ -57,6 +63,12 @@ public class ArcheryManager {
      * @param event The event to modify
      * @param event The event to modify
      */
      */
     public void dazeCheck(Player defender, EntityDamageEvent event) {
     public void dazeCheck(Player defender, EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.daze(player)) {
         if (!permissionsInstance.daze(player)) {
             return;
             return;
         }
         }
@@ -81,6 +93,12 @@ public class ArcheryManager {
      * @param event The event to modify.
      * @param event The event to modify.
      */
      */
     public void bonusDamage(EntityDamageEvent event) {
     public void bonusDamage(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.archeryBonus(player)) {
         if (!permissionsInstance.archeryBonus(player)) {
             return;
             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
      * @param event The event to modify
      */
      */
     public static void axesBonus(Player attacker, EntityDamageByEntityEvent event) {
     public static void axesBonus(Player attacker, EntityDamageByEntityEvent event) {
+        if(attacker == null)
+            return;
+
         final int MAX_BONUS = 4;
         final int MAX_BONUS = 4;
 
 
         /* Add 1 DMG for every 50 skill levels */
         /* Add 1 DMG for every 50 skill levels */
@@ -49,6 +52,9 @@ public class Axes {
      * @param event The event to modify
      * @param event The event to modify
      */
      */
     public static void axeCriticalCheck(Player attacker, EntityDamageByEntityEvent event) {
     public static void axeCriticalCheck(Player attacker, EntityDamageByEntityEvent event) {
+        if(attacker == null)
+            return;
+
         Entity entity = event.getEntity();
         Entity entity = event.getEntity();
 
 
         if (entity instanceof Tameable) {
         if (entity instanceof Tameable) {
@@ -104,6 +110,8 @@ public class Axes {
      */
      */
     @SuppressWarnings("deprecation")
     @SuppressWarnings("deprecation")
     public static void impact(Player attacker, LivingEntity target, EntityDamageByEntityEvent event) {
     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.
          * 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
      * @param event The event to modify
      */
      */
     private static void applyGreaterImpact(Player attacker, LivingEntity target, EntityDamageByEntityEvent event) {
     private static void applyGreaterImpact(Player attacker, LivingEntity target, EntityDamageByEntityEvent event) {
+        if(attacker == null)
+            return;
+
         final int GREATER_IMPACT_CHANCE = 25;
         final int GREATER_IMPACT_CHANCE = 25;
         final double GREATER_IMPACT_MULTIPLIER = 1.5;
         final double GREATER_IMPACT_MULTIPLIER = 1.5;
 
 
@@ -167,6 +178,9 @@ public class Axes {
      * @return true if the player has armor, false otherwise
      * @return true if the player has armor, false otherwise
      */
      */
     private static boolean hasArmor(Player player) {
     private static boolean hasArmor(Player player) {
+        if(player == null)
+            return false;
+
         PlayerInventory inventory = player.getInventory();
         PlayerInventory inventory = player.getInventory();
 
 
         if (inventory.getBoots() != null || inventory.getChestplate() != null || inventory.getHelmet() != null || inventory.getLeggings() != null) {
         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
      * @param event Event whose explosion is being processed
      */
      */
     public static void dropProcessing(Player player, EntityExplodeEvent event) {
     public static void dropProcessing(Player player, EntityExplodeEvent event) {
+        if(player == null)
+            return;
+
         final int RANK_1_LEVEL = 125;
         final int RANK_1_LEVEL = 125;
         final int RANK_2_LEVEL = 250;
         final int RANK_2_LEVEL = 250;
         final int RANK_3_LEVEL = 375;
         final int RANK_3_LEVEL = 375;
@@ -172,6 +175,9 @@ public class BlastMining {
      * @param event Event whose explosion radius is being changed
      * @param event Event whose explosion radius is being changed
      */
      */
     public static void biggerBombs(Player player, ExplosionPrimeEvent event) {
     public static void biggerBombs(Player player, ExplosionPrimeEvent event) {
+        if(player == null)
+            return;
+
         final int RANK_1_LEVEL = 250;
         final int RANK_1_LEVEL = 250;
         final int RANK_2_LEVEL = 500;
         final int RANK_2_LEVEL = 500;
         final int RANK_3_LEVEL = 750;
         final int RANK_3_LEVEL = 750;
@@ -210,6 +216,9 @@ public class BlastMining {
      * @param event Event whose explosion damage is being reduced
      * @param event Event whose explosion damage is being reduced
      */
      */
     public static void demolitionsExpertise(Player player, EntityDamageEvent event) {
     public static void demolitionsExpertise(Player player, EntityDamageEvent event) {
+        if(player == null)
+            return;
+
         final int RANK_1_LEVEL = 500;
         final int RANK_1_LEVEL = 500;
         final int RANK_2_LEVEL = 750;
         final int RANK_2_LEVEL = 750;
         final int RANK_3_LEVEL = 1000;
         final int RANK_3_LEVEL = 1000;
@@ -242,6 +251,9 @@ public class BlastMining {
      * @param plugin mcMMO plugin instance
      * @param plugin mcMMO plugin instance
      */
      */
     public static void detonate(PlayerInteractEvent event, Player player, mcMMO plugin) {
     public static void detonate(PlayerInteractEvent event, Player player, mcMMO plugin) {
+        if(player == null)
+            return;
+
         PlayerProfile profile = Users.getProfile(player);
         PlayerProfile profile = Users.getProfile(player);
 
 
         if (profile.getSkillLevel(SkillType.MINING) < 125)
         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
      * @param player The player who broke the block
      */
      */
     public static void excavationProcCheck(Block block, Player player) {
     public static void excavationProcCheck(Block block, Player player) {
+        if(player == null)
+            return;
+
         Material type = block.getType();
         Material type = block.getType();
         Location location = block.getLocation();
         Location location = block.getLocation();
 
 
@@ -122,6 +125,9 @@ public class Excavation {
      * @param block The block to check
      * @param block The block to check
      */
      */
     public static void gigaDrillBreaker(Player player, Block block) {
     public static void gigaDrillBreaker(Player player, Block block) {
+        if(player == null)
+            return;
+
         Skills.abilityDurabilityLoss(player.getItemInHand(), Config.getInstance().getAbilityToolDamage());
         Skills.abilityDurabilityLoss(player.getItemInHand(), Config.getInstance().getAbilityToolDamage());
 
 
         if (!mcMMO.placeStore.isTrue(block) && !Misc.blockBreakSimulate(block, player, true)) {
         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
      * @param event The event to modify
      */
      */
     private static void getFishingResults(Player player, PlayerFishEvent event) {
     private static void getFishingResults(Player player, PlayerFishEvent event) {
+        if(player == null)
+            return;
+
         PlayerProfile profile = Users.getProfile(player);
         PlayerProfile profile = Users.getProfile(player);
         List<FishingTreasure> rewards = new ArrayList<FishingTreasure>();
         List<FishingTreasure> rewards = new ArrayList<FishingTreasure>();
         Item theCatch = (Item) event.getCaught();
         Item theCatch = (Item) event.getCaught();
@@ -135,6 +138,9 @@ public class Fishing {
      */
      */
     public static void processResults(PlayerFishEvent event) {
     public static void processResults(PlayerFishEvent event) {
         Player player = event.getPlayer();
         Player player = event.getPlayer();
+        if(player == null)
+            return;
+
         PlayerProfile profile = Users.getProfile(player);
         PlayerProfile profile = Users.getProfile(player);
 
 
         getFishingResults(player, event);
         getFishingResults(player, event);
@@ -147,11 +153,11 @@ public class Fishing {
 
 
             player.sendMessage(LocaleLoader.getString("Fishing.ItemFound"));
             player.sendMessage(LocaleLoader.getString("Fishing.ItemFound"));
 
 
-            if (ItemChecks.isArmor(fishingResults) || ItemChecks.isTool(fishingResults)) {
+            if (ItemChecks.isEnchantable(fishingResults)) {
                 int randomChance = 100;
                 int randomChance = 100;
 
 
                 if (player.hasPermission("mcmmo.perks.lucky.fishing")) {
                 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)) {
                 if (random.nextInt(randomChance) <= ENCHANTMENT_CHANCE && Permissions.getInstance().fishingMagic(player)) {
@@ -160,9 +166,8 @@ public class Fishing {
                             Map<Enchantment, Integer> resultEnchantments = fishingResults.getEnchantments();
                             Map<Enchantment, Integer> resultEnchantments = fishingResults.getEnchantments();
 
 
                             for (Enchantment oldEnchant : resultEnchantments.keySet()) {
                             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 */
                             /* Actual chance to have an enchantment is related to your fishing skill */
@@ -174,6 +179,9 @@ public class Fishing {
                                     randomEnchantLevel = newEnchant.getStartLevel();
                                     randomEnchantLevel = newEnchant.getStartLevel();
                                 }
                                 }
 
 
+                                if(randomEnchantLevel >= 1000)
+                                    continue;
+
                                 fishingResults.addEnchantment(newEnchant, randomEnchantLevel);
                                 fishingResults.addEnchantment(newEnchant, randomEnchantLevel);
                             }
                             }
                         }
                         }
@@ -199,7 +207,7 @@ public class Fishing {
             randomChance = (int) (randomChance * 0.75);
             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();
         LivingEntity le = (LivingEntity) event.getCaught();
         EntityType type = le.getType();
         EntityType type = le.getType();
@@ -379,7 +387,7 @@ public class Fishing {
             break;
             break;
 
 
         case WITCH:
         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 > 97) {
                 if(DROP_NUMBER_2 > 66) {
                 if(DROP_NUMBER_2 > 66) {
                     Misc.dropItem(location, new ItemStack(Material.POTION, 1, (short) 8197));
                     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 (BlockChecks.treeFellerCompatible(yPositive)) {
             if(!mcMMO.placeStore.isTrue(currentBlock) && !toBeFelled.contains(yPositive)) {
             if(!mcMMO.placeStore.isTrue(currentBlock) && !toBeFelled.contains(yPositive)) {
                 processTreeFelling(yPositive, toBeFelled);
                 processTreeFelling(yPositive, toBeFelled);
@@ -298,6 +331,13 @@ public class WoodCutting {
 
 
         int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.WOODCUTTING);
         int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.WOODCUTTING);
         byte type = block.getData();
         byte type = block.getData();
+
+        if((type & 0x4) == 0x4)
+            type ^= 0x4;
+
+        if((type & 0x8) == 0x8)
+            type ^= 0x8;
+
         Material mat = Material.getMaterial(block.getTypeId());
         Material mat = Material.getMaterial(block.getTypeId());
 
 
         int randomChance = 1000;
         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() {
     protected boolean isHoldingSword() {
+        if(player == null)
+            return false;
+
         return ItemChecks.isSword(player.getItemInHand());
         return ItemChecks.isSword(player.getItemInHand());
     }
     }
 
 
@@ -36,6 +39,9 @@ public class CounterAttackEventHandler {
     }
     }
 
 
     protected void sendAbilityMessages() {
     protected void sendAbilityMessages() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Swords.Combat.Countered"));
         player.sendMessage(LocaleLoader.getString("Swords.Combat.Countered"));
 
 
         if (attacker instanceof Player) {
         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() {
     protected void applyAbilityEffects() {
+        if(player == null)
+            return;
+
         Combat.applyAbilityAoE(player, target, damage / Swords.SERRATED_STRIKES_MODIFIER, SkillType.SWORDS);
         Combat.applyAbilityAoE(player, target, damage / Swords.SERRATED_STRIKES_MODIFIER, SkillType.SWORDS);
         BleedTimer.add(target, Swords.SERRATED_STRIKES_BLEED_TICKS);
         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
      * @param defender The defending entity
      */
      */
     public void bleedCheck(LivingEntity defender) {
     public void bleedCheck(LivingEntity defender) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.swordsBleed(player)) {
         if (!permissionsInstance.swordsBleed(player)) {
             return;
             return;
         }
         }
@@ -49,6 +55,12 @@ public class SwordsManager {
     }
     }
 
 
     public void counterAttackChecks(LivingEntity attacker, int damage) {
     public void counterAttackChecks(LivingEntity attacker, int damage) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.counterAttack(player)) {
         if (!permissionsInstance.counterAttack(player)) {
             return;
             return;
         }
         }
@@ -72,6 +84,12 @@ public class SwordsManager {
     }
     }
 
 
     public void serratedStrikes(LivingEntity target, int damage) {
     public void serratedStrikes(LivingEntity target, int damage) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.serratedStrikes(player)) {
         if (!permissionsInstance.serratedStrikes(player)) {
             return;
             return;
         }
         }

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

@@ -19,6 +19,9 @@ public class BeastLoreEventHandler {
     }
     }
 
 
     protected void sendInspectMessage() {
     protected void sendInspectMessage() {
+        if(player == null)
+            return;
+
         String message = LocaleLoader.getString("Combat.BeastLore") + " ";
         String message = LocaleLoader.getString("Combat.BeastLore") + " ";
 
 
         if (beast.isTamed()) {
         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() {
     protected void sendInsufficientAmountMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.GRAY + Misc.prettyItemString(inHand.getTypeId()));
         player.sendMessage(LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.GRAY + Misc.prettyItemString(inHand.getTypeId()));
     }
     }
 
 
     protected boolean nearbyEntityExists() {
     protected boolean nearbyEntityExists() {
+        if(player == null)
+            return false;
+
         boolean entityExists = false;
         boolean entityExists = false;
 
 
         for (Entity entity : player.getNearbyEntities(40, 40, 40)) {
         for (Entity entity : player.getNearbyEntities(40, 40, 40)) {
@@ -46,6 +52,9 @@ public class CallOfTheWildEventHandler {
     }
     }
 
 
     protected void sendFailureMessage() {
     protected void sendFailureMessage() {
+        if(player == null)
+            return;
+
         if (type == EntityType.OCELOT) {
         if (type == EntityType.OCELOT) {
             player.sendMessage(LocaleLoader.getString("Taming.Summon.Fail.Ocelot"));
             player.sendMessage(LocaleLoader.getString("Taming.Summon.Fail.Ocelot"));
         }
         }
@@ -55,6 +64,9 @@ public class CallOfTheWildEventHandler {
     }
     }
 
 
     protected void spawnCreature() {
     protected void spawnCreature() {
+        if(player == null)
+            return;
+
         LivingEntity entity = (LivingEntity) player.getWorld().spawnEntity(player.getLocation(), type);
         LivingEntity entity = (LivingEntity) player.getWorld().spawnEntity(player.getLocation(), type);
         entity.setMetadata("mcmmoSummoned", new FixedMetadataValue(mcMMO.p, true));
         entity.setMetadata("mcmmoSummoned", new FixedMetadataValue(mcMMO.p, true));
 
 
@@ -69,6 +81,9 @@ public class CallOfTheWildEventHandler {
     }
     }
 
 
     protected void processResourceCost() {
     protected void processResourceCost() {
+        if(player == null)
+            return;
+
         int newAmount = inHand.getAmount() - summonAmount;
         int newAmount = inHand.getAmount() - summonAmount;
 
 
         if (newAmount == 0) {
         if (newAmount == 0) {
@@ -80,6 +95,9 @@ public class CallOfTheWildEventHandler {
     }
     }
 
 
     protected void sendSuccessMessage() {
     protected void sendSuccessMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Taming.Summon.Complete"));
         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() {
     protected void teleportWolf() {
+        if(player == null)
+            return;
+
         if (event.getDamage() > wolf.getHealth()) {
         if (event.getDamage() > wolf.getHealth()) {
             return;
             return;
         }
         }
@@ -26,6 +29,9 @@ public class EnvironmentallyAwareEventHandler {
     }
     }
 
 
     protected void sendAbilityMessage() {
     protected void sendAbilityMessage() {
+        if(player == null)
+            return;
+
         player.sendMessage(LocaleLoader.getString("Taming.Listener.Wolf"));
         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
      * @param damage The damage being absorbed by the wolf
      */
      */
     public void fastFoodService(Wolf wolf, int damage) {
     public void fastFoodService(Wolf wolf, int damage) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.fastFoodService(player)) {
         if (!permissionsInstance.fastFoodService(player)) {
             return;
             return;
         }
         }
@@ -61,6 +67,12 @@ public class TamingManager {
      * @param event The event to modify
      * @param event The event to modify
      */
      */
     public void sharpenedClaws(EntityDamageEvent event) {
     public void sharpenedClaws(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.sharpenedClaws(player)) {
         if (!permissionsInstance.sharpenedClaws(player)) {
             return;
             return;
         }
         }
@@ -78,6 +90,12 @@ public class TamingManager {
      * @param event The event to modify
      * @param event The event to modify
      */
      */
     public void gore(EntityDamageEvent event) {
     public void gore(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.gore(player)) {
         if (!permissionsInstance.gore(player)) {
             return;
             return;
         }
         }
@@ -150,6 +168,12 @@ public class TamingManager {
      * @param livingEntity The entity to examine
      * @param livingEntity The entity to examine
      */
      */
     public void beastLore(LivingEntity livingEntity) {
     public void beastLore(LivingEntity livingEntity) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.beastLore(player)) {
         if (!permissionsInstance.beastLore(player)) {
             return;
             return;
         }
         }
@@ -166,6 +190,12 @@ public class TamingManager {
      * @param summonAmount The amount of material needed to summon the entity
      * @param summonAmount The amount of material needed to summon the entity
      */
      */
     private void callOfTheWild(EntityType type, int summonAmount) {
     private void callOfTheWild(EntityType type, int summonAmount) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.callOfTheWild(player)) {
         if (!permissionsInstance.callOfTheWild(player)) {
             return;
             return;
         }
         }
@@ -198,6 +228,12 @@ public class TamingManager {
      * @param cause The damage cause of the event
      * @param cause The damage cause of the event
      */
      */
     private void environmentallyAware(EntityDamageEvent event, DamageCause cause) {
     private void environmentallyAware(EntityDamageEvent event, DamageCause cause) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.environmentallyAware(player)) {
         if (!permissionsInstance.environmentallyAware(player)) {
             return;
             return;
         }
         }
@@ -230,6 +266,12 @@ public class TamingManager {
      * @param cause The damage cause of the event
      * @param cause The damage cause of the event
      */
      */
     private void thickFur(EntityDamageEvent event, DamageCause cause) {
     private void thickFur(EntityDamageEvent event, DamageCause cause) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.thickFur(player)) {
         if (!permissionsInstance.thickFur(player)) {
             return;
             return;
         }
         }
@@ -247,6 +289,12 @@ public class TamingManager {
      * @param event The event to modify
      * @param event The event to modify
      */
      */
     private void shockProof(EntityDamageEvent event) {
     private void shockProof(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.shockProof(player)) {
         if (!permissionsInstance.shockProof(player)) {
             return;
             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
      * @param defender The defending player
      */
      */
     public void disarmCheck(Player defender) {
     public void disarmCheck(Player defender) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.disarm(player)) {
         if (!permissionsInstance.disarm(player)) {
             return;
             return;
         }
         }
@@ -58,6 +64,12 @@ public class UnarmedManager {
      * @param event The event to modify
      * @param event The event to modify
      */
      */
     public void deflectCheck(EntityDamageEvent event) {
     public void deflectCheck(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.deflect(player)) {
         if (!permissionsInstance.deflect(player)) {
             return;
             return;
         }
         }
@@ -82,6 +94,12 @@ public class UnarmedManager {
      * @param event The event to modify.
      * @param event The event to modify.
      */
      */
     public void bonusDamage(EntityDamageEvent event) {
     public void bonusDamage(EntityDamageEvent event) {
+        if(player == null)
+            return;
+
+        if(permissionsInstance == null)
+            return;
+
         if (!permissionsInstance.unarmedBonus(player)) {
         if (!permissionsInstance.unarmedBonus(player)) {
             return;
             return;
         }
         }
@@ -99,6 +117,12 @@ public class UnarmedManager {
      * @return true if the defender was not disarmed, false otherwise
      * @return true if the defender was not disarmed, false otherwise
      */
      */
     private boolean hasIronGrip(Player defender) {
     private boolean hasIronGrip(Player defender) {
+        if(defender == null)
+            return false;
+
+        if(permissionsInstance == null)
+            return false;
+
         if (!permissionsInstance.ironGrip(defender)) {
         if (!permissionsInstance.ironGrip(defender)) {
             return false;
             return false;
         }
         }

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

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.util;
 package com.gmail.nossr50.util;
 
 
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
+import org.bukkit.Material;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.api.SpoutToolsAPI;
 import com.gmail.nossr50.api.SpoutToolsAPI;
@@ -463,4 +464,14 @@ public class ItemChecks {
             return false;
             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
      * @param xp the amount of XP to gain
      */
      */
     public static void xpProcessing(Player player, PlayerProfile profile, SkillType type, int xp) {
     public static void xpProcessing(Player player, PlayerProfile profile, SkillType type, int xp) {
+        if(player == null)
+            return;
+
         if (type.getPermissions(player)) {
         if (type.getPermissions(player)) {
+	    if(Users.getPlayer(player) == null)
+                return;
+
             Users.getPlayer(player).addXP(type, xp);
             Users.getPlayer(player).addXP(type, xp);
             xpCheckSkill(type, player, profile);
             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) {
     public void saveWorld(World world) {
         String worldName = world.getName();
         String worldName = world.getName();
         File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
         File dataDir = new File(world.getWorldFolder(), "mcmmo_data");
+        if(!dataDir.exists())
+            dataDir.mkdirs();
 
 
         for(String key : store.keySet()) {
         for(String key : store.keySet()) {
             String[] info = key.split(",");
             String[] info = key.split(",");
@@ -280,6 +282,8 @@ public class HashChunkletManager implements ChunkletManager {
         ObjectOutputStream objOut = null;
         ObjectOutputStream objOut = null;
 
 
         try {
         try {
+            if(!location.exists())
+                location.createNewFile();
             fileOut = new FileOutputStream(location);
             fileOut = new FileOutputStream(location);
             objOut = new ObjectOutputStream(fileOut);
             objOut = new ObjectOutputStream(fileOut);
             objOut.writeObject(cStore);
             objOut.writeObject(cStore);