Browse Source

Join-Leave-Message Events, Command-Aliases, Permission-System, Msg, Answer

Kajetan Johannes Hammerle 7 years ago
parent
commit
b92a467bad
70 changed files with 855 additions and 319 deletions
  1. 6 0
      src/main/java/me/km/ClientProxy.java
  2. 21 0
      src/main/java/me/km/CommonProxy.java
  3. 19 7
      src/main/java/me/km/KajetansMod.java
  4. 1 2
      src/main/java/me/km/afk/CommandAFK.java
  5. 5 0
      src/main/java/me/km/api/GlobalText.java
  6. 24 9
      src/main/java/me/km/api/ModuleCommand.java
  7. 2 2
      src/main/java/me/km/api/SimpleConfig.java
  8. 7 59
      src/main/java/me/km/api/Utils.java
  9. 4 5
      src/main/java/me/km/blockprotections/BlockProtection.java
  10. 11 9
      src/main/java/me/km/blockprotections/CommandBlock.java
  11. 1 2
      src/main/java/me/km/blockprotections/SemiProtections.java
  12. 2 2
      src/main/java/me/km/chatmanager/ChatManager.java
  13. 1 0
      src/main/java/me/km/chatmanager/CommandColor.java
  14. 1 0
      src/main/java/me/km/chatmanager/CommandNickName.java
  15. 64 0
      src/main/java/me/km/commands/Answer.java
  16. 2 2
      src/main/java/me/km/commands/CommandBed.java
  17. 1 0
      src/main/java/me/km/commands/CommandBook.java
  18. 1 0
      src/main/java/me/km/commands/CommandCoords.java
  19. 1 0
      src/main/java/me/km/commands/CommandExp.java
  20. 2 2
      src/main/java/me/km/commands/CommandFly.java
  21. 3 2
      src/main/java/me/km/commands/CommandGameMode.java
  22. 5 6
      src/main/java/me/km/commands/CommandHome.java
  23. 1 0
      src/main/java/me/km/commands/CommandItemInfo.java
  24. 3 2
      src/main/java/me/km/commands/CommandKill.java
  25. 1 1
      src/main/java/me/km/commands/CommandLightUpdate.java
  26. 1 0
      src/main/java/me/km/commands/CommandMemory.java
  27. 18 56
      src/main/java/me/km/commands/CommandMsg.java
  28. 2 1
      src/main/java/me/km/commands/CommandPosition.java
  29. 1 2
      src/main/java/me/km/commands/CommandPvP.java
  30. 1 0
      src/main/java/me/km/commands/CommandSummon.java
  31. 1 1
      src/main/java/me/km/commands/CommandTeleport.java
  32. 1 0
      src/main/java/me/km/commands/CommandTeleportAccept.java
  33. 3 1
      src/main/java/me/km/commands/CommandWarp.java
  34. 2 2
      src/main/java/me/km/databank/SimpleDataBank.java
  35. 2 1
      src/main/java/me/km/datatools/CommandDataTools.java
  36. 1 1
      src/main/java/me/km/datatools/CommandVillager.java
  37. 2 2
      src/main/java/me/km/effects/EffectUtils.java
  38. 0 2
      src/main/java/me/km/effects/active/Harvest.java
  39. 0 2
      src/main/java/me/km/effects/passive/Mugging.java
  40. 1 0
      src/main/java/me/km/environment/CommandHealStats.java
  41. 1 0
      src/main/java/me/km/environment/CommandTemperature.java
  42. 11 8
      src/main/java/me/km/events/CustomEventCaller.java
  43. 227 0
      src/main/java/me/km/events/ModDedicatedPlayerList.java
  44. 15 0
      src/main/java/me/km/events/ModNetHandlerPlayServer.java
  45. 32 0
      src/main/java/me/km/events/PlayerJoinMessageEvent.java
  46. 25 0
      src/main/java/me/km/events/PlayerLeaveMessageEvent.java
  47. 1 2
      src/main/java/me/km/items/ItemWand.java
  48. 1 0
      src/main/java/me/km/jobsystem/CommandRecipe.java
  49. 0 17
      src/main/java/me/km/permissions/Permission.java
  50. 34 0
      src/main/java/me/km/permissions/PermissionListener.java
  51. 141 0
      src/main/java/me/km/permissions/PermissionManager.java
  52. 8 9
      src/main/java/me/km/playerbank/PlayerLogInOut.java
  53. 19 17
      src/main/java/me/km/plots/CommandPlot.java
  54. 4 4
      src/main/java/me/km/plots/ProtectionBlockAction.java
  55. 2 2
      src/main/java/me/km/plots/ProtectionBucketUse.java
  56. 0 24
      src/main/java/me/km/plots/ProtectionCommand.java
  57. 4 4
      src/main/java/me/km/plots/ProtectionEntity.java
  58. 4 4
      src/main/java/me/km/plots/ProtectionInteract.java
  59. 3 3
      src/main/java/me/km/plots/ProtectionMarkPlot.java
  60. 1 0
      src/main/java/me/km/scrolls/CommandScroll.java
  61. 1 0
      src/main/java/me/km/skills/CommandActiveSkills.java
  62. 1 2
      src/main/java/me/km/skills/Skill.java
  63. 4 0
      src/main/java/me/km/snuviscript/CommandGiveUp.java
  64. 1 0
      src/main/java/me/km/snuviscript/CommandQuest.java
  65. 1 0
      src/main/java/me/km/snuviscript/CommandScript.java
  66. 1 13
      src/main/java/me/km/snuviscript/QuestData.java
  67. 17 7
      src/main/java/me/km/snuviscript/QuestParser.java
  68. 17 15
      src/main/java/me/km/snuviscript/QuestsEvents.java
  69. 22 5
      src/main/java/me/km/utils/ItemStackBuilder.java
  70. 32 0
      src/main/java/me/km/utils/ItemStackUtils.java

+ 6 - 0
src/main/java/me/km/ClientProxy.java

@@ -9,6 +9,7 @@ import net.minecraft.client.renderer.block.statemap.StateMapperBase;
 import net.minecraft.client.renderer.entity.Render;
 import net.minecraft.entity.Entity;
 import net.minecraft.item.Item;
+import net.minecraft.server.MinecraftServer;
 import net.minecraftforge.client.model.ModelLoader;
 import net.minecraftforge.fluids.IFluidBlock;
 import net.minecraftforge.fml.client.registry.RenderingRegistry;
@@ -50,4 +51,9 @@ public class ClientProxy extends CommonProxy
     {
         ModEntities.initClient();
     }
+
+    @Override
+    public void overloadPlayerList(MinecraftServer server) 
+    {
+    }
 }

+ 21 - 0
src/main/java/me/km/CommonProxy.java

@@ -1,10 +1,15 @@
 package me.km;
 
 import me.km.entities.ModEntities;
+import me.km.events.ModDedicatedPlayerList;
 import net.minecraft.client.renderer.entity.Render;
 import net.minecraft.entity.Entity;
 import net.minecraft.item.Item;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.dedicated.DedicatedServer;
 import net.minecraftforge.fluids.IFluidBlock;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
 
 public class CommonProxy 
 {
@@ -24,4 +29,20 @@ public class CommonProxy
     {
         ModEntities.initServer();
     }
+    
+    public void overloadPlayerList(MinecraftServer server)
+    {
+        // This prevents clients from crashing, the custom player list only loads on servers
+        overloadPlayerListWorkaround(server);
+    }
+    
+    @SideOnly(Side.SERVER)
+    private void overloadPlayerListWorkaround(MinecraftServer server)
+    {
+        if(server instanceof DedicatedServer)
+        {
+            DedicatedServer dedi = (DedicatedServer) server;
+            dedi.setPlayerList(new ModDedicatedPlayerList(dedi));
+        }
+    }
 }

+ 19 - 7
src/main/java/me/km/KajetansMod.java

@@ -6,12 +6,12 @@ import me.km.blockprotections.BlockProtectionBank;
 import me.km.blocks.ModBlocks;
 import me.km.chatmanager.ChatManager;
 import me.km.databank.DataBank;
-import me.km.dimensions.ModDimensions;
 import me.km.dimensions.WorldData;
 import me.km.effects.EffectUtils;
 import me.km.fluids.ModFluids;
 import me.km.items.ModItems;
 import me.km.jobsystem.JobAPI;
+import me.km.permissions.PermissionManager;
 import me.km.playerbank.PlayerBank;
 import me.km.playerbank.PlayerManager;
 import me.km.plots.ProtectionBank;
@@ -22,13 +22,13 @@ import me.km.snuviscript.QuestAPI;
 import me.km.snuviscript.QuestBank;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.util.text.TextFormatting;
-import net.minecraftforge.fml.common.FMLCommonHandler;
 import net.minecraftforge.fml.common.Mod;
 import net.minecraftforge.fml.common.SidedProxy;
 import net.minecraftforge.fml.common.event.FMLInitializationEvent;
 import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
 import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
 import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
+import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent;
 import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
 // event classes
 //import net.minecraftforge.common.ForgeHooks;
@@ -39,6 +39,7 @@ public class KajetansMod
 {    
     public static SimpleConfig conf;
     
+    public static Module error;
     public static DataBank databank;
     public static SnuviScheduler scheduler;
     public static PlayerManager playerbank;
@@ -56,6 +57,7 @@ public class KajetansMod
     public static SkillManager skills;
     public static Module scrolls;
     public static ScoreboardAPI scoreboard;
+    public static PermissionManager perms;
     
     @SidedProxy(serverSide = "me.km.CommonProxy", clientSide = "me.km.ClientProxy")
     public static CommonProxy proxy;
@@ -78,13 +80,19 @@ public class KajetansMod
         ModBlocks.init();
     }
     
+    @Mod.EventHandler
+    public void beforeStart(FMLServerAboutToStartEvent e) 
+    {
+        // takes place after setting of playerlist but before world load
+        server = e.getServer();
+        proxy.overloadPlayerList(server);
+    }
+    
     @Mod.EventHandler
     public void serverStarting(FMLServerStartingEvent e) 
     {
-        server = FMLCommonHandler.instance().getMinecraftServerInstance();
-        
         // Konfiguration und Error-Dummy
-        Module error = new Module("ERROR", "ERROR", TextFormatting.RED);
+        error = new Module("ERROR", "ERROR", TextFormatting.RED);
         conf = new SimpleConfig(error, "config", true);
         
         // Datenbankverbindung
@@ -174,6 +182,10 @@ public class KajetansMod
         // Scoreboard
         scoreboard = new ScoreboardAPI("Scoreboard", "Scoreboard", TextFormatting.GOLD);
         scoreboard.registerEvents("me.km.scoreboard");
+        
+        // Permissions
+        perms = new PermissionManager("Permissions", "Perms", TextFormatting.DARK_PURPLE);
+        perms.registerEvents("me.km.permissions");
           
         //quest.startScript(this.getServer().getConsoleSender(), "startscript");
     }
@@ -185,13 +197,13 @@ public class KajetansMod
     }
 
     @Mod.EventHandler
-    public void init(FMLInitializationEvent event) 
+    public void init(FMLInitializationEvent e) 
     {
         proxy.initEntities();
     }
 
     @Mod.EventHandler
-    public void postInit(FMLPostInitializationEvent event) 
+    public void postInit(FMLPostInitializationEvent e) 
     {
         ModItems.lateInit();
     }

+ 1 - 2
src/main/java/me/km/afk/CommandAFK.java

@@ -6,7 +6,6 @@ import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.api.Utils;
 import me.km.exception.PlayerNotFoundException;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -27,7 +26,7 @@ public class CommandAFK extends ModuleCommand
         EntityPlayer affectedPlayer;
         try
         {
-            if(!Permission.has(cs, Permissions.AFK))
+            if(!KajetansMod.perms.has(cs, Permissions.AFK))
             {
                 throw new IndexOutOfBoundsException();
             }   

+ 5 - 0
src/main/java/me/km/api/GlobalText.java

@@ -52,6 +52,11 @@ public class GlobalText
         return "Dieses Feature ist noch nicht implementiert.";
     }
     
+    public static String noPermission()
+    {
+        return "Du hast keine Rechte für diesen Command.";
+    }
+    
     public static String Spacer()
     {
         return "§0-----------------------------------------------------";

+ 24 - 9
src/main/java/me/km/api/ModuleCommand.java

@@ -1,6 +1,9 @@
 package me.km.api;
 
-import me.km.permissions.Permission;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import me.km.KajetansMod;
 import me.km.permissions.Permissions;
 import net.minecraft.command.CommandBase;
 import net.minecraft.command.CommandException;
@@ -14,6 +17,7 @@ public abstract class ModuleCommand extends CommandBase
     private String usage;
     private String description;
     private Permissions perm;
+    private List<String> aliases;
     
     public ModuleCommand(String name, Module m) 
     {
@@ -21,8 +25,24 @@ public abstract class ModuleCommand extends CommandBase
         this.m = m;
         this.usage = "";
         this.perm = null;
+        this.aliases = Collections.<String>emptyList();
+    }
+
+    @Override
+    public List<String> getAliases() 
+    {
+        return aliases;
     }
     
+    public void addAlias(String s)
+    {
+        if(aliases.isEmpty())
+        {
+            aliases = new ArrayList<>();
+        }
+        aliases.add(s);
+    }
+
     public Module getModule()
     {
         return m;
@@ -70,9 +90,9 @@ public abstract class ModuleCommand extends CommandBase
     @Override
     public void execute(MinecraftServer server, ICommandSender cs, String[] args) throws CommandException
     {
-        if(!Permission.has(cs, this))
+        if(!KajetansMod.perms.has(cs, perm))
         {
-            m.sendWarning(cs, "Du hast keine Rechte für diesen Command.");
+            m.sendWarning(cs, GlobalText.noPermission());
             return;
         }       
         if(!execute(cs, args))
@@ -84,11 +104,6 @@ public abstract class ModuleCommand extends CommandBase
     @Override
     public boolean checkPermission(MinecraftServer server, ICommandSender cs) 
     {
-        if(Permission.has(cs, this))
-        {
-            return true;
-        }  
-        m.sendWarning(cs, "Du hast keine Rechte für diesen Command. 2");
-        return false;
+        return KajetansMod.perms.has(cs, perm);
     }
 }

+ 2 - 2
src/main/java/me/km/api/SimpleConfig.java

@@ -55,9 +55,9 @@ public class SimpleConfig
         }
     }
     
-    public static List<File> getFiles(String path)
+    public static File[] getFiles(String path)
     {
-        return Arrays.asList(new File("./" + path).listFiles());
+        return new File("./" + path).listFiles();
     }
     
     public boolean exists()

+ 7 - 59
src/main/java/me/km/api/Utils.java

@@ -239,65 +239,6 @@ public class Utils
     // ItemStack-Tools
     // -------------------------------------------------------------------------
     
-    public static List<String> getLore(ItemStack stack)
-    {
-        //TODO
-        /*if(!stack.hasItemMeta() || !stack.getItemMeta().hasLore())
-        {*/
-            return new ArrayList<>();
-        /*}
-        return new ArrayList<>(stack.getItemMeta().getLore());*/
-    }    
-    
-    public static void setLore(ItemStack stack, String s, int i)
-    {     
-        //TODO
-        /*ItemMeta meta = stack.getItemMeta();
-        List<String> list;
-        if(meta.hasLore())
-        {
-            list = meta.getLore();
-        }
-        else
-        {
-            list = new ArrayList<>();
-        }                           
-        if(i >= list.size())
-        {
-            list.add(s);
-        }
-        else
-        {
-            list.set(i, s);
-        }           
-        meta.setLore(list);
-        stack.setItemMeta(meta);*/
-    }
-    
-    public static ArrayList<String> buildLimitedLore(String whole, int limit, String addition)
-    {
-        ArrayList<String> list = new ArrayList<>();
-        int pos = 0;
-        int space;
-        while(pos + limit < whole.length())
-        {
-            space = whole.lastIndexOf(" ", pos + limit);
-            if(space == -1 || pos > space)
-            {
-                space = whole.indexOf(" ", pos + limit);
-            }          
-            list.add(addition + whole.substring(pos, space));  
-            pos = space + 1;
-        }
-        list.add(addition + whole.substring(pos));
-        return list;
-    }
-    
-    public static ArrayList<String> buildLimitedLore(String whole, String addition)
-    { 
-        return buildLimitedLore(whole, 25, addition);
-    }
-    
     public static void dropRandomTreeItem(World w, BlockPos l, IBlockState b)
     {
         Block block = b.getBlock();
@@ -614,6 +555,13 @@ public class Utils
                     .filter(pl -> pl.getName().contains(name))
                     .findFirst().orElseThrow(() -> new PlayerNotFoundException(name));
     }
+    
+    public static EntityPlayerMP getPlayerByDisplayName(String name) throws PlayerNotFoundException
+    {
+        return KajetansMod.server.getPlayerList().getPlayers().stream()
+                    .filter(pl -> pl.getDisplayNameString().contains(name))
+                    .findFirst().orElseThrow(() -> new PlayerNotFoundException(name));
+    }
         
     // -------------------------------------------------------------------------
     // Spawn

+ 4 - 5
src/main/java/me/km/blockprotections/BlockProtection.java

@@ -4,7 +4,6 @@ import me.km.KajetansMod;
 import me.km.api.Utils;
 import me.km.api.Module;
 import me.km.api.ModuleListener;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.block.Block;
 import net.minecraft.block.BlockContainer;
@@ -49,7 +48,7 @@ public class BlockProtection extends ModuleListener
         if(b == Blocks.CHEST || b == Blocks.TRAPPED_CHEST)
         {
             BlockPos otherChest = Utils.getSameNearbyBlock(w, e.getPos(), b);
-            if(otherChest != null && !bank.hasAccess(otherChest, w, p.getGameProfile(), true) && !Permission.has(p, Permissions.BLOCK_BYPASS))
+            if(otherChest != null && !bank.hasAccess(otherChest, w, p.getGameProfile(), true) && !KajetansMod.perms.has(p, Permissions.BLOCK_BYPASS))
             {
                 this.getModule().send(p, "Du darfst diesen Block hier nicht setzen");
                 e.setCanceled(true);
@@ -63,7 +62,7 @@ public class BlockProtection extends ModuleListener
             BlockPos pos = e.getPos().add(0, 1, 0);
             if(w.getBlockState(pos).getBlock() instanceof BlockContainer)
             {
-                if(!bank.hasAccess(pos, w, p, true) && !Permission.has(p, Permissions.BLOCK_BYPASS))
+                if(!bank.hasAccess(pos, w, p, true) && !KajetansMod.perms.has(p, Permissions.BLOCK_BYPASS))
                 {
                     this.getModule().send(p, "Du darfst diesen Block hier nicht setzen");
                     e.setCanceled(true);
@@ -93,7 +92,7 @@ public class BlockProtection extends ModuleListener
             {
                 return;
             }       
-            if(bank.hasAccess(pos, w, p, false) || Permission.has(p, Permissions.BLOCK_BYPASS))
+            if(bank.hasAccess(pos, w, p, false) || KajetansMod.perms.has(p, Permissions.BLOCK_BYPASS))
             {
                 bank.removeBlock(pos, w, p);
                 return;
@@ -121,7 +120,7 @@ public class BlockProtection extends ModuleListener
         {
             pos = pos.add(0, -1, 0);
         }
-        if(bank.hasAccess(pos, e.getWorld(), p, true) || Permission.has(p, Permissions.BLOCK_BYPASS))
+        if(bank.hasAccess(pos, e.getWorld(), p, true) || KajetansMod.perms.has(p, Permissions.BLOCK_BYPASS))
         {
             return;
         }  

+ 11 - 9
src/main/java/me/km/blockprotections/CommandBlock.java

@@ -6,7 +6,6 @@ import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.api.Utils;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.block.Block;
 import net.minecraft.block.BlockDoor;
@@ -31,6 +30,9 @@ public class CommandBlock extends ModuleCommand
         super.setDescription("Zeigt alles für die Block-Verwaltung");
         super.setUsage("/block für die Hilfe");
         super.setPermission(Permissions.BLOCK);
+        super.addAlias("blocks");
+        super.addAlias("pro");
+        super.addAlias("protect");
         
         bank = KajetansMod.blocks.getDataBank(BlockProtectionBank.class);
         //locs = new ArrayList<>();
@@ -48,7 +50,7 @@ public class CommandBlock extends ModuleCommand
         Module m = this.getModule();
         EntityPlayerMP p = (EntityPlayerMP) cs;
         World w = p.getEntityWorld();
-        if(!KajetansMod.worldManager.getWorldPreferences(w).blockProtection && !Permission.has(cs, Permissions.BLOCK_BYPASS))
+        if(!KajetansMod.worldManager.getWorldPreferences(w).blockProtection && !KajetansMod.perms.has(cs, Permissions.BLOCK_BYPASS))
         {
             m.send(cs, "Du darfst hier keine Blöcke schützen.");
             return true;
@@ -58,7 +60,7 @@ public class CommandBlock extends ModuleCommand
             BlockPos pos = Utils.getPlayerTarget(p);  
             IBlockState state = w.getBlockState(pos);
             Block b = state.getBlock();
-            if(!Utils.shouldBeProtected(b) && !Permission.has(cs, Permissions.BLOCK_ALL))
+            if(!Utils.shouldBeProtected(b) && !KajetansMod.perms.has(cs, Permissions.BLOCK_ALL))
             {
                 m.send(cs, "Du kannst diesen Block nicht bearbeiten.");
                 m.send(cs, "Du bist auf folgenden Block gerichtet: " + b.toString());
@@ -73,7 +75,7 @@ public class CommandBlock extends ModuleCommand
                 case "protect":  
                 {
                     String name = null;
-                    if(arg.length >= 2 && Permission.has(cs, Permissions.BLOCK_OTHER))
+                    if(arg.length >= 2 && KajetansMod.perms.has(cs, Permissions.BLOCK_OTHER))
                     {
                         name = arg[1];
                     }
@@ -96,7 +98,7 @@ public class CommandBlock extends ModuleCommand
                         this.getModule().send(p, "Der Block ist nicht gesichert.");
                         return true;
                     }
-                    if(!bank.hasAccess(pos, w, p, false) && !Permission.has(cs, Permissions.BLOCK_BYPASS))
+                    if(!bank.hasAccess(pos, w, p, false) && !KajetansMod.perms.has(cs, Permissions.BLOCK_BYPASS))
                     {
                         m.send(cs, "Du hast keinen Zugriff auf diesen Block.");
                         return true;
@@ -127,7 +129,7 @@ public class CommandBlock extends ModuleCommand
                             this.getModule().send(p, "Der Block ist nicht gesichert.");
                             return true;
                         }
-                        if(!bank.hasAccess(pos, w, p, false) && !Permission.has(cs, Permissions.BLOCK_BYPASS))
+                        if(!bank.hasAccess(pos, w, p, false) && !KajetansMod.perms.has(cs, Permissions.BLOCK_BYPASS))
                         {
                             m.send(cs, "Du hast keinen Zugriff auf diesen Block.");
                             return true;
@@ -160,7 +162,7 @@ public class CommandBlock extends ModuleCommand
                             this.getModule().send(p, "Der Block ist nicht gesichert.");
                             return true;
                         }
-                        if(!bank.hasAccess(pos, w, p, true) && !Permission.has(cs, Permissions.BLOCK_BYPASS))
+                        if(!bank.hasAccess(pos, w, p, true) && !KajetansMod.perms.has(cs, Permissions.BLOCK_BYPASS))
                         {
                             m.send(cs, "Du hast keinen Zugriff auf diesen Block.");
                             return true;
@@ -186,7 +188,7 @@ public class CommandBlock extends ModuleCommand
                 }
                 case "clear":
                 {
-                    if(Permission.has(cs, Permissions.BLOCK_CLEAR))
+                    if(KajetansMod.perms.has(cs, Permissions.BLOCK_CLEAR))
                     {
                         //TODO
                         this.getModule().send(cs, GlobalText.notImplementedYet());
@@ -243,7 +245,7 @@ public class CommandBlock extends ModuleCommand
         m.sendHelpListElement(cs, "info", "Gibt Information über den Block");
         m.sendHelpListElement(cs, "share <player>", "Teilt eine Block-Protection mit einem Spieler");
         m.sendHelpListElement(cs, "kick <player>", "Kickt einen Spieler von einer Block-Protection");
-        if(Permission.has(cs, Permissions.BLOCK_CLEAR))
+        if(KajetansMod.perms.has(cs, Permissions.BLOCK_CLEAR))
         {
             m.sendHelpListElement(cs, "clear", "Entfernt ungültige Block-Protections auf jeden Block");
         }

+ 1 - 2
src/main/java/me/km/blockprotections/SemiProtections.java

@@ -3,7 +3,6 @@ package me.km.blockprotections;
 import me.km.KajetansMod;
 import me.km.api.Module;
 import me.km.api.ModuleListener;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import me.km.plots.ProtectionBank;
 import net.minecraft.block.BlockCrops;
@@ -26,7 +25,7 @@ public class SemiProtections extends ModuleListener
     public void onBlockBreak(BlockEvent.BreakEvent e)
     {
         EntityPlayer p = e.getPlayer();
-        if(Permission.has(p, Permissions.BLOCK_BYPASS) && p.isCreative())
+        if(KajetansMod.perms.has(p, Permissions.BLOCK_BYPASS) && p.isCreative())
         {
             return;
         }

+ 2 - 2
src/main/java/me/km/chatmanager/ChatManager.java

@@ -6,7 +6,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.UUID;
 import java.util.stream.Collectors;
-import me.km.permissions.Permission;
+import me.km.KajetansMod;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -153,7 +153,7 @@ public class ChatManager extends Module
     public static String colorMessage(String text, ICommandSender cs) 
     {
         text = text.replace("&k", "");
-        if(Permission.has(cs, Permissions.USE_COLOR))
+        if(KajetansMod.perms.has(cs, Permissions.USE_COLOR))
         {
             text = text.replace("&", "§");
             return text;

+ 1 - 0
src/main/java/me/km/chatmanager/CommandColor.java

@@ -13,6 +13,7 @@ public class CommandColor extends ModuleCommand
         super.setDescription("Zeigt dir die möglichen Farben");
         super.setUsage("/color");
         super.setPermission(Permissions.COLOR);
+        super.addAlias("colors");
     }
 
     @Override

+ 1 - 0
src/main/java/me/km/chatmanager/CommandNickName.java

@@ -17,6 +17,7 @@ public class CommandNickName extends ModuleCommand
         super.setDescription("Gibt einem Spieler einen Nickname");
         super.setUsage("/nickname <nick/clear> [player]");
         super.setPermission(Permissions.NICKNAME);
+        super.addAlias("nick");
     }
 
     @Override

+ 64 - 0
src/main/java/me/km/commands/Answer.java

@@ -0,0 +1,64 @@
+package me.km.commands;
+
+import java.util.HashMap;
+import me.km.KajetansMod;
+import me.km.api.Module;
+import me.km.api.ModuleCommand;
+import me.km.api.Utils;
+import me.km.chatmanager.ChatManager;
+import me.km.exception.PlayerNotFoundException;
+import me.km.permissions.Permissions;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.util.text.TextComponentString;
+
+public class Answer extends ModuleCommand
+{
+    public Answer(Module m) 
+    {
+        super("answer", m);
+        super.setDescription("Schreibt dem letzten Spieler eine Privatnachricht");
+        super.setUsage("/answer <message>");
+        super.setPermission(Permissions.MSG);
+        super.addAlias("r");
+    }
+
+    @Override
+    public boolean execute(ICommandSender cs, String[] arg) 
+    {
+        if(arg.length == 0)
+        {
+            return false;
+        }
+        HashMap<String, String> answer = KajetansMod.generalCommands.getCommand(CommandMsg.class).answer;
+        String s = answer.get(cs.getName());
+        if(s == null)
+        {
+            this.getModule().send(cs, "Du hast niemanden, dem du antworten könntest.");
+            return true;
+        }
+        ICommandSender previous;
+        if(s.equals("CONSOLE"))
+        {
+            previous = KajetansMod.server;
+        }
+        else
+        {
+            try
+            {
+                previous = Utils.getPlayerByName(s);            
+            }
+            catch(PlayerNotFoundException ex)
+            {
+                this.getModule().send(cs, "Du hast niemanden, dem du antworten könntest.");
+                return true;
+            }
+        }
+        
+        String message = ChatManager.colorMessage(Utils.connectSpaces(arg, 0), cs);
+        cs.sendMessage(new TextComponentString("§6[ -> §c" + previous.getName()+ "§6] §r" + message));
+        previous.sendMessage(new TextComponentString("§6[§c" + cs.getName()+ "§6] §r" + message));
+        answer.put(cs.getName(), previous.getName());
+        answer.put(previous.getName(), cs.getName());
+        return true;  
+    }
+}

+ 2 - 2
src/main/java/me/km/commands/CommandBed.java

@@ -1,12 +1,12 @@
 package me.km.commands;
 
+import me.km.KajetansMod;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.api.Location;
 import me.km.api.Utils;
 import me.km.exception.PlayerNotFoundException;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -32,7 +32,7 @@ public class CommandBed extends ModuleCommand
         }
         EntityPlayer p = (EntityPlayer) cs;
         
-        if(arg.length == 0 || !Permission.has(cs, Permissions.BED_OTHER))
+        if(arg.length == 0 || !KajetansMod.perms.has(cs, Permissions.BED_OTHER))
         {
             BlockPos pos = p.getBedLocation(p.dimension);
             if(pos == null)

+ 1 - 0
src/main/java/me/km/commands/CommandBook.java

@@ -38,6 +38,7 @@ public class CommandBook extends ModuleCommand
                 m.send(cs, "Du hast kein signiertes Buch in der Hand.");
                 return true;
             }
+            m.send(cs, GlobalText.notImplementedYet());
             // TODO
             /*BookMeta bmeta = (BookMeta) stack.getItemMeta();
             

+ 1 - 0
src/main/java/me/km/commands/CommandCoords.java

@@ -20,6 +20,7 @@ public class CommandCoords extends ModuleCommand
         super.setDescription("Ändert den Typ eines Spawners");
         super.setUsage("/coords");
         super.setPermission(Permissions.COORDS);
+        super.addAlias("coord");
     }
 
     @Override

+ 1 - 0
src/main/java/me/km/commands/CommandExp.java

@@ -17,6 +17,7 @@ public class CommandExp extends ModuleCommand
         super.setDescription("Befehle um die EXP eines Spielers zu verändern");
         super.setUsage("/exp für die Hilfe");
         super.setPermission(Permissions.EXP);
+        super.addAlias("xp");
     }
 
     @Override

+ 2 - 2
src/main/java/me/km/commands/CommandFly.java

@@ -1,11 +1,11 @@
 package me.km.commands;
 
+import me.km.KajetansMod;
 import me.km.api.Utils;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.exception.PlayerNotFoundException;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -26,7 +26,7 @@ public class CommandFly extends ModuleCommand
         EntityPlayer affectedPlayer;
         try
         {
-            if(arg.length >= 1 && !Permission.has(cs, Permissions.FLY_OTHER))
+            if(arg.length >= 1 && !KajetansMod.perms.has(cs, Permissions.FLY_OTHER))
             {
                 this.getModule().send(cs, "Du darfst nur deinen eigenen Fly setzen.");
                 return true;

+ 3 - 2
src/main/java/me/km/commands/CommandGameMode.java

@@ -1,11 +1,11 @@
 package me.km.commands;
 
+import me.km.KajetansMod;
 import me.km.api.Utils;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.exception.PlayerNotFoundException;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -19,6 +19,7 @@ public class CommandGameMode extends ModuleCommand
         super.setDescription("Ändert den GameMode eines Spielers");
         super.setUsage("/gamemode <mode> [player]");
         super.setPermission(Permissions.GAMEMODE);
+        super.addAlias("gm");
     }
 
     @Override
@@ -32,7 +33,7 @@ public class CommandGameMode extends ModuleCommand
         EntityPlayer affectedPlayer;
         try
         {
-            if(arg.length >= 2 && !Permission.has(cs, Permissions.GAMEMODE_OTHER))
+            if(arg.length >= 2 && !KajetansMod.perms.has(cs, Permissions.GAMEMODE_OTHER))
             {
                 this.getModule().send(cs, "Du darfst nur deinen eigenen GameMode setzen.");
                 return true;

+ 5 - 6
src/main/java/me/km/commands/CommandHome.java

@@ -6,10 +6,9 @@ import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.api.SimpleConfig;
 import java.io.File;
-import java.util.List;
+import java.util.Arrays;
 import me.km.api.Location;
 import me.km.api.Utils;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -40,7 +39,7 @@ public class CommandHome extends ModuleCommand
         if(arg.length >= 1)
         {
             homename = arg[0];          
-            if(arg[0].contains(":") && Permission.has(cs, Permissions.HOME_OTHER))
+            if(arg[0].contains(":") && KajetansMod.perms.has(cs, Permissions.HOME_OTHER))
             {               
                 String[] split = homename.split(":");
                 String uuid = KajetansMod.playerbank.getDataBank().getUUID(split[0]);
@@ -58,8 +57,8 @@ public class CommandHome extends ModuleCommand
         }
 
         Module m = this.getModule();
-        List<File> homes = SimpleConfig.getFiles("home/" + playeruuid);
-        if(homes.isEmpty())
+        File[] homes = SimpleConfig.getFiles("home/" + playeruuid);
+        if(homes.length == 0)
         {
             String name = KajetansMod.playerbank.getDataBank().getName(playeruuid);
             if(name.equals(p.getName()))
@@ -73,7 +72,7 @@ public class CommandHome extends ModuleCommand
         if(arg.length == 0 || homename.equals(""))
         {
             m.send(cs, "Folgende Homepunkte stehen zur Verfügung:");      
-            homes.stream().forEach(h -> {m.sendListElement(cs, h.getName().replaceAll(".yml", ""));});
+            Arrays.stream(homes).forEach(h -> {m.sendListElement(cs, h.getName().replaceAll(".yml", ""));});
             return true;
         }
                   

+ 1 - 0
src/main/java/me/km/commands/CommandItemInfo.java

@@ -19,6 +19,7 @@ public class CommandItemInfo extends ModuleCommand
         super.setDescription("Gibt Information über ein Item aus");
         super.setUsage("/iteminfo");
         super.setPermission(Permissions.ITEMINFO);
+        super.addAlias("itemdb");
     }
 
     @Override

+ 3 - 2
src/main/java/me/km/commands/CommandKill.java

@@ -1,11 +1,11 @@
 package me.km.commands;
 
+import me.km.KajetansMod;
 import me.km.api.Utils;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.exception.PlayerNotFoundException;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -18,12 +18,13 @@ public class CommandKill extends ModuleCommand
         super.setDescription("Tötet einen Spieler");
         super.setUsage("/kill [player]");
         super.setPermission(Permissions.KILL);
+        super.addAlias("suicide");
     }
 
     @Override
     public boolean execute(ICommandSender cs, String[] arg) 
     {
-        if(arg.length == 0 || !Permission.has(cs, Permissions.KILL_OTHER))
+        if(arg.length == 0 || !KajetansMod.perms.has(cs, Permissions.KILL_OTHER))
         {
             if(!(cs instanceof EntityPlayer))
             {

+ 1 - 1
src/main/java/me/km/commands/CommandLightUpdate.java

@@ -26,7 +26,7 @@ public class CommandLightUpdate extends ModuleCommand
             return true;
         }
         EntityPlayer p = (EntityPlayer) cs;
-        this.getModule().send(cs, "Dieser Command macht momentan nichts.");
+        this.getModule().send(cs, GlobalText.notImplementedYet());
         return true;
     }
     

+ 1 - 0
src/main/java/me/km/commands/CommandMemory.java

@@ -13,6 +13,7 @@ public class CommandMemory extends ModuleCommand
         super.setDescription("Gibt RAM Information aus");
         super.setUsage("/memory");
         super.setPermission(Permissions.MEMORY);
+        super.addAlias("mem");
     }
 
     @Override

+ 18 - 56
src/main/java/me/km/commands/CommandMsg.java

@@ -1,13 +1,13 @@
 package me.km.commands;
 
-import me.km.api.Utils;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
-import me.km.chatmanager.ChatManager;
-import me.km.exception.PlayerNotFoundException;
 import java.util.HashMap;
 import me.km.KajetansMod;
+import me.km.api.Utils;
+import me.km.chatmanager.ChatManager;
+import me.km.exception.PlayerNotFoundException;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -15,7 +15,7 @@ import net.minecraft.util.text.TextComponentString;
 
 public class CommandMsg extends ModuleCommand
 {
-    private final HashMap<String, String> answer; 
+    protected final HashMap<String, String> answer; 
     
     public CommandMsg(Module m) 
     {
@@ -23,70 +23,32 @@ public class CommandMsg extends ModuleCommand
         super.setDescription("Schreibt dem Spieler eine Privatnachricht");
         super.setUsage("/msg <player> <message> oder /r <message>");
         super.setPermission(Permissions.MSG);
-        
+        super.addAlias("tell");
         answer = new HashMap<>();
     }
 
     @Override
     public boolean execute(ICommandSender cs, String[] arg) 
     {
-        this.getModule().send(cs, GlobalText.notImplementedYet());
-        /*if(!string.equalsIgnoreCase("r"))
-        {
-            if(arg.length <= 1)
-            {
-                return false;
-            }
-            EntityPlayer affectedPlayer;
-            try
-            {
-                affectedPlayer = Utils.getPlayerByName(arg[0]);                   
-            }
-            catch(PlayerNotFoundException ex)
-            {
-                this.getModule().send(cs, GlobalText.cantFindPlayer(arg[0]));
-                return true;
-            }
-            String message = ChatManager.colorMessage(Utils.connectSpaces(arg, 1), cs);
-            cs.sendMessage(new TextComponentString("§6[ -> §c" + affectedPlayer.getName() + "§6] §r" + message));
-            affectedPlayer.sendMessage(new TextComponentString("§6[§c" + cs.getName()+ "§6] §r" + message));
-            answer.put(cs.getName(), affectedPlayer.getName());
-            answer.put(affectedPlayer.getName(), cs.getName());
-            return true;
-        }
-        if(arg.length == 0)
+        if(arg.length <= 1)
         {
             return false;
         }
-        String s = answer.get(cs.getName());
-        if(s == null)
-        {
-            this.getModule().send(cs, "Du hast niemanden, dem du antworten könntest.");
-            return true;
-        }
-        ICommandSender previous;
-        if(s.equals("CONSOLE"))
+        EntityPlayer affectedPlayer;
+        try
         {
-            previous = KajetansMod.server;
+            affectedPlayer = Utils.getPlayerByName(arg[0]);                   
         }
-        else
+        catch(PlayerNotFoundException ex)
         {
-            try
-            {
-                previous = Utils.getPlayerByName(s);            
-            }
-            catch(PlayerNotFoundException ex)
-            {
-                this.getModule().send(cs, "Du hast niemanden, dem du antworten könntest.");
-                return true;
-            }
+            this.getModule().send(cs, GlobalText.cantFindPlayer(arg[0]));
+            return true;
         }
-        
-        String message = ChatManager.colorMessage(Utils.connectSpaces(arg, 0), cs);
-        cs.sendMessage(new TextComponentString("§6[ -> §c" + previous.getName()+ "§6] §r" + message));
-        previous.sendMessage(new TextComponentString("§6[§c" + cs.getName()+ "§6] §r" + message));
-        answer.put(cs.getName(), previous.getName());
-        answer.put(previous.getName(), cs.getName());*/
-        return true;  
+        String message = ChatManager.colorMessage(Utils.connectSpaces(arg, 1), cs);
+        cs.sendMessage(new TextComponentString("§6[ -> §c" + affectedPlayer.getName() + "§6] §r" + message));
+        affectedPlayer.sendMessage(new TextComponentString("§6[§c" + cs.getName()+ "§6] §r" + message));
+        answer.put(cs.getName(), affectedPlayer.getName());
+        answer.put(affectedPlayer.getName(), cs.getName());
+        return true;
     }
 }

+ 2 - 1
src/main/java/me/km/commands/CommandPosition.java

@@ -1,6 +1,5 @@
 package me.km.commands;
 
-import me.km.api.Utils;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
@@ -17,6 +16,8 @@ public class CommandPosition extends ModuleCommand
         super.setDescription("Zeigt deine Position an");
         super.setUsage("/position");
         super.setPermission(Permissions.POSITION);
+        super.addAlias("pos");
+        super.addAlias("whereami");
     }
 
     @Override

+ 1 - 2
src/main/java/me/km/commands/CommandPvP.java

@@ -7,7 +7,6 @@ import me.km.api.Module;
 import me.km.api.ModuleCommand;
 import me.km.playerbank.PlayerBank;
 import me.km.exception.PlayerNotFoundException;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
@@ -28,7 +27,7 @@ public class CommandPvP extends ModuleCommand
         EntityPlayer affectedPlayer;
         try
         {
-            if(!Permission.has(cs, Permissions.PVP_OTHER))
+            if(!KajetansMod.perms.has(cs, Permissions.PVP_OTHER))
             {
                 throw new IndexOutOfBoundsException();
             }

+ 1 - 0
src/main/java/me/km/commands/CommandSummon.java

@@ -29,6 +29,7 @@ public class CommandSummon extends ModuleCommand
         super.setDescription("Spawnt ein Mob / Mobs");
         super.setUsage("/summon <type> [amount] [data]");
         super.setPermission(Permissions.SUMMON);
+        super.addAlias("spawnmob");
     }
 
     @Override

+ 1 - 1
src/main/java/me/km/commands/CommandTeleport.java

@@ -8,7 +8,6 @@ import me.km.exception.PlayerNotFoundException;
 import me.km.permissions.Permissions;
 import net.minecraft.command.ICommandSender;
 import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.world.GameType;
 
 public class CommandTeleport extends ModuleCommand
 {
@@ -18,6 +17,7 @@ public class CommandTeleport extends ModuleCommand
         super.setDescription("Teleportiert einen Spieler zu einem anderen");
         super.setUsage("/tp [player] <to-player>");
         super.setPermission(Permissions.TELEPORT);
+        super.addAlias("tp");
     }
 
     @Override

+ 1 - 0
src/main/java/me/km/commands/CommandTeleportAccept.java

@@ -21,6 +21,7 @@ public class CommandTeleportAccept extends ModuleCommand
         super.setDescription("Akzeptiert eine Teleportanfrage");
         super.setUsage("/teleportaccept");
         super.setPermission(Permissions.TELEPORT_ACCEPT);
+        super.addAlias("tpa");
         
         tpaccept = new HashMap<>();
     }

+ 3 - 1
src/main/java/me/km/commands/CommandWarp.java

@@ -1,5 +1,6 @@
 package me.km.commands;
 
+import java.util.Arrays;
 import me.km.api.GlobalText;
 import me.km.api.Module;
 import me.km.api.ModuleCommand;
@@ -22,11 +23,12 @@ public class CommandWarp extends ModuleCommand
         super.setDescription("Teleportiert einen Spieler zum Warp");
         super.setUsage("/warp <warpname> [player]");
         super.setPermission(Permissions.WARP);
+        super.addAlias("warps");
     }
 
     public List<String> getWarps()
     {
-        return SimpleConfig.getFiles("warp").stream().map(w -> w.getName().substring(0, w.getName().length() - 6)).collect(Collectors.toList());
+        return Arrays.stream(SimpleConfig.getFiles("warp")).map(w -> w.getName().substring(0, w.getName().length() - 6)).collect(Collectors.toList());
     }
     
     @Override

+ 2 - 2
src/main/java/me/km/databank/SimpleDataBank.java

@@ -6,6 +6,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import me.km.api.Module;
+import me.km.snuviscript.QuestUtils;
 import me.km.table.Table;
 
 public abstract class SimpleDataBank 
@@ -275,8 +276,7 @@ public abstract class SimpleDataBank
             ResultSet rs = stmt.executeQuery(query);
             while(rs.next())
             {
-                //TODO
-                table.addRow(new Object[] {rs.getString(1), /*QuestUtils.convertInput(*/rs.getString(2)/*)*/});
+                table.addRow(new Object[] {rs.getString(1), QuestUtils.convertInput(rs.getString(2))});
             }
             return table;
         }

+ 2 - 1
src/main/java/me/km/datatools/CommandDataTools.java

@@ -31,6 +31,7 @@ public class CommandDataTools extends ModuleCommand
         super.setDescription("Spezielle Commands um Daten zu verändern");
         super.setUsage("/datatools für die Hilfe");
         super.setPermission(Permissions.DATATOOLS);  
+        super.addAlias("dt");
         
         first = new ArrayList<>(Arrays.asList(new String[]
                 {"print-nbt", "flag", "attribute", "hide-entity", "show-entity", "name-entity", "name-item", "lore-item", "silent-entity"})); 
@@ -271,7 +272,7 @@ public class CommandDataTools extends ModuleCommand
                         m.send(cs, GlobalText.noNaturalNumber());
                         return true;
                     }            
-                    Utils.setLore(hand, ChatManager.colorMessage(Utils.connectSpaces(arg, 2), p), line);
+                    ItemStackUtils.setLore(hand, ChatManager.colorMessage(Utils.connectSpaces(arg, 2), p), line);
                     m.send(cs, "Die neue Lore wurde hinzugefügt.");
                     return true;
             }

+ 1 - 1
src/main/java/me/km/datatools/CommandVillager.java

@@ -18,7 +18,6 @@ import net.minecraft.util.math.BlockPos;
 import net.minecraft.village.MerchantRecipe;
 import net.minecraft.village.MerchantRecipeList;
 import net.minecraft.world.World;
-import net.minecraftforge.fml.common.registry.VillagerRegistry;
 
 public class CommandVillager extends ModuleCommand
 {
@@ -30,6 +29,7 @@ public class CommandVillager extends ModuleCommand
         super.setDescription("Spezielle Commands für Villager");
         super.setUsage("/villager für die Hilfe");
         super.setPermission(Permissions.VILLAGER);
+        super.addAlias("vi");
         
         vil = new ArrayList<>(Arrays.asList(new String[] {"inv", "trades", "spawn", "child"})); 
     }

+ 2 - 2
src/main/java/me/km/effects/EffectUtils.java

@@ -7,6 +7,7 @@ import me.km.KajetansMod;
 import me.km.api.Module;
 import me.km.api.Utils;
 import me.km.jobsystem.JobAPI;
+import me.km.plots.ProtectionBank;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.EntityAreaEffectCloud;
 import net.minecraft.entity.EntityLivingBase;
@@ -145,8 +146,7 @@ public class EffectUtils extends Module
     
     public static Collection<EntityLivingBase> getEntsOfNotGuild(EntityPlayer p, World w, Vec3d v, double radius)
     {       
-        // TODO
-        boolean animals = false; //KajetansMod.plots.getDataBank(ProtectionBank.class).canBuild(l, p);
+        boolean animals = KajetansMod.plots.getDataBank(ProtectionBank.class).canBuild(w, new BlockPos(v), p);
         boolean pvp = !KajetansMod.worldManager.getWorldPreferences(w).pvpProtection;
         boolean ppvp = KajetansMod.playerbank.getDataBank().getTag(p, "pvp") >= 1;
         int id = KajetansMod.playerbank.getGuildId(p);

+ 0 - 2
src/main/java/me/km/effects/active/Harvest.java

@@ -1,8 +1,6 @@
  package me.km.effects.active;
 
 import me.km.KajetansMod;
-import me.km.api.Location;
-import me.km.api.Module;
 import me.km.effects.ActiveEffectBase;
 import net.minecraft.block.BlockCrops;
 import net.minecraft.block.state.IBlockState;

+ 0 - 2
src/main/java/me/km/effects/passive/Mugging.java

@@ -1,7 +1,5 @@
 package me.km.effects.passive;
 
-import java.util.ArrayList;
-import java.util.stream.Collectors;
 import me.km.api.Module;
 import me.km.api.ModuleListener;
 

+ 1 - 0
src/main/java/me/km/environment/CommandHealStats.java

@@ -17,6 +17,7 @@ public class CommandHealStats extends ModuleCommand
         super.setDescription("Füllt die Zusatzstats eines Spielers");
         super.setUsage("/healstats [player]");
         super.setPermission(Permissions.HEAL_STATS);
+        super.addAlias("heals");
     }
 
     @Override

+ 1 - 0
src/main/java/me/km/environment/CommandTemperature.java

@@ -15,6 +15,7 @@ public class CommandTemperature extends ModuleCommand
         super.setDescription("Zeigt dir die aktuelle Temperatur an");
         super.setUsage("/temperature");
         super.setPermission(Permissions.TEMPERATURE);
+        super.addAlias("temp");
     }
 
     @Override

+ 11 - 8
src/main/java/me/km/events/CustomEventCaller.java

@@ -1,10 +1,6 @@
 package me.km.events;
 
 import java.util.ArrayList;
-import me.km.KajetansMod;
-import me.km.api.Utils;
-import me.km.effects.Effect;
-import me.km.effects.EffectUtils;
 import me.km.utils.ReflectionUtils;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.player.EntityPlayer;
@@ -19,7 +15,7 @@ import net.minecraftforge.fml.common.gameevent.TickEvent;
 
 public class CustomEventCaller 
 {
-    private static ArrayList<EntityArrow> arrows = new ArrayList<>();
+    private static final ArrayList<EntityArrow> ARROWS = new ArrayList<>();
     
     @SubscribeEvent
     public void onPlayerMove(LivingEvent.LivingUpdateEvent e)
@@ -44,7 +40,7 @@ public class CustomEventCaller
             EntityArrow arrow = (EntityArrow) ent;
             if(arrow.shootingEntity instanceof EntityPlayer)
             {
-                arrows.add(arrow);
+                ARROWS.add(arrow);
                 MinecraftForge.EVENT_BUS.post(new ArrowLaunchEvent((EntityPlayer) arrow.shootingEntity, arrow, e.getWorld()));
             }
         }
@@ -61,8 +57,15 @@ public class CustomEventCaller
     @SubscribeEvent
     public void tickServer(TickEvent.ServerTickEvent e) 
     {       
-        arrows.removeIf(arrow -> ReflectionUtils.getArrowTimeInGround(arrow) > 1);
-        arrows.forEach(arrow -> MinecraftForge.EVENT_BUS.post(new ArrowHitGroundEvent(arrow)));
+        ARROWS.removeIf(arrow -> 
+        {
+            if(ReflectionUtils.getArrowTimeInGround(arrow) >= 1)
+            {
+                MinecraftForge.EVENT_BUS.post(new ArrowHitGroundEvent(arrow));
+                return true;
+            }
+            return false;
+        });
     }
     
     @SubscribeEvent

+ 227 - 0
src/main/java/me/km/events/ModDedicatedPlayerList.java

@@ -0,0 +1,227 @@
+package me.km.events;
+
+import com.mojang.authlib.GameProfile;
+import io.netty.buffer.Unpooled;
+import java.util.UUID;
+import me.km.KajetansMod;
+import me.km.api.GlobalText;
+import me.km.api.Utils;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetHandlerPlayServer;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.PacketBuffer;
+import net.minecraft.network.play.server.SPacketChat;
+import net.minecraft.network.play.server.SPacketCustomPayload;
+import net.minecraft.network.play.server.SPacketEntityEffect;
+import net.minecraft.network.play.server.SPacketHeldItemChange;
+import net.minecraft.network.play.server.SPacketJoinGame;
+import net.minecraft.network.play.server.SPacketPlayerAbilities;
+import net.minecraft.network.play.server.SPacketServerDifficulty;
+import net.minecraft.scoreboard.ServerScoreboard;
+import net.minecraft.server.dedicated.DedicatedPlayerList;
+import net.minecraft.server.dedicated.DedicatedServer;
+import net.minecraft.server.management.PlayerProfileCache;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.TextComponentString;
+import net.minecraft.util.text.TextComponentTranslation;
+import net.minecraft.world.World;
+import net.minecraft.world.WorldServer;
+import net.minecraft.world.chunk.storage.AnvilChunkLoader;
+import net.minecraft.world.storage.WorldInfo;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@SideOnly(Side.SERVER)
+public class ModDedicatedPlayerList extends DedicatedPlayerList
+{
+    private final DedicatedServer mcServer;
+    private static final Logger LOG = LogManager.getLogger();
+    
+    public ModDedicatedPlayerList(DedicatedServer server) 
+    {
+        super(server);
+        this.mcServer = server;
+    }
+    
+    // copied from net.minecraft.server.management.PlayerList
+    private void setPlayerGameTypeBasedOnOther(EntityPlayerMP target, EntityPlayerMP source, World worldIn)
+    {
+        /*if (source != null)
+        {
+            target.interactionManager.setGameType(source.interactionManager.getGameType());
+        }
+        else if (this.gameType != null)
+        {
+            target.interactionManager.setGameType(this.gameType);
+        }*/
+
+        target.interactionManager.initializeGameType(worldIn.getWorldInfo().getGameType());
+    }
+    
+    // copied from net.minecraft.server.management.PlayerList
+    @Override
+    public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, NetHandlerPlayServer nethandlerplayserver)
+    {
+        GameProfile gameprofile = playerIn.getGameProfile();
+        PlayerProfileCache playerprofilecache = this.mcServer.getPlayerProfileCache();
+        GameProfile gameprofile1 = playerprofilecache.getProfileByUUID(gameprofile.getId());
+        String s = gameprofile1 == null ? gameprofile.getName() : gameprofile1.getName();
+        playerprofilecache.addEntry(gameprofile);
+        NBTTagCompound nbttagcompound = this.readPlayerDataFromFile(playerIn);
+        playerIn.setWorld(this.mcServer.worldServerForDimension(playerIn.dimension));
+
+        World playerWorld = this.mcServer.worldServerForDimension(playerIn.dimension);
+        if (playerWorld == null)
+        {
+            playerIn.dimension = 0;
+            playerWorld = this.mcServer.worldServerForDimension(0);
+            BlockPos spawnPoint = playerWorld.provider.getRandomizedSpawnPoint();
+            playerIn.setPosition(spawnPoint.getX(), spawnPoint.getY(), spawnPoint.getZ());
+        }
+
+        playerIn.setWorld(playerWorld);
+        playerIn.interactionManager.setWorld((WorldServer)playerIn.world);
+        String s1 = "local";
+
+        if (netManager.getRemoteAddress() != null)
+        {
+            s1 = netManager.getRemoteAddress().toString();
+        }
+
+        LOG.info("{}[{}] logged in with entity id {} at ({}, {}, {})", new Object[] {playerIn.getName(), s1, playerIn.getEntityId(), playerIn.posX, playerIn.posY, playerIn.posZ});
+        WorldServer worldserver = this.mcServer.worldServerForDimension(playerIn.dimension);
+        WorldInfo worldinfo = worldserver.getWorldInfo();
+        this.setPlayerGameTypeBasedOnOther(playerIn, null, worldserver);
+        playerIn.connection = nethandlerplayserver;
+        nethandlerplayserver.sendPacket(new SPacketJoinGame(playerIn.getEntityId(), playerIn.interactionManager.getGameType(), worldinfo.isHardcoreModeEnabled(), worldserver.provider.getDimension(), worldserver.getDifficulty(), this.getMaxPlayers(), worldinfo.getTerrainType(), worldserver.getGameRules().getBoolean("reducedDebugInfo")));
+        nethandlerplayserver.sendPacket(new SPacketCustomPayload("MC|Brand", (new PacketBuffer(Unpooled.buffer())).writeString(this.getServerInstance().getServerModName())));
+        nethandlerplayserver.sendPacket(new SPacketServerDifficulty(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked()));
+        nethandlerplayserver.sendPacket(new SPacketPlayerAbilities(playerIn.capabilities));
+        nethandlerplayserver.sendPacket(new SPacketHeldItemChange(playerIn.inventory.currentItem));
+        this.updatePermissionLevel(playerIn);
+        playerIn.getStatFile().markAllDirty();
+        playerIn.getStatFile().sendAchievements(playerIn);
+        this.sendScoreboard((ServerScoreboard)worldserver.getScoreboard(), playerIn);
+        this.mcServer.refreshStatusNextTick();
+        // Custom Join Message - Start
+        //TextComponentTranslation textcomponenttranslation;
+        
+        PlayerJoinMessageEvent event;
+        if (playerIn.getName().equalsIgnoreCase(s))
+        {
+            //textcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined", new Object[] {playerIn.getDisplayName()});
+            event = new PlayerJoinMessageEvent(playerIn, false, "No message was set.");
+        }
+        else
+        {
+            //textcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined.renamed", new Object[] {playerIn.getDisplayName(), s});
+            event = new PlayerJoinMessageEvent(playerIn, true, "No message was set.");
+        }
+
+        //textcomponenttranslation.getStyle().setColor(TextFormatting.YELLOW);
+        //this.sendMessage(textcomponenttranslation);
+        if(!MinecraftForge.EVENT_BUS.post(event))
+        {
+            this.sendMessage(new TextComponentString(event.getMessage()));
+        }
+        // Custom Join Message - End
+        this.playerLoggedIn(playerIn);
+        nethandlerplayserver.setPlayerLocation(playerIn.posX, playerIn.posY, playerIn.posZ, playerIn.rotationYaw, playerIn.rotationPitch);
+        this.updateTimeAndWeatherForPlayer(playerIn, worldserver);
+
+        if (!this.mcServer.getResourcePackUrl().isEmpty())
+        {
+            playerIn.loadResourcePack(this.mcServer.getResourcePackUrl(), this.mcServer.getResourcePackHash());
+        }
+
+        playerIn.getActivePotionEffects().stream().forEach((potioneffect) -> 
+        {
+            nethandlerplayserver.sendPacket(new SPacketEntityEffect(playerIn.getEntityId(), potioneffect));
+        });
+
+        if (nbttagcompound != null && nbttagcompound.hasKey("RootVehicle", 10))
+        {
+            NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("RootVehicle");
+            Entity entity1 = AnvilChunkLoader.readWorldEntity(nbttagcompound1.getCompoundTag("Entity"), worldserver, true);
+
+            if (entity1 != null)
+            {
+                UUID uuid = nbttagcompound1.getUniqueId("Attach");
+
+                if (entity1.getUniqueID().equals(uuid))
+                {
+                    playerIn.startRiding(entity1, true);
+                }
+                else
+                {
+                    for (Entity entity : entity1.getRecursivePassengers())
+                    {
+                        if (entity.getUniqueID().equals(uuid))
+                        {
+                            playerIn.startRiding(entity, true);
+                            break;
+                        }
+                    }
+                }
+
+                if (!playerIn.isRiding())
+                {
+                    LOG.warn("Couldn\'t reattach entity to player");
+                    worldserver.removeEntityDangerously(entity1);
+
+                    entity1.getRecursivePassengers().stream().forEach((entity2) -> 
+                    {
+                        worldserver.removeEntityDangerously(entity2);
+                    });
+                }
+            }
+        }
+
+        playerIn.addSelfToInternalCraftingInventory();
+        net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerLoggedIn(playerIn);
+    }
+    
+    // workaround handler for leave message
+    @Override
+    public void sendMessage(ITextComponent component)
+    {
+        // Custom Leave Message - Start
+        if(component instanceof TextComponentTranslation)
+        {
+            TextComponentTranslation trans = (TextComponentTranslation) component;
+            if(trans.getKey().equals("multiplayer.player.left"))
+            {
+                // trying to get a player
+                Object[] o = trans.getFormatArgs();
+                if(o.length >= 1)
+                {
+                    EntityPlayer p = Utils.getPlayerByDisplayName(o[0].toString());
+                    if(p == null)
+                    {
+                        KajetansMod.error.sendToConsole(GlobalText.shouldNotHappen());
+                        return;
+                    }
+                    PlayerLeaveMessageEvent event = new PlayerLeaveMessageEvent(p, "No message was set.");;
+                    if(!MinecraftForge.EVENT_BUS.post(event))
+                    {
+                        this.sendMessage(new TextComponentString(event.getMessage()), true);
+                    }
+                }
+                else
+                {
+                    KajetansMod.error.sendToConsole(GlobalText.shouldNotHappen());
+                }
+                return;
+            }
+        }
+        // Custom Leave Message - End
+        this.sendMessage(component, true);
+    }
+}

+ 15 - 0
src/main/java/me/km/events/ModNetHandlerPlayServer.java

@@ -0,0 +1,15 @@
+package me.km.events;
+
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.network.NetHandlerPlayServer;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.server.MinecraftServer;
+
+public class ModNetHandlerPlayServer extends NetHandlerPlayServer
+{
+    public ModNetHandlerPlayServer(MinecraftServer server, NetworkManager networkManagerIn, EntityPlayerMP playerIn) 
+    {
+        super(server, networkManagerIn, playerIn);
+    }
+    
+}

+ 32 - 0
src/main/java/me/km/events/PlayerJoinMessageEvent.java

@@ -0,0 +1,32 @@
+package me.km.events;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraftforge.event.entity.player.PlayerEvent;
+
+public class PlayerJoinMessageEvent extends PlayerEvent
+{
+    private String message;
+    private final boolean nameChange;
+    
+    public PlayerJoinMessageEvent(EntityPlayer player, boolean nameChange, String message) 
+    {
+        super(player);
+        this.message = message;
+        this.nameChange = nameChange;
+    }
+
+    public void setMessage(String message) 
+    {
+        this.message = message;
+    }
+
+    public String getMessage() 
+    {
+        return message;
+    }
+    
+    public boolean hasNameChanged()
+    {
+        return nameChange;
+    }
+}

+ 25 - 0
src/main/java/me/km/events/PlayerLeaveMessageEvent.java

@@ -0,0 +1,25 @@
+package me.km.events;
+
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraftforge.event.entity.player.PlayerEvent;
+
+public class PlayerLeaveMessageEvent extends PlayerEvent
+{
+    private String message;
+    
+    public PlayerLeaveMessageEvent(EntityPlayer player, String message) 
+    {
+        super(player);
+        this.message = message;
+    }
+
+    public void setMessage(String message) 
+    {
+        this.message = message;
+    }
+
+    public String getMessage() 
+    {
+        return message;
+    }
+}

+ 1 - 2
src/main/java/me/km/items/ItemWand.java

@@ -47,10 +47,9 @@ public class ItemWand extends ItemWeapon
         }
         
         ItemStack stack = p.getHeldItem(hand);
-        String s = stack.getDisplayName();
         try
         {
-            Class<? extends ActiveEffectBase> c = EffectUtils.getEffectClass(s);
+            Class<? extends ActiveEffectBase> c = EffectUtils.getEffectClass(stack.getDisplayName());
             if(c == null)
             { 
                 throw new Exception();

+ 1 - 0
src/main/java/me/km/jobsystem/CommandRecipe.java

@@ -19,6 +19,7 @@ public class CommandRecipe extends ModuleCommand
         super.setDescription("Zeigt deine Rezepte");
         super.setUsage("/recipe [player]");
         super.setPermission(Permissions.RECIPE);
+        super.addAlias("recipes");
     }
 
     @Override

+ 0 - 17
src/main/java/me/km/permissions/Permission.java

@@ -1,17 +0,0 @@
-package me.km.permissions;
-
-import net.minecraft.command.ICommand;
-import net.minecraft.command.ICommandSender;
-
-public class Permission 
-{
-    public static boolean has(ICommandSender cs, ICommand command)
-    {
-        return true;
-    }
-    
-    public static boolean has(ICommandSender cs, Permissions perm)
-    {
-        return true;
-    }
-}

+ 34 - 0
src/main/java/me/km/permissions/PermissionListener.java

@@ -0,0 +1,34 @@
+package me.km.permissions;
+
+import me.km.KajetansMod;
+import me.km.api.GlobalText;
+import me.km.api.Module;
+import me.km.api.ModuleCommand;
+import me.km.api.ModuleListener;
+import net.minecraft.command.ICommand;
+import net.minecraftforge.event.CommandEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class PermissionListener extends ModuleListener
+{
+    public PermissionListener(Module m) 
+    {
+        super(m);
+    }
+    
+    @SubscribeEvent(priority = EventPriority.HIGHEST)
+    public void CommandProtection(CommandEvent e)
+    {
+        ICommand command = e.getCommand();
+        if(command instanceof ModuleCommand)
+        {
+            return;
+        }
+        if(!KajetansMod.perms.has(e.getSender(), command.getName()))
+        {
+            e.setCanceled(true);
+            KajetansMod.perms.send(e.getSender(), GlobalText.noPermission());
+        }
+    }
+}

+ 141 - 0
src/main/java/me/km/permissions/PermissionManager.java

@@ -0,0 +1,141 @@
+package me.km.permissions;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.UUID;
+import me.km.api.Module;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.text.TextFormatting;
+
+public class PermissionManager extends Module
+{
+    private final HashMap<UUID, ArrayList<Integer>> playerGroups;
+    private final ArrayList<EnumSet<Permissions>> enumGroupPerms;
+    private final ArrayList<HashSet<String>> stringGroupPerms;
+    
+    public PermissionManager(String mname, String prefix, TextFormatting color) 
+    {
+        super(mname, prefix, color);
+        playerGroups = new HashMap<>();
+        enumGroupPerms = new ArrayList<>();
+        stringGroupPerms = new ArrayList<>();
+    }
+
+    public void clear()
+    {
+        playerGroups.clear();
+        enumGroupPerms.clear();
+        stringGroupPerms.clear();
+    }
+    
+    // -----------------------------------------------------------------------------------
+    // Permission-Check
+    // -----------------------------------------------------------------------------------
+    
+    public boolean has(ICommandSender cs, Permissions perm)
+    {
+        if(cs instanceof EntityPlayer)
+        {
+            ArrayList<Integer> groups = playerGroups.get(((EntityPlayer) cs).getUniqueID());
+            if(groups == null)
+            {
+                //falling back to default group
+                if(!enumGroupPerms.isEmpty())
+                {
+                    return enumGroupPerms.get(0).contains(perm);
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            // check for valid group id takes place at the registry
+            return groups.stream().anyMatch(i -> enumGroupPerms.get(i).contains(perm));
+        }
+        return cs instanceof MinecraftServer;
+    }
+    
+    public boolean has(ICommandSender cs, String perm)
+    {
+        if(cs instanceof EntityPlayer)
+        {
+            ArrayList<Integer> groups = playerGroups.get(((EntityPlayer) cs).getUniqueID());
+            if(groups == null)
+            {
+                //falling back to default group
+                if(!stringGroupPerms.isEmpty())
+                {
+                    return stringGroupPerms.get(0).contains(perm);
+                }
+                else
+                {
+                    return false;
+                }
+            }
+            // check for valid group id is done at the registry
+            return groups.stream().anyMatch(i -> stringGroupPerms.get(i).contains(perm));
+        }
+        return cs instanceof MinecraftServer;
+    }
+    
+    // -----------------------------------------------------------------------------------
+    // Permission-Registry
+    // -----------------------------------------------------------------------------------
+    
+    public void registerPlayerGroup(UUID uuid, int id)
+    {
+        if(id < 0 || id >= playerGroups.size())
+        {
+            throw new IllegalArgumentException("'" + id + "' is no valid group id");
+        }
+        ArrayList<Integer> groups = playerGroups.get(uuid);
+        if(groups == null)
+        {
+            groups = new ArrayList<>();
+            // adding default group
+            groups.add(0);
+            playerGroups.put(uuid, groups);
+        }
+        groups.add(id);
+    }
+    
+    public void registerGroupPermission(int id, String perm)
+    {
+        if(perm.isEmpty())
+        {
+            throw new IllegalArgumentException("empty permission string");
+        }
+        else if(Character.isUpperCase(perm.charAt(0)))
+        {
+            // guess it's an enum ...
+            Permissions permission = Permissions.valueOf(perm);
+            if(id >= enumGroupPerms.size())
+            {
+                EnumSet<Permissions> set = EnumSet.of(permission);
+                enumGroupPerms.add(set);
+                // keep other permissions at same id level
+                stringGroupPerms.add(new HashSet<>());
+                return;
+            }
+            enumGroupPerms.get(id).add(permission);
+        }
+        else
+        {
+            // just a string ...
+            if(id >= stringGroupPerms.size())
+            {
+                HashSet<String> set = new HashSet<>();
+                set.add(perm);
+                stringGroupPerms.add(set);
+                // keep other permissions at same id level
+                enumGroupPerms.add(EnumSet.noneOf(Permissions.class));
+                return;
+            }
+            stringGroupPerms.get(id).add(perm);
+        }
+    }
+}

+ 8 - 9
src/main/java/me/km/playerbank/PlayerLogInOut.java

@@ -4,7 +4,10 @@ import me.km.KajetansMod;
 import me.km.api.Module;
 import me.km.api.ModuleListener;
 import me.km.api.Utils;
+import me.km.commands.CommandSilent;
 import me.km.commands.CommandTeleportAccept;
+import me.km.events.PlayerJoinMessageEvent;
+import me.km.permissions.Permissions;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraftforge.fml.common.eventhandler.EventPriority;
 import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -48,19 +51,15 @@ public class PlayerLogInOut extends ModuleListener
         }      
     }
     
-    // TODO
-    /*@SubscribeEvent(priority = EventPriority.LOW)
-    public void silentJoin(PlayerLoginEvent e)
+    @SubscribeEvent(priority = EventPriority.LOW)
+    public void silentJoin(PlayerJoinMessageEvent e)
     {
-        // does not work currently, needs overwriting of PlayerList in DedicatedServer
-        
-        Entity p = e.getEntity();
-        if(p instanceof EntityPlayerMP && Permission.hasPermission(p, Permissions.SILENT) && 
+        if(KajetansMod.perms.has(e.getEntityPlayer(), Permissions.SILENT) && 
             KajetansMod.generalCommands.getCommand(CommandSilent.class).silentjoin)
         {
-            ((EntityPlayerMP) p).add
+            e.setCanceled(true);
         }
-    }*/
+    }
     
     @SubscribeEvent(priority = EventPriority.LOW)
     public void onPlayerLeaveCleanup(PlayerEvent.PlayerLoggedOutEvent e)

+ 19 - 17
src/main/java/me/km/plots/CommandPlot.java

@@ -10,7 +10,6 @@ import me.km.api.ModuleCommand;
 import me.km.api.Utils;
 import me.km.chatmanager.ChatManager;
 import me.km.dimensions.ModDimensions;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import me.km.playerbank.PlayerBank;
 import net.minecraft.command.ICommandSender;
@@ -29,6 +28,9 @@ public class CommandPlot extends ModuleCommand
         super.setDescription("Zeigt alles für die Plot-Verwaltung");
         super.setUsage("/plot für die Hilfe");
         super.setPermission(Permissions.PLOT);
+        super.addAlias("p");
+        super.addAlias("pl");
+        super.addAlias("plo");
         
         coord1 = new HashMap<>();
         coord2 = new HashMap<>();
@@ -51,7 +53,7 @@ public class CommandPlot extends ModuleCommand
                 case "create":
                 case "add":
                 {
-                    if(!Permission.has(cs, Permissions.PLOT_CREATE))
+                    if(!KajetansMod.perms.has(cs, Permissions.PLOT_CREATE))
                     {
                         break;
                     }
@@ -80,7 +82,7 @@ public class CommandPlot extends ModuleCommand
                 case "create3d":
                 case "add3d":
                 {
-                    if(!Permission.has(cs, Permissions.PLOT_CREATE))
+                    if(!KajetansMod.perms.has(cs, Permissions.PLOT_CREATE))
                     {
                         break;
                     }
@@ -109,7 +111,7 @@ public class CommandPlot extends ModuleCommand
                 case "e":
                 case "expand":
                 {
-                    if(!Permission.has(cs, Permissions.PLOT_CREATE) || arg.length < 2)
+                    if(!KajetansMod.perms.has(cs, Permissions.PLOT_CREATE) || arg.length < 2)
                     {
                         break;
                     }
@@ -218,7 +220,7 @@ public class CommandPlot extends ModuleCommand
                 }
                 case "name":
                 {
-                    if(!Permission.has(cs, Permissions.PLOT_CREATE) || arg.length < 2)
+                    if(!KajetansMod.perms.has(cs, Permissions.PLOT_CREATE) || arg.length < 2)
                     {
                         break;
                     }
@@ -248,7 +250,7 @@ public class CommandPlot extends ModuleCommand
                 case "i":
                 case "info":
                 {
-                    if(Permission.has(cs, Permissions.PLOT_INFO))
+                    if(KajetansMod.perms.has(cs, Permissions.PLOT_INFO))
                     {
                         if(!(cs instanceof EntityPlayer))
                         {
@@ -265,7 +267,7 @@ public class CommandPlot extends ModuleCommand
                 case "remove":
                 case "delete":
                 {
-                    if(Permission.has(cs, Permissions.PLOT_CREATE))
+                    if(KajetansMod.perms.has(cs, Permissions.PLOT_CREATE))
                     {
                         Integer id;
                         if(arg.length >= 2)
@@ -302,7 +304,7 @@ public class CommandPlot extends ModuleCommand
                 case "at":
                 case "addtag":
                 {
-                    if(Permission.has(cs, Permissions.PLOT_TAG) && arg.length >= 2)
+                    if(KajetansMod.perms.has(cs, Permissions.PLOT_TAG) && arg.length >= 2)
                     {
                         Integer id;
                         if(arg.length >= 3)
@@ -339,7 +341,7 @@ public class CommandPlot extends ModuleCommand
                 case "rt":
                 case "removetag":
                 {
-                    if(Permission.has(cs, Permissions.PLOT_TAG) && arg.length >= 2)
+                    if(KajetansMod.perms.has(cs, Permissions.PLOT_TAG) && arg.length >= 2)
                     {
                         Integer id;
                         if(arg.length >= 3)
@@ -375,7 +377,7 @@ public class CommandPlot extends ModuleCommand
                 }
                 case "share":
                 {
-                    if(Permission.has(cs, Permissions.PLOT_SHARE) && arg.length >= 2)
+                    if(KajetansMod.perms.has(cs, Permissions.PLOT_SHARE) && arg.length >= 2)
                     {
                         Integer id;
                         if(arg.length >= 3)
@@ -417,7 +419,7 @@ public class CommandPlot extends ModuleCommand
                 }
                 case "kick":
                 {
-                    if(Permission.has(cs, Permissions.PLOT_SHARE) && arg.length >= 2)
+                    if(KajetansMod.perms.has(cs, Permissions.PLOT_SHARE) && arg.length >= 2)
                     {
                         Integer id;
                         if(arg.length >= 3)
@@ -459,7 +461,7 @@ public class CommandPlot extends ModuleCommand
                 }
                 case "sign":
                 {
-                    if(Permission.has(cs, Permissions.PLOT_SIGN) && arg.length >= 3)
+                    if(KajetansMod.perms.has(cs, Permissions.PLOT_SIGN) && arg.length >= 3)
                     {
                         // TODO
                         this.getModule().send(cs, GlobalText.notImplementedYet());
@@ -519,11 +521,11 @@ public class CommandPlot extends ModuleCommand
         }
         // Help Menu
         m.send(cs, "/plot ...");
-        if(Permission.has(cs, Permissions.PLOT_INFO))
+        if(KajetansMod.perms.has(cs, Permissions.PLOT_INFO))
         {
             m.sendHelpListElement(cs, "info", "Gibt Infos über die aktuelle Position");
         }
-        if(Permission.has(cs, Permissions.PLOT_CREATE))
+        if(KajetansMod.perms.has(cs, Permissions.PLOT_CREATE))
         {
             m.sendHelpListElement(cs, "create [player]", "Erstellt ein Plot (30 - 255)");
             m.sendHelpListElement(cs, "create3D [player]", "Erstellt ein Plot");
@@ -531,17 +533,17 @@ public class CommandPlot extends ModuleCommand
             m.sendHelpListElement(cs, "expand <blocks>", "Erweitert die aktuelle Auswahl");
             m.sendHelpListElement(cs, "name [id] <name>", "Gibt einem Plot einen Namen");
         }
-        if(Permission.has(cs, Permissions.PLOT_TAG))
+        if(KajetansMod.perms.has(cs, Permissions.PLOT_TAG))
         {
             m.sendHelpListElement(cs, "addtag <tag> [id]", "Fügt einen Tag hinzu");
             m.sendHelpListElement(cs, "removetag <tag> [id]", "Entfernt einen Tag");
         }
-        if(Permission.has(cs, Permissions.PLOT_SHARE))
+        if(KajetansMod.perms.has(cs, Permissions.PLOT_SHARE))
         {
             m.sendHelpListElement(cs, "share <player> [id]", "Fügt einen Spieler hinzu");
             m.sendHelpListElement(cs, "kick <player> [id]", "Entfernt einen Spieler");
         }
-        if(Permission.has(cs, Permissions.PLOT_SIGN))
+        if(KajetansMod.perms.has(cs, Permissions.PLOT_SIGN))
         {
             m.sendHelpListElement(cs, "sign <price> <id>", "Ändert ein Schild zum Verkaufsschild");
         }

+ 4 - 4
src/main/java/me/km/plots/ProtectionBlockAction.java

@@ -1,8 +1,8 @@
 package me.km.plots;
 
+import me.km.KajetansMod;
 import me.km.api.Location;
 import me.km.api.Module;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.init.Items;
@@ -25,7 +25,7 @@ public class ProtectionBlockAction extends Protection
     public void onBlockPlace(BlockEvent.PlaceEvent e)
     {
         EntityPlayer p = e.getPlayer();
-        if(Permission.has(p, Permissions.PLOT_BYPASS))
+        if(KajetansMod.perms.has(p, Permissions.PLOT_BYPASS))
         {
             return;
         }     
@@ -43,12 +43,12 @@ public class ProtectionBlockAction extends Protection
     public void onBlockBreak(BlockEvent.BreakEvent e)
     {
         EntityPlayer p = e.getPlayer();
-        if(Permission.has(p, Permissions.PLOT_MARK) && p.getHeldItemMainhand().getItem() == Items.WOODEN_SWORD && p.isCreative())
+        if(KajetansMod.perms.has(p, Permissions.PLOT_MARK) && p.getHeldItemMainhand().getItem() == Items.WOODEN_SWORD && p.isCreative())
         {
             e.setCanceled(true);
             return;
         }
-        if(Permission.has(p, Permissions.PLOT_BYPASS))
+        if(KajetansMod.perms.has(p, Permissions.PLOT_BYPASS))
         {
             return;
         }

+ 2 - 2
src/main/java/me/km/plots/ProtectionBucketUse.java

@@ -1,7 +1,7 @@
 package me.km.plots;
 
+import me.km.KajetansMod;
 import me.km.api.Module;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.util.math.BlockPos;
@@ -22,7 +22,7 @@ public class ProtectionBucketUse extends Protection
     {
         EntityPlayer p = e.getEntityPlayer(); 
         RayTraceResult ray = e.getTarget();
-        if(ray == null || Permission.has(p, Permissions.PLOT_BYPASS))
+        if(ray == null || KajetansMod.perms.has(p, Permissions.PLOT_BYPASS))
         {
             return;
         }

+ 0 - 24
src/main/java/me/km/plots/ProtectionCommand.java

@@ -1,24 +0,0 @@
-package me.km.plots;
-
-import me.km.api.Module;
-import net.minecraftforge.fml.common.eventhandler.EventPriority;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import net.minecraftforge.event.CommandEvent;
-
-public class ProtectionCommand extends Protection
-{
-    public ProtectionCommand(Module m) 
-    {
-        super(m);
-    }
-
-    @SubscribeEvent(priority = EventPriority.HIGHEST)
-    public void CommandProtection(CommandEvent e)
-    {
-        String name = e.getCommand().getName();
-        if(name.equals("op"))
-        {
-            e.setCanceled(true);   
-        }
-    }
-}

+ 4 - 4
src/main/java/me/km/plots/ProtectionEntity.java

@@ -1,10 +1,10 @@
 package me.km.plots;
 
+import me.km.KajetansMod;
 import me.km.api.Module;
 import me.km.api.Utils;
-import me.km.permissions.Permission;
+import me.km.permissions.PermissionManager;
 import me.km.permissions.Permissions;
-import net.minecraft.entity.Entity;
 import net.minecraft.entity.EntityLivingBase;
 import net.minecraft.entity.passive.EntityAnimal;
 import net.minecraft.entity.player.EntityPlayer;
@@ -45,7 +45,7 @@ public class ProtectionEntity extends Protection
             EntityPlayer p = Utils.getDamager(e.getSource());
             if(p != null)
             {
-                if(Permission.has(p, Permissions.PLOT_BYPASS) || this.getProtectionBank().canBuild(w, pos, p))
+                if(KajetansMod.perms.has(p, Permissions.PLOT_BYPASS) || this.getProtectionBank().canBuild(w, pos, p))
                 {
                     return;
                 }
@@ -62,7 +62,7 @@ public class ProtectionEntity extends Protection
         {
             EntityPotion potion = (EntityPotion) e.getEntityThrowable();
             EntityLivingBase ent = potion.getThrower();
-            if(ent instanceof EntityPlayer && !Permission.has(ent, Permissions.PLOT_BYPASS) &&
+            if(ent instanceof EntityPlayer && !KajetansMod.perms.has(ent, Permissions.PLOT_BYPASS) &&
                 !this.getProtectionBank().canBuild(potion.world, potion.getPosition(), (EntityPlayer) ent))
             {
                 e.setCanceled(true);

+ 4 - 4
src/main/java/me/km/plots/ProtectionInteract.java

@@ -1,7 +1,7 @@
 package me.km.plots;
 
+import me.km.KajetansMod;
 import me.km.api.Module;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import net.minecraft.block.Block;
 import net.minecraft.entity.player.EntityPlayer;
@@ -21,7 +21,7 @@ public class ProtectionInteract extends Protection
     public void onPlayerInteract(PlayerInteractEvent.LeftClickBlock e) 
     {
         EntityPlayer p = e.getEntityPlayer();
-        if(Permission.has(p, Permissions.PLOT_BYPASS))
+        if(KajetansMod.perms.has(p, Permissions.PLOT_BYPASS))
         {
             return;
         }  
@@ -36,7 +36,7 @@ public class ProtectionInteract extends Protection
     public void onPlayerInteract(PlayerInteractEvent.RightClickBlock e) 
     {
         EntityPlayer p = e.getEntityPlayer();
-        if(Permission.has(p, Permissions.PLOT_BYPASS))
+        if(KajetansMod.perms.has(p, Permissions.PLOT_BYPASS))
         {
             return;
         }    
@@ -57,7 +57,7 @@ public class ProtectionInteract extends Protection
     public void protectFromInteract(PlayerInteractEvent.EntityInteract e)
     {      
         EntityPlayer p = e.getEntityPlayer();
-        if(Permission.has(p, Permissions.PLOT_BYPASS) || 
+        if(KajetansMod.perms.has(p, Permissions.PLOT_BYPASS) || 
             this.getProtectionBank().canBuild(e.getWorld(), e.getTarget().getPosition(), p))
         {
             return;

+ 3 - 3
src/main/java/me/km/plots/ProtectionMarkPlot.java

@@ -4,7 +4,7 @@ import me.km.api.Module;
 import java.util.HashMap;
 import java.util.UUID;
 import me.km.KajetansMod;
-import me.km.permissions.Permission;
+import me.km.permissions.PermissionManager;
 import me.km.permissions.Permissions;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.init.Items;
@@ -33,7 +33,7 @@ public class ProtectionMarkPlot extends Protection
             return;
         }
         EntityPlayer p = e.getEntityPlayer();
-        if(Permission.has(p, Permissions.PLOT_MARK) && p.getHeldItemMainhand().getItem() == Items.WOODEN_SWORD && p.isCreative())
+        if(KajetansMod.perms.has(p, Permissions.PLOT_MARK) && p.getHeldItemMainhand().getItem() == Items.WOODEN_SWORD && p.isCreative())
         {
             BlockPos pos = e.getPos();
             coord2.put(p.getUniqueID(), pos);
@@ -50,7 +50,7 @@ public class ProtectionMarkPlot extends Protection
             return;
         }
         EntityPlayer p = e.getEntityPlayer();
-        if(Permission.has(p, Permissions.PLOT_MARK) && p.getHeldItemMainhand().getItem() == Items.WOODEN_SWORD && p.isCreative())
+        if(KajetansMod.perms.has(p, Permissions.PLOT_MARK) && p.getHeldItemMainhand().getItem() == Items.WOODEN_SWORD && p.isCreative())
         {
             BlockPos pos = e.getPos();
             coord1.put(p.getUniqueID(), pos);

+ 1 - 0
src/main/java/me/km/scrolls/CommandScroll.java

@@ -23,6 +23,7 @@ public class CommandScroll extends ModuleTabCommand
         super.setDescription("Erstellt Schriftrollen");
         super.setUsage("/scroll <name> [level] [amount]");
         super.setPermission(Permissions.SCROLL);
+        super.addAlias("sc");
     }
 
     @Override

+ 1 - 0
src/main/java/me/km/skills/CommandActiveSkills.java

@@ -17,6 +17,7 @@ public class CommandActiveSkills extends ModuleCommand
         super.setDescription("Zeigt dir deine aktiven Skills");
         super.setUsage("/activeskills");
         super.setPermission(Permissions.ACTIVE_SKILLS);
+        super.addAlias("askills");
     }
 
     @Override

+ 1 - 2
src/main/java/me/km/skills/Skill.java

@@ -1,6 +1,5 @@
 package me.km.skills;
 
-import me.km.api.Utils;
 import me.km.effects.Effect;
 import me.km.utils.ItemStackBuilder;
 import me.km.utils.ItemStackUtils;
@@ -18,7 +17,7 @@ public class Skill
         ItemStackUtils.addItemFlag(stack, ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_UNBREAKABLE);
         ItemStackUtils.setUnbreakable(stack);
         stack.setStackDisplayName("§6" + name);
-        ItemStackUtils.setLore(stack, Utils.buildLimitedLore(explanation, "§7"));
+        ItemStackUtils.setLore(stack, ItemStackBuilder.buildLimitedLore(explanation, 25, "§7"));
         this.stack = stack;
         this.effect = eff;
         this.name = name;

+ 4 - 0
src/main/java/me/km/snuviscript/CommandGiveUp.java

@@ -18,6 +18,10 @@ public class CommandGiveUp extends ModuleCommand
         super.setDescription("Gibt deine Quest auf");
         super.setUsage("/giveup");
         super.setPermission(Permissions.GIVEUP);
+        super.addAlias("fuckit");
+        super.addAlias("fuckitigiveup");
+        super.addAlias("ineedhelp");
+        super.addAlias("leave");
     }
 
     @Override

+ 1 - 0
src/main/java/me/km/snuviscript/CommandQuest.java

@@ -23,6 +23,7 @@ public class CommandQuest extends ModuleCommand
         super.setDescription("Zeigt alles über Quests");
         super.setUsage("/quest für die Hilfe");
         super.setPermission(Permissions.QUEST);
+        super.addAlias("q");
     }
 
     @SuppressWarnings("unchecked")

+ 1 - 0
src/main/java/me/km/snuviscript/CommandScript.java

@@ -21,6 +21,7 @@ public class CommandScript extends ModuleCommand
         super.setDescription("Zeigt alles über Scripts");
         super.setUsage("/script für die Hilfe");
         super.setPermission(Permissions.SCRIPT);
+        super.addAlias("s");
     }
 
     @SuppressWarnings("unchecked")

+ 1 - 13
src/main/java/me/km/snuviscript/QuestData.java

@@ -57,8 +57,7 @@ public class QuestData
     private final boolean script;
     private int idCounter;
  
-    private final ArrayList<EntityPlayer> quester;
-    private final ArrayList<EntityPlayer> offquester;      
+    private final ArrayList<EntityPlayer> quester;  
     
     public QuestData(int id, EntityPlayer p, String filename, ICommandSender cs)
     {       
@@ -87,7 +86,6 @@ public class QuestData
         isTrying = false;
         
         quester = new ArrayList<>();
-        offquester = new ArrayList<>();
         
         info = "Keine Info wurde gesetzt.";
         
@@ -688,7 +686,6 @@ public class QuestData
     public boolean removePlayer(EntityPlayer p)
     {
         quester.remove(p);
-        offquester.remove(p);
         return quester.isEmpty();
     }
     
@@ -702,15 +699,6 @@ public class QuestData
         return getPlayers().stream().map(p -> p.getName()).collect(Collectors.toList());
     }
     
-    public void addToOffQuesters(EntityPlayer p)
-    {
-        if(p == null)
-        {
-            return;
-        }
-        offquester.add(p);
-    }
-    
     // -------------------------------------------------------------------------
     // Location Handling für Wait-For-Location
     // -------------------------------------------------------------------------

+ 17 - 7
src/main/java/me/km/snuviscript/QuestParser.java

@@ -31,6 +31,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -41,7 +42,6 @@ import me.km.api.TitleAPI;
 import me.km.dimensions.ModDimensions;
 import me.km.effects.EffectUtils;
 import me.km.inventory.InventoryUtils;
-import me.km.permissions.Permission;
 import me.km.permissions.Permissions;
 import me.km.table.Table;
 import me.km.utils.ItemStackUtils;
@@ -132,6 +132,16 @@ public class QuestParser
         registerConsumer(list, "clearbenchmark", (args, qd) -> 
                 qd.clearBenchmark());
 
+        // -------------------------------------------------------------
+        // Permission-Bibliothek  
+        // -------------------------------------------------------------
+        registerConsumer(list, "perm.clear", (args, qd) -> 
+                KajetansMod.perms.clear());
+        registerConsumer(list, "perm.registergroup", (args, qd) -> 
+                KajetansMod.perms.registerGroupPermission(QuestUtils.getInt(args[0]), args[1].toString()));
+        registerConsumer(list, "perm.registerplayer", (args, qd) -> 
+                KajetansMod.perms.registerPlayerGroup(UUID.fromString(args[0].toString()), QuestUtils.getInt(args[1])));
+        
         // -------------------------------------------------------------
         // Title-Bibliothek  
         // -------------------------------------------------------------
@@ -313,9 +323,9 @@ public class QuestParser
         registerConsumer(list, "item.setname", (args, qd) ->   
                 ((ItemStack) args[0]).setStackDisplayName(QuestUtils.connect(args, 1)));
         registerConsumer(list, "item.getlore", (args, qd) ->    
-                qd.setVar(args[0], Utils.getLore((ItemStack) args[1])));
+                qd.setVar(args[0], ItemStackUtils.getLore((ItemStack) args[1])));
         registerConsumer(list, "item.setlore", (args, qd) ->   
-                Utils.setLore((ItemStack) args[0], QuestUtils.connect(args, 2), QuestUtils.getInt(args[1])));
+                ItemStackUtils.setLore((ItemStack) args[0], QuestUtils.connect(args, 2), QuestUtils.getInt(args[1])));
         registerFunction(list, "item.getenchantlevel", (args, qd) ->   
                 EnchantmentHelper.getEnchantmentLevel(ReflectionUtils.getEnchantment(args[1].toString()), (ItemStack) args[0]));
         registerConsumer(list, "item.setcooldown", (args, qd) ->   
@@ -1325,7 +1335,7 @@ public class QuestParser
             return;
         }
         EntityPlayer p = qd.getPlayers().get(0);
-        if(Permission.has(p, Permissions.SCRIPT_ERROR))
+        if(KajetansMod.perms.has(p, Permissions.SCRIPT_ERROR))
         {
             qd.loadNewCode(args[0].toString(), p);
             return;
@@ -1755,10 +1765,10 @@ public class QuestParser
                 case "dev":
                     if(qd.isScript())
                     {
-                        KajetansMod.server.getPlayerList().getPlayers().stream().filter(p -> Permission.has(p, Permissions.SCRIPT_ERROR)).forEach(p -> c.accept(p));
+                        KajetansMod.server.getPlayerList().getPlayers().stream().filter(p -> KajetansMod.perms.has(p, Permissions.SCRIPT_ERROR)).forEach(p -> c.accept(p));
                         return;
                     }
-                    qd.getPlayers().stream().filter(p ->  Permission.has(p, Permissions.SCRIPT_ERROR)).forEach(p -> c.accept(p));
+                    qd.getPlayers().stream().filter(p ->  KajetansMod.perms.has(p, Permissions.SCRIPT_ERROR)).forEach(p -> c.accept(p));
                     break;
                 case "server":
                     c.accept(KajetansMod.server);
@@ -1796,7 +1806,7 @@ public class QuestParser
     {
         Module m = KajetansMod.quest;
         String warnMessage = "§4" + message;
-        KajetansMod.server.getPlayerList().getPlayers().stream().filter(p -> Permission.has(p, Permissions.SCRIPT_ERROR)).forEach(p -> m.send(p, warnMessage));
+        KajetansMod.server.getPlayerList().getPlayers().stream().filter(p -> KajetansMod.perms.has(p, Permissions.SCRIPT_ERROR)).forEach(p -> m.send(p, warnMessage));
     }
     
     private void sendToDevsWithList(QuestData qd, String message)

+ 17 - 15
src/main/java/me/km/snuviscript/QuestsEvents.java

@@ -13,6 +13,8 @@ import me.km.api.Module;
 import me.km.api.Utils;
 import me.km.effects.PlayerUsesEffectEvent;
 import me.km.events.PlayerHurtEvent;
+import me.km.events.PlayerJoinMessageEvent;
+import me.km.events.PlayerLeaveMessageEvent;
 import me.km.events.PlayerMoveEvent;
 import net.minecraft.entity.EntityLivingBase;
 import net.minecraft.entity.item.EntityItem;
@@ -416,34 +418,34 @@ public class QuestsEvents extends ModuleListener
         });
     }
     
-    // TODO
-    /*@SubscribeEvent
-    public void QuestPlayerJoin(PlayerJoinEvent e)
+    @SubscribeEvent
+    public void QuestPlayerJoin(PlayerJoinMessageEvent e)
     {    
-        EntityPlayer p = e.getPlayer();
+        EntityPlayer p = e.getEntityPlayer();
         handleEvent(p, "player-join-server", (qd) -> 
         {       
-            qd.setVar("message", e.getJoinMessage());
+            qd.setVar("message", e.getMessage());
+            qd.setVar("changed-name", e.hasNameChanged());
+            qd.setVar("cancel", e.isCanceled()); 
         }, (qd) -> 
         {
-            e.setJoinMessage(String.valueOf(qd.getVar("message"))); 
+            e.setMessage(String.valueOf(qd.getVar("message"))); 
+            e.setCanceled(qd.getBoolean("cancel")); 
         });
-    }*/
+    }
     
-    // TODO
-    /*@SubscribeEvent
-    public void onPlayerLeave(PlayerQuitEvent e)
+    @SubscribeEvent
+    public void onPlayerLeave(PlayerLeaveMessageEvent e)
     {      
-        EntityPlayer p = e.getPlayer();
+        EntityPlayer p = e.getEntityPlayer();
         handleEvent(p, "player-leave", (qd) -> 
         {       
-            qd.setVar("message", e.getQuitMessage());
+            qd.setVar("message", e.getMessage());
         }, (qd) -> 
         {
-            e.setQuitMessage(String.valueOf(qd.getVar("message"))); 
-            qd.addToOffQuesters(p);
+            e.setMessage(String.valueOf(qd.getVar("message"))); 
         });
-    }*/
+    }
     
     @SubscribeEvent
     public void QuestBucketFill(FillBucketEvent e)

+ 22 - 5
src/main/java/me/km/utils/ItemStackBuilder.java

@@ -1,5 +1,6 @@
 package me.km.utils;
 
+import java.util.ArrayList;
 import me.km.api.Utils;
 import me.km.utils.ItemStackUtils.ItemFlag;
 import net.minecraft.block.Block;
@@ -62,16 +63,13 @@ public class ItemStackBuilder
     
     public ItemStackBuilder addLore(String line)
     {
-        Utils.setLore(stack, line, -1);
+        ItemStackUtils.addLore(stack, line);
         return this;
     }
     
     public ItemStackBuilder addLimitedLore(String whole, int limit, String addition)
     {
-        //TODO
-        /*ItemMeta meta = stack.getItemMeta();
-        meta.setLore(Utils.buildLimitedLore(whole, limit, addition));
-        stack.setItemMeta(meta);*/
+        ItemStackUtils.setLore(stack, buildLimitedLore(whole, limit, addition));
         return this;
     }
     
@@ -80,6 +78,25 @@ public class ItemStackBuilder
         return addLimitedLore(whole, 25, addition);
     }
     
+    public static ArrayList<String> buildLimitedLore(String whole, int limit, String addition)
+    {
+        ArrayList<String> list = new ArrayList<>();
+        int pos = 0;
+        int space;
+        while(pos + limit < whole.length())
+        {
+            space = whole.lastIndexOf(" ", pos + limit);
+            if(space == -1 || pos > space)
+            {
+                space = whole.indexOf(" ", pos + limit);
+            }          
+            list.add(addition + whole.substring(pos, space));  
+            pos = space + 1;
+        }
+        list.add(addition + whole.substring(pos));
+        return list;
+    }
+    
     public ItemStackBuilder hideTags()
     {
         ItemStackUtils.addItemFlag(stack, ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_ENCHANTS);

+ 32 - 0
src/main/java/me/km/utils/ItemStackUtils.java

@@ -1,6 +1,7 @@
 package me.km.utils;
 
 import java.util.ArrayList;
+import java.util.List;
 import me.km.exception.IllegalItemStackStringException;
 import net.minecraft.block.Block;
 import net.minecraft.entity.ai.attributes.AttributeModifier;
@@ -201,6 +202,37 @@ public class ItemStackUtils
         // TODO
     }
     
+    public static List<String> getLore(ItemStack stack)
+    {
+        //TODO
+        return new ArrayList<>();
+    }    
+    
+    public static void setLore(ItemStack stack, String s, int i)
+    {     
+        //TODO
+        /*ItemMeta meta = stack.getItemMeta();
+        List<String> list;
+        if(meta.hasLore())
+        {
+            list = meta.getLore();
+        }
+        else
+        {
+            list = new ArrayList<>();
+        }                           
+        if(i >= list.size())
+        {
+            list.add(s);
+        }
+        else
+        {
+            list.set(i, s);
+        }           
+        meta.setLore(list);
+        stack.setItemMeta(meta);*/
+    }
+    
     public static void drop(World w, BlockPos pos, ItemStack stack)
     {
         Block.spawnAsEntity(w, pos, stack);