Browse Source

programmable help for commands

Kajetan Johannes Hammerle 4 years ago
parent
commit
5eb776135f

+ 2 - 1
.gitignore

@@ -1,4 +1,5 @@
-/run
+/runClient
+/runServer
 /build
 /build
 /gradle
 /gradle
 gradle.properties
 gradle.properties

+ 2 - 2
build.gradle

@@ -20,14 +20,14 @@ minecraft {
 
 
     runs {
     runs {
         client {
         client {
-            workingDirectory project.file('run')
+            workingDirectory project.file('runClient')
             property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
             property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
             property 'forge.logging.console.level', 'info'
             property 'forge.logging.console.level', 'info'
             args '--username', 'kajetanjohannes'
             args '--username', 'kajetanjohannes'
         }
         }
 
 
         server {
         server {
-            workingDirectory project.file('run')
+            workingDirectory project.file('runServer')
             property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
             property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
             property 'forge.logging.console.level', 'info'
             property 'forge.logging.console.level', 'info'
         }
         }

+ 37 - 0
src/main/java/me/km/ObjectRegistry.java

@@ -1,9 +1,13 @@
 package me.km;
 package me.km;
 
 
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
 import me.km.blocks.ModBlocks;
 import me.km.blocks.ModBlocks;
 import me.km.blocks.cookingpot.TileEntityCookingPot;
 import me.km.blocks.cookingpot.TileEntityCookingPot;
 import me.km.entities.ModEntities;
 import me.km.entities.ModEntities;
 import me.km.items.ModItems;
 import me.km.items.ModItems;
+import me.km.utils.ReflectionUtils;
+import me.km.world.ModBiomeProvider;
 import me.km.world.WorldManager;
 import me.km.world.WorldManager;
 import net.minecraft.block.Block;
 import net.minecraft.block.Block;
 import net.minecraft.block.Blocks;
 import net.minecraft.block.Blocks;
@@ -11,6 +15,11 @@ import net.minecraft.entity.EntityType;
 import net.minecraft.item.Item;
 import net.minecraft.item.Item;
 import net.minecraft.item.Items;
 import net.minecraft.item.Items;
 import net.minecraft.tileentity.TileEntityType;
 import net.minecraft.tileentity.TileEntityType;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.biome.Biome;
+import net.minecraft.world.biome.Biomes;
+import net.minecraft.world.biome.provider.BiomeProviderType;
+import net.minecraft.world.biome.provider.OverworldBiomeProviderSettings;
 import net.minecraftforge.common.ModDimension;
 import net.minecraftforge.common.ModDimension;
 import net.minecraftforge.event.RegistryEvent;
 import net.minecraftforge.event.RegistryEvent;
 import net.minecraftforge.eventbus.api.SubscribeEvent;
 import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -97,4 +106,32 @@ public class ObjectRegistry
     {
     {
         e.getRegistry().register(WorldManager.MOD_DIMENSION);
         e.getRegistry().register(WorldManager.MOD_DIMENSION);
     }
     }
+    
+    public static BiomeProviderType<OverworldBiomeProviderSettings, ModBiomeProvider> DESERT_BIOME_PROVIDER;
+    public static BiomeProviderType<OverworldBiomeProviderSettings, ModBiomeProvider> SNOW_BIOME_PROVIDER;
+    
+    private static BiomeProviderType createBiomeProviderType(Set<Biome> biomes, String name)
+    {
+        BiomeProviderType provider = ReflectionUtils.newBiomeProviderType((OverworldBiomeProviderSettings settings) -> 
+        {
+            return new ModBiomeProvider(biomes, settings);
+        }, OverworldBiomeProviderSettings::new);
+        provider.setRegistryName(new ResourceLocation("km", name));
+        return provider;
+    }
+    
+    @SubscribeEvent
+    public static void onBiomeProviderTypeRegistry(RegistryEvent.Register<BiomeProviderType<?, ?>> e) 
+    {
+        DESERT_BIOME_PROVIDER = createBiomeProviderType(ImmutableSet.of(
+                    Biomes.DESERT, Biomes.DESERT_HILLS, Biomes.BADLANDS, Biomes.BADLANDS_PLATEAU, 
+                    Biomes.DESERT_LAKES, Biomes.ERODED_BADLANDS, Biomes.MODIFIED_BADLANDS_PLATEAU), "desert_layered");
+        SNOW_BIOME_PROVIDER = createBiomeProviderType(ImmutableSet.of(
+                    Biomes.FROZEN_OCEAN, Biomes.FROZEN_RIVER, Biomes.SNOWY_TUNDRA, 
+                    Biomes.SNOWY_MOUNTAINS, Biomes.SNOWY_BEACH, Biomes.SNOWY_TAIGA, 
+                    Biomes.SNOWY_TAIGA_HILLS, Biomes.DEEP_FROZEN_OCEAN, 
+                    Biomes.ICE_SPIKES, Biomes.SNOWY_TAIGA_MOUNTAINS), "snow_layered");
+        
+        e.getRegistry().registerAll(DESERT_BIOME_PROVIDER, SNOW_BIOME_PROVIDER);
+    }
 }
 }

+ 1 - 6
src/main/java/me/km/Server.java

@@ -140,7 +140,7 @@ public class Server
         }
         }
         MinecraftFunctions.registerFunctions(
         MinecraftFunctions.registerFunctions(
                 scripts.getScriptManager(), scripts, perms, scheduler, server, playerBank, 
                 scripts.getScriptManager(), scripts, perms, scheduler, server, playerBank, 
-                customEventCaller, scriptBank, databank, blockProtection, plotMap);
+                customEventCaller, scriptBank, databank, blockProtection, plotMap, commands);
         
         
         MinecraftForge.EVENT_BUS.register(new WorldEvents());
         MinecraftForge.EVENT_BUS.register(new WorldEvents());
         scripts.startScript("startscript");
         scripts.startScript("startscript");
@@ -154,11 +154,6 @@ public class Server
         databank.closeDataBankConnection();
         databank.closeDataBankConnection();
     }
     }
     
     
-    public static void executeCommand(String s)
-    {
-        commands.handleCommand(server.getCommandSource(), s);
-    }
-    
     public static ISnuviLogger getLogger()
     public static ISnuviLogger getLogger()
     {
     {
         return logger;
         return logger;

+ 30 - 15
src/main/java/me/km/permissions/ModCommandManager.java

@@ -31,6 +31,8 @@ public class ModCommandManager extends Commands
     private final PermissionManager perms;
     private final PermissionManager perms;
     private final ScriptEvents events;
     private final ScriptEvents events;
     private final Scripts scripts;
     private final Scripts scripts;
+    
+    private final ArrayList<CommandNode> customNodes = new ArrayList<>();
 
 
     public ModCommandManager(boolean isDedicatedServer, PermissionManager perms, ScriptEvents events, Scripts scripts, ISnuviScheduler scheduler)
     public ModCommandManager(boolean isDedicatedServer, PermissionManager perms, ScriptEvents events, Scripts scripts, ISnuviScheduler scheduler)
     {
     {
@@ -54,6 +56,16 @@ public class ModCommandManager extends Commands
         this.scripts = scripts;
         this.scripts = scripts;
     }
     }
     
     
+    public void clearCustomNodes()
+    {
+        customNodes.clear();
+    }
+    
+    public void addCustomNodes(CommandNode node)
+    {
+        customNodes.add(node);
+    }
+    
     public void registerCommand(Command command)
     public void registerCommand(Command command)
     {
     {
         commands.put(command.getName(), command);
         commands.put(command.getName(), command);
@@ -181,7 +193,6 @@ public class ModCommandManager extends Commands
                         return 0;
                         return 0;
                     }
                     }
                 }
                 }
-                System.out.println("execute: " + rawCommand + " " + cs.hasPermissionLevel(4));
                 return super.handleCommand(cs, rawCommand);
                 return super.handleCommand(cs, rawCommand);
             }
             }
             events.onMissingPermission(getSource(cs), commandName);
             events.onMissingPermission(getSource(cs), commandName);
@@ -199,26 +210,30 @@ public class ModCommandManager extends Commands
         RootCommandNode<ISuggestionProvider> rootcommandnode = new RootCommandNode<>();
         RootCommandNode<ISuggestionProvider> rootcommandnode = new RootCommandNode<>();
         map.put(getDispatcher().getRoot(), rootcommandnode);
         map.put(getDispatcher().getRoot(), rootcommandnode);
         this.commandSourceNodesToSuggestionNodes(true, getDispatcher().getRoot(), rootcommandnode, player.getCommandSource(), map);
         this.commandSourceNodesToSuggestionNodes(true, getDispatcher().getRoot(), rootcommandnode, player.getCommandSource(), map);
+        
+        for(CommandNode node : customNodes)
+        {
+            rootcommandnode.addChild(node);
+        }
+        
         player.connection.sendPacket(new SCommandListPacket(rootcommandnode));
         player.connection.sendPacket(new SCommandListPacket(rootcommandnode));
     }
     }
 
 
-    private void commandSourceNodesToSuggestionNodes(boolean first, CommandNode<CommandSource> node, CommandNode<ISuggestionProvider> suggestion, CommandSource source, Map<CommandNode<CommandSource>, CommandNode<ISuggestionProvider>> commandNodeToSuggestionNode)
+    private void commandSourceNodesToSuggestionNodes(boolean first, 
+            CommandNode<CommandSource> node, 
+            CommandNode<ISuggestionProvider> suggestion, 
+            CommandSource source, 
+            Map<CommandNode<CommandSource>, CommandNode<ISuggestionProvider>> map)
     {
     {
         for(CommandNode<CommandSource> commandnode : node.getChildren())
         for(CommandNode<CommandSource> commandnode : node.getChildren())
         {
         {
             if((first && perms.hasPermission(source, commandnode.getName()) || (!first && commandnode.canUse(source))))
             if((first && perms.hasPermission(source, commandnode.getName()) || (!first && commandnode.canUse(source))))
             {
             {
                 ArgumentBuilder<ISuggestionProvider, ?> argumentbuilder = (ArgumentBuilder) commandnode.createBuilder();
                 ArgumentBuilder<ISuggestionProvider, ?> argumentbuilder = (ArgumentBuilder) commandnode.createBuilder();
-                argumentbuilder.requires((p_197060_0_) ->
-                {
-                    return true;
-                });
+                argumentbuilder.requires(a -> true);
                 if(argumentbuilder.getCommand() != null)
                 if(argumentbuilder.getCommand() != null)
                 {
                 {
-                    argumentbuilder.executes((p_197053_0_) ->
-                    {
-                        return 0;
-                    });
+                    argumentbuilder.executes(a -> 0);
                 }
                 }
 
 
                 if(argumentbuilder instanceof RequiredArgumentBuilder)
                 if(argumentbuilder instanceof RequiredArgumentBuilder)
@@ -232,15 +247,15 @@ public class ModCommandManager extends Commands
 
 
                 if(argumentbuilder.getRedirect() != null)
                 if(argumentbuilder.getRedirect() != null)
                 {
                 {
-                    argumentbuilder.redirect(commandNodeToSuggestionNode.get(argumentbuilder.getRedirect()));
+                    argumentbuilder.redirect(map.get(argumentbuilder.getRedirect()));
                 }
                 }
 
 
-                CommandNode<ISuggestionProvider> commandnode1 = argumentbuilder.build();
-                commandNodeToSuggestionNode.put(commandnode, commandnode1);
-                suggestion.addChild(commandnode1);
+                CommandNode<ISuggestionProvider> commandNode = argumentbuilder.build();
+                map.put(commandnode, commandNode);
+                suggestion.addChild(commandNode);
                 if(!commandnode.getChildren().isEmpty())
                 if(!commandnode.getChildren().isEmpty())
                 {
                 {
-                    this.commandSourceNodesToSuggestionNodes(false, commandnode, commandnode1, source, commandNodeToSuggestionNode);
+                    this.commandSourceNodesToSuggestionNodes(false, commandnode, commandNode, source, map);
                 }
                 }
             }
             }
         }
         }

+ 156 - 8
src/main/java/me/km/snuviscript/MinecraftFunctions.java

@@ -2,6 +2,16 @@ package me.km.snuviscript;
 
 
 import com.mojang.authlib.GameProfile;
 import com.mojang.authlib.GameProfile;
 import com.mojang.brigadier.StringReader;
 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.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.SQLException;
@@ -46,6 +56,7 @@ import me.km.inventory.CustomContainer;
 import me.km.inventory.ModInventory;
 import me.km.inventory.ModInventory;
 import me.km.networking.ModPacketHandler;
 import me.km.networking.ModPacketHandler;
 import me.km.overrides.ModEntityPlayerMP;
 import me.km.overrides.ModEntityPlayerMP;
+import me.km.permissions.ModCommandManager;
 import me.km.permissions.PermissionManager;
 import me.km.permissions.PermissionManager;
 import me.km.playerbank.IPlayerBank;
 import me.km.playerbank.IPlayerBank;
 import me.km.plots.PlotMap.Plot;
 import me.km.plots.PlotMap.Plot;
@@ -58,8 +69,15 @@ import net.minecraft.block.BlockState;
 import net.minecraft.block.ChestBlock;
 import net.minecraft.block.ChestBlock;
 import net.minecraft.block.CropsBlock;
 import net.minecraft.block.CropsBlock;
 import net.minecraft.block.DoorBlock;
 import net.minecraft.block.DoorBlock;
+import net.minecraft.command.CommandSource;
+import net.minecraft.command.Commands;
 import net.minecraft.command.ICommandSource;
 import net.minecraft.command.ICommandSource;
+import net.minecraft.command.arguments.BlockStateArgument;
 import net.minecraft.command.arguments.BlockStateParser;
 import net.minecraft.command.arguments.BlockStateParser;
+import net.minecraft.command.arguments.EnchantmentArgument;
+import net.minecraft.command.arguments.ItemArgument;
+import net.minecraft.command.arguments.ItemInput;
+import net.minecraft.command.arguments.PotionArgument;
 import net.minecraft.entity.AgeableEntity;
 import net.minecraft.entity.AgeableEntity;
 import net.minecraft.entity.EntityType;
 import net.minecraft.entity.EntityType;
 import net.minecraft.entity.LivingEntity;
 import net.minecraft.entity.LivingEntity;
@@ -153,11 +171,135 @@ public class MinecraftFunctions
             PermissionManager perms, SnuviScheduler scheduler, MinecraftServer server, 
             PermissionManager perms, SnuviScheduler scheduler, MinecraftServer server, 
             IPlayerBank playerBank, CustomEventCaller cec,
             IPlayerBank playerBank, CustomEventCaller cec,
             IScriptBank scriptBank, DataBank dataBank, IBlockProtection blockProtection,
             IScriptBank scriptBank, DataBank dataBank, IBlockProtection blockProtection,
-            WorldPlotMap plots)
+            WorldPlotMap plots, ModCommandManager commands)
     {
     {
         // ---------------------------------------------------------------------
         // ---------------------------------------------------------------------
         // Command-library  
         // Command-library  
         // ---------------------------------------------------------------------
         // ---------------------------------------------------------------------
+        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) -> 
         sm.registerFunction("command.add", (sc, in) -> 
         {
         {
             scripts.registerScriptCommand(in[0].getString(sc));
             scripts.registerScriptCommand(in[0].getString(sc));
@@ -261,8 +403,6 @@ public class MinecraftFunctions
             stack.setCount(InventoryUtils.addToInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
             stack.setCount(InventoryUtils.addToInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
             return stack;
             return stack;
         });
         });
-        sm.registerFunction("player.shootprojectile", (sc, in) -> launchProjectile((PlayerEntity) in[0].get(sc), 
-                getClass(in[1].getString(sc)), in[2].getDouble(sc), in.length >= 4 ? in[3].get(sc) : null));
         sm.registerFunction("player.respawn", (sc, in) -> 
         sm.registerFunction("player.respawn", (sc, in) -> 
         {
         {
             final ServerPlayerEntity p = ((ServerPlayerEntity) in[0].get(sc));
             final ServerPlayerEntity p = ((ServerPlayerEntity) in[0].get(sc));
@@ -1146,9 +1286,9 @@ public class MinecraftFunctions
         sm.registerFunction("damage.isabsolute", (sc, in) -> ((DamageSource) in[0].get(sc)).isDamageAbsolute()); 
         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.isdifficultyscaled", (sc, in) -> ((DamageSource) in[0].get(sc)).isDifficultyScaled()); 
         sm.registerFunction("damage.isexplosion", (sc, in) -> ((DamageSource) in[0].get(sc)).isExplosion()); 
         sm.registerFunction("damage.isexplosion", (sc, in) -> ((DamageSource) in[0].get(sc)).isExplosion()); 
-        sm.registerFunction("damage.isfireDamage", (sc, in) -> ((DamageSource) in[0].get(sc)).isFireDamage()); 
-        sm.registerFunction("damage.isunblockable", (sc, in) -> ((DamageSource) in[0].get(sc)).isMagicDamage()); 
-        sm.registerFunction("damage.ismagic", (sc, in) -> ((DamageSource) in[0].get(sc)).isProjectile()); 
+        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.isunblockable", (sc, in) -> ((DamageSource) in[0].get(sc)).isUnblockable()); 
         sm.registerFunction("damage.gettype", (sc, in) -> ((DamageSource) in[0].get(sc)).getDamageType()); 
         sm.registerFunction("damage.gettype", (sc, in) -> ((DamageSource) in[0].get(sc)).getDamageType()); 
         sm.registerFunction("damage.get", (sc, in) -> 
         sm.registerFunction("damage.get", (sc, in) -> 
@@ -1230,6 +1370,14 @@ public class MinecraftFunctions
         // ---------------------------------------------------------------------    
         // ---------------------------------------------------------------------    
         // entity commands
         // 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.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.getarmor", (sc, in) -> (double) ((LivingEntity) in[0].get(sc)).getTotalArmorValue()); 
         sm.registerFunction("entity.getmagicarmor", (sc, in) -> 
         sm.registerFunction("entity.getmagicarmor", (sc, in) -> 
@@ -2508,7 +2656,7 @@ public class MinecraftFunctions
         sm.registerFunction("command", (sc, in) -> 
         sm.registerFunction("command", (sc, in) -> 
         { 
         { 
             final String s = SnuviUtils.connect(sc, in, 0);
             final String s = SnuviUtils.connect(sc, in, 0);
-            scheduler.scheduleTask(() -> Server.executeCommand(s)); 
+            scheduler.scheduleTask(() -> commands.handleCommand(server.getCommandSource(), s)); 
             return Void.TYPE;
             return Void.TYPE;
         });
         });
         sm.registerFunction("isplayer", (sc, in) -> 
         sm.registerFunction("isplayer", (sc, in) -> 
@@ -2638,7 +2786,7 @@ public class MinecraftFunctions
         return text;
         return text;
     }
     }
     
     
-    private static <T> T launchProjectile(PlayerEntity p, Class<? extends T> projectile, double scale, Object data)
+    private static <T> T launchProjectile(LivingEntity p, Class<? extends T> projectile, double scale, Object data)
     {
     {
         World w = p.world;
         World w = p.world;
         Entity launch = null;
         Entity launch = null;

+ 8 - 2
src/main/java/me/km/snuviscript/ScriptEvents.java

@@ -77,11 +77,17 @@ public class ScriptEvents
         {
         {
             scripts.getScriptManager().callEvent(event, sc -> 
             scripts.getScriptManager().callEvent(event, sc -> 
             {
             {
-                before.accept(sc);
+                if(before != null)
+                {
+                    before.accept(sc);
+                }
                 sc.setVar("cancel", e.isCanceled());
                 sc.setVar("cancel", e.isCanceled());
             }, sc -> 
             }, sc -> 
             {
             {
-                after.accept(sc);
+                if(after != null)
+                {
+                    after.accept(sc);
+                }
                 handleVar(sc, event, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
                 handleVar(sc, event, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
             });
             });
         }
         }

+ 2 - 17
src/main/java/me/km/utils/ClientReflectionUtils.java

@@ -10,10 +10,8 @@ import net.minecraft.client.Minecraft;
 import net.minecraft.client.gui.overlay.BossOverlayGui;
 import net.minecraft.client.gui.overlay.BossOverlayGui;
 import net.minecraft.client.renderer.entity.EntityRenderer;
 import net.minecraft.client.renderer.entity.EntityRenderer;
 import net.minecraft.client.renderer.entity.EntityRendererManager;
 import net.minecraft.client.renderer.entity.EntityRendererManager;
-import net.minecraft.client.renderer.entity.LivingRenderer;
 import net.minecraft.client.renderer.entity.PlayerRenderer;
 import net.minecraft.client.renderer.entity.PlayerRenderer;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.Entity;
-import net.minecraft.entity.LivingEntity;
 import net.minecraftforge.api.distmarker.Dist;
 import net.minecraftforge.api.distmarker.Dist;
 import net.minecraftforge.api.distmarker.OnlyIn;
 import net.minecraftforge.api.distmarker.OnlyIn;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.LogManager;
@@ -22,8 +20,7 @@ import org.apache.logging.log4j.LogManager;
 public class ClientReflectionUtils
 public class ClientReflectionUtils
 {
 {
     private final static Method CAN_RENDER_NAME = getMethod(EntityRenderer.class, "func_177070_b", Entity.class);
     private final static Method CAN_RENDER_NAME = getMethod(EntityRenderer.class, "func_177070_b", Entity.class);
-    private final static Method RENDER_ENTITY_NAME = getMethod(EntityRenderer.class, "func_188296_a", Entity.class, double.class, double.class, double.class, String.class, double.class);
-    
+
     public static boolean canRenderName(EntityRenderer lr, Entity liv)
     public static boolean canRenderName(EntityRenderer lr, Entity liv)
     {
     {
         try
         try
@@ -36,19 +33,7 @@ public class ClientReflectionUtils
             return false;
             return false;
         }
         }
     }
     }
-    
-    public static void renderEntityName(LivingRenderer lr, LivingEntity liv, double x, double y, double z, String name, double distanceSq)
-    {
-        try
-        {
-            RENDER_ENTITY_NAME.invoke(lr, liv, x, y, z, name, distanceSq);
-        }
-        catch(Exception ex)
-        {
-            LogManager.getLogger().warn("renderEntityName - " + ex);
-        }
-    }
-    
+
     private final static Field BOSS_BAR_MAP = getField(BossOverlayGui.class, "field_184060_g");
     private final static Field BOSS_BAR_MAP = getField(BossOverlayGui.class, "field_184060_g");
 
 
     public static boolean isRenderingBossBar()
     public static boolean isRenderingBossBar()

+ 2 - 0
src/main/java/me/km/utils/Mapper.java

@@ -85,6 +85,8 @@ public class Mapper
             case "maxCommandChainLength": return GameRules.MAX_COMMAND_CHAIN_LENGTH;
             case "maxCommandChainLength": return GameRules.MAX_COMMAND_CHAIN_LENGTH;
             case "announceAdvancements": return GameRules.ANNOUNCE_ADVANCEMENTS;
             case "announceAdvancements": return GameRules.ANNOUNCE_ADVANCEMENTS;
             case "disableRaids": return GameRules.DISABLE_RAIDS;
             case "disableRaids": return GameRules.DISABLE_RAIDS;
+            case "doInsomnia": return GameRules.DO_INSOMNIA;
+            case "doImmediateRespawn": return GameRules.DO_IMMEDIATE_RESPAWN;
         }
         }
         return null;
         return null;
     }
     }

+ 21 - 2
src/main/java/me/km/utils/ReflectionUtils.java

@@ -1,25 +1,28 @@
 package me.km.utils;
 package me.km.utils;
 
 
 import cpw.mods.modlauncher.api.INameMappingService;
 import cpw.mods.modlauncher.api.INameMappingService;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.Map;
+import java.util.function.Function;
 import net.minecraft.command.Commands;
 import net.minecraft.command.Commands;
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.Entity;
-import net.minecraft.entity.LivingEntity;
 import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.entity.item.ItemEntity;
 import net.minecraft.entity.player.PlayerAbilities;
 import net.minecraft.entity.player.PlayerAbilities;
 import net.minecraft.entity.player.ServerPlayerEntity;
 import net.minecraft.entity.player.ServerPlayerEntity;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.management.PlayerList;
 import net.minecraft.server.management.PlayerList;
-import net.minecraft.util.DamageSource;
 import net.minecraft.util.FoodStats;
 import net.minecraft.util.FoodStats;
 import net.minecraft.util.ResourceLocation;
 import net.minecraft.util.ResourceLocation;
 import net.minecraft.world.Explosion;
 import net.minecraft.world.Explosion;
 import net.minecraft.world.GameRules;
 import net.minecraft.world.GameRules;
 import net.minecraft.world.IWorld;
 import net.minecraft.world.IWorld;
 import net.minecraft.world.World;
 import net.minecraft.world.World;
+import net.minecraft.world.biome.provider.BiomeProvider;
+import net.minecraft.world.biome.provider.BiomeProviderType;
+import net.minecraft.world.biome.provider.IBiomeProviderSettings;
 import net.minecraft.world.storage.WorldInfo;
 import net.minecraft.world.storage.WorldInfo;
 import net.minecraftforge.common.DimensionManager;
 import net.minecraftforge.common.DimensionManager;
 import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
 import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
@@ -305,4 +308,20 @@ public class ReflectionUtils
     {
     {
         setInt(rule, INTEGER_VALUE, value);
         setInt(rule, INTEGER_VALUE, value);
     }
     }
+    
+    
+    public static <C extends IBiomeProviderSettings, T extends BiomeProvider> BiomeProviderType 
+        newBiomeProviderType(Function<C, T> factory, Function<WorldInfo, C> settingsFactory)
+    {
+        try
+        {
+            Constructor<BiomeProviderType> con = (Constructor<BiomeProviderType>) BiomeProviderType.class.getDeclaredConstructors()[0];
+            con.setAccessible(true);
+            return con.newInstance(factory, settingsFactory);
+        }
+        catch(Exception ex)
+        {
+            return null;
+        }
+    }
 }
 }

+ 56 - 0
src/main/java/me/km/world/ModBiomeProvider.java

@@ -0,0 +1,56 @@
+package me.km.world;
+
+import java.util.Set;
+import net.minecraft.util.registry.Registry;
+import net.minecraft.world.biome.Biome;
+import net.minecraft.world.biome.provider.BiomeProvider;
+import net.minecraft.world.biome.provider.OverworldBiomeProviderSettings;
+import net.minecraft.world.gen.layer.Layer;
+import net.minecraft.world.gen.layer.LayerUtil;
+
+public class ModBiomeProvider extends BiomeProvider
+{
+    private final Layer genBiomes;
+    private final Biome[] biomeArray;
+
+    public ModBiomeProvider(Set<Biome> biomes, OverworldBiomeProviderSettings settingsProvider)
+    {
+        super(biomes);
+        biomeArray = biomes.toArray(new Biome[biomes.size()]);
+        this.genBiomes = LayerUtil.func_227474_a_(settingsProvider.func_226850_a_(), settingsProvider.func_226851_b_(), settingsProvider.getGeneratorSettings());
+    }
+
+    @Override
+    public Biome getNoiseBiome(int x, int y, int z)
+    {
+        Biome vanillaBiome = genBiomes.func_215738_a(x, z);
+        
+        float min = Float.MAX_VALUE;
+        float min2 = Float.MAX_VALUE;
+        Biome minBiome = null;
+        Biome minBiome2 = null;
+        for(Biome b : biomeArray)
+        {
+            float distance = Math.abs(b.getDepth() - vanillaBiome.getDepth());
+            if(distance < min)
+            {
+                min2 = min;
+                minBiome2 = minBiome;
+                
+                min = distance;
+                minBiome = b;
+            }
+            else if(distance < min2)
+            {
+                min2 = distance;
+                minBiome2 = b;
+            }
+        }
+        
+        if((Registry.BIOME.getId(vanillaBiome) % 2) == 1)
+        {
+            return minBiome;
+        }
+        return minBiome2;
+    }
+}

+ 19 - 3
src/main/java/me/km/world/ModOverworldDimension.java

@@ -2,10 +2,15 @@ package me.km.world;
 
 
 import me.km.utils.ReflectionUtils;
 import me.km.utils.ReflectionUtils;
 import net.minecraft.world.World;
 import net.minecraft.world.World;
+import net.minecraft.world.biome.provider.BiomeProviderType;
+import net.minecraft.world.biome.provider.OverworldBiomeProviderSettings;
 import net.minecraft.world.dimension.DimensionType;
 import net.minecraft.world.dimension.DimensionType;
 import net.minecraft.world.dimension.OverworldDimension;
 import net.minecraft.world.dimension.OverworldDimension;
 import net.minecraft.world.gen.ChunkGenerator;
 import net.minecraft.world.gen.ChunkGenerator;
+import net.minecraft.world.gen.ChunkGeneratorType;
 import net.minecraft.world.gen.GenerationSettings;
 import net.minecraft.world.gen.GenerationSettings;
+import net.minecraft.world.gen.OverworldChunkGenerator;
+import net.minecraft.world.gen.OverworldGenSettings;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.LogManager;
 
 
 public class ModOverworldDimension extends OverworldDimension
 public class ModOverworldDimension extends OverworldDimension
@@ -19,14 +24,25 @@ public class ModOverworldDimension extends OverworldDimension
     public ChunkGenerator<? extends GenerationSettings> createChunkGenerator()
     public ChunkGenerator<? extends GenerationSettings> createChunkGenerator()
     {
     {
         LogManager.getLogger().warn("Try swapping " + world + " " + world.getDimension().getType());
         LogManager.getLogger().warn("Try swapping " + world + " " + world.getDimension().getType());
-        
+
         if(world.getDimension().getType().isVanilla())
         if(world.getDimension().getType().isVanilla())
         {
         {
             LogManager.getLogger().warn("no swap in vanilla world");
             LogManager.getLogger().warn("no swap in vanilla world");
             return super.createChunkGenerator();
             return super.createChunkGenerator();
         }
         }
-        
-        ReflectionUtils.setWorldInfo(world, new ModWorldInfo(world.getWorldInfo(), WorldManager.getName(world), world.getServer()));
+
+        ModWorldInfo info = new ModWorldInfo(world.getWorldInfo(), WorldManager.getName(world), world.getServer());
+        ReflectionUtils.setWorldInfo(world, info);
+
+        ModWorldInfo.Type type = info.getType();
+        if(type != ModWorldInfo.Type.VOID && type != ModWorldInfo.Type.VANILLA)
+        {
+            ChunkGeneratorType<OverworldGenSettings, OverworldChunkGenerator> chunkGenType = ChunkGeneratorType.SURFACE;
+            BiomeProviderType<OverworldBiomeProviderSettings, ModBiomeProvider> provider = info.getType().getProvider();
+            OverworldGenSettings genSettings = chunkGenType.createSettings();
+            OverworldBiomeProviderSettings providerSettings = provider.func_226840_a_(this.world.getWorldInfo()).setGeneratorSettings(genSettings);
+            return chunkGenType.create(this.world, provider.create(providerSettings), genSettings);
+        }
         
         
         return super.createChunkGenerator();
         return super.createChunkGenerator();
     }
     }

+ 40 - 6
src/main/java/me/km/world/ModWorldInfo.java

@@ -4,6 +4,7 @@ import net.minecraft.world.Difficulty;
 import net.minecraft.world.storage.DerivedWorldInfo;
 import net.minecraft.world.storage.DerivedWorldInfo;
 import net.minecraft.world.storage.WorldInfo;
 import net.minecraft.world.storage.WorldInfo;
 import me.hammerle.snuviscript.config.SnuviConfig;
 import me.hammerle.snuviscript.config.SnuviConfig;
+import me.km.ObjectRegistry;
 import me.km.Server;
 import me.km.Server;
 import me.km.utils.ReflectionUtils;
 import me.km.utils.ReflectionUtils;
 import net.minecraft.nbt.CompoundNBT;
 import net.minecraft.nbt.CompoundNBT;
@@ -12,9 +13,26 @@ import net.minecraft.server.MinecraftServer;
 import net.minecraft.world.GameRules;
 import net.minecraft.world.GameRules;
 import static net.minecraft.world.GameRules.*;
 import static net.minecraft.world.GameRules.*;
 import net.minecraft.world.WorldType;
 import net.minecraft.world.WorldType;
+import net.minecraft.world.biome.provider.BiomeProviderType;
+import net.minecraft.world.biome.provider.OverworldBiomeProviderSettings;
 
 
 public class ModWorldInfo extends DerivedWorldInfo
 public class ModWorldInfo extends DerivedWorldInfo
 {
 {
+    public static enum Type
+    {
+        VANILLA, VOID, DESERT, SNOW;
+        
+        public BiomeProviderType<OverworldBiomeProviderSettings, ModBiomeProvider> getProvider()
+        {
+            switch(this)
+            {
+                case DESERT: return ObjectRegistry.DESERT_BIOME_PROVIDER;
+                case SNOW: return ObjectRegistry.SNOW_BIOME_PROVIDER;
+            }
+            return null;
+        }
+    }
+    
     private final SnuviConfig config;
     private final SnuviConfig config;
     
     
     private long gameTime;
     private long gameTime;
@@ -27,7 +45,7 @@ public class ModWorldInfo extends DerivedWorldInfo
     private Difficulty difficulty;
     private Difficulty difficulty;
     private final GameRules gameRules = new GameRules();
     private final GameRules gameRules = new GameRules();
     
     
-    private boolean voidWorld;
+    private Type type;
    
    
     public ModWorldInfo(WorldInfo info, String name, MinecraftServer server)
     public ModWorldInfo(WorldInfo info, String name, MinecraftServer server)
     {
     {
@@ -40,7 +58,7 @@ public class ModWorldInfo extends DerivedWorldInfo
         }
         }
         onLoad(info, server);
         onLoad(info, server);
         
         
-        org.apache.logging.log4j.LogManager.getLogger().warn("status: " + voidWorld);
+        org.apache.logging.log4j.LogManager.getLogger().warn("status: " + type);
     }
     }
     
     
     private void onLoad(WorldInfo info, MinecraftServer server)
     private void onLoad(WorldInfo info, MinecraftServer server)
@@ -95,8 +113,17 @@ public class ModWorldInfo extends DerivedWorldInfo
         ReflectionUtils.setIntegerValue(gameRules.get(MAX_COMMAND_CHAIN_LENGTH), config.getInt("maxCommandChainLength", rules.getInt(MAX_COMMAND_CHAIN_LENGTH)));
         ReflectionUtils.setIntegerValue(gameRules.get(MAX_COMMAND_CHAIN_LENGTH), config.getInt("maxCommandChainLength", rules.getInt(MAX_COMMAND_CHAIN_LENGTH)));
         gameRules.get(ANNOUNCE_ADVANCEMENTS).set(config.getBoolean("announceAdvancements", rules.getBoolean(ANNOUNCE_ADVANCEMENTS)), server);
         gameRules.get(ANNOUNCE_ADVANCEMENTS).set(config.getBoolean("announceAdvancements", rules.getBoolean(ANNOUNCE_ADVANCEMENTS)), server);
         gameRules.get(DISABLE_RAIDS).set(config.getBoolean("disableRaids", rules.getBoolean(DISABLE_RAIDS)), server);
         gameRules.get(DISABLE_RAIDS).set(config.getBoolean("disableRaids", rules.getBoolean(DISABLE_RAIDS)), server);
+        gameRules.get(DO_INSOMNIA).set(config.getBoolean("doInsomnia", rules.getBoolean(DO_INSOMNIA)), server);
+        gameRules.get(DO_IMMEDIATE_RESPAWN).set(config.getBoolean("doImmediateRespawn", rules.getBoolean(DO_IMMEDIATE_RESPAWN)), server);
         
         
-        voidWorld = config.getBoolean("voidWorld", false);
+        try
+        {
+            type = Type.valueOf(config.getString("type", ""));
+        }
+        catch(IllegalArgumentException ex)
+        {
+            type = Type.VOID;
+        }
     }
     }
     
     
     public void onSave()
     public void onSave()
@@ -134,8 +161,10 @@ public class ModWorldInfo extends DerivedWorldInfo
         config.set("maxCommandChainLength", gameRules.getInt(MAX_COMMAND_CHAIN_LENGTH));
         config.set("maxCommandChainLength", gameRules.getInt(MAX_COMMAND_CHAIN_LENGTH));
         config.set("announceAdvancements", gameRules.getBoolean(ANNOUNCE_ADVANCEMENTS));
         config.set("announceAdvancements", gameRules.getBoolean(ANNOUNCE_ADVANCEMENTS));
         config.set("disableRaids", gameRules.getBoolean(DISABLE_RAIDS));
         config.set("disableRaids", gameRules.getBoolean(DISABLE_RAIDS));
+        config.set("doInsomnia", gameRules.getBoolean(DO_INSOMNIA));
+        config.set("doImmediateRespawn", gameRules.getBoolean(DO_IMMEDIATE_RESPAWN));
         
         
-        config.set("voidWorld", voidWorld);
+        config.set("type", type);
         
         
         config.save();
         config.save();
     }
     }
@@ -245,17 +274,22 @@ public class ModWorldInfo extends DerivedWorldInfo
     @Override
     @Override
     public WorldType getGenerator()
     public WorldType getGenerator()
     {
     {
-        if(voidWorld)
+        if(type == Type.VOID)
         {
         {
             return WorldType.FLAT;
             return WorldType.FLAT;
         }
         }
         return super.getGenerator();
         return super.getGenerator();
     }
     }
+    
+    public Type getType()
+    {
+        return type;
+    }
 
 
     @Override
     @Override
     public CompoundNBT getGeneratorOptions()
     public CompoundNBT getGeneratorOptions()
     {
     {
-        if(voidWorld)
+        if(type == Type.VOID)
         {
         {
             CompoundNBT base = new CompoundNBT();
             CompoundNBT base = new CompoundNBT();