diff --git a/MineTweaker3-API/src/main/java/minetweaker/IPlatformFunctions.java b/MineTweaker3-API/src/main/java/minetweaker/IPlatformFunctions.java index 42fb761..8a21ac8 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/IPlatformFunctions.java +++ b/MineTweaker3-API/src/main/java/minetweaker/IPlatformFunctions.java @@ -7,6 +7,7 @@ package minetweaker; import minetweaker.api.chat.IChatMessage; +import minetweaker.api.item.IItemDefinition; /** * @@ -14,4 +15,8 @@ import minetweaker.api.chat.IChatMessage; */ public interface IPlatformFunctions { public IChatMessage getMessage(String message); + + public void distributeScripts(byte[] data); + + public IItemDefinition getItemDefinition(int id); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java b/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java index 2df1847..ba34654 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java +++ b/MineTweaker3-API/src/main/java/minetweaker/MineTweakerAPI.java @@ -11,15 +11,18 @@ import java.util.logging.Level; import java.util.logging.Logger; import minetweaker.annotations.BracketHandler; import minetweaker.annotations.ModOnly; +import minetweaker.api.client.IClient; import minetweaker.api.event.IEventManager; +import minetweaker.api.game.IGame; import minetweaker.api.mods.ILoadedMods; -import minetweaker.runtime.IMineTweaker; +import minetweaker.runtime.ITweaker; import minetweaker.runtime.ILogger; -import minetweaker.runtime.Tweaker; +import minetweaker.runtime.MTTweaker; import minetweaker.api.recipes.IRecipeManager; import minetweaker.api.oredict.IOreDict; import minetweaker.api.recipes.IFurnaceManager; import minetweaker.api.resource.IResourceManager; +import minetweaker.api.server.IServer; import minetweaker.runtime.GlobalRegistry; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenExpansion; @@ -57,12 +60,13 @@ public class MineTweakerAPI { registerClass(cls); } - registerGlobalSymbol("logger", getJavaStaticFieldSymbol(MineTweakerAPI.class, "logger")); + registerGlobalSymbol("logger", getJavaStaticGetterSymbol(MineTweakerAPI.class, "getLogger")); registerGlobalSymbol("tweaker", getJavaStaticFieldSymbol(MineTweakerAPI.class, "tweaker")); registerGlobalSymbol("recipes", getJavaStaticFieldSymbol(MineTweakerAPI.class, "recipes")); registerGlobalSymbol("furnace", getJavaStaticFieldSymbol(MineTweakerAPI.class, "furnace")); registerGlobalSymbol("oreDict", getJavaStaticFieldSymbol(MineTweakerAPI.class, "oreDict")); registerGlobalSymbol("events", getJavaStaticFieldSymbol(MineTweakerAPI.class, "events")); + registerGlobalSymbol("server", getJavaStaticFieldSymbol(MineTweakerAPI.class, "server")); } private MineTweakerAPI() {} @@ -71,13 +75,17 @@ public class MineTweakerAPI { * The Tweaker is where you apply undoable actions. Any kind of action that * reloads with the scripts should always be submitted to the tweaker. */ - public static final IMineTweaker tweaker = new Tweaker(); + public static final ITweaker tweaker = new MTTweaker(); /** * The logger can be used to write logging messages to the client. Error and * warning messages should be relayed to admins for further handling. + * + * @return */ - public static ILogger logger = null; + public static final ILogger getLogger() { + return MineTweakerImplementationAPI.logger; + } /** * Access point to the ore dictionary. @@ -97,7 +105,22 @@ public class MineTweakerAPI { /** * Access point to the events manager. */ - public static IEventManager events = null; + public static final IEventManager events = MineTweakerImplementationAPI.events; + + /** + * Access point to the server, if any. + */ + public static IServer server = null; + + /** + * Access point to the client, if any. + */ + public static IClient client = null; + + /** + * Access point to general game data, such as items. + */ + public static IGame game = null; /** * Access point to mods list. @@ -110,11 +133,6 @@ public class MineTweakerAPI { */ public static IResourceManager resources = null; - /** - * Access point to general platform functions. - */ - public static IPlatformFunctions platform = null; - /** * Register a class registry class. Such class must have (at least) a public * static method called "getClasses" with accepts a List of classes and which diff --git a/MineTweaker3-API/src/main/java/minetweaker/MineTweakerImplementationAPI.java b/MineTweaker3-API/src/main/java/minetweaker/MineTweakerImplementationAPI.java new file mode 100644 index 0000000..27db903 --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/MineTweakerImplementationAPI.java @@ -0,0 +1,432 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker; + +import minetweaker.api.logger.MTLogger; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import static minetweaker.MineTweakerAPI.server; +import minetweaker.api.event.IPlayerLoggedInEventHandler; +import minetweaker.api.event.IPlayerLoggedOutEventHandler; +import minetweaker.api.event.MTEventManager; +import minetweaker.api.event.PlayerLoggedInEvent; +import minetweaker.api.event.PlayerLoggedOutEvent; +import minetweaker.api.item.IItemDefinition; +import minetweaker.api.item.IItemStack; +import minetweaker.api.liquid.ILiquidDefinition; +import minetweaker.api.mods.IMod; +import minetweaker.api.oredict.IOreDictEntry; +import minetweaker.api.player.IPlayer; +import minetweaker.api.server.ICommandFunction; +import minetweaker.api.server.ICommandValidator; + +/** + * + * @author Stan + */ +public class MineTweakerImplementationAPI { + private static final Map minetweakerCommands; + private static final Comparator ITEM_COMPARATOR = new ItemComparator(); + private static final Comparator LIQUID_COMPARATOR = new LiquidComparator(); + private static final ListenPlayerLoggedIn LISTEN_LOGIN = new ListenPlayerLoggedIn(); + private static final ListenPlayerLoggedOut LISTEN_LOGOUT = new ListenPlayerLoggedOut(); + + static { + minetweakerCommands = new HashMap(); + + minetweakerCommands.put("reload", new MineTweakerCommand( + "reload", + new String[] { + "/minetweaker reload", + " Reloads all scripts" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + reload(); + player.sendChat(platform.getMessage("Scripts reloaded")); + } + })); + + minetweakerCommands.put("names", new MineTweakerCommand( + "names", + new String[] { + "/minetweaker names", + " Outputs a list of all item names in the game to the minetweaker log" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + List items = MineTweakerAPI.game.getItems(); + Collections.sort(items, ITEM_COMPARATOR); + for (IItemDefinition item : items) { + String displayName = ""; + + try { + displayName = " -- " + item.makeStack(0).getDisplayName(); + } catch (Exception ex) { + // some mods (such as buildcraft) may throw exceptions when calling + // getDisplayName on an item stack that doesn't contain valid NBT data + } + + MineTweakerAPI.getLogger().logCommand("<" + item.getId() + ">" + displayName); + } + + if (player != null) { + player.sendChat(platform.getMessage("List generated; see minetweaker.log in your minecraft dir")); + } + } + })); + + minetweakerCommands.put("liquids", new MineTweakerCommand( + "liquids", + new String[] { + "/minetweaker liquids", + " Outputs a list of all liquid names in the game to the minetweaker log" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + List liquids = MineTweakerAPI.game.getLiquids(); + System.out.println("Liquids: " + liquids.size()); + Collections.sort(liquids, LIQUID_COMPARATOR); + for (ILiquidDefinition liquid : liquids) { + System.out.println("Liquid " + liquid.getName()); + MineTweakerAPI.getLogger().logCommand("<" + liquid.getName() + "> -- " + liquid.getDisplayName()); + } + + if (player != null) { + player.sendChat(platform.getMessage("List generated; see minetweaker.log in your minecraft dir")); + } + } + })); + + minetweakerCommands.put("inventory", new MineTweakerCommand( + "inventory", + new String[] { + "/minetweaker inventory", + " Lists all items in your inventory" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + for (int i = 0; i < player.getInventorySize(); i++) { + IItemStack stack = player.getInventoryStack(i); + if (stack != null) { + player.sendChat(platform.getMessage(stack.toString())); + } + } + } + })); + + minetweakerCommands.put("hand", new MineTweakerCommand( + "hand", + new String[] { + "/minetweaker hand", + " Outputs the name of the item in your hand" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + IItemStack hand = player.getCurrentItem(); + if (hand != null) { + player.sendChat(platform.getMessage(hand.toString())); + } + } + })); + + minetweakerCommands.put("oredict", new MineTweakerCommand( + "oredict", + new String[] { + "/minetweaker oredict", + " Outputs all ore dictionary entries in the game to the minetweaker log", + "/minetweaker oredict ", + " Outputs all items in the given ore dictionary entry to the minetweaker log" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + if (arguments.length > 0) { + String entryName = arguments[0]; + IOreDictEntry entry = MineTweakerAPI.oreDict.get(entryName); + if (entry.isEmpty()) { + player.sendChat(platform.getMessage("Entry doesn't exist")); + return; + } else { + MineTweakerAPI.getLogger().logCommand("Ore entries for " + entryName + ":"); + for (IItemStack ore : entry.getItems()) { + MineTweakerAPI.getLogger().logCommand(" " + ore); + } + } + } else { + for (IOreDictEntry entry : MineTweakerAPI.oreDict.getEntries()) { + if (!entry.isEmpty()) { + MineTweakerAPI.getLogger().logCommand("Ore entries for :"); + for (IItemStack ore : entry.getItems()) { + MineTweakerAPI.getLogger().logCommand(" " + ore); + } + } + } + } + player.sendChat(platform.getMessage("List generated; see minetweaker.log in your minecraft dir")); + } + })); + + minetweakerCommands.put("mods", new MineTweakerCommand( + "mods", + new String[] { + "/minetweaker mods", + " Outputs all active mod IDs and versions in the game" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + MineTweakerAPI.getLogger().logCommand("Mods list:"); + for (IMod mod : MineTweakerAPI.loadedMods) { + String message = mod.getId() + " - " + mod.getName() + " - " + mod.getVersion(); + player.sendChat(platform.getMessage(message)); + MineTweakerAPI.getLogger().logCommand("Mod: " + message); + } + } + })); + + minetweakerCommands.put("name", new MineTweakerCommand( + "name", + new String[] { + "/minetweaker name ", + " Outputs the name for the given item ID", + }, + new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + if (arguments.length < 1) { + player.sendChat(platform.getMessage("missing id parameter")); + } else { + try { + int id = Integer.parseInt(arguments[0]); + IItemDefinition definition = platform.getItemDefinition(id); + if (definition == null) { + player.sendChat(platform.getMessage("no such item")); + } else { + StringBuilder description = new StringBuilder(); + description.append('<'); + description.append(definition.getId()); + description.append('>'); + player.sendChat(platform.getMessage(description.toString())); + } + } catch (NumberFormatException e) { + MineTweakerAPI.getLogger().logCommand("ID must be an integer"); + } + } + } + })); + + minetweakerCommands.put("wiki", new MineTweakerCommand( + "wiki", + new String[] { + "/minetweaker wiki", + " Opens your browser with the wiki" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + player.openBrowser("http://minetweaker3.powerofbytes.com/wiki/"); + } + })); + + minetweakerCommands.put("bugs", new MineTweakerCommand( + "bugs", + new String[] { + "/minetweaker bugs", + " Opens your browser with the GitHub bug tracker" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + player.openBrowser("https://github.com/stanhebben/MineTweaker3/issues"); + } + })); + + minetweakerCommands.put("forum", new MineTweakerCommand( + "forum", + new String[] { + "/minetweaker forum", + " Opens your browser with the forum" + }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + player.openBrowser("http://www.minecraftforum.net/topic/1886008-164-17x-minetweaker-3-customize-your-minecraft-experience"); + } + })); + + } + + /** + * Access point to the event handler implementation. + */ + public static final MTEventManager events = new MTEventManager(); + + public static final MTLogger logger = new MTLogger(); + + /** + * Access point to general platform functions. + */ + public static IPlatformFunctions platform = null; + + public static void onServerStart() { + reload(); + } + + public static void onServerStop() { + + } + + public static void reload() { + logger.clear(); + events.clear(); + + if (MineTweakerAPI.server != null) { + events.onPlayerLoggedIn(LISTEN_LOGIN); + events.onPlayerLoggedOut(LISTEN_LOGOUT); + } + + MineTweakerAPI.tweaker.rollback(); + + if (MineTweakerAPI.server != null) { + server.addCommand("minetweaker", "", new String[] { "mt" }, new ICommandFunction() { + @Override + public void execute(String[] arguments, IPlayer player) { + if (arguments.length == 0) { + player.sendChat(platform.getMessage("Please provide a command. Use /mt help for more info.")); + } else if (arguments[0].equals("help")) { + String[] keys = minetweakerCommands.keySet().toArray(new String[minetweakerCommands.size()]); + Arrays.sort(keys); + for (String key : keys) { + for (String helpMessage : minetweakerCommands.get(key).description) { + player.sendChat(platform.getMessage(helpMessage)); + } + } + } else { + MineTweakerCommand command = minetweakerCommands.get(arguments[0]); + if (command == null) { + player.sendChat(platform.getMessage("No such minetweaker command available")); + } else { + command.function.execute(Arrays.copyOfRange(arguments, 1, arguments.length), player); + } + } + } + }, new ICommandValidator() { + @Override + public boolean canExecute(IPlayer player) { + return server.isOp(player); + } + }, null); + } + + MineTweakerAPI.tweaker.load(); + + if (MineTweakerAPI.server != null) { + platform.distributeScripts(MineTweakerAPI.tweaker.getScriptData()); + } + } + + public static void addMineTweakerCommand(String name, String[] description, ICommandFunction function) { + MineTweakerAPI.tweaker.apply(new AddMineTweakerCommandAction(new MineTweakerCommand(name, description, function))); + } + + public static void callMineTweakerCommand(String[] arguments, IPlayer player) { + if (minetweakerCommands.containsKey(arguments[0])) { + minetweakerCommands.get(arguments[0]).function.execute( + Arrays.copyOfRange(arguments, 1, arguments.length), + player); + } + } + + public static Set getMineTweakerCommands() { + return minetweakerCommands.keySet(); + } + + public static String[] getMineTweakerCommandDescription(String command) { + return minetweakerCommands.get(command).description; + } + + private static class AddMineTweakerCommandAction implements IUndoableAction { + private final MineTweakerCommand command; + + public AddMineTweakerCommandAction(MineTweakerCommand command) { + this.command = command; + } + + @Override + public void apply() { + minetweakerCommands.put(command.name, command); + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + minetweakerCommands.remove(command.name); + } + + @Override + public String describe() { + return "Adding minetweaker command " + command.name; + } + + @Override + public String describeUndo() { + return "Removing minetweaker command " + command.name; + } + + @Override + public Object getOverrideKey() { + return null; + } + } + + private static class MineTweakerCommand { + private final String name; + private final String[] description; + private final ICommandFunction function; + + public MineTweakerCommand(String name, String[] description, ICommandFunction function) { + this.name = name; + this.description = description; + this.function = function; + } + } + + private static class ItemComparator implements Comparator { + @Override + public int compare(IItemDefinition o1, IItemDefinition o2) { + return o1.getId().compareTo(o2.getId()); + } + } + + private static class LiquidComparator implements Comparator { + @Override + public int compare(ILiquidDefinition o1, ILiquidDefinition o2) { + return o1.getName().compareTo(o2.getName()); + } + } + + private static class ListenPlayerLoggedIn implements IPlayerLoggedInEventHandler { + @Override + public void handle(PlayerLoggedInEvent event) { + if (MineTweakerAPI.server != null && MineTweakerAPI.server.isOp(event.getPlayer())) { + logger.addPlayer(event.getPlayer()); + } + } + } + + private static class ListenPlayerLoggedOut implements IPlayerLoggedOutEventHandler { + @Override + public void handle(PlayerLoggedOutEvent event) { + logger.removePlayer(event.getPlayer()); + } + } +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/world/IGame.java b/MineTweaker3-API/src/main/java/minetweaker/api/client/IClient.java similarity index 63% rename from MineTweaker3-API/src/main/java/minetweaker/api/world/IGame.java rename to MineTweaker3-API/src/main/java/minetweaker/api/client/IClient.java index 813ddc6..a86e885 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/world/IGame.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/client/IClient.java @@ -4,9 +4,9 @@ * and open the template in the editor. */ -package minetweaker.api.world; +package minetweaker.api.client; -import java.util.List; +import minetweaker.api.player.IPlayer; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenGetter; @@ -14,8 +14,8 @@ import stanhebben.zenscript.annotations.ZenGetter; * * @author Stan */ -@ZenClass("minetweaker.world.IGame") -public interface IGame { - @ZenGetter("dimensions") - public List getDimensions(); +@ZenClass("minetweaker.api.IClient") +public interface IClient { + @ZenGetter("player") + public IPlayer getPlayer(); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/data/DataMap.java b/MineTweaker3-API/src/main/java/minetweaker/api/data/DataMap.java index a637366..b8a8d94 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/data/DataMap.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/data/DataMap.java @@ -203,6 +203,10 @@ public class DataMap implements IData { @Override public boolean contains(IData data) { + if (data instanceof DataString) { + return this.data.containsKey(data.asString()); + } + Map dataMap = data.asMap(); for (Map.Entry dataEntry : dataMap.entrySet()) { if (!this.data.containsKey(dataEntry.getKey())) { diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/event/AbstractEventManager.java b/MineTweaker3-API/src/main/java/minetweaker/api/event/MTEventManager.java similarity index 94% rename from MineTweaker3-API/src/main/java/minetweaker/api/event/AbstractEventManager.java rename to MineTweaker3-API/src/main/java/minetweaker/api/event/MTEventManager.java index ae508bf..911fbd0 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/event/AbstractEventManager.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/event/MTEventManager.java @@ -12,7 +12,30 @@ import minetweaker.util.EventList; * * @author Stan */ -public class AbstractEventManager implements IEventManager { +public class MTEventManager implements IEventManager { + public void clear() { + elPlayerCrafted.clear(); + elPlayerSmelted.clear(); + elPlayerChangedDimension.clear(); + elPlayerLoggedIn.clear(); + elPlayerLoggedOut.clear(); + elPlayerRespawn.clear(); + elPlayerAttackEntity.clear(); + elPlayerBonemeal.clear(); + elPlayerInteractEntity.clear(); + elPlayerPickup.clear(); + elPlayerPickupItem.clear(); + elPlayerFillBucket.clear(); + elPlayerDeathDrops.clear(); + elPlayerInteract.clear(); + elPlayerOpenContainer.clear(); + elPlayerPickupXp.clear(); + elPlayerSleepInBed.clear(); + elPlayerUseHoe.clear(); + elPlayerUseItemStart.clear(); + elPlayerUseItemTick.clear(); + } + // ########################## // ### PlayerCraftedEvent ### // ########################## diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/game/IGame.java b/MineTweaker3-API/src/main/java/minetweaker/api/game/IGame.java new file mode 100644 index 0000000..3c1ef5f --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/game/IGame.java @@ -0,0 +1,26 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.game; + +import java.util.List; +import minetweaker.api.item.IItemDefinition; +import minetweaker.api.liquid.ILiquidDefinition; +import stanhebben.zenscript.annotations.ZenClass; +import stanhebben.zenscript.annotations.ZenGetter; + +/** + * + * @author Stan + */ +@ZenClass("minetweaker.game.IGame") +public interface IGame { + @ZenGetter("items") + public List getItems(); + + @ZenGetter("liquids") + public List getLiquids(); +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java index aebcd1d..6d75850 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IIngredient.java @@ -115,6 +115,9 @@ public interface IIngredient { @ZenMethod public IItemStack applyTransform(IItemStack item); + @ZenGetter("hasTransformations") + public boolean hasTransformers(); + /** * Gets the internal item backing this ingredient. * diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/IItemDefinition.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IItemDefinition.java index 79fe781..872947e 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/IItemDefinition.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IItemDefinition.java @@ -6,7 +6,11 @@ package minetweaker.api.item; +import stanhebben.zenscript.annotations.Optional; import stanhebben.zenscript.annotations.ZenClass; +import stanhebben.zenscript.annotations.ZenGetter; +import stanhebben.zenscript.annotations.ZenMethod; +import stanhebben.zenscript.annotations.ZenSetter; /** * @@ -14,5 +18,12 @@ import stanhebben.zenscript.annotations.ZenClass; */ @ZenClass("minetweaker.item.IItemDefinition") public interface IItemDefinition { + @ZenGetter("id") + public String getId(); + @ZenGetter("name") + public String getName(); + + @ZenMethod + public IItemStack makeStack(@Optional int meta); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAny.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAny.java index 3b07570..80d3a0b 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAny.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAny.java @@ -70,6 +70,11 @@ public class IngredientAny implements IIngredient { return item; } + @Override + public boolean hasTransformers() { + return false; + } + @Override public Object getInternal() { return INTERNAL_ANY; diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAnyAdvanced.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAnyAdvanced.java index d83b416..66c7248 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAnyAdvanced.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientAnyAdvanced.java @@ -89,6 +89,11 @@ public class IngredientAnyAdvanced implements IIngredient { return item; } + @Override + public boolean hasTransformers() { + return transformers.length > 0; + } + @Override public Object getInternal() { return IngredientAny.INTERNAL_ANY; diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/Condition.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientCondition.java similarity index 66% rename from MineTweaker3-API/src/main/java/minetweaker/api/item/Condition.java rename to MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientCondition.java index 8a7b721..24fdecf 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/Condition.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientCondition.java @@ -7,8 +7,7 @@ package minetweaker.api.item; import minetweaker.api.data.IData; -import stanhebben.zenscript.annotations.ZenClass; -import stanhebben.zenscript.annotations.ZenGetter; +import stanhebben.zenscript.annotations.ZenExpansion; import stanhebben.zenscript.annotations.ZenMethod; /** @@ -18,104 +17,110 @@ import stanhebben.zenscript.annotations.ZenMethod; * * @author Stan Hebben */ -@ZenClass("minetweaker.item.Condition") -public class Condition { +@ZenExpansion("minetweaker.item.IIngredient") +public class IngredientCondition { /** * Requires the item to be damaged. A damage value of 1 is enough. * + * @param ingredient target value * @return damaged condition */ - @ZenGetter - public static IItemCondition damaged() { - return new IItemCondition() { + @ZenMethod + public static IIngredient onlyDamaged(IIngredient ingredient) { + return ingredient.only(new IItemCondition() { @Override public boolean matches(IItemStack stack) { return stack.getDamage() > 0; } - }; + }); } /** * Requires the item to be damaged with at least a specified amount. * + * @param ingredient target value * @param minDamage minimum damage * @return damage condition */ @ZenMethod - public static IItemCondition damageAtLeast(final int minDamage) { - return new IItemCondition() { + public static IIngredient onlyDamageAtLeast(IIngredient ingredient, final int minDamage) { + return ingredient.only(new IItemCondition() { @Override public boolean matches(IItemStack stack) { return stack.getDamage() >= minDamage; } - }; + }); } /** * Requires the item to be damaged with at most a specified amount. An * undamaged item is accepted. * + * @param ingredient target value * @param maxDamage maximum damage * @return damage condition */ @ZenMethod - public static IItemCondition damageAtMost(final int maxDamage) { - return new IItemCondition() { + public static IIngredient onlyDamageAtMost(IIngredient ingredient, final int maxDamage) { + return ingredient.only(new IItemCondition() { @Override public boolean matches(IItemStack stack) { return stack.getDamage() <= maxDamage; } - }; + }); } /** * Requires the item damage value to be between two values. * + * @param ingredient target value * @param minDamage minimum damage * @param maxDamage maximum damage * @return damage condition */ @ZenMethod - public static IItemCondition damageBetween(final int minDamage, final int maxDamage) { - return new IItemCondition() { + public static IIngredient onlyDamageBetween(IIngredient ingredient, final int minDamage, final int maxDamage) { + return ingredient.only(new IItemCondition() { @Override public boolean matches(IItemStack stack) { return stack.getDamage() >= minDamage && stack.getDamage() <= maxDamage; } - }; + }); } /** * Requires the item to contain at least the given tags. It is OK for the * item to contain more data, as remaining data is ignored. * + * @param ingredient target value * @param data required data * @return data condition */ @ZenMethod - public static IItemCondition data(final IData data) { - return new IItemCondition() { + public static IIngredient onlyWithTag(IIngredient ingredient, final IData data) { + return ingredient.only(new IItemCondition() { @Override public boolean matches(IItemStack stack) { return stack.getTag() != null && stack.getTag().contains(data); } - }; + }); } /** * Requires the input stack to contain at least the given number of items. * Used in combination with stack consuming recipes. * + * @param ingredient target value * @param amount required stack size * @return stack size condition */ @ZenMethod - public static IItemCondition stack(final int amount) { - return new IItemCondition() { + public static IIngredient onlyStack(IIngredient ingredient, final int amount) { + return ingredient.only(new IItemCondition() { @Override public boolean matches(IItemStack stack) { return stack.getAmount() >= amount; } - }; + }); } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientItem.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientItem.java index 574bed7..e724939 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientItem.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientItem.java @@ -67,7 +67,7 @@ public class IngredientItem implements IIngredient { @Override public boolean matches(IItemStack item) { - if (!item.matches(item)) return false; + if (!this.item.matches(item)) return false; for (IItemCondition condition : conditions) { if (!condition.matches(item)) return false; @@ -95,6 +95,11 @@ public class IngredientItem implements IIngredient { return item; } + @Override + public boolean hasTransformers() { + return transformers.length > 0; + } + @Override public Object getInternal() { return item.getInternal(); diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientStack.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientStack.java index d01e110..b7fe171 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientStack.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientStack.java @@ -75,4 +75,9 @@ public class IngredientStack implements IIngredient { public Object getInternal() { return null; } + + @Override + public boolean hasTransformers() { + return ingredient.hasTransformers(); + } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/item/Transform.java b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientTransform.java similarity index 65% rename from MineTweaker3-API/src/main/java/minetweaker/api/item/Transform.java rename to MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientTransform.java index 2087f34..22f33f8 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/item/Transform.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/item/IngredientTransform.java @@ -6,49 +6,51 @@ package minetweaker.api.item; -import stanhebben.zenscript.annotations.ZenClass; +import stanhebben.zenscript.annotations.ZenExpansion; import stanhebben.zenscript.annotations.ZenMethod; /** * * @author Stan */ -@ZenClass("minetweaker.item.Transform") -public class Transform { +@ZenExpansion("minetweaker.item.IIngredient") +public class IngredientTransform { /** * Makes the item reusable. Prevents consumption of the item upon crafting. * + * @param ingredient target value * @return reuse transformer */ @ZenMethod - public static IItemTransformer reuse() { - return new IItemTransformer() { + public static IIngredient reuse(IIngredient ingredient) { + return ingredient.transform(new IItemTransformer() { @Override public IItemStack transform(IItemStack item) { return item.withAmount(item.getAmount() + 1); } - }; + }); } /** * Damages the item. Also makes the item reusable. Will damage the item * for 1 point upon crafting and consume it when broken. * + * @param ingredient target value * @return damage transformer */ @ZenMethod - public static IItemTransformer damage() { - return new IItemTransformer() { + public static IIngredient transformDamage(IIngredient ingredient) { + return ingredient.transform(new IItemTransformer() { @Override public IItemStack transform(IItemStack item) { int newDamage = item.getDamage() + 1; if (newDamage >= item.getMaxDamage()) { - return item.withAmount(item.getAmount() - 1).withDamage(0); + return item.withAmount(item.getAmount()).withDamage(0); } else { - return item.withDamage(newDamage); + return item.withAmount(item.getAmount() + 1).withDamage(newDamage); } } - }; + }); } /** @@ -57,12 +59,13 @@ public class Transform { * set the proper condition such that an almost-broken item becomes * invalid for crafting. * + * @param ingredient target value * @param damage damage to be applied * @return damage transformer */ @ZenMethod - public static IItemTransformer damage(final int damage) { - return new IItemTransformer() { + public static IIngredient transformDamage(IIngredient ingredient, final int damage) { + return ingredient.transform(new IItemTransformer() { @Override public IItemStack transform(IItemStack item) { int newDamage = item.getDamage() + damage; @@ -72,26 +75,25 @@ public class Transform { return item.withDamage(newDamage); } } - }; + }); } /** * Causes the item to be replaced upon crafting. Can be used, for instance, * to return empty bottles or buckets. * + * @param ingredient target value * @param withItem replacement item * @return replacement transformer */ @ZenMethod - public static IItemTransformer replaceWith(IItemStack withItem) { - final IItemStack result = withItem.withAmount(withItem.getAmount() + 1); - - return new IItemTransformer() { + public static IIngredient transformReplace(IIngredient ingredient, final IItemStack withItem) { + return ingredient.transform(new IItemTransformer() { @Override public IItemStack transform(IItemStack item) { - return result; + return withItem.withAmount(withItem.getAmount() + 1); } - }; + }); } /** @@ -99,16 +101,17 @@ public class Transform { * a minimum stack size too, as otherwise smaller stacks would still be * accepted for input. * + * @param ingredient target value * @param amount consumption amount * @return consuming transformer */ @ZenMethod - public static IItemTransformer consume(final int amount) { - return new IItemTransformer() { + public static IIngredient transformConsume(IIngredient ingredient, final int amount) { + return ingredient.transform(new IItemTransformer() { @Override public IItemStack transform(IItemStack item) { return item.withAmount(Math.max(item.getAmount() - amount, 0) + 1); } - }; + }); } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/logger/FileLogger.java b/MineTweaker3-API/src/main/java/minetweaker/api/logger/FileLogger.java new file mode 100644 index 0000000..cf66fd7 --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/logger/FileLogger.java @@ -0,0 +1,74 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.logger; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import minetweaker.runtime.ILogger; + +/** + * + * @author Stan Hebben + */ +public class FileLogger implements ILogger { + private final Writer writer; + + public FileLogger(File output) { + try { + writer = new OutputStreamWriter(new FileOutputStream(output), "utf-8"); + } catch (UnsupportedEncodingException ex) { + throw new RuntimeException("What the heck?"); + } catch (FileNotFoundException ex) { + throw new RuntimeException("File not found"); + } + } + + @Override + public void logCommand(String message) { + try { + writer.write("COMMAND: " + message + "\n"); + writer.flush(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @Override + public void logInfo(String message) { + try { + writer.write("INFO: " + message + "\n"); + writer.flush(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @Override + public void logWarning(String message) { + try { + writer.write("WARNING: " + message + "\n"); + writer.flush(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @Override + public void logError(String message) { + try { + writer.write("ERROR: " + message + "\n"); + writer.flush(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/logger/MTLogger.java b/MineTweaker3-API/src/main/java/minetweaker/api/logger/MTLogger.java new file mode 100644 index 0000000..5fcc246 --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/logger/MTLogger.java @@ -0,0 +1,97 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.logger; + +import java.util.ArrayList; +import java.util.List; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.player.IPlayer; +import minetweaker.runtime.ILogger; + +/** + * + * @author Stan + */ +public class MTLogger implements ILogger { + private final List loggers = new ArrayList(); + private final List players = new ArrayList(); + private final List unprocessed = new ArrayList(); + + public void addLogger(ILogger logger) { + loggers.add(logger); + } + + public void removeLogger(ILogger logger) { + loggers.remove(logger); + } + + public void addPlayer(IPlayer player) { + players.add(player); + + if (!unprocessed.isEmpty()) { + for (String message : unprocessed) { + player.sendChat(MineTweakerImplementationAPI.platform.getMessage(message)); + } + } + } + + public void removePlayer(IPlayer player) { + players.remove(player); + } + + public void clear() { + unprocessed.clear(); + } + + @Override + public void logCommand(String message) { + for (ILogger logger : loggers) { + logger.logCommand(message); + } + } + + @Override + public void logInfo(String message) { + for (ILogger logger : loggers) { + logger.logInfo(message); + } + } + + @Override + public void logWarning(String message) { + for (ILogger logger : loggers) { + logger.logWarning(message); + } + + String message2 = "WARNING: " + message; + + if (players.isEmpty()) { + unprocessed.add(message2); + } else { + for (IPlayer player : players) { + player.sendChat(MineTweakerImplementationAPI.platform.getMessage(message2)); + } + } + } + + @Override + public void logError(String message) { + for (ILogger logger : loggers) { + logger.logError(message); + } + + String message2 = "ERROR: " + message; + + if (players.isEmpty()) { + unprocessed.add(message2); + } else { + for (IPlayer player : players) { + player.sendChat(MineTweakerImplementationAPI.platform.getMessage(message2)); + } + } + } +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDict.java b/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDict.java index 2b949a3..d8766c1 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDict.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDict.java @@ -6,7 +6,9 @@ package minetweaker.api.oredict; +import java.util.List; import stanhebben.zenscript.annotations.ZenClass; +import stanhebben.zenscript.annotations.ZenGetter; import stanhebben.zenscript.annotations.ZenMemberGetter; /** @@ -17,4 +19,7 @@ import stanhebben.zenscript.annotations.ZenMemberGetter; public interface IOreDict { @ZenMemberGetter public IOreDictEntry get(String name); + + @ZenGetter("entries") + public List getEntries(); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDictEntry.java b/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDictEntry.java index 44cc163..8e46da2 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDictEntry.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IOreDictEntry.java @@ -18,6 +18,9 @@ import stanhebben.zenscript.annotations.ZenMethod; */ @ZenClass("minetweaker.oredict.IOreDictEntry") public interface IOreDictEntry extends IIngredient { + @ZenGetter("name") + public String getName(); + @ZenGetter("empty") public boolean isEmpty(); diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IngredientOreDict.java b/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IngredientOreDict.java index 63a1c90..243b408 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IngredientOreDict.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/oredict/IngredientOreDict.java @@ -95,6 +95,11 @@ public class IngredientOreDict implements IIngredient { return item; } + @Override + public boolean hasTransformers() { + return transformers.length > 0; + } + @Override public Object getInternal() { return entry.getInternal(); diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java b/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java index 4bca2a4..d60861b 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/player/IPlayer.java @@ -6,8 +6,10 @@ package minetweaker.api.player; +import java.util.List; import minetweaker.api.chat.IChatMessage; import minetweaker.api.data.IData; +import minetweaker.api.item.IItemStack; import stanhebben.zenscript.annotations.ZenClass; import stanhebben.zenscript.annotations.ZenGetter; import stanhebben.zenscript.annotations.ZenMethod; @@ -18,6 +20,9 @@ import stanhebben.zenscript.annotations.ZenMethod; */ @ZenClass("minetweaker.player.IPlayer") public interface IPlayer { + @ZenGetter("id") + public String getId(); + @ZenGetter("name") public String getName(); @@ -29,4 +34,21 @@ public interface IPlayer { @ZenMethod public void sendChat(IChatMessage message); + + @ZenGetter("hotbarSize") + public int getHotbarSize(); + + @ZenMethod + public IItemStack getHotbarStack(int i); + + @ZenGetter("inventorySize") + public int getInventorySize(); + + @ZenMethod + public IItemStack getInventoryStack(int i); + + @ZenGetter("currentItem") + public IItemStack getCurrentItem(); + + public void openBrowser(String url); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/CraftingInfo.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/CraftingInfo.java new file mode 100644 index 0000000..160a565 --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/CraftingInfo.java @@ -0,0 +1,39 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.recipes; + +import minetweaker.api.player.IPlayer; +import minetweaker.api.world.IDimension; + +/** + * + * @author Stan + */ +public class CraftingInfo implements ICraftingInfo { + private final ICraftingInventory inventory; + private final IDimension dimension; + + public CraftingInfo(ICraftingInventory inventory, IDimension dimension) { + this.inventory = inventory; + this.dimension = dimension; + } + + @Override + public ICraftingInventory getInventory() { + return inventory; + } + + @Override + public IPlayer getPlayer() { + return inventory.getPlayer(); + } + + @Override + public IDimension getDimension() { + return dimension; + } +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ICraftingInfo.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ICraftingInfo.java new file mode 100644 index 0000000..52f3926 --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ICraftingInfo.java @@ -0,0 +1,28 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.recipes; + +import minetweaker.api.player.IPlayer; +import minetweaker.api.world.IDimension; +import stanhebben.zenscript.annotations.ZenClass; +import stanhebben.zenscript.annotations.ZenGetter; + +/** + * + * @author Stan Hebben + */ +@ZenClass("minetweaker.recipes.ICraftingInfo") +public interface ICraftingInfo { + @ZenGetter("inventory") + public ICraftingInventory getInventory(); + + @ZenGetter("player") + public IPlayer getPlayer(); + + @ZenGetter("dimension") + public IDimension getDimension(); +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ICraftingRecipe.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ICraftingRecipe.java new file mode 100644 index 0000000..058bf5b --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ICraftingRecipe.java @@ -0,0 +1,25 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.recipes; + +import minetweaker.api.item.IItemStack; +import stanhebben.zenscript.annotations.ZenClass; + +/** + * + * @author Stan + */ +@ZenClass("minetweaker.recipes.ICraftingRecipe") +public interface ICraftingRecipe { + public boolean matches(ICraftingInventory inventory); + + public IItemStack getCraftingResult(ICraftingInventory inventory); + + public boolean hasTransformers(); + + public void applyTransformers(ICraftingInventory inventory); +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeFunction.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeFunction.java index 8332a4a..9a1ae0b 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeFunction.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/IRecipeFunction.java @@ -16,5 +16,5 @@ import stanhebben.zenscript.annotations.ZenClass; */ @ZenClass("minetweaker.recipes.IRecipeFunction") public interface IRecipeFunction { - public IItemStack process(IItemStack output, Map inputs, ICraftingInventory inventory); + public IItemStack process(IItemStack output, Map inputs, ICraftingInfo craftingInfo); } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapedRecipe.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapedRecipe.java index dfc8629..2a6ebd6 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapedRecipe.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapedRecipe.java @@ -15,7 +15,7 @@ import minetweaker.api.item.IItemStack; * * @author Stan */ -public class ShapedRecipe { +public class ShapedRecipe implements ICraftingRecipe { private final int width; private final int height; private final byte[] posx; @@ -93,6 +93,7 @@ public class ShapedRecipe { return output; } + @Override public boolean matches(ICraftingInventory inventory) { if (inventory.getStackCount() != ingredients.length) { return false; @@ -129,6 +130,7 @@ public class ShapedRecipe { return false; } + @Override public IItemStack getCraftingResult(ICraftingInventory inventory) { IItemStack[] stacks = new IItemStack[ingredients.length]; @@ -165,6 +167,54 @@ public class ShapedRecipe { return null; } + @Override + public boolean hasTransformers() { + for (IIngredient ingredient : ingredients) { + if (ingredient.hasTransformers()) { + return true; + } + } + + return false; + } + + @Override + public void applyTransformers(ICraftingInventory inventory) { + IItemStack[] stacks = new IItemStack[ingredients.length]; + + for (int i = 0; i <= inventory.getWidth() - width; i++) { + out: for (int j = 0; j <= inventory.getHeight() - height; j++) { + for (int k = 0; k < ingredients.length; k++) { + IItemStack item = inventory.getStack(posx[k] + i, posy[k] + j); + if (item == null) continue out; + + if (!ingredients[k].matches(item)) continue out; + stacks[k] = item; + } + + doRecipeTransformers(inventory, stacks, i, j, false); + return; + } + } + + if (mirrored) { + for (int i = 0; i <= inventory.getWidth() - width; i++) { + out: for (int j = 0; j <= inventory.getHeight() - height; j++) { + for (int k = 0; k < ingredients.length; k++) { + IItemStack item = inventory.getStack(inventory.getWidth() - (posx[k] + i) - 1, posy[k] + j); + if (item == null) continue out; + + if (!ingredients[k].matches(item)) continue out; + stacks[k] = item; + } + + doRecipeTransformers(inventory, stacks, i, j, true); + return; + } + } + } + } + private IItemStack doRecipe( ICraftingInventory inventory, IItemStack[] stacks, @@ -181,7 +231,8 @@ public class ShapedRecipe { } } - output = function.process(output, tagged, inventory); + // TODO: supply dimension + output = function.process(output, tagged, new CraftingInfo(inventory, null)); System.out.println("Ouput: " + output); } @@ -189,6 +240,31 @@ public class ShapedRecipe { return null; } + /*for (int i = 0; i < ingredients.length; i++) { + IItemStack transformed = ingredients[i].applyTransform(stacks[i]); + if (transformed != stacks[i]) { + if (mirrored) { + inventory.setStack( + inventory.getWidth() - (offx + posx[i]) - 1, + offy + posy[i], + transformed); + } else { + inventory.setStack( + offx + posx[i], + offy + posy[i], + transformed); + } + } + }*/ + + return output; + } + + private void doRecipeTransformers( + ICraftingInventory inventory, + IItemStack[] stacks, + int offx, int offy, + boolean mirrored) { for (int i = 0; i < ingredients.length; i++) { IItemStack transformed = ingredients[i].applyTransform(stacks[i]); if (transformed != stacks[i]) { @@ -205,7 +281,5 @@ public class ShapedRecipe { } } } - - return output; } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapelessRecipe.java b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapelessRecipe.java index de19dd6..6a6552a 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapelessRecipe.java +++ b/MineTweaker3-API/src/main/java/minetweaker/api/recipes/ShapelessRecipe.java @@ -15,7 +15,7 @@ import minetweaker.api.item.IItemStack; * * @author Stan */ -public class ShapelessRecipe { +public class ShapelessRecipe implements ICraftingRecipe { private final IItemStack output; private final IRecipeFunction function; private final IIngredient[] ingredients; @@ -38,10 +38,12 @@ public class ShapelessRecipe { return output; } + @Override public boolean matches(ICraftingInventory inventory) { return matchShapeless(ingredients, inventory) != null; } + @Override public IItemStack getCraftingResult(ICraftingInventory inventory) { RecipeMatching matching = matchShapeless(ingredients, inventory); @@ -54,13 +56,20 @@ public class ShapelessRecipe { } } - actualOutput = function.process(actualOutput, map, inventory); + actualOutput = function.process(actualOutput, map, new CraftingInfo(inventory, null)); } if (actualOutput == null) { return null; } + return actualOutput; + } + + @Override + public void applyTransformers(ICraftingInventory inventory) { + RecipeMatching matching = matchShapeless(ingredients, inventory); + for (int i = 0; i < ingredients.length; i++) { IIngredient ingredient = ingredients[i]; IItemStack transformed = ingredient.applyTransform(matching.inputs[i]); @@ -68,8 +77,6 @@ public class ShapelessRecipe { inventory.setStack(matching.indices[i], transformed); } } - - return actualOutput; } /** @@ -116,6 +123,17 @@ public class ShapelessRecipe { return new RecipeMatching(matched, indices); } + @Override + public boolean hasTransformers() { + for (IIngredient ingredient : ingredients) { + if (ingredient.hasTransformers()) { + return true; + } + } + + return false; + } + private static class RecipeMatching { public final IItemStack[] inputs; public final int[] indices; diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/server/CommandValidators.java b/MineTweaker3-API/src/main/java/minetweaker/api/server/CommandValidators.java new file mode 100644 index 0000000..70be81d --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/server/CommandValidators.java @@ -0,0 +1,31 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.server; + +import minetweaker.MineTweakerAPI; +import minetweaker.api.player.IPlayer; +import stanhebben.zenscript.annotations.ZenClass; +import stanhebben.zenscript.annotations.ZenGetter; + +/** + * + * @author Stan + */ +@ZenClass("minetweaker.server.CommandValidators") +public class CommandValidators { + public static final ICommandValidator ISOP = new ICommandValidator() { + @Override + public boolean canExecute(IPlayer player) { + return MineTweakerAPI.server.isOp(player); + } + }; + + @ZenGetter + public static ICommandValidator isOp() { + return ISOP; + } +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandFunction.java b/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandFunction.java new file mode 100644 index 0000000..4eadd1c --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandFunction.java @@ -0,0 +1,19 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.server; + +import minetweaker.api.player.IPlayer; +import stanhebben.zenscript.annotations.ZenClass; + +/** + * + * @author Stan + */ +@ZenClass("minetweaker.server.ICommandFunction") +public interface ICommandFunction { + public void execute(String[] arguments, IPlayer player); +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandTabCompletion.java b/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandTabCompletion.java new file mode 100644 index 0000000..e64a52c --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandTabCompletion.java @@ -0,0 +1,19 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.server; + +import minetweaker.api.player.IPlayer; +import stanhebben.zenscript.annotations.ZenClass; + +/** + * + * @author Stan + */ +@ZenClass("minetweaker.server.ICommandTabCompletion") +public interface ICommandTabCompletion { + public String[] getTabCompletionOptions(String[] command, IPlayer player); +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandValidator.java b/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandValidator.java new file mode 100644 index 0000000..dcfeb04 --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/server/ICommandValidator.java @@ -0,0 +1,19 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.server; + +import minetweaker.api.player.IPlayer; +import stanhebben.zenscript.annotations.ZenClass; + +/** + * + * @author Stan + */ +@ZenClass("minetweaker.server.ICommandValidator") +public interface ICommandValidator { + public boolean canExecute(IPlayer player); +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/api/server/IServer.java b/MineTweaker3-API/src/main/java/minetweaker/api/server/IServer.java new file mode 100644 index 0000000..c883736 --- /dev/null +++ b/MineTweaker3-API/src/main/java/minetweaker/api/server/IServer.java @@ -0,0 +1,37 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.api.server; + +import minetweaker.api.player.IPlayer; +import stanhebben.zenscript.annotations.Optional; +import stanhebben.zenscript.annotations.ZenClass; +import stanhebben.zenscript.annotations.ZenMethod; + +/** + * + * @author Stan + */ +@ZenClass("minetweaker.server.IServer") +public interface IServer { + @ZenMethod + public void addCommand( + String name, + String usage, + String[] aliases, + ICommandFunction function, + @Optional ICommandValidator validator, + @Optional ICommandTabCompletion completion); + + @ZenMethod + public void removeCommand(String name); + + @ZenMethod + public void addMineTweakerCommand(String name, String[] usage, ICommandFunction function); + + @ZenMethod + public boolean isOp(IPlayer player); +} diff --git a/MineTweaker3-API/src/main/java/minetweaker/expand/ExpandString.java b/MineTweaker3-API/src/main/java/minetweaker/expand/ExpandString.java index 63a7863..e3ecd44 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/expand/ExpandString.java +++ b/MineTweaker3-API/src/main/java/minetweaker/expand/ExpandString.java @@ -6,12 +6,16 @@ package minetweaker.expand; -import minetweaker.MineTweakerAPI; +import java.util.ArrayList; +import java.util.List; +import minetweaker.MineTweakerImplementationAPI; import minetweaker.api.chat.IChatMessage; import minetweaker.api.data.DataString; import minetweaker.api.data.IData; +import stanhebben.zenscript.annotations.Optional; import stanhebben.zenscript.annotations.ZenCaster; import stanhebben.zenscript.annotations.ZenExpansion; +import stanhebben.zenscript.annotations.ZenMethod; /** * @@ -26,6 +30,46 @@ public class ExpandString { @ZenCaster public static IChatMessage asChatMessage(String value) { - return MineTweakerAPI.platform.getMessage(value); + return MineTweakerImplementationAPI.platform.getMessage(value); + } + + @ZenMethod + public static List split(String value, String separator, @Optional int maximum) { + List result = new ArrayList(); + int minIndex = 0; + int numSplits = 0; + + while (minIndex + separator.length() <= value.length()) { + int index = value.indexOf(separator, minIndex); + if (index < 0) break; + result.add(value.substring(minIndex, index)); + minIndex = index + separator.length(); + + numSplits++; + if (maximum > 0 && numSplits >= maximum) break; + } + + result.add(value.substring(minIndex)); + return result; + } + + @ZenMethod + public static int indexOf(String value, String needle) { + return value.indexOf(needle); + } + + @ZenMethod + public static int indexOf(String value, String needle, int fromIndex) { + return value.indexOf(needle, fromIndex); + } + + @ZenMethod + public static int lastIndexOf(String value, String needle) { + return value.lastIndexOf(needle); + } + + @ZenMethod + public static int lastIndexOf(String value, String needle, int fromIndex) { + return value.lastIndexOf(value, fromIndex); } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalFunctions.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalFunctions.java index c6f5714..257a41f 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalFunctions.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalFunctions.java @@ -16,6 +16,6 @@ public class GlobalFunctions { private GlobalFunctions() {} public static void print(String message) { - MineTweakerAPI.logger.logInfo(message); + MineTweakerAPI.getLogger().logInfo(message); } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java index f7371f7..0ca465f 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/GlobalRegistry.java @@ -142,12 +142,20 @@ public class GlobalRegistry { private static class MyErrorLogger implements IZenErrorLogger { @Override public void error(ZenPosition position, String message) { - MineTweakerAPI.logger.logError(position.toString() + ": " + message); + if (position == null) { + MineTweakerAPI.getLogger().logError("system: " + message); + } else { + MineTweakerAPI.getLogger().logError(position + ": " + message); + } } @Override public void warning(ZenPosition position, String message) { - MineTweakerAPI.logger.logWarning(position.toString() + ": " + message); + if (position == null) { + MineTweakerAPI.getLogger().logWarning("system: " + message); + } else { + MineTweakerAPI.getLogger().logWarning(position + ": " + message); + } } } @@ -251,12 +259,12 @@ public class GlobalRegistry { @Override public void error(ZenPosition position, String message) { - MineTweakerAPI.logger.logError(position.toString() + " > " + message); + MineTweakerAPI.getLogger().logError(position.toString() + " > " + message); } @Override public void warning(ZenPosition position, String message) { - MineTweakerAPI.logger.logWarning(position.toString() + " > " + message); + MineTweakerAPI.getLogger().logWarning(position.toString() + " > " + message); } } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/IMineTweaker.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/ITweaker.java similarity index 96% rename from MineTweaker3-API/src/main/java/minetweaker/runtime/IMineTweaker.java rename to MineTweaker3-API/src/main/java/minetweaker/runtime/ITweaker.java index d2340c7..93b0067 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/IMineTweaker.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/ITweaker.java @@ -6,7 +6,6 @@ package minetweaker.runtime; -import java.io.Closeable; import java.util.List; import minetweaker.IUndoableAction; import minetweaker.api.item.IIngredient; @@ -18,7 +17,7 @@ import stanhebben.zenscript.annotations.ZenMethod; * @author Stan */ @ZenClass("minetweaker.IMineTweaker") -public interface IMineTweaker { +public interface ITweaker { /** * Executes a specified MineTweaker action. Will print a log message and * adds the action to the undo list. diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/Tweaker.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/MTTweaker.java similarity index 82% rename from MineTweaker3-API/src/main/java/minetweaker/runtime/Tweaker.java rename to MineTweaker3-API/src/main/java/minetweaker/runtime/MTTweaker.java index 0766a04..d69a1d7 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/Tweaker.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/MTTweaker.java @@ -35,7 +35,7 @@ import stanhebben.zenscript.parser.ParseException; * * @author Stan Hebben */ -public class Tweaker implements IMineTweaker { +public class MTTweaker implements ITweaker { private final List actions = new ArrayList(); private final Set wereStuck = new LinkedHashSet(); private final Map stuckOverridable = new HashMap(); @@ -45,7 +45,7 @@ public class Tweaker implements IMineTweaker { @Override public void apply(IUndoableAction action) { - MineTweakerAPI.logger.logInfo(action.describe()); + MineTweakerAPI.getLogger().logInfo(action.describe()); Object overrideKey = action.getOverrideKey(); if (wereStuck.contains(action)) { @@ -76,10 +76,10 @@ public class Tweaker implements IMineTweaker { for (int i = actions.size() - 1; i >= 0; i--) { IUndoableAction action = actions.get(i); if (action.canUndo()) { - MineTweakerAPI.logger.logInfo(action.describeUndo()); + MineTweakerAPI.getLogger().logInfo(action.describeUndo()); action.undo(); } else { - MineTweakerAPI.logger.logInfo("[Stuck] " + action.describe()); + MineTweakerAPI.getLogger().logInfo("[Stuck] " + action.describe()); stuck.add(0, action); wereStuck.add(action); @@ -100,6 +100,8 @@ public class Tweaker implements IMineTweaker { @Override public void load() { + System.out.println("Loading scripts"); + scriptData = ScriptProviderMemory.collect(scriptProvider); Set executed = new HashSet(); @@ -127,11 +129,12 @@ public class Tweaker implements IMineTweaker { ZenParsedFile pfile = new ZenParsedFile(filename, className, parser, environmentGlobal); files.add(pfile); } catch (IOException ex) { - MineTweakerAPI.logger.logError("Could not load script " + script.getName() + ": " + ex.getMessage()); + MineTweakerAPI.getLogger().logError("Could not load script " + script.getName() + ": " + ex.getMessage()); } catch (ParseException ex) { - MineTweakerAPI.logger.logError("Error parsing " + ex.getFile() + ":" + ex.getLine() + " -- " + ex.getExplanation()); + //ex.printStackTrace(); + MineTweakerAPI.getLogger().logError("Error parsing " + ex.getFile().getFileName() + ":" + ex.getLine() + " -- " + ex.getExplanation()); } catch (Exception ex) { - MineTweakerAPI.logger.logError("Error loading " + script.getName() + ": " + ex.toString()); + MineTweakerAPI.getLogger().logError("Error loading " + script.getName() + ": " + ex.toString()); ex.printStackTrace(); } @@ -151,16 +154,16 @@ public class Tweaker implements IMineTweaker { ZenModule module = new ZenModule(classes, MineTweakerAPI.class.getClassLoader()); module.getMain().run(); } catch (Exception ex) { - MineTweakerAPI.logger.logError("Error executing " + script.getGroupName() + ": " + ex.getMessage()); + MineTweakerAPI.getLogger().logError("Error executing " + script.getGroupName() + ": " + ex.getMessage()); ex.printStackTrace(); } } } if (wereStuck.size() > 0) { - MineTweakerAPI.logger.logWarning(Integer.toString(wereStuck.size()) + " modifications were stuck"); + MineTweakerAPI.getLogger().logWarning(Integer.toString(wereStuck.size()) + " modifications were stuck"); for (IUndoableAction action : wereStuck) { - MineTweakerAPI.logger.logInfo("Stuck: " + action.describe()); + MineTweakerAPI.getLogger().logInfo("Stuck: " + action.describe()); } } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderDirectory.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderDirectory.java index 61ec9aa..c50a8cc 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderDirectory.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderDirectory.java @@ -23,22 +23,26 @@ public class ScriptProviderDirectory implements IScriptProvider { private final File directory; public ScriptProviderDirectory(File directory) { + if (directory == null) throw new IllegalArgumentException("directory cannot be null"); + this.directory = directory; } @Override public Iterator getScripts() { List scripts = new ArrayList(); - for (File file : directory.listFiles()) { - if (file.isDirectory()) { - scripts.add(new ScriptIteratorDirectory(file)); - } else if (file.getName().endsWith(".zs")) { - scripts.add(new ScriptIteratorSingle(file)); - } else if (file.getName().endsWith(".zip")) { - try { - scripts.add(new ScriptIteratorZip(file)); - } catch (IOException ex) { - MineTweakerAPI.logger.logError("Could not load " + file.getName() + ": " + ex.getMessage()); + if (directory.exists()) { + for (File file : directory.listFiles()) { + if (file.isDirectory()) { + scripts.add(new ScriptIteratorDirectory(file)); + } else if (file.getName().endsWith(".zs")) { + scripts.add(new ScriptIteratorSingle(file)); + } else if (file.getName().endsWith(".zip")) { + try { + scripts.add(new ScriptIteratorZip(file)); + } catch (IOException ex) { + MineTweakerAPI.getLogger().logError("Could not load " + file.getName() + ": " + ex.getMessage()); + } } } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderMemory.java b/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderMemory.java index dee719a..81b9f99 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderMemory.java +++ b/MineTweaker3-API/src/main/java/minetweaker/runtime/providers/ScriptProviderMemory.java @@ -63,7 +63,7 @@ public class ScriptProviderMemory implements IScriptProvider { deflater.close(); } catch (IOException ex) { - MineTweakerAPI.logger.logError("Could not collect scripts: " + ex.getMessage()); + MineTweakerAPI.getLogger().logError("Could not collect scripts: " + ex.getMessage()); } return output.toByteArray(); } @@ -96,7 +96,7 @@ public class ScriptProviderMemory implements IScriptProvider { inflaterData.close(); } catch (IOException ex) { - MineTweakerAPI.logger.logError("Could not load transmitted scripts: " + ex.getMessage()); + MineTweakerAPI.getLogger().logError("Could not load transmitted scripts: " + ex.getMessage()); } } diff --git a/MineTweaker3-API/src/main/java/minetweaker/util/EventList.java b/MineTweaker3-API/src/main/java/minetweaker/util/EventList.java index 55db290..4e87612 100644 --- a/MineTweaker3-API/src/main/java/minetweaker/util/EventList.java +++ b/MineTweaker3-API/src/main/java/minetweaker/util/EventList.java @@ -16,6 +16,10 @@ public class EventList { private EventNode first = null; private EventNode last = null; + public void clear() { + first = last = null; + } + public IEventHandle add(IEventHandler handler) { EventNode node = new EventNode(handler, last, null); diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java index d9d5f13..f574c28 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java @@ -35,7 +35,7 @@ public class MineTweakerMC { public static ItemStack getItemStack(IItemStack item) { Object internal = item.getInternal(); if (internal == null || !(internal instanceof ItemStack)) { - MineTweakerAPI.logger.logError("Not a valid item stack: " + item); + MineTweakerAPI.getLogger().logError("Not a valid item stack: " + item); } return (ItemStack) internal; } @@ -50,7 +50,7 @@ public class MineTweakerMC { public static ItemStack getItemStack(IIngredient ingredient) { List items = ingredient.getItems(); if (items.size() != 1) { - MineTweakerAPI.logger.logError("Not an ingredient with a single item: " + ingredient); + MineTweakerAPI.getLogger().logError("Not an ingredient with a single item: " + ingredient); } return getItemStack(items.get(0)); } @@ -62,9 +62,20 @@ public class MineTweakerMC { * @return minetweaker item stack */ public static IItemStack getIItemStack(ItemStack item) { + if (item == null) return null; return new MCItemStack(item); } + /** + * Constructs an item stack with wildcard size. + * + * @param item minecraft item stack + * @return minetweaker stack + */ + public static IItemStack getIItemStackWildcardSize(ItemStack item) { + return new MCItemStack(item, true); + } + /** * Constructs an item stack with wildcard size. * @@ -131,7 +142,7 @@ public class MineTweakerMC { if (internal != null && internal instanceof ItemStack) { output[i] = (ItemStack) internal; } else { - MineTweakerAPI.logger.logError("Invalid item stack: " + items.get(i)); + MineTweakerAPI.getLogger().logError("Invalid item stack: " + items.get(i)); } } return output; @@ -196,7 +207,7 @@ public class MineTweakerMC { */ public static EntityPlayer getPlayer(IPlayer player) { if (!(player instanceof MCPlayer)) { - MineTweakerAPI.logger.logError("Invalid player: " + player); + MineTweakerAPI.getLogger().logError("Invalid player: " + player); } return ((MCPlayer) player).getInternal(); diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MCPlatformFunctions.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MCPlatformFunctions.java index 45714a1..fc7716f 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MCPlatformFunctions.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MCPlatformFunctions.java @@ -6,9 +6,17 @@ package minetweaker.mc164; +import cpw.mods.fml.common.network.PacketDispatcher; import minetweaker.IPlatformFunctions; +import minetweaker.MineTweakerAPI; import minetweaker.api.chat.IChatMessage; +import minetweaker.api.item.IItemDefinition; import minetweaker.mc164.chat.MCChatMessage; +import minetweaker.mc164.item.MCItemDefinition; +import minetweaker.mc164.network.MCPacketHandler; +import net.minecraft.item.Item; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.Packet250CustomPayload; /** * @@ -23,4 +31,20 @@ public class MCPlatformFunctions implements IPlatformFunctions { public IChatMessage getMessage(String message) { return new MCChatMessage(message); } + + @Override + public void distributeScripts(byte[] data) { + Packet packet = new Packet250CustomPayload( + MCPacketHandler.CHANNEL_SERVERSCRIPT, + MineTweakerAPI.tweaker.getScriptData()); + PacketDispatcher.sendPacketToAllPlayers(packet); + } + + @Override + public IItemDefinition getItemDefinition(int id) { + if (id < 0 || id >= Item.itemsList.length) return null; + Item item = Item.itemsList[id]; + if (item == null) return null; + return new MCItemDefinition(item); + } } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MTCraftingHandler.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MTCraftingHandler.java new file mode 100644 index 0000000..f861956 --- /dev/null +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MTCraftingHandler.java @@ -0,0 +1,41 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc164; + +import cpw.mods.fml.common.ICraftingHandler; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.event.PlayerCraftedEvent; +import minetweaker.api.minecraft.MineTweakerMC; +import minetweaker.mc164.recipes.MCCraftingInventory; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +/** + * + * @author Stan + */ +public class MTCraftingHandler implements ICraftingHandler { + @Override + public void onCrafting(EntityPlayer player, ItemStack crafting, IInventory craftMatrix) { + if (MineTweakerMod.INSTANCE.recipes.hasTransformerRecipes()) { + MineTweakerMod.INSTANCE.recipes.applyTransformations(MCCraftingInventory.get(craftMatrix, player)); + } + + if (MineTweakerImplementationAPI.events.hasPlayerCrafted()) { + MineTweakerImplementationAPI.events.publishPlayerCrafted(new PlayerCraftedEvent( + MineTweakerMC.getIPlayer(player), + MineTweakerMC.getIItemStack(crafting), + MCCraftingInventory.get(craftMatrix, player))); + } + } + + @Override + public void onSmelting(EntityPlayer ep, ItemStack is) { + + } +} diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerCommand.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerCommand.java deleted file mode 100644 index a26b3cd..0000000 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerCommand.java +++ /dev/null @@ -1,399 +0,0 @@ -package minetweaker.mc164; - -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.ModContainer; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import minetweaker.MineTweakerAPI; -import minetweaker.api.item.IItemStack; -import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; -import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; -import minetweaker.api.oredict.IOreDictEntry; - -import net.minecraft.command.ICommand; -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ChatMessageComponent; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.oredict.OreDictionary; -import stanhebben.zenscript.util.StringUtil; - -/** - * Implements the /minetweaker command set. - * - * @author Stan Hebben - */ -public class MineTweakerCommand implements ICommand { - // ########################### - // ## Public static methods ## - // ########################### - - public static void sendChatMessage(ICommandSender sender, String message) { - sender.sendChatToPlayer(ChatMessageComponent.createFromText(message)); - } - - private static final List aliases = Arrays.asList("mt"); - - // ####################################### - // ## ICommand interface implementation ## - // ####################################### - - @Override - public int compareTo(Object arg0) { - return 0; - } - - @Override - public String getCommandName() { - return "minetweaker"; - } - - @Override - public String getCommandUsage(ICommandSender icommandsender) { - return StringUtil.join(new String[] { - "", - "minetweaker reload", - " Reloads all scripts", - "minetweaker names", - " Outputs a list of all item names in the game to the minetweaker log", - "minetweaker liquids", - " Outputs a list of all liquid names in the game to the minetweaker log", - "minetweaker inventory", - " Lists all items in your inventory", - "minetweaker hand", - " Outputs the name of the item in your hand", - "minetweaker oredict", - " Outputs all ore dictionary entries in the game to the minetweaker log", - "minetweaker oredict ", - " Outputs all items in the given ore dictionary entry to the minetweaker log", - "minetweaker mods", - " Outputs all active mod IDs in the game", - "minetweaker name ", - " Outputs the name for the given item ID" - }, "\n"); - } - - @Override - public List getCommandAliases() { - return aliases; - } - - @Override - public void processCommand(ICommandSender icommandsender, String[] arguments) { - if (arguments.length == 0) { - sendChatMessage(icommandsender, "Please provide a command. Use /help minetweaker for more info."); - return; - } - - if (arguments[0].equals("reload")) { - MineTweakerMod.INSTANCE.reload(); - - String message = "Scripts have been reloaded"; - sendChatMessage(icommandsender, message); - } else if (arguments[0].equals("names")) { - for (Item item : Item.itemsList) { - if (item == null) continue; - - String key = item.getUnlocalizedName(); - - String displayName = ""; - - try { - displayName = " -- " + new ItemStack(item, 1, 0).getDisplayName(); - } catch (Exception ex) { - // some mods (such as buildcraft) may throw exceptions when calling - // getDisplayName on a item stack that doesn't contain valid NBT data - } - - String message = "<" + key + ">" + displayName; - MineTweakerAPI.logger.logCommand(message); - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("liquids")) { - for (Map.Entry entry : FluidRegistry.getRegisteredFluids().entrySet()) { - String message = " -- " + entry.getValue().getLocalizedName(); - MineTweakerAPI.logger.logCommand(message); - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("inventory")) { - if (icommandsender instanceof EntityPlayer) { - InventoryPlayer inventory = ((EntityPlayer) icommandsender).inventory; - for(int i = 0; i < inventory.getSizeInventory(); i++) { - ItemStack stack = inventory.getStackInSlot(i); - if (stack != null) { - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(stack.getItem().getUnlocalizedName()); - if (stack.getItemDamage() > 0) { - description.append(':').append(stack.getItemDamage()); - } - description.append('>'); - - if (stack.stackSize != 1) { - description.append('*').append(stack.stackSize); - } - - sendChatMessage(icommandsender, getIItemStack(stack).toString()); - } - } - } else { - sendChatMessage(icommandsender, "Inventory command can only be executed by players"); - } - } else if (arguments[0].equals("hand")) { - if (icommandsender instanceof EntityPlayer) { - InventoryPlayer inventory = ((EntityPlayer) icommandsender).inventory; - ItemStack stack = inventory.getCurrentItem(); - if (stack != null) { - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(stack.getItem().getUnlocalizedName()); - if (stack.getItemDamage() > 0) { - description.append(':').append(stack.getItemDamage()); - } - description.append('>'); - - if (stack.stackSize != 1) { - description.append('*').append(stack.stackSize); - } - - sendChatMessage(icommandsender, getIItemStack(stack).toString()); - } - } else { - sendChatMessage(icommandsender, "Hand command can only be executed by players"); - } - } else if (arguments[0].equals("oredict")) { - if (arguments.length > 2) { - String entryName = arguments[2]; - IOreDictEntry entry = getOreDict(entryName); - if (entry.isEmpty()) { - sendChatMessage(icommandsender, "Entry doesn't exist"); - return; - } else { - MineTweakerAPI.logger.logCommand("Ore entries for " + entryName + ":"); - for (IItemStack ore : entry.getItems()) { - MineTweakerAPI.logger.logCommand(" " + ore); - } - } - } else { - for (String entryName : OreDictionary.getOreNames()) { - MineTweakerAPI.logger.logCommand("Ore entries for " + entryName + ":"); - IOreDictEntry entry = getOreDict(entryName); - if (!entry.isEmpty()) { - for (IItemStack ore : entry.getItems()) { - MineTweakerAPI.logger.logCommand(" " + ore); - } - } - } - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("mods")) { - List mods = Loader.instance().getActiveModList(); - MineTweakerAPI.logger.logCommand("Mods list:"); - for (ModContainer mod : mods) { - sendChatMessage(icommandsender, mod.getModId()); - MineTweakerAPI.logger.logCommand("Mod: " + mod.getModId()); - } - } else if (arguments[0].equals("name")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "missing id parameter"); - } else { - try { - int id = Integer.parseInt(arguments[1]); - if (id < 0 || id >= Item.itemsList.length || Item.itemsList[id] == null) { - sendChatMessage(icommandsender, "invalid id"); - } else { - Item item = Item.itemsList[id]; - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(item.getUnlocalizedName()); - description.append('>'); - sendChatMessage(icommandsender, description.toString()); - } - } catch (NumberFormatException e) { - MineTweakerAPI.logger.logCommand("ID must be an integer"); - } - } - } - - /*if (arguments[0].equals("name")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - } else { - try { - ITweakerItem item = TweakerItem.parse(arguments[1]); - sendChatMessage(icommandsender, "Name for " + item.toIdString() + ": " + MineTweakerUtil.formatItemName(item.getName())); - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, ex.getMessage()); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, ex.getExplanation()); - } - } - } else if (arguments[0].equals("liquid")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide a liquid container item id"); - } else { - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - //#ifdef MC152 - //+if (LiquidContainerRegistry.isLiquid(item.make(1))) { - //+sendChatMessage(icommandsender, "Liquid name: " + item.getName()); - //+} else if (LiquidContainerRegistry.isFilledContainer(item.make(1))) { - //+sendChatMessage(icommandsender, "Liquid name: " + LiquidContainerRegistry.getLiquidForFilledItem(item.make(1)).asItemStack().getItemName()); - //+} else { - //+sendChatMessage(icommandsender, "This item is not a liquid or liquid container"); - //+} - //#else - if (item.getItemId() == 9) { - sendChatMessage(icommandsender, "Liquid name: fluid.tile.water"); - } else if (item.getItemId() == 11) { - sendChatMessage(icommandsender, "Liquid name: fluid.tile.lava"); - } else if (Block.blocksList[item.getItemId()] != null && Block.blocksList[item.getItemId()] instanceof IFluidBlock) { - sendChatMessage(icommandsender, "Liquid name: " + ((IFluidBlock)(Block.blocksList[item.getItemId()])).getFluid().getUnlocalizedName()); - } else if (FluidContainerRegistry.isFilledContainer(item.make(1))) { - sendChatMessage(icommandsender, "Liquid name: " + FluidContainerRegistry.getFluidForFilledItem(item.make(1)).getFluid().getUnlocalizedName()); - } else { - sendChatMessage(icommandsender, "This item is not a liquid or liquid container"); - } - //#endif - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, ex.getMessage()); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, ex.getExplanation()); - } - } - } else if (arguments[0].equals("oredict")) { - if (arguments.length == 1) { - String[] names = OreDictionary.getOreNames(); - Arrays.sort(names); - for (String name : names) { - sendChatMessage(icommandsender, "[" + name + "]"); - ArrayList entries = OreDictionary.getOres(name); - for (ItemStack stack : entries) { - //#ifdef MC152 - //+sendChatMessage(icommandsender, - //+" " + MineTweakerUtil.getItemString(stack) + " - " + - //+MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getItemName())); - //#else - sendChatMessage(icommandsender, - " " + MineTweakerUtil.getItemString(stack) + " - " + - MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getUnlocalizedName())); - //#endif - } - } - } else { - try { - if (Character.isDigit(arguments[1].charAt(0))) { - TweakerItemPattern item = TweakerItem.parse(arguments[1]).asItemPattern(); - for (String name : OreDictionary.getOreNames()) { - for (ItemStack stack : OreDictionary.getOres(name)) { - if (item.matches(stack)) { - sendChatMessage(icommandsender, " " + name); - break; - } - } - } - } else { - for (ItemStack stack : OreDictionary.getOres(arguments[1])) { - //#ifdef MC152 - //+sendChatMessage(icommandsender, - //+" " + MineTweakerUtil.getItemString(stack) + " - " + - //+MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getItemName())); - //#else - sendChatMessage(icommandsender, - " " + MineTweakerUtil.getItemString(stack) + " - " + - MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getUnlocalizedName())); - //#endif - } - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id or ore dictionary entry"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id or ore dictionary entry"); - } - } - } else if (arguments[0].equals("recipes")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - return; - } - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - sendChatMessage(icommandsender, "Recipes for item " + item.toIdString()); - - TweakerItemPattern pattern = item.asItemPattern(); - - @SuppressWarnings("unchecked") - List recipes = CraftingManager.getInstance().getRecipeList(); - - for (IRecipe recipe : recipes) { - if (pattern.matches(recipe.getRecipeOutput())) { - sendChatMessage(icommandsender, " " + MineTweakerUtil.getRecipeString(recipe)); - } - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } - } else if (arguments[0].equals("fuel")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - return; - } - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - ItemStack stack = item.make(1); - int value = TileEntityFurnace.getItemBurnTime(stack); - int regValue = GameRegistry.getFuelValue(stack); - - sendChatMessage(icommandsender, "Fuel for " + item.toIdString() + " = " + value); - if (value != regValue) { - sendChatMessage(icommandsender, "The value is hardcoded and cannot be altered."); - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } - } else if (arguments[0].equals("reload")) { - if (!MineTweaker.instance.canRollback()) { - sendChatMessage(icommandsender, "Previous server script contained permanent actions, cannot reload. A restart is required to reload scripts."); - } else { - MineTweaker.instance.reloadScripts(); - sendChatMessage(icommandsender, "Script reloaded, updating all players"); - } - } else if (arguments[0].equals("logdamage=on")) { - DamageTweaker.logDamage = true; - sendChatMessage(icommandsender, "Damage logging turned on"); - sendChatMessage(icommandsender, "Info: logging is sent to the development console"); - } else if (arguments[0].equals("logdamage=off")) { - DamageTweaker.logDamage = false; - sendChatMessage(icommandsender, "Damage logging turned off"); - } else { - sendChatMessage(icommandsender, "Unrecognized minetweaker command"); - }*/ - - //MineCraftCompat.sendChatMessage(icommandsender, "[" + Arrays2.join(arguments, ", ") + "]"); - } - - @Override - public boolean canCommandSenderUseCommand(ICommandSender icommandsender) { - return true; - } - - @Override - public List addTabCompletionOptions(ICommandSender icommandsender, - String[] astring) { - return null; - } - - @Override - public boolean isUsernameIndex(String[] astring, int i) { - return false; - } -} diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerLogger.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerLogger.java deleted file mode 100644 index dc0b34b..0000000 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerLogger.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package minetweaker.mc164; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.List; -import minetweaker.runtime.ILogger; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.ChatMessageComponent; - -/** - * - * @author Stan - */ -public class MineTweakerLogger implements ILogger { - private Writer writer; - private final List unreportedErrors; - private final List players; - - public MineTweakerLogger() { - File logFile = new File("minetweaker.log"); - if (logFile.exists()) logFile.delete(); - - unreportedErrors = new ArrayList(); - players = new ArrayList(); - - try { - writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(logFile))); - } catch (IOException ex) { - - } - } - - public void clear() { - unreportedErrors.clear(); - } - - public void addPlayer(EntityPlayer player) { - players.add(player); - - if (!unreportedErrors.isEmpty()) { - for (String error : unreportedErrors) { - player.sendChatToPlayer(ChatMessageComponent.createFromText(error)); - } - - unreportedErrors.clear(); - } - } - - public void removePlayer(EntityPlayer player) { - players.remove(player); - } - - @Override - public void logCommand(String message) { - try { - writer.append("COMMAND: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("COMMAND: " + message); - } - - @Override - public void logInfo(String message) { - try { - writer.append("INFO: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("INFO: " + message); - } - - @Override - public void logWarning(String message) { - report("WARNING: " + message); - } - - @Override - public void logError(String message) { - report("ERROR: " + message); - } - - private void report(String message) { - try { - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println(message); - - if (players.isEmpty()) { - unreportedErrors.add(message); - } else { - ChatMessageComponent text = ChatMessageComponent.createFromText(message); - for (EntityPlayer player : players) { - player.sendChatToPlayer(text); - } - } - } -} diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerMod.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerMod.java index 23a0540..f252b00 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerMod.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/MineTweakerMod.java @@ -13,28 +13,35 @@ import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerAboutToStartEvent; import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStoppedEvent; +import cpw.mods.fml.common.network.NetworkMod; import cpw.mods.fml.common.network.NetworkRegistry; -import cpw.mods.fml.common.network.PacketDispatcher; +import cpw.mods.fml.common.network.Player; +import cpw.mods.fml.common.registry.GameRegistry; import java.io.File; import java.util.HashMap; import java.util.Map; import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.event.PlayerLoggedInEvent; +import minetweaker.api.event.PlayerLoggedOutEvent; +import minetweaker.api.logger.FileLogger; +import minetweaker.api.minecraft.MineTweakerMC; import minetweaker.mc164.furnace.FuelTweaker; import minetweaker.mc164.furnace.MCFurnaceManager; +import minetweaker.mc164.game.MCGame; import minetweaker.mc164.mods.MCLoadedMods; import minetweaker.mc164.network.MCConnectionHandler; import minetweaker.mc164.network.MCPacketHandler; import minetweaker.mc164.oredict.MCOreDict; import minetweaker.mc164.recipes.MCRecipeManager; +import minetweaker.mc164.server.MCServer; import minetweaker.mc164.util.MineTweakerHacks; import minetweaker.runtime.IScriptProvider; import minetweaker.runtime.providers.ScriptProviderCascade; import minetweaker.runtime.providers.ScriptProviderDirectory; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.network.INetworkManager; -import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.NetHandler; import net.minecraft.network.packet.Packet250CustomPayload; -import net.minecraft.server.MinecraftServer; /** * Main mod class. Performs some general logic, initialization of the API and @@ -43,6 +50,7 @@ import net.minecraft.server.MinecraftServer; * @author Stan Hebben */ @Mod(modid = MineTweakerMod.MODID, version = MineTweakerMod.MCVERSION + "-3.0.0") +@NetworkMod(clientSideRequired = true, serverSideRequired = true, channels = {MCPacketHandler.CHANNEL_SERVERSCRIPT, MCPacketHandler.CHANNEL_OPENBROWSER}, packetHandler = MCPacketHandler.class) public class MineTweakerMod { public static final String MODID = "MineTweaker3"; public static final String MCVERSION = "1.6.4"; @@ -55,20 +63,20 @@ public class MineTweakerMod { @Mod.Instance(MODID) public static MineTweakerMod INSTANCE; - private final MineTweakerLogger logger; + public final MCRecipeManager recipes; private final IScriptProvider scriptsGlobal; - private final Map onlinePlayers; - - private boolean iAmServer = false; + private final Map networkByUser = new HashMap(); + private final Map userByNetwork = new HashMap(); public MineTweakerMod() { MineTweakerAPI.oreDict = new MCOreDict(); - MineTweakerAPI.recipes = new MCRecipeManager(); - MineTweakerAPI.logger = logger = new MineTweakerLogger(); + MineTweakerAPI.recipes = recipes = new MCRecipeManager(); + MineTweakerImplementationAPI.logger.addLogger(new FileLogger(new File("minetweaker.log"))); + MineTweakerAPI.game = MCGame.INSTANCE; MineTweakerAPI.furnace = new MCFurnaceManager(); MineTweakerAPI.loadedMods = new MCLoadedMods(); - MineTweakerAPI.platform = MCPlatformFunctions.INSTANCE; + MineTweakerImplementationAPI.platform = MCPlatformFunctions.INSTANCE; File globalDir = new File("scripts"); if (!globalDir.exists()) { @@ -77,44 +85,34 @@ public class MineTweakerMod { scriptsGlobal = new ScriptProviderDirectory(globalDir); MineTweakerAPI.tweaker.setScriptProvider(scriptsGlobal); - - onlinePlayers = new HashMap(); } - public boolean iAmServer() { - return iAmServer; + public void onPlayerLogin(Player player, NetHandler netHandler, INetworkManager manager) { + networkByUser.put(netHandler.getPlayer().username, manager); + userByNetwork.put(manager, netHandler); + + MineTweakerImplementationAPI.events.publishPlayerLoggedIn(new PlayerLoggedInEvent(MineTweakerMC.getIPlayer(netHandler.getPlayer()))); } - /** - * Reloads all scripts. - */ - public void reload() { - MineTweakerAPI.tweaker.rollback(); - MineTweakerAPI.tweaker.load(); - - if (iAmServer) { - // execute script on all connected clients - Packet packet = new Packet250CustomPayload( - MCPacketHandler.CHANNEL_SERVERSCRIPT, - MineTweakerAPI.tweaker.getScriptData()); - PacketDispatcher.sendPacketToAllPlayers(packet); + public void onPlayerLogout(INetworkManager manager) { + // TODO: there appear to be some problems here + NetHandler netHandler = userByNetwork.get(manager); + if (netHandler != null && netHandler.getPlayer() != null) { + String name = netHandler.getPlayer().username; + networkByUser.remove(name); + userByNetwork.remove(manager); + MineTweakerImplementationAPI.events.publishPlayerLoggedOut(new PlayerLoggedOutEvent(MineTweakerMC.getIPlayer(netHandler.getPlayer()))); } } - public void onPlayerLoggedIn(INetworkManager networkManager, EntityPlayer player) { - onlinePlayers.put(networkManager, player); - if (iAmServer || MinecraftServer.getServer().getConfigurationManager().getOps().contains(player.getCommandSenderName())) { - System.out.println("Op logged in"); - - logger.addPlayer(player); + public void openBrowser(String user, String url) { + if (networkByUser.containsKey(user)) { + networkByUser.get(user).addToSendQueue(new Packet250CustomPayload( + MCPacketHandler.CHANNEL_OPENBROWSER, + MCPacketHandler.UTF8.encode(url).array())); } } - public void onPlayerLoggedOut(INetworkManager networkManager) { - logger.removePlayer(onlinePlayers.get(networkManager)); - onlinePlayers.remove(networkManager); - } - // ########################## // ### FML Event Handlers ### // ########################## @@ -134,6 +132,7 @@ public class MineTweakerMod { FuelTweaker.INSTANCE.register(); NetworkRegistry.instance().registerConnectionHandler(new MCConnectionHandler()); + GameRegistry.registerCraftingHandler(new MTCraftingHandler()); } @EventHandler @@ -146,21 +145,25 @@ public class MineTweakerMod { scriptsDir.mkdir(); } - iAmServer = true; + MineTweakerAPI.server = new MCServer(ev.getServer()); IScriptProvider scriptsLocal = new ScriptProviderDirectory(scriptsDir); IScriptProvider cascaded = new ScriptProviderCascade(scriptsGlobal, scriptsLocal); MineTweakerAPI.tweaker.setScriptProvider(cascaded); - reload(); + + MineTweakerImplementationAPI.onServerStart(); } @EventHandler public void onServerStarting(FMLServerStartingEvent ev) { - ev.registerServerCommand(new MineTweakerCommand()); + } @EventHandler public void onServerStopped(FMLServerStoppedEvent ev) { - iAmServer = false; + System.out.println("[MineTweaker] Server stopped"); + + MineTweakerAPI.server = null; + MineTweakerImplementationAPI.onServerStop(); } } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java index 857e432..66f51e7 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/brackets/ItemBracketHandler.java @@ -115,8 +115,21 @@ public class ItemBracketHandler implements IBracketHandler { } private IZenSymbol find(List tokens, int startIndex, int endIndex, int meta) { - if (tokens.size() == 1 && tokens.get(0).getType() == ZenTokener.T_INTVALUE) { - int id = Integer.parseInt(tokens.get(0).getValue()); + /*StringBuilder test = new StringBuilder(); + for (int i = startIndex; i < endIndex; i++) { + Token token = tokens.get(i); + if (i > startIndex) { + test.append(' '); + } + test.append(token.getValue()); + test.append(" ("); + test.append(token.getType()); + test.append(")"); + } + System.out.println("Find " + test);*/ + + if (endIndex == startIndex + 1 && tokens.get(startIndex).getType() == ZenTokener.T_INTVALUE) { + int id = Integer.parseInt(tokens.get(startIndex).getValue()); if (id < 0 || id > Item.itemsList.length || Item.itemsList[id] == null) { return null; } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/FuelTweaker.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/FuelTweaker.java index 45e6f5b..cdf4caa 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/FuelTweaker.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/FuelTweaker.java @@ -47,7 +47,7 @@ public class FuelTweaker { public void addFuelPattern(SetFuelPattern pattern) { List items = pattern.getPattern().getItems(); if (items == null) { - MineTweakerAPI.logger.logError("Cannot set fuel for <*>"); + MineTweakerAPI.getLogger().logError("Cannot set fuel for <*>"); return; } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/MCFurnaceManager.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/MCFurnaceManager.java index 34e201d..61837df 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/MCFurnaceManager.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/furnace/MCFurnaceManager.java @@ -60,7 +60,7 @@ public class MCFurnaceManager implements IFurnaceManager { } if (toRemove.isEmpty() && toRemoveMeta.isEmpty()) { - MineTweakerAPI.logger.logWarning("No furnace recipes for " + output.toString()); + MineTweakerAPI.getLogger().logWarning("No furnace recipes for " + output.toString()); } else { MineTweakerAPI.tweaker.apply(new RemoveAction(toRemove, toRemoveValues, toRemoveMeta, toRemoveMetaValues)); } @@ -70,7 +70,7 @@ public class MCFurnaceManager implements IFurnaceManager { public void addRecipe(IItemStack output, IIngredient input, double xp) { List items = input.getItems(); if (items == null) { - MineTweakerAPI.logger.logError("Cannot turn " + input.toString() + " into a furnace recipe"); + MineTweakerAPI.getLogger().logError("Cannot turn " + input.toString() + " into a furnace recipe"); } ItemStack[] items2 = getItemStacks(items); diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/game/MCGame.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/game/MCGame.java new file mode 100644 index 0000000..28f0eec --- /dev/null +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/game/MCGame.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc164.game; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import minetweaker.api.game.IGame; +import minetweaker.api.item.IItemDefinition; +import minetweaker.api.liquid.ILiquidDefinition; +import minetweaker.mc164.item.MCItemDefinition; +import minetweaker.mc164.liquid.MCLiquidDefinition; +import net.minecraft.item.Item; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +/** + * + * @author Stan + */ +public class MCGame implements IGame { + public static final MCGame INSTANCE = new MCGame(); + + private MCGame() {} + + @Override + public List getItems() { + List result = new ArrayList(); + for (Item item : Item.itemsList) { + if (item == null) continue; + result.add(new MCItemDefinition(item)); + } + return result; + } + + @Override + public List getLiquids() { + List result = new ArrayList(); + for (Map.Entry entry : FluidRegistry.getRegisteredFluids().entrySet()) { + result.add(new MCLiquidDefinition(entry.getValue())); + } + return result; + } +} diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemDefinition.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemDefinition.java index aefc51a..cfeff85 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemDefinition.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemDefinition.java @@ -7,7 +7,10 @@ package minetweaker.mc164.item; import minetweaker.api.item.IItemDefinition; +import minetweaker.api.item.IItemStack; +import minetweaker.api.minecraft.MineTweakerMC; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; /** * @@ -19,4 +22,19 @@ public class MCItemDefinition implements IItemDefinition { public MCItemDefinition(Item item) { this.item = item; } + + @Override + public String getId() { + return item.getUnlocalizedName(); + } + + @Override + public String getName() { + return item.getUnlocalizedName(); + } + + @Override + public IItemStack makeStack(int meta) { + return MineTweakerMC.getIItemStackWildcardSize(new ItemStack(item, 1, meta)); + } } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemStack.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemStack.java index f7cdfa2..fa3b58b 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemStack.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/item/MCItemStack.java @@ -111,7 +111,7 @@ public class MCItemStack implements IItemStack { @Override public IIngredient anyDamage() { if (stack.getItem().getHasSubtypes()) { - MineTweakerAPI.logger.logWarning("subitems don't have damaged states"); + MineTweakerAPI.getLogger().logWarning("subitems don't have damaged states"); return this; } else { ItemStack result = new ItemStack(stack.getItem(), stack.stackSize, OreDictionary.WILDCARD_VALUE); @@ -123,7 +123,7 @@ public class MCItemStack implements IItemStack { @Override public IItemStack withDamage(int damage) { if (stack.getItem().getHasSubtypes()) { - MineTweakerAPI.logger.logWarning("subitems don't have damaged states"); + MineTweakerAPI.getLogger().logWarning("subitems don't have damaged states"); return this; } else { ItemStack result = new ItemStack(stack.getItem(), stack.stackSize, damage); @@ -235,6 +235,11 @@ public class MCItemStack implements IItemStack { return item; } + @Override + public boolean hasTransformers() { + return false; + } + @Override public Object getInternal() { return stack; diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCConnectionHandler.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCConnectionHandler.java index 697509f..a0439e0 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCConnectionHandler.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCConnectionHandler.java @@ -23,10 +23,14 @@ public class MCConnectionHandler implements IConnectionHandler { INetworkManager manager) { System.out.println("Player logged in: " + netHandler.getPlayer().username); + byte[] scriptData = MineTweakerAPI.tweaker.getScriptData(); + System.out.println("Sending script data: " + scriptData.length + " bytes"); + manager.addToSendQueue(new Packet250CustomPayload( MCPacketHandler.CHANNEL_SERVERSCRIPT, MineTweakerAPI.tweaker.getScriptData())); - MineTweakerMod.INSTANCE.onPlayerLoggedIn(manager, netHandler.getPlayer()); + + MineTweakerMod.INSTANCE.onPlayerLogin(player, netHandler, manager); } @Override @@ -47,7 +51,7 @@ public class MCConnectionHandler implements IConnectionHandler { @Override public void connectionClosed(INetworkManager manager) { - MineTweakerMod.INSTANCE.onPlayerLoggedOut(manager); + MineTweakerMod.INSTANCE.onPlayerLogout(manager); } @Override diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCPacketHandler.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCPacketHandler.java index cb7f0db..907ca21 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCPacketHandler.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/network/MCPacketHandler.java @@ -10,11 +10,20 @@ import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet250CustomPayload; import cpw.mods.fml.common.network.IPacketHandler; import cpw.mods.fml.common.network.Player; +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; import minetweaker.MineTweakerAPI; import minetweaker.runtime.providers.ScriptProviderMemory; public class MCPacketHandler implements IPacketHandler { + public static final Charset UTF8 = Charset.forName("utf-8"); + public static final String CHANNEL_SERVERSCRIPT = "MTServerScript"; + public static final String CHANNEL_OPENBROWSER = "MTOpenBrowser"; @Override public void onPacketData(INetworkManager manager, @@ -23,9 +32,21 @@ public class MCPacketHandler implements IPacketHandler { if (packet == null || packet.channel == null || packet.data == null) return; if (packet.channel.equals(CHANNEL_SERVERSCRIPT)) { + System.out.println("Received script data: " + packet.data.length + " bytes"); + MineTweakerAPI.tweaker.setScriptProvider(new ScriptProviderMemory(packet.data)); MineTweakerAPI.tweaker.rollback(); MineTweakerAPI.tweaker.load(); + } else if (packet.channel.equals(CHANNEL_OPENBROWSER)) { + String url = UTF8.decode(ByteBuffer.wrap(packet.data)).toString().trim(); + if(Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI(url)); + } catch (IOException e) { + } catch (URISyntaxException e) { + } + } } } } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDict.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDict.java index 38ee2d2..9bff08d 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDict.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDict.java @@ -6,6 +6,10 @@ package minetweaker.mc164.oredict; +import java.util.ArrayList; +import java.util.List; +import minetweaker.api.minecraft.MineTweakerMC; +import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; import minetweaker.api.oredict.IOreDict; import minetweaker.api.oredict.IOreDictEntry; import net.minecraftforge.oredict.OreDictionary; @@ -17,6 +21,17 @@ import net.minecraftforge.oredict.OreDictionary; public class MCOreDict implements IOreDict { @Override public IOreDictEntry get(String name) { - return new MCOreDictEntry(OreDictionary.getOreID(name)); + return getOreDict(name); + } + + @Override + public List getEntries() { + List entries = new ArrayList(); + for (String key : OreDictionary.getOreNames()) { + if (!OreDictionary.getOres(key).isEmpty()) { + entries.add(MineTweakerMC.getOreDict(key)); + } + } + return entries; } } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDictEntry.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDictEntry.java index 96c80d8..dd0aa17 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDictEntry.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/oredict/MCOreDictEntry.java @@ -16,7 +16,7 @@ import minetweaker.api.item.IItemCondition; import minetweaker.api.item.IItemStack; import minetweaker.api.item.IItemTransformer; import minetweaker.api.item.IngredientStack; -import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; +import static minetweaker.api.minecraft.MineTweakerMC.getIItemStackWildcardSize; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; import minetweaker.api.oredict.IOreDictEntry; import minetweaker.api.oredict.IngredientOreDict; @@ -43,6 +43,11 @@ public class MCOreDictEntry implements IOreDictEntry { // ### IOreDictEntry implementation ### // #################################### + @Override + public String getName() { + return OreDictionary.getOreName(id); + } + @Override public boolean isEmpty() { return OreDictionary.getOres(id).isEmpty(); @@ -52,7 +57,7 @@ public class MCOreDictEntry implements IOreDictEntry { public void add(IItemStack item) { ItemStack stack = getItemStack(item); if (stack == null) { - MineTweakerAPI.logger.logError("not a valid item"); + MineTweakerAPI.getLogger().logError("not a valid item"); } else { MineTweakerAPI.tweaker.apply(new ActionAddItem(id, stack)); } @@ -63,7 +68,7 @@ public class MCOreDictEntry implements IOreDictEntry { if (entry instanceof MCOreDictEntry) { MineTweakerAPI.tweaker.apply(new ActionAddAll(id, ((MCOreDictEntry) entry).id)); } else { - MineTweakerAPI.logger.logError("not a valid entry"); + MineTweakerAPI.getLogger().logError("not a valid entry"); } } @@ -71,7 +76,7 @@ public class MCOreDictEntry implements IOreDictEntry { public void remove(IItemStack item) { ItemStack result = null; for (ItemStack itemStack : OreDictionary.getOres(id)) { - if (item.matches(getIItemStack(itemStack))) { + if (item.matches(getIItemStackWildcardSize(itemStack))) { result = itemStack; break; } @@ -85,7 +90,7 @@ public class MCOreDictEntry implements IOreDictEntry { @Override public boolean contains(IItemStack item) { for (ItemStack itemStack : OreDictionary.getOres(id)) { - if (item.matches(getIItemStack(itemStack))) { + if (getIItemStackWildcardSize(itemStack).matches(item)) { return true; } } @@ -98,7 +103,7 @@ public class MCOreDictEntry implements IOreDictEntry { if (other instanceof MCOreDictEntry) { MineTweakerAPI.tweaker.apply(new ActionMirror(id, ((MCOreDictEntry) other).id)); } else { - MineTweakerAPI.logger.logError("not a valid oredict entry"); + MineTweakerAPI.getLogger().logError("not a valid oredict entry"); } } @@ -116,7 +121,7 @@ public class MCOreDictEntry implements IOreDictEntry { public List getItems() { List result = new ArrayList(); for (ItemStack item : OreDictionary.getOres(id)) { - result.add(getIItemStack(item)); + result.add(getIItemStackWildcardSize(item)); } return result; } @@ -161,6 +166,11 @@ public class MCOreDictEntry implements IOreDictEntry { return item; } + @Override + public boolean hasTransformers() { + return false; + } + @Override public Object getInternal() { return OreDictionary.getOreName(id); diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java index 7f62d50..d82fdb2 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/player/MCPlayer.java @@ -10,8 +10,12 @@ import minetweaker.MineTweakerAPI; import minetweaker.api.chat.IChatMessage; import minetweaker.mc164.data.NBTConverter; import minetweaker.api.data.IData; +import minetweaker.api.item.IItemStack; +import minetweaker.api.minecraft.MineTweakerMC; import minetweaker.api.player.IPlayer; +import minetweaker.mc164.MineTweakerMod; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.ChatMessageComponent; /** @@ -28,6 +32,11 @@ public class MCPlayer implements IPlayer { public EntityPlayer getInternal() { return player; } + + @Override + public String getId() { + return null; + } @Override public String getName() { @@ -46,11 +55,44 @@ public class MCPlayer implements IPlayer { @Override public void sendChat(IChatMessage message) { - Object internal = message; + Object internal = message.getInternal(); if (!(internal instanceof ChatMessageComponent)) { - MineTweakerAPI.logger.logError("not a valid chat message"); + //throw new RuntimeException("Not a valid chat message: " + internal); + MineTweakerAPI.getLogger().logError("not a valid chat message"); return; } player.sendChatToPlayer((ChatMessageComponent) internal); } + + @Override + public int getHotbarSize() { + return 9; + } + + @Override + public IItemStack getHotbarStack(int i) { + return i < 0 || i >= 9 ? null : MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)); + } + + @Override + public int getInventorySize() { + return player.inventory.getSizeInventory(); + } + + @Override + public IItemStack getInventoryStack(int i) { + return MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)); + } + + @Override + public IItemStack getCurrentItem() { + return MineTweakerMC.getIItemStack(player.getCurrentEquippedItem()); + } + + @Override + public void openBrowser(String url) { + if (player instanceof EntityPlayerMP) { + MineTweakerMod.INSTANCE.openBrowser(player.username, url); + } + } } diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCCraftingInventory.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCCraftingInventory.java index e12d29e..7c09486 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCCraftingInventory.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCCraftingInventory.java @@ -16,6 +16,7 @@ import minetweaker.api.recipes.ICraftingInventory; import minetweaker.mc164.player.MCPlayer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; @@ -27,6 +28,7 @@ import net.minecraft.item.ItemStack; */ public class MCCraftingInventory implements ICraftingInventory { private static final ThreadLocal cache = new ThreadLocal(); + private static final ThreadLocal cache2 = new ThreadLocal(); public static MCCraftingInventory get(InventoryCrafting inventory) { if (cache.get() == null || cache.get().inventory != inventory) { @@ -40,13 +42,26 @@ public class MCCraftingInventory implements ICraftingInventory { } } + public static MCCraftingInventory get(IInventory inventory, EntityPlayer player) { + if (cache2.get() == null || cache2.get().inventory != inventory || cache2.get().player != player) { + MCCraftingInventory result = new MCCraftingInventory(inventory, player); + cache2.set(result); + return result; + } else { + MCCraftingInventory result = cache2.get(); + result.update(); + return result; + } + } + private int width; private int height; - private final InventoryCrafting inventory; + private final IInventory inventory; private IItemStack[] stacks; private ItemStack[] original; private int stackCount; - private MCPlayer player; + private final IPlayer player; + private final EntityPlayer playerOrig; private MCCraftingInventory(InventoryCrafting inventory) { this.inventory = inventory; @@ -60,13 +75,26 @@ public class MCCraftingInventory implements ICraftingInventory { List slots = container.inventorySlots; if (!slots.isEmpty() && slots.get(0) instanceof SlotCrafting) { SlotCrafting slotCrafting = (SlotCrafting) slots.get(0); - EntityPlayer playerEntity = MineTweakerHacks.getCraftingSlotPlayer(slotCrafting); - player = new MCPlayer(playerEntity); + playerOrig = MineTweakerHacks.getCraftingSlotPlayer(slotCrafting); + player = new MCPlayer(playerOrig); } else { + playerOrig = null; player = null; } } + public MCCraftingInventory(IInventory inventory, EntityPlayer player) { + this.inventory = inventory; + width = height = (int) Math.sqrt(inventory.getSizeInventory()); + stacks = new IItemStack[width * height]; + original = new ItemStack[stacks.length]; + stackCount = 0; + update(); + + playerOrig = player; + this.player = player == null ? null : new MCPlayer(player); + } + private void update() { if (inventory.getSizeInventory() != original.length) { width = height = (int) Math.sqrt(inventory.getSizeInventory()); diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java index 3b6391e..02d35b5 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/recipes/MCRecipeManager.java @@ -12,6 +12,8 @@ import minetweaker.api.item.IItemStack; import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; +import minetweaker.api.recipes.ICraftingInventory; +import minetweaker.api.recipes.ICraftingRecipe; import minetweaker.api.recipes.IRecipeFunction; import minetweaker.api.recipes.IRecipeManager; import net.minecraft.entity.player.EntityPlayer; @@ -31,9 +33,24 @@ import net.minecraftforge.oredict.ShapelessOreRecipe; */ public class MCRecipeManager implements IRecipeManager { private final List recipes; + private final List transformerRecipes; public MCRecipeManager() { recipes = (List) CraftingManager.getInstance().getRecipeList(); + transformerRecipes = new ArrayList(); + } + + public boolean hasTransformerRecipes() { + return transformerRecipes.size() > 0; + } + + public void applyTransformations(ICraftingInventory inventory) { + for (ICraftingRecipe recipe : transformerRecipes) { + if (recipe.matches(inventory)) { + recipe.applyTransformers(inventory); + return; + } + } } @Override @@ -66,14 +83,14 @@ public class MCRecipeManager implements IRecipeManager { public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe)); + MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe, recipe)); } @Override public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function) { ShapelessRecipe recipe = new ShapelessRecipe(output, ingredients, function); IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe)); + MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe, recipe)); } @Override @@ -305,14 +322,19 @@ public class MCRecipeManager implements IRecipeManager { private class ActionAddRecipe implements IUndoableAction { private final IRecipe recipe; + private final ICraftingRecipe craftingRecipe; - public ActionAddRecipe(IRecipe recipe) { + public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe) { this.recipe = recipe; + this.craftingRecipe = craftingRecipe; } @Override public void apply() { recipes.add(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.add(craftingRecipe); + } } @Override @@ -323,6 +345,9 @@ public class MCRecipeManager implements IRecipeManager { @Override public void undo() { recipes.remove(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.remove(craftingRecipe); + } } @Override diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/server/MCServer.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/server/MCServer.java new file mode 100644 index 0000000..4af985f --- /dev/null +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/server/MCServer.java @@ -0,0 +1,226 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc164.server; + +import java.util.Arrays; +import java.util.List; +import minetweaker.IUndoableAction; +import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.minecraft.MineTweakerMC; +import minetweaker.api.player.IPlayer; +import minetweaker.api.server.ICommandFunction; +import minetweaker.api.server.ICommandTabCompletion; +import minetweaker.api.server.ICommandValidator; +import minetweaker.api.server.IServer; +import net.minecraft.command.CommandHandler; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; + +/** + * + * @author Stan + */ +public class MCServer implements IServer { + private final MinecraftServer server; + + public MCServer(MinecraftServer server) { + this.server = server; + } + + @Override + public void addCommand(String name, String usage, String[] aliases, ICommandFunction function, ICommandValidator validator, ICommandTabCompletion completion) { + ICommand command = new MCCommand(name, usage, aliases, function, validator, completion); + MineTweakerAPI.tweaker.apply(new AddCommandAction(command)); + } + + @Override + public void removeCommand(String name) { + ICommand command = (ICommand)((CommandHandler) server.getCommandManager()).getCommands().get(name); + if (command == null) { + MineTweakerAPI.getLogger().logWarning("No such command: " + name); + } else { + MineTweakerAPI.tweaker.apply(new RemoveCommandAction(command)); + } + } + + @Override + public void addMineTweakerCommand(String name, String[] usage, ICommandFunction function) { + MineTweakerImplementationAPI.addMineTweakerCommand(name, usage, function); + } + + @Override + public boolean isOp(IPlayer player) { + return MinecraftServer.getServer().getConfigurationManager().getOps().isEmpty() + || MinecraftServer.getServer().getConfigurationManager().getOps().contains(player.getName()); + } + + private static IPlayer getPlayer(ICommandSender commandSender) { + if (commandSender instanceof EntityPlayer) { + return MineTweakerMC.getIPlayer((EntityPlayer) commandSender); + } else { + return null; + } + } + + private static void removeCommand(ICommand command) { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.getCommands().remove(command.getCommandName()); + + if (command.getCommandAliases() != null) { + for (String alias : (List)command.getCommandAliases()) { + ch.getCommands().remove(alias); + } + } + } + + private class MCCommand implements ICommand { + private final String name; + private final String usage; + private final List aliases; + private final ICommandFunction function; + private final ICommandValidator validator; + private final ICommandTabCompletion completion; + + public MCCommand(String name, String usage, String[] aliases, ICommandFunction function, ICommandValidator validator, ICommandTabCompletion completion) { + this.name = name; + this.usage = usage; + this.aliases = Arrays.asList(aliases); + this.function = function; + this.validator = validator; + this.completion = completion; + } + + @Override + public String getCommandName() { + return name; + } + + @Override + public String getCommandUsage(ICommandSender var1) { + return usage; + } + + @Override + public List getCommandAliases() { + return aliases; + } + + @Override + public void processCommand(ICommandSender var1, String[] var2) { + function.execute(var2, getPlayer(var1)); + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender var1) { + if (validator == null) { + return true; + } else { + return validator.canExecute(getPlayer(var1)); + } + } + + @Override + public List addTabCompletionOptions(ICommandSender var1, String[] var2) { + if (completion != null) { + return Arrays.asList(completion.getTabCompletionOptions(var2, getPlayer(var1))); + } else { + return null; + } + } + + @Override + public boolean isUsernameIndex(String[] var1, int var2) { + return false; + } + + @Override + public int compareTo(Object o) { + return 0; + } + } + + private class AddCommandAction implements IUndoableAction { + private final ICommand command; + + public AddCommandAction(ICommand command) { + this.command = command; + } + + @Override + public void apply() { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.registerCommand(command); + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + removeCommand(command); + } + + @Override + public String describe() { + return "Adding command " + command.getCommandName(); + } + + @Override + public String describeUndo() { + return "Removing command " + command.getCommandName(); + } + + @Override + public Object getOverrideKey() { + return null; + } + } + + private class RemoveCommandAction implements IUndoableAction { + private final ICommand command; + + public RemoveCommandAction(ICommand command) { + this.command = command; + } + + @Override + public void apply() { + removeCommand(command); + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.registerCommand(command); + } + + @Override + public String describe() { + return "Adding command " + command.getCommandName(); + } + + @Override + public String describeUndo() { + return "Removing command " + command.getCommandName(); + } + + @Override + public Object getOverrideKey() { + return null; + } + } +} diff --git a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/util/MineTweakerHacks.java b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/util/MineTweakerHacks.java index a2b643d..d37cb5c 100644 --- a/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/util/MineTweakerHacks.java +++ b/MineTweaker3-MC164-Main/src/main/java/minetweaker/mc164/util/MineTweakerHacks.java @@ -64,7 +64,7 @@ public class MineTweakerHacks { try { return (Map>) OREDICTIONARY_ORESTACKS.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("ERROR - could not load ore dictionary stacks!"); + MineTweakerAPI.getLogger().logError("ERROR - could not load ore dictionary stacks!"); return null; } } @@ -73,7 +73,7 @@ public class MineTweakerHacks { try { return (File) MINECRAFTSERVER_ANVILFILE.get(server); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not load anvil file!"); + MineTweakerAPI.getLogger().logError("could not load anvil file!"); return null; } } @@ -93,7 +93,7 @@ public class MineTweakerHacks { try { return SHAPEDORERECIPE_WIDTH.getInt(recipe); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not load anvil file!"); + MineTweakerAPI.getLogger().logError("could not load anvil file!"); return 3; } } @@ -102,7 +102,7 @@ public class MineTweakerHacks { try { return (Container) INVENTORYCRAFTING_EVENTHANDLER.get(inventory); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get inventory eventhandler"); + MineTweakerAPI.getLogger().logError("could not get inventory eventhandler"); return null; } } @@ -111,7 +111,7 @@ public class MineTweakerHacks { try { return (EntityPlayer) SLOTCRAFTING_PLAYER.get(slot); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get inventory eventhandler"); + MineTweakerAPI.getLogger().logError("could not get inventory eventhandler"); return null; } } @@ -121,7 +121,7 @@ public class MineTweakerHacks { Field field = getField(StringTranslate.class, MineTweakerObfuscation.STRINGTRANSLATE_INSTANCE); return (StringTranslate) field.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get string translator"); + MineTweakerAPI.getLogger().logError("could not get string translator"); return null; } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java index db22b01..5c75895 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java @@ -35,7 +35,7 @@ public class MineTweakerMC { public static ItemStack getItemStack(IItemStack item) { Object internal = item.getInternal(); if (internal == null || !(internal instanceof ItemStack)) { - MineTweakerAPI.logger.logError("Not a valid item stack: " + item); + MineTweakerAPI.getLogger().logError("Not a valid item stack: " + item); } return (ItemStack) internal; } @@ -50,7 +50,7 @@ public class MineTweakerMC { public static ItemStack getItemStack(IIngredient ingredient) { List items = ingredient.getItems(); if (items.size() != 1) { - MineTweakerAPI.logger.logError("Not an ingredient with a single item: " + ingredient); + MineTweakerAPI.getLogger().logError("Not an ingredient with a single item: " + ingredient); } return getItemStack(items.get(0)); } @@ -62,9 +62,20 @@ public class MineTweakerMC { * @return minetweaker item stack */ public static IItemStack getIItemStack(ItemStack item) { + if (item == null) return null; return new MCItemStack(item); } + /** + * Constructs an item stack with wildcard size. + * + * @param item minecraft item stack + * @return minetweaker stack + */ + public static IItemStack getIItemStackWildcardSize(ItemStack item) { + return new MCItemStack(item, true); + } + /** * Constructs an item stack with wildcard size. * @@ -131,7 +142,7 @@ public class MineTweakerMC { if (internal != null && internal instanceof ItemStack) { output[i] = (ItemStack) internal; } else { - MineTweakerAPI.logger.logError("Invalid item stack: " + items.get(i)); + MineTweakerAPI.getLogger().logError("Invalid item stack: " + items.get(i)); } } return output; @@ -196,7 +207,7 @@ public class MineTweakerMC { */ public static EntityPlayer getPlayer(IPlayer player) { if (!(player instanceof MCPlayer)) { - MineTweakerAPI.logger.logError("Invalid player: " + player); + MineTweakerAPI.getLogger().logError("Invalid player: " + player); } return ((MCPlayer) player).getInternal(); diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/FMLEventHandler.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/FMLEventHandler.java index 89493f0..774befe 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/FMLEventHandler.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/FMLEventHandler.java @@ -3,7 +3,13 @@ package minetweaker.mc1710; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.event.PlayerCraftedEvent; +import minetweaker.api.event.PlayerLoggedInEvent; +import minetweaker.api.event.PlayerLoggedOutEvent; +import minetweaker.api.minecraft.MineTweakerMC; import minetweaker.mc1710.network.MineTweakerLoadScriptsPacket; +import minetweaker.mc1710.recipes.MCCraftingInventory; import net.minecraft.entity.player.EntityPlayerMP; /** @@ -19,5 +25,26 @@ public class FMLEventHandler { new MineTweakerLoadScriptsPacket(MineTweakerAPI.tweaker.getScriptData()), player); } + + MineTweakerImplementationAPI.events.publishPlayerLoggedIn(new PlayerLoggedInEvent(MineTweakerMC.getIPlayer(ev.player))); + } + + @SubscribeEvent + public void onPlayerItemCrafted(PlayerEvent.ItemCraftedEvent ev) { + if (MineTweakerMod.INSTANCE.recipes.hasTransformerRecipes()) { + MineTweakerMod.INSTANCE.recipes.applyTransformations(MCCraftingInventory.get(ev.craftMatrix, ev.player)); + } + + if (MineTweakerImplementationAPI.events.hasPlayerCrafted()) { + MineTweakerImplementationAPI.events.publishPlayerCrafted(new PlayerCraftedEvent( + MineTweakerMC.getIPlayer(ev.player), + MineTweakerMC.getIItemStack(ev.crafting), + MCCraftingInventory.get(ev.craftMatrix, ev.player))); + } + } + + @SubscribeEvent + public void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent ev) { + MineTweakerImplementationAPI.events.publishPlayerLoggedOut(new PlayerLoggedOutEvent(MineTweakerMC.getIPlayer(ev.player))); } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MCPlatformFunctions.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MCPlatformFunctions.java index a857c76..2a0ed32 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MCPlatformFunctions.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MCPlatformFunctions.java @@ -8,7 +8,12 @@ package minetweaker.mc1710; import minetweaker.IPlatformFunctions; import minetweaker.api.chat.IChatMessage; +import minetweaker.api.item.IItemDefinition; +import static minetweaker.mc1710.MineTweakerMod.NETWORK; import minetweaker.mc1710.chat.MCChatMessage; +import minetweaker.mc1710.item.MCItemDefinition; +import minetweaker.mc1710.network.MineTweakerLoadScriptsPacket; +import net.minecraft.item.Item; /** * @@ -23,4 +28,17 @@ public class MCPlatformFunctions implements IPlatformFunctions { public IChatMessage getMessage(String message) { return new MCChatMessage(message); } + + @Override + public void distributeScripts(byte[] data) { + NETWORK.sendToAll(new MineTweakerLoadScriptsPacket(data)); + } + + @Override + public IItemDefinition getItemDefinition(int id) { + Item item = Item.getItemById(id); + if (item == null) return null; + String sid = Item.itemRegistry.getNameForObject(item); + return new MCItemDefinition(sid, item); + } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerCommand.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerCommand.java deleted file mode 100644 index 3acbec2..0000000 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerCommand.java +++ /dev/null @@ -1,395 +0,0 @@ -package minetweaker.mc1710; - -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.ModContainer; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; -import minetweaker.MineTweakerAPI; -import minetweaker.mc1710.item.MCItemStack; - -import net.minecraft.command.ICommand; -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ChatComponentText; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.oredict.OreDictionary; -import stanhebben.zenscript.util.StringUtil; - -/** - * Implements the /minetweaker command set. - * - * @author Stan Hebben - */ -public class MineTweakerCommand implements ICommand { - // ########################### - // ## Public static methods ## - // ########################### - - public static void sendChatMessage(ICommandSender sender, String message) { - sender.addChatMessage(new ChatComponentText(message)); - } - - private static final List aliases = Arrays.asList("mt"); - - // ####################################### - // ## ICommand interface implementation ## - // ####################################### - - @Override - public int compareTo(Object arg0) { - return 0; - } - - @Override - public String getCommandName() { - return "minetweaker"; - } - - @Override - public String getCommandUsage(ICommandSender icommandsender) { - return StringUtil.join(new String[] { - "", - "minetweaker reload", - " Reloads all scripts", - "minetweaker names", - " Outputs a list of all item names in the game to the minetweaker log", - "minetweaker liquids", - " Outputs a list of all liquid names in the game to the minetweaker log", - "minetweaker inventory", - " Lists all items in your inventory", - "minetweaker hand", - " Outputs the name of the item in your hand", - "minetweaker oredict", - " Outputs all ore dictionary entries in the game to the minetweaker log", - "minetweaker oredict ", - " Outputs all items in the given ore dictionary entry to the minetweaker log", - "minetweaker mods", - " Outputs all active mod IDs in the game", - "minetweaker name ", - " Outputs the name for the given item ID" - }, "\n"); - } - - @Override - public List getCommandAliases() { - return aliases; - } - - @Override - public void processCommand(ICommandSender icommandsender, String[] arguments) { - if (arguments.length == 0) { - sendChatMessage(icommandsender, "Please provide a command. Use /help minetweaker for more info."); - return; - } - - if (arguments[0].equals("reload")) { - MineTweakerMod.INSTANCE.reload(); - - String message = "Scripts have been reloaded"; - sendChatMessage(icommandsender, message); - } else if (arguments[0].equals("names")) { - Set keys = Item.itemRegistry.getKeys(); - String[] sortedKeys = new String[keys.size()]; - int sortedKeyIndex = 0; - for (String key : keys) sortedKeys[sortedKeyIndex++] = key; - Arrays.sort(sortedKeys); - - for (String key : sortedKeys) { - Item item = (Item) Item.itemRegistry.getObject(key); - - String displayName = ""; - - try { - displayName = " -- " + new ItemStack(item, 1, 0).getDisplayName(); - } catch (Exception ex) { - // some mods (such as buildcraft) may throw exceptions when calling - // getDisplayName on a item stack that doesn't contain valid NBT data - } - - String message = "<" + key + ">" + displayName; - MineTweakerAPI.logger.logCommand(message); - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("liquids")) { - for (Map.Entry entry : FluidRegistry.getRegisteredFluids().entrySet()) { - String message = " -- " + entry.getValue().getLocalizedName(); - MineTweakerAPI.logger.logCommand(message); - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("inventory")) { - if (icommandsender instanceof EntityPlayer) { - InventoryPlayer inventory = ((EntityPlayer) icommandsender).inventory; - for(int i = 0; i < inventory.getSizeInventory(); i++) { - ItemStack stack = inventory.getStackInSlot(i); - if (stack != null) { - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(Item.itemRegistry.getNameForObject(stack.getItem())); - if (stack.getItemDamage() > 0) { - description.append(':').append(stack.getItemDamage()); - } - description.append('>'); - - if (stack.stackSize != 1) { - description.append('*').append(stack.stackSize); - } - - sendChatMessage(icommandsender, new MCItemStack(stack).toString()); - } - } - } else { - sendChatMessage(icommandsender, "Inventory command can only be executed by players"); - } - } else if (arguments[0].equals("hand")) { - if (icommandsender instanceof EntityPlayer) { - InventoryPlayer inventory = ((EntityPlayer) icommandsender).inventory; - ItemStack stack = inventory.getCurrentItem(); - if (stack != null) { - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(Item.itemRegistry.getNameForObject(stack.getItem())); - if (stack.getItemDamage() > 0) { - description.append(':').append(stack.getItemDamage()); - } - description.append('>'); - - if (stack.stackSize != 1) { - description.append('*').append(stack.stackSize); - } - - sendChatMessage(icommandsender, new MCItemStack(stack).toString()); - } - } else { - sendChatMessage(icommandsender, "Hand command can only be executed by players"); - } - } else if (arguments[0].equals("oredict")) { - if (arguments.length > 2) { - String entryName = arguments[2]; - List ores = OreDictionary.getOres(entryName); - if (ores.isEmpty()) { - sendChatMessage(icommandsender, "Entry doesn't exist"); - return; - } else { - MineTweakerAPI.logger.logCommand("Ore entries for " + entryName + ":"); - for (ItemStack ore : ores) { - MineTweakerAPI.logger.logCommand(" " + new MCItemStack(ore).toString()); - } - } - } else { - for (String entryName : OreDictionary.getOreNames()) { - MineTweakerAPI.logger.logCommand("Ore entries for " + entryName + ":"); - List ores = OreDictionary.getOres(entryName); - for (ItemStack ore : ores) { - MineTweakerAPI.logger.logCommand(" " + new MCItemStack(ore).toString()); - } - } - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("mods")) { - List mods = Loader.instance().getActiveModList(); - MineTweakerAPI.logger.logCommand("Mods list:"); - for (ModContainer mod : mods) { - sendChatMessage(icommandsender, mod.getModId()); - MineTweakerAPI.logger.logCommand("Mod: " + mod.getModId()); - } - } else if (arguments[0].equals("name")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "missing id parameter"); - } else { - try { - int id = Integer.parseInt(arguments[1]); - Item item = Item.getItemById(id); - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(Item.itemRegistry.getNameForObject(item)); - description.append('>'); - sendChatMessage(icommandsender, description.toString()); - } catch (NumberFormatException e) { - MineTweakerAPI.logger.logCommand("ID must be an integer"); - } - } - } - - /*if (arguments[0].equals("name")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - } else { - try { - ITweakerItem item = TweakerItem.parse(arguments[1]); - sendChatMessage(icommandsender, "Name for " + item.toIdString() + ": " + MineTweakerUtil.formatItemName(item.getName())); - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, ex.getMessage()); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, ex.getExplanation()); - } - } - } else if (arguments[0].equals("liquid")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide a liquid container item id"); - } else { - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - //#ifdef MC152 - //+if (LiquidContainerRegistry.isLiquid(item.make(1))) { - //+sendChatMessage(icommandsender, "Liquid name: " + item.getName()); - //+} else if (LiquidContainerRegistry.isFilledContainer(item.make(1))) { - //+sendChatMessage(icommandsender, "Liquid name: " + LiquidContainerRegistry.getLiquidForFilledItem(item.make(1)).asItemStack().getItemName()); - //+} else { - //+sendChatMessage(icommandsender, "This item is not a liquid or liquid container"); - //+} - //#else - if (item.getItemId() == 9) { - sendChatMessage(icommandsender, "Liquid name: fluid.tile.water"); - } else if (item.getItemId() == 11) { - sendChatMessage(icommandsender, "Liquid name: fluid.tile.lava"); - } else if (Block.blocksList[item.getItemId()] != null && Block.blocksList[item.getItemId()] instanceof IFluidBlock) { - sendChatMessage(icommandsender, "Liquid name: " + ((IFluidBlock)(Block.blocksList[item.getItemId()])).getFluid().getUnlocalizedName()); - } else if (FluidContainerRegistry.isFilledContainer(item.make(1))) { - sendChatMessage(icommandsender, "Liquid name: " + FluidContainerRegistry.getFluidForFilledItem(item.make(1)).getFluid().getUnlocalizedName()); - } else { - sendChatMessage(icommandsender, "This item is not a liquid or liquid container"); - } - //#endif - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, ex.getMessage()); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, ex.getExplanation()); - } - } - } else if (arguments[0].equals("oredict")) { - if (arguments.length == 1) { - String[] names = OreDictionary.getOreNames(); - Arrays.sort(names); - for (String name : names) { - sendChatMessage(icommandsender, "[" + name + "]"); - ArrayList entries = OreDictionary.getOres(name); - for (ItemStack stack : entries) { - //#ifdef MC152 - //+sendChatMessage(icommandsender, - //+" " + MineTweakerUtil.getItemString(stack) + " - " + - //+MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getItemName())); - //#else - sendChatMessage(icommandsender, - " " + MineTweakerUtil.getItemString(stack) + " - " + - MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getUnlocalizedName())); - //#endif - } - } - } else { - try { - if (Character.isDigit(arguments[1].charAt(0))) { - TweakerItemPattern item = TweakerItem.parse(arguments[1]).asItemPattern(); - for (String name : OreDictionary.getOreNames()) { - for (ItemStack stack : OreDictionary.getOres(name)) { - if (item.matches(stack)) { - sendChatMessage(icommandsender, " " + name); - break; - } - } - } - } else { - for (ItemStack stack : OreDictionary.getOres(arguments[1])) { - //#ifdef MC152 - //+sendChatMessage(icommandsender, - //+" " + MineTweakerUtil.getItemString(stack) + " - " + - //+MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getItemName())); - //#else - sendChatMessage(icommandsender, - " " + MineTweakerUtil.getItemString(stack) + " - " + - MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getUnlocalizedName())); - //#endif - } - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id or ore dictionary entry"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id or ore dictionary entry"); - } - } - } else if (arguments[0].equals("recipes")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - return; - } - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - sendChatMessage(icommandsender, "Recipes for item " + item.toIdString()); - - TweakerItemPattern pattern = item.asItemPattern(); - - @SuppressWarnings("unchecked") - List recipes = CraftingManager.getInstance().getRecipeList(); - - for (IRecipe recipe : recipes) { - if (pattern.matches(recipe.getRecipeOutput())) { - sendChatMessage(icommandsender, " " + MineTweakerUtil.getRecipeString(recipe)); - } - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } - } else if (arguments[0].equals("fuel")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - return; - } - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - ItemStack stack = item.make(1); - int value = TileEntityFurnace.getItemBurnTime(stack); - int regValue = GameRegistry.getFuelValue(stack); - - sendChatMessage(icommandsender, "Fuel for " + item.toIdString() + " = " + value); - if (value != regValue) { - sendChatMessage(icommandsender, "The value is hardcoded and cannot be altered."); - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } - } else if (arguments[0].equals("reload")) { - if (!MineTweaker.instance.canRollback()) { - sendChatMessage(icommandsender, "Previous server script contained permanent actions, cannot reload. A restart is required to reload scripts."); - } else { - MineTweaker.instance.reloadScripts(); - sendChatMessage(icommandsender, "Script reloaded, updating all players"); - } - } else if (arguments[0].equals("logdamage=on")) { - DamageTweaker.logDamage = true; - sendChatMessage(icommandsender, "Damage logging turned on"); - sendChatMessage(icommandsender, "Info: logging is sent to the development console"); - } else if (arguments[0].equals("logdamage=off")) { - DamageTweaker.logDamage = false; - sendChatMessage(icommandsender, "Damage logging turned off"); - } else { - sendChatMessage(icommandsender, "Unrecognized minetweaker command"); - }*/ - - //MineCraftCompat.sendChatMessage(icommandsender, "[" + Arrays2.join(arguments, ", ") + "]"); - } - - @Override - public boolean canCommandSenderUseCommand(ICommandSender icommandsender) { - return true; - } - - @Override - public List addTabCompletionOptions(ICommandSender icommandsender, - String[] astring) { - return null; - } - - @Override - public boolean isUsernameIndex(String[] astring, int i) { - return false; - } -} diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerLogger.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerLogger.java deleted file mode 100644 index 8569dc5..0000000 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerLogger.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package minetweaker.mc1710; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import minetweaker.runtime.ILogger; - -/** - * - * @author Stan - */ -public class MineTweakerLogger implements ILogger { - private Writer writer; - - public MineTweakerLogger() { - File logFile = new File("minetweaker.log"); - if (logFile.exists()) logFile.delete(); - - try { - writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(logFile))); - } catch (IOException ex) { - - } - } - - @Override - public void logCommand(String message) { - try { - writer.append("COMMAND: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("COMMAND: " + message); - } - - @Override - public void logInfo(String message) { - try { - writer.append("INFO: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("INFO: " + message); - } - - @Override - public void logWarning(String message) { - try { - writer.append("WARNING: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("WARNING: " + message); - } - - @Override - public void logError(String message) { - try { - writer.append("ERROR: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("ERROR: " + message); - } -} diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerMod.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerMod.java index 5e4fd4b..eda4d67 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerMod.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/MineTweakerMod.java @@ -19,13 +19,19 @@ import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; import java.io.File; import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.logger.FileLogger; import minetweaker.mc1710.furnace.FuelTweaker; import minetweaker.mc1710.furnace.MCFurnaceManager; +import minetweaker.mc1710.game.MCGame; import minetweaker.mc1710.mods.MCLoadedMods; import minetweaker.mc1710.network.MineTweakerLoadScriptsHandler; import minetweaker.mc1710.network.MineTweakerLoadScriptsPacket; +import minetweaker.mc1710.network.MineTweakerOpenBrowserHandler; +import minetweaker.mc1710.network.MineTweakerOpenBrowserPacket; import minetweaker.mc1710.oredict.MCOreDict; import minetweaker.mc1710.recipes.MCRecipeManager; +import minetweaker.mc1710.server.MCServer; import minetweaker.mc1710.util.MineTweakerHacks; import minetweaker.runtime.IScriptProvider; import minetweaker.runtime.providers.ScriptProviderCascade; @@ -52,23 +58,24 @@ public class MineTweakerMod { static { NETWORK.registerMessage(MineTweakerLoadScriptsHandler.class, MineTweakerLoadScriptsPacket.class, 0, Side.CLIENT); + NETWORK.registerMessage(MineTweakerOpenBrowserHandler.class, MineTweakerOpenBrowserPacket.class, 1, Side.CLIENT); } @Mod.Instance(MODID) public static MineTweakerMod INSTANCE; + public final MCRecipeManager recipes; private final IScriptProvider scriptsGlobal; - private boolean iAmServer = false; - public MineTweakerMod() { MineTweakerAPI.oreDict = new MCOreDict(); - MineTweakerAPI.recipes = new MCRecipeManager(); - MineTweakerAPI.logger = new MineTweakerLogger(); + MineTweakerAPI.recipes = recipes = new MCRecipeManager(); + MineTweakerImplementationAPI.logger.addLogger(new FileLogger(new File("minetweaker.log"))); + MineTweakerAPI.game = MCGame.INSTANCE; MineTweakerAPI.furnace = new MCFurnaceManager(); MineTweakerAPI.loadedMods = new MCLoadedMods(); - MineTweakerAPI.platform = MCPlatformFunctions.INSTANCE; + MineTweakerImplementationAPI.platform = MCPlatformFunctions.INSTANCE; File globalDir = new File("scripts"); if (!globalDir.exists()) { @@ -79,23 +86,6 @@ public class MineTweakerMod { MineTweakerAPI.tweaker.setScriptProvider(scriptsGlobal); } - public boolean iAmServer() { - return iAmServer; - } - - /** - * Reloads all scripts. - */ - public void reload() { - MineTweakerAPI.tweaker.rollback(); - MineTweakerAPI.tweaker.load(); - - if (iAmServer) { - // execute script on all connected clients - NETWORK.sendToAll(new MineTweakerLoadScriptsPacket(MineTweakerAPI.tweaker.getScriptData())); - } - } - // ########################## // ### FML Event Handlers ### // ########################## @@ -121,27 +111,32 @@ public class MineTweakerMod { public void onServerAboutToStart(FMLServerAboutToStartEvent ev) { // starts before loading worlds // perfect place to start MineTweaker! + System.out.println("[MineTweaker] Server about to start"); File scriptsDir = new File(MineTweakerHacks.getWorldDirectory(ev.getServer()), "scripts"); if (!scriptsDir.exists()) { scriptsDir.mkdir(); } - iAmServer = true; + MineTweakerAPI.server = new MCServer(ev.getServer()); IScriptProvider scriptsLocal = new ScriptProviderDirectory(scriptsDir); IScriptProvider cascaded = new ScriptProviderCascade(scriptsGlobal, scriptsLocal); MineTweakerAPI.tweaker.setScriptProvider(cascaded); - reload(); + + MineTweakerImplementationAPI.onServerStart(); } @EventHandler public void onServerStarting(FMLServerStartingEvent ev) { - ev.registerServerCommand(new MineTweakerCommand()); + } @EventHandler public void onServerStopped(FMLServerStoppedEvent ev) { - iAmServer = false; + System.out.println("[MineTweaker] Server stopped"); + + MineTweakerAPI.server = null; + MineTweakerImplementationAPI.onServerStop(); } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/FuelTweaker.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/FuelTweaker.java index 813a01f..41a2f12 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/FuelTweaker.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/FuelTweaker.java @@ -47,7 +47,7 @@ public class FuelTweaker { public void addFuelPattern(SetFuelPattern pattern) { List items = pattern.getPattern().getItems(); if (items == null) { - MineTweakerAPI.logger.logError("Cannot set fuel for <*>"); + MineTweakerAPI.getLogger().logError("Cannot set fuel for <*>"); return; } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/MCFurnaceManager.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/MCFurnaceManager.java index b000a07..a1819cf 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/MCFurnaceManager.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/furnace/MCFurnaceManager.java @@ -47,7 +47,7 @@ public class MCFurnaceManager implements IFurnaceManager { } if (toRemove.isEmpty()) { - MineTweakerAPI.logger.logWarning("No furnace recipes for " + output.toString()); + MineTweakerAPI.getLogger().logWarning("No furnace recipes for " + output.toString()); } else { MineTweakerAPI.tweaker.apply(new RemoveAction(toRemove, toRemoveValues)); } @@ -57,7 +57,7 @@ public class MCFurnaceManager implements IFurnaceManager { public void addRecipe(IItemStack output, IIngredient input, double xp) { List items = input.getItems(); if (items == null) { - MineTweakerAPI.logger.logError("Cannot turn " + input.toString() + " into a furnace recipe"); + MineTweakerAPI.getLogger().logError("Cannot turn " + input.toString() + " into a furnace recipe"); } ItemStack[] items2 = getItemStacks(items); diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/game/MCGame.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/game/MCGame.java new file mode 100644 index 0000000..723aceb --- /dev/null +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/game/MCGame.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc1710.game; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import minetweaker.api.game.IGame; +import minetweaker.api.item.IItemDefinition; +import minetweaker.api.liquid.ILiquidDefinition; +import minetweaker.mc1710.item.MCItemDefinition; +import minetweaker.mc1710.liquid.MCLiquidDefinition; +import net.minecraft.item.Item; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +/** + * + * @author Stan + */ +public class MCGame implements IGame { + public static final MCGame INSTANCE = new MCGame(); + + private MCGame() {} + + @Override + public List getItems() { + List result = new ArrayList(); + for (String item : (Set)Item.itemRegistry.getKeys()) { + result.add(new MCItemDefinition(item, (Item) Item.itemRegistry.getObject(item))); + } + return result; + } + + @Override + public List getLiquids() { + List result = new ArrayList(); + for (Map.Entry entry : FluidRegistry.getRegisteredFluids().entrySet()) { + result.add(new MCLiquidDefinition(entry.getValue())); + } + return result; + } +} diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemDefinition.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemDefinition.java index 2631a07..82a8349 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemDefinition.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemDefinition.java @@ -7,16 +7,36 @@ package minetweaker.mc1710.item; import minetweaker.api.item.IItemDefinition; +import minetweaker.api.item.IItemStack; +import minetweaker.api.minecraft.MineTweakerMC; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; /** * * @author Stan */ public class MCItemDefinition implements IItemDefinition { + private final String id; private final Item item; - public MCItemDefinition(Item item) { + public MCItemDefinition(String id, Item item) { + this.id = id; this.item = item; } + + @Override + public String getId() { + return id; + } + + @Override + public String getName() { + return item.getUnlocalizedName(); + } + + @Override + public IItemStack makeStack(int meta) { + return MineTweakerMC.getIItemStackWildcardSize(new ItemStack(item, 1, meta)); + } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java index a59efd8..a4aad7f 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/item/MCItemStack.java @@ -63,7 +63,9 @@ public class MCItemStack implements IItemStack { @Override public IItemDefinition getDefinition() { - return new MCItemDefinition(stack.getItem()); + return new MCItemDefinition( + Item.itemRegistry.getNameForObject(stack.getItem()), + stack.getItem()); } @Override @@ -112,7 +114,7 @@ public class MCItemStack implements IItemStack { @Override public IIngredient anyDamage() { if (stack.getItem().getHasSubtypes()) { - MineTweakerAPI.logger.logWarning("subitems don't have damaged states"); + MineTweakerAPI.getLogger().logWarning("subitems don't have damaged states"); return this; } else { ItemStack result = new ItemStack(stack.getItem(), stack.stackSize, OreDictionary.WILDCARD_VALUE); @@ -124,7 +126,7 @@ public class MCItemStack implements IItemStack { @Override public IItemStack withDamage(int damage) { if (stack.getItem().getHasSubtypes()) { - MineTweakerAPI.logger.logWarning("subitems don't have damaged states"); + MineTweakerAPI.getLogger().logWarning("subitems don't have damaged states"); return this; } else { ItemStack result = new ItemStack(stack.getItem(), stack.stackSize, damage); @@ -232,6 +234,11 @@ public class MCItemStack implements IItemStack { return item; } + @Override + public boolean hasTransformers() { + return false; + } + @Override public Object getInternal() { return stack; diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerLoadScriptsHandler.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerLoadScriptsHandler.java index e0d935d..51410a7 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerLoadScriptsHandler.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerLoadScriptsHandler.java @@ -10,7 +10,7 @@ import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import minetweaker.MineTweakerAPI; -import minetweaker.mc1710.MineTweakerMod; +import minetweaker.MineTweakerImplementationAPI; import minetweaker.runtime.providers.ScriptProviderMemory; /** @@ -20,20 +20,9 @@ import minetweaker.runtime.providers.ScriptProviderMemory; public class MineTweakerLoadScriptsHandler implements IMessageHandler { @Override public IMessage onMessage(MineTweakerLoadScriptsPacket message, MessageContext ctx) { - if (!MineTweakerMod.INSTANCE.iAmServer()) { - /*IScriptProvider scriptProvider = new ScriptProviderMemory(message.getData()); - Iterator scripts = scriptProvider.getScripts(); - while (scripts.hasNext()) { - IScriptIterator myGroup = scripts.next(); - System.out.println("Scripts: " + myGroup.getGroupName()); - - while (myGroup.next()) { - System.out.println("Script name: " + myGroup.getName()); - } - }*/ + if (MineTweakerAPI.server == null) { MineTweakerAPI.tweaker.setScriptProvider(new ScriptProviderMemory(message.getData())); - MineTweakerAPI.tweaker.rollback(); - MineTweakerAPI.tweaker.load(); + MineTweakerImplementationAPI.reload(); } return null; diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerOpenBrowserHandler.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerOpenBrowserHandler.java new file mode 100644 index 0000000..e4a2c47 --- /dev/null +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerOpenBrowserHandler.java @@ -0,0 +1,37 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc1710.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * + * @author Stan + */ +public class MineTweakerOpenBrowserHandler implements IMessageHandler { + @Override + public IMessage onMessage(MineTweakerOpenBrowserPacket message, MessageContext ctx) { + if(Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI(message.getUrl())); + } catch (IOException e) { + } catch (URISyntaxException e) { + } + } else { + System.out.println("Desktop not supported"); + } + + return null; + } +} diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerOpenBrowserPacket.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerOpenBrowserPacket.java new file mode 100644 index 0000000..f777103 --- /dev/null +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/network/MineTweakerOpenBrowserPacket.java @@ -0,0 +1,44 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc1710.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import io.netty.buffer.ByteBuf; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + +/** + * + * @author Stan + */ +public class MineTweakerOpenBrowserPacket implements IMessage { + private static final Charset UTF8 = Charset.forName("utf-8"); + + private String url; + + public MineTweakerOpenBrowserPacket() { + + } + + public MineTweakerOpenBrowserPacket(String url) { + this.url = url; + } + + public String getUrl() { + return url; + } + + @Override + public void fromBytes(ByteBuf buf) { + url = UTF8.decode(ByteBuffer.wrap(buf.array())).toString().trim(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeBytes(UTF8.encode(url).array()); + } +} diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDict.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDict.java index 195e39a..42d2203 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDict.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDict.java @@ -6,6 +6,10 @@ package minetweaker.mc1710.oredict; +import java.util.ArrayList; +import java.util.List; +import minetweaker.api.minecraft.MineTweakerMC; +import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; import minetweaker.api.oredict.IOreDict; import minetweaker.api.oredict.IOreDictEntry; import net.minecraftforge.oredict.OreDictionary; @@ -17,6 +21,17 @@ import net.minecraftforge.oredict.OreDictionary; public class MCOreDict implements IOreDict { @Override public IOreDictEntry get(String name) { - return new MCOreDictEntry(OreDictionary.getOreID(name)); + return getOreDict(name); + } + + @Override + public List getEntries() { + List entries = new ArrayList(); + for (String key : OreDictionary.getOreNames()) { + if (!OreDictionary.getOres(key).isEmpty()) { + entries.add(MineTweakerMC.getOreDict(key)); + } + } + return entries; } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDictEntry.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDictEntry.java index c36b375..d58f9c5 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDictEntry.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/oredict/MCOreDictEntry.java @@ -10,13 +10,13 @@ import java.util.ArrayList; import java.util.List; import minetweaker.IUndoableAction; import minetweaker.MineTweakerAPI; -import minetweaker.mc1710.item.MCItemStack; import minetweaker.mc1710.util.MineTweakerHacks; import minetweaker.api.item.IIngredient; import minetweaker.api.item.IItemCondition; import minetweaker.api.item.IItemStack; import minetweaker.api.item.IItemTransformer; import minetweaker.api.item.IngredientStack; +import static minetweaker.api.minecraft.MineTweakerMC.getIItemStackWildcardSize; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; import minetweaker.api.oredict.IOreDictEntry; import minetweaker.api.oredict.IngredientOreDict; @@ -46,6 +46,11 @@ public class MCOreDictEntry implements IOreDictEntry { // ### IOreDictEntry implementation ### // #################################### + @Override + public String getName() { + return OreDictionary.getOreName(id); + } + @Override public boolean isEmpty() { return OreDictionary.getOres(id).isEmpty(); @@ -64,7 +69,7 @@ public class MCOreDictEntry implements IOreDictEntry { if (entry instanceof MCOreDictEntry) { MineTweakerAPI.tweaker.apply(new ActionAddAll(id, ((MCOreDictEntry) entry).id)); } else { - MineTweakerAPI.logger.logError("not a valid entry"); + MineTweakerAPI.getLogger().logError("not a valid entry"); } } @@ -72,7 +77,7 @@ public class MCOreDictEntry implements IOreDictEntry { public void remove(IItemStack item) { ItemStack result = null; for (ItemStack itemStack : OreDictionary.getOres(id)) { - if (item.matches(new MCItemStack(itemStack))) { + if (item.matches(getIItemStackWildcardSize(itemStack))) { result = itemStack; break; } @@ -86,7 +91,7 @@ public class MCOreDictEntry implements IOreDictEntry { @Override public boolean contains(IItemStack item) { for (ItemStack itemStack : OreDictionary.getOres(id)) { - if (item.matches(new MCItemStack(itemStack))) { + if (getIItemStackWildcardSize(itemStack).matches(item)) { return true; } } @@ -99,7 +104,7 @@ public class MCOreDictEntry implements IOreDictEntry { if (other instanceof MCOreDictEntry) { MineTweakerAPI.tweaker.apply(new ActionMirror(id, ((MCOreDictEntry) other).id)); } else { - MineTweakerAPI.logger.logError("not a valid oredict entry"); + MineTweakerAPI.getLogger().logError("not a valid oredict entry"); } } @@ -117,7 +122,7 @@ public class MCOreDictEntry implements IOreDictEntry { public List getItems() { List result = new ArrayList(); for (ItemStack item : OreDictionary.getOres(id)) { - result.add(new MCItemStack(item)); + result.add(getIItemStackWildcardSize(item)); } return result; } @@ -162,6 +167,11 @@ public class MCOreDictEntry implements IOreDictEntry { return item; } + @Override + public boolean hasTransformers() { + return false; + } + @Override public Object getInternal() { return OreDictionary.getOreName(id); diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java index 9fe545a..26bb4f3 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/player/MCPlayer.java @@ -8,10 +8,15 @@ package minetweaker.mc1710.player; import minetweaker.MineTweakerAPI; import minetweaker.api.chat.IChatMessage; -import minetweaker.mc1710.data.NBTConverter; import minetweaker.api.data.IData; +import minetweaker.api.item.IItemStack; +import minetweaker.api.minecraft.MineTweakerMC; import minetweaker.api.player.IPlayer; +import minetweaker.mc1710.MineTweakerMod; +import minetweaker.mc1710.data.NBTConverter; +import minetweaker.mc1710.network.MineTweakerOpenBrowserPacket; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.IChatComponent; /** @@ -29,6 +34,11 @@ public class MCPlayer implements IPlayer { return player; } + @Override + public String getId() { + return null; // TODO: we should be having this for MC 1.7.10, right? + } + @Override public String getName() { return player.getCommandSenderName(); @@ -48,9 +58,43 @@ public class MCPlayer implements IPlayer { public void sendChat(IChatMessage message) { Object internal = message; if (!(internal instanceof IChatComponent)) { - MineTweakerAPI.logger.logError("not a valid chat message"); + MineTweakerAPI.getLogger().logError("not a valid chat message"); return; } player.addChatMessage((IChatComponent) internal); } + + @Override + public int getHotbarSize() { + return 9; + } + + @Override + public IItemStack getHotbarStack(int i) { + return i < 0 || i >= 9 ? null : MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)); + } + + @Override + public int getInventorySize() { + return player.inventory.getSizeInventory(); + } + + @Override + public IItemStack getInventoryStack(int i) { + return MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)); + } + + @Override + public IItemStack getCurrentItem() { + return MineTweakerMC.getIItemStack(player.getCurrentEquippedItem()); + } + + @Override + public void openBrowser(String url) { + if (player instanceof EntityPlayerMP) { + MineTweakerMod.NETWORK.sendTo( + new MineTweakerOpenBrowserPacket(url), + (EntityPlayerMP) player); + } + } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCCraftingInventory.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCCraftingInventory.java index 140b8ff..432dff1 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCCraftingInventory.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCCraftingInventory.java @@ -10,12 +10,15 @@ import java.util.List; import minetweaker.mc1710.item.MCItemStack; import minetweaker.mc1710.util.MineTweakerHacks; import minetweaker.api.item.IItemStack; +import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; +import static minetweaker.api.minecraft.MineTweakerMC.getIPlayer; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; import minetweaker.api.player.IPlayer; import minetweaker.api.recipes.ICraftingInventory; import minetweaker.mc1710.player.MCPlayer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; @@ -27,6 +30,7 @@ import net.minecraft.item.ItemStack; */ public class MCCraftingInventory implements ICraftingInventory { private static final ThreadLocal cache = new ThreadLocal(); + private static final ThreadLocal cache2 = new ThreadLocal(); public static MCCraftingInventory get(InventoryCrafting inventory) { if (cache.get() == null || cache.get().inventory != inventory) { @@ -40,13 +44,26 @@ public class MCCraftingInventory implements ICraftingInventory { } } + public static MCCraftingInventory get(IInventory inventory, EntityPlayer player) { + if (cache2.get() == null || cache2.get().inventory != inventory || cache2.get().player != player) { + MCCraftingInventory result = new MCCraftingInventory(inventory, player); + cache2.set(result); + return result; + } else { + MCCraftingInventory result = cache2.get(); + result.update(); + return result; + } + } + private int width; private int height; - private final InventoryCrafting inventory; + private final IInventory inventory; private IItemStack[] stacks; private ItemStack[] original; private int stackCount; - private MCPlayer player; + private final IPlayer player; + private final EntityPlayer playerOrig; private MCCraftingInventory(InventoryCrafting inventory) { this.inventory = inventory; @@ -60,13 +77,26 @@ public class MCCraftingInventory implements ICraftingInventory { List slots = container.inventorySlots; if (!slots.isEmpty() && slots.get(0) instanceof SlotCrafting) { SlotCrafting slotCrafting = (SlotCrafting) slots.get(0); - EntityPlayer playerEntity = MineTweakerHacks.getCraftingSlotPlayer(slotCrafting); - player = new MCPlayer(playerEntity); + playerOrig = MineTweakerHacks.getCraftingSlotPlayer(slotCrafting); + player = getIPlayer(playerOrig); } else { + playerOrig = null; player = null; } } + public MCCraftingInventory(IInventory inventory, EntityPlayer player) { + this.inventory = inventory; + width = height = (int) Math.sqrt(inventory.getSizeInventory()); + stacks = new IItemStack[width * height]; + original = new ItemStack[stacks.length]; + stackCount = 0; + update(); + + playerOrig = player; + this.player = player == null ? null : new MCPlayer(player); + } + private void update() { if (inventory.getSizeInventory() != original.length) { width = height = (int) Math.sqrt(inventory.getSizeInventory()); @@ -81,7 +111,7 @@ public class MCCraftingInventory implements ICraftingInventory { original[i] = inventory.getStackInSlot(i); if (inventory.getStackInSlot(i) != null) { if (stacks[i] == null) stackCount++; - stacks[i] = new MCItemStack(original[i]); + stacks[i] = getIItemStack(original[i]); } else { if (stacks[i] != null) stackCount--; stacks[i] = null; diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java index 06a2f7d..7c757ed 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/recipes/MCRecipeManager.java @@ -6,12 +6,14 @@ import java.util.ArrayList; import java.util.List; import minetweaker.IUndoableAction; import minetweaker.MineTweakerAPI; -import minetweaker.mc1710.item.MCItemStack; -import minetweaker.mc1710.oredict.MCOreDictEntry; import minetweaker.mc1710.util.MineTweakerHacks; import minetweaker.api.item.IIngredient; import minetweaker.api.item.IItemStack; +import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; +import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; +import minetweaker.api.recipes.ICraftingInventory; +import minetweaker.api.recipes.ICraftingRecipe; import minetweaker.api.recipes.IRecipeFunction; import minetweaker.api.recipes.IRecipeManager; import net.minecraft.entity.player.EntityPlayer; @@ -31,9 +33,24 @@ import net.minecraftforge.oredict.ShapelessOreRecipe; */ public class MCRecipeManager implements IRecipeManager { private final List recipes; + private final List transformerRecipes; public MCRecipeManager() { recipes = (List) CraftingManager.getInstance().getRecipeList(); + transformerRecipes = new ArrayList(); + } + + public boolean hasTransformerRecipes() { + return transformerRecipes.size() > 0; + } + + public void applyTransformations(ICraftingInventory inventory) { + for (ICraftingRecipe recipe : transformerRecipes) { + if (recipe.matches(inventory)) { + recipe.applyTransformers(inventory); + return; + } + } } @Override @@ -46,7 +63,7 @@ public class MCRecipeManager implements IRecipeManager { // certain special recipes have no predefined output. ignore those // since these cannot be removed with MineTweaker scripts if (recipe.getRecipeOutput() != null) { - if (output.matches(new MCItemStack(recipe.getRecipeOutput()))) { + if (output.matches(getIItemStack(recipe.getRecipeOutput()))) { toRemove.add(recipe); removeIndex.add(i); } @@ -66,14 +83,14 @@ public class MCRecipeManager implements IRecipeManager { public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe)); + MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe, recipe)); } - + @Override public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function) { ShapelessRecipe recipe = new ShapelessRecipe(output, ingredients, function); IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe)); + MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe, recipe)); } @Override @@ -94,7 +111,7 @@ public class MCRecipeManager implements IRecipeManager { outer: for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); - if (recipe.getRecipeOutput() == null || !output.matches(new MCItemStack(recipe.getRecipeOutput()))) { + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { continue; } @@ -160,7 +177,7 @@ public class MCRecipeManager implements IRecipeManager { outer: for (int i = 0; i < recipes.size(); i++) { IRecipe recipe = recipes.get(i); - if (recipe.getRecipeOutput() == null || !output.matches(new MCItemStack(recipe.getRecipeOutput()))) { + if (recipe.getRecipeOutput() == null || !output.matches(getIItemStack(recipe.getRecipeOutput()))) { continue; } @@ -248,7 +265,7 @@ public class MCRecipeManager implements IRecipeManager { if (result == null) { return null; } else { - return new MCItemStack(result); + return getIItemStack(result); } } @@ -305,14 +322,19 @@ public class MCRecipeManager implements IRecipeManager { private class ActionAddRecipe implements IUndoableAction { private final IRecipe recipe; + private final ICraftingRecipe craftingRecipe; - public ActionAddRecipe(IRecipe recipe) { + public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe) { this.recipe = recipe; + this.craftingRecipe = craftingRecipe; } @Override public void apply() { recipes.add(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.add(craftingRecipe); + } } @Override @@ -323,6 +345,9 @@ public class MCRecipeManager implements IRecipeManager { @Override public void undo() { recipes.remove(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.remove(craftingRecipe); + } } @Override @@ -346,11 +371,11 @@ public class MCRecipeManager implements IRecipeManager { return false; } else if (ingredient != null) { if (input instanceof ItemStack) { - if (!ingredient.matches(new MCItemStack((ItemStack) input))) { + if (!ingredient.matches(getIItemStack((ItemStack) input))) { return false; } } else if (input instanceof String) { - if (!ingredient.contains(new MCOreDictEntry((String) input))) { + if (!ingredient.contains(getOreDict((String) input))) { return false; } } diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/server/MCServer.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/server/MCServer.java new file mode 100644 index 0000000..8f49662 --- /dev/null +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/server/MCServer.java @@ -0,0 +1,227 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc1710.server; + +import java.util.Arrays; +import java.util.List; +import minetweaker.IUndoableAction; +import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.minecraft.MineTweakerMC; +import minetweaker.api.player.IPlayer; +import minetweaker.api.server.ICommandFunction; +import minetweaker.api.server.ICommandTabCompletion; +import minetweaker.api.server.ICommandValidator; +import minetweaker.api.server.IServer; +import net.minecraft.command.CommandHandler; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.management.UserListOps; + +/** + * + * @author Stan + */ +public class MCServer implements IServer { + private final MinecraftServer server; + + public MCServer(MinecraftServer server) { + this.server = server; + } + + @Override + public void addCommand(String name, String usage, String[] aliases, ICommandFunction function, ICommandValidator validator, ICommandTabCompletion completion) { + ICommand command = new MCCommand(name, usage, aliases, function, validator, completion); + MineTweakerAPI.tweaker.apply(new AddCommandAction(command)); + } + + @Override + public void removeCommand(String name) { + ICommand command = (ICommand)((CommandHandler) server.getCommandManager()).getCommands().get(name); + if (command == null) { + MineTweakerAPI.getLogger().logWarning("No such command: " + name); + } else { + MineTweakerAPI.tweaker.apply(new RemoveCommandAction(command)); + } + } + + @Override + public void addMineTweakerCommand(String name, String[] usage, ICommandFunction function) { + MineTweakerImplementationAPI.addMineTweakerCommand(name, usage, function); + } + + @Override + public boolean isOp(IPlayer player) { + UserListOps ops = MinecraftServer.getServer().getConfigurationManager().func_152603_m(); + return ops.func_152690_d() || ops.func_152700_a(player.getName()) != null; + } + + private static IPlayer getPlayer(ICommandSender commandSender) { + if (commandSender instanceof EntityPlayer) { + return MineTweakerMC.getIPlayer((EntityPlayer) commandSender); + } else { + return null; + } + } + + private static void removeCommand(ICommand command) { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.getCommands().remove(command.getCommandName()); + + if (command.getCommandAliases() != null) { + for (String alias : (List)command.getCommandAliases()) { + ch.getCommands().remove(alias); + } + } + } + + private class MCCommand implements ICommand { + private final String name; + private final String usage; + private final List aliases; + private final ICommandFunction function; + private final ICommandValidator validator; + private final ICommandTabCompletion completion; + + public MCCommand(String name, String usage, String[] aliases, ICommandFunction function, ICommandValidator validator, ICommandTabCompletion completion) { + this.name = name; + this.usage = usage; + this.aliases = Arrays.asList(aliases); + this.function = function; + this.validator = validator; + this.completion = completion; + } + + @Override + public String getCommandName() { + return name; + } + + @Override + public String getCommandUsage(ICommandSender var1) { + return usage; + } + + @Override + public List getCommandAliases() { + return aliases; + } + + @Override + public void processCommand(ICommandSender var1, String[] var2) { + function.execute(var2, getPlayer(var1)); + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender var1) { + if (validator == null) { + return true; + } else { + return validator.canExecute(getPlayer(var1)); + } + } + + @Override + public List addTabCompletionOptions(ICommandSender var1, String[] var2) { + if (completion != null) { + return Arrays.asList(completion.getTabCompletionOptions(var2, getPlayer(var1))); + } else { + return null; + } + } + + @Override + public boolean isUsernameIndex(String[] var1, int var2) { + return false; + } + + @Override + public int compareTo(Object o) { + return 0; + } + } + + private class AddCommandAction implements IUndoableAction { + private final ICommand command; + + public AddCommandAction(ICommand command) { + this.command = command; + } + + @Override + public void apply() { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.registerCommand(command); + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + removeCommand(command); + } + + @Override + public String describe() { + return "Adding command " + command.getCommandName(); + } + + @Override + public String describeUndo() { + return "Removing command " + command.getCommandName(); + } + + @Override + public Object getOverrideKey() { + return null; + } + } + + private class RemoveCommandAction implements IUndoableAction { + private final ICommand command; + + public RemoveCommandAction(ICommand command) { + this.command = command; + } + + @Override + public void apply() { + removeCommand(command); + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.registerCommand(command); + } + + @Override + public String describe() { + return "Adding command " + command.getCommandName(); + } + + @Override + public String describeUndo() { + return "Removing command " + command.getCommandName(); + } + + @Override + public Object getOverrideKey() { + return null; + } + } +} diff --git a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/util/MineTweakerHacks.java b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/util/MineTweakerHacks.java index 26d6339..6bf2e09 100644 --- a/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/util/MineTweakerHacks.java +++ b/MineTweaker3-MC1710-Main/src/main/java/minetweaker/mc1710/util/MineTweakerHacks.java @@ -67,7 +67,7 @@ public class MineTweakerHacks { try { return (List>) OREDICTIONARY_IDTOSTACK.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("ERROR - could not load ore dictionary stacks!"); + MineTweakerAPI.getLogger().logError("ERROR - could not load ore dictionary stacks!"); return null; } } @@ -76,7 +76,7 @@ public class MineTweakerHacks { try { return (List>) OREDICTIONARY_IDTOSTACKUN.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("ERROR - could not load ore dictionary stacks!"); + MineTweakerAPI.getLogger().logError("ERROR - could not load ore dictionary stacks!"); return null; } } @@ -85,7 +85,7 @@ public class MineTweakerHacks { try { return (File) MINECRAFTSERVER_ANVILFILE.get(server); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not load anvil file!"); + MineTweakerAPI.getLogger().logError("could not load anvil file!"); return null; } } @@ -105,7 +105,7 @@ public class MineTweakerHacks { try { return SHAPEDORERECIPE_WIDTH.getInt(recipe); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not load anvil file!"); + MineTweakerAPI.getLogger().logError("could not load anvil file!"); return 3; } } @@ -114,7 +114,7 @@ public class MineTweakerHacks { try { return (Container) INVENTORYCRAFTING_EVENTHANDLER.get(inventory); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get inventory eventhandler"); + MineTweakerAPI.getLogger().logError("could not get inventory eventhandler"); return null; } } @@ -123,7 +123,7 @@ public class MineTweakerHacks { try { return (EntityPlayer) SLOTCRAFTING_PLAYER.get(slot); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get inventory eventhandler"); + MineTweakerAPI.getLogger().logError("could not get inventory eventhandler"); return null; } } @@ -133,7 +133,7 @@ public class MineTweakerHacks { Field field = getField(StringTranslate.class, MineTweakerObfuscation.STRINGTRANSLATE_INSTANCE); return (StringTranslate) field.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get string translator"); + MineTweakerAPI.getLogger().logError("could not get string translator"); return null; } } diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java index 546cfa1..dd7568a 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java @@ -56,12 +56,12 @@ public class IC2BracketHandler implements IBracketHandler { } else if (tokens.get(6).getValue().equals("*")) { meta = OreDictionary.WILDCARD_VALUE; } else { - MineTweakerAPI.logger.logError("Not a valid meta value: " + tokens.get(6).getValue()); + MineTweakerAPI.getLogger().logError("Not a valid meta value: " + tokens.get(6).getValue()); } } ItemStack item = IC2Items.getItem(name); if (item == null) { - MineTweakerAPI.logger.logError("Not a valid IC2 item: " + name); + MineTweakerAPI.getLogger().logError("Not a valid IC2 item: " + name); return null; } else { return new ItemReferenceSymbol(name, meta); diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java index 679c131..fdf7a76 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java @@ -35,7 +35,7 @@ public class IC2ExplosionWhitelist { ItemStack iStack = getItemStack(item); Block block = Block.getBlockFromItem(iStack.getItem()); if (block == null) { - MineTweakerAPI.logger.logError("This item is not a block"); + MineTweakerAPI.getLogger().logError("This item is not a block"); } else { MineTweakerAPI.tweaker.apply(new AddAction(block)); } @@ -51,10 +51,10 @@ public class IC2ExplosionWhitelist { ItemStack iStack = getItemStack(item); Block block = Block.getBlockFromItem(iStack.getItem()); if (block == null) { - MineTweakerAPI.logger.logError("This item is not a block"); + MineTweakerAPI.getLogger().logError("This item is not a block"); } else { if (ExplosionWhitelist.isBlockWhitelisted(block)) { - MineTweakerAPI.logger.logWarning("This block is not in the whitelist"); + MineTweakerAPI.getLogger().logWarning("This block is not in the whitelist"); } else { MineTweakerAPI.tweaker.apply(new RemoveAction(block)); } @@ -72,7 +72,7 @@ public class IC2ExplosionWhitelist { ItemStack iStack = getItemStack(item); Block block = Block.getBlockFromItem(iStack.getItem()); if (block == null) { - MineTweakerAPI.logger.logWarning("This item is not a block"); + MineTweakerAPI.getLogger().logWarning("This item is not a block"); return false; } else { return ExplosionWhitelist.isBlockWhitelisted(block); diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java index 67f3941..87778d5 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java @@ -31,7 +31,7 @@ public class MachineAddRecipeAction extends OneWayAction { try { machine.addRecipe(input, tag, output); } catch (RuntimeException ex) { - MineTweakerAPI.logger.logError(ex.getMessage()); + MineTweakerAPI.getLogger().logError(ex.getMessage()); } } diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java index c192f43..b5738ef 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java @@ -38,7 +38,7 @@ public class Compressor { @NotNull IItemStack output, @NotNull IIngredient ingredient) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { MineTweakerAPI.tweaker.apply(new MachineAddRecipeAction( "compressor", diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java index f19adf6..94d0b23 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java @@ -43,7 +43,7 @@ public class Extractor { @NotNull IItemStack output, @NotNull IIngredient ingredient) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { MineTweakerAPI.tweaker.apply(new MachineAddRecipeAction( "extractor", diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java index 731384e..b817a2c 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java @@ -38,7 +38,7 @@ public class Macerator { @NotNull IItemStack output, @NotNull IIngredient ingredient) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { MineTweakerAPI.tweaker.apply(new MachineAddRecipeAction( "macerator", diff --git a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java index 3839585..45d94b4 100644 --- a/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java +++ b/MineTweaker3-MC1710-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java @@ -37,7 +37,7 @@ public class ThermalCentrifuge { @ZenMethod public static void addRecipe(IItemStack[] output, IIngredient ingredient, int minHeat) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("minHeat", minHeat); diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java index 210f48c..82609b1 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/api/minecraft/MineTweakerMC.java @@ -35,7 +35,7 @@ public class MineTweakerMC { public static ItemStack getItemStack(IItemStack item) { Object internal = item.getInternal(); if (internal == null || !(internal instanceof ItemStack)) { - MineTweakerAPI.logger.logError("Not a valid item stack: " + item); + MineTweakerAPI.getLogger().logError("Not a valid item stack: " + item); } return (ItemStack) internal; } @@ -50,21 +50,33 @@ public class MineTweakerMC { public static ItemStack getItemStack(IIngredient ingredient) { List items = ingredient.getItems(); if (items.size() != 1) { - MineTweakerAPI.logger.logError("Not an ingredient with a single item: " + ingredient); + MineTweakerAPI.getLogger().logError("Not an ingredient with a single item: " + ingredient); } return getItemStack(items.get(0)); } /** - * Returns the MineTweaker item stack for this item. + * Returns the MineTweaker item stack for this item. Passing null returns + * null. * * @param item minecraft item stack - * @return minetweaker item stack + * @return minetweaker item stack, or null */ public static IItemStack getIItemStack(ItemStack item) { + if (item == null) return null; return new MCItemStack(item); } + /** + * Constructs an item stack with wildcard size. + * + * @param item minecraft item stack + * @return minetweaker stack + */ + public static IItemStack getIItemStackWildcardSize(ItemStack item) { + return new MCItemStack(item, true); + } + /** * Constructs an item stack with wildcard size. * @@ -131,7 +143,7 @@ public class MineTweakerMC { if (internal != null && internal instanceof ItemStack) { output[i] = (ItemStack) internal; } else { - MineTweakerAPI.logger.logError("Invalid item stack: " + items.get(i)); + MineTweakerAPI.getLogger().logError("Invalid item stack: " + items.get(i)); } } return output; @@ -196,7 +208,7 @@ public class MineTweakerMC { */ public static EntityPlayer getPlayer(IPlayer player) { if (!(player instanceof MCPlayer)) { - MineTweakerAPI.logger.logError("Invalid player: " + player); + MineTweakerAPI.getLogger().logError("Invalid player: " + player); } return ((MCPlayer) player).getInternal(); diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/FMLEventHandler.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/FMLEventHandler.java index 4778045..37aa525 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/FMLEventHandler.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/FMLEventHandler.java @@ -3,7 +3,13 @@ package minetweaker.mc172; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.event.PlayerCraftedEvent; +import minetweaker.api.event.PlayerLoggedInEvent; +import minetweaker.api.event.PlayerLoggedOutEvent; +import minetweaker.api.minecraft.MineTweakerMC; import minetweaker.mc172.network.MineTweakerLoadScriptsPacket; +import minetweaker.mc172.recipes.MCCraftingInventory; import net.minecraft.entity.player.EntityPlayerMP; /** @@ -18,12 +24,27 @@ public class FMLEventHandler { MineTweakerMod.NETWORK.sendTo( new MineTweakerLoadScriptsPacket(MineTweakerAPI.tweaker.getScriptData()), player); - MineTweakerMod.INSTANCE.onPlayerLoggedIn(player); + } + + MineTweakerImplementationAPI.events.publishPlayerLoggedIn(new PlayerLoggedInEvent(MineTweakerMC.getIPlayer(ev.player))); + } + + @SubscribeEvent + public void onPlayerItemCrafted(PlayerEvent.ItemCraftedEvent ev) { + if (MineTweakerMod.INSTANCE.recipes.hasTransformerRecipes()) { + MineTweakerMod.INSTANCE.recipes.applyTransformations(MCCraftingInventory.get(ev.craftMatrix, ev.player)); + } + + if (MineTweakerImplementationAPI.events.hasPlayerCrafted()) { + MineTweakerImplementationAPI.events.publishPlayerCrafted(new PlayerCraftedEvent( + MineTweakerMC.getIPlayer(ev.player), + MineTweakerMC.getIItemStack(ev.crafting), + MCCraftingInventory.get(ev.craftMatrix, ev.player))); } } @SubscribeEvent public void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent ev) { - MineTweakerMod.INSTANCE.onPlayerLoggedOut(ev.player); + MineTweakerImplementationAPI.events.publishPlayerLoggedOut(new PlayerLoggedOutEvent(MineTweakerMC.getIPlayer(ev.player))); } } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MCPlatformFunctions.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MCPlatformFunctions.java index 2c7d64d..4dbb7c2 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MCPlatformFunctions.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MCPlatformFunctions.java @@ -8,7 +8,12 @@ package minetweaker.mc172; import minetweaker.IPlatformFunctions; import minetweaker.api.chat.IChatMessage; +import minetweaker.api.item.IItemDefinition; +import static minetweaker.mc172.MineTweakerMod.NETWORK; import minetweaker.mc172.chat.MCChatMessage; +import minetweaker.mc172.item.MCItemDefinition; +import minetweaker.mc172.network.MineTweakerLoadScriptsPacket; +import net.minecraft.item.Item; /** * @@ -23,4 +28,17 @@ public class MCPlatformFunctions implements IPlatformFunctions { public IChatMessage getMessage(String message) { return new MCChatMessage(message); } + + @Override + public void distributeScripts(byte[] data) { + NETWORK.sendToAll(new MineTweakerLoadScriptsPacket(data)); + } + + @Override + public IItemDefinition getItemDefinition(int id) { + Item item = Item.getItemById(id); + if (item == null) return null; + String sid = Item.itemRegistry.getNameForObject(item); + return new MCItemDefinition(sid, item); + } } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerCommand.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerCommand.java deleted file mode 100644 index a54f475..0000000 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerCommand.java +++ /dev/null @@ -1,400 +0,0 @@ -package minetweaker.mc172; - -import cpw.mods.fml.common.Loader; -import cpw.mods.fml.common.ModContainer; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; -import minetweaker.MineTweakerAPI; -import minetweaker.api.item.IItemStack; -import minetweaker.api.minecraft.MineTweakerMC; -import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; -import minetweaker.api.oredict.IOreDictEntry; - -import net.minecraft.command.ICommand; -import net.minecraft.command.ICommandSender; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.InventoryPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ChatComponentText; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.oredict.OreDictionary; -import stanhebben.zenscript.util.StringUtil; - -/** - * Implements the /minetweaker command set. - * - * @author Stan Hebben - */ -public class MineTweakerCommand implements ICommand { - // ########################### - // ## Public static methods ## - // ########################### - - public static void sendChatMessage(ICommandSender sender, String message) { - sender.addChatMessage(new ChatComponentText(message)); - } - - private static final List aliases = Arrays.asList("mt"); - - // ####################################### - // ## ICommand interface implementation ## - // ####################################### - - @Override - public int compareTo(Object arg0) { - return 0; - } - - @Override - public String getCommandName() { - return "minetweaker"; - } - - @Override - public String getCommandUsage(ICommandSender icommandsender) { - return StringUtil.join(new String[] { - "", - "minetweaker reload", - " Reloads all scripts", - "minetweaker names", - " Outputs a list of all item names in the game to the minetweaker log", - "minetweaker liquids", - " Outputs a list of all liquid names in the game to the minetweaker log", - "minetweaker inventory", - " Lists all items in your inventory", - "minetweaker hand", - " Outputs the name of the item in your hand", - "minetweaker oredict", - " Outputs all ore dictionary entries in the game to the minetweaker log", - "minetweaker oredict ", - " Outputs all items in the given ore dictionary entry to the minetweaker log", - "minetweaker mods", - " Outputs all active mod IDs in the game", - "minetweaker name ", - " Outputs the name for the given item ID" - }, "\n"); - } - - @Override - public List getCommandAliases() { - return aliases; - } - - @Override - public void processCommand(ICommandSender icommandsender, String[] arguments) { - if (arguments.length == 0) { - sendChatMessage(icommandsender, "Please provide a command. Use /help minetweaker for more info."); - return; - } - - if (arguments[0].equals("reload")) { - MineTweakerMod.INSTANCE.reload(); - - String message = "Scripts have been reloaded"; - sendChatMessage(icommandsender, message); - } else if (arguments[0].equals("names")) { - Set keys = Item.itemRegistry.getKeys(); - String[] sortedKeys = new String[keys.size()]; - int sortedKeyIndex = 0; - for (String key : keys) sortedKeys[sortedKeyIndex++] = key; - Arrays.sort(sortedKeys); - - for (String key : sortedKeys) { - Item item = (Item) Item.itemRegistry.getObject(key); - - String displayName = ""; - - try { - displayName = " -- " + new ItemStack(item, 1, 0).getDisplayName(); - } catch (Exception ex) { - // some mods (such as buildcraft) may throw exceptions when calling - // getDisplayName on a item stack that doesn't contain valid NBT data - } - - String message = "<" + key + ">" + displayName; - MineTweakerAPI.logger.logCommand(message); - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("liquids")) { - for (Map.Entry entry : FluidRegistry.getRegisteredFluids().entrySet()) { - String message = " -- " + entry.getValue().getLocalizedName(); - MineTweakerAPI.logger.logCommand(message); - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("inventory")) { - if (icommandsender instanceof EntityPlayer) { - InventoryPlayer inventory = ((EntityPlayer) icommandsender).inventory; - for(int i = 0; i < inventory.getSizeInventory(); i++) { - ItemStack stack = inventory.getStackInSlot(i); - if (stack != null) { - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(Item.itemRegistry.getNameForObject(stack.getItem())); - if (stack.getItemDamage() > 0) { - description.append(':').append(stack.getItemDamage()); - } - description.append('>'); - - if (stack.stackSize != 1) { - description.append('*').append(stack.stackSize); - } - - sendChatMessage(icommandsender, getIItemStack(stack).toString()); - } - } - } else { - sendChatMessage(icommandsender, "Inventory command can only be executed by players"); - } - } else if (arguments[0].equals("hand")) { - if (icommandsender instanceof EntityPlayer) { - InventoryPlayer inventory = ((EntityPlayer) icommandsender).inventory; - ItemStack stack = inventory.getCurrentItem(); - if (stack != null) { - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(Item.itemRegistry.getNameForObject(stack.getItem())); - if (stack.getItemDamage() > 0) { - description.append(':').append(stack.getItemDamage()); - } - description.append('>'); - - if (stack.stackSize != 1) { - description.append('*').append(stack.stackSize); - } - - sendChatMessage(icommandsender, getIItemStack(stack).toString()); - } - } else { - sendChatMessage(icommandsender, "Hand command can only be executed by players"); - } - } else if (arguments[0].equals("oredict")) { - if (arguments.length > 2) { - String entryName = arguments[2]; - IOreDictEntry entry = MineTweakerMC.getOreDict(entryName); - if (entry.isEmpty()) { - sendChatMessage(icommandsender, "Entry doesn't exist"); - return; - } else { - MineTweakerAPI.logger.logCommand("Ore entries for " + entryName + ":"); - for (IItemStack ore : entry.getItems()) { - MineTweakerAPI.logger.logCommand(" " + ore); - } - } - } else { - for (String entryName : OreDictionary.getOreNames()) { - IOreDictEntry entry = MineTweakerMC.getOreDict(entryName); - if (!entry.isEmpty()) { - MineTweakerAPI.logger.logCommand("Ore entries for " + entryName + ":"); - for (IItemStack ore : entry.getItems()) { - MineTweakerAPI.logger.logCommand(" " + ore); - } - } - } - } - sendChatMessage(icommandsender, "List generated; see minetweaker.log in your minecraft dir"); - } else if (arguments[0].equals("mods")) { - List mods = Loader.instance().getActiveModList(); - MineTweakerAPI.logger.logCommand("Mods list:"); - for (ModContainer mod : mods) { - sendChatMessage(icommandsender, mod.getModId()); - MineTweakerAPI.logger.logCommand("Mod: " + mod.getModId()); - } - } else if (arguments[0].equals("name")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "missing id parameter"); - } else { - try { - int id = Integer.parseInt(arguments[1]); - Item item = Item.getItemById(id); - StringBuilder description = new StringBuilder(); - description.append('<'); - description.append(Item.itemRegistry.getNameForObject(item)); - description.append('>'); - sendChatMessage(icommandsender, description.toString()); - } catch (NumberFormatException e) { - MineTweakerAPI.logger.logCommand("ID must be an integer"); - } - } - } - - /*if (arguments[0].equals("name")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - } else { - try { - ITweakerItem item = TweakerItem.parse(arguments[1]); - sendChatMessage(icommandsender, "Name for " + item.toIdString() + ": " + MineTweakerUtil.formatItemName(item.getName())); - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, ex.getMessage()); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, ex.getExplanation()); - } - } - } else if (arguments[0].equals("liquid")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide a liquid container item id"); - } else { - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - //#ifdef MC152 - //+if (LiquidContainerRegistry.isLiquid(item.make(1))) { - //+sendChatMessage(icommandsender, "Liquid name: " + item.getName()); - //+} else if (LiquidContainerRegistry.isFilledContainer(item.make(1))) { - //+sendChatMessage(icommandsender, "Liquid name: " + LiquidContainerRegistry.getLiquidForFilledItem(item.make(1)).asItemStack().getItemName()); - //+} else { - //+sendChatMessage(icommandsender, "This item is not a liquid or liquid container"); - //+} - //#else - if (item.getItemId() == 9) { - sendChatMessage(icommandsender, "Liquid name: fluid.tile.water"); - } else if (item.getItemId() == 11) { - sendChatMessage(icommandsender, "Liquid name: fluid.tile.lava"); - } else if (Block.blocksList[item.getItemId()] != null && Block.blocksList[item.getItemId()] instanceof IFluidBlock) { - sendChatMessage(icommandsender, "Liquid name: " + ((IFluidBlock)(Block.blocksList[item.getItemId()])).getFluid().getUnlocalizedName()); - } else if (FluidContainerRegistry.isFilledContainer(item.make(1))) { - sendChatMessage(icommandsender, "Liquid name: " + FluidContainerRegistry.getFluidForFilledItem(item.make(1)).getFluid().getUnlocalizedName()); - } else { - sendChatMessage(icommandsender, "This item is not a liquid or liquid container"); - } - //#endif - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, ex.getMessage()); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, ex.getExplanation()); - } - } - } else if (arguments[0].equals("oredict")) { - if (arguments.length == 1) { - String[] names = OreDictionary.getOreNames(); - Arrays.sort(names); - for (String name : names) { - sendChatMessage(icommandsender, "[" + name + "]"); - ArrayList entries = OreDictionary.getOres(name); - for (ItemStack stack : entries) { - //#ifdef MC152 - //+sendChatMessage(icommandsender, - //+" " + MineTweakerUtil.getItemString(stack) + " - " + - //+MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getItemName())); - //#else - sendChatMessage(icommandsender, - " " + MineTweakerUtil.getItemString(stack) + " - " + - MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getUnlocalizedName())); - //#endif - } - } - } else { - try { - if (Character.isDigit(arguments[1].charAt(0))) { - TweakerItemPattern item = TweakerItem.parse(arguments[1]).asItemPattern(); - for (String name : OreDictionary.getOreNames()) { - for (ItemStack stack : OreDictionary.getOres(name)) { - if (item.matches(stack)) { - sendChatMessage(icommandsender, " " + name); - break; - } - } - } - } else { - for (ItemStack stack : OreDictionary.getOres(arguments[1])) { - //#ifdef MC152 - //+sendChatMessage(icommandsender, - //+" " + MineTweakerUtil.getItemString(stack) + " - " + - //+MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getItemName())); - //#else - sendChatMessage(icommandsender, - " " + MineTweakerUtil.getItemString(stack) + " - " + - MineTweakerUtil.formatItemName(stack.getItemDamage() == OreDictionary.WILDCARD_VALUE ? stack.getItem().getUnlocalizedName() : stack.getUnlocalizedName())); - //#endif - } - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id or ore dictionary entry"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id or ore dictionary entry"); - } - } - } else if (arguments[0].equals("recipes")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - return; - } - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - sendChatMessage(icommandsender, "Recipes for item " + item.toIdString()); - - TweakerItemPattern pattern = item.asItemPattern(); - - @SuppressWarnings("unchecked") - List recipes = CraftingManager.getInstance().getRecipeList(); - - for (IRecipe recipe : recipes) { - if (pattern.matches(recipe.getRecipeOutput())) { - sendChatMessage(icommandsender, " " + MineTweakerUtil.getRecipeString(recipe)); - } - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } - } else if (arguments[0].equals("fuel")) { - if (arguments.length < 2) { - sendChatMessage(icommandsender, "Please provide an item id"); - return; - } - try { - TweakerItem item = TweakerItem.parse(arguments[1]); - ItemStack stack = item.make(1); - int value = TileEntityFurnace.getItemBurnTime(stack); - int regValue = GameRegistry.getFuelValue(stack); - - sendChatMessage(icommandsender, "Fuel for " + item.toIdString() + " = " + value); - if (value != regValue) { - sendChatMessage(icommandsender, "The value is hardcoded and cannot be altered."); - } - } catch (TweakerExecuteException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } catch (TweakerException ex) { - sendChatMessage(icommandsender, "Invalid item id"); - } - } else if (arguments[0].equals("reload")) { - if (!MineTweaker.instance.canRollback()) { - sendChatMessage(icommandsender, "Previous server script contained permanent actions, cannot reload. A restart is required to reload scripts."); - } else { - MineTweaker.instance.reloadScripts(); - sendChatMessage(icommandsender, "Script reloaded, updating all players"); - } - } else if (arguments[0].equals("logdamage=on")) { - DamageTweaker.logDamage = true; - sendChatMessage(icommandsender, "Damage logging turned on"); - sendChatMessage(icommandsender, "Info: logging is sent to the development console"); - } else if (arguments[0].equals("logdamage=off")) { - DamageTweaker.logDamage = false; - sendChatMessage(icommandsender, "Damage logging turned off"); - } else { - sendChatMessage(icommandsender, "Unrecognized minetweaker command"); - }*/ - - //MineCraftCompat.sendChatMessage(icommandsender, "[" + Arrays2.join(arguments, ", ") + "]"); - } - - @Override - public boolean canCommandSenderUseCommand(ICommandSender icommandsender) { - return true; - } - - @Override - public List addTabCompletionOptions(ICommandSender icommandsender, - String[] astring) { - return null; - } - - @Override - public boolean isUsernameIndex(String[] astring, int i) { - return false; - } -} diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerLogger.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerLogger.java deleted file mode 100644 index b57c16d..0000000 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerLogger.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -package minetweaker.mc172; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.List; -import minetweaker.runtime.ILogger; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.ChatComponentText; - -/** - * - * @author Stan - */ -public class MineTweakerLogger implements ILogger { - private Writer writer; - private List unreportedErrors; - private List players; - - public MineTweakerLogger() { - File logFile = new File("minetweaker.log"); - if (logFile.exists()) logFile.delete(); - - unreportedErrors = new ArrayList(); - players = new ArrayList(); - - try { - writer = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(logFile))); - } catch (IOException ex) { - - } - } - - public void clear() { - unreportedErrors.clear(); - } - - public void addPlayer(EntityPlayer player) { - players.add(player); - - if (!unreportedErrors.isEmpty()) { - for (String error : unreportedErrors) { - player.addChatMessage(new ChatComponentText(error)); - } - - unreportedErrors.clear(); - } - } - - public void removePlayer(EntityPlayer player) { - players.remove(player); - } - - @Override - public void logCommand(String message) { - try { - writer.append("COMMAND: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("COMMAND: " + message); - } - - @Override - public void logInfo(String message) { - try { - writer.append("INFO: "); - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println("INFO: " + message); - } - - @Override - public void logWarning(String message) { - report("WARNING: " + message); - } - - @Override - public void logError(String message) { - report("ERROR: " + message); - } - - private void report(String message) { - try { - writer.append(message); - writer.append('\n'); - writer.flush(); - } catch (IOException ex) { - - } - - System.out.println(message); - - if (players.isEmpty()) { - unreportedErrors.add(message); - } else { - ChatComponentText text = new ChatComponentText(message); - for (EntityPlayer player : players) { - player.addChatMessage(text); - } - } - } -} diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerMod.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerMod.java index f251b9d..38e9e99 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerMod.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/MineTweakerMod.java @@ -19,19 +19,23 @@ import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; import java.io.File; import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.logger.FileLogger; import minetweaker.mc172.furnace.FuelTweaker; import minetweaker.mc172.furnace.MCFurnaceManager; +import minetweaker.mc172.game.MCGame; import minetweaker.mc172.mods.MCLoadedMods; import minetweaker.mc172.network.MineTweakerLoadScriptsHandler; import minetweaker.mc172.network.MineTweakerLoadScriptsPacket; +import minetweaker.mc172.network.MineTweakerOpenBrowserHandler; +import minetweaker.mc172.network.MineTweakerOpenBrowserPacket; import minetweaker.mc172.oredict.MCOreDict; import minetweaker.mc172.recipes.MCRecipeManager; +import minetweaker.mc172.server.MCServer; import minetweaker.mc172.util.MineTweakerHacks; import minetweaker.runtime.IScriptProvider; import minetweaker.runtime.providers.ScriptProviderCascade; import minetweaker.runtime.providers.ScriptProviderDirectory; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.server.MinecraftServer; import net.minecraftforge.common.MinecraftForge; /** @@ -54,24 +58,24 @@ public class MineTweakerMod { static { NETWORK.registerMessage(MineTweakerLoadScriptsHandler.class, MineTweakerLoadScriptsPacket.class, 0, Side.CLIENT); + NETWORK.registerMessage(MineTweakerOpenBrowserHandler.class, MineTweakerOpenBrowserPacket.class, 1, Side.CLIENT); } @Mod.Instance(MODID) public static MineTweakerMod INSTANCE; - public final MineTweakerLogger logger; + public final MCRecipeManager recipes; private final IScriptProvider scriptsGlobal; - private boolean iAmServer = false; - public MineTweakerMod() { MineTweakerAPI.oreDict = new MCOreDict(); - MineTweakerAPI.recipes = new MCRecipeManager(); - MineTweakerAPI.logger = logger = new MineTweakerLogger(); + MineTweakerAPI.recipes = recipes = new MCRecipeManager(); + MineTweakerImplementationAPI.logger.addLogger(new FileLogger(new File("minetweaker.log"))); + MineTweakerAPI.game = MCGame.INSTANCE; MineTweakerAPI.furnace = new MCFurnaceManager(); MineTweakerAPI.loadedMods = new MCLoadedMods(); - MineTweakerAPI.platform = MCPlatformFunctions.INSTANCE; + MineTweakerImplementationAPI.platform = MCPlatformFunctions.INSTANCE; File globalDir = new File("scripts"); if (!globalDir.exists()) { @@ -82,36 +86,6 @@ public class MineTweakerMod { MineTweakerAPI.tweaker.setScriptProvider(scriptsGlobal); } - public boolean iAmServer() { - return iAmServer; - } - - /** - * Reloads all scripts. - */ - public void reload() { - logger.clear(); - MineTweakerAPI.tweaker.rollback(); - MineTweakerAPI.tweaker.load(); - - if (iAmServer) { - // execute script on all connected clients - NETWORK.sendToAll(new MineTweakerLoadScriptsPacket(MineTweakerAPI.tweaker.getScriptData())); - } - } - - public void onPlayerLoggedIn(EntityPlayer player) { - if (iAmServer || MinecraftServer.getServer().getConfigurationManager().getOps().contains(player.getCommandSenderName())) { - logger.addPlayer(player); - } - } - - public void onPlayerLoggedOut(EntityPlayer player) { - if (iAmServer || MinecraftServer.getServer().getConfigurationManager().getOps().contains(player.getCommandSenderName())) { - logger.removePlayer(player); - } - } - // ########################## // ### FML Event Handlers ### // ########################## @@ -137,27 +111,32 @@ public class MineTweakerMod { public void onServerAboutToStart(FMLServerAboutToStartEvent ev) { // starts before loading worlds // perfect place to start MineTweaker! + System.out.println("[MineTweaker] Server about to start"); File scriptsDir = new File(MineTweakerHacks.getWorldDirectory(ev.getServer()), "scripts"); if (!scriptsDir.exists()) { scriptsDir.mkdir(); } - iAmServer = true; + MineTweakerAPI.server = new MCServer(ev.getServer()); IScriptProvider scriptsLocal = new ScriptProviderDirectory(scriptsDir); IScriptProvider cascaded = new ScriptProviderCascade(scriptsGlobal, scriptsLocal); MineTweakerAPI.tweaker.setScriptProvider(cascaded); - reload(); + + MineTweakerImplementationAPI.onServerStart(); } @EventHandler public void onServerStarting(FMLServerStartingEvent ev) { - ev.registerServerCommand(new MineTweakerCommand()); + } @EventHandler public void onServerStopped(FMLServerStoppedEvent ev) { - iAmServer = false; + System.out.println("[MineTweaker] Server stopped"); + + MineTweakerAPI.server = null; + MineTweakerImplementationAPI.onServerStop(); } } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/client/MCClient.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/client/MCClient.java new file mode 100644 index 0000000..46f0d27 --- /dev/null +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/client/MCClient.java @@ -0,0 +1,29 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc172.client; + +import minetweaker.api.client.IClient; +import minetweaker.api.minecraft.MineTweakerMC; +import minetweaker.api.player.IPlayer; +import net.minecraft.client.Minecraft; + +/** + * + * @author Stan + */ +public class MCClient implements IClient { + private final IPlayer player; + + public MCClient() { + player = MineTweakerMC.getIPlayer(Minecraft.getMinecraft().thePlayer); + } + + @Override + public IPlayer getPlayer() { + return player; + } +} diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/FuelTweaker.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/FuelTweaker.java index 0031d0a..37200ee 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/FuelTweaker.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/FuelTweaker.java @@ -47,7 +47,7 @@ public class FuelTweaker { public void addFuelPattern(SetFuelPattern pattern) { List items = pattern.getPattern().getItems(); if (items == null) { - MineTweakerAPI.logger.logError("Cannot set fuel for <*>"); + MineTweakerAPI.getLogger().logError("Cannot set fuel for <*>"); return; } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/MCFurnaceManager.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/MCFurnaceManager.java index 2ccf30a..a192b1d 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/MCFurnaceManager.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/furnace/MCFurnaceManager.java @@ -47,7 +47,7 @@ public class MCFurnaceManager implements IFurnaceManager { } if (toRemove.isEmpty()) { - MineTweakerAPI.logger.logWarning("No furnace recipes for " + output.toString()); + MineTweakerAPI.getLogger().logWarning("No furnace recipes for " + output.toString()); } else { MineTweakerAPI.tweaker.apply(new RemoveAction(toRemove, toRemoveValues)); } @@ -57,7 +57,7 @@ public class MCFurnaceManager implements IFurnaceManager { public void addRecipe(IItemStack output, IIngredient input, double xp) { List items = input.getItems(); if (items == null) { - MineTweakerAPI.logger.logError("Cannot turn " + input.toString() + " into a furnace recipe"); + MineTweakerAPI.getLogger().logError("Cannot turn " + input.toString() + " into a furnace recipe"); } ItemStack[] items2 = getItemStacks(items); diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/game/MCGame.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/game/MCGame.java new file mode 100644 index 0000000..36fa3d3 --- /dev/null +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/game/MCGame.java @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc172.game; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import minetweaker.api.game.IGame; +import minetweaker.api.item.IItemDefinition; +import minetweaker.api.liquid.ILiquidDefinition; +import minetweaker.mc172.item.MCItemDefinition; +import minetweaker.mc172.liquid.MCLiquidDefinition; +import net.minecraft.item.Item; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; + +/** + * + * @author Stan + */ +public class MCGame implements IGame { + public static final MCGame INSTANCE = new MCGame(); + + private MCGame() {} + + @Override + public List getItems() { + List result = new ArrayList(); + for (String item : (Set)Item.itemRegistry.getKeys()) { + result.add(new MCItemDefinition(item, (Item) Item.itemRegistry.getObject(item))); + } + return result; + } + + @Override + public List getLiquids() { + List result = new ArrayList(); + for (Map.Entry entry : FluidRegistry.getRegisteredFluids().entrySet()) { + result.add(new MCLiquidDefinition(entry.getValue())); + } + return result; + } +} diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemDefinition.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemDefinition.java index 7fc7990..782f33b 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemDefinition.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemDefinition.java @@ -7,16 +7,36 @@ package minetweaker.mc172.item; import minetweaker.api.item.IItemDefinition; +import minetweaker.api.item.IItemStack; +import minetweaker.api.minecraft.MineTweakerMC; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; /** * * @author Stan */ public class MCItemDefinition implements IItemDefinition { + private final String id; private final Item item; - public MCItemDefinition(Item item) { + public MCItemDefinition(String id, Item item) { + this.id = id; this.item = item; } + + @Override + public String getId() { + return id; + } + + @Override + public String getName() { + return item.getUnlocalizedName(); + } + + @Override + public IItemStack makeStack(int meta) { + return MineTweakerMC.getIItemStackWildcardSize(new ItemStack(item, 1, meta)); + } } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemStack.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemStack.java index 6580b2d..3ca4e71 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemStack.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/item/MCItemStack.java @@ -63,7 +63,9 @@ public class MCItemStack implements IItemStack { @Override public IItemDefinition getDefinition() { - return new MCItemDefinition(stack.getItem()); + return new MCItemDefinition( + Item.itemRegistry.getNameForObject(stack.getItem()), + stack.getItem()); } @Override @@ -112,7 +114,7 @@ public class MCItemStack implements IItemStack { @Override public IIngredient anyDamage() { if (stack.getItem().getHasSubtypes()) { - MineTweakerAPI.logger.logWarning("subitems don't have damaged states"); + MineTweakerAPI.getLogger().logWarning("subitems don't have damaged states"); return this; } else { ItemStack result = new ItemStack(stack.getItem(), stack.stackSize, OreDictionary.WILDCARD_VALUE); @@ -124,7 +126,7 @@ public class MCItemStack implements IItemStack { @Override public IItemStack withDamage(int damage) { if (stack.getItem().getHasSubtypes()) { - MineTweakerAPI.logger.logWarning("subitems don't have damaged states"); + MineTweakerAPI.getLogger().logWarning("subitems don't have damaged states"); return this; } else { ItemStack result = new ItemStack(stack.getItem(), stack.stackSize, damage); @@ -232,6 +234,11 @@ public class MCItemStack implements IItemStack { return item; } + @Override + public boolean hasTransformers() { + return false; + } + @Override public Object getInternal() { return stack; diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerLoadScriptsHandler.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerLoadScriptsHandler.java index 5e04969..da8bcab 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerLoadScriptsHandler.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerLoadScriptsHandler.java @@ -10,7 +10,7 @@ import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import minetweaker.MineTweakerAPI; -import minetweaker.mc172.MineTweakerMod; +import minetweaker.MineTweakerImplementationAPI; import minetweaker.runtime.providers.ScriptProviderMemory; /** @@ -20,20 +20,9 @@ import minetweaker.runtime.providers.ScriptProviderMemory; public class MineTweakerLoadScriptsHandler implements IMessageHandler { @Override public IMessage onMessage(MineTweakerLoadScriptsPacket message, MessageContext ctx) { - if (!MineTweakerMod.INSTANCE.iAmServer()) { - /*IScriptProvider scriptProvider = new ScriptProviderMemory(message.getData()); - Iterator scripts = scriptProvider.getScripts(); - while (scripts.hasNext()) { - IScriptIterator myGroup = scripts.next(); - System.out.println("Scripts: " + myGroup.getGroupName()); - - while (myGroup.next()) { - System.out.println("Script name: " + myGroup.getName()); - } - }*/ + if (MineTweakerAPI.server == null) { MineTweakerAPI.tweaker.setScriptProvider(new ScriptProviderMemory(message.getData())); - MineTweakerAPI.tweaker.rollback(); - MineTweakerAPI.tweaker.load(); + MineTweakerImplementationAPI.reload(); } return null; diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerOpenBrowserHandler.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerOpenBrowserHandler.java new file mode 100644 index 0000000..45c1769 --- /dev/null +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerOpenBrowserHandler.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc172.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * + * @author Stan + */ +public class MineTweakerOpenBrowserHandler implements IMessageHandler { + @Override + public IMessage onMessage(MineTweakerOpenBrowserPacket message, MessageContext ctx) { + if(Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI(message.getUrl())); + } catch (IOException e) { + } catch (URISyntaxException e) { + } + } + + return null; + } +} diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerOpenBrowserPacket.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerOpenBrowserPacket.java new file mode 100644 index 0000000..5505de3 --- /dev/null +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/network/MineTweakerOpenBrowserPacket.java @@ -0,0 +1,44 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc172.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import io.netty.buffer.ByteBuf; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + +/** + * + * @author Stan + */ +public class MineTweakerOpenBrowserPacket implements IMessage { + private static final Charset UTF8 = Charset.forName("utf-8"); + + private String url; + + public MineTweakerOpenBrowserPacket() { + + } + + public MineTweakerOpenBrowserPacket(String url) { + this.url = url; + } + + public String getUrl() { + return url; + } + + @Override + public void fromBytes(ByteBuf buf) { + url = UTF8.decode(ByteBuffer.wrap(buf.array())).toString().trim(); + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeBytes(UTF8.encode(url).array()); + } +} diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDict.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDict.java index 6113134..5055dc5 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDict.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDict.java @@ -6,9 +6,13 @@ package minetweaker.mc172.oredict; +import java.util.ArrayList; +import java.util.List; +import minetweaker.api.minecraft.MineTweakerMC; import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; import minetweaker.api.oredict.IOreDict; import minetweaker.api.oredict.IOreDictEntry; +import net.minecraftforge.oredict.OreDictionary; /** * @@ -19,4 +23,15 @@ public class MCOreDict implements IOreDict { public IOreDictEntry get(String name) { return getOreDict(name); } + + @Override + public List getEntries() { + List entries = new ArrayList(); + for (String key : OreDictionary.getOreNames()) { + if (!OreDictionary.getOres(key).isEmpty()) { + entries.add(MineTweakerMC.getOreDict(key)); + } + } + return entries; + } } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDictEntry.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDictEntry.java index ed67f54..bb99c15 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDictEntry.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/oredict/MCOreDictEntry.java @@ -16,7 +16,7 @@ import minetweaker.api.item.IItemCondition; import minetweaker.api.item.IItemStack; import minetweaker.api.item.IItemTransformer; import minetweaker.api.item.IngredientStack; -import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; +import static minetweaker.api.minecraft.MineTweakerMC.getIItemStackWildcardSize; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; import minetweaker.api.oredict.IOreDictEntry; import minetweaker.api.oredict.IngredientOreDict; @@ -46,6 +46,11 @@ public class MCOreDictEntry implements IOreDictEntry { // ### IOreDictEntry implementation ### // #################################### + @Override + public String getName() { + return OreDictionary.getOreName(id); + } + @Override public boolean isEmpty() { return OreDictionary.getOres(id).isEmpty(); @@ -64,7 +69,7 @@ public class MCOreDictEntry implements IOreDictEntry { if (entry instanceof MCOreDictEntry) { MineTweakerAPI.tweaker.apply(new ActionAddAll(id, ((MCOreDictEntry) entry).id)); } else { - MineTweakerAPI.logger.logError("not a valid entry"); + MineTweakerAPI.getLogger().logError("not a valid entry"); } } @@ -72,7 +77,7 @@ public class MCOreDictEntry implements IOreDictEntry { public void remove(IItemStack item) { ItemStack result = null; for (ItemStack itemStack : OreDictionary.getOres(id)) { - if (item.matches(getIItemStack(itemStack))) { + if (item.matches(getIItemStackWildcardSize(itemStack))) { result = itemStack; break; } @@ -86,7 +91,7 @@ public class MCOreDictEntry implements IOreDictEntry { @Override public boolean contains(IItemStack item) { for (ItemStack itemStack : OreDictionary.getOres(id)) { - if (item.matches(getIItemStack(itemStack))) { + if (getIItemStackWildcardSize(itemStack).matches(item)) { return true; } } @@ -99,7 +104,7 @@ public class MCOreDictEntry implements IOreDictEntry { if (other instanceof MCOreDictEntry) { MineTweakerAPI.tweaker.apply(new ActionMirror(id, ((MCOreDictEntry) other).id)); } else { - MineTweakerAPI.logger.logError("not a valid oredict entry"); + MineTweakerAPI.getLogger().logError("not a valid oredict entry"); } } @@ -117,7 +122,7 @@ public class MCOreDictEntry implements IOreDictEntry { public List getItems() { List result = new ArrayList(); for (ItemStack item : OreDictionary.getOres(id)) { - result.add(getIItemStack(item)); + result.add(getIItemStackWildcardSize(item)); } return result; } @@ -162,6 +167,11 @@ public class MCOreDictEntry implements IOreDictEntry { return item; } + @Override + public boolean hasTransformers() { + return false; + } + @Override public Object getInternal() { return OreDictionary.getOreName(id); diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java index 4314b19..4c5d5bb 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/player/MCPlayer.java @@ -9,9 +9,14 @@ package minetweaker.mc172.player; import minetweaker.MineTweakerAPI; import minetweaker.api.chat.IChatMessage; import minetweaker.api.data.IData; +import minetweaker.api.item.IItemStack; +import minetweaker.api.minecraft.MineTweakerMC; import minetweaker.api.player.IPlayer; +import minetweaker.mc172.MineTweakerMod; import minetweaker.mc172.data.NBTConverter; +import minetweaker.mc172.network.MineTweakerOpenBrowserPacket; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.util.IChatComponent; /** @@ -22,12 +27,18 @@ public class MCPlayer implements IPlayer { private final EntityPlayer player; public MCPlayer(EntityPlayer player) { + if (player == null) throw new IllegalArgumentException("player cannot be null"); this.player = player; } public EntityPlayer getInternal() { return player; } + + @Override + public String getId() { + return null; + } @Override public String getName() { @@ -48,9 +59,43 @@ public class MCPlayer implements IPlayer { public void sendChat(IChatMessage message) { Object internal = message.getInternal(); if (!(internal instanceof IChatComponent)) { - MineTweakerAPI.logger.logError("not a valid chat message"); + MineTweakerAPI.getLogger().logError("not a valid chat message"); return; } player.addChatMessage((IChatComponent) internal); } + + @Override + public int getHotbarSize() { + return 9; + } + + @Override + public IItemStack getHotbarStack(int i) { + return i < 0 || i >= 9 ? null : MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)); + } + + @Override + public int getInventorySize() { + return player.inventory.getSizeInventory(); + } + + @Override + public IItemStack getInventoryStack(int i) { + return MineTweakerMC.getIItemStack(player.inventory.getStackInSlot(i)); + } + + @Override + public IItemStack getCurrentItem() { + return MineTweakerMC.getIItemStack(player.getCurrentEquippedItem()); + } + + @Override + public void openBrowser(String url) { + if (player instanceof EntityPlayerMP) { + MineTweakerMod.NETWORK.sendTo( + new MineTweakerOpenBrowserPacket(url), + (EntityPlayerMP) player); + } + } } diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCCraftingInventory.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCCraftingInventory.java index ab43320..9ff14c9 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCCraftingInventory.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCCraftingInventory.java @@ -14,8 +14,10 @@ import static minetweaker.api.minecraft.MineTweakerMC.getIPlayer; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; import minetweaker.api.player.IPlayer; import minetweaker.api.recipes.ICraftingInventory; +import minetweaker.mc172.player.MCPlayer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; +import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; @@ -27,6 +29,7 @@ import net.minecraft.item.ItemStack; */ public class MCCraftingInventory implements ICraftingInventory { private static final ThreadLocal cache = new ThreadLocal(); + private static final ThreadLocal cache2 = new ThreadLocal(); public static MCCraftingInventory get(InventoryCrafting inventory) { if (cache.get() == null || cache.get().inventory != inventory) { @@ -40,13 +43,26 @@ public class MCCraftingInventory implements ICraftingInventory { } } + public static MCCraftingInventory get(IInventory inventory, EntityPlayer player) { + if (cache2.get() == null || cache2.get().inventory != inventory || cache2.get().player != player) { + MCCraftingInventory result = new MCCraftingInventory(inventory, player); + cache2.set(result); + return result; + } else { + MCCraftingInventory result = cache2.get(); + result.update(); + return result; + } + } + private int width; private int height; - private final InventoryCrafting inventory; + private final IInventory inventory; private IItemStack[] stacks; private ItemStack[] original; private int stackCount; - private IPlayer player; + private final IPlayer player; + private final EntityPlayer playerOrig; private MCCraftingInventory(InventoryCrafting inventory) { this.inventory = inventory; @@ -60,13 +76,26 @@ public class MCCraftingInventory implements ICraftingInventory { List slots = container.inventorySlots; if (!slots.isEmpty() && slots.get(0) instanceof SlotCrafting) { SlotCrafting slotCrafting = (SlotCrafting) slots.get(0); - EntityPlayer playerEntity = MineTweakerHacks.getCraftingSlotPlayer(slotCrafting); - player = getIPlayer(playerEntity); + playerOrig = MineTweakerHacks.getCraftingSlotPlayer(slotCrafting); + player = getIPlayer(playerOrig); } else { + playerOrig = null; player = null; } } + public MCCraftingInventory(IInventory inventory, EntityPlayer player) { + this.inventory = inventory; + width = height = (int) Math.sqrt(inventory.getSizeInventory()); + stacks = new IItemStack[width * height]; + original = new ItemStack[stacks.length]; + stackCount = 0; + update(); + + playerOrig = player; + this.player = player == null ? null : new MCPlayer(player); + } + private void update() { if (inventory.getSizeInventory() != original.length) { width = height = (int) Math.sqrt(inventory.getSizeInventory()); diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java index f41461b..fb13871 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/recipes/MCRecipeManager.java @@ -12,6 +12,8 @@ import minetweaker.api.item.IItemStack; import static minetweaker.api.minecraft.MineTweakerMC.getIItemStack; import static minetweaker.api.minecraft.MineTweakerMC.getItemStack; import static minetweaker.api.minecraft.MineTweakerMC.getOreDict; +import minetweaker.api.recipes.ICraftingInventory; +import minetweaker.api.recipes.ICraftingRecipe; import minetweaker.api.recipes.IRecipeFunction; import minetweaker.api.recipes.IRecipeManager; import net.minecraft.entity.player.EntityPlayer; @@ -31,9 +33,24 @@ import net.minecraftforge.oredict.ShapelessOreRecipe; */ public class MCRecipeManager implements IRecipeManager { private final List recipes; + private final List transformerRecipes; public MCRecipeManager() { recipes = (List) CraftingManager.getInstance().getRecipeList(); + transformerRecipes = new ArrayList(); + } + + public boolean hasTransformerRecipes() { + return transformerRecipes.size() > 0; + } + + public void applyTransformations(ICraftingInventory inventory) { + for (ICraftingRecipe recipe : transformerRecipes) { + if (recipe.matches(inventory)) { + recipe.applyTransformers(inventory); + return; + } + } } @Override @@ -66,14 +83,14 @@ public class MCRecipeManager implements IRecipeManager { public void addShaped(IItemStack output, IIngredient[][] ingredients, IRecipeFunction function, boolean mirrored) { ShapedRecipe recipe = new ShapedRecipe(output, ingredients, function, mirrored); IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe)); + MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe, recipe)); } @Override public void addShapeless(IItemStack output, IIngredient[] ingredients, IRecipeFunction function) { ShapelessRecipe recipe = new ShapelessRecipe(output, ingredients, function); IRecipe irecipe = RecipeConverter.convert(recipe); - MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe)); + MineTweakerAPI.tweaker.apply(new ActionAddRecipe(irecipe, recipe)); } @Override @@ -305,14 +322,19 @@ public class MCRecipeManager implements IRecipeManager { private class ActionAddRecipe implements IUndoableAction { private final IRecipe recipe; + private final ICraftingRecipe craftingRecipe; - public ActionAddRecipe(IRecipe recipe) { + public ActionAddRecipe(IRecipe recipe, ICraftingRecipe craftingRecipe) { this.recipe = recipe; + this.craftingRecipe = craftingRecipe; } @Override public void apply() { recipes.add(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.add(craftingRecipe); + } } @Override @@ -323,6 +345,9 @@ public class MCRecipeManager implements IRecipeManager { @Override public void undo() { recipes.remove(recipe); + if (craftingRecipe.hasTransformers()) { + transformerRecipes.remove(craftingRecipe); + } } @Override diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/server/MCServer.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/server/MCServer.java new file mode 100644 index 0000000..5818946 --- /dev/null +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/server/MCServer.java @@ -0,0 +1,226 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +package minetweaker.mc172.server; + +import java.util.Arrays; +import java.util.List; +import minetweaker.IUndoableAction; +import minetweaker.MineTweakerAPI; +import minetweaker.MineTweakerImplementationAPI; +import minetweaker.api.minecraft.MineTweakerMC; +import minetweaker.api.player.IPlayer; +import minetweaker.api.server.ICommandFunction; +import minetweaker.api.server.ICommandTabCompletion; +import minetweaker.api.server.ICommandValidator; +import minetweaker.api.server.IServer; +import net.minecraft.command.CommandHandler; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; + +/** + * + * @author Stan + */ +public class MCServer implements IServer { + private final MinecraftServer server; + + public MCServer(MinecraftServer server) { + this.server = server; + } + + @Override + public void addCommand(String name, String usage, String[] aliases, ICommandFunction function, ICommandValidator validator, ICommandTabCompletion completion) { + ICommand command = new MCCommand(name, usage, aliases, function, validator, completion); + MineTweakerAPI.tweaker.apply(new AddCommandAction(command)); + } + + @Override + public void removeCommand(String name) { + ICommand command = (ICommand)((CommandHandler) server.getCommandManager()).getCommands().get(name); + if (command == null) { + MineTweakerAPI.getLogger().logWarning("No such command: " + name); + } else { + MineTweakerAPI.tweaker.apply(new RemoveCommandAction(command)); + } + } + + @Override + public void addMineTweakerCommand(String name, String[] usage, ICommandFunction function) { + MineTweakerImplementationAPI.addMineTweakerCommand(name, usage, function); + } + + @Override + public boolean isOp(IPlayer player) { + return MinecraftServer.getServer().getConfigurationManager().getOps().isEmpty() + || MinecraftServer.getServer().getConfigurationManager().getOps().contains(player.getName()); + } + + private static IPlayer getPlayer(ICommandSender commandSender) { + if (commandSender instanceof EntityPlayer) { + return MineTweakerMC.getIPlayer((EntityPlayer) commandSender); + } else { + return null; + } + } + + private static void removeCommand(ICommand command) { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.getCommands().remove(command.getCommandName()); + + if (command.getCommandAliases() != null) { + for (String alias : (List)command.getCommandAliases()) { + ch.getCommands().remove(alias); + } + } + } + + private class MCCommand implements ICommand { + private final String name; + private final String usage; + private final List aliases; + private final ICommandFunction function; + private final ICommandValidator validator; + private final ICommandTabCompletion completion; + + public MCCommand(String name, String usage, String[] aliases, ICommandFunction function, ICommandValidator validator, ICommandTabCompletion completion) { + this.name = name; + this.usage = usage; + this.aliases = Arrays.asList(aliases); + this.function = function; + this.validator = validator; + this.completion = completion; + } + + @Override + public String getCommandName() { + return name; + } + + @Override + public String getCommandUsage(ICommandSender var1) { + return usage; + } + + @Override + public List getCommandAliases() { + return aliases; + } + + @Override + public void processCommand(ICommandSender var1, String[] var2) { + function.execute(var2, getPlayer(var1)); + } + + @Override + public boolean canCommandSenderUseCommand(ICommandSender var1) { + if (validator == null) { + return true; + } else { + return validator.canExecute(getPlayer(var1)); + } + } + + @Override + public List addTabCompletionOptions(ICommandSender var1, String[] var2) { + if (completion != null) { + return Arrays.asList(completion.getTabCompletionOptions(var2, getPlayer(var1))); + } else { + return null; + } + } + + @Override + public boolean isUsernameIndex(String[] var1, int var2) { + return false; + } + + @Override + public int compareTo(Object o) { + return 0; + } + } + + private class AddCommandAction implements IUndoableAction { + private final ICommand command; + + public AddCommandAction(ICommand command) { + this.command = command; + } + + @Override + public void apply() { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.registerCommand(command); + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + removeCommand(command); + } + + @Override + public String describe() { + return "Adding command " + command.getCommandName(); + } + + @Override + public String describeUndo() { + return "Removing command " + command.getCommandName(); + } + + @Override + public Object getOverrideKey() { + return null; + } + } + + private class RemoveCommandAction implements IUndoableAction { + private final ICommand command; + + public RemoveCommandAction(ICommand command) { + this.command = command; + } + + @Override + public void apply() { + removeCommand(command); + } + + @Override + public boolean canUndo() { + return true; + } + + @Override + public void undo() { + CommandHandler ch = (CommandHandler) MinecraftServer.getServer().getCommandManager(); + ch.registerCommand(command); + } + + @Override + public String describe() { + return "Adding command " + command.getCommandName(); + } + + @Override + public String describeUndo() { + return "Removing command " + command.getCommandName(); + } + + @Override + public Object getOverrideKey() { + return null; + } + } +} diff --git a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/util/MineTweakerHacks.java b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/util/MineTweakerHacks.java index 04d725f..8df1057 100644 --- a/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/util/MineTweakerHacks.java +++ b/MineTweaker3-MC172-Main/src/main/java/minetweaker/mc172/util/MineTweakerHacks.java @@ -67,7 +67,7 @@ public class MineTweakerHacks { try { return (List>) OREDICTIONARY_IDTOSTACK.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("ERROR - could not load ore dictionary stacks!"); + MineTweakerAPI.getLogger().logError("ERROR - could not load ore dictionary stacks!"); return null; } } @@ -76,7 +76,7 @@ public class MineTweakerHacks { try { return (List>) OREDICTIONARY_IDTOSTACKUN.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("ERROR - could not load ore dictionary stacks!"); + MineTweakerAPI.getLogger().logError("ERROR - could not load ore dictionary stacks!"); return null; } } @@ -85,7 +85,7 @@ public class MineTweakerHacks { try { return (File) MINECRAFTSERVER_ANVILFILE.get(server); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not load anvil file!"); + MineTweakerAPI.getLogger().logError("could not load anvil file!"); return null; } } @@ -105,7 +105,7 @@ public class MineTweakerHacks { try { return SHAPEDORERECIPE_WIDTH.getInt(recipe); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not load anvil file!"); + MineTweakerAPI.getLogger().logError("could not load anvil file!"); return 3; } } @@ -114,7 +114,7 @@ public class MineTweakerHacks { try { return (Container) INVENTORYCRAFTING_EVENTHANDLER.get(inventory); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get inventory eventhandler"); + MineTweakerAPI.getLogger().logError("could not get inventory eventhandler"); return null; } } @@ -123,7 +123,7 @@ public class MineTweakerHacks { try { return (EntityPlayer) SLOTCRAFTING_PLAYER.get(slot); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get inventory eventhandler"); + MineTweakerAPI.getLogger().logError("could not get inventory eventhandler"); return null; } } @@ -133,7 +133,7 @@ public class MineTweakerHacks { Field field = getField(StringTranslate.class, MineTweakerObfuscation.STRINGTRANSLATE_INSTANCE); return (StringTranslate) field.get(null); } catch (IllegalAccessException ex) { - MineTweakerAPI.logger.logError("could not get string translator"); + MineTweakerAPI.getLogger().logError("could not get string translator"); return null; } } diff --git a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java index 546cfa1..dd7568a 100644 --- a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java +++ b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2BracketHandler.java @@ -56,12 +56,12 @@ public class IC2BracketHandler implements IBracketHandler { } else if (tokens.get(6).getValue().equals("*")) { meta = OreDictionary.WILDCARD_VALUE; } else { - MineTweakerAPI.logger.logError("Not a valid meta value: " + tokens.get(6).getValue()); + MineTweakerAPI.getLogger().logError("Not a valid meta value: " + tokens.get(6).getValue()); } } ItemStack item = IC2Items.getItem(name); if (item == null) { - MineTweakerAPI.logger.logError("Not a valid IC2 item: " + name); + MineTweakerAPI.getLogger().logError("Not a valid IC2 item: " + name); return null; } else { return new ItemReferenceSymbol(name, meta); diff --git a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java index 679c131..fdf7a76 100644 --- a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java +++ b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/IC2ExplosionWhitelist.java @@ -35,7 +35,7 @@ public class IC2ExplosionWhitelist { ItemStack iStack = getItemStack(item); Block block = Block.getBlockFromItem(iStack.getItem()); if (block == null) { - MineTweakerAPI.logger.logError("This item is not a block"); + MineTweakerAPI.getLogger().logError("This item is not a block"); } else { MineTweakerAPI.tweaker.apply(new AddAction(block)); } @@ -51,10 +51,10 @@ public class IC2ExplosionWhitelist { ItemStack iStack = getItemStack(item); Block block = Block.getBlockFromItem(iStack.getItem()); if (block == null) { - MineTweakerAPI.logger.logError("This item is not a block"); + MineTweakerAPI.getLogger().logError("This item is not a block"); } else { if (ExplosionWhitelist.isBlockWhitelisted(block)) { - MineTweakerAPI.logger.logWarning("This block is not in the whitelist"); + MineTweakerAPI.getLogger().logWarning("This block is not in the whitelist"); } else { MineTweakerAPI.tweaker.apply(new RemoveAction(block)); } @@ -72,7 +72,7 @@ public class IC2ExplosionWhitelist { ItemStack iStack = getItemStack(item); Block block = Block.getBlockFromItem(iStack.getItem()); if (block == null) { - MineTweakerAPI.logger.logWarning("This item is not a block"); + MineTweakerAPI.getLogger().logWarning("This item is not a block"); return false; } else { return ExplosionWhitelist.isBlockWhitelisted(block); diff --git a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java index 67f3941..87778d5 100644 --- a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java +++ b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/MachineAddRecipeAction.java @@ -31,7 +31,7 @@ public class MachineAddRecipeAction extends OneWayAction { try { machine.addRecipe(input, tag, output); } catch (RuntimeException ex) { - MineTweakerAPI.logger.logError(ex.getMessage()); + MineTweakerAPI.getLogger().logError(ex.getMessage()); } } diff --git a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java index c192f43..b5738ef 100644 --- a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java +++ b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Compressor.java @@ -38,7 +38,7 @@ public class Compressor { @NotNull IItemStack output, @NotNull IIngredient ingredient) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { MineTweakerAPI.tweaker.apply(new MachineAddRecipeAction( "compressor", diff --git a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java index f19adf6..94d0b23 100644 --- a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java +++ b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Extractor.java @@ -43,7 +43,7 @@ public class Extractor { @NotNull IItemStack output, @NotNull IIngredient ingredient) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { MineTweakerAPI.tweaker.apply(new MachineAddRecipeAction( "extractor", diff --git a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java index 731384e..b817a2c 100644 --- a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java +++ b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/Macerator.java @@ -38,7 +38,7 @@ public class Macerator { @NotNull IItemStack output, @NotNull IIngredient ingredient) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { MineTweakerAPI.tweaker.apply(new MachineAddRecipeAction( "macerator", diff --git a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java index 3839585..45d94b4 100644 --- a/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java +++ b/MineTweaker3-MC172-Mod-IC2/src/main/java/minetweaker/mods/ic2/machines/ThermalCentrifuge.java @@ -37,7 +37,7 @@ public class ThermalCentrifuge { @ZenMethod public static void addRecipe(IItemStack[] output, IIngredient ingredient, int minHeat) { if (ingredient.getAmount() < 0) { - MineTweakerAPI.logger.logWarning("invalid ingredient: " + ingredient + " - stack size not known"); + MineTweakerAPI.getLogger().logWarning("invalid ingredient: " + ingredient + " - stack size not known"); } else { NBTTagCompound tag = new NBTTagCompound(); tag.setInteger("minHeat", minHeat); diff --git a/MineTweaker3-Web/index.html b/MineTweaker3-Web/index.html index c638b04..8a7c8cb 100644 --- a/MineTweaker3-Web/index.html +++ b/MineTweaker3-Web/index.html @@ -95,9 +95,9 @@

GitHub

diff --git a/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java b/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java index 025a1a3..45d6b7e 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/ZenModule.java @@ -56,7 +56,7 @@ public class ZenModule { * @param environmentGlobal global compile environment */ public static void compileScripts(String mainFileName, List scripts, IEnvironmentGlobal environmentGlobal) { - ClassWriter clsMain = new ClassWriter(ClassWriter.COMPUTE_MAXS); + ClassWriter clsMain = new ClassWriter(ClassWriter.COMPUTE_FRAMES); clsMain.visitSource(mainFileName, null); clsMain.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, "__ZenMain__", null, internal(Object.class), new String[] {internal(Runnable.class)}); @@ -76,7 +76,7 @@ public class ZenModule { } for (ZenParsedFile script : scripts) { - ClassWriter clsScript = new ClassWriter(ClassWriter.COMPUTE_MAXS); + ClassWriter clsScript = new ClassWriter(ClassWriter.COMPUTE_FRAMES); clsScript.visitSource(script.getFileName(), null); EnvironmentClass environmentScript = new EnvironmentClass(clsScript, script.getEnvironment()); @@ -155,6 +155,7 @@ public class ZenModule { * * @param single file to be compiled * @param environment compile environment + * @param baseClassLoader * @return compiled module * @throws IOException if the file could not be read */ diff --git a/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java b/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java index 0de02f5..316e9c1 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/ZenParsedFile.java @@ -179,4 +179,9 @@ public class ZenParsedFile { public Map getFunctions() { return functions; } + + @Override + public String toString() { + return filename; + } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/ZenTokener.java b/ZenScript/src/main/java/stanhebben/zenscript/ZenTokener.java index fbc7840..7b8d552 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/ZenTokener.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/ZenTokener.java @@ -100,7 +100,8 @@ public class ZenTokener extends TokenStream { "[a-zA-Z_][a-zA-Z_0-9]*", "\\-?(0|[1-9][0-9]*)\\.[0-9]+([eE][\\+\\-]?[0-9]+)?", "\\-?(0|[1-9][0-9]*)", - "\"([^\"\\\\]|\\\\([\"\\\\/bfnrt]|u[0-9a-fA-F]{4}))*\"", + "\"([^\"\\\\]|\\\\([\'\"\\\\/bfnrt]|u[0-9a-fA-F]{4}))*\"", + "\'([^\'\\\\]|\\\\([\'\"\\\\/bfnrt]|u[0-9a-fA-F]{4}))*\'", "\\{", "\\}", "\\[", @@ -152,6 +153,7 @@ public class ZenTokener extends TokenStream { T_FLOATVALUE, T_INTVALUE, T_STRINGVALUE, + T_STRINGVALUE, T_AOPEN, T_ACLOSE, T_SQBROPEN, diff --git a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java index 535e075..0ec7508 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/expression/ExpressionJavaLambda.java @@ -63,7 +63,7 @@ public class ExpressionJavaLambda extends Expression { // generate class String clsName = environment.makeClassName(); - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, clsName, null, "java/lang/Object", new String[] { internal(interfaceClass) }); MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "", "()V", null, null); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/ParseException.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/ParseException.java index c0831c5..e752279 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/ParseException.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/ParseException.java @@ -12,18 +12,35 @@ import stanhebben.zenscript.ZenParsedFile; * @author Stan */ public class ParseException extends RuntimeException { + private final ZenParsedFile file; + private final int line; + private final int lineOffset; + private final Token token; private final String message; public ParseException(Token token, String error) { super(token == null ? "Error at end of file - " + error : "Error parsing line " + token.getPosition().getLine() + ":" + token.getPosition().getLineOffset() + " - " + error + " (last token: " + token.getValue() + ")"); + this.file = token.getPosition().getFile(); + this.line = token.getPosition().getLine(); + this.lineOffset = token.getPosition().getLineOffset(); + this.token = token; this.message = error; } + + public ParseException(ZenParsedFile file, int line, int lineOffset, String error) { + this.file = file; + this.line = line; + this.lineOffset = lineOffset; + + token = null; + message = error; + } public ZenParsedFile getFile() { - return token == null ? null : token.getPosition().getFile(); + return file; } public int getLine() { diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java index 0eb228b..e1191ec 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/TokenStream.java @@ -76,6 +76,14 @@ public class TokenStream implements Iterator { public ZenParsedFile getFile() { return file; } + + public int getLine() { + return line; + } + + public int getLineOffset() { + return lineOffset; + } public Token peek() { if (tokenMemoryCurrent < tokenMemoryOffset + tokenMemory.size()) { @@ -102,7 +110,7 @@ public class TokenStream implements Iterator { if (t != null && t.getType() == type) { return next(); } else { - throw new ParseException(t, error); + throw new ParseException(file, line, lineOffset, error); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java index abcdd0b..a37d330 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/parser/expression/ParsedExpression.java @@ -42,10 +42,24 @@ public abstract class ParsedExpression { } private static ParsedExpression readAssignExpression(ZenTokener parser, IEnvironmentGlobal environment) { - ZenPosition position = parser.peek().getPosition(); + Token token = parser.peek(); + if (token == null) { + ZenPosition position = new ZenPosition(parser.getFile(), parser.getLine(), parser.getLineOffset()); + environment.error(position, "unexpected end of file; expression expected"); + return new ParsedExpressionInvalid(position); + } + + ZenPosition position = token.getPosition(); ParsedExpression left = readConditionalExpression(position, parser, environment); - switch (parser.peek() == null ? -1 : parser.peek().getType()) { + + if (parser.peek() == null) { + ZenPosition position2 = new ZenPosition(parser.getFile(), parser.getLine(), parser.getLineOffset()); + environment.error(position2, "unexpected end of file - ; expected"); + return new ParsedExpressionInvalid(position2); + } + + switch (parser.peek().getType()) { case T_ASSIGN: parser.next(); return new ParsedExpressionAssign(position, left, readAssignExpression(parser, environment)); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java index b77e9df..014b616 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/Statement.java @@ -66,7 +66,7 @@ public abstract class Statement { names.add(parser.required(T_ID, "identifier expected").getValue()); } - parser.required(T_COLON, ": expected"); + parser.required(T_IN, "in expected"); ParsedExpression source = ParsedExpression.read(parser, environment); Statement content = read(parser, environment); return new StatementForeach( diff --git a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java index b18fe64..c8fa7d6 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/statements/StatementForeach.java @@ -41,8 +41,9 @@ public class StatementForeach extends Statement { IEnvironmentMethod local = new EnvironmentScope(environment); int[] localVariables = new int[varnames.length]; for (int i = 0; i < localVariables.length; i++) { - localVariables[i] = methodOutput.local(iterator.getType(i).toASMType()); - local.putValue(varnames[i], new SymbolLocal(iterator.getType(i), true)); + SymbolLocal localVar = new SymbolLocal(iterator.getType(i), true); + local.putValue(varnames[i], localVar); + localVariables[i] = local.getLocal(localVar); } cList.compile(true, environment); diff --git a/ZenScript/src/main/java/stanhebben/zenscript/type/iterator/IteratorIterable.java b/ZenScript/src/main/java/stanhebben/zenscript/type/iterator/IteratorIterable.java index 212567b..6812dab 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/type/iterator/IteratorIterable.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/type/iterator/IteratorIterable.java @@ -30,21 +30,22 @@ public class IteratorIterable implements IZenIterator { @Override public void compileStart(int[] locals) { iterator = methodOutput.local(Type.getType(Iterator.class)); - methodOutput.invokeVirtual(Iterator.class, "iterator", Iterator.class); + methodOutput.invokeInterface(Iterable.class, "iterator", Iterator.class); methodOutput.storeObject(iterator); } @Override public void compilePreIterate(int[] locals, Label exit) { - methodOutput.dup(); + methodOutput.loadObject(iterator); methodOutput.invokeInterface( Iterator.class, "hasNext", boolean.class); methodOutput.ifEQ(exit); - methodOutput.dup(); + methodOutput.loadObject(iterator); methodOutput.invokeInterface(Iterator.class, "next", Object.class); + methodOutput.checkCast(iteratorType.getSignature()); methodOutput.store(iteratorType.toASMType(), locals[0]); } @@ -60,7 +61,6 @@ public class IteratorIterable implements IZenIterator { @Override public void compileEnd() { - // pop iterator methodOutput.pop(); } } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java b/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java index 8b314a4..006a589 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/util/MethodOutput.java @@ -182,6 +182,10 @@ public class MethodOutput { visitor.visitTypeInsn(CHECKCAST, signature(newClass)); } + public void checkCast(String newClass) { + visitor.visitTypeInsn(CHECKCAST, newClass.substring(1, newClass.length() - 1)); + } + public void iNeg() { visitor.visitInsn(INEG); } diff --git a/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java b/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java index 37e249f..28cf15e 100644 --- a/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java +++ b/ZenScript/src/main/java/stanhebben/zenscript/util/StringUtil.java @@ -25,7 +25,7 @@ public class StringUtil { if (first) { first = false; } else { - result.append('.'); + result.append(separator); } result.append(value); } @@ -189,7 +189,8 @@ public class StringUtil { * @return */ public static String unescapeString(String oldstr) { - if (oldstr.charAt(0) != '"' || oldstr.charAt(oldstr.length() - 1) != '"') { + if ((oldstr.charAt(0) != '"' || oldstr.charAt(oldstr.length() - 1) != '"') + && (oldstr.charAt(0) != '\'' || oldstr.charAt(oldstr.length() - 1) != '\'')) { // TODO: error //throw new TweakerExecuteException("Not a valid string constant: " // + oldstr);