Browse Source

new snuvi commands, commands moved into several files

Kajetan Johannes Hammerle 4 years ago
parent
commit
1af06e16e0
44 changed files with 2606 additions and 2702 deletions
  1. 3 11
      src/main/java/me/km/Server.java
  2. 0 81
      src/main/java/me/km/blockprotections/BlockProtectionBank.java
  3. 0 104
      src/main/java/me/km/blockprotections/BlockProtectionEvents.java
  4. 0 17
      src/main/java/me/km/blockprotections/DummyBlockProtection.java
  5. 0 11
      src/main/java/me/km/blockprotections/IBlockProtection.java
  6. 0 1
      src/main/java/me/km/overrides/ModCapeLayer.java
  7. 5 5
      src/main/java/me/km/permissions/ModCommandManager.java
  8. 22 28
      src/main/java/me/km/permissions/Permissions.java
  9. 4 4
      src/main/java/me/km/plots/ProtectionEvents.java
  10. 36 2426
      src/main/java/me/km/snuviscript/MinecraftFunctions.java
  11. 7 7
      src/main/java/me/km/snuviscript/ScriptEvents.java
  12. 8 7
      src/main/java/me/km/snuviscript/SnuviLogger.java
  13. 37 0
      src/main/java/me/km/snuviscript/commands/BanCommands.java
  14. 203 0
      src/main/java/me/km/snuviscript/commands/BlockCommands.java
  15. 126 0
      src/main/java/me/km/snuviscript/commands/CommandCommands.java
  16. 113 0
      src/main/java/me/km/snuviscript/commands/CommandUtils.java
  17. 43 0
      src/main/java/me/km/snuviscript/commands/Commands.java
  18. 108 0
      src/main/java/me/km/snuviscript/commands/DamageCommands.java
  19. 25 0
      src/main/java/me/km/snuviscript/commands/DataCommands.java
  20. 71 0
      src/main/java/me/km/snuviscript/commands/DatabankCommands.java
  21. 170 0
      src/main/java/me/km/snuviscript/commands/DeprecatedCommands.java
  22. 27 0
      src/main/java/me/km/snuviscript/commands/DisplayCommands.java
  23. 355 0
      src/main/java/me/km/snuviscript/commands/EntityCommands.java
  24. 18 0
      src/main/java/me/km/snuviscript/commands/EventCommands.java
  25. 35 0
      src/main/java/me/km/snuviscript/commands/HeadCommands.java
  26. 29 0
      src/main/java/me/km/snuviscript/commands/HumanCommands.java
  27. 54 0
      src/main/java/me/km/snuviscript/commands/InventoryCommands.java
  28. 107 0
      src/main/java/me/km/snuviscript/commands/ItemCommands.java
  29. 37 0
      src/main/java/me/km/snuviscript/commands/ItemStackDisplayCommands.java
  30. 37 0
      src/main/java/me/km/snuviscript/commands/LivingCommands.java
  31. 85 0
      src/main/java/me/km/snuviscript/commands/LocationCommands.java
  32. 74 0
      src/main/java/me/km/snuviscript/commands/ParticleCommands.java
  33. 17 0
      src/main/java/me/km/snuviscript/commands/PermissionCommands.java
  34. 287 0
      src/main/java/me/km/snuviscript/commands/PlayerCommands.java
  35. 63 0
      src/main/java/me/km/snuviscript/commands/PlotCommands.java
  36. 53 0
      src/main/java/me/km/snuviscript/commands/ReadCommands.java
  37. 26 0
      src/main/java/me/km/snuviscript/commands/ScoreboardCommands.java
  38. 43 0
      src/main/java/me/km/snuviscript/commands/ScriptCommands.java
  39. 31 0
      src/main/java/me/km/snuviscript/commands/SoundCommands.java
  40. 33 0
      src/main/java/me/km/snuviscript/commands/StatusCommands.java
  41. 25 0
      src/main/java/me/km/snuviscript/commands/TableCommands.java
  42. 67 0
      src/main/java/me/km/snuviscript/commands/TextCommands.java
  43. 33 0
      src/main/java/me/km/snuviscript/commands/TitleCommands.java
  44. 89 0
      src/main/java/me/km/snuviscript/commands/WorldCommands.java

+ 3 - 11
src/main/java/me/km/Server.java

@@ -3,15 +3,11 @@ package me.km;
 import me.hammerle.snuviscript.code.ISnuviLogger;
 import me.hammerle.snuviscript.config.SnuviConfig;
 import me.kcm.Hooks;
-import me.km.blockprotections.BlockProtectionBank;
-import me.km.blockprotections.BlockProtectionEvents;
-import me.km.blockprotections.DummyBlockProtection;
-import me.km.blockprotections.IBlockProtection;
 import me.km.databank.DataBank;
 import me.km.events.CustomEventCaller;
 import me.km.overrides.ModPlayerList;
 import me.km.permissions.ModCommandManager;
-import me.km.permissions.PermissionManager;
+import me.km.permissions.Permissions;
 import me.km.playerbank.DummyPlayerBank;
 import me.km.playerbank.IPlayerBank;
 import me.km.playerbank.PlayerBank;
@@ -58,7 +54,7 @@ public class Server {
         boolean debug = conf.getBoolean("debug", false);
 
         // permissions
-        PermissionManager perms = new PermissionManager(debug);
+        Permissions perms = new Permissions(debug);
         logger.setPlayerLoggingData(server, perms);
         if(debug) {
             logger.print("------------------------------------------------");
@@ -101,17 +97,13 @@ public class Server {
         scheduler.scheduleRepeatingTask(() -> plotMap.save(), time, time);
 
         // block protections / player manager
-        IBlockProtection blockProtection;
         IPlayerBank playerBank;
         if(databank.isDummyDatabank()) {
-            blockProtection = new DummyBlockProtection();
             playerBank = new DummyPlayerBank();
         } else {
-            blockProtection = new BlockProtectionBank(databank);
             playerBank = new PlayerBank(databank);
         }
         MinecraftForge.EVENT_BUS.register(new ProtectionEvents(plotMap, perms));
-        MinecraftForge.EVENT_BUS.register(new BlockProtectionEvents(blockProtection, perms));
 
         PlayerManager playerManager = new PlayerManager(logger, playerBank);
         MinecraftForge.EVENT_BUS.register(playerManager);
@@ -128,7 +120,7 @@ public class Server {
         }
         MinecraftFunctions.registerFunctions(
                 scripts.getScriptManager(), scripts, perms, scheduler, server, playerBank,
-                customEventCaller, scriptBank, databank, blockProtection, plotMap, commands);
+                customEventCaller, scriptBank, databank, plotMap, commands);
 
         MinecraftForge.EVENT_BUS.register(new WorldEvents());
         scripts.startScript("startscript");

+ 0 - 81
src/main/java/me/km/blockprotections/BlockProtectionBank.java

@@ -1,81 +0,0 @@
-package me.km.blockprotections;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import me.km.databank.DataBank;
-import me.km.overrides.ModEntityPlayerMP;
-import me.km.world.WorldManager;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.IWorld;
-
-public class BlockProtectionBank implements IBlockProtection {
-    private final PreparedStatement hasAccess;
-    private final PreparedStatement getId;
-
-    public BlockProtectionBank(DataBank databank) {
-        databank.execute("CREATE TABLE IF NOT EXISTS block ("
-                + "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
-                + "x int(11) NOT NULL, "
-                + "y int(11) NOT NULL, "
-                + "z int(11) NOT NULL, "
-                + "world_name varchar(20) NOT NULL, "
-                + "UNIQUE KEY uniq_block_pos (world_name,x,y,z));");
-
-        databank.execute("CREATE TABLE IF NOT EXISTS block_grant ("
-                + "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
-                + "block_id int(11) NOT NULL, "
-                + "player_id int(11) NOT NULL, "
-                + "INDEX block_id (block_id), "
-                + "UNIQUE KEY (block_id, player_id), "
-                + "CONSTRAINT block_grant_ibfk_1 FOREIGN KEY (block_id) REFERENCES block (id) ON DELETE CASCADE);");
-
-        hasAccess = databank.prepareStatement("Select id from block_grant WHERE id = ? AND player_id = ?;");
-        getId = databank.prepareStatement("SELECT id FROM block WHERE world_name=? AND x=? AND y=? AND z=?;");
-    }
-
-    @Override
-    public boolean hasAccess(int x, int y, int z, String worldName, int playerId) {
-        int id = getId(x, y, z, worldName);
-        if(id == -1) {
-            return true;
-        }
-        try {
-            hasAccess.setInt(1, id);
-            hasAccess.setInt(2, playerId);
-            try(ResultSet rs = hasAccess.executeQuery()) {
-                return rs.next();
-            } catch(SQLException ex) {
-                ex.printStackTrace();
-            }
-        } catch(SQLException ex) {
-            ex.printStackTrace();
-        }
-        return false;
-    }
-
-    @Override
-    public boolean hasAccess(BlockPos pos, IWorld w, ModEntityPlayerMP p) {
-        return hasAccess(pos.getX(), pos.getY(), pos.getZ(), WorldManager.getName(w), p.getId());
-    }
-
-    private int getId(int x, int y, int z, String worldName) {
-        try {
-            getId.setString(1, worldName);
-            getId.setInt(2, x);
-            getId.setInt(3, y);
-            getId.setInt(4, z);
-            try(ResultSet rs = getId.executeQuery()) {
-                if(rs.next()) {
-                    return rs.getInt(1);
-                }
-                return -1;
-            } catch(SQLException ex) {
-                ex.printStackTrace();
-            }
-        } catch(SQLException ex) {
-            ex.printStackTrace();
-        }
-        return -1;
-    }
-}

+ 0 - 104
src/main/java/me/km/blockprotections/BlockProtectionEvents.java

@@ -1,104 +0,0 @@
-package me.km.blockprotections;
-
-import me.km.overrides.ModEntityPlayerMP;
-import me.km.permissions.PermissionManager;
-import me.km.utils.Location;
-import net.minecraft.block.Block;
-import net.minecraft.block.ContainerBlock;
-import net.minecraft.block.DoorBlock;
-import net.minecraft.block.BlockState;
-import net.minecraft.block.Blocks;
-import net.minecraft.state.properties.DoubleBlockHalf;
-import net.minecraft.tags.BlockTags;
-import net.minecraft.util.Hand;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.IWorld;
-import net.minecraftforge.event.entity.player.PlayerInteractEvent;
-import net.minecraftforge.event.world.BlockEvent;
-import net.minecraftforge.eventbus.api.EventPriority;
-import net.minecraftforge.eventbus.api.SubscribeEvent;
-
-public class BlockProtectionEvents {
-    private final static String BLOCK_BYPASS = "block.bypass";
-
-    private final IBlockProtection bank;
-    private final PermissionManager perms;
-
-    public BlockProtectionEvents(IBlockProtection bank, PermissionManager perms) {
-        this.bank = bank;
-        this.perms = perms;
-    }
-
-    private BlockPos getSameNearbyBlock(IWorld w, BlockPos pos, Block b) {
-        Location l = new Location(w, pos);
-        if(l.getRelativeBlockState(1, 0, 0).getBlock() == b) {
-            return pos.add(1, 0, 0);
-        } else if(l.getRelativeBlockState(-1, 0, 0).getBlock() == b) {
-            return pos.add(-1, 0, 0);
-        } else if(l.getRelativeBlockState(0, 0, 1).getBlock() == b) {
-            return pos.add(0, 0, 1);
-        } else if(l.getRelativeBlockState(0, 0, -1).getBlock() == b) {
-            return pos.add(0, 0, -1);
-        }
-        return null;
-    }
-
-    @SubscribeEvent(priority = EventPriority.HIGHEST)
-    public void onBlockPlace(BlockEvent.EntityPlaceEvent e) {
-        Block b = e.getPlacedBlock().getBlock();
-        if(!(e.getEntity() instanceof ModEntityPlayerMP)) {
-            return;
-        }
-        ModEntityPlayerMP p = (ModEntityPlayerMP) e.getEntity();
-        IWorld w = e.getWorld();
-
-        if(b == Blocks.CHEST || b == Blocks.TRAPPED_CHEST) // Deny placing chests near other protected chests
-        {
-            BlockPos otherChest = getSameNearbyBlock(w, e.getPos(), b);
-            if(otherChest != null && !bank.hasAccess(otherChest, w, p) && !perms.hasPermission(p, BLOCK_BYPASS)) {
-                e.setCanceled(true);
-            }
-        } else if(b == Blocks.HOPPER) // Deny placing of hoppers under blocks
-        {
-            BlockPos pos = e.getPos().add(0, 1, 0);
-            if(w.getBlockState(pos).getBlock() instanceof ContainerBlock) {
-                if(!bank.hasAccess(pos, w, p) && !perms.hasPermission(p, BLOCK_BYPASS)) {
-                    e.setCanceled(true);
-                }
-            }
-        }
-    }
-
-    @SubscribeEvent(priority = EventPriority.HIGHEST)
-    public void onBlockBreak(BlockEvent.BreakEvent e) {
-        ModEntityPlayerMP p = (ModEntityPlayerMP) e.getPlayer();
-        BlockState state = e.getState();
-
-        BlockPos pos = e.getPos();
-        if(BlockTags.DOORS.contains(state.getBlock()) && state.get(DoorBlock.HALF) == DoubleBlockHalf.UPPER) {
-            pos = pos.add(0, -1, 0);
-        }
-        IWorld w = e.getWorld();
-        if(bank.hasAccess(pos, w, p) || perms.hasPermission(p, BLOCK_BYPASS)) {
-            // ToDo remove protection
-            return;
-        }
-        e.setCanceled(true);
-    }
-
-    @SubscribeEvent(priority = EventPriority.HIGHEST)
-    public void onContainerOpen(PlayerInteractEvent.RightClickBlock e) {
-        if(e.getHand() != Hand.MAIN_HAND) {
-            return;
-        }
-        BlockState state = e.getWorld().getBlockState(e.getPos());
-        ModEntityPlayerMP p = (ModEntityPlayerMP) e.getPlayer();
-        BlockPos pos = e.getPos();
-        if(BlockTags.DOORS.contains(state.getBlock()) && state.get(DoorBlock.HALF) == DoubleBlockHalf.UPPER) {
-            pos = pos.add(0, -1, 0);
-        }
-        if(!bank.hasAccess(pos, e.getWorld(), p) && !perms.hasPermission(p, BLOCK_BYPASS)) {
-            e.setCanceled(true);
-        }
-    }
-}

+ 0 - 17
src/main/java/me/km/blockprotections/DummyBlockProtection.java

@@ -1,17 +0,0 @@
-package me.km.blockprotections;
-
-import me.km.overrides.ModEntityPlayerMP;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.IWorld;
-
-public class DummyBlockProtection implements IBlockProtection {
-    @Override
-    public boolean hasAccess(int x, int y, int z, String worldName, int playerId) {
-        return true;
-    }
-
-    @Override
-    public boolean hasAccess(BlockPos pos, IWorld w, ModEntityPlayerMP p) {
-        return true;
-    }
-}

+ 0 - 11
src/main/java/me/km/blockprotections/IBlockProtection.java

@@ -1,11 +0,0 @@
-package me.km.blockprotections;
-
-import me.km.overrides.ModEntityPlayerMP;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.IWorld;
-
-public interface IBlockProtection {
-    public boolean hasAccess(int x, int y, int z, String worldName, int playerId);
-
-    public boolean hasAccess(BlockPos pos, IWorld w, ModEntityPlayerMP p);
-}

+ 0 - 1
src/main/java/me/km/overrides/ModCapeLayer.java

@@ -1,7 +1,6 @@
 package me.km.overrides;
 
 import com.mojang.blaze3d.matrix.MatrixStack;
-import com.mojang.blaze3d.platform.GlStateManager;
 import com.mojang.blaze3d.vertex.IVertexBuilder;
 import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
 import net.minecraft.client.renderer.IRenderTypeBuffer;

+ 5 - 5
src/main/java/me/km/permissions/ModCommandManager.java

@@ -27,14 +27,14 @@ public class ModCommandManager extends Commands {
     private final HashSet<String> otherCommands = new HashSet<>();
 
     private final HashMap<String, Command> commands = new HashMap<>();
-    private final PermissionManager perms;
+    private final Permissions perms;
     private final ScriptEvents events;
     private final Scripts scripts;
 
     private final ArrayList<CommandNode> customNodes = new ArrayList<>();
     private final HashSet<String> ignoredCommands = new HashSet<>();
 
-    public ModCommandManager(boolean isDedicatedServer, PermissionManager perms, ScriptEvents events, Scripts scripts, ISnuviScheduler scheduler) {
+    public ModCommandManager(boolean isDedicatedServer, Permissions perms, ScriptEvents events, Scripts scripts, ISnuviScheduler scheduler) {
         super(isDedicatedServer);
         getDispatcher().getRoot().getChildren().forEach(c -> {
             otherCommands.add(c.getName());
@@ -146,7 +146,7 @@ public class ModCommandManager extends Commands {
 
         Command command = commands.get(commandName);
         if(command != null) {
-            if(perms.hasPermission(cs, command.getName())) {
+            if(perms.has(cs, command.getName())) {
                 command.execute(getSource(cs), getArguments(rawCommand));
                 return 1;
             }
@@ -165,7 +165,7 @@ public class ModCommandManager extends Commands {
         }
 
         if(otherCommands.contains(commandName)) {
-            if(perms.hasPermission(cs, commandName)) {
+            if(perms.has(cs, commandName)) {
                 Entity ent = cs.getEntity();
                 if(ent != null && ent instanceof PlayerEntity) {
                     CommandEvent e = new CommandEvent((PlayerEntity) ent, commandName);
@@ -207,7 +207,7 @@ public class ModCommandManager extends Commands {
             if(first && ignoredCommands.contains(commandnode.getName())) {
                 continue;
             }
-            if((first && perms.hasPermission(source, commandnode.getName()) || (!first && commandnode.canUse(source)))) {
+            if((first && perms.has(source, commandnode.getName()) || (!first && commandnode.canUse(source)))) {
                 ArgumentBuilder<ISuggestionProvider, ?> argumentbuilder = (ArgumentBuilder) commandnode.createBuilder();
                 argumentbuilder.requires(a -> true);
                 if(argumentbuilder.getCommand() != null) {

+ 22 - 28
src/main/java/me/km/permissions/PermissionManager.java → src/main/java/me/km/permissions/Permissions.java

@@ -10,13 +10,16 @@ import net.minecraftforge.api.distmarker.Dist;
 import net.minecraftforge.api.distmarker.OnlyIn;
 
 @OnlyIn(Dist.DEDICATED_SERVER)
-public class PermissionManager {
+public class Permissions {
+    private final static UUID MARVINIUS = UUID.fromString("e41b5335-3c74-46e9-a6c5-dafc6334a477");
+    private final static UUID KAJETANJOHANNES = UUID.fromString("51e240f9-ab10-4ea6-8a5d-779319f51257");
+
     private final HashMap<UUID, ArrayList<Integer>> playerGroups = new HashMap<>();
     private final ArrayList<HashSet<String>> stringGroupPerms = new ArrayList<>();
     private final HashSet<String> otherGroup = new HashSet<>();
     private final boolean debug;
 
-    public PermissionManager(boolean debug) {
+    public Permissions(boolean debug) {
         this.debug = debug;
         addGroups();
     }
@@ -36,17 +39,11 @@ public class PermissionManager {
         otherGroup.add(perm);
     }
 
-    // -------------------------------------------------------------------------
-    // Permission-Check
-    // -------------------------------------------------------------------------
-    private final static UUID MARVINIUS = UUID.fromString("e41b5335-3c74-46e9-a6c5-dafc6334a477");
-    private final static UUID KAJETANJOHANNES = UUID.fromString("51e240f9-ab10-4ea6-8a5d-779319f51257");
-
-    public boolean hasPermission(Entity ent, String perm) {
-        return hasPermission(ent.getUniqueID(), perm);
+    public boolean has(Entity ent, String perm) {
+        return Permissions.this.has(ent.getUniqueID(), perm);
     }
 
-    public boolean hasPermission(UUID uuid, String perm) {
+    public boolean has(UUID uuid, String perm) {
         if(debug) {
             return true;
         }
@@ -66,20 +63,17 @@ public class PermissionManager {
         return groups.stream().anyMatch(i -> stringGroupPerms.get(i).contains(perm));
     }
 
-    public boolean hasPermission(CommandSource cs, String perm) {
+    public boolean has(CommandSource cs, String perm) {
         Entity ent = cs.getEntity();
         if(ent != null) {
-            return hasPermission(ent.getUniqueID(), perm);
+            return Permissions.this.has(ent.getUniqueID(), perm);
         }
         return true;
     }
 
-    // -------------------------------------------------------------------------
-    // Permission-Registry
-    // -------------------------------------------------------------------------
-    public void registerPlayerGroup(UUID uuid, int id) {
-        if(id < 0 || id >= stringGroupPerms.size()) {
-            throw new IllegalArgumentException(String.format("%d' is no valid group id", id));
+    public void register(UUID uuid, int groupId) {
+        if(groupId < 0 || groupId >= stringGroupPerms.size()) {
+            throw new IllegalArgumentException(String.format("%d' is no valid group id", groupId));
         }
         ArrayList<Integer> groups = playerGroups.get(uuid);
         if(groups == null) {
@@ -88,33 +82,33 @@ public class PermissionManager {
             groups.add(0);
             playerGroups.put(uuid, groups);
         }
-        groups.add(id);
+        groups.add(groupId);
     }
 
-    public boolean unregisterPlayer(UUID uuid, int id) {
-        if(id < 0 || id >= stringGroupPerms.size()) {
-            throw new IllegalArgumentException(String.format("%d' is no valid group id", id));
+    public boolean unregister(UUID uuid, int groupId) {
+        if(groupId < 0 || groupId >= stringGroupPerms.size()) {
+            throw new IllegalArgumentException(String.format("%d' is no valid group id", groupId));
         }
         ArrayList<Integer> groups = playerGroups.get(uuid);
         if(groups == null) {
             return false;
         }
-        return groups.remove((Integer) id);
+        return groups.remove((Integer) groupId);
     }
 
-    public void registerGroupPermission(int id, String perm) {
+    public void register(int groupId, String perm) {
         if(perm.isEmpty()) {
             throw new IllegalArgumentException("empty permission string");
         }
-        if(id == 1) {
+        if(groupId == 1) {
             throw new IllegalArgumentException("id 1 is reserved for worldedit");
         }
-        if(id >= stringGroupPerms.size()) {
+        if(groupId >= stringGroupPerms.size()) {
             HashSet<String> set = new HashSet<>();
             set.add(perm);
             stringGroupPerms.add(set);
             return;
         }
-        stringGroupPerms.get(id).add(perm);
+        stringGroupPerms.get(groupId).add(perm);
     }
 }

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

@@ -1,7 +1,7 @@
 package me.km.plots;
 
 import me.km.overrides.ModEntityPlayerMP;
-import me.km.permissions.PermissionManager;
+import me.km.permissions.Permissions;
 import net.minecraft.block.Block;
 import net.minecraft.block.Blocks;
 import net.minecraft.entity.Entity;
@@ -24,15 +24,15 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
 
 public class ProtectionEvents {
     private final WorldPlotMap plots;
-    private final PermissionManager perms;
+    private final Permissions perms;
 
-    public ProtectionEvents(WorldPlotMap plotMap, PermissionManager perms) {
+    public ProtectionEvents(WorldPlotMap plotMap, Permissions perms) {
         this.plots = plotMap;
         this.perms = perms;
     }
 
     private boolean canBypass(PlayerEntity p) {
-        return perms.hasPermission(p, "plot.bypass");
+        return perms.has(p, "plot.bypass");
     }
 
     private boolean shouldBeProtected(Entity ent) {

+ 36 - 2426
src/main/java/me/km/snuviscript/MinecraftFunctions.java

@@ -1,2440 +1,50 @@
 package me.km.snuviscript;
 
-import com.mojang.authlib.GameProfile;
-import com.mojang.brigadier.StringReader;
-import com.mojang.brigadier.arguments.ArgumentType;
-import com.mojang.brigadier.arguments.BoolArgumentType;
-import com.mojang.brigadier.arguments.DoubleArgumentType;
-import com.mojang.brigadier.arguments.FloatArgumentType;
-import com.mojang.brigadier.arguments.IntegerArgumentType;
-import com.mojang.brigadier.arguments.LongArgumentType;
-import com.mojang.brigadier.arguments.StringArgumentType;
-import com.mojang.brigadier.builder.ArgumentBuilder;
-import com.mojang.brigadier.builder.LiteralArgumentBuilder;
-import com.mojang.brigadier.builder.RequiredArgumentBuilder;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.List;
-import java.util.UUID;
-import java.util.function.Consumer;
-import me.hammerle.snuviscript.code.Script;
 import me.hammerle.snuviscript.code.ScriptManager;
-import me.hammerle.snuviscript.code.SnuviUtils;
-import me.hammerle.snuviscript.inputprovider.InputProvider;
-import me.km.blockprotections.IBlockProtection;
 import me.km.databank.DataBank;
-import me.km.utils.Location;
-import me.km.utils.Utils;
-import me.km.world.WorldManager;
-import me.km.entities.EntityHuman;
-import me.km.entities.EntityItemProjectile;
-import me.km.entities.ModEntities;
-import me.km.inventory.InventoryUtils;
-import me.km.utils.ItemStackUtils;
-import me.km.utils.ReflectionUtils;
-import net.minecraft.enchantment.Enchantment;
-import net.minecraft.enchantment.EnchantmentHelper;
-import net.minecraft.entity.Entity;
-import net.minecraft.inventory.IInventory;
-import net.minecraft.item.ItemStack;
-import net.minecraft.network.ThreadQuickExitException;
-import net.minecraft.potion.PotionUtils;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.DamageSource;
-import net.minecraft.util.SoundCategory;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.Vec3d;
-import net.minecraft.world.World;
 import me.km.events.CustomEventCaller;
-import me.km.events.PlayerMoveData;
-import me.km.inventory.CustomContainer;
-import me.km.inventory.ModInventory;
-import me.km.networking.ModPacketHandler;
-import me.km.overrides.ModEntityPlayerMP;
 import me.km.permissions.ModCommandManager;
-import me.km.permissions.PermissionManager;
+import me.km.permissions.Permissions;
 import me.km.playerbank.IPlayerBank;
-import me.km.plots.PlotMap.Plot;
 import me.km.plots.WorldPlotMap;
 import me.km.scheduler.SnuviScheduler;
-import me.km.utils.Mapper;
-import me.km.utils.TableUtils;
-import net.minecraft.block.Block;
-import net.minecraft.block.BlockState;
-import net.minecraft.block.ChestBlock;
-import net.minecraft.block.CropsBlock;
-import net.minecraft.block.DoorBlock;
-import net.minecraft.command.CommandSource;
-import net.minecraft.command.Commands;
-import net.minecraft.command.ICommandSource;
-import net.minecraft.command.arguments.BlockStateArgument;
-import net.minecraft.command.arguments.BlockStateParser;
-import net.minecraft.command.arguments.EnchantmentArgument;
-import net.minecraft.command.arguments.ItemArgument;
-import net.minecraft.command.arguments.PotionArgument;
-import net.minecraft.entity.AgeableEntity;
-import net.minecraft.entity.EntityType;
-import net.minecraft.entity.LivingEntity;
-import net.minecraft.entity.MobEntity;
-import net.minecraft.entity.SharedMonsterAttributes;
-import net.minecraft.entity.SpawnReason;
-import net.minecraft.entity.ai.attributes.AttributeModifier.Operation;
-import net.minecraft.entity.effect.LightningBoltEntity;
-import net.minecraft.entity.item.EnderPearlEntity;
-import net.minecraft.entity.item.ExperienceBottleEntity;
-import net.minecraft.entity.item.ItemEntity;
-import net.minecraft.entity.item.ItemFrameEntity;
-import net.minecraft.entity.monster.CreeperEntity;
-import net.minecraft.entity.passive.SheepEntity;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.entity.projectile.AbstractArrowEntity;
-import net.minecraft.entity.projectile.ArrowEntity;
-import net.minecraft.entity.projectile.DamagingProjectileEntity;
-import net.minecraft.entity.projectile.DragonFireballEntity;
-import net.minecraft.entity.projectile.EggEntity;
-import net.minecraft.entity.projectile.FireballEntity;
-import net.minecraft.entity.projectile.PotionEntity;
-import net.minecraft.entity.projectile.SmallFireballEntity;
-import net.minecraft.entity.projectile.SnowballEntity;
-import net.minecraft.entity.projectile.SpectralArrowEntity;
-import net.minecraft.entity.projectile.WitherSkullEntity;
-import net.minecraft.inventory.EnderChestInventory;
-import net.minecraft.inventory.EquipmentSlotType;
-import net.minecraft.inventory.container.ChestContainer;
-import net.minecraft.inventory.container.SimpleNamedContainerProvider;
-import net.minecraft.item.ArmorItem;
-import net.minecraft.item.Item;
-import net.minecraft.item.Items;
-import net.minecraft.nbt.CompoundNBT;
-import net.minecraft.nbt.JsonToNBT;
-import net.minecraft.nbt.NBTUtil;
-import net.minecraft.network.play.client.CChatMessagePacket;
-import net.minecraft.network.play.client.CClientStatusPacket;
-import net.minecraft.network.play.server.SPlaySoundEffectPacket;
-import net.minecraft.network.play.server.SSpawnPositionPacket;
-import net.minecraft.network.play.server.STitlePacket;
-import net.minecraft.network.play.server.SUpdateTileEntityPacket;
-import net.minecraft.particles.BlockParticleData;
-import net.minecraft.particles.IParticleData;
-import net.minecraft.particles.ItemParticleData;
-import net.minecraft.particles.ParticleType;
-import net.minecraft.particles.ParticleTypes;
-import net.minecraft.particles.RedstoneParticleData;
-import net.minecraft.potion.Effect;
-import net.minecraft.potion.EffectInstance;
 import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.management.PlayerList;
-import net.minecraft.server.management.ProfileBanEntry;
-import net.minecraft.state.IProperty;
-import net.minecraft.state.properties.ChestType;
-import net.minecraft.stats.Stats;
-import net.minecraft.tags.BlockTags;
-import net.minecraft.tags.ItemTags;
-import net.minecraft.tags.Tag;
-import net.minecraft.tileentity.ChestTileEntity;
-import net.minecraft.tileentity.MobSpawnerTileEntity;
-import net.minecraft.tileentity.SignTileEntity;
-import net.minecraft.tileentity.SkullTileEntity;
-import net.minecraft.util.Direction;
-import net.minecraft.util.NonNullList;
-import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.SoundEvent;
-import net.minecraft.util.math.BlockRayTraceResult;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.util.math.RayTraceContext;
-import net.minecraft.util.math.RayTraceResult;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.StringTextComponent;
-import net.minecraft.util.text.Style;
-import net.minecraft.util.text.TextFormatting;
-import net.minecraft.util.text.event.ClickEvent;
-import net.minecraft.util.text.event.HoverEvent;
-import net.minecraft.world.Difficulty;
-import net.minecraft.world.GameRules;
-import net.minecraft.world.GameType;
-import net.minecraft.world.IWorld;
-import net.minecraft.world.server.ServerWorld;
-import net.minecraft.world.storage.WorldInfo;
+import me.km.snuviscript.commands.*;
 
 public class MinecraftFunctions {
-    public static int inventoryIds = 0;
-
-    @SuppressWarnings("")
-    public static void registerFunctions(ScriptManager sm, Scripts scripts,
-            PermissionManager perms, SnuviScheduler scheduler, MinecraftServer server,
-            IPlayerBank playerBank, CustomEventCaller cec,
-            IScriptBank scriptBank, DataBank dataBank, IBlockProtection blockProtection,
-            WorldPlotMap plots, ModCommandManager commands) {
-        // ---------------------------------------------------------------------
-        // Command-library  
-        // ---------------------------------------------------------------------
-        sm.registerFunction("command.addignored", (sc, in) -> {
-            commands.addIgnoredCommands(in[0].getString(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.clearignored", (sc, in) -> {
-            commands.clearIgnoredCommands();
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.newhelp", (sc, in) -> Commands.literal(in[0].getString(sc)).requires(p -> perms.hasPermission(p, in[1].getString(sc))));
-        sm.registerFunction("command.newhelp", (sc, in) -> Commands.literal(in[0].getString(sc)).requires(p -> perms.hasPermission(p, in[1].getString(sc))));
-        sm.registerFunction("command.newhelpliteral", (sc, in) -> {
-            LiteralArgumentBuilder<CommandSource> arg = Commands.literal(in[0].getString(sc));
-            if(in.length >= 2) {
-                arg.requires(p -> perms.hasPermission(p, in[1].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.newhelpbool", (sc, in) -> {
-            RequiredArgumentBuilder<CommandSource, Boolean> arg = Commands.argument(in[0].getString(sc), BoolArgumentType.bool());
-            if(in.length >= 2) {
-                arg.requires(p -> perms.hasPermission(p, in[1].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.newhelpdouble", (sc, in) -> {
-            double min = in[1].getDouble(sc);
-            double max = in[2].getDouble(sc);
-            RequiredArgumentBuilder<CommandSource, Double> arg = Commands.argument(in[0].getString(sc), DoubleArgumentType.doubleArg(min, max));
-            if(in.length >= 4) {
-                arg.requires(p -> perms.hasPermission(p, in[3].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.newhelpfloat", (sc, in) -> {
-            float min = in[1].getFloat(sc);
-            float max = in[2].getFloat(sc);
-            RequiredArgumentBuilder<CommandSource, Float> arg = Commands.argument(in[0].getString(sc), FloatArgumentType.floatArg(min, max));
-            if(in.length >= 4) {
-                arg.requires(p -> perms.hasPermission(p, in[3].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.newhelpint", (sc, in) -> {
-            int min = in[1].getInt(sc);
-            int max = in[2].getInt(sc);
-            RequiredArgumentBuilder<CommandSource, Integer> arg = Commands.argument(in[0].getString(sc), IntegerArgumentType.integer(min, max));
-            if(in.length >= 4) {
-                arg.requires(p -> perms.hasPermission(p, in[3].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.newhelplong", (sc, in) -> {
-            long min = in[1].getLong(sc);
-            long max = in[2].getLong(sc);
-            RequiredArgumentBuilder<CommandSource, Long> arg = Commands.argument(in[0].getString(sc), LongArgumentType.longArg(min, max));
-            if(in.length >= 4) {
-                arg.requires(p -> perms.hasPermission(p, in[3].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.newhelpstring", (sc, in) -> {
-            RequiredArgumentBuilder<CommandSource, String> arg;
-            if(in[1].getBoolean(sc)) {
-                arg = Commands.argument(in[0].getString(sc), StringArgumentType.greedyString());
-            } else {
-                arg = Commands.argument(in[0].getString(sc), StringArgumentType.string());
-            }
-            if(in.length >= 3) {
-                arg.requires(p -> perms.hasPermission(p, in[2].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.newhelpspecial", (sc, in) -> {
-            RequiredArgumentBuilder<CommandSource, ArgumentType> arg = null;
-            String name = in[0].getString(sc);
-            switch(name) {
-                case "Item":
-                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) ItemArgument.item());
-                    break;
-                case "Block":
-                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) BlockStateArgument.blockState());
-                    break;
-                case "Potion":
-                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) PotionArgument.mobEffect());
-                    break;
-                case "Enchantment":
-                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) EnchantmentArgument.enchantment());
-                    break;
-                default:
-                    throw new IllegalArgumentException(String.format("'%s' is not a valid special help", name));
-            }
-            if(in.length >= 3) {
-                arg.requires(p -> perms.hasPermission(p, in[2].getString(sc)));
-            }
-            return arg;
-        });
-        sm.registerFunction("command.sendhelp", (sc, in) -> {
-            server.getPlayerList().getPlayers().forEach(p -> commands.send(p));
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.addhelpalias", (sc, in) -> {
-            ((ArgumentBuilder) in[0].get(sc)).redirect(((ArgumentBuilder) in[1].get(sc)).build());
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.addhelpchild", (sc, in) -> {
-            ((ArgumentBuilder) in[0].get(sc)).then(((ArgumentBuilder) in[1].get(sc)).build());
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.addhelp", (sc, in) -> {
-            commands.addCustomNodes(((LiteralArgumentBuilder<CommandSource>) in[0].get(sc)).build());
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.clearhelp", (sc, in) -> {
-            commands.clearCustomNodes();
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.add", (sc, in) -> {
-            scripts.registerScriptCommand(in[0].getString(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.remove", (sc, in) -> {
-            scripts.unregisterScriptCommand(in[0].getString(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("command.exists", (sc, in) -> scripts.isRegisteredScriptCommand(in[0].getString(sc)));
-        sm.registerFunction("command.clear", (sc, in) -> {
-            scripts.clearScriptCommands();
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------
-        // Permission-library  
-        // ---------------------------------------------------------------------
-        sm.registerFunction("perm.clear", (sc, in) -> {
-            perms.clear();
-            return Void.TYPE;
-        });
-        sm.registerFunction("perm.registergroup", (sc, in) -> {
-            perms.registerGroupPermission(in[0].getInt(sc), in[1].getString(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("perm.registerplayer", (sc, in) -> {
-            perms.registerPlayerGroup(getUUID(in[0].get(sc)), in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("perm.unregisterplayer", (sc, in) -> perms.unregisterPlayer(getUUID(in[0].get(sc)), in[1].getInt(sc)));
-        sm.registerFunction("perm.has", (sc, in) -> perms.hasPermission((Entity) in[0].get(sc), in[1].getString(sc)));
-
-        // ---------------------------------------------------------------------
-        // Title-library  
-        // ---------------------------------------------------------------------
-        sm.registerFunction("table.getstart", (sc, in) -> TableUtils.getTableStart(in[0].getInt(sc), in[1].getInt(sc), in[2].getString(sc)));
-        sm.registerFunction("table.getmiddle", (sc, in) -> TableUtils.getTableMiddle(in[0].getInt(sc), in[1].getInt(sc), in[2].getString(sc)));
-        sm.registerFunction("table.getend", (sc, in) -> TableUtils.getTableEnd(in[0].getInt(sc), in[1].getInt(sc), in[2].getString(sc)));
-        sm.registerFunction("table.get", (sc, in) -> {
-            String[] columns = new String[in.length - 2];
-            for(int i = 0; i < columns.length; i++) {
-                columns[i] = in[i + 2].getString(sc);
-            }
-            return TableUtils.getTable(in[0].getInt(sc), in[1].getString(sc), columns);
-        });
-
-        // ---------------------------------------------------------------------
-        // table library  
-        // ---------------------------------------------------------------------
-        sm.registerFunction("title.settime", (sc, in) -> {
-            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new STitlePacket(in[1].getInt(sc), in[2].getInt(sc), in[3].getInt(sc)));
-            return Void.TYPE;
-        });
-        sm.registerFunction("title.clear", (sc, in) -> {
-            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
-            p.connection.sendPacket(new STitlePacket(STitlePacket.Type.CLEAR, null));
-            p.connection.sendPacket(new STitlePacket(STitlePacket.Type.RESET, null));
-            return Void.TYPE;
-        });
-        sm.registerFunction("title.reset", (sc, in) -> {
-            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new STitlePacket(STitlePacket.Type.RESET, null));
-            return Void.TYPE;
-        });
-        sm.registerFunction("title.send", (sc, in) -> {
-            ITextComponent text = new StringTextComponent(SnuviUtils.connect(sc, in, 1));
-            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new STitlePacket(STitlePacket.Type.TITLE, text));
-            return Void.TYPE;
-        });
-        sm.registerFunction("title.setsub", (sc, in) -> {
-            ITextComponent text = new StringTextComponent(SnuviUtils.connect(sc, in, 1));
-            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new STitlePacket(STitlePacket.Type.SUBTITLE, text));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // Player-library
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("player.getitemamount", (sc, in) -> (double) InventoryUtils.searchInventoryFor(((PlayerEntity) in[0].get(sc)).inventory, (ItemStack) in[2].get(sc), in[1].getBoolean(sc)));
-        sm.registerFunction("player.removeitem", (sc, in) -> {
-            ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
-            stack.setCount(InventoryUtils.removeFromInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
-            return stack;
-        });
-        sm.registerFunction("player.giveitem", (sc, in) -> {
-            ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
-            stack.setCount(InventoryUtils.addToInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
-            return stack;
-        });
-        sm.registerFunction("player.respawn", (sc, in) -> {
-            final ServerPlayerEntity p = ((ServerPlayerEntity) in[0].get(sc));
-            scheduler.scheduleTask(() -> {
-                try {
-                    p.connection.processClientStatus(new CClientStatusPacket(CClientStatusPacket.State.PERFORM_RESPAWN));
-                } catch(ThreadQuickExitException ex) {
-                    // Minecraft needs this for canceling and queueing into main thread
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.clearinventory", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).inventory.clear();
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.inventorytolist", (sc, in) -> ((PlayerEntity) in[1].get(sc)).inventory.mainInventory);
-        sm.registerFunction("player.getnearest", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return l.getWorld().getClosestPlayer(l.getX(), l.getY(), l.getZ(), -1, p -> true);
-        });
-        sm.registerFunction("player.say", (sc, in) -> {
-            try {
-                ((ServerPlayerEntity) in[0].get(sc)).connection.processChatMessage(new CChatMessagePacket(SnuviUtils.connect(sc, in, 1)));
-            } catch(ThreadQuickExitException ex) {
-                // Minecraft needs this for canceling and queueing into main thread
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.speak", (sc, in) -> {
-            sendMessageToGroup(server, scripts, perms, in[0].get(sc), sc, concat(sc, 2, "§7[§r" + in[1].getString(sc) + "§7]§r ", in));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.setcompass", (sc, in) -> {
-            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new SSpawnPositionPacket(((Location) in[1].get(sc)).getBlockPos()));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.gethunger", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).getFoodStats().getFoodLevel());
-        sm.registerFunction("player.sethunger", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).getFoodStats().setFoodLevel(in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.getsaturation", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).getFoodStats().getSaturationLevel());
-        sm.registerFunction("player.setsaturation", (sc, in) -> {
-            ReflectionUtils.setSaturation(((PlayerEntity) in[0].get(sc)).getFoodStats(), in[1].getFloat(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.getname", (sc, in) -> {
-            Object o = in[0].get(sc);
-            if(o instanceof PlayerEntity) {
-                return ((PlayerEntity) o).getName().getFormattedText();
-            }
-            return server.getPlayerProfileCache().getProfileByUUID(getUUID(o.toString())).getName();
-        });
-        sm.registerFunction("player.getuuid", (sc, in) -> {
-            Object o = in[0].get(sc);
-            if(o instanceof PlayerEntity) {
-                return ((PlayerEntity) o).getUniqueID();
-            }
-            return playerBank.getUUID(o.toString());
-        });
-        sm.registerFunction("player.getid", (sc, in) -> (double) getId(playerBank, in[0].get(sc)));
-        sm.registerFunction("player.get", (sc, in) -> server.getPlayerList().getPlayerByUUID(getUUID(in[0].get(sc))));
-        sm.registerFunction("player.getuuidfromid", (sc, in) -> playerBank.getUUIDfromID(in[0].getInt(sc)));
-        sm.registerFunction("player.getnamefromid", (sc, in) -> playerBank.getNamefromID(in[0].getInt(sc)));
-        sm.registerFunction("player.getip", (sc, in) -> ((ServerPlayerEntity) in[0].get(sc)).connection.netManager.getRemoteAddress().toString());
-        sm.registerFunction("player.iscreative", (sc, in) -> ((PlayerEntity) in[0].get(sc)).isCreative());
-        sm.registerFunction("player.isspectator", (sc, in) -> ((PlayerEntity) in[0].get(sc)).isSpectator());
-        sm.registerFunction("player.issurvival", (sc, in) -> {
-            PlayerEntity p = (PlayerEntity) in[0].get(sc);
-            return !p.isCreative() && !p.isSpectator();
-        });
-        sm.registerFunction("player.isadventure", (sc, in) -> !((PlayerEntity) in[0].get(sc)).abilities.allowEdit);
-        sm.registerFunction("player.setfly", (sc, in) -> {
-            PlayerEntity p = ((PlayerEntity) in[0].get(sc));
-            boolean b = in[1].getBoolean(sc);
-            p.abilities.allowFlying = b;
-            p.abilities.isFlying = b;
-            p.sendPlayerAbilities();
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.hasfly", (sc, in) -> ((PlayerEntity) in[0].get(sc)).abilities.allowFlying);
-        sm.registerFunction("player.isflying", (sc, in) -> ((PlayerEntity) in[0].get(sc)).abilities.isFlying);
-        sm.registerFunction("player.setgamemode", (sc, in) -> {
-            PlayerEntity p = (PlayerEntity) in[0].get(sc);
-            switch(in[1].get(sc).toString()) {
-                case "survival":
-                case "s":
-                case "0":
-                    p.setGameType(GameType.SURVIVAL);
-                    break;
-                case "creative":
-                case "c":
-                case "1":
-                    p.setGameType(GameType.CREATIVE);
-                    break;
-                case "adventure":
-                case "a":
-                case "2":
-                    p.setGameType(GameType.ADVENTURE);
-                    break;
-                case "spectator":
-                case "w":
-                case "3":
-                    p.setGameType(GameType.SPECTATOR);
-                    break;
-                default:
-                    p.setGameType(GameType.CREATIVE);
-                    break;
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.getlastdamager", (sc, in) -> {
-            DamageSource ds = ((PlayerEntity) in[0].get(sc)).getLastDamageSource();
-            if(ds == null) {
-                return null;
-            }
-            return ds.getImmediateSource();
-        });
-        sm.registerFunction("player.dropinventory", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).inventory.dropAllItems();
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.gettarget", (sc, in) -> {
-            PlayerEntity p = (PlayerEntity) in[0].get(sc);
-
-            double radius = in[1].getDouble(sc);
-            if(radius > 128.0) {
-                radius = 128.0;
-            }
-
-            RayTraceContext.BlockMode bm = RayTraceContext.BlockMode.OUTLINE;
-            if(in.length >= 3 && in[2].getBoolean(sc)) {
-                bm = RayTraceContext.BlockMode.COLLIDER;
-            }
-            RayTraceContext.FluidMode fm = RayTraceContext.FluidMode.NONE;
-            if(in.length >= 4 && in[3].getBoolean(sc)) {
-                fm = RayTraceContext.FluidMode.ANY;
-            }
-
-            Vec3d start = p.getEyePosition(0.0f);
-            Vec3d unit = p.getLook(0.0f);
-            Vec3d end = start.add(unit.x * radius, unit.y * radius, unit.z * radius);
-
-            BlockRayTraceResult result = p.world.rayTraceBlocks(new RayTraceContext(start, end, bm, fm, p));
-
-            if(result.getType() == RayTraceResult.Type.BLOCK) {
-                return new Location(p.world, result.getPos());
-            }
-
-            return new Location(p.world, end);
-        });
-
-        sm.registerFunction("player.gettargetentity", (sc, in) -> Utils.getTargetedEntity((PlayerEntity) in[0].get(sc), in[1].getDouble(sc), getClass(in[2].getString(sc))));
-        sm.registerFunction("player.hasscript", (sc, in) -> scripts.isRegistered((PlayerEntity) in[0].get(sc)));
-        sm.registerAlias("player.hasscript", "player.hasquest");
-        sm.registerFunction("player.action", (sc, in) -> {
-            StringTextComponent text = new StringTextComponent(SnuviUtils.connect(sc, in, 1));
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ServerPlayerEntity) p).sendStatusMessage(text, true));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.disconnect", (sc, in) -> {
-            ((ServerPlayerEntity) in[0].get(sc)).connection.disconnect(new StringTextComponent(in[1].getString(sc)));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.kick", (sc, in) -> scripts.unregisterPlayer(sc, (PlayerEntity) in[0].get(sc)));
-        sm.registerFunction("player.getspawn", (sc, in) -> {
-            ServerWorld ws = (ServerWorld) in[1].get(sc);
-            return new Location(ws, ((PlayerEntity) in[0].get(sc)).getBedLocation(ws.getDimension().getType()));
-        });
-        sm.registerAlias("player.getspawn", "player.getbedspawn");
-        sm.registerFunction("player.setspawn", (sc, in) -> {
-            Location l = (Location) in[1].get(sc);
-            ((ServerPlayerEntity) in[0].get(sc)).setSpawnPoint(l.getBlockPos(), true, false, l.getWorld().getDimension().getType());
-            return Void.TYPE;
-        });
-        sm.registerAlias("player.setspawn", "player.setbedspawn");
-        sm.registerFunction("player.damageitem", (sc, in) -> {
-            PlayerEntity p = (PlayerEntity) in[0].get(sc);
-            p.getHeldItemMainhand().damageItem(in[1].getInt(sc), p, (c) -> {
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.damagearmor", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).inventory.damageArmor(in[1].getFloat(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.openenderchest", (sc, in) -> {
-            PlayerEntity p1 = (PlayerEntity) in[0].get(sc);
-            PlayerEntity p2 = (PlayerEntity) in[1].get(sc);
-
-            EnderChestInventory inv = p2.getInventoryEnderChest();
-            p1.openContainer(new SimpleNamedContainerProvider((id, pInv, p) -> {
-                return ChestContainer.createGeneric9X3(id, pInv, inv);
-            }, new StringTextComponent(in[2].getString(sc))));
-
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.getlevel", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).experienceLevel);
-        sm.registerFunction("player.getexp", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).experience);
-        sm.registerFunction("player.addlevel", (sc, in) -> {
-            PlayerEntity p = (PlayerEntity) in[0].get(sc);
-            p.addExperienceLevel(in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.setexp", (sc, in) -> {
-            PlayerEntity p = (PlayerEntity) in[0].get(sc);
-            float f = in[1].getFloat(sc);
-            if(f < 0.0f) {
-                f = 0.0f;
-            } else if(f > 1.0f) {
-                f = 1.0f;
-            }
-            p.giveExperiencePoints((int) (f * p.xpBarCap()));
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.gethead", (sc, in) -> {
-            ItemStack stack = new ItemStack(Items.PLAYER_HEAD);
-            CompoundNBT com = stack.getOrCreateTag();
-            GameProfile gp = new GameProfile(getUUID(in[0].get(sc)), in[1].getString(sc));
-            gp = SkullTileEntity.updateGameProfile(gp);
-            com.put("SkullOwner", NBTUtil.writeGameProfile(new CompoundNBT(), gp));
-            return stack;
-        });
-        sm.registerFunction("player.setspeed", (sc, in) -> {
-            PlayerEntity p = (PlayerEntity) in[0].get(sc);
-            float f = in[1].getFloat(sc);
-            ReflectionUtils.setFlySpeed(p.abilities, f);
-            ReflectionUtils.setWalkSpeed(p.abilities, f * 2);
-            p.sendPlayerAbilities();
-            return true;
-        });
-        sm.registerFunction("player.near", (sc, in) -> Utils.getPlayers((Entity) in[0].get(sc), in[1].getDouble(sc)));
-        sm.registerFunction("player.getinvslot", (sc, in) -> ((PlayerEntity) in[0].get(sc)).inventory.mainInventory.get(in[1].getInt(sc)));
-        sm.registerFunction("player.setinvslot", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).inventory.mainInventory.set(in[1].getInt(sc), ((ItemStack) in[2].get(sc)).copy());
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.getenderslot", (sc, in) -> ((PlayerEntity) in[0].get(sc)).getInventoryEnderChest().getStackInSlot(in[1].getInt(sc)));
-        sm.registerFunction("player.setenderslot", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).getInventoryEnderChest().setInventorySlotContents(in[1].getInt(sc), ((ItemStack) in[2].get(sc)).copy());
-            return Void.TYPE;
-        });
-        sm.registerFunction("player.setdisplayname", (sc, in) -> {
-            ((ModEntityPlayerMP) in[0].get(sc)).setTabListDisplayName(in[1].getString(sc), scheduler);
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // Players-library
-        // --------------------------------------------------------------------- 
-        sm.registerFunction("players.getamount", (sc, in) -> (double) server.getCurrentPlayerCount());
-        sm.registerFunction("players.tolist", (sc, in) -> new ArrayList(server.getPlayerList().getPlayers()));
-        sm.registerFunction("players.toworldlist", (sc, in) -> new ArrayList(((World) in[0].get(sc)).getPlayers()));
-        sm.registerFunction("players.near", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return Utils.getPlayers(l.getWorld(), l.getX(), l.getY(), l.getZ(), in[1].getDouble(sc));
-        });
-
-        // ---------------------------------------------------------------------    
-        // World-library
-        // ---------------------------------------------------------------------
-        sm.registerAlias("players.toworldlist", "world.getplayers");
-        sm.registerFunction("world.register", (sc, in) -> WorldManager.register(in[0].getString(sc)));
-        sm.registerFunction("world.unregister", (sc, in) -> WorldManager.unregister(server, in[0].getString(sc)));
-        sm.registerFunction("world.get", (sc, in) -> {
-            return WorldManager.get(server, in[0].getString(sc));
-        });
-        sm.registerFunction("world.getname", (sc, in) -> {
-            return WorldManager.getName((World) in[0].get(sc));
-        });
-        sm.registerFunction("world.setdiffi", (sc, in) -> {
-            Difficulty diffi = Difficulty.valueOf(in[1].getString(sc).toUpperCase());
-            ((World) in[0].get(sc)).getWorldInfo().setDifficulty(diffi);
-            return Void.TYPE;
-        });
-        sm.registerFunction("world.setgamerule", (sc, in) -> {
-            Object o = ((World) in[0].get(sc)).getGameRules().get(Mapper.getGameRule(in[1].getString(sc)));
-            if(o instanceof GameRules.BooleanValue) {
-                ((GameRules.BooleanValue) o).set(in[2].getBoolean(sc), server);
-            }
-            if(o instanceof GameRules.IntegerValue) {
-                ReflectionUtils.setIntegerValue((GameRules.IntegerValue) o, in[2].getInt(sc));
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("world.getgamerule", (sc, in) -> {
-            Object o = ((World) in[0].get(sc)).getGameRules().get(Mapper.getGameRule(in[1].getString(sc)));
-            if(o instanceof GameRules.BooleanValue) {
-                return ((GameRules.BooleanValue) o).get();
-            }
-            if(o instanceof GameRules.IntegerValue) {
-                return (double) ((GameRules.IntegerValue) o).get();
-            }
-            return null;
-        });
-        sm.registerFunction("world.setspawn", (sc, in) -> {
-            Location l = ((Location) in[0].get(sc));
-            l.getWorld().getDimension().setSpawnPoint(l.getBlockPos());
-            return Void.TYPE;
-        });
-        sm.registerFunction("world.getspawn", (sc, in) -> {
-            World w = (World) in[0].get(sc);
-            return new Location(w, w.getSpawnPoint());
-        });
-        sm.registerFunction("world.getall", (sc, in) -> {
-            ArrayList<World> worlds = new ArrayList<>();
-            for(World w : server.getWorlds()) {
-                worlds.add(w);
-            }
-            return worlds;
-        });
-        sm.registerFunction("world.settime", (sc, in) -> {
-            ((World) in[0].get(sc)).setDayTime(in[1].getLong(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("world.gettime", (sc, in) -> (double) ((World) in[0].get(sc)).getDayTime());
-        sm.registerFunction("world.hasstorm", (sc, in) -> ((World) in[0].get(sc)).isRaining());
-        sm.registerFunction("world.clearweather", (sc, in) -> {
-            WorldInfo wi = ((World) in[0].get(sc)).getWorldInfo();
-            wi.setClearWeatherTime(in[1].getInt(sc));
-            wi.setRainTime(0);
-            wi.setThunderTime(0);
-            wi.setRaining(false);
-            wi.setThundering(false);
-            return Void.TYPE;
-        });
-        sm.registerFunction("world.setrain", (sc, in) -> {
-            WorldInfo wi = ((World) in[0].get(sc)).getWorldInfo();
-            wi.setClearWeatherTime(0);
-            int i = in[1].getInt(sc);
-            wi.setRainTime(i);
-            wi.setThunderTime(i);
-            wi.setRaining(true);
-            wi.setThundering(false);
-            return Void.TYPE;
-        });
-        sm.registerFunction("world.setthunder", (sc, in) -> {
-            WorldInfo wi = ((World) in[0].get(sc)).getWorldInfo();
-            wi.setClearWeatherTime(0);
-            int i = in[1].getInt(sc);
-            wi.setRainTime(i);
-            wi.setThunderTime(i);
-            wi.setRaining(true);
-            wi.setThundering(true);
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // Item-library   
-        // ---------------------------------------------------------------------   
-        sm.registerFunction("item.drop", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            World w = l.getWorld().getWorld();
-            BlockPos pos = l.getBlockPos();
-            ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
-            int amount = stack.getCount();
-            while(amount > stack.getMaxStackSize()) {
-                stack.setCount(stack.getMaxStackSize());
-                amount -= stack.getMaxStackSize();
-                Block.spawnAsEntity(w, pos, stack.copy());
-            }
-            if(amount > 0) {
-                stack.setCount(amount);
-                Block.spawnAsEntity(w, pos, stack);
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.gettag", (sc, in) -> ItemTags.getCollection().get(new ResourceLocation(in[0].getString(sc))));
-        sm.registerFunction("item.hastag", (sc, in) -> ((Tag<Item>) in[0].get(sc)).contains(((ItemStack) in[1].get(sc)).getItem()));
-        sm.registerFunction("item.get", (sc, in) -> ((ItemStack) in[0].get(sc)).getItem());
-        sm.registerFunction("item.gettype", (sc, in) -> ((ItemStack) in[0].get(sc)).getItem().getRegistryName().toString());
-        sm.registerFunction("item.getamount", (sc, in) -> (double) ((ItemStack) in[0].get(sc)).getCount());
-        sm.registerFunction("item.setamount", (sc, in) -> {
-            ((ItemStack) in[0].get(sc)).setCount(in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.getname", (sc, in) -> ((ItemStack) in[0].get(sc)).getDisplayName().getFormattedText());
-        sm.registerFunction("item.setname", (sc, in) -> {
-            ((ItemStack) in[0].get(sc)).setDisplayName(new StringTextComponent(SnuviUtils.connect(sc, in, 1)));
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.getlore", (sc, in) -> {
-            return ItemStackUtils.getLore((ItemStack) in[0].get(sc));
-        });
-        sm.registerFunction("item.setlore", (sc, in) -> {
-            ItemStackUtils.setLore((ItemStack) in[0].get(sc), (List<Object>) in[1].get(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.addlore", (sc, in) -> {
-            ItemStackUtils.addLore((ItemStack) in[0].get(sc), SnuviUtils.connect(sc, in, 2), in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.addenchant", (sc, in) -> {
-            ItemStack stack = (ItemStack) in[0].get(sc);
-            Enchantment ench = Mapper.getEnchantment(in[1].getString(sc));
-            int i = in[2].getInt(sc);
-            stack.addEnchantment(ench, i);
-            return true;
-        });
-        sm.registerFunction("item.getenchantlevel", (sc, in) -> (double) EnchantmentHelper.getEnchantmentLevel(Mapper.getEnchantment(in[1].getString(sc)), (ItemStack) in[0].get(sc)));
-        sm.registerFunction("item.setcooldown", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).getCooldownTracker().setCooldown(((ItemStack) in[1].get(sc)).getItem(), in[2].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.addpotion", (sc, in) -> {
-            ItemStack stack = (ItemStack) in[0].get(sc);
-            List<EffectInstance> list = PotionUtils.getEffectsFromStack(stack);
-            list.add(new EffectInstance(Mapper.getPotion(in[1].getString(sc)), in[2].getInt(sc), in[3].getInt(sc)));
-            PotionUtils.appendEffects(stack, list);
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.addflag", (sc, in) -> {
-            ItemStackUtils.addItemFlag((ItemStack) in[0].get(sc), ItemStackUtils.ItemFlag.valueOf(in[1].getString(sc).toUpperCase()));
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.addattribute", (sc, in) -> {
-            ItemStackUtils.addAttribute((ItemStack) in[0].get(sc),
-                    ItemStackUtils.Attribute.valueOf(in[1].getString(sc).toUpperCase()),
-                    EquipmentSlotType.valueOf(in[2].getString(sc).toUpperCase()),
-                    in[3].getDouble(sc),
-                    Operation.valueOf(in[4].getString(sc).toUpperCase()));
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.setmagic", (sc, in) -> {
-            ItemStack stack = (ItemStack) in[0].get(sc);
-            int value = in[1].getInt(sc);
-            if(stack.getItem() instanceof ArmorItem) {
-                CompoundNBT com = stack.getTag();
-                if(com == null) {
-                    com = new CompoundNBT();
-                    stack.setTag(com);
-                }
-                com.putInt("magic", value);
-            } else {
-                throw new IllegalArgumentException("magic resistance is only for armor");
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("item.clone", (sc, in) -> ((ItemStack) in[0].get(sc)).copy());
-
-        // ---------------------------------------------------------------------    
-        // Location-library
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("loc.new", (sc, in) -> {
-            if(in.length >= 6) {
-                return new Location((World) in[0].get(sc),
-                        in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc),
-                        in[4].getFloat(sc), in[5].getFloat(sc));
-            }
-            return new Location((World) in[0].get(sc), in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc), 0, 0);
-        });
-        sm.registerFunction("loc.getx", (sc, in) -> ((Location) in[0].get(sc)).getX());
-        sm.registerFunction("loc.gety", (sc, in) -> ((Location) in[0].get(sc)).getY());
-        sm.registerFunction("loc.getz", (sc, in) -> ((Location) in[0].get(sc)).getZ());
-        sm.registerFunction("loc.setx", (sc, in) -> {
-            ((Location) in[0].get(sc)).setX(in[1].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.sety", (sc, in) -> {
-            ((Location) in[0].get(sc)).setY(in[1].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.setz", (sc, in) -> {
-            ((Location) in[0].get(sc)).setZ(in[1].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.addx", (sc, in) -> {
-            ((Location) in[0].get(sc)).addX(in[1].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.addy", (sc, in) -> {
-            ((Location) in[0].get(sc)).addY(in[1].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.addz", (sc, in) -> {
-            ((Location) in[0].get(sc)).addZ(in[1].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.setyaw", (sc, in) -> {
-            ((Location) in[0].get(sc)).setYaw(in[1].getFloat(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.getyaw", (sc, in) -> (double) ((Location) in[0].get(sc)).getYaw());
-        sm.registerFunction("loc.setpitch", (sc, in) -> {
-            ((Location) in[0].get(sc)).setPitch(in[1].getFloat(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("loc.getpitch", (sc, in) -> (double) ((Location) in[0].get(sc)).getPitch());
-        sm.registerFunction("loc.getworld", (sc, in) -> ((Location) in[0].get(sc)).getWorld());
-        sm.registerFunction("loc.distance", (sc, in) -> ((Location) in[0].get(sc)).getPos().distanceTo(((Location) in[1].get(sc)).getPos()));
-        sm.registerFunction("loc.mod", (sc, in) -> ((Location) in[0].get(sc)).copyAdd(in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc)));
-        sm.registerFunction("loc.getcoord", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            switch(in[1].getString(sc)) {
-                case "x":
-                    return l.getX();
-                case "y":
-                    return l.getY();
-                case "z":
-                    return l.getZ();
-                case "bx":
-                    return (double) MathHelper.floor(l.getX());
-                case "by":
-                    return (double) MathHelper.floor(l.getY());
-                case "bz":
-                    return (double) MathHelper.floor(l.getZ());
-                case "w":
-                    return WorldManager.getName(l.getWorld());
-                default:
-                    return null;
-            }
-        });
-        sm.registerFunction("loc.isbetween", (sc, in) -> {
-            Location l1 = (Location) in[0].get(sc);
-            Location l2 = (Location) in[1].get(sc);
-            Location l3 = (Location) in[2].get(sc);
-            return l1.getX() >= Math.min(l2.getX(), l3.getX()) && l1.getX() <= Math.max(l2.getX(), l3.getX())
-                    && l1.getY() >= Math.min(l2.getY(), l3.getY()) && l1.getY() <= Math.max(l2.getY(), l3.getY())
-                    && l1.getZ() >= Math.min(l2.getZ(), l3.getZ()) && l1.getZ() <= Math.max(l2.getZ(), l3.getZ());
-        });
-        sm.registerFunction("loc.sort", (sc, in) -> {
-            Location l1 = (Location) in[0].get(sc);
-            Location l2 = (Location) in[1].get(sc);
-
-            if(l1.getX() > l2.getX()) {
-                double tmp = l1.getX();
-                l1.setX(l2.getX());
-                l2.setX(tmp);
-            }
-
-            if(l1.getY() > l2.getY()) {
-                double tmp = l1.getY();
-                l1.setY(l2.getY());
-                l2.setY(tmp);
-            }
-
-            if(l1.getZ() > l2.getZ()) {
-                double tmp = l1.getZ();
-                l1.setZ(l2.getZ());
-                l2.setZ(tmp);
-            }
-
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // Block-library
-        // ---------------------------------------------------------------------    
-        sm.registerFunction("block.gettag", (sc, in) -> BlockTags.getCollection().get(new ResourceLocation(in[0].getString(sc))));
-        sm.registerFunction("block.hastag", (sc, in) -> ((Tag<Block>) in[0].get(sc)).contains((Block) in[1].get(sc)));
-        sm.registerFunction("block.gettype", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return l.getWorld().getBlockState(l.getBlockPos()).getBlock().getRegistryName().toString();
-        });
-        sm.registerFunction("block.get", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return l.getWorld().getBlockState(l.getBlockPos()).getBlock();
-        });
-        sm.registerFunction("block.getproperty", (sc, in) -> Mapper.getProperty(in[0].getString(sc)));
-        sm.registerFunction("block.getstate", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            IProperty prop = (IProperty) in[1].get(sc);
-            BlockState state = l.getWorld().getBlockState(l.getBlockPos());
-            if(state.has(prop)) {
-                Object o = l.getWorld().getBlockState(l.getBlockPos()).get(prop);
-                if(o instanceof Number) {
-                    return ((Number) o).doubleValue();
-                } else if(o instanceof Boolean) {
-                    return o;
-                }
-                return o.toString();
-            }
-            return null;
-        });
-        sm.registerFunction("block.clone", (sc, in) -> {
-            Location l0 = (Location) in[0].get(sc);
-            Location l1 = (Location) in[1].get(sc);
-
-            IWorld w0 = l0.getWorld();
-            BlockPos pos0 = l0.getBlockPos();
-            BlockState state = w0.getBlockState(pos0);
-            TileEntity tileEnt0 = w0.getTileEntity(pos0);
-
-            IWorld w1 = l1.getWorld();
-            BlockPos pos1 = l1.getBlockPos();
-            w1.setBlockState(pos1, state, 2);
-            TileEntity tileEnt1 = w1.getTileEntity(pos1);
-            if(tileEnt0 != null && tileEnt1 != null) {
-                CompoundNBT nbt = tileEnt0.write(new CompoundNBT());
-                nbt.putInt("x", pos1.getX());
-                nbt.putInt("y", pos1.getY());
-                nbt.putInt("z", pos1.getZ());
-                tileEnt1.read(nbt);
-                tileEnt1.markDirty();
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("block.set", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            BlockStateParser parser = new BlockStateParser(new StringReader(in[1].getString(sc)), true);
-            BlockState state = parser.parse(true).getState();
-            int flag = 2;
-            if(in.length >= 3 && in[2].getBoolean(sc)) {
-                flag |= 16;
-            }
-            l.getWorld().setBlockState(l.getBlockPos(), state, flag);
-            return Void.TYPE;
-        });
-        sm.registerFunction("block.setsign", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            SignTileEntity sign = (SignTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
-            sign.signText[in[1].getInt(sc)] = new StringTextComponent(SnuviUtils.connect(sc, in, 2));
-
-            SUpdateTileEntityPacket packet = sign.getUpdatePacket();
-            World w = sign.getWorld();
-            if(w != null) {
-                w.getPlayers().stream().filter(p -> p instanceof ServerPlayerEntity)
-                        .forEach(p -> ((ServerPlayerEntity) p).connection.sendPacket(packet));
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("block.getsign", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            SignTileEntity sign = (SignTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
-            return sign.signText[in[1].getInt(sc)].getString();
-        });
-        sm.registerFunction("block.setdoorstatus", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            BlockPos pos = l.getBlockPos();
-            ((DoorBlock) l.getWorld().getBlockState(pos).getBlock()).toggleDoor(l.getWorld().getWorld(), pos, in[1].getBoolean(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("block.getdoorstatus", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return l.getBlockState().get(DoorBlock.OPEN);
-        });
-        sm.registerFunction("block.isdoor", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return l.getWorld().getBlockState(l.getBlockPos()).getBlock() instanceof DoorBlock;
-        });
-        sm.registerFunction("block.issolid", (sc, in) -> {
-            BlockState state = getBlockState((Location) in[0].get(sc));
-            return state.isSolid();
-        });
-        sm.registerFunction("block.tostack", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return new ItemStack(l.getBlockState().getBlock().asItem());
-        });
-        sm.registerFunction("block.getitemamount", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
-            if(te == null || !(te instanceof ChestTileEntity)) {
-                return 0.0d;
-            }
-            return (double) InventoryUtils.searchInventoryFor((ChestTileEntity) te, (ItemStack) in[2].get(sc), in[1].getBoolean(sc));
-        });
-        sm.registerFunction("block.getsecchest", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            BlockPos pos = l.getBlockPos();
-            BlockState state = l.getWorld().getBlockState(pos);
-            ChestType chesttype = state.get(ChestBlock.TYPE);
-            if(chesttype == ChestType.SINGLE) {
-                return null;
-            }
-            Direction dir = ChestBlock.getDirectionToAttached(state);
-            return l.copyAdd(dir.getXOffset(), dir.getYOffset(), dir.getZOffset());
-        });
-        sm.registerFunction("block.additem", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            ItemStack stack = ((ItemStack) in[1].get(sc));
-            TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
-            if(te == null || !(te instanceof ChestTileEntity)) {
-                return stack;
-            }
-            stack.setCount(InventoryUtils.addToInventory((ChestTileEntity) te, stack));
-            return stack;
-        });
-        sm.registerFunction("block.subitem", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            ItemStack stack = ((ItemStack) in[1].get(sc));
-            TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
-            if(te == null || !(te instanceof ChestTileEntity)) {
-                return stack;
-            }
-            stack.setCount(InventoryUtils.removeFromInventory((ChestTileEntity) te, stack));
-            return stack;
-        });
-        sm.registerFunction("block.grow", (sc, in) -> {
-            Location l1 = (Location) in[0].get(sc);
-            World w = l1.getWorld().getWorld();
-            BlockPos pos1 = l1.getBlockPos();
-            BlockPos pos2 = ((Location) in[1].get(sc)).getBlockPos();
-
-            int x = Math.min(pos1.getX(), pos2.getX());
-            int endX = Math.max(pos1.getX(), pos2.getX());
-
-            int y = Math.min(pos1.getY(), pos2.getY());
-            int endY = Math.max(pos1.getY(), pos2.getY());
-
-            int z = Math.min(pos1.getZ(), pos2.getZ());
-            int endZ = Math.max(pos1.getZ(), pos2.getZ());
-
-            if(endX - x > 50 || endY - y > 50 || endZ - z > 50) {
-                throw new IllegalArgumentException("uhh, that area seems way to big for growing plants");
-            }
-
-            BlockPos relative;
-            BlockState state;
-            for(; x <= endX; x++) {
-                for(; y <= endY; y++) {
-                    for(; z <= endZ; z++) {
-                        relative = new BlockPos(x, y, z);
-                        state = w.getBlockState(relative);
-                        if(state.getBlock() instanceof CropsBlock) {
-                            w.setBlockState(relative, state.with(CropsBlock.AGE, 7));
-                        }
-                    }
-                }
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("block.setspawnertype", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            MobSpawnerTileEntity spawner = (MobSpawnerTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
-            spawner.getSpawnerBaseLogic().setEntityType(EntityType.byKey(in[1].getString(sc)).get());
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // Event-library 
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("event.addmovedata", (sc, in) -> {
-            UUID uuid = in.length >= 5 ? getUUID(in[4].get(sc)) : null;
-            PlayerMoveData pmd = new PlayerMoveData(sc, (Location) in[0].get(sc), (Location) in[1].get(sc), in[2].getInt(sc), in[3].getInt(sc), uuid);
-            return (double) cec.registerMoveData(pmd);
-        });
-        sm.registerFunction("event.removemovedata", (sc, in) -> {
-            cec.removeMoveData(in[0].getInt(sc));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // damage stuff
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("damage.getimmediatesource", (sc, in) -> ((DamageSource) in[0].get(sc)).getImmediateSource());
-        sm.registerFunction("damage.gettruesource", (sc, in) -> ((DamageSource) in[0].get(sc)).getTrueSource());
-        sm.registerFunction("damage.iscreativeplayer", (sc, in) -> ((DamageSource) in[0].get(sc)).isCreativePlayer());
-        sm.registerFunction("damage.isabsolute", (sc, in) -> ((DamageSource) in[0].get(sc)).isDamageAbsolute());
-        sm.registerFunction("damage.isdifficultyscaled", (sc, in) -> ((DamageSource) in[0].get(sc)).isDifficultyScaled());
-        sm.registerFunction("damage.isexplosion", (sc, in) -> ((DamageSource) in[0].get(sc)).isExplosion());
-        sm.registerFunction("damage.isfire", (sc, in) -> ((DamageSource) in[0].get(sc)).isFireDamage());
-        sm.registerFunction("damage.ismagic", (sc, in) -> ((DamageSource) in[0].get(sc)).isMagicDamage());
-        sm.registerFunction("damage.isprojectile", (sc, in) -> ((DamageSource) in[0].get(sc)).isProjectile());
-        sm.registerFunction("damage.isunblockable", (sc, in) -> ((DamageSource) in[0].get(sc)).isUnblockable());
-        sm.registerFunction("damage.gettype", (sc, in) -> ((DamageSource) in[0].get(sc)).getDamageType());
-        sm.registerFunction("damage.get", (sc, in) -> {
-            Object o = in[0].get(sc);
-            if(o instanceof LivingEntity) {
-                LivingEntity ent = (LivingEntity) o;
-                DamageSource ds;
-                if(ent instanceof PlayerEntity) {
-                    ds = DamageSource.causePlayerDamage((PlayerEntity) ent);
-                } else {
-                    ds = DamageSource.causeMobDamage(ent);
-                }
-
-                if(in[1].getBoolean(sc)) {
-                    ds.setDamageAllowedInCreativeMode();
-                }
-                if(in[2].getBoolean(sc)) {
-                    ds.setDamageBypassesArmor();
-                }
-                if(in[3].getBoolean(sc)) {
-                    ds.setDamageIsAbsolute();
-                }
-                if(in[4].getBoolean(sc)) {
-                    ds.setExplosion();
-                }
-                if(in[5].getBoolean(sc)) {
-                    ds.setFireDamage();
-                }
-                if(in[6].getBoolean(sc)) {
-                    ds.setMagicDamage();
-                }
-                if(in[7].getBoolean(sc)) {
-                    ds.setProjectile();
-                }
-                return ds;
-            }
-
-            switch(o.toString()) {
-                case "inFire":
-                    return DamageSource.IN_FIRE;
-                case "lightningBolt":
-                    return DamageSource.LIGHTNING_BOLT;
-                case "onFire":
-                    return DamageSource.ON_FIRE;
-                case "lava":
-                    return DamageSource.LAVA;
-                case "hotFloor":
-                    return DamageSource.HOT_FLOOR;
-                case "inWall":
-                    return DamageSource.IN_WALL;
-                case "cramming":
-                    return DamageSource.CRAMMING;
-                case "drown":
-                    return DamageSource.DROWN;
-                case "starve":
-                    return DamageSource.STARVE;
-                case "cactus":
-                    return DamageSource.CACTUS;
-                case "fall":
-                    return DamageSource.FALL;
-                case "flyIntoWall":
-                    return DamageSource.FLY_INTO_WALL;
-                case "outOfWorld":
-                    return DamageSource.OUT_OF_WORLD;
-                case "generic":
-                    return DamageSource.GENERIC;
-                case "magic":
-                    return DamageSource.MAGIC;
-                case "wither":
-                    return DamageSource.WITHER;
-                case "anvil":
-                    return DamageSource.ANVIL;
-                case "fallingBlock":
-                    return DamageSource.FALLING_BLOCK;
-                case "dragonBreath":
-                    return DamageSource.DRAGON_BREATH;
-                case "fireworks":
-                    return DamageSource.FIREWORKS;
-                case "dryout":
-                    return DamageSource.DRYOUT;
-                case "sweetBerryBush":
-                    return DamageSource.SWEET_BERRY_BUSH;
-                case "thorns":
-                    return DamageSource.causeThornsDamage((Entity) in[1].get(sc));
-            }
-            return DamageSource.GENERIC;
-        });
-
-        // ---------------------------------------------------------------------    
-        // entity commands
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("entity.setnopickup", (sc, in) -> {
-            ((AbstractArrowEntity) in[0].get(sc)).pickupStatus = AbstractArrowEntity.PickupStatus.DISALLOWED;
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.shootprojectile", (sc, in) -> launchProjectile((LivingEntity) in[0].get(sc),
-                getClass(in[1].getString(sc)), in[2].getDouble(sc), in.length >= 4 ? in[3].get(sc) : null));
-        sm.registerFunction("entity.isblocking", (sc, in) -> ((LivingEntity) in[0].get(sc)).isActiveItemStackBlocking());
-        sm.registerFunction("entity.getarmorthoughness", (sc, in) -> ((LivingEntity) in[0].get(sc)).getAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS).getValue());
-        sm.registerFunction("entity.getarmor", (sc, in) -> (double) ((LivingEntity) in[0].get(sc)).getTotalArmorValue());
-        sm.registerFunction("entity.getmagicarmor", (sc, in) -> {
-            int level = 0;
-            for(ItemStack stack : ((LivingEntity) in[0].get(sc)).getArmorInventoryList()) {
-                CompoundNBT com = stack.getTag();
-                if(com != null && com.contains("magic")) {
-                    level += com.getInt("magic");
-                }
-            }
-            return level;
-        });
-        sm.registerFunction("entity.getenchantmentmodifier", (sc, in) -> EnchantmentHelper.getEnchantmentModifierDamage(((LivingEntity) in[0].get(sc)).getArmorInventoryList(), (DamageSource) in[1].get(sc)));
-        sm.registerFunction("entity.setburning", (sc, in) -> {
-            ((Entity) in[0].get(sc)).setFire(in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.isburning", (sc, in) -> ((Entity) in[0].get(sc)).isBurning());
-        sm.registerFunction("entity.getlook", (sc, in) -> {
-            Object[] o = new Object[3];
-            Vec3d v = ((Entity) in[0].get(sc)).getLookVec();
-            o[0] = v.x;
-            o[1] = v.y;
-            o[2] = v.z;
-            return o;
-        });
-        sm.registerFunction("entity.getlocation", (sc, in) -> new Location((Entity) in[0].get(sc)));
-        sm.registerFunction("entity.damage", (sc, in) -> {
-            LivingEntity liv = (LivingEntity) in[0].get(sc);
-            float damage = in[1].getFloat(sc);
-            DamageSource damageSource = (in.length >= 3) ? (DamageSource) in[2].get(sc) : DamageSource.GENERIC;
-            scheduler.scheduleTask(() -> liv.attackEntityFrom(damageSource, damage));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.damagedirect", (sc, in) -> {
-            LivingEntity liv = (LivingEntity) in[0].get(sc);
-            float damageAmount = in[1].getFloat(sc);
-            DamageSource ds = (DamageSource) in[2].get(sc);
-            if(!liv.isInvulnerableTo(ds)) {
-                float f2 = Math.max(damageAmount - liv.getAbsorptionAmount(), 0.0F);
-                liv.setAbsorptionAmount(liv.getAbsorptionAmount() - (damageAmount - f2));
-                float absorbedDamage = damageAmount - f2;
-                if(absorbedDamage > 0.0f && absorbedDamage < 3.4028235E37f && ds.getTrueSource() instanceof ServerPlayerEntity) {
-                    ((ServerPlayerEntity) ds.getTrueSource()).addStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(absorbedDamage * 10.0f));
-                }
-
-                if(f2 > 0.0f) {
-                    float f1 = liv.getHealth();
-                    liv.getCombatTracker().trackDamage(ds, f1, f2);
-                    liv.setHealth(f1 - f2);
-                    liv.setAbsorptionAmount(liv.getAbsorptionAmount() - f2);
-                }
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.fromsource", (sc, in) -> {
-            DamageSource ds = (DamageSource) in[0].get(sc);
-            Entity ent = ds.getTrueSource();
-            if(ent == null) {
-                return ds.getImmediateSource();
-            }
-            return ent;
-        });
-        sm.registerAlias("damage.get", "entity.getdamagesource");
-        sm.registerFunction("entity.gethealth", (sc, in) -> (double) ((LivingEntity) in[0].get(sc)).getHealth());
-        sm.registerFunction("entity.sethealth", (sc, in) -> {
-            ((LivingEntity) in[0].get(sc)).setHealth(in[1].getFloat(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.setname", (sc, in) -> {
-            Entity ent = (Entity) in[0].get(sc);
-            ent.setCustomName(new StringTextComponent(in[1].getString(sc)));
-            if(in.length >= 3) {
-                ent.setCustomNameVisible(in[2].getBoolean(sc));
-                return Void.TYPE;
-            }
-            ent.setCustomNameVisible(false);
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.getname", (sc, in) -> ((Entity) in[0].get(sc)).getDisplayName().getFormattedText());
-        sm.registerFunction("entity.throw", (sc, in) -> {
-            Entity ent = (Entity) in[0].get(sc);
-            ent.setMotion(in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc));
-            ent.velocityChanged = true;
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.teleport", (sc, in) -> {
-            Entity ent = (Entity) in[0].get(sc);
-            Location l = (Location) in[1].get(sc);
-            if(l.getWorld() == null) {
-                throw new IllegalArgumentException("world must not be null");
-            }
-            if(ent instanceof ServerPlayerEntity) {
-                ServerPlayerEntity p = (ServerPlayerEntity) ent;
-
-                p.stopRiding();
-                if(p.isSleeping()) {
-                    p.func_225652_a_(true, true);
-                }
-
-                float yaw = l.getYaw() != 0.0f ? l.getYaw() : ent.rotationYaw;
-                float pitch = l.getPitch() != 0.0f ? l.getPitch() : ent.rotationPitch;
-                p.teleport((ServerWorld) l.getWorld(), l.getX(), l.getY(), l.getZ(), yaw, pitch);
-            } else {
-                if(ent.world != l.getWorld()) {
-                    ServerWorld ws = (ServerWorld) l.getWorld();
-                    ent.changeDimension(ws.getDimension().getType());
-                }
-                if(l.getYaw() != 0 && l.getPitch() != 0) {
-                    ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
-                } else {
-                    ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch);
-                }
-            }
-
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.setequip", (sc, in) -> {
-            LivingEntity liv = (LivingEntity) in[0].get(sc);
-            ItemStack stack = ((ItemStack) in[2].get(sc)).copy();
-            switch(in[1].getString(sc)) {
-                case "hand":
-                    liv.setItemStackToSlot(EquipmentSlotType.MAINHAND, stack);
-                    return Void.TYPE;
-                case "head":
-                    liv.setItemStackToSlot(EquipmentSlotType.HEAD, stack);
-                    return Void.TYPE;
-                case "chest":
-                    liv.setItemStackToSlot(EquipmentSlotType.CHEST, stack);
-                    return Void.TYPE;
-                case "legs":
-                    liv.setItemStackToSlot(EquipmentSlotType.LEGS, stack);
-                    return Void.TYPE;
-                case "feet":
-                    liv.setItemStackToSlot(EquipmentSlotType.FEET, stack);
-                    return Void.TYPE;
-                case "offhand":
-                    liv.setItemStackToSlot(EquipmentSlotType.OFFHAND, stack);
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.getequip", (sc, in) -> {
-            LivingEntity liv = (LivingEntity) in[0].get(sc);
-            switch(in[1].getString(sc)) {
-                case "hand":
-                    return liv.getItemStackFromSlot(EquipmentSlotType.MAINHAND);
-                case "head":
-                    return liv.getItemStackFromSlot(EquipmentSlotType.HEAD);
-                case "chest":
-                    return liv.getItemStackFromSlot(EquipmentSlotType.CHEST);
-                case "legs":
-                    return liv.getItemStackFromSlot(EquipmentSlotType.LEGS);
-                case "feet":
-                    return liv.getItemStackFromSlot(EquipmentSlotType.FEET);
-                case "offhand":
-                    return liv.getItemStackFromSlot(EquipmentSlotType.OFFHAND);
-            }
-            return ItemStack.EMPTY;
-        });
-        sm.registerFunction("entity.removeall", (sc, in) -> {
-            Class<? extends Entity> c = (Class<? extends Entity>) getClass(in[0].getString(sc));
-            if(c == Entity.class) {
-                return Void.TYPE;
-            }
-            Location l = (Location) in[1].get(sc);
-            Utils.getEntities(l.getWorld(), l.getX(), l.getY(), l.getZ(), in[2].getDouble(sc), c).stream().forEach(ent -> {
-                ent.remove();
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.remove", (sc, in) -> {
-            ((Entity) in[0].get(sc)).remove();
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.setinvulnerable", (sc, in) -> {
-            ((Entity) in[0].get(sc)).setInvulnerable(in[1].getBoolean(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.setsilent", (sc, in) -> {
-            ((Entity) in[0].get(sc)).setSilent(in[1].getBoolean(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.setinvisible", (sc, in) -> {
-            ((Entity) in[0].get(sc)).setInvisible(in[1].getBoolean(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.ride", (sc, in) -> {
-            ((Entity) in[0].get(sc)).startRiding(((Entity) in[1].get(sc)));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.addeffect", (sc, in) -> {
-            LivingEntity base = (LivingEntity) in[0].get(sc);
-            Effect potion = Mapper.getPotion(in[1].getString(sc));
-            if(potion == null) // doing this only to prevent EffectInstance doing shit
-            {
-                throw new IllegalArgumentException("potion does not exist");
-            }
-            if(base.isPotionActive(potion)) {
-                base.removePotionEffect(potion);
-            }
-            base.addPotionEffect(new EffectInstance(potion, in[2].getInt(sc), in[3].getInt(sc)));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.cleareffects", (sc, in) -> {
-            ((LivingEntity) in[0].get(sc)).clearActivePotions();
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.geteffectamplifier", (sc, in) -> {
-            EffectInstance effect = ((LivingEntity) in[0].get(sc)).getActivePotionEffect(Mapper.getPotion(in[1].getString(sc)));
-            return effect == null ? 0 : effect.getAmplifier() + 1;
-        });
-        sm.registerFunction("entity.spawnitemframe", (sc, in) -> {
-            Location l = ((Location) in[0].get(sc));
-            ItemFrameEntity frame = new ItemFrameEntity(l.getWorld().getWorld(), l.getBlockPos(), Direction.byName(in[1].getString(sc)));
-            frame.setDisplayedItem(((ItemStack) in[2].get(sc))); // copy happens in internals
-            l.getWorld().addEntity(frame);
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.getitemfromframe", (sc, in) -> ((ItemFrameEntity) in[0].get(sc)).getDisplayedItem());
-        sm.registerFunction("entity.get", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return Utils.getEntity(l.getWorld(), l.getX(), l.getY(), l.getZ(), in[1].getDouble(sc), getClass(in[2].getString(sc)));
-        });
-        sm.registerFunction("entity.getpotiontype", (sc, in) -> PotionUtils.getPotionFromItem(((PotionEntity) in[0].get(sc)).getItem()).getRegistryName().toString());
-        sm.registerFunction("entity.setgravity", (sc, in) -> {
-            ((Entity) in[0].get(sc)).setNoGravity(!in[1].getBoolean(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.iswet", (sc, in) -> ((Entity) in[0].get(sc)).isWet());
-        sm.registerFunction("entity.setpickupdelay", (sc, in) -> {
-            ((ItemEntity) in[0].get(sc)).setPickupDelay(in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.setage", (sc, in) -> {
-            ReflectionUtils.setAge((ItemEntity) in[0].get(sc), in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.spawn", (sc, in) -> {
-            ResourceLocation rl = new ResourceLocation(in[0].getString(sc));
-            Location l = (Location) in[1].get(sc);
-            ServerWorld sw = (ServerWorld) l.getWorld();
-
-            CompoundNBT compoundnbt = in.length >= 3 ? JsonToNBT.getTagFromJson(in[2].getString(sc)) : new CompoundNBT();
-            compoundnbt.putString("id", rl.toString());
-            if(EntityType.getKey(EntityType.LIGHTNING_BOLT).equals(rl)) {
-                LightningBoltEntity ent = new LightningBoltEntity(sw, l.getX(), l.getY(), l.getZ(), false);
-                sw.addLightningBolt(ent);
-                return ent;
-            }
-
-            Entity entity = EntityType.func_220335_a(compoundnbt, sw, (ent) -> {
-                ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch);
-                return sw.summonEntity(ent) ? ent : null;
-            });
-            if(entity != null && entity instanceof MobEntity) {
-                ((MobEntity) entity).onInitialSpawn(sw, sw.getDifficultyForLocation(new BlockPos(entity)), SpawnReason.COMMAND, null, null);
-            }
-            return entity;
-        });
-        sm.registerFunction("entity.near", (sc, in) -> Utils.getLiving((Entity) in[0].get(sc), in[1].getDouble(sc)));
-        sm.registerFunction("entity.setspeed", (sc, in) -> {
-            ((LivingEntity) in[0].get(sc)).getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(in[1].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.setgrowingage", (sc, in) -> {
-            ((AgeableEntity) in[0].get(sc)).setGrowingAge(in[1].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("entity.gettype", (sc, in) -> ((Entity) in[0].get(sc)).getType().getRegistryName().getPath());
-        sm.registerFunction("entity.issneaking", (sc, in) -> ((Entity) in[0].get(sc)).isCrouching());
-        sm.registerFunction("sheep.issheared", (sc, in) -> ((SheepEntity) in[0].get(sc)).getSheared());
-        sm.registerFunction("sheep.getcolor", (sc, in) -> ((SheepEntity) in[0].get(sc)).getFleeceColor().getName());
-        sm.registerFunction("creeper.explode", (sc, in) -> {
-            ((CreeperEntity) in[0].get(sc)).ignite();
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // human commands
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("human.spawn", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            World w = l.getWorld().getWorld();
-            EntityHuman h = ModEntities.HUMAN.create(w);
-            h.setPosition(l.getX(), l.getY(), l.getZ());
-            w.addEntity(h);
-            return h;
-        });
-        sm.registerFunction("human.setskin", (sc, in) -> {
-            ((EntityHuman) in[0].get(sc)).setSkinName(in[1].getString(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("human.setscale", (sc, in) -> {
-            ((EntityHuman) in[0].get(sc)).setScale(in[1].getFloat(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("human.setslim", (sc, in) -> {
-            ((EntityHuman) in[0].get(sc)).setSlim(in[1].getBoolean(sc));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // GMap-library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("gmap.removeall", (sc, in) -> {
-            final String map = in[0].getString(sc);
-            scheduler.getWorker().add(() -> {
-                try {
-                    scriptBank.removeMap(map);
-                } catch(Exception ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("gmap.add", (sc, in) -> {
-            final String map = in[0].getString(sc);
-            final String key = in[1].getString(sc);
-            final String value = in[2].getString(sc);
-            scheduler.getWorker().add(() -> {
-                try {
-                    scriptBank.addMapElement(map, key, value);
-                } catch(Exception ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("gmap.remove", (sc, in) -> {
-            final String map = in[0].getString(sc);
-            final String key = in[1].getString(sc);
-            scheduler.getWorker().add(() -> {
-                try {
-                    scriptBank.removeMapElement(map, key);
-                } catch(Exception ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("gmap.get", (sc, in) -> scriptBank.getMapValue(in[0].getString(sc), in[1].getString(sc)));
-        sm.registerFunction("gmap.getordefault", (sc, in) -> {
-            Object o = scriptBank.getMapValue(in[0].getString(sc), in[1].getString(sc));
-            if(o == null) {
-                return in[2].get(sc);
-            }
-            return o;
-        });
-
-        // ---------------------------------------------------------------------  
-        // GDMap-library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("gdmap.removeall", (sc, in) -> {
-            if(in.length >= 2) {
-                final String map = in[0].getString(sc);
-                final String key = in[1].getString(sc);
-                scheduler.getWorker().add(() -> {
-                    try {
-                        scriptBank.removeDualMapElement(map, key);
-                    } catch(Exception ex) {
-                        scheduler.scheduleTask(() -> {
-                            sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                        });
-                    }
-                });
-            } else {
-                final String map = in[0].getString(sc);
-                scheduler.getWorker().add(() -> {
-                    try {
-                        scriptBank.removeDualMap(map);
-                    } catch(Exception ex) {
-                        scheduler.scheduleTask(() -> {
-                            sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                        });
-                    }
-                });
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("gdmap.add", (sc, in) -> {
-            final String map = in[0].getString(sc);
-            final String key1 = in[1].getString(sc);
-            final String key2 = in[2].getString(sc);
-            final String value = in[3].getString(sc);
-            scheduler.getWorker().add(() -> {
-                try {
-                    scriptBank.addDualMapElement(map, key1, key2, value);
-                } catch(Exception ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("gdmap.remove", (sc, in) -> {
-            final String map = in[0].getString(sc);
-            final String key1 = in[1].getString(sc);
-            final String key2 = in[2].getString(sc);
-            scheduler.getWorker().add(() -> {
-                try {
-                    scriptBank.removeDualMapElement(map, key1, key2);
-                } catch(Exception ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("gdmap.get", (sc, in) -> {
-            return scriptBank.getDualMapValue(in[0].getString(sc), in[1].getString(sc), in[2].getString(sc));
-        });
-        sm.registerFunction("gdmap.getordefault", (sc, in) -> {
-            Object o = scriptBank.getDualMapValue(in[0].getString(sc), in[1].getString(sc), in[2].getString(sc));
-            if(o == null) {
-                return in[3].get(sc);
-            }
-            return o;
-        });
-
-        // ---------------------------------------------------------------------  
-        // databank library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("databank.prepare", (sc, in) -> {
-            PreparedStatement p = dataBank.prepareUnsafeStatement(in[0].getString(sc));
-            if(in.length <= 1 || in[1].getBoolean(sc)) {
-                sc.addCloseable(p);
-            }
-            return p;
-        });
-        sm.registerFunction("databank.setint", (sc, in) -> {
-            ((PreparedStatement) in[0].get(sc)).setInt(in[1].getInt(sc), in[2].getInt(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("databank.setlong", (sc, in) -> {
-            ((PreparedStatement) in[0].get(sc)).setLong(in[1].getInt(sc), in[2].getLong(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("databank.setdouble", (sc, in) -> {
-            ((PreparedStatement) in[0].get(sc)).setDouble(in[1].getInt(sc), in[2].getDouble(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("databank.setstring", (sc, in) -> {
-            ((PreparedStatement) in[0].get(sc)).setString(in[1].getInt(sc), in[2].getString(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("databank.setbool", (sc, in) -> {
-            ((PreparedStatement) in[0].get(sc)).setBoolean(in[1].getInt(sc), in[2].getBoolean(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("databank.getint", (sc, in) -> (double) ((ResultSet) in[0].get(sc)).getInt(in[1].getInt(sc)));
-        sm.registerFunction("databank.getlong", (sc, in) -> (double) ((ResultSet) in[0].get(sc)).getLong(in[1].getInt(sc)));
-        sm.registerFunction("databank.getdouble", (sc, in) -> ((ResultSet) in[0].get(sc)).getDouble(in[1].getInt(sc)));
-        sm.registerFunction("databank.getstring", (sc, in) -> ((ResultSet) in[0].get(sc)).getString(in[1].getInt(sc)));
-        sm.registerFunction("databank.getbool", (sc, in) -> ((ResultSet) in[0].get(sc)).getBoolean(in[1].getInt(sc)));
-        sm.registerFunction("databank.execute", (sc, in) -> ((PreparedStatement) in[0].get(sc)).executeQuery());
-        sm.registerFunction("databank.workerexecute", (sc, in) -> {
-            final PreparedStatement p = (PreparedStatement) in[0].get(sc);
-            scheduler.getWorker().add(() -> {
-                try {
-                    p.execute();
-                } catch(SQLException ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-                sc.removeCloseable(p);
-                try {
-                    p.close();
-                } catch(SQLException ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerFunction("databank.next", (sc, in) -> ((ResultSet) in[0].get(sc)).next());
-        sm.registerFunction("databank.close", (sc, in) -> {
-            AutoCloseable auto = (AutoCloseable) in[0].get(sc);
-            auto.close();
-            sc.removeCloseable(auto);
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // Plot-library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("plot.get", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            return plots.getPlots(l.getWorld(), l.getBlockPos());
-        });
-        sm.registerFunction("plot.check", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            ModEntityPlayerMP p = (ModEntityPlayerMP) in[1].get(sc);
-            int flags = in[2].getInt(sc);
-            boolean empty = in[3].getBoolean(sc);
-            return plots.canDoSomething(l.getWorld(), l.getBlockPos(), p, flags, empty);
-        });
-        sm.registerFunction("plot.setflags", (sc, in) -> {
-            Plot p = (Plot) in[0].get(sc);
-            p.setFlag(in[1].getInt(sc), in[2].getBoolean(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("plot.hasflags", (sc, in) -> ((Plot) in[0].get(sc)).hasFlags(in[1].getInt(sc)));
-        sm.registerFunction("plot.getflags", (sc, in) -> (double) ((Plot) in[0].get(sc)).getFlags());
-        sm.registerFunction("plot.getowners", (sc, in) -> ((Plot) in[0].get(sc)).getOwners());
-        sm.registerFunction("plot.add", (sc, in) -> {
-            Location l1 = (Location) in[0].get(sc);
-            Location l2 = (Location) in[1].get(sc);
-            if(l1.getWorld() != l2.getWorld()) {
-                throw new IllegalArgumentException("worlds not equal for locations");
-            }
-            return plots.add(l1.getWorld(), l1.getBlockPos(), l2.getBlockPos());
-        });
-        sm.registerFunction("plot.remove", (sc, in) -> {
-            plots.remove((IWorld) in[1].get(sc), (Plot) in[0].get(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("plot.getname", (sc, in) -> ((Plot) in[0].get(sc)).getName());
-        sm.registerFunction("plot.setname", (sc, in) -> {
-            ((Plot) in[0].get(sc)).setName(in[1].getString(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("plot.getid", (sc, in) -> (double) ((Plot) in[0].get(sc)).getId());
-        sm.registerFunction("plot.iterator", (sc, in) -> {
-            IWorld word = (IWorld) in[0].get(sc);
-            if(in.length >= 2) {
-                plots.getIterator(word, getUUID(in[1].get(sc)));
-            }
-            return plots.getIterator(word);
-        });
-        sm.registerFunction("plot.intersecting", (sc, in) -> plots.getIntersectingPlots((IWorld) in[0].get(sc), in[1].getInt(sc),
-                in[2].getInt(sc), in[3].getInt(sc), in[4].getInt(sc),
-                in[5].getInt(sc), in[6].getInt(sc)));
-
-        sm.registerFunction("plot.getminx", (sc, in) -> (double) ((Plot) in[0].get(sc)).getMinX());
-        sm.registerFunction("plot.getminy", (sc, in) -> (double) ((Plot) in[0].get(sc)).getMinY());
-        sm.registerFunction("plot.getminz", (sc, in) -> (double) ((Plot) in[0].get(sc)).getMinZ());
-        sm.registerFunction("plot.getmaxx", (sc, in) -> (double) ((Plot) in[0].get(sc)).getMaxX());
-        sm.registerFunction("plot.getmaxy", (sc, in) -> (double) ((Plot) in[0].get(sc)).getMaxY());
-        sm.registerFunction("plot.getmaxz", (sc, in) -> (double) ((Plot) in[0].get(sc)).getMaxZ());
-
-        // ---------------------------------------------------------------------  
-        // block protection library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("protect.hasaccess", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            BlockPos pos = l.getBlockPos();
-            return blockProtection.hasAccess(pos, l.getWorld(), (ModEntityPlayerMP) in[1].get(sc));
-        });
-
-        // ---------------------------------------------------------------------  
-        // Script-library   
-        // ---------------------------------------------------------------------    
-        sm.registerFunction("script.playerstolist", (sc, in) -> new ArrayList<>(scripts.getPlayerList(sc.getId())));
-        sm.registerFunction("script.getplayeramount", (sc, in) -> (double) scripts.getPlayerList(sc.getId()).size());
-        sm.registerFunction("script.start", (sc, in) -> {
-            Object o = in[0].get(sc);
-            if(o instanceof PlayerEntity) {
-                String[] names = new String[in.length - 1];
-                for(int i = 1; i < in.length; i++) {
-                    names[i - 1] = in[i].getString(sc);
-                }
-                return scripts.startPlayerScript((PlayerEntity) in[0].get(sc), names);
-            }
-            String[] names = new String[in.length];
-            names[0] = o.toString();
-            for(int i = 1; i < in.length; i++) {
-                names[i] = in[i].getString(sc);
-            }
-            scripts.startScript(names);
-            return true;
-        });
-        sm.registerFunction("script.join", (sc, in) -> scripts.registerPlayer((Script) in[0].get(sc), (PlayerEntity) in[1].get(sc)));
-        sm.registerFunction("script.kick", (sc, in) -> scripts.unregisterPlayer(sc, (PlayerEntity) in[0].get(sc)));
-        sm.registerFunction("script.getleader", (sc, in) -> {
-            List<UUID> players = scripts.getPlayerList(sc.getId());
-            if(players.isEmpty()) {
-                return null;
-            }
-            return server.getPlayerList().getPlayerByUUID(players.get(0));
-        });
-
-        // ---------------------------------------------------------------------  
-        // Scoreboard-library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("sb.add", (sc, in) -> {
-            int id = in[1].getInt(sc);
-            String message = SnuviUtils.connect(sc, in, 2);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ModEntityPlayerMP) p).getScoreboard().addText(id, message));
-            return Void.TYPE;
-        });
-        sm.registerFunction("sb.remove", (sc, in) -> {
-            int id = in[1].getInt(sc);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ModEntityPlayerMP) p).getScoreboard().removeText(id));
-            return Void.TYPE;
-        });
-        sm.registerFunction("sb.reset", (sc, in) -> {
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ModEntityPlayerMP) p).getScoreboard().clear((ModEntityPlayerMP) p));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // Display-library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("display.add", (sc, in) -> {
-            byte id = in[1].getByte(sc);
-            String message = SnuviUtils.connect(sc, in, 2);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToDisplay((ServerPlayerEntity) p, (byte) 1, id, message));
-            return Void.TYPE;
-        });
-        sm.registerFunction("display.remove", (sc, in) -> {
-            byte id = in[1].getByte(sc);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToDisplay((ServerPlayerEntity) p, (byte) 2, id, ""));
-            return Void.TYPE;
-        });
-        sm.registerFunction("display.reset", (sc, in) -> {
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToDisplay((ServerPlayerEntity) p, (byte) 3, (byte) -1, ""));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // status - library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("status.add", (sc, in) -> {
-            byte index = in[1].getByte(sc);
-            String message = SnuviUtils.connect(sc, in, 2);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.addStatus((ServerPlayerEntity) p, index, message));
-            return Void.TYPE;
-        });
-        sm.registerFunction("status.addtimed", (sc, in) -> {
-            byte index = in[1].getByte(sc);
-            int time = in[2].getInt(sc);
-            String message = SnuviUtils.connect(sc, in, 3);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.addTimedStatus((ServerPlayerEntity) p, index, message, time));
-            return Void.TYPE;
-        });
-        sm.registerFunction("status.remove", (sc, in) -> {
-            byte index = in[1].getByte(sc);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.removeStatus((ServerPlayerEntity) p, index));
-            return Void.TYPE;
-        });
-        sm.registerFunction("status.reset", (sc, in) -> {
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.clearStatus((ServerPlayerEntity) p));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // ItemStack-Display-library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("stacks.set", (sc, in) -> {
-            byte index = in[1].getByte(sc);
-            if(index < 0 || index >= 9) {
-                throw new IllegalArgumentException("index must be beetween 0 and 8, given: " + index);
-            }
-            int iconIndex = in[2].getInt(sc);
-            int count = in[3].getInt(sc);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.setItemStackIndex((ServerPlayerEntity) p, index, iconIndex, count));
-            return Void.TYPE;
-        });
-        sm.registerFunction("stacks.clearindex", (sc, in) -> {
-            byte index = in[1].getByte(sc);
-            if(index < 0 || index >= 9) {
-                throw new IllegalArgumentException("index must be beetween 0 and 8, given: " + index);
-            }
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.setItemStackIndex((ServerPlayerEntity) p, index, -1, 0));
-            return Void.TYPE;
-        });
-        sm.registerFunction("stacks.clear", (sc, in) -> {
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.clearItemStacks((ServerPlayerEntity) p));
-            return Void.TYPE;
-        });
-        sm.registerFunction("stacks.setactive", (sc, in) -> {
-            boolean active = in[1].getBoolean(sc);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.setItemStackActive((ServerPlayerEntity) p, active));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // Head-library   
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("head.add", (sc, in) -> {
-            byte id = in[1].getByte(sc);
-            String name = in[2].getString(sc);
-            int x = in[3].getInt(sc);
-            int y = in[4].getInt(sc);
-            byte scale = in[5].getByte(sc);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToHead((ServerPlayerEntity) p, (byte) 1, id, name, x, y, scale));
-            return Void.TYPE;
-        });
-        sm.registerFunction("head.remove", (sc, in) -> {
-            byte id = in[1].getByte(sc);
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToHead((ServerPlayerEntity) p, (byte) 2, id, "", -1, -1, (byte) -1));
-            return Void.TYPE;
-        });
-        sm.registerFunction("head.reset", (sc, in) -> {
-            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToHead((ServerPlayerEntity) p, (byte) 3, (byte) -1, "", -1, -1, (byte) -1));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // particle library   
-        // --------------------------------------------------------------------- 
-        sm.registerFunction("particle.get", (sc, in) -> {
-            IParticleData data = Mapper.getParticle(in[0].getString(sc));
-            if(data == ParticleTypes.BLOCK || data == ParticleTypes.FALLING_DUST) {
-                data = new BlockParticleData((ParticleType<BlockParticleData>) data, Mapper.getBlock(in[1].getString(sc)).getDefaultState());
-            } else if(data == ParticleTypes.DUST) {
-                data = new RedstoneParticleData(in[1].getFloat(sc), in[2].getFloat(sc), in[3].getFloat(sc), in[4].getFloat(sc));
-            } else if(data == ParticleTypes.ITEM) {
-                data = new ItemParticleData((ParticleType<ItemParticleData>) data, new ItemStack(Mapper.getItem(in[1].getString(sc))));
-            }
-            return data;
-        });
-        sm.registerFunction("particle.spawn", (sc, in) -> {
-            Location l = ((Location) in[0].get(sc));
-            IParticleData data = ((IParticleData) in[1].get(sc));
-            int count = in.length >= 3 ? in[2].getInt(sc) : 1;
-            double speed = in.length >= 4 ? in[3].getDouble(sc) : 0.0;
-            double offX = in.length >= 5 ? in[4].getDouble(sc) : 0.0;
-            double offY = in.length >= 6 ? in[5].getDouble(sc) : 0.0;
-            double offZ = in.length >= 7 ? in[6].getDouble(sc) : 0.0;
-            ((ServerWorld) l.getWorld()).spawnParticle(data, l.getX(), l.getY(), l.getZ(), count, offX, offY, offZ, speed);
-            return Void.TYPE;
-        });
-        sm.registerFunction("particle.spawncircle", (sc, in) -> {
-            Location l = ((Location) in[0].get(sc));
-            IParticleData data = ((IParticleData) in[1].get(sc));
-            int instances = in[2].getInt(sc);
-            double radius = in[3].getDouble(sc);
-            int count = in.length >= 5 ? in[4].getInt(sc) : 1;
-            double speed = in.length >= 6 ? in[5].getDouble(sc) : 0.0;
-            double offX = in.length >= 7 ? in[6].getDouble(sc) : 0.0;
-            double offY = in.length >= 8 ? in[7].getDouble(sc) : 0.0;
-            double offZ = in.length >= 9 ? in[8].getDouble(sc) : 0.0;
-            double x = l.getX();
-            double y = l.getY();
-            double z = l.getZ();
-            ServerWorld sw = (ServerWorld) l.getWorld();
-            double angle = 2 * Math.PI / instances;
-            for(int i = 0; i < instances; i++) {
-                sw.spawnParticle(data, x + Math.cos(i * angle) * radius, y, z + Math.sin(i * angle) * radius, count, offX, offY, offZ, speed);
-            }
-            return Void.TYPE;
-        });
-        sm.registerFunction("particle.spawnline", (sc, in) -> {
-            Location l = ((Location) in[0].get(sc));
-            IParticleData data = ((IParticleData) in[1].get(sc));
-            int instances = in[2].getInt(sc);
-            double stepX = in[3].getDouble(sc);
-            double stepY = in[4].getDouble(sc);
-            double stepZ = in[5].getDouble(sc);
-
-            int count = in.length >= 7 ? in[6].getInt(sc) : 1;
-            double speed = in.length >= 8 ? in[7].getDouble(sc) : 0.0;
-            double offX = in.length >= 9 ? in[8].getDouble(sc) : 0.0;
-            double offY = in.length >= 10 ? in[9].getDouble(sc) : 0.0;
-            double offZ = in.length >= 11 ? in[10].getDouble(sc) : 0.0;
-            double x = l.getX();
-            double y = l.getY();
-            double z = l.getZ();
-            ServerWorld sw = (ServerWorld) l.getWorld();
-            for(int i = 0; i < instances; i++) {
-                sw.spawnParticle(data, x + i * stepX, y + i * stepY, z + i * stepZ, count, offX, offY, offZ, speed);
-            }
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // particle library   
-        // --------------------------------------------------------------------- 
-        sm.registerFunction("sound.get", (sc, in) -> Mapper.getSound(in[0].getString(sc)));
-        sm.registerFunction("sound.getcategory", (sc, in) -> Mapper.getSoundCategory(in[0].getString(sc)));
-        sm.registerFunction("sound.spawn", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            ServerWorld sw = (ServerWorld) l.getWorld();
-            float volume = in.length >= 4 ? in[3].getFloat(sc) : 1.0f;
-            float pitch = in.length >= 5 ? in[4].getFloat(sc) : (sw.rand.nextFloat() * 0.1f + 0.9f);
-            sw.playSound(null, l.getX(), l.getY(), l.getZ(), (SoundEvent) in[1].get(sc), (SoundCategory) in[2].get(sc), volume, pitch);
-            return Void.TYPE;
-        });
-        sm.registerFunction("sound.spawnforplayer", (sc, in) -> {
-            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
-            float volume = in.length >= 4 ? in[3].getFloat(sc) : 1.0f;
-            float pitch = in.length >= 5 ? in[4].getFloat(sc) : (p.world.rand.nextFloat() * 0.1f + 0.9f);
-            p.connection.sendPacket(new SPlaySoundEffectPacket((SoundEvent) in[1].get(sc),
-                    (SoundCategory) in[2].get(sc), p.getPosX(), p.getPosY(), p.getPosZ(), volume, pitch));
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // Inventory-library   
-        // ---------------------------------------------------------------------
-        sm.registerFunction("inv.new", (sc, in) -> new ModInventory(in[0].getString(sc)));
-        sm.registerFunction("inv.getid", (sc, in) -> (double) ((ModInventory) in[0].get(sc)).getModId());
-        sm.registerFunction("inv.loadblock", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            ChestTileEntity chest = (ChestTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
-            int size = chest.getSizeInventory();
-            if(size % 9 != 0) {
-                size /= 9;
-                size++;
-                size *= 9;
-            }
-            ModInventory inv = new ModInventory(size);
-            for(int i = 0; i < chest.getSizeInventory(); i++) {
-                inv.setInventorySlotContents(i, chest.getStackInSlot(i).copy());
-            }
-            return inv;
-        });
-        sm.registerFunction("inv.setitem", (sc, in) -> {
-            ((IInventory) in[0].get(sc)).setInventorySlotContents(in[1].getInt(sc), (ItemStack) in[2].get(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("inv.getitem", (sc, in) -> ((IInventory) in[0].get(sc)).getStackInSlot(in[1].getInt(sc)));
-        sm.registerFunction("inv.open", (sc, in) -> {
-            CustomContainer.openForPlayer((ServerPlayerEntity) in[1].get(sc), (ModInventory) in[0].get(sc), in[2].getString(sc), sc);
-            return Void.TYPE;
-        });
-        sm.registerFunction("inv.close", (sc, in) -> {
-            ((PlayerEntity) in[0].get(sc)).closeScreen();
-            return Void.TYPE;
-        });
-        sm.registerFunction("inv.update", (sc, in) -> {
-            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
-            NonNullList<ItemStack> list = NonNullList.<ItemStack>create();
-            int size = p.openContainer.inventorySlots.size();
-            for(int j = 0; j < size; j++) {
-                ItemStack itemstack = p.openContainer.inventorySlots.get(j).getStack();
-                list.add(itemstack.isEmpty() ? ItemStack.EMPTY : itemstack);
-            }
-            p.sendAllContents(p.openContainer, list);
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------  
-        // Read-library   
-        // ---------------------------------------------------------------------
-        sm.registerFunction("read.player", (sc, in) -> Utils.getPlayerByName(server, in[0].getString(sc)));
-        sm.registerFunction("read.location", (sc, in) -> new Location(server, in[0].getString(sc)));
-        sm.registerFunction("read.item", (sc, in) -> {
-            String s = in[0].getString(sc);
-            if(s.startsWith("{")) {
-                String left = SnuviUtils.connect(sc, in, 1);
-                return ItemStackUtils.getStackFromNbtString(s + left);
-            }
-            Item item = Mapper.getItem(s);
-            int amount = in.length >= 2 ? in[1].getInt(sc) : 1;
-            ItemStack stack = new ItemStack(item, amount);
-            if(in.length >= 3) {
-                stack.setDisplayName(new StringTextComponent(in[2].getString(sc)));
-            }
-            if(in.length >= 4) {
-                for(int i = 3; i < in.length; i++) {
-                    ItemStackUtils.addLore(stack, in[i].getString(sc));
-                }
-            }
-            return stack;
-        });
-        sm.registerFunction("read.spawnmob", (sc, in) -> {
-            Location l = (Location) in[0].get(sc);
-            ServerWorld sw = (ServerWorld) l.getWorld();
-            CompoundNBT compoundnbt = JsonToNBT.getTagFromJson(SnuviUtils.connect(sc, in, 1));
-            Entity entity = EntityType.func_220335_a(compoundnbt, sw, (ent) -> {
-                ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch);
-                return sw.summonEntity(ent) ? ent : null;
-            });
-            return entity;
-        });
-
-        // ---------------------------------------------------------------------  
-        // Text-library   
-        // ---------------------------------------------------------------------
-        sm.registerFunction("text.location", (sc, in) -> ((Location) in[0].get(sc)).toString());
-        sm.registerFunction("text.locationblock", (sc, in) -> ((Location) in[0].get(sc)).toBlockString());
-        sm.registerFunction("text.item", (sc, in) -> ItemStackUtils.getNbtString((ItemStack) in[0].get(sc)));
-        sm.registerFunction("text.click", (sc, in) -> {
-            Object message = in[0].get(sc);
-            ITextComponent text;
-            if(message instanceof ITextComponent) {
-                text = (ITextComponent) message;
-            } else {
-                text = new StringTextComponent(String.valueOf(message));
-            }
-            Style style = text.getStyle();
-            style.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, in[1].getString(sc)));
-            return text;
-        });
-        sm.registerFunction("text.hover", (sc, in) -> {
-            Object message = in[0].get(sc);
-            ITextComponent text;
-            if(message instanceof ITextComponent) {
-                text = (ITextComponent) message;
-            } else {
-                text = new StringTextComponent(String.valueOf(message));
-            }
-            Style style = text.getStyle();
-            style.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new StringTextComponent(in[1].getString(sc))));
-            return text;
-        });
-        sm.registerFunction("text.link", (sc, in) -> {
-            StringTextComponent text = new StringTextComponent(in[0].getString(sc));
-            Style style = text.getStyle();
-            style.setColor(TextFormatting.RED);
-            style.setBold(true);
-            style.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, in[1].getString(sc)));
-            return text;
-        });
-        sm.registerFunction("text.copytext", (sc, in) -> {
-            String s = in[1].getString(sc);
-            //s = s.replace('{', 'Ɛ');
-            //s = s.replace('}', 'Ƒ');
-            //s = s.replace('[', 'ƒ');
-            //s = s.replace(']', 'Ɠ');
-            //s = s.replace('(', 'ƕ');
-            //s = s.replace(')', 'Ɩ');
-            s = s.replace(" ", "%20");
-            //s = s.replace('\'', 'Ɩ');
-            //s = s.replace('"', 'Ɩ');
-            //s = s.replace("\\", "");
-
-            StringTextComponent text = new StringTextComponent(in[0].getString(sc));
-            Style style = text.getStyle();
-            style.setColor(TextFormatting.RED);
-            style.setBold(true);
-            style.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "http://minecraft.hammerle.me/showtext.php/?text=" + s));
-            return text;
-        });
-        sm.registerFunction("text.entity", (sc, in) -> {
-            CompoundNBT tag = new CompoundNBT();
-            ((Entity) in[0].get(sc)).writeWithoutTypeId(tag);
-            return tag.toString();
-        });
-
-        // ---------------------------------------------------------------------    
-        // worker library
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("worker.haswork", (sc, in) -> scheduler.getWorker().hasWork());
-
-        // ---------------------------------------------------------------------    
-        // ban library
-        // ---------------------------------------------------------------------  
-        sm.registerFunction("ban.kick", (sc, in) -> {
-            ((ServerPlayerEntity) in[0].get(sc)).connection.disconnect(new StringTextComponent(in[1].getString(sc)));
-            return Void.TYPE;
-        });
-        sm.registerFunction("ban.add", (sc, in) -> {
-            GameProfile gp = server.getPlayerProfileCache().getProfileByUUID(getUUID(in[0].get(sc)));
-            String reason = in[1].getString(sc);
-            String banner = in[2].getString(sc);
-            ProfileBanEntry entry;
-            if(in.length >= 4) {
-                GregorianCalendar calender = (GregorianCalendar) in[3].get(sc);
-                Date d = new Date(calender.getTimeInMillis());
-                entry = new ProfileBanEntry(gp, null, banner, d, reason);
-            } else {
-                entry = new ProfileBanEntry(gp, null, banner, null, reason);
-            }
-            server.getPlayerList().getBannedPlayers().addEntry(entry);
-            return Void.TYPE;
-        });
-        sm.registerFunction("ban.remove", (sc, in) -> {
-            GameProfile gp = server.getPlayerProfileCache().getProfileByUUID(getUUID(in[0].get(sc)));
-            server.getPlayerList().getBannedPlayers().removeEntry(gp);
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // player data
-        // ---------------------------------------------------------------------   
-        sm.registerFunction("data.set", (sc, in) -> {
-            ((ModEntityPlayerMP) in[0].get(sc)).setVar(in[1].getString(sc), in[2].get(sc));
-            return Void.TYPE;
-        });
-        sm.registerFunction("data.settimer", (sc, in) -> {
-            ((ModEntityPlayerMP) in[0].get(sc)).setTimer(in[1].getString(sc), in[2].getInt(sc), scheduler);
-            return Void.TYPE;
-        });
-        sm.registerFunction("data.get", (sc, in) -> {
-            return ((ModEntityPlayerMP) in[0].get(sc)).getVar(in[1].getString(sc));
-        });
-        sm.registerFunction("data.gettimer", (sc, in) -> {
-            return (double) ((ModEntityPlayerMP) in[0].get(sc)).getTimer(in[1].getString(sc));
-        });
-        sm.registerFunction("data.clear", (sc, in) -> {
-            ((ModEntityPlayerMP) in[0].get(sc)).clearData(scheduler);
-            return Void.TYPE;
-        });
-
-        // ---------------------------------------------------------------------    
-        // no library
-        // ---------------------------------------------------------------------   
-        sm.registerFunction("setmotd", (sc, in) -> {
-            server.getServerStatusResponse().setServerDescription(new StringTextComponent(in[0].getString(sc)));
-            return Void.TYPE;
-        });
-        sm.registerFunction("getglobalvar", (sc, in) -> {
-            Object o = in[0].get(sc);
-            if(in.length == 2) {
-                return scriptBank.getVar(in[1].getString(sc), getId(playerBank, o));
-            }
-            return scriptBank.getVar(in[1].getString(sc), getId(playerBank, o), in[2].get(sc));
-        });
-        sm.registerAlias("getglobalvar", "ggv");
-        sm.registerFunction("setglobalvar", (sc, in) -> {
-            final String value = in[2].getString(sc);
-            final String var = in[1].getString(sc);
-            final int id = getId(playerBank, in[0].get(sc));
-            scheduler.getWorker().add(() -> {
-                try {
-                    scriptBank.setVar(value, var, id);
-                } catch(Exception ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerAlias("setglobalvar", "sgv");
-        sm.registerFunction("delglobalvar", (sc, in) -> {
-            final String var = in[1].getString(sc);
-            final int id = getId(playerBank, in[0].get(sc));
-            scheduler.getWorker().add(() -> {
-                try {
-                    scriptBank.deleteVar(var, id);
-                } catch(Exception ex) {
-                    scheduler.scheduleTask(() -> {
-                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, -1);
-                    });
-                }
-            });
-            return Void.TYPE;
-        });
-        sm.registerAlias("delglobalvar", "dgv");
-        sm.registerFunction("msg", (sc, in) -> {
-            sendMessageToGroup(server, scripts, perms, in[0].get(sc), sc, concat(sc, 1, "", in));
-            return Void.TYPE;
-        });
-        sm.registerFunction("removeformat", (sc, in) -> SnuviUtils.connect(sc, in, 0).replaceAll("§.", ""));
-        sm.registerFunction("command", (sc, in) -> {
-            final String s = SnuviUtils.connect(sc, in, 0);
-            scheduler.scheduleTask(() -> commands.handleCommand(server.getCommandSource(), s));
-            return Void.TYPE;
-        });
-        sm.registerFunction("isplayer", (sc, in) -> {
-            Object o = in[0].get(sc);
-            return o != null && o instanceof PlayerEntity;
-        });
-    }
-
-    private static Class getClass(String s) throws ClassNotFoundException {
-        return Class.forName(s);
-    }
-
-    private static BlockState getBlockState(Location l) {
-        return l.getWorld().getBlockState(l.getBlockPos());
-    }
-
-    private final static UUID SERVER_UUID = new UUID(0, 0);
-
-    private static UUID getUUID(Object o) {
-        if(o instanceof PlayerEntity) {
-            return ((PlayerEntity) o).getUniqueID();
-        } else if(o instanceof UUID) {
-            return (UUID) o;
-        } else if("SERVER".equals(o)) {
-            return SERVER_UUID;
-        }
-        return UUID.fromString(o.toString());
-    }
-
-    private static int getId(IPlayerBank bank, Object o) {
-        if(o instanceof ModEntityPlayerMP) {
-            return ((ModEntityPlayerMP) o).getId();
-        } else if(o instanceof Double) {
-            return ((Double) o).intValue();
-        }
-        UUID uuid = getUUID(o);
-        return bank.getId(uuid);
-    }
-
-    public static void doForGroup(MinecraftServer server, Scripts scripts, PermissionManager perms, Object group, Script sc, Consumer<ICommandSource> c) {
-        if(group instanceof String) {
-            switch(group.toString().toLowerCase()) {
-                case "all":
-                    PlayerList list = server.getPlayerList();
-                    if(list != null) {
-                        scripts.getPlayerList(sc.getId()).forEach(uuid -> {
-                            ServerPlayerEntity p = list.getPlayerByUUID(uuid);
-                            if(p != null) {
-                                c.accept(p);
-                            }
-                        });
-                    }
-                    break;
-                case "online":
-                    if(server.getPlayerList() != null) {
-                        server.getPlayerList().getPlayers().forEach(p -> c.accept(p));
-                    }
-                    break;
-                case "dev":
-                    if(server.getPlayerList() != null) {
-                        server.getPlayerList().getPlayers().forEach(p -> {
-                            if(perms.hasPermission(p, "script.error")) {
-                                c.accept(p);
-                            }
-                        });
-                    }
-                    break;
-                case "server":
-                    c.accept(server);
-                    break;
-                default:
-                    if(server.getPlayerList() != null) {
-                        c.accept(Utils.getPlayerByName(server, group.toString()));
-                    }
-                    break;
-            }
-            return;
-        }
-        c.accept((PlayerEntity) group);
-    }
-
-    private static void sendMessageToGroup(MinecraftServer server, Scripts scripts, PermissionManager perms, Object group, Script sc, ITextComponent text) {
-        doForGroup(server, scripts, perms, group, sc, p -> p.sendMessage(text));
-    }
-
-    private static ITextComponent concat(Script sc, int start, String pre, InputProvider... ob) throws Exception {
-        StringTextComponent text = new StringTextComponent(pre);
-        Object o;
-        for(int i = start; i < ob.length; i++) {
-            o = ob[i].get(sc);
-            if(o instanceof ITextComponent) {
-                text.appendSibling((ITextComponent) o);
-            } else {
-                text.appendText(String.valueOf(o));
-            }
-        }
-        return text;
-    }
-
-    private static <T> T launchProjectile(LivingEntity liv, Class<? extends T> projectile, double scale, Object data) {
-        World w = liv.world;
-        Entity launch = null;
-
-        if(EntityItemProjectile.class == projectile) {
-            if(data == null) {
-                throw new NullPointerException("Data musn't be null for EntityItemProjectile");
-            }
-            ItemStack stack = (ItemStack) data;
-            if(stack.isEmpty()) {
-                throw new IllegalArgumentException("Empty ItemStack not allowed here");
-            }
-            launch = new EntityItemProjectile(liv, stack.copy());
-            ((EntityItemProjectile) launch).setHeadingFromThrower(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
-        } else if(SnowballEntity.class == projectile) {
-            launch = new SnowballEntity(w, liv);
-            ((SnowballEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
-        } else if(EggEntity.class == projectile) {
-            launch = new EggEntity(w, liv);
-            ((EggEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
-        } else if(EnderPearlEntity.class == projectile) {
-            launch = new EnderPearlEntity(w, liv);
-            ((EnderPearlEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
-        } else if(PotionEntity.class == projectile) {
-            launch = new PotionEntity(w, liv);
-            ((PotionEntity) launch).setItem((ItemStack) data);
-            ((PotionEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, -20.0f, 0.5f, 1.0f);
-        } else if(ExperienceBottleEntity.class == projectile) {
-            launch = new ExperienceBottleEntity(w, liv);
-            ((ExperienceBottleEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, -20.0f, 0.7f, 1.0f);
-        } else if(AbstractArrowEntity.class.isAssignableFrom(projectile)) {
-            if(SpectralArrowEntity.class == projectile) {
-                launch = new SpectralArrowEntity(w, liv);
-            } else {
-                launch = new ArrowEntity(w, liv);
-                if(data != null) {
-                    ((ArrowEntity) launch).setPotionEffect((ItemStack) data);
-                }
-            }
-            ((AbstractArrowEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0F, 3.0F, 1.0F);
-        } else if(DamagingProjectileEntity.class.isAssignableFrom(projectile)) {
-            Vec3d v = liv.getLookVec().scale(10);
-            if(SmallFireballEntity.class == projectile) {
-                launch = new SmallFireballEntity(w, liv, v.x, v.y, v.z);
-            } else if(WitherSkullEntity.class == projectile) {
-                launch = new WitherSkullEntity(w, liv, v.x, v.y, v.z);
-            } else if(DragonFireballEntity.class == projectile) {
-                launch = new DragonFireballEntity(w, liv, v.x, v.y, v.z);
-            } else {
-                launch = new FireballEntity(w, liv, v.x, v.y, v.z);
-            }
-        } else {
-            return null;
-        }
-
-        launch.setMotion(launch.getMotion().scale(scale));
-        w.addEntity(launch);
-        return (T) launch;
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, SnuviScheduler scheduler, 
+            MinecraftServer server, IPlayerBank playerBank, CustomEventCaller cec, IScriptBank scriptBank, 
+            DataBank dataBank, WorldPlotMap plots, ModCommandManager commands) {
+        CommandCommands.registerFunctions(sm, scripts, perms, server, commands);        
+        PermissionCommands.registerFunctions(sm, perms);
+        TableCommands.registerFunctions(sm);
+        TitleCommands.registerFunctions(sm);
+        PlayerCommands.registerFunctions(sm, scripts, perms, scheduler, server, playerBank);
+        WorldCommands.registerFunctions(sm, server);
+        ItemCommands.registerFunctions(sm);
+        LocationCommands.registerFunctions(sm);
+        BlockCommands.registerFunctions(sm);
+        EventCommands.registerFunctions(sm, cec);
+        DamageCommands.registerFunctions(sm);
+        EntityCommands.registerFunctions(sm, scheduler);
+        LivingCommands.registerFunctions(sm);
+        HumanCommands.registerFunctions(sm);
+        DeprecatedCommands.registerFunctions(sm, scripts, perms, scheduler, server, playerBank, cec, scriptBank, dataBank, plots, commands);
+        DatabankCommands.registerFunctions(sm, scheduler, dataBank);      
+        PlotCommands.registerFunctions(sm, plots);
+        ScriptCommands.registerFunctions(sm, scripts, server);
+        ScoreboardCommands.registerFunctions(sm, scripts, perms, server);
+        DisplayCommands.registerFunctions(sm, scripts, perms, server);
+        StatusCommands.registerFunctions(sm, scripts, perms, server);
+        ItemStackDisplayCommands.registerFunctions(sm, scripts, perms, server);
+        HeadCommands.registerFunctions(sm, scripts, perms, server);     
+        ParticleCommands.registerFunctions(sm);
+        SoundCommands.registerFunctions(sm);
+        InventoryCommands.registerFunctions(sm);
+        DataCommands.registerFunctions(sm, scheduler);
+        ReadCommands.registerFunctions(sm, server);
+        TextCommands.registerFunctions(sm);       
+        BanCommands.registerFunctions(sm, server);
+        Commands.registerFunctions(sm, scripts, perms, scheduler, server, commands);
     }
 }

+ 7 - 7
src/main/java/me/km/snuviscript/ScriptEvents.java

@@ -12,7 +12,7 @@ import me.km.entities.EntityHuman;
 import me.km.entities.EntityItemProjectile;
 import me.km.events.CommandEvent;
 import me.km.inventory.ModInventory;
-import me.km.permissions.PermissionManager;
+import me.km.permissions.Permissions;
 import me.km.utils.Location;
 import net.minecraft.command.ICommandSource;
 import net.minecraft.entity.Entity;
@@ -61,9 +61,9 @@ public class ScriptEvents {
 
     private final Scripts scripts;
     private final MinecraftServer server;
-    private final PermissionManager perms;
+    private final Permissions perms;
 
-    public ScriptEvents(Scripts scripts, MinecraftServer server, PermissionManager perms) {
+    public ScriptEvents(Scripts scripts, MinecraftServer server, Permissions perms) {
         this.scripts = scripts;
         this.server = server;
         this.perms = perms;
@@ -125,7 +125,7 @@ public class ScriptEvents {
         try {
             ifVarNotNull(sc, name, c);
         } catch(Exception ex) {
-            scripts.getLogger().print(String.format("invalid var in '%s' event", event), ex, null, sc.getName(), sc, sc.getActiveSourceLine());
+            scripts.getLogger().print(String.format("invalid var in '%s' event", event), ex, null, sc.getName(), sc, sc.getStackTrace());
         }
     }
 
@@ -140,7 +140,7 @@ public class ScriptEvents {
         try {
             ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
         } catch(Exception ex) {
-            scripts.getLogger().print(String.format("invalid var in '%s' event", name), ex, null, sc.getName(), sc, sc.getActiveSourceLine());
+            scripts.getLogger().print(String.format("invalid var in '%s' event", name), ex, null, sc.getName(), sc, sc.getStackTrace());
         }
     }
 
@@ -220,7 +220,7 @@ public class ScriptEvents {
                 ifVarNotNull(sc, "player_damage", v -> e.setAmount(v.getFloat(sc)));
                 ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
             } catch(Exception ex) {
-                scripts.getLogger().print("invalid var in 'player_hurt' event", ex, null, sc.getName(), sc, sc.getActiveSourceLine());
+                scripts.getLogger().print("invalid var in 'player_hurt' event", ex, null, sc.getName(), sc, sc.getStackTrace());
             }
         });
     }
@@ -301,7 +301,7 @@ public class ScriptEvents {
                 }
                 ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
             } catch(Exception ex) {
-                scripts.getLogger().print("invalid var in 'player_death' event", ex, null, sc.getName(), sc, sc.getActiveSourceLine());
+                scripts.getLogger().print("invalid var in 'player_death' event", ex, null, sc.getName(), sc, sc.getStackTrace());
             }
         });
     }

+ 8 - 7
src/main/java/me/km/snuviscript/SnuviLogger.java

@@ -2,26 +2,27 @@ package me.km.snuviscript;
 
 import me.hammerle.snuviscript.code.ISnuviLogger;
 import me.hammerle.snuviscript.code.Script;
-import me.km.permissions.PermissionManager;
+import me.hammerle.snuviscript.exceptions.StackTrace;
+import me.km.permissions.Permissions;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.util.text.StringTextComponent;
 
 public class SnuviLogger implements ISnuviLogger {
     private boolean printToConsole = true;
     private MinecraftServer server = null;
-    private PermissionManager perms = null;
+    private Permissions perms = null;
 
     public void setConsoleLogging(boolean b) {
         printToConsole = b;
     }
 
-    public void setPlayerLoggingData(MinecraftServer server, PermissionManager perms) {
+    public void setPlayerLoggingData(MinecraftServer server, Permissions perms) {
         this.server = server;
         this.perms = perms;
     }
 
     @Override
-    public void print(String message, Exception ex, String function, String scriptname, Script sc, int line) {
+    public void print(String message, Exception ex, String function, String scriptname, Script sc, StackTrace lines) {
         StringBuilder sb = new StringBuilder();
         sb.append("[§cLogger§r] ");
 
@@ -69,10 +70,10 @@ public class SnuviLogger implements ISnuviLogger {
             sb.append("§r'");
         }
 
-        if(line != -1) {
+        if(lines != null) {
             sb.append(" in line '");
             sb.append(color);
-            sb.append(line);
+            sb.append(lines);
             sb.append("§r'");
         }
 
@@ -84,7 +85,7 @@ public class SnuviLogger implements ISnuviLogger {
 
         if(server != null && perms != null && server.getPlayerList() != null) {
             server.getPlayerList().getPlayers().forEach(p -> {
-                if(perms.hasPermission(p, "script.error")) {
+                if(perms.has(p, "script.error")) {
                     p.sendMessage(text);
                 }
             });

+ 37 - 0
src/main/java/me/km/snuviscript/commands/BanCommands.java

@@ -0,0 +1,37 @@
+package me.km.snuviscript.commands;
+
+import com.mojang.authlib.GameProfile;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import me.hammerle.snuviscript.code.ScriptManager;
+import static me.km.snuviscript.commands.CommandUtils.getUUID;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.management.ProfileBanEntry;
+import net.minecraft.util.text.StringTextComponent;
+
+public class BanCommands {
+    public static void registerFunctions(ScriptManager sm, MinecraftServer server) {
+        sm.registerConsumer("ban.kick", (sc, in) -> {
+            ((ServerPlayerEntity) in[0].get(sc)).connection.disconnect(new StringTextComponent(in[1].getString(sc)));
+        });
+        sm.registerConsumer("ban.add", (sc, in) -> {
+            GameProfile gp = server.getPlayerProfileCache().getProfileByUUID(getUUID(in[0].get(sc)));
+            String reason = in[1].getString(sc);
+            String banner = in[2].getString(sc);
+            ProfileBanEntry entry;
+            if(in.length >= 4) {
+                GregorianCalendar calender = (GregorianCalendar) in[3].get(sc);
+                Date d = new Date(calender.getTimeInMillis());
+                entry = new ProfileBanEntry(gp, null, banner, d, reason);
+            } else {
+                entry = new ProfileBanEntry(gp, null, banner, null, reason);
+            }
+            server.getPlayerList().getBannedPlayers().addEntry(entry);
+        });
+        sm.registerConsumer("ban.remove", (sc, in) -> {
+            GameProfile gp = server.getPlayerProfileCache().getProfileByUUID(getUUID(in[0].get(sc)));
+            server.getPlayerList().getBannedPlayers().removeEntry(gp);
+        });
+    }
+}

+ 203 - 0
src/main/java/me/km/snuviscript/commands/BlockCommands.java

@@ -0,0 +1,203 @@
+package me.km.snuviscript.commands;
+
+import com.mojang.brigadier.StringReader;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.inventory.InventoryUtils;
+import me.km.utils.Location;
+import me.km.utils.Mapper;
+import net.minecraft.block.*;
+import net.minecraft.command.arguments.BlockStateParser;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.network.play.server.SUpdateTileEntityPacket;
+import net.minecraft.state.IProperty;
+import net.minecraft.state.properties.ChestType;
+import net.minecraft.tags.BlockTags;
+import net.minecraft.tags.Tag;
+import net.minecraft.tileentity.*;
+import net.minecraft.util.Direction;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.text.StringTextComponent;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+
+public class BlockCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("block.gettag", (sc, in) -> BlockTags.getCollection().get(new ResourceLocation(in[0].getString(sc))));
+        sm.registerFunction("block.hastag", (sc, in) -> ((Tag<Block>) in[0].get(sc)).contains((Block) in[1].get(sc)));
+        sm.registerFunction("block.gettype", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return l.getWorld().getBlockState(l.getBlockPos()).getBlock().getRegistryName().toString();
+        });
+        sm.registerFunction("block.get", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return l.getWorld().getBlockState(l.getBlockPos()).getBlock();
+        });
+        sm.registerFunction("block.getproperty", (sc, in) -> Mapper.getProperty(in[0].getString(sc)));
+        sm.registerFunction("block.getstate", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            IProperty prop = (IProperty) in[1].get(sc);
+            BlockState state = l.getWorld().getBlockState(l.getBlockPos());
+            if(state.has(prop)) {
+                Object o = l.getWorld().getBlockState(l.getBlockPos()).get(prop);
+                if(o instanceof Number) {
+                    return ((Number) o).doubleValue();
+                } else if(o instanceof Boolean) {
+                    return o;
+                }
+                return o.toString();
+            }
+            return null;
+        });
+        sm.registerConsumer("block.clone", (sc, in) -> {
+            Location l0 = (Location) in[0].get(sc);
+            Location l1 = (Location) in[1].get(sc);
+
+            IWorld w0 = l0.getWorld();
+            BlockPos pos0 = l0.getBlockPos();
+            BlockState state = w0.getBlockState(pos0);
+            TileEntity tileEnt0 = w0.getTileEntity(pos0);
+
+            IWorld w1 = l1.getWorld();
+            BlockPos pos1 = l1.getBlockPos();
+            w1.setBlockState(pos1, state, 2);
+            TileEntity tileEnt1 = w1.getTileEntity(pos1);
+            if(tileEnt0 != null && tileEnt1 != null) {
+                CompoundNBT nbt = tileEnt0.write(new CompoundNBT());
+                nbt.putInt("x", pos1.getX());
+                nbt.putInt("y", pos1.getY());
+                nbt.putInt("z", pos1.getZ());
+                tileEnt1.read(nbt);
+                tileEnt1.markDirty();
+            }
+        });
+        sm.registerConsumer("block.set", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            BlockStateParser parser = new BlockStateParser(new StringReader(in[1].getString(sc)), true);
+            BlockState state = parser.parse(true).getState();
+            int flag = 2;
+            if(in.length >= 3 && in[2].getBoolean(sc)) {
+                flag |= 16;
+            }
+            l.getWorld().setBlockState(l.getBlockPos(), state, flag);
+        });
+        sm.registerConsumer("block.setsign", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            SignTileEntity sign = (SignTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
+            sign.signText[in[1].getInt(sc)] = new StringTextComponent(SnuviUtils.connect(sc, in, 2));
+
+            SUpdateTileEntityPacket packet = sign.getUpdatePacket();
+            World w = sign.getWorld();
+            if(w != null) {
+                w.getPlayers().stream().filter(p -> p instanceof ServerPlayerEntity)
+                        .forEach(p -> ((ServerPlayerEntity) p).connection.sendPacket(packet));
+            }
+        });
+        sm.registerFunction("block.getsign", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            SignTileEntity sign = (SignTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
+            return sign.signText[in[1].getInt(sc)].getString();
+        });
+        sm.registerConsumer("block.setdoorstatus", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            BlockPos pos = l.getBlockPos();
+            ((DoorBlock) l.getWorld().getBlockState(pos).getBlock()).toggleDoor(l.getWorld().getWorld(), pos, in[1].getBoolean(sc));
+        });
+        sm.registerFunction("block.getdoorstatus", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return l.getBlockState().get(DoorBlock.OPEN);
+        });
+        sm.registerFunction("block.isdoor", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return l.getWorld().getBlockState(l.getBlockPos()).getBlock() instanceof DoorBlock;
+        });
+        sm.registerFunction("block.issolid", (sc, in) -> {
+            return CommandUtils.getBlockState((Location) in[0].get(sc)).isSolid();
+        });
+        sm.registerFunction("block.tostack", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return new ItemStack(l.getBlockState().getBlock().asItem());
+        });
+        sm.registerFunction("block.getitemamount", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
+            if(te == null || !(te instanceof ChestTileEntity)) {
+                return 0.0d;
+            }
+            return (double) InventoryUtils.searchInventoryFor((ChestTileEntity) te, (ItemStack) in[2].get(sc), in[1].getBoolean(sc));
+        });
+        sm.registerFunction("block.getsecchest", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            BlockPos pos = l.getBlockPos();
+            BlockState state = l.getWorld().getBlockState(pos);
+            ChestType chesttype = state.get(ChestBlock.TYPE);
+            if(chesttype == ChestType.SINGLE) {
+                return null;
+            }
+            Direction dir = ChestBlock.getDirectionToAttached(state);
+            return l.copyAdd(dir.getXOffset(), dir.getYOffset(), dir.getZOffset());
+        });
+        sm.registerFunction("block.additem", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            ItemStack stack = ((ItemStack) in[1].get(sc));
+            TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
+            if(te == null || !(te instanceof ChestTileEntity)) {
+                return stack;
+            }
+            stack.setCount(InventoryUtils.addToInventory((ChestTileEntity) te, stack));
+            return stack;
+        });
+        sm.registerFunction("block.subitem", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            ItemStack stack = ((ItemStack) in[1].get(sc));
+            TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
+            if(te == null || !(te instanceof ChestTileEntity)) {
+                return stack;
+            }
+            stack.setCount(InventoryUtils.removeFromInventory((ChestTileEntity) te, stack));
+            return stack;
+        });
+        sm.registerConsumer("block.grow", (sc, in) -> {
+            Location l1 = (Location) in[0].get(sc);
+            World w = l1.getWorld().getWorld();
+            BlockPos pos1 = l1.getBlockPos();
+            BlockPos pos2 = ((Location) in[1].get(sc)).getBlockPos();
+
+            int x = Math.min(pos1.getX(), pos2.getX());
+            int endX = Math.max(pos1.getX(), pos2.getX());
+
+            int y = Math.min(pos1.getY(), pos2.getY());
+            int endY = Math.max(pos1.getY(), pos2.getY());
+
+            int z = Math.min(pos1.getZ(), pos2.getZ());
+            int endZ = Math.max(pos1.getZ(), pos2.getZ());
+
+            if(endX - x > 50 || endY - y > 50 || endZ - z > 50) {
+                throw new IllegalArgumentException("uhh, that area seems way to big for growing plants");
+            }
+
+            BlockPos relative;
+            BlockState state;
+            for(; x <= endX; x++) {
+                for(; y <= endY; y++) {
+                    for(; z <= endZ; z++) {
+                        relative = new BlockPos(x, y, z);
+                        state = w.getBlockState(relative);
+                        if(state.getBlock() instanceof CropsBlock) {
+                            w.setBlockState(relative, state.with(CropsBlock.AGE, 7));
+                        }
+                    }
+                }
+            }
+        });
+        sm.registerConsumer("block.setspawnertype", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            MobSpawnerTileEntity spawner = (MobSpawnerTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
+            spawner.getSpawnerBaseLogic().setEntityType(EntityType.byKey(in[1].getString(sc)).get());
+        });
+    }
+}

+ 126 - 0
src/main/java/me/km/snuviscript/commands/CommandCommands.java

@@ -0,0 +1,126 @@
+package me.km.snuviscript.commands;
+
+import com.mojang.brigadier.arguments.*;
+import com.mojang.brigadier.builder.*;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.permissions.ModCommandManager;
+import me.km.permissions.Permissions;
+import me.km.snuviscript.Scripts;
+import net.minecraft.command.CommandSource;
+import net.minecraft.command.Commands;
+import net.minecraft.command.arguments.*;
+import net.minecraft.server.MinecraftServer;
+
+public class CommandCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms,
+            MinecraftServer server, ModCommandManager commands) {
+        sm.registerConsumer("command.addignored", (sc, in) -> commands.addIgnoredCommands(in[0].getString(sc)));
+        sm.registerConsumer("command.clearignored", (sc, in) -> commands.clearIgnoredCommands());
+        sm.registerFunction("command.newhelp", (sc, in) -> {
+            return Commands.literal(in[0].getString(sc)).requires(p -> perms.has(p, in[1].getString(sc)));
+        });
+        sm.registerFunction("command.newhelpliteral", (sc, in) -> {
+            LiteralArgumentBuilder<CommandSource> arg = Commands.literal(in[0].getString(sc));
+            if(in.length >= 2) {
+                arg.requires(p -> perms.has(p, in[1].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerFunction("command.newhelpbool", (sc, in) -> {
+            RequiredArgumentBuilder<CommandSource, Boolean> arg = Commands.argument(in[0].getString(sc), BoolArgumentType.bool());
+            if(in.length >= 2) {
+                arg.requires(p -> perms.has(p, in[1].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerFunction("command.newhelpdouble", (sc, in) -> {
+            double min = in[1].getDouble(sc);
+            double max = in[2].getDouble(sc);
+            RequiredArgumentBuilder<CommandSource, Double> arg = Commands.argument(in[0].getString(sc), DoubleArgumentType.doubleArg(min, max));
+            if(in.length >= 4) {
+                arg.requires(p -> perms.has(p, in[3].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerFunction("command.newhelpfloat", (sc, in) -> {
+            float min = in[1].getFloat(sc);
+            float max = in[2].getFloat(sc);
+            RequiredArgumentBuilder<CommandSource, Float> arg = Commands.argument(in[0].getString(sc), FloatArgumentType.floatArg(min, max));
+            if(in.length >= 4) {
+                arg.requires(p -> perms.has(p, in[3].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerFunction("command.newhelpint", (sc, in) -> {
+            int min = in[1].getInt(sc);
+            int max = in[2].getInt(sc);
+            RequiredArgumentBuilder<CommandSource, Integer> arg = Commands.argument(in[0].getString(sc), IntegerArgumentType.integer(min, max));
+            if(in.length >= 4) {
+                arg.requires(p -> perms.has(p, in[3].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerFunction("command.newhelplong", (sc, in) -> {
+            long min = in[1].getLong(sc);
+            long max = in[2].getLong(sc);
+            RequiredArgumentBuilder<CommandSource, Long> arg = Commands.argument(in[0].getString(sc), LongArgumentType.longArg(min, max));
+            if(in.length >= 4) {
+                arg.requires(p -> perms.has(p, in[3].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerFunction("command.newhelpstring", (sc, in) -> {
+            RequiredArgumentBuilder<CommandSource, String> arg;
+            if(in[1].getBoolean(sc)) {
+                arg = Commands.argument(in[0].getString(sc), StringArgumentType.greedyString());
+            } else {
+                arg = Commands.argument(in[0].getString(sc), StringArgumentType.string());
+            }
+            if(in.length >= 3) {
+                arg.requires(p -> perms.has(p, in[2].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerFunction("command.newhelpspecial", (sc, in) -> {
+            RequiredArgumentBuilder<CommandSource, ArgumentType> arg = null;
+            String name = in[0].getString(sc);
+            switch(name) {
+                case "Item":
+                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) ItemArgument.item());
+                    break;
+                case "Block":
+                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) BlockStateArgument.blockState());
+                    break;
+                case "Potion":
+                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) PotionArgument.mobEffect());
+                    break;
+                case "Enchantment":
+                    arg = Commands.argument(in[1].getString(sc), (ArgumentType) EnchantmentArgument.enchantment());
+                    break;
+                default:
+                    throw new IllegalArgumentException(String.format("'%s' is not a valid special help", name));
+            }
+            if(in.length >= 3) {
+                arg.requires(p -> perms.has(p, in[2].getString(sc)));
+            }
+            return arg;
+        });
+        sm.registerConsumer("command.sendhelp", (sc, in) -> {
+            server.getPlayerList().getPlayers().forEach(p -> commands.send(p));
+        });
+        sm.registerConsumer("command.addhelpalias", (sc, in) -> {
+            ((ArgumentBuilder) in[0].get(sc)).redirect(((ArgumentBuilder) in[1].get(sc)).build());
+        });
+        sm.registerConsumer("command.addhelpchild", (sc, in) -> {
+            ((ArgumentBuilder) in[0].get(sc)).then(((ArgumentBuilder) in[1].get(sc)).build());
+        });
+        sm.registerConsumer("command.addhelp", (sc, in) -> {
+            commands.addCustomNodes(((LiteralArgumentBuilder<CommandSource>) in[0].get(sc)).build());
+        });
+        sm.registerConsumer("command.clearhelp", (sc, in) -> commands.clearCustomNodes());
+        sm.registerConsumer("command.add", (sc, in) -> scripts.registerScriptCommand(in[0].getString(sc)));
+        sm.registerConsumer("command.remove", (sc, in) -> scripts.unregisterScriptCommand(in[0].getString(sc)));
+        sm.registerFunction("command.exists", (sc, in) -> scripts.isRegisteredScriptCommand(in[0].getString(sc)));
+        sm.registerConsumer("command.clear", (sc, in) -> scripts.clearScriptCommands());
+    }
+}

+ 113 - 0
src/main/java/me/km/snuviscript/commands/CommandUtils.java

@@ -0,0 +1,113 @@
+package me.km.snuviscript.commands;
+
+import java.util.UUID;
+import java.util.function.Consumer;
+import me.hammerle.snuviscript.code.Script;
+import me.hammerle.snuviscript.inputprovider.InputProvider;
+import me.km.overrides.ModEntityPlayerMP;
+import me.km.permissions.Permissions;
+import me.km.playerbank.IPlayerBank;
+import me.km.snuviscript.Scripts;
+import me.km.utils.Location;
+import me.km.utils.Utils;
+import net.minecraft.block.BlockState;
+import net.minecraft.command.ICommandSource;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.management.PlayerList;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.StringTextComponent;
+
+public class CommandUtils {
+    private final static UUID SERVER_UUID = new UUID(0, 0);
+
+    public static UUID getUUID(Object o) {
+        if(o instanceof PlayerEntity) {
+            return ((PlayerEntity) o).getUniqueID();
+        } else if(o instanceof UUID) {
+            return (UUID) o;
+        } else if("SERVER".equals(o)) {
+            return SERVER_UUID;
+        }
+        return UUID.fromString(o.toString());
+    }
+
+    public static ITextComponent concat(Script sc, int start, String pre, InputProvider... ob) throws Exception {
+        StringTextComponent text = new StringTextComponent(pre);
+        Object o;
+        for(int i = start; i < ob.length; i++) {
+            o = ob[i].get(sc);
+            if(o instanceof ITextComponent) {
+                text.appendSibling((ITextComponent) o);
+            } else {
+                text.appendText(String.valueOf(o));
+            }
+        }
+        return text;
+    }
+
+    public static void sendMessageToGroup(MinecraftServer server, Scripts scripts, Permissions perms, Object group, Script sc, ITextComponent text) {
+        doForGroup(server, scripts, perms, group, sc, p -> p.sendMessage(text));
+    }
+
+    public static void doForGroup(MinecraftServer server, Scripts scripts, Permissions perms, Object group, Script sc, Consumer<ICommandSource> c) {
+        if(group instanceof String) {
+            switch(group.toString().toLowerCase()) {
+                case "all":
+                    PlayerList list = server.getPlayerList();
+                    if(list != null) {
+                        scripts.getPlayerList(sc.getId()).forEach(uuid -> {
+                            ServerPlayerEntity p = list.getPlayerByUUID(uuid);
+                            if(p != null) {
+                                c.accept(p);
+                            }
+                        });
+                    }
+                    break;
+                case "online":
+                    if(server.getPlayerList() != null) {
+                        server.getPlayerList().getPlayers().forEach(p -> c.accept(p));
+                    }
+                    break;
+                case "dev":
+                    if(server.getPlayerList() != null) {
+                        server.getPlayerList().getPlayers().forEach(p -> {
+                            if(perms.has(p, "script.error")) {
+                                c.accept(p);
+                            }
+                        });
+                    }
+                    break;
+                case "server":
+                    c.accept(server);
+                    break;
+                default:
+                    if(server.getPlayerList() != null) {
+                        c.accept(Utils.getPlayerByName(server, group.toString()));
+                    }
+                    break;
+            }
+            return;
+        }
+        c.accept((PlayerEntity) group);
+    }
+
+    public static int getId(IPlayerBank bank, Object o) {
+        if(o instanceof ModEntityPlayerMP) {
+            return ((ModEntityPlayerMP) o).getId();
+        } else if(o instanceof Double) {
+            return ((Double) o).intValue();
+        }
+        UUID uuid = getUUID(o);
+        return bank.getId(uuid);
+    }
+    
+    public static Class getNamedClass(String s) throws ClassNotFoundException {
+        return Class.forName(s);
+    }
+    
+    public static BlockState getBlockState(Location l) {
+        return l.getWorld().getBlockState(l.getBlockPos());
+    }
+}

+ 43 - 0
src/main/java/me/km/snuviscript/commands/Commands.java

@@ -0,0 +1,43 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.permissions.ModCommandManager;
+import me.km.permissions.Permissions;
+import me.km.scheduler.SnuviScheduler;
+import me.km.snuviscript.Scripts;
+import static me.km.snuviscript.commands.CommandUtils.concat;
+import static me.km.snuviscript.commands.CommandUtils.sendMessageToGroup;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.text.StringTextComponent;
+
+public class Commands {
+    @SuppressWarnings("")
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, SnuviScheduler scheduler,
+            MinecraftServer server, ModCommandManager commands) {
+        sm.registerFunction("setmotd", (sc, in) -> {
+            server.getServerStatusResponse().setServerDescription(new StringTextComponent(in[0].getString(sc)));
+            return Void.TYPE;
+        });
+        sm.registerFunction("msg", (sc, in) -> {
+            sendMessageToGroup(server, scripts, perms, in[0].get(sc), sc, concat(sc, 1, "", in));
+            return Void.TYPE;
+        });
+        sm.registerFunction("removeformat", (sc, in) -> SnuviUtils.connect(sc, in, 0).replaceAll("§.", ""));
+        sm.registerFunction("command", (sc, in) -> {
+            final String s = SnuviUtils.connect(sc, in, 0);
+            scheduler.scheduleTask(() -> commands.handleCommand(server.getCommandSource(), s));
+            return Void.TYPE;
+        });
+        sm.registerFunction("isplayer", (sc, in) -> {
+            Object o = in[0].get(sc);
+            return o != null && o instanceof PlayerEntity;
+        });
+        sm.registerFunction("isliving", (sc, in) -> {
+            Object o = in[0].get(sc);
+            return o != null && o instanceof LivingEntity;
+        });
+    }
+}

+ 108 - 0
src/main/java/me/km/snuviscript/commands/DamageCommands.java

@@ -0,0 +1,108 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.util.DamageSource;
+
+public class DamageCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("damage.getimmediatesource", (sc, in) -> ((DamageSource) in[0].get(sc)).getImmediateSource());
+        sm.registerFunction("damage.gettruesource", (sc, in) -> ((DamageSource) in[0].get(sc)).getTrueSource());
+        sm.registerFunction("damage.iscreativeplayer", (sc, in) -> ((DamageSource) in[0].get(sc)).isCreativePlayer());
+        sm.registerFunction("damage.isabsolute", (sc, in) -> ((DamageSource) in[0].get(sc)).isDamageAbsolute());
+        sm.registerFunction("damage.isdifficultyscaled", (sc, in) -> ((DamageSource) in[0].get(sc)).isDifficultyScaled());
+        sm.registerFunction("damage.isexplosion", (sc, in) -> ((DamageSource) in[0].get(sc)).isExplosion());
+        sm.registerFunction("damage.isfire", (sc, in) -> ((DamageSource) in[0].get(sc)).isFireDamage());
+        sm.registerFunction("damage.ismagic", (sc, in) -> ((DamageSource) in[0].get(sc)).isMagicDamage());
+        sm.registerFunction("damage.isprojectile", (sc, in) -> ((DamageSource) in[0].get(sc)).isProjectile());
+        sm.registerFunction("damage.isunblockable", (sc, in) -> ((DamageSource) in[0].get(sc)).isUnblockable());
+        sm.registerFunction("damage.gettype", (sc, in) -> ((DamageSource) in[0].get(sc)).getDamageType());
+        sm.registerFunction("damage.get", (sc, in) -> {
+            Object o = in[0].get(sc);
+            if(o instanceof LivingEntity) {
+                LivingEntity ent = (LivingEntity) o;
+                DamageSource ds;
+                if(ent instanceof PlayerEntity) {
+                    ds = DamageSource.causePlayerDamage((PlayerEntity) ent);
+                } else {
+                    ds = DamageSource.causeMobDamage(ent);
+                }
+
+                if(in[1].getBoolean(sc)) {
+                    ds.setDamageAllowedInCreativeMode();
+                }
+                if(in[2].getBoolean(sc)) {
+                    ds.setDamageBypassesArmor();
+                }
+                if(in[3].getBoolean(sc)) {
+                    ds.setDamageIsAbsolute();
+                }
+                if(in[4].getBoolean(sc)) {
+                    ds.setExplosion();
+                }
+                if(in[5].getBoolean(sc)) {
+                    ds.setFireDamage();
+                }
+                if(in[6].getBoolean(sc)) {
+                    ds.setMagicDamage();
+                }
+                if(in[7].getBoolean(sc)) {
+                    ds.setProjectile();
+                }
+                return ds;
+            }
+
+            switch(o.toString()) {
+                case "inFire":
+                    return DamageSource.IN_FIRE;
+                case "lightningBolt":
+                    return DamageSource.LIGHTNING_BOLT;
+                case "onFire":
+                    return DamageSource.ON_FIRE;
+                case "lava":
+                    return DamageSource.LAVA;
+                case "hotFloor":
+                    return DamageSource.HOT_FLOOR;
+                case "inWall":
+                    return DamageSource.IN_WALL;
+                case "cramming":
+                    return DamageSource.CRAMMING;
+                case "drown":
+                    return DamageSource.DROWN;
+                case "starve":
+                    return DamageSource.STARVE;
+                case "cactus":
+                    return DamageSource.CACTUS;
+                case "fall":
+                    return DamageSource.FALL;
+                case "flyIntoWall":
+                    return DamageSource.FLY_INTO_WALL;
+                case "outOfWorld":
+                    return DamageSource.OUT_OF_WORLD;
+                case "generic":
+                    return DamageSource.GENERIC;
+                case "magic":
+                    return DamageSource.MAGIC;
+                case "wither":
+                    return DamageSource.WITHER;
+                case "anvil":
+                    return DamageSource.ANVIL;
+                case "fallingBlock":
+                    return DamageSource.FALLING_BLOCK;
+                case "dragonBreath":
+                    return DamageSource.DRAGON_BREATH;
+                case "fireworks":
+                    return DamageSource.FIREWORKS;
+                case "dryout":
+                    return DamageSource.DRYOUT;
+                case "sweetBerryBush":
+                    return DamageSource.SWEET_BERRY_BUSH;
+                case "thorns":
+                    return DamageSource.causeThornsDamage((Entity) in[1].get(sc));
+            }
+            return DamageSource.GENERIC;
+        });
+    }
+}

+ 25 - 0
src/main/java/me/km/snuviscript/commands/DataCommands.java

@@ -0,0 +1,25 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.overrides.ModEntityPlayerMP;
+import me.km.scheduler.SnuviScheduler;
+
+public class DataCommands {
+    public static void registerFunctions(ScriptManager sm, SnuviScheduler scheduler) {
+        sm.registerConsumer("data.set", (sc, in) -> {
+            ((ModEntityPlayerMP) in[0].get(sc)).setVar(in[1].getString(sc), in[2].get(sc));
+        });
+        sm.registerConsumer("data.settimer", (sc, in) -> {
+            ((ModEntityPlayerMP) in[0].get(sc)).setTimer(in[1].getString(sc), in[2].getInt(sc), scheduler);
+        });
+        sm.registerFunction("data.get", (sc, in) -> {
+            return ((ModEntityPlayerMP) in[0].get(sc)).getVar(in[1].getString(sc));
+        });
+        sm.registerFunction("data.gettimer", (sc, in) -> {
+            return (double) ((ModEntityPlayerMP) in[0].get(sc)).getTimer(in[1].getString(sc));
+        });
+        sm.registerConsumer("data.clear", (sc, in) -> {
+            ((ModEntityPlayerMP) in[0].get(sc)).clearData(scheduler);
+        });
+    }
+}

+ 71 - 0
src/main/java/me/km/snuviscript/commands/DatabankCommands.java

@@ -0,0 +1,71 @@
+package me.km.snuviscript.commands;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.exceptions.StackTrace;
+import me.km.databank.DataBank;
+import me.km.scheduler.SnuviScheduler;
+
+public class DatabankCommands {
+    public static void registerFunctions(ScriptManager sm, SnuviScheduler scheduler, DataBank dataBank) {
+        sm.registerFunction("databank.prepare", (sc, in) -> {
+            PreparedStatement p = dataBank.prepareUnsafeStatement(in[0].getString(sc));
+            if(in.length <= 1 || in[1].getBoolean(sc)) {
+                sc.addCloseable(p);
+            }
+            return p;
+        });
+        sm.registerConsumer("databank.setint", (sc, in) -> {
+            ((PreparedStatement) in[0].get(sc)).setInt(in[1].getInt(sc), in[2].getInt(sc));
+        });
+        sm.registerConsumer("databank.setlong", (sc, in) -> {
+            ((PreparedStatement) in[0].get(sc)).setLong(in[1].getInt(sc), in[2].getLong(sc));
+        });
+        sm.registerConsumer("databank.setdouble", (sc, in) -> {
+            ((PreparedStatement) in[0].get(sc)).setDouble(in[1].getInt(sc), in[2].getDouble(sc));
+        });
+        sm.registerConsumer("databank.setstring", (sc, in) -> {
+            ((PreparedStatement) in[0].get(sc)).setString(in[1].getInt(sc), in[2].getString(sc));
+        });
+        sm.registerConsumer("databank.setbool", (sc, in) -> {
+            ((PreparedStatement) in[0].get(sc)).setBoolean(in[1].getInt(sc), in[2].getBoolean(sc));
+        });
+        sm.registerFunction("databank.getint", (sc, in) -> (double) ((ResultSet) in[0].get(sc)).getInt(in[1].getInt(sc)));
+        sm.registerFunction("databank.getlong", (sc, in) -> (double) ((ResultSet) in[0].get(sc)).getLong(in[1].getInt(sc)));
+        sm.registerFunction("databank.getdouble", (sc, in) -> ((ResultSet) in[0].get(sc)).getDouble(in[1].getInt(sc)));
+        sm.registerFunction("databank.getstring", (sc, in) -> ((ResultSet) in[0].get(sc)).getString(in[1].getInt(sc)));
+        sm.registerFunction("databank.getbool", (sc, in) -> ((ResultSet) in[0].get(sc)).getBoolean(in[1].getInt(sc)));
+        sm.registerFunction("databank.execute", (sc, in) -> ((PreparedStatement) in[0].get(sc)).executeQuery());
+        sm.registerConsumer("databank.workerexecute", (sc, in) -> {
+            final PreparedStatement p = (PreparedStatement) in[0].get(sc);
+            StackTrace lines = sc.getStackTrace();
+            String function = "databank.workerexecute";
+            scheduler.getWorker().add(() -> {
+                try {
+                    p.execute();
+                } catch(SQLException ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, function, sc.getName(), sc, lines);
+                    });
+                }
+                sc.removeCloseable(p);
+                try {
+                    p.close();
+                } catch(SQLException ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, function, sc.getName(), sc, lines);
+                    });
+                }
+            });
+        });
+        sm.registerFunction("databank.next", (sc, in) -> ((ResultSet) in[0].get(sc)).next());
+        sm.registerConsumer("databank.close", (sc, in) -> {
+            AutoCloseable auto = (AutoCloseable) in[0].get(sc);
+            auto.close();
+            sc.removeCloseable(auto);
+        });
+        sm.registerFunction("worker.haswork", (sc, in) -> scheduler.getWorker().hasWork());
+    }
+}

+ 170 - 0
src/main/java/me/km/snuviscript/commands/DeprecatedCommands.java

@@ -0,0 +1,170 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.databank.DataBank;
+import me.km.events.CustomEventCaller;
+import me.km.permissions.ModCommandManager;
+import me.km.permissions.Permissions;
+import me.km.playerbank.IPlayerBank;
+import me.km.plots.WorldPlotMap;
+import me.km.scheduler.SnuviScheduler;
+import me.km.snuviscript.IScriptBank;
+import me.km.snuviscript.Scripts;
+import static me.km.snuviscript.commands.CommandUtils.getId;
+import net.minecraft.server.MinecraftServer;
+
+public class DeprecatedCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, SnuviScheduler scheduler, 
+            MinecraftServer server, IPlayerBank playerBank, CustomEventCaller cec, IScriptBank scriptBank, 
+            DataBank dataBank, WorldPlotMap plots, ModCommandManager commands) {
+        sm.registerFunction("getglobalvar", (sc, in) -> {
+            Object o = in[0].get(sc);
+            if(in.length == 2) {
+                return scriptBank.getVar(in[1].getString(sc), getId(playerBank, o));
+            }
+            return scriptBank.getVar(in[1].getString(sc), getId(playerBank, o), in[2].get(sc));
+        });
+        sm.registerAlias("getglobalvar", "ggv");
+        sm.registerConsumer("setglobalvar", (sc, in) -> {
+            final String value = in[2].getString(sc);
+            final String var = in[1].getString(sc);
+            final int id = getId(playerBank, in[0].get(sc));
+            scheduler.getWorker().add(() -> {
+                try {
+                    scriptBank.setVar(value, var, id);
+                } catch(Exception ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                    });
+                }
+            });
+        });
+        sm.registerAlias("setglobalvar", "sgv");
+        sm.registerConsumer("delglobalvar", (sc, in) -> {
+            final String var = in[1].getString(sc);
+            final int id = getId(playerBank, in[0].get(sc));
+            scheduler.getWorker().add(() -> {
+                try {
+                    scriptBank.deleteVar(var, id);
+                } catch(Exception ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                    });
+                }
+            });
+        });
+        sm.registerAlias("delglobalvar", "dgv");
+        sm.registerConsumer("gmap.removeall", (sc, in) -> {
+            final String map = in[0].getString(sc);
+            scheduler.getWorker().add(() -> {
+                try {
+                    scriptBank.removeMap(map);
+                } catch(Exception ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                    });
+                }
+            });
+        });
+        sm.registerConsumer("gmap.add", (sc, in) -> {
+            final String map = in[0].getString(sc);
+            final String key = in[1].getString(sc);
+            final String value = in[2].getString(sc);
+            scheduler.getWorker().add(() -> {
+                try {
+                    scriptBank.addMapElement(map, key, value);
+                } catch(Exception ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                    });
+                }
+            });
+        });
+        sm.registerConsumer("gmap.remove", (sc, in) -> {
+            final String map = in[0].getString(sc);
+            final String key = in[1].getString(sc);
+            scheduler.getWorker().add(() -> {
+                try {
+                    scriptBank.removeMapElement(map, key);
+                } catch(Exception ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                    });
+                }
+            });
+        });
+        sm.registerFunction("gmap.get", (sc, in) -> scriptBank.getMapValue(in[0].getString(sc), in[1].getString(sc)));
+        sm.registerFunction("gmap.getordefault", (sc, in) -> {
+            Object o = scriptBank.getMapValue(in[0].getString(sc), in[1].getString(sc));
+            if(o == null) {
+                return in[2].get(sc);
+            }
+            return o;
+        });
+        sm.registerConsumer("gdmap.removeall", (sc, in) -> {
+            if(in.length >= 2) {
+                final String map = in[0].getString(sc);
+                final String key = in[1].getString(sc);
+                scheduler.getWorker().add(() -> {
+                    try {
+                        scriptBank.removeDualMapElement(map, key);
+                    } catch(Exception ex) {
+                        scheduler.scheduleTask(() -> {
+                            sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                        });
+                    }
+                });
+            } else {
+                final String map = in[0].getString(sc);
+                scheduler.getWorker().add(() -> {
+                    try {
+                        scriptBank.removeDualMap(map);
+                    } catch(Exception ex) {
+                        scheduler.scheduleTask(() -> {
+                            sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                        });
+                    }
+                });
+            }
+        });
+        sm.registerConsumer("gdmap.add", (sc, in) -> {
+            final String map = in[0].getString(sc);
+            final String key1 = in[1].getString(sc);
+            final String key2 = in[2].getString(sc);
+            final String value = in[3].getString(sc);
+            scheduler.getWorker().add(() -> {
+                try {
+                    scriptBank.addDualMapElement(map, key1, key2, value);
+                } catch(Exception ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                    });
+                }
+            });
+        });
+        sm.registerConsumer("gdmap.remove", (sc, in) -> {
+            final String map = in[0].getString(sc);
+            final String key1 = in[1].getString(sc);
+            final String key2 = in[2].getString(sc);
+            scheduler.getWorker().add(() -> {
+                try {
+                    scriptBank.removeDualMapElement(map, key1, key2);
+                } catch(Exception ex) {
+                    scheduler.scheduleTask(() -> {
+                        sc.getScriptManager().getLogger().print("Worker error", ex, null, sc.getName(), sc, null);
+                    });
+                }
+            });
+        });
+        sm.registerFunction("gdmap.get", (sc, in) -> {
+            return scriptBank.getDualMapValue(in[0].getString(sc), in[1].getString(sc), in[2].getString(sc));
+        });
+        sm.registerFunction("gdmap.getordefault", (sc, in) -> {
+            Object o = scriptBank.getDualMapValue(in[0].getString(sc), in[1].getString(sc), in[2].getString(sc));
+            if(o == null) {
+                return in[3].get(sc);
+            }
+            return o;
+        });
+    }
+}

+ 27 - 0
src/main/java/me/km/snuviscript/commands/DisplayCommands.java

@@ -0,0 +1,27 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.networking.ModPacketHandler;
+import me.km.permissions.Permissions;
+import me.km.snuviscript.Scripts;
+import static me.km.snuviscript.commands.CommandUtils.doForGroup;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.server.MinecraftServer;
+
+public class DisplayCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, MinecraftServer server) {
+        sm.registerConsumer("display.add", (sc, in) -> {
+            byte id = in[1].getByte(sc);
+            String message = SnuviUtils.connect(sc, in, 2);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToDisplay((ServerPlayerEntity) p, (byte) 1, id, message));
+        });
+        sm.registerConsumer("display.remove", (sc, in) -> {
+            byte id = in[1].getByte(sc);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToDisplay((ServerPlayerEntity) p, (byte) 2, id, ""));
+        });
+        sm.registerConsumer("display.reset", (sc, in) -> {
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.sendToDisplay((ServerPlayerEntity) p, (byte) 3, (byte) -1, ""));
+        });
+    }
+}

+ 355 - 0
src/main/java/me/km/snuviscript/commands/EntityCommands.java

@@ -0,0 +1,355 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.entities.EntityItemProjectile;
+import me.km.scheduler.SnuviScheduler;
+import static me.km.snuviscript.commands.CommandUtils.getNamedClass;
+import me.km.utils.Location;
+import me.km.utils.Mapper;
+import me.km.utils.ReflectionUtils;
+import me.km.utils.Utils;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.*;
+import net.minecraft.entity.effect.LightningBoltEntity;
+import net.minecraft.entity.item.*;
+import net.minecraft.entity.monster.CreeperEntity;
+import net.minecraft.entity.passive.SheepEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.entity.projectile.*;
+import net.minecraft.inventory.EquipmentSlotType;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.nbt.JsonToNBT;
+import net.minecraft.potion.Effect;
+import net.minecraft.potion.EffectInstance;
+import net.minecraft.potion.PotionUtils;
+import net.minecraft.stats.Stats;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Direction;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.util.text.StringTextComponent;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+
+public class EntityCommands {
+    public static void registerFunctions(ScriptManager sm, SnuviScheduler scheduler) {
+        sm.registerConsumer("entity.setnopickup", (sc, in) -> {
+            ((AbstractArrowEntity) in[0].get(sc)).pickupStatus = AbstractArrowEntity.PickupStatus.DISALLOWED;
+        });
+        sm.registerFunction("entity.shootprojectile", (sc, in) -> launchProjectile((LivingEntity) in[0].get(sc),
+                getNamedClass(in[1].getString(sc)), in[2].getDouble(sc), in.length >= 4 ? in[3].get(sc) : null));
+        sm.registerFunction("entity.isblocking", (sc, in) -> ((LivingEntity) in[0].get(sc)).isActiveItemStackBlocking());
+        sm.registerFunction("entity.getarmorthoughness", (sc, in) -> ((LivingEntity) in[0].get(sc)).getAttribute(SharedMonsterAttributes.ARMOR_TOUGHNESS).getValue());
+        sm.registerFunction("entity.getarmor", (sc, in) -> (double) ((LivingEntity) in[0].get(sc)).getTotalArmorValue());
+        sm.registerFunction("entity.getmagicarmor", (sc, in) -> {
+            int level = 0;
+            for(ItemStack stack : ((LivingEntity) in[0].get(sc)).getArmorInventoryList()) {
+                CompoundNBT com = stack.getTag();
+                if(com != null && com.contains("magic")) {
+                    level += com.getInt("magic");
+                }
+            }
+            return level;
+        });
+        sm.registerFunction("entity.getenchantmentmodifier", (sc, in) -> EnchantmentHelper.getEnchantmentModifierDamage(((LivingEntity) in[0].get(sc)).getArmorInventoryList(), (DamageSource) in[1].get(sc)));
+        sm.registerConsumer("entity.setburning", (sc, in) -> ((Entity) in[0].get(sc)).setFire(in[1].getInt(sc)));
+        sm.registerFunction("entity.isburning", (sc, in) -> ((Entity) in[0].get(sc)).isBurning());
+        sm.registerFunction("entity.getlook", (sc, in) -> {
+            Object[] o = new Object[3];
+            Vec3d v = ((Entity) in[0].get(sc)).getLookVec();
+            o[0] = v.x;
+            o[1] = v.y;
+            o[2] = v.z;
+            return o;
+        });
+        sm.registerFunction("entity.getlocation", (sc, in) -> new Location((Entity) in[0].get(sc)));
+        sm.registerConsumer("entity.heal", (sc, in) -> {
+            LivingEntity liv = (LivingEntity) in[0].get(sc);
+            float heal = in[1].getFloat(sc);
+            scheduler.scheduleTask(() -> liv.heal(heal));
+        });
+        sm.registerConsumer("entity.damage", (sc, in) -> {
+            LivingEntity liv = (LivingEntity) in[0].get(sc);
+            float damage = in[1].getFloat(sc);
+            DamageSource damageSource = (in.length >= 3) ? (DamageSource) in[2].get(sc) : DamageSource.GENERIC;
+            scheduler.scheduleTask(() -> liv.attackEntityFrom(damageSource, damage));
+        });
+        sm.registerConsumer("entity.damagedirect", (sc, in) -> {
+            LivingEntity liv = (LivingEntity) in[0].get(sc);
+            float damageAmount = in[1].getFloat(sc);
+            DamageSource ds = (DamageSource) in[2].get(sc);
+            if(!liv.isInvulnerableTo(ds)) {
+                float f2 = Math.max(damageAmount - liv.getAbsorptionAmount(), 0.0F);
+                liv.setAbsorptionAmount(liv.getAbsorptionAmount() - (damageAmount - f2));
+                float absorbedDamage = damageAmount - f2;
+                if(absorbedDamage > 0.0f && absorbedDamage < 3.4028235E37f && ds.getTrueSource() instanceof ServerPlayerEntity) {
+                    ((ServerPlayerEntity) ds.getTrueSource()).addStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(absorbedDamage * 10.0f));
+                }
+
+                if(f2 > 0.0f) {
+                    float f1 = liv.getHealth();
+                    liv.getCombatTracker().trackDamage(ds, f1, f2);
+                    liv.setHealth(f1 - f2);
+                    liv.setAbsorptionAmount(liv.getAbsorptionAmount() - f2);
+                }
+            }
+        });
+        sm.registerFunction("entity.fromsource", (sc, in) -> {
+            DamageSource ds = (DamageSource) in[0].get(sc);
+            Entity ent = ds.getTrueSource();
+            if(ent == null) {
+                return ds.getImmediateSource();
+            }
+            return ent;
+        });
+        sm.registerAlias("damage.get", "entity.getdamagesource");
+        sm.registerFunction("entity.getmaxhealth", (sc, in) -> (double) ((LivingEntity) in[0].get(sc)).getMaxHealth());
+        sm.registerFunction("entity.gethealth", (sc, in) -> (double) ((LivingEntity) in[0].get(sc)).getHealth());
+        sm.registerConsumer("entity.sethealth", (sc, in) -> ((LivingEntity) in[0].get(sc)).setHealth(in[1].getFloat(sc)));
+        sm.registerConsumer("entity.setname", (sc, in) -> {
+            Entity ent = (Entity) in[0].get(sc);
+            ent.setCustomName(new StringTextComponent(in[1].getString(sc)));
+            if(in.length >= 3) {
+                ent.setCustomNameVisible(in[2].getBoolean(sc));
+                return;
+            }
+            ent.setCustomNameVisible(false);
+        });
+        sm.registerFunction("entity.getname", (sc, in) -> ((Entity) in[0].get(sc)).getDisplayName().getFormattedText());
+        sm.registerConsumer("entity.throw", (sc, in) -> {
+            Entity ent = (Entity) in[0].get(sc);
+            ent.setMotion(in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc));
+            ent.velocityChanged = true;
+        });
+        sm.registerConsumer("entity.teleport", (sc, in) -> {
+            Entity ent = (Entity) in[0].get(sc);
+            Location l = (Location) in[1].get(sc);
+            if(l.getWorld() == null) {
+                throw new IllegalArgumentException("world must not be null");
+            }
+            if(ent instanceof ServerPlayerEntity) {
+                ServerPlayerEntity p = (ServerPlayerEntity) ent;
+
+                p.stopRiding();
+                if(p.isSleeping()) {
+                    p.func_225652_a_(true, true);
+                }
+
+                float yaw = l.getYaw() != 0.0f ? l.getYaw() : ent.rotationYaw;
+                float pitch = l.getPitch() != 0.0f ? l.getPitch() : ent.rotationPitch;
+                p.teleport((ServerWorld) l.getWorld(), l.getX(), l.getY(), l.getZ(), yaw, pitch);
+            } else {
+                if(ent.world != l.getWorld()) {
+                    ServerWorld ws = (ServerWorld) l.getWorld();
+                    ent.changeDimension(ws.getDimension().getType());
+                }
+                if(l.getYaw() != 0 && l.getPitch() != 0) {
+                    ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
+                } else {
+                    ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch);
+                }
+            }
+        });
+        sm.registerConsumer("entity.setequip", (sc, in) -> {
+            LivingEntity liv = (LivingEntity) in[0].get(sc);
+            ItemStack stack = ((ItemStack) in[2].get(sc)).copy();
+            switch(in[1].getString(sc)) {
+                case "hand":
+                    liv.setItemStackToSlot(EquipmentSlotType.MAINHAND, stack);
+                    return;
+                case "head":
+                    liv.setItemStackToSlot(EquipmentSlotType.HEAD, stack);
+                    return;
+                case "chest":
+                    liv.setItemStackToSlot(EquipmentSlotType.CHEST, stack);
+                    return;
+                case "legs":
+                    liv.setItemStackToSlot(EquipmentSlotType.LEGS, stack);
+                    return;
+                case "feet":
+                    liv.setItemStackToSlot(EquipmentSlotType.FEET, stack);
+                    return;
+                case "offhand":
+                    liv.setItemStackToSlot(EquipmentSlotType.OFFHAND, stack);
+            }
+        });
+        sm.registerFunction("entity.getequip", (sc, in) -> {
+            LivingEntity liv = (LivingEntity) in[0].get(sc);
+            switch(in[1].getString(sc)) {
+                case "hand":
+                    return liv.getItemStackFromSlot(EquipmentSlotType.MAINHAND);
+                case "head":
+                    return liv.getItemStackFromSlot(EquipmentSlotType.HEAD);
+                case "chest":
+                    return liv.getItemStackFromSlot(EquipmentSlotType.CHEST);
+                case "legs":
+                    return liv.getItemStackFromSlot(EquipmentSlotType.LEGS);
+                case "feet":
+                    return liv.getItemStackFromSlot(EquipmentSlotType.FEET);
+                case "offhand":
+                    return liv.getItemStackFromSlot(EquipmentSlotType.OFFHAND);
+            }
+            return ItemStack.EMPTY;
+        });
+        sm.registerConsumer("entity.removeall", (sc, in) -> {
+            Class<? extends Entity> c = (Class<? extends Entity>) getNamedClass(in[0].getString(sc));
+            if(c == Entity.class) {
+                return;
+            }
+            Location l = (Location) in[1].get(sc);
+            Utils.getEntities(l.getWorld(), l.getX(), l.getY(), l.getZ(), in[2].getDouble(sc), c).stream().forEach(ent -> {
+                ent.remove();
+            });
+        });
+        sm.registerConsumer("entity.remove", (sc, in) -> ((Entity) in[0].get(sc)).remove());
+        sm.registerConsumer("entity.setinvulnerable", (sc, in) -> {
+            ((Entity) in[0].get(sc)).setInvulnerable(in[1].getBoolean(sc));
+        });
+        sm.registerConsumer("entity.setsilent", (sc, in) -> {
+            ((Entity) in[0].get(sc)).setSilent(in[1].getBoolean(sc));
+        });
+        sm.registerConsumer("entity.setinvisible", (sc, in) -> {
+            ((Entity) in[0].get(sc)).setInvisible(in[1].getBoolean(sc));
+        });
+        sm.registerConsumer("entity.ride", (sc, in) -> {
+            ((Entity) in[0].get(sc)).startRiding(((Entity) in[1].get(sc)));
+        });
+        sm.registerConsumer("entity.addeffect", (sc, in) -> {
+            LivingEntity base = (LivingEntity) in[0].get(sc);
+            Effect potion = Mapper.getPotion(in[1].getString(sc));
+            if(potion == null) // doing this only to prevent EffectInstance doing shit
+            {
+                throw new IllegalArgumentException("potion does not exist");
+            }
+            if(base.isPotionActive(potion)) {
+                base.removePotionEffect(potion);
+            }
+            base.addPotionEffect(new EffectInstance(potion, in[2].getInt(sc), in[3].getInt(sc)));
+        });
+        sm.registerConsumer("entity.cleareffects", (sc, in) -> {
+            ((LivingEntity) in[0].get(sc)).clearActivePotions();
+        });
+        sm.registerFunction("entity.geteffectamplifier", (sc, in) -> {
+            EffectInstance effect = ((LivingEntity) in[0].get(sc)).getActivePotionEffect(Mapper.getPotion(in[1].getString(sc)));
+            return effect == null ? 0 : effect.getAmplifier() + 1;
+        });
+        sm.registerConsumer("entity.spawnitemframe", (sc, in) -> {
+            Location l = ((Location) in[0].get(sc));
+            ItemFrameEntity frame = new ItemFrameEntity(l.getWorld().getWorld(), l.getBlockPos(), Direction.byName(in[1].getString(sc)));
+            frame.setDisplayedItem(((ItemStack) in[2].get(sc))); // copy happens in internals
+            l.getWorld().addEntity(frame);
+        });
+        sm.registerFunction("entity.getitemfromframe", (sc, in) -> ((ItemFrameEntity) in[0].get(sc)).getDisplayedItem());
+        sm.registerFunction("entity.get", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return Utils.getEntity(l.getWorld(), l.getX(), l.getY(), l.getZ(), in[1].getDouble(sc), getNamedClass(in[2].getString(sc)));
+        });
+        sm.registerFunction("entity.getpotiontype", (sc, in) -> PotionUtils.getPotionFromItem(((PotionEntity) in[0].get(sc)).getItem()).getRegistryName().toString());
+        sm.registerConsumer("entity.setgravity", (sc, in) -> {
+            ((Entity) in[0].get(sc)).setNoGravity(!in[1].getBoolean(sc));
+        });
+        sm.registerFunction("entity.iswet", (sc, in) -> ((Entity) in[0].get(sc)).isWet());
+        sm.registerConsumer("entity.setpickupdelay", (sc, in) -> {
+            ((ItemEntity) in[0].get(sc)).setPickupDelay(in[1].getInt(sc));
+        });
+        sm.registerConsumer("entity.setage", (sc, in) -> {
+            ReflectionUtils.setAge((ItemEntity) in[0].get(sc), in[1].getInt(sc));
+        });
+        sm.registerFunction("entity.spawn", (sc, in) -> {
+            ResourceLocation rl = new ResourceLocation(in[0].getString(sc));
+            Location l = (Location) in[1].get(sc);
+            ServerWorld sw = (ServerWorld) l.getWorld();
+
+            CompoundNBT compoundnbt = in.length >= 3 ? JsonToNBT.getTagFromJson(in[2].getString(sc)) : new CompoundNBT();
+            compoundnbt.putString("id", rl.toString());
+            if(EntityType.getKey(EntityType.LIGHTNING_BOLT).equals(rl)) {
+                LightningBoltEntity ent = new LightningBoltEntity(sw, l.getX(), l.getY(), l.getZ(), false);
+                sw.addLightningBolt(ent);
+                return ent;
+            }
+
+            Entity entity = EntityType.func_220335_a(compoundnbt, sw, (ent) -> {
+                ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch);
+                return sw.summonEntity(ent) ? ent : null;
+            });
+            if(entity != null && entity instanceof MobEntity) {
+                ((MobEntity) entity).onInitialSpawn(sw, sw.getDifficultyForLocation(new BlockPos(entity)), SpawnReason.COMMAND, null, null);
+            }
+            return entity;
+        });
+        sm.registerFunction("entity.near", (sc, in) -> Utils.getLiving((Entity) in[0].get(sc), in[1].getDouble(sc)));
+        sm.registerConsumer("entity.setspeed", (sc, in) -> {
+            ((LivingEntity) in[0].get(sc)).getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(in[1].getDouble(sc));
+        });
+        sm.registerConsumer("entity.setgrowingage", (sc, in) -> {
+            ((AgeableEntity) in[0].get(sc)).setGrowingAge(in[1].getInt(sc));
+        });
+        sm.registerFunction("entity.gettype", (sc, in) -> ((Entity) in[0].get(sc)).getType().getRegistryName().getPath());
+        sm.registerFunction("entity.issneaking", (sc, in) -> ((Entity) in[0].get(sc)).isCrouching());
+        sm.registerFunction("sheep.issheared", (sc, in) -> ((SheepEntity) in[0].get(sc)).getSheared());
+        sm.registerFunction("sheep.getcolor", (sc, in) -> ((SheepEntity) in[0].get(sc)).getFleeceColor().getName());
+        sm.registerConsumer("creeper.explode", (sc, in) -> ((CreeperEntity) in[0].get(sc)).ignite());
+    }
+
+    private static <T> T launchProjectile(LivingEntity liv, Class<? extends T> projectile, double scale, Object data) {
+        World w = liv.world;
+        Entity launch = null;
+
+        if(EntityItemProjectile.class == projectile) {
+            if(data == null) {
+                throw new NullPointerException("Data musn't be null for EntityItemProjectile");
+            }
+            ItemStack stack = (ItemStack) data;
+            if(stack.isEmpty()) {
+                throw new IllegalArgumentException("Empty ItemStack not allowed here");
+            }
+            launch = new EntityItemProjectile(liv, stack.copy());
+            ((EntityItemProjectile) launch).setHeadingFromThrower(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
+        } else if(SnowballEntity.class == projectile) {
+            launch = new SnowballEntity(w, liv);
+            ((SnowballEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
+        } else if(EggEntity.class == projectile) {
+            launch = new EggEntity(w, liv);
+            ((EggEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
+        } else if(EnderPearlEntity.class == projectile) {
+            launch = new EnderPearlEntity(w, liv);
+            ((EnderPearlEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
+        } else if(PotionEntity.class == projectile) {
+            launch = new PotionEntity(w, liv);
+            ((PotionEntity) launch).setItem((ItemStack) data);
+            ((PotionEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, -20.0f, 0.5f, 1.0f);
+        } else if(ExperienceBottleEntity.class == projectile) {
+            launch = new ExperienceBottleEntity(w, liv);
+            ((ExperienceBottleEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, -20.0f, 0.7f, 1.0f);
+        } else if(AbstractArrowEntity.class.isAssignableFrom(projectile)) {
+            if(SpectralArrowEntity.class == projectile) {
+                launch = new SpectralArrowEntity(w, liv);
+            } else {
+                launch = new ArrowEntity(w, liv);
+                if(data != null) {
+                    ((ArrowEntity) launch).setPotionEffect((ItemStack) data);
+                }
+            }
+            ((AbstractArrowEntity) launch).shoot(liv, liv.rotationPitch, liv.rotationYaw, 0.0F, 3.0F, 1.0F);
+        } else if(DamagingProjectileEntity.class.isAssignableFrom(projectile)) {
+            Vec3d v = liv.getLookVec().scale(10);
+            if(SmallFireballEntity.class == projectile) {
+                launch = new SmallFireballEntity(w, liv, v.x, v.y, v.z);
+            } else if(WitherSkullEntity.class == projectile) {
+                launch = new WitherSkullEntity(w, liv, v.x, v.y, v.z);
+            } else if(DragonFireballEntity.class == projectile) {
+                launch = new DragonFireballEntity(w, liv, v.x, v.y, v.z);
+            } else {
+                launch = new FireballEntity(w, liv, v.x, v.y, v.z);
+            }
+        } else {
+            return null;
+        }
+
+        launch.setMotion(launch.getMotion().scale(scale));
+        w.addEntity(launch);
+        return (T) launch;
+    }
+}

+ 18 - 0
src/main/java/me/km/snuviscript/commands/EventCommands.java

@@ -0,0 +1,18 @@
+package me.km.snuviscript.commands;
+
+import java.util.UUID;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.events.CustomEventCaller;
+import me.km.events.PlayerMoveData;
+import me.km.utils.Location;
+
+public class EventCommands {
+    public static void registerFunctions(ScriptManager sm, CustomEventCaller cec) {
+        sm.registerFunction("event.addmovedata", (sc, in) -> {
+            UUID uuid = in.length >= 5 ? CommandUtils.getUUID(in[4].get(sc)) : null;
+            PlayerMoveData pmd = new PlayerMoveData(sc, (Location) in[0].get(sc), (Location) in[1].get(sc), in[2].getInt(sc), in[3].getInt(sc), uuid);
+            return (double) cec.registerMoveData(pmd);
+        });
+        sm.registerConsumer("event.removemovedata", (sc, in) -> cec.removeMoveData(in[0].getInt(sc)));
+    }
+}

+ 35 - 0
src/main/java/me/km/snuviscript/commands/HeadCommands.java

@@ -0,0 +1,35 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.networking.ModPacketHandler;
+import me.km.permissions.Permissions;
+import me.km.snuviscript.Scripts;
+import static me.km.snuviscript.commands.CommandUtils.doForGroup;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.server.MinecraftServer;
+
+public class HeadCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, MinecraftServer server) {
+        sm.registerConsumer("head.add", (sc, in) -> {
+            byte id = in[1].getByte(sc);
+            String name = in[2].getString(sc);
+            int x = in[3].getInt(sc);
+            int y = in[4].getInt(sc);
+            byte scale = in[5].getByte(sc);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> {
+                ModPacketHandler.sendToHead((ServerPlayerEntity) p, (byte) 1, id, name, x, y, scale);
+            });
+        });
+        sm.registerConsumer("head.remove", (sc, in) -> {
+            byte id = in[1].getByte(sc);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> {
+                ModPacketHandler.sendToHead((ServerPlayerEntity) p, (byte) 2, id, "", -1, -1, (byte) -1);
+            });
+        });
+        sm.registerConsumer("head.reset", (sc, in) -> {
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> {
+                ModPacketHandler.sendToHead((ServerPlayerEntity) p, (byte) 3, (byte) -1, "", -1, -1, (byte) -1);
+            });
+        });
+    }
+}

+ 29 - 0
src/main/java/me/km/snuviscript/commands/HumanCommands.java

@@ -0,0 +1,29 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.entities.EntityHuman;
+import me.km.entities.ModEntities;
+import me.km.utils.Location;
+import net.minecraft.world.World;
+
+public class HumanCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("human.spawn", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            World w = l.getWorld().getWorld();
+            EntityHuman h = ModEntities.HUMAN.create(w);
+            h.setPosition(l.getX(), l.getY(), l.getZ());
+            w.addEntity(h);
+            return h;
+        });
+        sm.registerConsumer("human.setskin", (sc, in) -> {
+            ((EntityHuman) in[0].get(sc)).setSkinName(in[1].getString(sc));
+        });
+        sm.registerConsumer("human.setscale", (sc, in) -> {
+            ((EntityHuman) in[0].get(sc)).setScale(in[1].getFloat(sc));
+        });
+        sm.registerConsumer("human.setslim", (sc, in) -> {
+            ((EntityHuman) in[0].get(sc)).setSlim(in[1].getBoolean(sc));
+        });
+    }
+}

+ 54 - 0
src/main/java/me/km/snuviscript/commands/InventoryCommands.java

@@ -0,0 +1,54 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.inventory.CustomContainer;
+import me.km.inventory.ModInventory;
+import me.km.utils.Location;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.ChestTileEntity;
+import net.minecraft.util.NonNullList;
+
+public class InventoryCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("inv.new", (sc, in) -> new ModInventory(in[0].getString(sc)));
+        sm.registerFunction("inv.getid", (sc, in) -> (double) ((ModInventory) in[0].get(sc)).getModId());
+        sm.registerFunction("inv.loadblock", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            ChestTileEntity chest = (ChestTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
+            int size = chest.getSizeInventory();
+            if(size % 9 != 0) {
+                size /= 9;
+                size++;
+                size *= 9;
+            }
+            ModInventory inv = new ModInventory(size);
+            for(int i = 0; i < chest.getSizeInventory(); i++) {
+                inv.setInventorySlotContents(i, chest.getStackInSlot(i).copy());
+            }
+            return inv;
+        });
+        sm.registerConsumer("inv.setitem", (sc, in) -> {
+            ((IInventory) in[0].get(sc)).setInventorySlotContents(in[1].getInt(sc), (ItemStack) in[2].get(sc));
+        });
+        sm.registerFunction("inv.getitem", (sc, in) -> ((IInventory) in[0].get(sc)).getStackInSlot(in[1].getInt(sc)));
+        sm.registerConsumer("inv.open", (sc, in) -> {
+            CustomContainer.openForPlayer((ServerPlayerEntity) in[1].get(sc), (ModInventory) in[0].get(sc), in[2].getString(sc), sc);
+        });
+        sm.registerConsumer("inv.close", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).closeScreen();
+        });
+        sm.registerConsumer("inv.update", (sc, in) -> {
+            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
+            NonNullList<ItemStack> list = NonNullList.<ItemStack>create();
+            int size = p.openContainer.inventorySlots.size();
+            for(int j = 0; j < size; j++) {
+                ItemStack itemstack = p.openContainer.inventorySlots.get(j).getStack();
+                list.add(itemstack.isEmpty() ? ItemStack.EMPTY : itemstack);
+            }
+            p.sendAllContents(p.openContainer, list);
+        });
+    }
+}

+ 107 - 0
src/main/java/me/km/snuviscript/commands/ItemCommands.java

@@ -0,0 +1,107 @@
+package me.km.snuviscript.commands;
+
+import java.util.List;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.utils.ItemStackUtils;
+import me.km.utils.Location;
+import me.km.utils.Mapper;
+import net.minecraft.block.Block;
+import net.minecraft.enchantment.Enchantment;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.ai.attributes.AttributeModifier;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.EquipmentSlotType;
+import net.minecraft.item.ArmorItem;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.potion.EffectInstance;
+import net.minecraft.potion.PotionUtils;
+import net.minecraft.tags.ItemTags;
+import net.minecraft.tags.Tag;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.text.StringTextComponent;
+import net.minecraft.world.World;
+
+public class ItemCommands {
+    @SuppressWarnings("")
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerConsumer("item.drop", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            World w = l.getWorld().getWorld();
+            BlockPos pos = l.getBlockPos();
+            ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
+            int amount = stack.getCount();
+            while(amount > stack.getMaxStackSize()) {
+                stack.setCount(stack.getMaxStackSize());
+                amount -= stack.getMaxStackSize();
+                Block.spawnAsEntity(w, pos, stack.copy());
+            }
+            if(amount > 0) {
+                stack.setCount(amount);
+                Block.spawnAsEntity(w, pos, stack);
+            }
+        });
+        sm.registerFunction("item.gettag", (sc, in) -> ItemTags.getCollection().get(new ResourceLocation(in[0].getString(sc))));
+        sm.registerFunction("item.hastag", (sc, in) -> ((Tag<Item>) in[0].get(sc)).contains(((ItemStack) in[1].get(sc)).getItem()));
+        sm.registerFunction("item.get", (sc, in) -> ((ItemStack) in[0].get(sc)).getItem());
+        sm.registerFunction("item.gettype", (sc, in) -> ((ItemStack) in[0].get(sc)).getItem().getRegistryName().toString());
+        sm.registerFunction("item.getamount", (sc, in) -> (double) ((ItemStack) in[0].get(sc)).getCount());
+        sm.registerConsumer("item.setamount", (sc, in) -> ((ItemStack) in[0].get(sc)).setCount(in[1].getInt(sc)));
+        sm.registerFunction("item.getname", (sc, in) -> ((ItemStack) in[0].get(sc)).getDisplayName().getFormattedText());
+        sm.registerConsumer("item.setname", (sc, in) -> {
+            ((ItemStack) in[0].get(sc)).setDisplayName(new StringTextComponent(SnuviUtils.connect(sc, in, 1)));
+        });
+        sm.registerFunction("item.getlore", (sc, in) -> ItemStackUtils.getLore((ItemStack) in[0].get(sc)));
+        sm.registerConsumer("item.setlore", (sc, in) -> {
+            ItemStackUtils.setLore((ItemStack) in[0].get(sc), (List<Object>) in[1].get(sc));
+        });
+        sm.registerConsumer("item.addlore", (sc, in) -> {
+            ItemStackUtils.addLore((ItemStack) in[0].get(sc), SnuviUtils.connect(sc, in, 2), in[1].getInt(sc));
+        });
+        sm.registerFunction("item.addenchant", (sc, in) -> {
+            ItemStack stack = (ItemStack) in[0].get(sc);
+            Enchantment ench = Mapper.getEnchantment(in[1].getString(sc));
+            int i = in[2].getInt(sc);
+            stack.addEnchantment(ench, i);
+            return true;
+        });
+        sm.registerFunction("item.getenchantlevel", (sc, in) -> (double) EnchantmentHelper.getEnchantmentLevel(Mapper.getEnchantment(in[1].getString(sc)), (ItemStack) in[0].get(sc)));
+        sm.registerConsumer("item.setcooldown", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).getCooldownTracker().setCooldown(((ItemStack) in[1].get(sc)).getItem(), in[2].getInt(sc));
+        });
+        sm.registerConsumer("item.addpotion", (sc, in) -> {
+            ItemStack stack = (ItemStack) in[0].get(sc);
+            List<EffectInstance> list = PotionUtils.getEffectsFromStack(stack);
+            list.add(new EffectInstance(Mapper.getPotion(in[1].getString(sc)), in[2].getInt(sc), in[3].getInt(sc)));
+            PotionUtils.appendEffects(stack, list);
+        });
+        sm.registerConsumer("item.addflag", (sc, in) -> {
+            ItemStackUtils.addItemFlag((ItemStack) in[0].get(sc), ItemStackUtils.ItemFlag.valueOf(in[1].getString(sc).toUpperCase()));
+        });
+        sm.registerConsumer("item.addattribute", (sc, in) -> {
+            ItemStackUtils.addAttribute((ItemStack) in[0].get(sc),
+                    ItemStackUtils.Attribute.valueOf(in[1].getString(sc).toUpperCase()),
+                    EquipmentSlotType.valueOf(in[2].getString(sc).toUpperCase()),
+                    in[3].getDouble(sc),
+                    AttributeModifier.Operation.valueOf(in[4].getString(sc).toUpperCase()));
+        });
+        sm.registerConsumer("item.setmagic", (sc, in) -> {
+            ItemStack stack = (ItemStack) in[0].get(sc);
+            int value = in[1].getInt(sc);
+            if(stack.getItem() instanceof ArmorItem) {
+                CompoundNBT com = stack.getTag();
+                if(com == null) {
+                    com = new CompoundNBT();
+                    stack.setTag(com);
+                }
+                com.putInt("magic", value);
+            } else {
+                throw new IllegalArgumentException("magic resistance is only for armor");
+            }
+        });
+        sm.registerFunction("item.clone", (sc, in) -> ((ItemStack) in[0].get(sc)).copy());
+    }
+}

+ 37 - 0
src/main/java/me/km/snuviscript/commands/ItemStackDisplayCommands.java

@@ -0,0 +1,37 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.networking.ModPacketHandler;
+import me.km.permissions.Permissions;
+import me.km.snuviscript.Scripts;
+import static me.km.snuviscript.commands.CommandUtils.doForGroup;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.server.MinecraftServer;
+
+public class ItemStackDisplayCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, MinecraftServer server) {
+        sm.registerConsumer("stacks.set", (sc, in) -> {
+            byte index = in[1].getByte(sc);
+            if(index < 0 || index >= 9) {
+                throw new IllegalArgumentException("index must be beetween 0 and 8, given: " + index);
+            }
+            int iconIndex = in[2].getInt(sc);
+            int count = in[3].getInt(sc);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.setItemStackIndex((ServerPlayerEntity) p, index, iconIndex, count));
+        });
+        sm.registerConsumer("stacks.clearindex", (sc, in) -> {
+            byte index = in[1].getByte(sc);
+            if(index < 0 || index >= 9) {
+                throw new IllegalArgumentException("index must be beetween 0 and 8, given: " + index);
+            }
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.setItemStackIndex((ServerPlayerEntity) p, index, -1, 0));
+        });
+        sm.registerConsumer("stacks.clear", (sc, in) -> {
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.clearItemStacks((ServerPlayerEntity) p));
+        });
+        sm.registerConsumer("stacks.setactive", (sc, in) -> {
+            boolean active = in[1].getBoolean(sc);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.setItemStackActive((ServerPlayerEntity) p, active));
+        });
+    }
+}

+ 37 - 0
src/main/java/me/km/snuviscript/commands/LivingCommands.java

@@ -0,0 +1,37 @@
+package me.km.snuviscript.commands;
+
+import java.util.UUID;
+import me.hammerle.snuviscript.code.ScriptManager;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.SharedMonsterAttributes;
+import net.minecraft.entity.ai.attributes.AttributeModifier;
+import net.minecraft.entity.ai.attributes.IAttribute;
+
+public class LivingCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        IAttribute[] attributes = new IAttribute[]{
+            SharedMonsterAttributes.ARMOR, SharedMonsterAttributes.ARMOR_TOUGHNESS,
+            SharedMonsterAttributes.ATTACK_DAMAGE, SharedMonsterAttributes.ATTACK_KNOCKBACK,
+            SharedMonsterAttributes.ATTACK_SPEED, SharedMonsterAttributes.FLYING_SPEED,
+            SharedMonsterAttributes.FOLLOW_RANGE, SharedMonsterAttributes.KNOCKBACK_RESISTANCE,
+            SharedMonsterAttributes.LUCK, SharedMonsterAttributes.MAX_HEALTH,
+            SharedMonsterAttributes.MOVEMENT_SPEED
+        };
+        for(IAttribute attribute : attributes) {
+            String name = attribute.getName().substring(8).toLowerCase();
+            sm.registerConsumer("living.set" + name, (sc, in) -> {
+                LivingEntity liv = (LivingEntity) in[0].get(sc);
+                double amount = in[1].getDouble(sc) - liv.getAttribute(attribute).getBaseValue();
+                UUID uuid = new UUID(name.length(), name.hashCode());
+                liv.getAttribute(attribute).removeModifier(uuid);
+                liv.getAttribute(attribute).applyModifier(new AttributeModifier(uuid, name, amount, AttributeModifier.Operation.ADDITION));
+            });
+            sm.registerFunction("living.get" + name, (sc, in) -> {
+                return ((LivingEntity) in[0].get(sc)).getAttribute(attribute).getValue();
+            });
+            sm.registerFunction("living.getbase" + name, (sc, in) -> {
+                return ((LivingEntity) in[0].get(sc)).getAttribute(attribute).getBaseValue();
+            });
+        }
+    }
+}

+ 85 - 0
src/main/java/me/km/snuviscript/commands/LocationCommands.java

@@ -0,0 +1,85 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.Location;
+import me.km.world.WorldManager;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.world.World;
+
+public class LocationCommands {
+    @SuppressWarnings("")
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("loc.new", (sc, in) -> {
+            if(in.length >= 6) {
+                return new Location((World) in[0].get(sc),
+                        in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc),
+                        in[4].getFloat(sc), in[5].getFloat(sc));
+            }
+            return new Location((World) in[0].get(sc), in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc), 0, 0);
+        });
+        sm.registerFunction("loc.getx", (sc, in) -> ((Location) in[0].get(sc)).getX());
+        sm.registerFunction("loc.gety", (sc, in) -> ((Location) in[0].get(sc)).getY());
+        sm.registerFunction("loc.getz", (sc, in) -> ((Location) in[0].get(sc)).getZ());
+        sm.registerConsumer("loc.setx", (sc, in) -> ((Location) in[0].get(sc)).setX(in[1].getDouble(sc)));
+        sm.registerConsumer("loc.sety", (sc, in) -> ((Location) in[0].get(sc)).setY(in[1].getDouble(sc)));
+        sm.registerConsumer("loc.setz", (sc, in) -> ((Location) in[0].get(sc)).setZ(in[1].getDouble(sc)));
+        sm.registerConsumer("loc.addx", (sc, in) -> ((Location) in[0].get(sc)).addX(in[1].getDouble(sc)));
+        sm.registerConsumer("loc.addy", (sc, in) -> ((Location) in[0].get(sc)).addY(in[1].getDouble(sc)));
+        sm.registerConsumer("loc.addz", (sc, in) -> ((Location) in[0].get(sc)).addZ(in[1].getDouble(sc)));
+        sm.registerConsumer("loc.setyaw", (sc, in) -> ((Location) in[0].get(sc)).setYaw(in[1].getFloat(sc)));
+        sm.registerFunction("loc.getyaw", (sc, in) -> (double) ((Location) in[0].get(sc)).getYaw());
+        sm.registerConsumer("loc.setpitch", (sc, in) -> ((Location) in[0].get(sc)).setPitch(in[1].getFloat(sc)));
+        sm.registerFunction("loc.getpitch", (sc, in) -> (double) ((Location) in[0].get(sc)).getPitch());
+        sm.registerFunction("loc.getworld", (sc, in) -> ((Location) in[0].get(sc)).getWorld());
+        sm.registerFunction("loc.distance", (sc, in) -> ((Location) in[0].get(sc)).getPos().distanceTo(((Location) in[1].get(sc)).getPos()));
+        sm.registerFunction("loc.mod", (sc, in) -> ((Location) in[0].get(sc)).copyAdd(in[1].getDouble(sc), in[2].getDouble(sc), in[3].getDouble(sc)));
+        sm.registerFunction("loc.getcoord", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            switch(in[1].getString(sc)) {
+                case "x":
+                    return l.getX();
+                case "y":
+                    return l.getY();
+                case "z":
+                    return l.getZ();
+                case "bx":
+                    return (double) MathHelper.floor(l.getX());
+                case "by":
+                    return (double) MathHelper.floor(l.getY());
+                case "bz":
+                    return (double) MathHelper.floor(l.getZ());
+                case "w":
+                    return WorldManager.getName(l.getWorld());
+                default:
+                    return null;
+            }
+        });
+        sm.registerFunction("loc.isbetween", (sc, in) -> {
+            Location l1 = (Location) in[0].get(sc);
+            Location l2 = (Location) in[1].get(sc);
+            Location l3 = (Location) in[2].get(sc);
+            return l1.getX() >= Math.min(l2.getX(), l3.getX()) && l1.getX() <= Math.max(l2.getX(), l3.getX())
+                    && l1.getY() >= Math.min(l2.getY(), l3.getY()) && l1.getY() <= Math.max(l2.getY(), l3.getY())
+                    && l1.getZ() >= Math.min(l2.getZ(), l3.getZ()) && l1.getZ() <= Math.max(l2.getZ(), l3.getZ());
+        });
+        sm.registerConsumer("loc.sort", (sc, in) -> {
+            Location l1 = (Location) in[0].get(sc);
+            Location l2 = (Location) in[1].get(sc);
+            if(l1.getX() > l2.getX()) {
+                double tmp = l1.getX();
+                l1.setX(l2.getX());
+                l2.setX(tmp);
+            }
+            if(l1.getY() > l2.getY()) {
+                double tmp = l1.getY();
+                l1.setY(l2.getY());
+                l2.setY(tmp);
+            }
+            if(l1.getZ() > l2.getZ()) {
+                double tmp = l1.getZ();
+                l1.setZ(l2.getZ());
+                l2.setZ(tmp);
+            }
+        });
+    }
+}

+ 74 - 0
src/main/java/me/km/snuviscript/commands/ParticleCommands.java

@@ -0,0 +1,74 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.Location;
+import me.km.utils.Mapper;
+import net.minecraft.item.ItemStack;
+import net.minecraft.particles.*;
+import net.minecraft.world.server.ServerWorld;
+
+public class ParticleCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("particle.get", (sc, in) -> {
+            IParticleData data = Mapper.getParticle(in[0].getString(sc));
+            if(data == ParticleTypes.BLOCK || data == ParticleTypes.FALLING_DUST) {
+                data = new BlockParticleData((ParticleType<BlockParticleData>) data, Mapper.getBlock(in[1].getString(sc)).getDefaultState());
+            } else if(data == ParticleTypes.DUST) {
+                data = new RedstoneParticleData(in[1].getFloat(sc), in[2].getFloat(sc), in[3].getFloat(sc), in[4].getFloat(sc));
+            } else if(data == ParticleTypes.ITEM) {
+                data = new ItemParticleData((ParticleType<ItemParticleData>) data, new ItemStack(Mapper.getItem(in[1].getString(sc))));
+            }
+            return data;
+        });
+        sm.registerConsumer("particle.spawn", (sc, in) -> {
+            Location l = ((Location) in[0].get(sc));
+            IParticleData data = ((IParticleData) in[1].get(sc));
+            int count = in.length >= 3 ? in[2].getInt(sc) : 1;
+            double speed = in.length >= 4 ? in[3].getDouble(sc) : 0.0;
+            double offX = in.length >= 5 ? in[4].getDouble(sc) : 0.0;
+            double offY = in.length >= 6 ? in[5].getDouble(sc) : 0.0;
+            double offZ = in.length >= 7 ? in[6].getDouble(sc) : 0.0;
+            ((ServerWorld) l.getWorld()).spawnParticle(data, l.getX(), l.getY(), l.getZ(), count, offX, offY, offZ, speed);
+        });
+        sm.registerConsumer("particle.spawncircle", (sc, in) -> {
+            Location l = ((Location) in[0].get(sc));
+            IParticleData data = ((IParticleData) in[1].get(sc));
+            int instances = in[2].getInt(sc);
+            double radius = in[3].getDouble(sc);
+            int count = in.length >= 5 ? in[4].getInt(sc) : 1;
+            double speed = in.length >= 6 ? in[5].getDouble(sc) : 0.0;
+            double offX = in.length >= 7 ? in[6].getDouble(sc) : 0.0;
+            double offY = in.length >= 8 ? in[7].getDouble(sc) : 0.0;
+            double offZ = in.length >= 9 ? in[8].getDouble(sc) : 0.0;
+            double x = l.getX();
+            double y = l.getY();
+            double z = l.getZ();
+            ServerWorld sw = (ServerWorld) l.getWorld();
+            double angle = 2 * Math.PI / instances;
+            for(int i = 0; i < instances; i++) {
+                sw.spawnParticle(data, x + Math.cos(i * angle) * radius, y, z + Math.sin(i * angle) * radius, count, offX, offY, offZ, speed);
+            }
+        });
+        sm.registerConsumer("particle.spawnline", (sc, in) -> {
+            Location l = ((Location) in[0].get(sc));
+            IParticleData data = ((IParticleData) in[1].get(sc));
+            int instances = in[2].getInt(sc);
+            double stepX = in[3].getDouble(sc);
+            double stepY = in[4].getDouble(sc);
+            double stepZ = in[5].getDouble(sc);
+
+            int count = in.length >= 7 ? in[6].getInt(sc) : 1;
+            double speed = in.length >= 8 ? in[7].getDouble(sc) : 0.0;
+            double offX = in.length >= 9 ? in[8].getDouble(sc) : 0.0;
+            double offY = in.length >= 10 ? in[9].getDouble(sc) : 0.0;
+            double offZ = in.length >= 11 ? in[10].getDouble(sc) : 0.0;
+            double x = l.getX();
+            double y = l.getY();
+            double z = l.getZ();
+            ServerWorld sw = (ServerWorld) l.getWorld();
+            for(int i = 0; i < instances; i++) {
+                sw.spawnParticle(data, x + i * stepX, y + i * stepY, z + i * stepZ, count, offX, offY, offZ, speed);
+            }
+        });
+    }
+}

+ 17 - 0
src/main/java/me/km/snuviscript/commands/PermissionCommands.java

@@ -0,0 +1,17 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.permissions.Permissions;
+import net.minecraft.entity.Entity;
+
+public class PermissionCommands {
+    public static void registerFunctions(ScriptManager sm, Permissions perms) {
+        sm.registerConsumer("perm.clear", (sc, in) -> perms.clear());
+        sm.registerConsumer("perm.registergroup", (sc, in) -> perms.register(in[0].getInt(sc), in[1].getString(sc)));
+        sm.registerConsumer("perm.registerplayer", (sc, in) -> {
+            perms.register(CommandUtils.getUUID(in[0].get(sc)), in[1].getInt(sc));
+        });
+        sm.registerFunction("perm.unregisterplayer", (sc, in) -> perms.unregister(CommandUtils.getUUID(in[0].get(sc)), in[1].getInt(sc)));
+        sm.registerFunction("perm.has", (sc, in) -> perms.has((Entity) in[0].get(sc), in[1].getString(sc)));
+    }
+}

+ 287 - 0
src/main/java/me/km/snuviscript/commands/PlayerCommands.java

@@ -0,0 +1,287 @@
+package me.km.snuviscript.commands;
+
+import com.mojang.authlib.GameProfile;
+import java.util.ArrayList;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.inventory.InventoryUtils;
+import me.km.overrides.ModEntityPlayerMP;
+import me.km.permissions.Permissions;
+import me.km.playerbank.IPlayerBank;
+import me.km.scheduler.SnuviScheduler;
+import me.km.snuviscript.Scripts;
+import static me.km.snuviscript.commands.CommandUtils.*;
+import me.km.utils.Location;
+import me.km.utils.ReflectionUtils;
+import me.km.utils.Utils;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.inventory.EnderChestInventory;
+import net.minecraft.inventory.container.ChestContainer;
+import net.minecraft.inventory.container.SimpleNamedContainerProvider;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.nbt.NBTUtil;
+import net.minecraft.network.ThreadQuickExitException;
+import net.minecraft.network.play.client.CChatMessagePacket;
+import net.minecraft.network.play.client.CClientStatusPacket;
+import net.minecraft.network.play.server.SSpawnPositionPacket;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.tileentity.SkullTileEntity;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.RayTraceContext;
+import net.minecraft.util.math.RayTraceResult;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.util.text.StringTextComponent;
+import net.minecraft.world.GameType;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+
+public class PlayerCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts,
+            Permissions perms, SnuviScheduler scheduler, MinecraftServer server,
+            IPlayerBank playerBank) {
+        sm.registerFunction("player.getitemamount", (sc, in) -> (double) InventoryUtils.searchInventoryFor(((PlayerEntity) in[0].get(sc)).inventory, (ItemStack) in[2].get(sc), in[1].getBoolean(sc)));
+        sm.registerFunction("player.removeitem", (sc, in) -> {
+            ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
+            stack.setCount(InventoryUtils.removeFromInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
+            return stack;
+        });
+        sm.registerFunction("player.giveitem", (sc, in) -> {
+            ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
+            stack.setCount(InventoryUtils.addToInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
+            return stack;
+        });
+        sm.registerConsumer("player.respawn", (sc, in) -> {
+            final ServerPlayerEntity p = ((ServerPlayerEntity) in[0].get(sc));
+            scheduler.scheduleTask(() -> {
+                try {
+                    p.connection.processClientStatus(new CClientStatusPacket(CClientStatusPacket.State.PERFORM_RESPAWN));
+                } catch(ThreadQuickExitException ex) {
+                    // Minecraft needs this for canceling and queueing into main thread
+                }
+            });
+        });
+        sm.registerConsumer("player.clearinventory", (sc, in) -> ((PlayerEntity) in[0].get(sc)).inventory.clear());
+        sm.registerFunction("player.inventorytolist", (sc, in) -> ((PlayerEntity) in[1].get(sc)).inventory.mainInventory);
+        sm.registerFunction("player.getnearest", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return l.getWorld().getClosestPlayer(l.getX(), l.getY(), l.getZ(), -1, p -> true);
+        });
+        sm.registerConsumer("player.say", (sc, in) -> {
+            try {
+                ((ServerPlayerEntity) in[0].get(sc)).connection.processChatMessage(new CChatMessagePacket(SnuviUtils.connect(sc, in, 1)));
+            } catch(ThreadQuickExitException ex) {
+                // Minecraft needs this for canceling and queueing into main thread
+            }
+        });
+        sm.registerConsumer("player.speak", (sc, in) -> {
+            sendMessageToGroup(server, scripts, perms, in[0].get(sc), sc, concat(sc, 2, "§7[§r" + in[1].getString(sc) + "§7]§r ", in));
+        });
+        sm.registerConsumer("player.setcompass", (sc, in) -> {
+            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new SSpawnPositionPacket(((Location) in[1].get(sc)).getBlockPos()));
+        });
+        sm.registerFunction("player.gethunger", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).getFoodStats().getFoodLevel());
+        sm.registerConsumer("player.sethunger", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).getFoodStats().setFoodLevel(in[1].getInt(sc));
+        });
+        sm.registerFunction("player.getsaturation", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).getFoodStats().getSaturationLevel());
+        sm.registerConsumer("player.setsaturation", (sc, in) -> {
+            ReflectionUtils.setSaturation(((PlayerEntity) in[0].get(sc)).getFoodStats(), in[1].getFloat(sc));
+        });
+        sm.registerFunction("player.getname", (sc, in) -> {
+            Object o = in[0].get(sc);
+            if(o instanceof PlayerEntity) {
+                return ((PlayerEntity) o).getName().getFormattedText();
+            }
+            return server.getPlayerProfileCache().getProfileByUUID(getUUID(o.toString())).getName();
+        });
+        sm.registerFunction("player.getuuid", (sc, in) -> {
+            Object o = in[0].get(sc);
+            if(o instanceof PlayerEntity) {
+                return ((PlayerEntity) o).getUniqueID();
+            }
+            return playerBank.getUUID(o.toString());
+        });
+        sm.registerFunction("player.getid", (sc, in) -> (double) getId(playerBank, in[0].get(sc)));
+        sm.registerFunction("player.get", (sc, in) -> server.getPlayerList().getPlayerByUUID(getUUID(in[0].get(sc))));
+        sm.registerFunction("player.getuuidfromid", (sc, in) -> playerBank.getUUIDfromID(in[0].getInt(sc)));
+        sm.registerFunction("player.getnamefromid", (sc, in) -> playerBank.getNamefromID(in[0].getInt(sc)));
+        sm.registerFunction("player.getip", (sc, in) -> ((ServerPlayerEntity) in[0].get(sc)).connection.netManager.getRemoteAddress().toString());
+        sm.registerFunction("player.iscreative", (sc, in) -> ((PlayerEntity) in[0].get(sc)).isCreative());
+        sm.registerFunction("player.isspectator", (sc, in) -> ((PlayerEntity) in[0].get(sc)).isSpectator());
+        sm.registerFunction("player.issurvival", (sc, in) -> {
+            PlayerEntity p = (PlayerEntity) in[0].get(sc);
+            return !p.isCreative() && !p.isSpectator();
+        });
+        sm.registerFunction("player.isadventure", (sc, in) -> !((PlayerEntity) in[0].get(sc)).abilities.allowEdit);
+        sm.registerConsumer("player.setfly", (sc, in) -> {
+            PlayerEntity p = ((PlayerEntity) in[0].get(sc));
+            boolean b = in[1].getBoolean(sc);
+            p.abilities.allowFlying = b;
+            p.abilities.isFlying = b;
+            p.sendPlayerAbilities();
+        });
+        sm.registerFunction("player.hasfly", (sc, in) -> ((PlayerEntity) in[0].get(sc)).abilities.allowFlying);
+        sm.registerFunction("player.isflying", (sc, in) -> ((PlayerEntity) in[0].get(sc)).abilities.isFlying);
+        sm.registerConsumer("player.setgamemode", (sc, in) -> {
+            PlayerEntity p = (PlayerEntity) in[0].get(sc);
+            switch(in[1].get(sc).toString()) {
+                case "survival":
+                case "s":
+                case "0":
+                    p.setGameType(GameType.SURVIVAL);
+                    break;
+                case "creative":
+                case "c":
+                case "1":
+                    p.setGameType(GameType.CREATIVE);
+                    break;
+                case "adventure":
+                case "a":
+                case "2":
+                    p.setGameType(GameType.ADVENTURE);
+                    break;
+                case "spectator":
+                case "w":
+                case "3":
+                    p.setGameType(GameType.SPECTATOR);
+                    break;
+                default:
+                    p.setGameType(GameType.CREATIVE);
+                    break;
+            }
+        });
+        sm.registerFunction("player.getlastdamager", (sc, in) -> {
+            DamageSource ds = ((PlayerEntity) in[0].get(sc)).getLastDamageSource();
+            if(ds == null) {
+                return null;
+            }
+            return ds.getImmediateSource();
+        });
+        sm.registerConsumer("player.dropinventory", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).inventory.dropAllItems();
+        });
+        sm.registerFunction("player.gettarget", (sc, in) -> {
+            PlayerEntity p = (PlayerEntity) in[0].get(sc);
+
+            double radius = in[1].getDouble(sc);
+            if(radius > 128.0) {
+                radius = 128.0;
+            }
+
+            RayTraceContext.BlockMode bm = RayTraceContext.BlockMode.OUTLINE;
+            if(in.length >= 3 && in[2].getBoolean(sc)) {
+                bm = RayTraceContext.BlockMode.COLLIDER;
+            }
+            RayTraceContext.FluidMode fm = RayTraceContext.FluidMode.NONE;
+            if(in.length >= 4 && in[3].getBoolean(sc)) {
+                fm = RayTraceContext.FluidMode.ANY;
+            }
+
+            Vec3d start = p.getEyePosition(0.0f);
+            Vec3d unit = p.getLook(0.0f);
+            Vec3d end = start.add(unit.x * radius, unit.y * radius, unit.z * radius);
+
+            BlockRayTraceResult result = p.world.rayTraceBlocks(new RayTraceContext(start, end, bm, fm, p));
+
+            if(result.getType() == RayTraceResult.Type.BLOCK) {
+                return new Location(p.world, result.getPos());
+            }
+
+            return new Location(p.world, end);
+        });
+
+        sm.registerFunction("player.gettargetentity", (sc, in) -> Utils.getTargetedEntity((PlayerEntity) in[0].get(sc), in[1].getDouble(sc), getNamedClass(in[2].getString(sc))));
+        sm.registerFunction("player.hasscript", (sc, in) -> scripts.isRegistered((PlayerEntity) in[0].get(sc)));
+        sm.registerAlias("player.hasscript", "player.hasquest");
+        sm.registerConsumer("player.action", (sc, in) -> {
+            StringTextComponent text = new StringTextComponent(SnuviUtils.connect(sc, in, 1));
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ServerPlayerEntity) p).sendStatusMessage(text, true));
+        });
+        sm.registerConsumer("player.disconnect", (sc, in) -> {
+            ((ServerPlayerEntity) in[0].get(sc)).connection.disconnect(new StringTextComponent(in[1].getString(sc)));
+        });
+        sm.registerFunction("player.kick", (sc, in) -> scripts.unregisterPlayer(sc, (PlayerEntity) in[0].get(sc)));
+        sm.registerFunction("player.getspawn", (sc, in) -> {
+            ServerWorld ws = (ServerWorld) in[1].get(sc);
+            return new Location(ws, ((PlayerEntity) in[0].get(sc)).getBedLocation(ws.getDimension().getType()));
+        });
+        sm.registerAlias("player.getspawn", "player.getbedspawn");
+        sm.registerConsumer("player.setspawn", (sc, in) -> {
+            Location l = (Location) in[1].get(sc);
+            ((ServerPlayerEntity) in[0].get(sc)).setSpawnPoint(l.getBlockPos(), true, false, l.getWorld().getDimension().getType());
+        });
+        sm.registerAlias("player.setspawn", "player.setbedspawn");
+        sm.registerConsumer("player.damageitem", (sc, in) -> {
+            PlayerEntity p = (PlayerEntity) in[0].get(sc);
+            p.getHeldItemMainhand().damageItem(in[1].getInt(sc), p, (c) -> {
+            });
+        });
+        sm.registerConsumer("player.damagearmor", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).inventory.damageArmor(in[1].getFloat(sc));
+        });
+        sm.registerConsumer("player.openenderchest", (sc, in) -> {
+            PlayerEntity p1 = (PlayerEntity) in[0].get(sc);
+            PlayerEntity p2 = (PlayerEntity) in[1].get(sc);
+
+            EnderChestInventory inv = p2.getInventoryEnderChest();
+            p1.openContainer(new SimpleNamedContainerProvider((id, pInv, p) -> {
+                return ChestContainer.createGeneric9X3(id, pInv, inv);
+            }, new StringTextComponent(in[2].getString(sc))));
+        });
+        sm.registerFunction("player.getlevel", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).experienceLevel);
+        sm.registerFunction("player.getexp", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).experience);
+        sm.registerConsumer("player.addlevel", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).addExperienceLevel(in[1].getInt(sc));
+        });
+        sm.registerConsumer("player.setexp", (sc, in) -> {
+            PlayerEntity p = (PlayerEntity) in[0].get(sc);
+            float f = in[1].getFloat(sc);
+            if(f < 0.0f) {
+                f = 0.0f;
+            } else if(f > 1.0f) {
+                f = 1.0f;
+            }
+            p.giveExperiencePoints((int) (f * p.xpBarCap()));
+        });
+        sm.registerFunction("player.gethead", (sc, in) -> {
+            ItemStack stack = new ItemStack(Items.PLAYER_HEAD);
+            CompoundNBT com = stack.getOrCreateTag();
+            GameProfile gp = new GameProfile(getUUID(in[0].get(sc)), in[1].getString(sc));
+            gp = SkullTileEntity.updateGameProfile(gp);
+            com.put("SkullOwner", NBTUtil.writeGameProfile(new CompoundNBT(), gp));
+            return stack;
+        });
+        sm.registerFunction("player.setspeed", (sc, in) -> {
+            PlayerEntity p = (PlayerEntity) in[0].get(sc);
+            float f = in[1].getFloat(sc);
+            ReflectionUtils.setFlySpeed(p.abilities, f);
+            ReflectionUtils.setWalkSpeed(p.abilities, f * 2);
+            p.sendPlayerAbilities();
+            return true;
+        });
+        sm.registerFunction("player.near", (sc, in) -> Utils.getPlayers((Entity) in[0].get(sc), in[1].getDouble(sc)));
+        sm.registerFunction("player.getinvslot", (sc, in) -> ((PlayerEntity) in[0].get(sc)).inventory.mainInventory.get(in[1].getInt(sc)));
+        sm.registerConsumer("player.setinvslot", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).inventory.mainInventory.set(in[1].getInt(sc), ((ItemStack) in[2].get(sc)).copy());
+        });
+        sm.registerFunction("player.getenderslot", (sc, in) -> ((PlayerEntity) in[0].get(sc)).getInventoryEnderChest().getStackInSlot(in[1].getInt(sc)));
+        sm.registerConsumer("player.setenderslot", (sc, in) -> {
+            ((PlayerEntity) in[0].get(sc)).getInventoryEnderChest().setInventorySlotContents(in[1].getInt(sc), ((ItemStack) in[2].get(sc)).copy());
+        });
+        sm.registerConsumer("player.setdisplayname", (sc, in) -> {
+            ((ModEntityPlayerMP) in[0].get(sc)).setTabListDisplayName(in[1].getString(sc), scheduler);
+        });
+        sm.registerFunction("players.getamount", (sc, in) -> (double) server.getCurrentPlayerCount());
+        sm.registerFunction("players.tolist", (sc, in) -> new ArrayList(server.getPlayerList().getPlayers()));
+        sm.registerFunction("players.toworldlist", (sc, in) -> new ArrayList(((World) in[0].get(sc)).getPlayers()));
+        sm.registerFunction("players.near", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return Utils.getPlayers(l.getWorld(), l.getX(), l.getY(), l.getZ(), in[1].getDouble(sc));
+        });
+    }
+}

+ 63 - 0
src/main/java/me/km/snuviscript/commands/PlotCommands.java

@@ -0,0 +1,63 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.overrides.ModEntityPlayerMP;
+import me.km.plots.PlotMap;
+import me.km.plots.WorldPlotMap;
+import me.km.utils.Location;
+import net.minecraft.world.IWorld;
+
+public class PlotCommands {
+    public static void registerFunctions(ScriptManager sm, WorldPlotMap plots) {
+        sm.registerFunction("plot.get", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            return plots.getPlots(l.getWorld(), l.getBlockPos());
+        });
+        sm.registerFunction("plot.check", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            ModEntityPlayerMP p = (ModEntityPlayerMP) in[1].get(sc);
+            int flags = in[2].getInt(sc);
+            boolean empty = in[3].getBoolean(sc);
+            return plots.canDoSomething(l.getWorld(), l.getBlockPos(), p, flags, empty);
+        });
+        sm.registerConsumer("plot.setflags", (sc, in) -> {
+            PlotMap.Plot p = (PlotMap.Plot) in[0].get(sc);
+            p.setFlag(in[1].getInt(sc), in[2].getBoolean(sc));
+        });
+        sm.registerFunction("plot.hasflags", (sc, in) -> ((PlotMap.Plot) in[0].get(sc)).hasFlags(in[1].getInt(sc)));
+        sm.registerFunction("plot.getflags", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getFlags());
+        sm.registerFunction("plot.getowners", (sc, in) -> ((PlotMap.Plot) in[0].get(sc)).getOwners());
+        sm.registerFunction("plot.add", (sc, in) -> {
+            Location l1 = (Location) in[0].get(sc);
+            Location l2 = (Location) in[1].get(sc);
+            if(l1.getWorld() != l2.getWorld()) {
+                throw new IllegalArgumentException("worlds not equal for locations");
+            }
+            return plots.add(l1.getWorld(), l1.getBlockPos(), l2.getBlockPos());
+        });
+        sm.registerConsumer("plot.remove", (sc, in) -> {
+            plots.remove((IWorld) in[1].get(sc), (PlotMap.Plot) in[0].get(sc));
+        });
+        sm.registerFunction("plot.getname", (sc, in) -> ((PlotMap.Plot) in[0].get(sc)).getName());
+        sm.registerConsumer("plot.setname", (sc, in) -> {
+            ((PlotMap.Plot) in[0].get(sc)).setName(in[1].getString(sc));
+        });
+        sm.registerFunction("plot.getid", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getId());
+        sm.registerFunction("plot.iterator", (sc, in) -> {
+            IWorld word = (IWorld) in[0].get(sc);
+            if(in.length >= 2) {
+                plots.getIterator(word, CommandUtils.getUUID(in[1].get(sc)));
+            }
+            return plots.getIterator(word);
+        });
+        sm.registerFunction("plot.intersecting", (sc, in) -> plots.getIntersectingPlots((IWorld) in[0].get(sc), in[1].getInt(sc),
+                in[2].getInt(sc), in[3].getInt(sc), in[4].getInt(sc),
+                in[5].getInt(sc), in[6].getInt(sc)));
+        sm.registerFunction("plot.getminx", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getMinX());
+        sm.registerFunction("plot.getminy", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getMinY());
+        sm.registerFunction("plot.getminz", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getMinZ());
+        sm.registerFunction("plot.getmaxx", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getMaxX());
+        sm.registerFunction("plot.getmaxy", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getMaxY());
+        sm.registerFunction("plot.getmaxz", (sc, in) -> (double) ((PlotMap.Plot) in[0].get(sc)).getMaxZ());
+    }
+}

+ 53 - 0
src/main/java/me/km/snuviscript/commands/ReadCommands.java

@@ -0,0 +1,53 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.utils.ItemStackUtils;
+import me.km.utils.Location;
+import me.km.utils.Mapper;
+import me.km.utils.Utils;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.nbt.JsonToNBT;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.text.StringTextComponent;
+import net.minecraft.world.server.ServerWorld;
+
+public class ReadCommands {
+    public static void registerFunctions(ScriptManager sm, MinecraftServer server) {
+        sm.registerFunction("read.player", (sc, in) -> Utils.getPlayerByName(server, in[0].getString(sc)));
+        sm.registerFunction("read.location", (sc, in) -> new Location(server, in[0].getString(sc)));
+        sm.registerFunction("read.item", (sc, in) -> {
+            String s = in[0].getString(sc);
+            if(s.startsWith("{")) {
+                String left = SnuviUtils.connect(sc, in, 1);
+                return ItemStackUtils.getStackFromNbtString(s + left);
+            }
+            Item item = Mapper.getItem(s);
+            int amount = in.length >= 2 ? in[1].getInt(sc) : 1;
+            ItemStack stack = new ItemStack(item, amount);
+            if(in.length >= 3) {
+                stack.setDisplayName(new StringTextComponent(in[2].getString(sc)));
+            }
+            if(in.length >= 4) {
+                for(int i = 3; i < in.length; i++) {
+                    ItemStackUtils.addLore(stack, in[i].getString(sc));
+                }
+            }
+            return stack;
+        });
+        sm.registerFunction("read.spawnmob", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            ServerWorld sw = (ServerWorld) l.getWorld();
+            CompoundNBT compoundnbt = JsonToNBT.getTagFromJson(SnuviUtils.connect(sc, in, 1));
+            Entity entity = EntityType.func_220335_a(compoundnbt, sw, (ent) -> {
+                ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch);
+                return sw.summonEntity(ent) ? ent : null;
+            });
+            return entity;
+        });
+    }
+}

+ 26 - 0
src/main/java/me/km/snuviscript/commands/ScoreboardCommands.java

@@ -0,0 +1,26 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.overrides.ModEntityPlayerMP;
+import me.km.permissions.Permissions;
+import static me.km.snuviscript.commands.CommandUtils.doForGroup;
+import me.km.snuviscript.Scripts;
+import net.minecraft.server.MinecraftServer;
+
+public class ScoreboardCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, MinecraftServer server) {
+        sm.registerConsumer("sb.add", (sc, in) -> {
+            int id = in[1].getInt(sc);
+            String message = SnuviUtils.connect(sc, in, 2);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ModEntityPlayerMP) p).getScoreboard().addText(id, message));
+        });
+        sm.registerConsumer("sb.remove", (sc, in) -> {
+            int id = in[1].getInt(sc);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ModEntityPlayerMP) p).getScoreboard().removeText(id));
+        });
+        sm.registerConsumer("sb.reset", (sc, in) -> {
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ModEntityPlayerMP) p).getScoreboard().clear((ModEntityPlayerMP) p));
+        });
+    }
+}

+ 43 - 0
src/main/java/me/km/snuviscript/commands/ScriptCommands.java

@@ -0,0 +1,43 @@
+package me.km.snuviscript.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import me.hammerle.snuviscript.code.Script;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.snuviscript.Scripts;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.server.MinecraftServer;
+
+public class ScriptCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, MinecraftServer server) {
+        sm.registerFunction("script.playerstolist", (sc, in) -> new ArrayList<>(scripts.getPlayerList(sc.getId())));
+        sm.registerFunction("script.getplayeramount", (sc, in) -> (double) scripts.getPlayerList(sc.getId()).size());
+        sm.registerFunction("script.start", (sc, in) -> {
+            Object o = in[0].get(sc);
+            if(o instanceof PlayerEntity) {
+                String[] names = new String[in.length - 1];
+                for(int i = 1; i < in.length; i++) {
+                    names[i - 1] = in[i].getString(sc);
+                }
+                return scripts.startPlayerScript((PlayerEntity) in[0].get(sc), names);
+            }
+            String[] names = new String[in.length];
+            names[0] = o.toString();
+            for(int i = 1; i < in.length; i++) {
+                names[i] = in[i].getString(sc);
+            }
+            scripts.startScript(names);
+            return true;
+        });
+        sm.registerFunction("script.join", (sc, in) -> scripts.registerPlayer((Script) in[0].get(sc), (PlayerEntity) in[1].get(sc)));
+        sm.registerFunction("script.kick", (sc, in) -> scripts.unregisterPlayer(sc, (PlayerEntity) in[0].get(sc)));
+        sm.registerFunction("script.getleader", (sc, in) -> {
+            List<UUID> players = scripts.getPlayerList(sc.getId());
+            if(players.isEmpty()) {
+                return null;
+            }
+            return server.getPlayerList().getPlayerByUUID(players.get(0));
+        });
+    }
+}

+ 31 - 0
src/main/java/me/km/snuviscript/commands/SoundCommands.java

@@ -0,0 +1,31 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.Location;
+import me.km.utils.Mapper;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.network.play.server.SPlaySoundEffectPacket;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.world.server.ServerWorld;
+
+public class SoundCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("sound.get", (sc, in) -> Mapper.getSound(in[0].getString(sc)));
+        sm.registerFunction("sound.getcategory", (sc, in) -> Mapper.getSoundCategory(in[0].getString(sc)));
+        sm.registerConsumer("sound.spawn", (sc, in) -> {
+            Location l = (Location) in[0].get(sc);
+            ServerWorld sw = (ServerWorld) l.getWorld();
+            float volume = in.length >= 4 ? in[3].getFloat(sc) : 1.0f;
+            float pitch = in.length >= 5 ? in[4].getFloat(sc) : (sw.rand.nextFloat() * 0.1f + 0.9f);
+            sw.playSound(null, l.getX(), l.getY(), l.getZ(), (SoundEvent) in[1].get(sc), (SoundCategory) in[2].get(sc), volume, pitch);
+        });
+        sm.registerConsumer("sound.spawnforplayer", (sc, in) -> {
+            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
+            float volume = in.length >= 4 ? in[3].getFloat(sc) : 1.0f;
+            float pitch = in.length >= 5 ? in[4].getFloat(sc) : (p.world.rand.nextFloat() * 0.1f + 0.9f);
+            p.connection.sendPacket(new SPlaySoundEffectPacket((SoundEvent) in[1].get(sc),
+                    (SoundCategory) in[2].get(sc), p.getPosX(), p.getPosY(), p.getPosZ(), volume, pitch));
+        });
+    }
+}

+ 33 - 0
src/main/java/me/km/snuviscript/commands/StatusCommands.java

@@ -0,0 +1,33 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import me.km.networking.ModPacketHandler;
+import me.km.permissions.Permissions;
+import me.km.snuviscript.Scripts;
+import static me.km.snuviscript.commands.CommandUtils.doForGroup;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.server.MinecraftServer;
+
+public class StatusCommands {
+    public static void registerFunctions(ScriptManager sm, Scripts scripts, Permissions perms, MinecraftServer server) {
+        sm.registerConsumer("status.add", (sc, in) -> {
+            byte index = in[1].getByte(sc);
+            String message = SnuviUtils.connect(sc, in, 2);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.addStatus((ServerPlayerEntity) p, index, message));
+        });
+        sm.registerConsumer("status.addtimed", (sc, in) -> {
+            byte index = in[1].getByte(sc);
+            int time = in[2].getInt(sc);
+            String message = SnuviUtils.connect(sc, in, 3);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.addTimedStatus((ServerPlayerEntity) p, index, message, time));
+        });
+        sm.registerConsumer("status.remove", (sc, in) -> {
+            byte index = in[1].getByte(sc);
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.removeStatus((ServerPlayerEntity) p, index));
+        });
+        sm.registerConsumer("status.reset", (sc, in) -> {
+            doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ModPacketHandler.clearStatus((ServerPlayerEntity) p));
+        });
+    }
+}

+ 25 - 0
src/main/java/me/km/snuviscript/commands/TableCommands.java

@@ -0,0 +1,25 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.TableUtils;
+
+public class TableCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("table.getstart", (sc, in) -> {
+            return TableUtils.getTableStart(in[0].getInt(sc), in[1].getInt(sc), in[2].getString(sc));
+        });
+        sm.registerFunction("table.getmiddle", (sc, in) -> {
+            return TableUtils.getTableMiddle(in[0].getInt(sc), in[1].getInt(sc), in[2].getString(sc));
+        });
+        sm.registerFunction("table.getend", (sc, in) -> {
+            return TableUtils.getTableEnd(in[0].getInt(sc), in[1].getInt(sc), in[2].getString(sc));
+        });
+        sm.registerFunction("table.get", (sc, in) -> {
+            String[] columns = new String[in.length - 2];
+            for(int i = 0; i < columns.length; i++) {
+                columns[i] = in[i + 2].getString(sc);
+            }
+            return TableUtils.getTable(in[0].getInt(sc), in[1].getString(sc), columns);
+        });
+    }
+}

+ 67 - 0
src/main/java/me/km/snuviscript/commands/TextCommands.java

@@ -0,0 +1,67 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.ItemStackUtils;
+import me.km.utils.Location;
+import net.minecraft.entity.Entity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.text.*;
+import net.minecraft.util.text.event.ClickEvent;
+import net.minecraft.util.text.event.HoverEvent;
+
+public class TextCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerFunction("text.location", (sc, in) -> ((Location) in[0].get(sc)).toString());
+        sm.registerFunction("text.locationblock", (sc, in) -> ((Location) in[0].get(sc)).toBlockString());
+        sm.registerFunction("text.item", (sc, in) -> ItemStackUtils.getNbtString((ItemStack) in[0].get(sc)));
+        sm.registerFunction("text.click", (sc, in) -> {
+            Object message = in[0].get(sc);
+            ITextComponent text;
+            if(message instanceof ITextComponent) {
+                text = (ITextComponent) message;
+            } else {
+                text = new StringTextComponent(String.valueOf(message));
+            }
+            Style style = text.getStyle();
+            style.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, in[1].getString(sc)));
+            return text;
+        });
+        sm.registerFunction("text.hover", (sc, in) -> {
+            Object message = in[0].get(sc);
+            ITextComponent text;
+            if(message instanceof ITextComponent) {
+                text = (ITextComponent) message;
+            } else {
+                text = new StringTextComponent(String.valueOf(message));
+            }
+            Style style = text.getStyle();
+            style.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new StringTextComponent(in[1].getString(sc))));
+            return text;
+        });
+        sm.registerFunction("text.link", (sc, in) -> {
+            StringTextComponent text = new StringTextComponent(in[0].getString(sc));
+            Style style = text.getStyle();
+            style.setColor(TextFormatting.RED);
+            style.setBold(true);
+            style.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, in[1].getString(sc)));
+            return text;
+        });
+        sm.registerFunction("text.copytext", (sc, in) -> {
+            String s = in[1].getString(sc);
+            s = s.replace(" ", "%20");
+
+            StringTextComponent text = new StringTextComponent(in[0].getString(sc));
+            Style style = text.getStyle();
+            style.setColor(TextFormatting.RED);
+            style.setBold(true);
+            style.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "http://minecraft.hammerle.me/showtext.php/?text=" + s));
+            return text;
+        });
+        sm.registerFunction("text.entity", (sc, in) -> {
+            CompoundNBT tag = new CompoundNBT();
+            ((Entity) in[0].get(sc)).writeWithoutTypeId(tag);
+            return tag.toString();
+        });
+    }
+}

+ 33 - 0
src/main/java/me/km/snuviscript/commands/TitleCommands.java

@@ -0,0 +1,33 @@
+package me.km.snuviscript.commands;
+
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.hammerle.snuviscript.code.SnuviUtils;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.network.play.server.STitlePacket;
+import net.minecraft.util.text.ITextComponent;
+import net.minecraft.util.text.StringTextComponent;
+
+public class TitleCommands {
+    public static void registerFunctions(ScriptManager sm) {
+        sm.registerConsumer("title.settime", (sc, in) -> {
+            STitlePacket packet = new STitlePacket(in[1].getInt(sc), in[2].getInt(sc), in[3].getInt(sc));
+            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(packet);
+        });
+        sm.registerConsumer("title.clear", (sc, in) -> {
+            ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
+            p.connection.sendPacket(new STitlePacket(STitlePacket.Type.CLEAR, null));
+            p.connection.sendPacket(new STitlePacket(STitlePacket.Type.RESET, null));
+        });
+        sm.registerConsumer("title.reset", (sc, in) -> {
+            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new STitlePacket(STitlePacket.Type.RESET, null));
+        });
+        sm.registerConsumer("title.send", (sc, in) -> {
+            ITextComponent text = new StringTextComponent(SnuviUtils.connect(sc, in, 1));
+            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new STitlePacket(STitlePacket.Type.TITLE, text));
+        });
+        sm.registerConsumer("title.setsub", (sc, in) -> {
+            ITextComponent text = new StringTextComponent(SnuviUtils.connect(sc, in, 1));
+            ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new STitlePacket(STitlePacket.Type.SUBTITLE, text));
+        });
+    }
+}

+ 89 - 0
src/main/java/me/km/snuviscript/commands/WorldCommands.java

@@ -0,0 +1,89 @@
+package me.km.snuviscript.commands;
+
+import java.util.ArrayList;
+import me.hammerle.snuviscript.code.ScriptManager;
+import me.km.utils.Location;
+import me.km.utils.Mapper;
+import me.km.utils.ReflectionUtils;
+import me.km.world.WorldManager;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.Difficulty;
+import net.minecraft.world.GameRules;
+import net.minecraft.world.World;
+import net.minecraft.world.storage.WorldInfo;
+
+public class WorldCommands {
+    @SuppressWarnings("")
+    public static void registerFunctions(ScriptManager sm, MinecraftServer server) {
+        sm.registerAlias("players.toworldlist", "world.getplayers");
+        sm.registerFunction("world.register", (sc, in) -> WorldManager.register(in[0].getString(sc)));
+        sm.registerFunction("world.unregister", (sc, in) -> WorldManager.unregister(server, in[0].getString(sc)));
+        sm.registerFunction("world.get", (sc, in) -> WorldManager.get(server, in[0].getString(sc)));
+        sm.registerFunction("world.getname", (sc, in) -> WorldManager.getName((World) in[0].get(sc)));
+        sm.registerConsumer("world.setdiffi", (sc, in) -> {
+            Difficulty diffi = Difficulty.valueOf(in[1].getString(sc).toUpperCase());
+            ((World) in[0].get(sc)).getWorldInfo().setDifficulty(diffi);
+        });
+        sm.registerConsumer("world.setgamerule", (sc, in) -> {
+            Object o = ((World) in[0].get(sc)).getGameRules().get(Mapper.getGameRule(in[1].getString(sc)));
+            if(o instanceof GameRules.BooleanValue) {
+                ((GameRules.BooleanValue) o).set(in[2].getBoolean(sc), server);
+            } else if(o instanceof GameRules.IntegerValue) {
+                ReflectionUtils.setIntegerValue((GameRules.IntegerValue) o, in[2].getInt(sc));
+            }
+        });
+        sm.registerFunction("world.getgamerule", (sc, in) -> {
+            Object o = ((World) in[0].get(sc)).getGameRules().get(Mapper.getGameRule(in[1].getString(sc)));
+            if(o instanceof GameRules.BooleanValue) {
+                return ((GameRules.BooleanValue) o).get();
+            } else if(o instanceof GameRules.IntegerValue) {
+                return (double) ((GameRules.IntegerValue) o).get();
+            }
+            return null;
+        });
+        sm.registerConsumer("world.setspawn", (sc, in) -> {
+            Location l = ((Location) in[0].get(sc));
+            l.getWorld().getDimension().setSpawnPoint(l.getBlockPos());
+        });
+        sm.registerFunction("world.getspawn", (sc, in) -> {
+            World w = (World) in[0].get(sc);
+            return new Location(w, w.getSpawnPoint());
+        });
+        sm.registerFunction("world.getall", (sc, in) -> {
+            ArrayList<World> worlds = new ArrayList<>();
+            for(World w : server.getWorlds()) {
+                worlds.add(w);
+            }
+            return worlds;
+        });
+        sm.registerConsumer("world.settime", (sc, in) -> ((World) in[0].get(sc)).setDayTime(in[1].getLong(sc)));
+        sm.registerFunction("world.gettime", (sc, in) -> (double) ((World) in[0].get(sc)).getDayTime());
+        sm.registerFunction("world.hasstorm", (sc, in) -> ((World) in[0].get(sc)).isRaining());
+        sm.registerConsumer("world.clearweather", (sc, in) -> {
+            WorldInfo wi = ((World) in[0].get(sc)).getWorldInfo();
+            wi.setClearWeatherTime(in[1].getInt(sc));
+            wi.setRainTime(0);
+            wi.setThunderTime(0);
+            wi.setRaining(false);
+            wi.setThundering(false);
+        });
+        sm.registerConsumer("world.setrain", (sc, in) -> {
+            WorldInfo wi = ((World) in[0].get(sc)).getWorldInfo();
+            wi.setClearWeatherTime(0);
+            int i = in[1].getInt(sc);
+            wi.setRainTime(i);
+            wi.setThunderTime(i);
+            wi.setRaining(true);
+            wi.setThundering(false);
+        });
+        sm.registerConsumer("world.setthunder", (sc, in) -> {
+            WorldInfo wi = ((World) in[0].get(sc)).getWorldInfo();
+            wi.setClearWeatherTime(0);
+            int i = in[1].getInt(sc);
+            wi.setRainTime(i);
+            wi.setThunderTime(i);
+            wi.setRaining(true);
+            wi.setThundering(true);
+        });
+    }
+}