From b2e01d8f2a0fa35c4b79709ea8c9578e499c9539 Mon Sep 17 00:00:00 2001 From: Christian Weeks Date: Sat, 14 Apr 2012 23:01:03 -0400 Subject: [PATCH] Bukkit version --- .../cpw/mods/fml/server/FMLBukkitHandler.java | 487 ++++++++++++++ .../fml/server/ModLoaderModContainer.java | 522 +++++++++++++++ fml/bukkit/net/minecraft/server/BaseMod.java | 325 +++++++++ .../net/minecraft/server/BukkitRegistry.java | 147 +++++ fml/bukkit/net/minecraft/server/MLProp.java | 48 ++ .../net/minecraft/server/ModLoader.java | 617 ++++++++++++++++++ 6 files changed, 2146 insertions(+) create mode 100644 fml/bukkit/cpw/mods/fml/server/FMLBukkitHandler.java create mode 100644 fml/bukkit/cpw/mods/fml/server/ModLoaderModContainer.java create mode 100644 fml/bukkit/net/minecraft/server/BaseMod.java create mode 100644 fml/bukkit/net/minecraft/server/BukkitRegistry.java create mode 100644 fml/bukkit/net/minecraft/server/MLProp.java create mode 100644 fml/bukkit/net/minecraft/server/ModLoader.java diff --git a/fml/bukkit/cpw/mods/fml/server/FMLBukkitHandler.java b/fml/bukkit/cpw/mods/fml/server/FMLBukkitHandler.java new file mode 100644 index 000000000..a48abb229 --- /dev/null +++ b/fml/bukkit/cpw/mods/fml/server/FMLBukkitHandler.java @@ -0,0 +1,487 @@ +/* + * The FML Forge Mod Loader suite. Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package cpw.mods.fml.server; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Random; +import java.util.logging.Logger; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.BaseMod; +import net.minecraft.server.BiomeBase; +import net.minecraft.server.CommonRegistry; +import net.minecraft.server.EntityItem; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.IChunkProvider; +import net.minecraft.server.ICommandListener; +import net.minecraft.server.IInventory; +import net.minecraft.server.ItemStack; +import net.minecraft.server.NetworkManager; +import net.minecraft.server.Packet1Login; +import net.minecraft.server.Packet250CustomPayload; +import net.minecraft.server.Packet3Chat; +import net.minecraft.server.BukkitRegistry; +import net.minecraft.server.World; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.IFMLSidedHandler; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ModContainer; + +/** + * Handles primary communication from hooked code into the system + * + * The FML entry point is {@link #onPreLoad(MinecraftServer)} called from {@link MinecraftServer} + * + * Obfuscated code should focus on this class and other members of the "server" (or "client") code + * + * The actual mod loading is handled at arms length by {@link Loader} + * + * It is expected that a similar class will exist for each target environment: Bukkit and Client side. + * + * It should not be directly modified. + * + * @author cpw + * + */ +public class FMLBukkitHandler implements IFMLSidedHandler +{ + /** + * The singleton + */ + private static final FMLBukkitHandler INSTANCE = new FMLBukkitHandler(); + + /** + * A reference to the server itself + */ + private MinecraftServer server; + + /** + * A handy list of the default overworld biomes + */ + private BiomeBase[] defaultOverworldBiomes; + + /** + * Called to start the whole game off from {@link MinecraftServer#startServer} + * @param minecraftServer + */ + public void onPreLoad(MinecraftServer minecraftServer) + { + server = minecraftServer; + FMLCommonHandler.instance().registerSidedDelegate(this); + CommonRegistry.registerRegistry(new BukkitRegistry()); + Loader.instance().loadMods(); + } + + /** + * Called a bit later on during server initialization to finish loading mods + */ + public void onLoadComplete() + { + Loader.instance().initializeMods(); + } + + /** + * Every tick just before world and other ticks occur + */ + public void onPreTick() + { + FMLCommonHandler.instance().gameTickStart(); + } + + /** + * Every tick just after world and other ticks occur + */ + public void onPostTick() + { + FMLCommonHandler.instance().gameTickEnd(); + } + + /** + * Get the server instance + * @return + */ + public MinecraftServer getServer() + { + return server; + } + + /** + * Get a handle to the server's logger instance + */ + public Logger getMinecraftLogger() + { + return MinecraftServer.log; + } + + /** + * Called from ChunkProviderServer when a chunk needs to be populated + * + * To avoid polluting the worldgen seed, we generate a new random from the world seed and + * generate a seed from that + * + * @param chunkProvider + * @param chunkX + * @param chunkZ + * @param world + * @param generator + */ + public void onChunkPopulate(IChunkProvider chunkProvider, int chunkX, int chunkZ, World world, IChunkProvider generator) + { + Random fmlRandom = new Random(world.getSeed()); + long xSeed = fmlRandom.nextLong() >> 2 + 1L; + long zSeed = fmlRandom.nextLong() >> 2 + 1L; + fmlRandom.setSeed((xSeed * chunkX + zSeed * chunkZ) ^ world.getSeed()); + + for (ModContainer mod : Loader.getModList()) + { + if (mod.generatesWorld()) + { + mod.getWorldGenerator().generate(fmlRandom, chunkX, chunkZ, world, generator, chunkProvider); + } + } + } + + /** + * Called from the furnace to lookup fuel values + * + * @param itemId + * @param itemDamage + * @return + */ + public int fuelLookup(int itemId, int itemDamage) + { + int fv = 0; + + for (ModContainer mod : Loader.getModList()) + { + fv = Math.max(fv, mod.lookupFuelValue(itemId, itemDamage)); + } + + return fv; + } + + /** + * Is the offered class and instance of BaseMod and therefore a ModLoader mod? + */ + public boolean isModLoaderMod(Class clazz) + { + return BaseMod.class.isAssignableFrom(clazz); + } + + /** + * Load the supplied mod class into a mod container + */ + public ModContainer loadBaseModMod(Class clazz, String canonicalPath) + { + @SuppressWarnings("unchecked") + Class bmClazz = (Class ) clazz; + return new ModLoaderModContainer(bmClazz, canonicalPath); + } + + /** + * Called to notify that an item was picked up from the world + * @param entityItem + * @param entityPlayer + */ + public void notifyItemPickup(EntityItem entityItem, EntityHuman entityPlayer) + { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsPickupNotification()) + { + mod.getPickupNotifier().notifyPickup(entityItem, entityPlayer); + } + } + } + + /** + * Raise an exception + * @param exception + * @param message + * @param stopGame + */ + public void raiseException(Throwable exception, String message, boolean stopGame) + { + FMLCommonHandler.instance().getFMLLogger().throwing("FMLHandler", "raiseException", exception); + throw new RuntimeException(exception); + } + + /** + * Attempt to dispense the item as an entity other than just as a the item itself + * + * @param world + * @param x + * @param y + * @param z + * @param xVelocity + * @param zVelocity + * @param item + * @return + */ + public boolean tryDispensingEntity(World world, double x, double y, double z, byte xVelocity, byte zVelocity, ItemStack item) + { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsToDispense() && mod.getDispenseHandler().dispense(x, y, z, xVelocity, zVelocity, world, item)) + { + return true; + } + } + + return false; + } + + /** + * @return the instance + */ + public static FMLBukkitHandler instance() + { + return INSTANCE; + } + + /** + * Build a list of default overworld biomes + * @return + */ + public BiomeBase[] getDefaultOverworldBiomes() + { + if (defaultOverworldBiomes == null) + { + ArrayList biomes = new ArrayList(20); + + for (int i = 0; i < 23; i++) + { + if ("Sky".equals(BiomeBase.biomes[i].y) || "Hell".equals(BiomeBase.biomes[i].y)) + { + continue; + } + + biomes.add(BiomeBase.biomes[i]); + } + + defaultOverworldBiomes = new BiomeBase[biomes.size()]; + biomes.toArray(defaultOverworldBiomes); + } + + return defaultOverworldBiomes; + } + + /** + * Called when an item is crafted + * @param player + * @param craftedItem + * @param craftingGrid + */ + public void onItemCrafted(EntityHuman player, ItemStack craftedItem, IInventory craftingGrid) + { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsCraftingNotification()) + { + mod.getCraftingHandler().onCrafting(player, craftedItem, craftingGrid); + } + } + } + + /** + * Called when an item is smelted + * + * @param player + * @param smeltedItem + */ + public void onItemSmelted(EntityHuman player, ItemStack smeltedItem) + { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsCraftingNotification()) + { + mod.getCraftingHandler().onSmelting(player, smeltedItem); + } + } + } + + /** + * Called when a chat packet is received + * + * @param chat + * @param player + * @return true if you want the packet to stop processing and not echo to the rest of the world + */ + public boolean handleChatPacket(Packet3Chat chat, EntityHuman player) + { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsNetworkPackets() && mod.getNetworkHandler().onChat(chat, player)) + { + return true; + } + } + + return false; + } + + /** + * Called when a packet 250 packet is received from the player + * @param packet + * @param player + */ + public void handlePacket250(Packet250CustomPayload packet, EntityHuman player) + { + if ("REGISTER".equals(packet.tag) || "UNREGISTER".equals(packet.tag)) + { + handleClientRegistration(packet, player); + return; + } + + ModContainer mod = FMLCommonHandler.instance().getModForChannel(packet.tag); + + if (mod != null) + { + mod.getNetworkHandler().onPacket250Packet(packet, player); + } + } + + /** + * Handle register requests for packet 250 channels + * @param packet + */ + private void handleClientRegistration(Packet250CustomPayload packet, EntityHuman player) + { + if (packet.data==null) { + return; + } + try + { + for (String channel : new String(packet.data, "UTF8").split("\0")) + { + // Skip it if we don't know it + if (FMLCommonHandler.instance().getModForChannel(channel) == null) + { + continue; + } + + if ("REGISTER".equals(packet.tag)) + { + FMLCommonHandler.instance().activateChannel(player, channel); + } + else + { + FMLCommonHandler.instance().deactivateChannel(player, channel); + } + } + } + catch (UnsupportedEncodingException e) + { + getMinecraftLogger().warning("Received invalid registration packet"); + } + } + + /** + * Handle a login + * @param loginPacket + * @param networkManager + */ + public void handleLogin(Packet1Login loginPacket, NetworkManager networkManager) + { + Packet250CustomPayload packet = new Packet250CustomPayload(); + packet.tag = "REGISTER"; + packet.data = FMLCommonHandler.instance().getPacketRegistry(); + packet.length = packet.data.length; + if (packet.length>0) { + networkManager.queue(packet); + } + } + + public void announceLogin(EntityHuman player) { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsPlayerTracking()) + { + mod.getPlayerTracker().onPlayerLogin(player); + } + } + } + /** + * Are we a server? + */ + @Override + public boolean isServer() + { + return true; + } + + /** + * Are we a client? + */ + @Override + public boolean isClient() + { + return false; + } + + @Override + public File getMinecraftRootDirectory() + { + try { + return server.a(".").getCanonicalFile(); + } catch (IOException ioe) { + return new File("."); + } + } + + /** + * @param var2 + * @return + */ + public boolean handleServerCommand(String command, String player, ICommandListener listener) + { + for (ModContainer mod : Loader.getModList()) { + if (mod.wantsConsoleCommands() && mod.getConsoleHandler().handleCommand(command, player, listener)) { + return true; + } + } + return false; + } + + /** + * @param player + */ + public void announceLogout(EntityHuman player) + { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsPlayerTracking()) + { + mod.getPlayerTracker().onPlayerLogout(player); + } + } + } + + /** + * @param p_28168_1_ + */ + public void announceDimensionChange(EntityHuman player) + { + for (ModContainer mod : Loader.getModList()) + { + if (mod.wantsPlayerTracking()) + { + mod.getPlayerTracker().onPlayerChangedDimension(player); + } + } + } +} diff --git a/fml/bukkit/cpw/mods/fml/server/ModLoaderModContainer.java b/fml/bukkit/cpw/mods/fml/server/ModLoaderModContainer.java new file mode 100644 index 000000000..7dc41121f --- /dev/null +++ b/fml/bukkit/cpw/mods/fml/server/ModLoaderModContainer.java @@ -0,0 +1,522 @@ +/* + * The FML Forge Mod Loader suite. + * Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package cpw.mods.fml.server; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; + +import net.minecraft.server.BaseMod; +import net.minecraft.server.MLProp; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.IConsoleHandler; +import cpw.mods.fml.common.ICraftingHandler; +import cpw.mods.fml.common.IDispenseHandler; +import cpw.mods.fml.common.INetworkHandler; +import cpw.mods.fml.common.IPickupNotifier; +import cpw.mods.fml.common.IPlayerTracker; +import cpw.mods.fml.common.IWorldGenerator; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.LoaderException; +import cpw.mods.fml.common.ModContainer; + +public class ModLoaderModContainer implements ModContainer +{ + private Class modClazz; + private BaseMod mod; + private boolean isTicking; + private String modSource ; + private ArrayList dependencies; + private ArrayList preDependencies; + private ArrayList postDependencies; + public ModLoaderModContainer(Class modClazz, String modSource) + { + this.modClazz = modClazz; + this.modSource = modSource; + } + + @Override + public boolean wantsPreInit() + { + return true; + } + + @Override + public boolean wantsPostInit() + { + return true; + } + + @Override + public void preInit() + { + try + { + configureMod(); + mod = modClazz.newInstance(); + } + catch (Exception e) + { + throw new LoaderException(e); + } + } + + /** + * + */ + private void configureMod() + { + File configDir = Loader.instance().getConfigDir(); + File modConfig = new File(configDir, String.format("%s.cfg", modClazz.getSimpleName())); + Properties props = new Properties(); + + if (modConfig.exists()) + { + try + { + FileReader configReader = new FileReader(modConfig); + props.load(configReader); + configReader.close(); + } + catch (Exception e) + { + Loader.log.severe(String.format("Error occured reading mod configuration file %s", modConfig.getName())); + Loader.log.throwing("ModLoaderModContainer", "configureMod", e); + throw new LoaderException(e); + } + } + + StringBuffer comments = new StringBuffer(); + comments.append("MLProperties: name (type:default) min:max -- information\n"); + + try + { + for (Field f : modClazz.getDeclaredFields()) + { + if (!Modifier.isStatic(f.getModifiers())) + { + continue; + } + + if (!f.isAnnotationPresent(MLProp.class)) + { + continue; + } + + MLProp property = f.getAnnotation(MLProp.class); + String propertyName = property.name().length() > 0 ? property.name() : f.getName(); + String propertyValue = null; + Object defaultValue = null; + + try + { + defaultValue = f.get(null); + propertyValue = props.getProperty(propertyName, extractValue(defaultValue)); + Object currentValue = parseValue(propertyValue, property, f.getType()); + + if (currentValue != null && !currentValue.equals(defaultValue)) + { + f.set(null, currentValue); + } + } + catch (Exception e) + { + Loader.log.severe(String.format("Invalid configuration found for %s in %s", propertyName, modConfig.getName())); + Loader.log.throwing("ModLoaderModContainer", "configureMod", e); + throw new LoaderException(e); + } + finally + { + comments.append(String.format("MLProp : %s (%s:%s", propertyName, f.getType().getName(), defaultValue)); + + if (property.min() != Double.MIN_VALUE) + { + comments.append(",>=").append(String.format("%.1f", property.min())); + } + + if (property.max() != Double.MAX_VALUE) + { + comments.append(",<=").append(String.format("%.1f", property.max())); + } + + comments.append(")"); + + if (property.info().length() > 0) + { + comments.append(" -- ").append(property.info()); + } + + if (propertyValue != null) + { + props.setProperty(propertyName, extractValue(propertyValue)); + } + } + } + } + finally + { + try + { + FileWriter configWriter = new FileWriter(modConfig); + props.store(configWriter, comments.toString()); + configWriter.close(); + } + catch (IOException e) + { + Loader.log.warning(String.format("Error trying to write the config file %s", modConfig.getName())); + Loader.log.throwing("ModLoaderModContainer", "configureMod", e); + throw new LoaderException(e); + } + } + } + + private Object parseValue(String val, MLProp property, Class type) + { + if (type.isAssignableFrom(String.class)) + { + return (String)val; + } + else if (type.isAssignableFrom(Boolean.TYPE) || type.isAssignableFrom(Boolean.class)) + { + return Boolean.parseBoolean(val); + } + else if (Number.class.isAssignableFrom(type)) + { + Number n = null; + + if (Double.class.isAssignableFrom(type)) + { + n = Double.parseDouble(val); + } + if (Float.class.isAssignableFrom(type)) + { + n = Float.parseFloat(val); + } + if (Long.class.isAssignableFrom(type)) + { + n = Long.parseLong(val); + } + if (Integer.class.isAssignableFrom(type)) + { + n = Integer.parseInt(val); + } + if (Short.class.isAssignableFrom(type)) + { + n = Short.parseShort(val); + } + if (Byte.class.isAssignableFrom(type)) + { + n = Byte.parseByte(val); + } + else + { + throw new IllegalArgumentException("MLProp declared on non-standard type"); + } + + if (n.doubleValue() < property.min() || n.doubleValue() > property.max()) + { + return null; + } + else + { + return n; + } + } + + return null; + } + private String extractValue(Object value) + { + if (String.class.isInstance(value)) + { + return (String)value; + } + else if (Number.class.isInstance(value) || Boolean.class.isInstance(value)) + { + return String.valueOf(value); + } + else + { + throw new IllegalArgumentException("MLProp declared on non-standard type"); + } + } + @Override + public void init() + { + mod.load(); + } + + @Override + public void postInit() + { + mod.modsLoaded(); + } + + @Override + public void tickStart() + { + if (isTicking) + { + isTicking = mod.onTickInGame(FMLBukkitHandler.instance().getServer()); + } + } + @Override + public void tickEnd() + { + // NOOP for modloader + } + + @Override + public String getName() + { + return mod != null ? mod.getName() : null; + } + + public static ModContainer findContainerFor(BaseMod mod) + { + for (ModContainer mc : Loader.getModList()) + { + if (mc.matches(mod)) + { + return mc; + } + } + + return null; + } + + @Override + public boolean matches(Object mod) + { + return modClazz.isInstance(mod); + } + + public void setTicking(boolean enable) + { + isTicking = enable; + } + + /** + * Find all the BaseMods in the system + * @return + */ + public static List findAll() + { + ArrayList modList = new ArrayList(); + + for (ModContainer mc : Loader.getModList()) + { + if (mc instanceof ModLoaderModContainer) + { + modList.add(((ModLoaderModContainer)mc).mod); + } + } + + return modList; + } + + @Override + public String getSource() + { + return modSource; + } + + @Override + public Object getMod() + { + return mod; + } + + @Override + public boolean generatesWorld() + { + return true; + } + + @Override + public IWorldGenerator getWorldGenerator() + { + return mod; + } + + @Override + public int lookupFuelValue(int itemId, int itemDamage) + { + return mod.addFuel(itemId, itemDamage); + } + + @Override + public boolean wantsPickupNotification() + { + return true; + } + + @Override + public IPickupNotifier getPickupNotifier() + { + return mod; + } + + @Override + public boolean wantsToDispense() + { + return true; + } + + @Override + public IDispenseHandler getDispenseHandler() + { + return mod; + } + + @Override + public boolean wantsCraftingNotification() + { + return true; + } + + @Override + public ICraftingHandler getCraftingHandler() + { + return mod; + } + + private void computeDependencies() + { + dependencies = new ArrayList(); + preDependencies = new ArrayList(); + postDependencies = new ArrayList(); + + if (mod.getPriorities() == null || mod.getPriorities().length() == 0) + { + return; + } + + StringTokenizer st = new StringTokenizer(mod.getPriorities(), ";"); + + for (; st.hasMoreTokens();) + { + String dep = st.nextToken(); + String[] depparts = dep.split(":"); + + if (depparts.length < 2) + { + throw new LoaderException(); + } + + if ("required-before".equals(depparts[0]) || "required-after".equals(depparts[0])) + { + dependencies.add(depparts[1]); + } + + if ("required-before".equals(depparts[0]) || "before".equals(depparts[0])) + { + postDependencies.add(depparts[1]); + } + + if ("required-after".equals(depparts[0]) || "after".equals(depparts[0])) + { + preDependencies.add(depparts[1]); + } + + } + } + + @Override + public List getDependencies() + { + if (dependencies == null) + { + computeDependencies(); + } + + return dependencies; + } + + @Override + public List getPostDepends() + { + if (dependencies == null) + { + computeDependencies(); + } + + return postDependencies; + } + + @Override + public List getPreDepends() + { + if (dependencies == null) + { + computeDependencies(); + } + return preDependencies; + } + + + public String toString() + { + return modSource; + } + + @Override + public boolean wantsNetworkPackets() + { + return true; + } + + @Override + public INetworkHandler getNetworkHandler() + { + return mod; + } + + @Override + public boolean ownsNetworkChannel(String channel) + { + return FMLCommonHandler.instance().getChannelListFor(this).contains(channel); + } + + @Override + public boolean wantsConsoleCommands() + { + return true; + } + + @Override + public IConsoleHandler getConsoleHandler() + { + return mod; + } + + @Override + public boolean wantsPlayerTracking() + { + return true; + } + + @Override + public IPlayerTracker getPlayerTracker() + { + return mod; + } +} diff --git a/fml/bukkit/net/minecraft/server/BaseMod.java b/fml/bukkit/net/minecraft/server/BaseMod.java new file mode 100644 index 000000000..c05136f75 --- /dev/null +++ b/fml/bukkit/net/minecraft/server/BaseMod.java @@ -0,0 +1,325 @@ +/* + * The FML Forge Mod Loader suite. Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraft.server; + +import java.util.Random; + +import cpw.mods.fml.common.IConsoleHandler; +import cpw.mods.fml.common.ICraftingHandler; +import cpw.mods.fml.common.IDispenseHandler; +import cpw.mods.fml.common.INetworkHandler; +import cpw.mods.fml.common.IPickupNotifier; +import cpw.mods.fml.common.IPlayerTracker; +import cpw.mods.fml.common.IWorldGenerator; + +public abstract class BaseMod implements IWorldGenerator, IPickupNotifier, IDispenseHandler, ICraftingHandler, INetworkHandler, IConsoleHandler, IPlayerTracker +{ + // CALLBACK MECHANISMS + @Override + public final void onCrafting(Object... craftingParameters) + { + takenFromCrafting((EntityPlayer)craftingParameters[0], (ItemStack)craftingParameters[1], (IInventory)craftingParameters[2]); + } + + @Override + public final void onSmelting(Object... smeltingParameters) + { + takenFromFurnace((EntityPlayer)smeltingParameters[0], (ItemStack)smeltingParameters[1]); + } + @Override + public final boolean dispense(double x, double y, double z, byte xVelocity, byte zVelocity, Object... data) + { + return dispenseEntity((World)data[0], x, y, z, xVelocity, zVelocity, (ItemStack)data[1]); + } + + @Override + public final boolean onChat(Object... data) + { + return onChatMessageReceived((EntityPlayer)data[1], (Packet3Chat)data[0]); + } + @Override + public final void onPlayerLogin(Object player) + { + onClientLogin((EntityPlayer) player); + } + + @Override + public void onPlayerLogout(Object player) + { + onClientLogout((EntityPlayer)player); + } + + @Override + public void onPlayerChangedDimension(Object player) + { + onClientDimensionChanged((EntityPlayer)player); + } + + @Override + public final void onPacket250Packet(Object... data) + { + onPacket250Received((EntityPlayer)data[1], (Packet250CustomPayload)data[0]); + } + + @Override + public final void notifyPickup(Object... pickupData) + { + EntityItem item = (EntityItem) pickupData[0]; + EntityPlayer player = (EntityPlayer) pickupData[1]; + onItemPickup(player, item.itemStack); + } + + @Override + public final void generate(Random random, int chunkX, int chunkZ, Object... additionalData) + { + World w = (World) additionalData[0]; + IChunkProvider cp = (IChunkProvider) additionalData[1]; + + if (cp instanceof ChunkProviderGenerate) + { + generateSurface(w, random, chunkX << 4, chunkZ << 4); + } + else if (cp instanceof ChunkProviderHell) + { + generateNether(w, random, chunkX << 4, chunkZ << 4); + } + } + + @Override + public final boolean handleCommand(String command, Object... data) + { + return onServerCommand(command, (String)data[0], (ICommandListener)data[1]); + } + // BASEMOD API + /** + * Override if you wish to provide a fuel item for the furnace and return the fuel value of the item + * @param id + * @param metadata + * @return + */ + public int addFuel(int id, int metadata) + { + return 0; + } + + /** + * Override if you wish to perform some action other than just dispensing the item from the dispenser + * @param world + * @param x + * @param y + * @param z + * @param xVel + * @param zVel + * @param item + * @return + */ + public boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item) + { + return false; + } + + /** + * Override if you wish to generate Nether (Hell biome) blocks + * @param world + * @param random + * @param chunkX + * @param chunkZ + */ + public void generateNether(World world, Random random, int chunkX, int chunkZ) + { + } + + /** + * Override if you wish to generate Overworld (not hell or the end) blocks + * @param world + * @param random + * @param chunkX + * @param chunkZ + */ + public void generateSurface(World world, Random random, int chunkX, int chunkZ) + { + } + + /** + * Return the name of your mod. Defaults to the class name + * @return + */ + public String getName() + { + return getClass().getSimpleName(); + } + + /** + * Get your mod priorities + * @return + */ + public String getPriorities() + { + return null; + } + + /** + * Return the version of your mod + * @return + */ + public abstract String getVersion(); + + /** + * Load your mod + */ + public abstract void load(); + + /** + * Finish loading your mod + */ + public void modsLoaded() + { + } + + /** + * Handle item pickup + * @param player + * @param item + */ + public void onItemPickup(EntityPlayer player, ItemStack item) + { + } + + /** + * Ticked every game tick if you have subscribed to tick events through {@link ModLoader#setInGameHook(BaseMod, boolean, boolean)} + * @param minecraftServer the server + * @return true to continue receiving ticks + */ + public boolean onTickInGame(MinecraftServer minecraftServer) + { + return false; + } + + /** + * Not implemented because on the server you don't know who it's from + * {@link #onChatMessageReceived(EntityPlayer, Packet3Chat)} + * @param text + */ + @Deprecated + public void receiveChatPacket(String text) + { + } + + /** + * Not implemented because on the server you don't know who it's from + * {@link #onPacket250Received(EntityPlayer, Packet250CustomPayload)} + * @param packet + */ + @Deprecated + public void receiveCustomPacket(Packet250CustomPayload packet) + { + } + + /** + * Called when someone crafts an item from a crafting table + * @param player + * @param item + * @param matrix + */ + public void takenFromCrafting(EntityPlayer player, ItemStack item, IInventory matrix) + { + } + + /** + * Called when someone takes a smelted item from a furnace + * + * @param player + * @param item + */ + public void takenFromFurnace(EntityPlayer player, ItemStack item) + { + } + + /** + * The identifier string for the mod- used in client<->server negotiation + */ + @Override + public String toString() + { + return getName() + " " + getVersion(); + } + + /** + * Called when a 250 packet is received on a channel registered to this mod + * + * @param source + * @param payload + */ + public void onPacket250Received(EntityPlayer source, Packet250CustomPayload payload) + { + } + + /** + * Called when a chat message is received. Return true to stop further processing + * @param source + * @param chat + * @return true if you want to consume the message so it is not available for further processing + */ + public boolean onChatMessageReceived(EntityPlayer source, Packet3Chat chat) + { + return false; + } + /** + * Called when a server command is received + * @param command + * @return true if you want to consume the message so it is not available for further processing + */ + public boolean onServerCommand(String command, String sender, ICommandListener listener) + { + return false; + } + + /** + * Called when a new client logs in. + * + * @param player + */ + public void onClientLogin(EntityPlayer player) + { + } + + /** + * Called when a client logs out of the server. + * + * @param player + */ + public void onClientLogout(EntityPlayer player) + { + + } + + /** + * + * Called when a client changes dimensions on the server. + * + * @param player + */ + public void onClientDimensionChanged(EntityPlayer player) + { + + } + + // Spare client junk + // ------- + // void addRenderer(Map, Render> renderers); + // void registerAnimation(Minecraft game); + // void renderInvBlock(RenderBlocks renderer, Block block, int metadata, int modelID); + // boolean renderWorldBlock(RenderBlocks renderer, IBlockAccess world, int x, int y, int z, Block block, int modelID); + // boolean onTickInGUI(float tick, Minecraft game, GuiScreen gui); + // void keyboardEvent(KeyBinding event); +} diff --git a/fml/bukkit/net/minecraft/server/BukkitRegistry.java b/fml/bukkit/net/minecraft/server/BukkitRegistry.java new file mode 100644 index 000000000..541fe66df --- /dev/null +++ b/fml/bukkit/net/minecraft/server/BukkitRegistry.java @@ -0,0 +1,147 @@ +package net.minecraft.server; + +import java.util.Collections; +import java.util.List; + +public class BukkitRegistry implements IMinecraftRegistry +{ + + @Override + public void addRecipe(ItemStack output, Object... params) + { + CraftingManager.getInstance().registerShapedRecipe(output, params); + } + + @Override + public void addShapelessRecipe(ItemStack output, Object... params) + { + CraftingManager.getInstance().registerShapelessRecipe(output, params); + } + + @Override + public void addSmelting(int input, ItemStack output) + { + FurnaceRecipes.getInstance().registerRecipe(input, output); + } + + @Override + public void registerBlock(Block block) + { + registerBlock(block, ItemBlock.class); + } + + @Override + public void registerBlock(Block block, Class itemclass) + { + try + { + assert block != null : "registerBlock: block cannot be null"; + assert itemclass != null : "registerBlock: itemclass cannot be null"; + int blockItemId = block.id - 256; + itemclass.getConstructor(int.class).newInstance(blockItemId); + } + catch (Exception e) + { + //HMMM + } + } + + @Override + public void registerEntityID(Class entityClass, String entityName, int id) + { + EntityTypes.addNewEntityListMapping(entityClass, entityName, id); + } + + @Override + public void registerEntityID(Class entityClass, String entityName, int id, int backgroundEggColour, int foregroundEggColour) + { + EntityTypes.addNewEntityListMapping(entityClass, entityName, id, backgroundEggColour, foregroundEggColour); + } + + @Override + public void registerTileEntity(Class tileEntityClass, String id) + { + TileEntity.addNewTileEntityMapping(tileEntityClass, id); + } + + @Override + public void addBiome(Object biome) + { + //NOOP because the implementation idea is broken. Creating a BiomeGenBase adds the biome already. + } + + @Override + public void addSpawn(Class entityClass, int weightedProb, int min, int max, EnumCreatureType typeOfCreature, Object... biomes) + { + BiomeBase[] realBiomes=(BiomeBase[]) biomes; + for (BiomeBase biome : realBiomes) + { + @SuppressWarnings("unchecked") + List spawns = biome.getMobs(typeOfCreature); + + for (BiomeMeta entry : spawns) + { + //Adjusting an existing spawn entry + if (entry.a == entityClass) + { + entry.d = weightedProb; + entry.b = min; + entry.c = max; + break; + } + } + + spawns.add(new BiomeMeta(entityClass, weightedProb, min, max)); + } + } + + @Override + @SuppressWarnings("unchecked") + public void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, Object... biomes) + { + Class entityClazz = EntityTypes.getEntityToClassMapping().get(entityName); + + if (EntityLiving.class.isAssignableFrom(entityClazz)) + { + addSpawn((Class ) entityClazz, weightedProb, min, max, spawnList, biomes); + } + } + + @Override + public void removeBiome(Object biome) + { + // NOOP because broken + } + + @Override + public void removeSpawn(Class entityClass, EnumCreatureType typeOfCreature, Object... biomesO) + { + BiomeBase[] biomes=(BiomeBase[]) biomesO; + for (BiomeBase biome : biomes) + { + @SuppressWarnings("unchecked") + List spawns = biome.getMobs(typeOfCreature); + + for (BiomeMeta entry : Collections.unmodifiableList(spawns)) + { + if (entry.a == entityClass) + { + spawns.remove(entry); + } + } + } + } + + @Override + @SuppressWarnings("unchecked") + public void removeSpawn(String entityName, EnumCreatureType spawnList, Object... biomes) + { + Class entityClazz = EntityTypes.getEntityToClassMapping().get(entityName); + + if (EntityLiving.class.isAssignableFrom(entityClazz)) + { + removeSpawn((Class ) entityClazz, spawnList, biomes); + } + } + +} diff --git a/fml/bukkit/net/minecraft/server/MLProp.java b/fml/bukkit/net/minecraft/server/MLProp.java new file mode 100644 index 000000000..25a20cbbd --- /dev/null +++ b/fml/bukkit/net/minecraft/server/MLProp.java @@ -0,0 +1,48 @@ +/* + * The FML Forge Mod Loader suite. Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraft.server; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.*; +import static java.lang.annotation.ElementType.*; + +/** + * @author cpw + * + */ +@Retention(value = RUNTIME) +@Target(value = FIELD) +public @interface MLProp +{ + /** + * Adds additional help to top of configuration file. + */ +String info() default ""; + + /** + * Maximum value allowed if field is a number. + */ +double max() default 1D; + + /** + * Minimum value allowed if field is a number. + */ +double min() default -1D; + + /** + * Overrides the field name for property key. + */ +String name() default ""; + +} diff --git a/fml/bukkit/net/minecraft/server/ModLoader.java b/fml/bukkit/net/minecraft/server/ModLoader.java new file mode 100644 index 000000000..aca6346a7 --- /dev/null +++ b/fml/bukkit/net/minecraft/server/ModLoader.java @@ -0,0 +1,617 @@ +/* + * The FML Forge Mod Loader suite. Copyright (C) 2012 cpw + * + * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraft.server; + +import java.util.List; +import java.util.logging.Logger; + +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ReflectionHelper; +import cpw.mods.fml.server.FMLBukkitHandler; +import cpw.mods.fml.server.ModLoaderModContainer; + +public class ModLoader +{ + /** + * Not used on the server. + * + * @param achievement + * @param name + * @param description + */ + public static void addAchievementDesc(Achievement achievement, String name, String description) + { + } + + /** + * This method is a call in hook from modified external code. Implemented elsewhere. + * + * {@link FMLBukkitHandler#fuelLookup(int, int)} + * @param id + * @param metadata + * @return + */ + @Deprecated + public static int addAllFuel(int id, int metadata) + { + return 0; + } + + /** + * This method is unimplemented in server versions to date. + * + * @param armor + * @return + */ + @Deprecated + public static int addArmor(String armor) + { + return 0; + } + + /** + * This method does not work. Creation of a BiomeGenBase is sufficient to populate this array. Using this method will likely corrupt worlds. + * + * @param biome + */ + @Deprecated + public static void addBiome(BiomeBase biome) + { + } + + /** + * Unimplemented on the server as it does not generate names + * @param key + * @param value + */ + @Deprecated + public static void addLocalization(String key, String value) + { + } + + /** + * Unimplemented on the server as it does not generate names + * @param key + * @param lang + * @param value + */ + @Deprecated + public static void addLocalization(String key, String lang, String value) + { + } + + /** + * Unimplemented on the server as it does not generate names + * @param instance + * @param name + */ + @Deprecated + public static void addName(Object instance, String name) + { + } + + /** + * Unimplemented on the server as it does not generate names + * @param instance + * @param lang + * @param name + */ + @Deprecated + public static void addName(Object instance, String lang, String name) + { + } + + /** + * Unimplemented on the server as it does not render textures + * @param fileToOverride + * @param fileToAdd + * @return + */ + @Deprecated + public static int addOverride(String fileToOverride, String fileToAdd) + { + return 0; + } + + /** + * Unimplemented on the server as it does not render textures + * @param path + * @param overlayPath + * @param index + */ + @Deprecated + public static void addOverride(String path, String overlayPath, int index) + { + } + + /** + * Add a Shaped Recipe + * @param output + * @param params + */ + public static void addRecipe(ItemStack output, Object... params) + { + CommonRegistry.addRecipe(output, params); + } + + /** + * Add a shapeless recipe + * @param output + * @param params + */ + public static void addShapelessRecipe(ItemStack output, Object... params) + { + CommonRegistry.addShapelessRecipe(output, params); + } + + /** + * Add a new product to be smelted + * @param input + * @param output + */ + public static void addSmelting(int input, ItemStack output) + { + CommonRegistry.addSmelting(input, output); + } + + /** + * Add a mob to the spawn list + * @param entityClass + * @param weightedProb + * @param min + * @param max + * @param spawnList + */ + public static void addSpawn(Class entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList) + { + CommonRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, FMLBukkitHandler.instance().getDefaultOverworldBiomes()); + } + + /** + * Add a mob to the spawn list + * @param entityClass + * @param weightedProb + * @param min + * @param max + * @param spawnList + * @param biomes + */ + public static void addSpawn(Class entityClass, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeBase... biomes) + { + CommonRegistry.addSpawn(entityClass, weightedProb, min, max, spawnList, biomes); + } + + /** + * Add a mob to the spawn list + * @param entityName + * @param weightedProb + * @param min + * @param max + * @param spawnList + */ + public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList) + { + CommonRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, FMLBukkitHandler.instance().getDefaultOverworldBiomes()); + } + + /** + * Add a mob to the spawn list + * @param entityName + * @param weightedProb + * @param min + * @param max + * @param spawnList + * @param biomes + */ + public static void addSpawn(String entityName, int weightedProb, int min, int max, EnumCreatureType spawnList, BiomeBase... biomes) + { + CommonRegistry.addSpawn(entityName, weightedProb, min, max, spawnList, biomes); + } + + /** + * This method is a call in hook from modified external code. Implemented elsewhere. + * {@link FMLBukkitHandler#tryDispensingEntity(World, double, double, double, byte, byte, ItemStack)} + * @param world + * @param x + * @param y + * @param z + * @param xVel + * @param zVel + * @param item + * @return + */ + @Deprecated + public static boolean dispenseEntity(World world, double x, double y, double z, int xVel, int zVel, ItemStack item) + { + return false; + } + + /** + * Remove a container and drop all the items in it on the ground around + * @param world + * @param x + * @param y + * @param z + */ + public static void genericContainerRemoval(World world, int x, int y, int z) + { + TileEntity te = world.getTileEntity(x, y, z); + + if (!(te instanceof IInventory)) + { + return; + } + + IInventory inv = (IInventory)te; + + for (int l = 0; l < inv.getSize(); l++) + { + ItemStack itemstack = inv.getItem(l); + + if (itemstack == null) + { + continue; + } + + float f = world.random.nextFloat() * 0.8F + 0.1F; + float f1 = world.random.nextFloat() * 0.8F + 0.1F; + float f2 = world.random.nextFloat() * 0.8F + 0.1F; + + while (itemstack.count > 0) + { + int i1 = world.random.nextInt(21) + 10; + + if (i1 > itemstack.count) + { + i1 = itemstack.count ; + } + + itemstack.count -= i1; + EntityItem entityitem = new EntityItem(world, (float)te.x + f, (float)te.y + f1, (float)te.z + f2, new ItemStack(itemstack.id, i1, itemstack.getData())); + float f3 = 0.05F; + entityitem.motX = (float)world.random.nextGaussian() * f3; + entityitem.motY = (float)world.random.nextGaussian() * f3 + 0.2F; + entityitem.motZ = (float)world.random.nextGaussian() * f3; + + if (itemstack.hasTag()) + { + entityitem.itemStack.setTag((NBTTagCompound)itemstack.getTag().clone()); + } + + world.addEntity(entityitem); + } + } + } + + /** + * Get a list of all BaseMod loaded into the system + * {@link ModLoaderModContainer#findAll} + * @return + */ + public static List getLoadedMods() + { + return ModLoaderModContainer.findAll(); + } + + /** + * Get a logger instance + * {@link FMLBukkitHandler#getFMLLogger()} + * @return + */ + public static Logger getLogger() + { + return FMLCommonHandler.instance().getFMLLogger(); + } + + /** + * Get a value from a field using reflection + * {@link ReflectionHelper#getPrivateValue(Class, Object, int)} + * @param instanceclass + * @param instance + * @param fieldindex + * @return + */ + public static T getPrivateValue(Class instanceclass, E instance, int fieldindex) + { + return ReflectionHelper.getPrivateValue(instanceclass, instance, fieldindex); + } + + /** + * Get a value from a field using reflection + * {@link ReflectionHelper#getPrivateValue(Class, Object, String)} + * @param instanceclass + * @param instance + * @param field + * @return + */ + public static T getPrivateValue(Class instanceclass, E instance, String field) + { + return ReflectionHelper.getPrivateValue(instanceclass, instance, field); + } + + /** + * Get a new unique entity id + * {@link Entity#getNextId()} + * @return + */ + public static int getUniqueEntityId() + { + return Entity.getNextId(); + } + + /** + * Is the named mod loaded? + * {@link Loader#isModLoaded(String)} + * @param modname + * @return + */ + public static boolean isModLoaded(String modname) + { + return Loader.isModLoaded(modname); + } + + /** + * This method is a call in hook from modified external code. Implemented elsewhere. + * {@link FMLBukkitHandler#handlePacket250(Packet250CustomPayload, EntityPlayer)} + * @param packet + */ + @Deprecated + public static void receivePacket(Packet250CustomPayload packet) + { + } + + /** + * Register a new block + * @param block + */ + public static void registerBlock(Block block) + { + CommonRegistry.registerBlock(block); + } + + /** + * Register a new block + * @param block + * @param itemclass + */ + public static void registerBlock(Block block, Class itemclass) + { + CommonRegistry.registerBlock(block, itemclass); + } + + /** + * Register a new entity ID + * @param entityClass + * @param entityName + * @param id + */ + public static void registerEntityID(Class entityClass, String entityName, int id) + { + CommonRegistry.registerEntityID(entityClass, entityName, id); + } + + /** + * Register a new entity ID + * @param entityClass + * @param entityName + * @param id + * @param background + * @param foreground + */ + public static void registerEntityID(Class entityClass, String entityName, int id, int background, int foreground) + { + CommonRegistry.registerEntityID(entityClass, entityName, id, background, foreground); + } + + /** + * Register the mod for packets on this channel. This only registers the channel with Forge Mod Loader, not + * with clients connecting- use BaseMod.onClientLogin to tell them about your custom channel + * {@link FMLCommonHandler#registerChannel(cpw.mods.fml.common.ModContainer, String)} + * @param mod + * @param channel + */ + public static void registerPacketChannel(BaseMod mod, String channel) + { + FMLCommonHandler.instance().registerChannel(ModLoaderModContainer.findContainerFor(mod), channel); + } + + /** + * Register a new tile entity class + * @param tileEntityClass + * @param id + */ + public static void registerTileEntity(Class tileEntityClass, String id) + { + CommonRegistry.registerTileEntity(tileEntityClass, id); + } + + /** + * Remove a biome. This code will probably not work correctly and will likely corrupt worlds. + * @param biome + */ + @Deprecated + public static void removeBiome(BiomeBase biome) + { + CommonRegistry.removeBiome(biome); + } + + /** + * Remove a spawn + * @param entityClass + * @param spawnList + */ + public static void removeSpawn(Class entityClass, EnumCreatureType spawnList) + { + CommonRegistry.removeSpawn(entityClass, spawnList, FMLBukkitHandler.instance().getDefaultOverworldBiomes()); + } + + /** + * Remove a spawn + * @param entityClass + * @param spawnList + * @param biomes + */ + public static void removeSpawn(Class entityClass, EnumCreatureType spawnList, BiomeBase... biomes) + { + CommonRegistry.removeSpawn(entityClass, spawnList, biomes); + } + + /** + * Remove a spawn + * @param entityName + * @param spawnList + */ + public static void removeSpawn(String entityName, EnumCreatureType spawnList) + { + CommonRegistry.removeSpawn(entityName, spawnList, FMLBukkitHandler.instance().getDefaultOverworldBiomes()); + } + + /** + * Remove a spawn + * @param entityName + * @param spawnList + * @param biomes + */ + public static void removeSpawn(String entityName, EnumCreatureType spawnList, BiomeBase... biomes) + { + CommonRegistry.removeSpawn(entityName, spawnList, biomes); + } + + /** + * Configuration is handled elsewhere + * {@link ModLoaderModContainer} + */ + @Deprecated + public static void saveConfig() + { + } + + /** + * This method is unimplemented on the server: it is meant for clients to send chat to the server + * {@link FMLBukkitHandler#handleChatPacket(Packet3Chat, EntityPlayer)} + * @param text + */ + @Deprecated + public static void serverChat(String text) + { + } + + /** + * Indicate that you want to receive ticks + * + * @param mod + * receiving the events + * @param enable + * indicates whether you want to recieve them or not + * @param useClock + * Not used in server side: all ticks are sent on the server side (no render subticks) + */ + public static void setInGameHook(BaseMod mod, boolean enable, boolean useClock) + { + ModLoaderModContainer mlmc = (ModLoaderModContainer) ModLoaderModContainer.findContainerFor(mod); + mlmc.setTicking(enable); + } + + /** + * Set a private field to a value using reflection + * {@link ReflectionHelper#setPrivateValue(Class, Object, int, Object)} + * @param instanceclass + * @param instance + * @param fieldindex + * @param value + */ + public static void setPrivateValue(Class instanceclass, T instance, int fieldindex, E value) + { + ReflectionHelper.setPrivateValue(instanceclass, instance, fieldindex, value); + } + + /** + * Set a private field to a value using reflection + * {@link ReflectionHelper#setPrivateValue(Class, Object, String, Object)} + * @param instanceclass + * @param instance + * @param field + * @param value + */ + public static void setPrivateValue(Class instanceclass, T instance, String field, E value) + { + ReflectionHelper.setPrivateValue(instanceclass, instance, field, value); + } + + /** + * This method is a call in hook from modified external code. Implemented elsewhere. + * {@link FMLBukkitHandler#onItemCrafted(EntityPlayer, ItemStack, IInventory)} + * @param player + * @param item + * @param matrix + */ + @Deprecated + public static void takenFromCrafting(EntityPlayer player, ItemStack item, IInventory matrix) + { + } + + /** + * This method is a call in hook from modified external code. Implemented elsewhere. + * {@link FMLBukkitHandler#onItemSmelted(EntityPlayer, ItemStack)} + * @param player + * @param item + */ + @Deprecated + public static void takenFromFurnace(EntityPlayer player, ItemStack item) + { + } + + /** + * Throw the offered exception. Likely will stop the game. + * {@link FMLBukkitHandler#raiseException(Throwable, String, boolean)} + * @param message + * @param e + */ + public static void throwException(String message, Throwable e) + { + FMLBukkitHandler.instance().raiseException(e, message, true); + } + + /** + * Get the minecraft server instance + * {@link FMLBukkitHandler#getServer()} + * @return + */ + public static MinecraftServer getMinecraftServerInstance() + { + return FMLBukkitHandler.instance().getServer(); + } + + /** + * To properly implement packet 250 protocol you should always check your channel + * is active prior to sending the packet + * + * @param player + * @param channel + * @return + */ + public static boolean isChannelActive(EntityPlayer player, String channel) + { + return FMLCommonHandler.instance().isChannelActive(channel, player); + } + + /** + * Stubbed method on the server to return a unique model id + * + */ + @Deprecated + public static int getUniqueBlockModelID(BaseMod mod, boolean flag) { + return 0; + } +} \ No newline at end of file