ForgePatch/fml/common/cpw/mods/fml/common/FMLCommonHandler.java

396 lines
11 KiB
Java
Raw Normal View History

2012-03-30 14:11:13 +00:00
/*
* The FML Forge Mod Loader suite.
2012-03-30 14:11:13 +00:00
* Copyright (C) 2012 cpw
*
2012-03-30 14:11:13 +00:00
* 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.
*
2012-03-30 14:11:13 +00:00
* 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.
*
2012-03-30 14:11:13 +00:00
* 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.common;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
2012-05-07 05:39:55 +00:00
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
2012-04-03 21:04:26 +00:00
import java.util.HashMap;
2012-05-07 05:39:55 +00:00
import java.util.List;
2012-04-03 21:04:26 +00:00
import java.util.Map;
2012-05-05 23:52:53 +00:00
import java.util.Properties;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.DedicatedServer;
2012-08-09 05:58:14 +00:00
import net.minecraft.src.Entity;
import net.minecraft.src.EntityPlayer;
2012-08-09 05:58:14 +00:00
import net.minecraft.src.World;
2012-07-24 01:20:37 +00:00
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
2012-07-24 01:20:37 +00:00
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.Lists;
2012-07-22 14:26:38 +00:00
import cpw.mods.fml.common.discovery.ContainerType;
2012-08-09 12:40:32 +00:00
import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
2012-08-09 05:58:14 +00:00
import cpw.mods.fml.common.network.EntitySpawnPacket;
2012-07-23 19:03:17 +00:00
import cpw.mods.fml.common.registry.TickRegistry;
2012-07-24 01:20:37 +00:00
import cpw.mods.fml.common.registry.GameRegistry;
2012-07-22 14:26:38 +00:00
2012-05-07 05:39:55 +00:00
/**
* The main class for non-obfuscated hook handling code
*
* Anything that doesn't require obfuscated or client/server specific code should
* go in this handler
*
* It also contains a reference to the sided handler instance that is valid
* allowing for common code to access specific properties from the obfuscated world
* without a direct dependency
*
* @author cpw
*
*/
public class FMLCommonHandler
{
/**
* The singleton
*/
private static final FMLCommonHandler INSTANCE = new FMLCommonHandler();
/**
* The delegate for side specific data and functions
*/
private IFMLSidedHandler sidedDelegate;
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
public void beginLoading(IFMLSidedHandler handler)
{
sidedDelegate = handler;
2012-07-23 19:03:17 +00:00
FMLLog.info("Attempting early MinecraftForge initialization");
callForgeMethod("initialize");
2012-07-23 19:03:17 +00:00
FMLLog.info("Completed early MinecraftForge initialization");
}
public void rescheduleTicks(Side side)
{
sidedDelegate.profileStart("modTickScheduling");
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
sidedDelegate.profileEnd();
}
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
{
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
if (scheduledTicks.size()==0)
{
return;
}
sidedDelegate.profileStart("modTickStart$"+ticks);
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
ticksToRun.removeAll(EnumSet.complementOf(ticks));
if (!ticksToRun.isEmpty())
{
sidedDelegate.profileStart(ticker.getLabel());
ticker.tickStart(ticksToRun, data);
sidedDelegate.profileEnd();
}
}
sidedDelegate.profileEnd();
2012-05-07 05:39:55 +00:00
}
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
2012-05-07 05:39:55 +00:00
{
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
if (scheduledTicks.size()==0)
{
return;
}
sidedDelegate.profileStart("modTickEnd$"+ticks);
for (IScheduledTickHandler ticker : scheduledTicks)
{
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
ticksToRun.removeAll(EnumSet.complementOf(ticks));
if (!ticksToRun.isEmpty())
{
sidedDelegate.profileStart(ticker.getLabel());
ticker.tickEnd(ticksToRun, data);
sidedDelegate.profileEnd();
}
}
sidedDelegate.profileEnd();
}
/**
* @return the instance
*/
public static FMLCommonHandler instance()
{
return INSTANCE;
2012-03-30 14:11:13 +00:00
}
/**
* Find the container that associates with the supplied mod object
* @param mod
* @return
*/
public ModContainer findContainerFor(Object mod)
{
return Loader.instance().getReversedModObjectList().get(mod);
}
/**
* Get the forge mod loader logging instance (goes to the forgemodloader log file)
* @return
*/
public Logger getFMLLogger()
{
return FMLLog.getLogger();
}
2012-05-05 23:52:53 +00:00
/**
* @param key
* @param lang
* @param value
*/
/**
* @param languagePack
* @param lang
*/
2012-05-06 04:58:40 +00:00
public Side getSide()
2012-05-07 04:54:18 +00:00
{
return sidedDelegate.getSide();
2012-05-07 04:54:18 +00:00
}
/**
* Raise an exception
*
* @param exception
* @param message
* @param stopGame
*/
public void raiseException(Throwable exception, String message, boolean stopGame)
2012-05-07 05:39:55 +00:00
{
FMLCommonHandler.instance().getFMLLogger().throwing("FMLHandler", "raiseException", exception);
if (stopGame)
{
getSidedDelegate().haltGame(message,exception);
}
2012-05-07 05:39:55 +00:00
}
private Class<?> forge;
private boolean noForge;
2012-07-24 01:20:37 +00:00
private List<String> brandings;
private Class<?> findMinecraftForge()
{
if (forge==null && !noForge)
{
try {
forge = Class.forName("net.minecraftforge.common.MinecraftForge");
} catch (Exception ex) {
noForge = true;
}
}
return forge;
}
private Object callForgeMethod(String method)
{
if (noForge)
return null;
try
{
return findMinecraftForge().getMethod(method).invoke(null);
}
catch (Exception e)
{
// No Forge installation
return null;
}
}
/**
* @param string
* @return
*/
2012-07-24 01:20:37 +00:00
public void computeBranding()
{
2012-07-24 01:20:37 +00:00
if (brandings == null)
{
2012-07-24 01:20:37 +00:00
Builder brd = ImmutableList.<String>builder();
2012-07-31 02:31:07 +00:00
brd.add(Loader.instance().getMCVersionString());
2012-07-24 01:20:37 +00:00
brd.add(Loader.instance().getFMLVersionString());
brd.addAll(sidedDelegate.getAdditionalBrandingInformation());
try {
Properties props=new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties"));
brd.add(props.getProperty("fmlbranding"));
} catch (Exception ex) {
// Ignore - no branding file found
}
int tModCount = Loader.instance().getModList().size();
int aModCount = Loader.instance().getActiveModList().size();
brd.add(String.format("%d mod%s loaded, %d mod%s active", tModCount, tModCount!=1 ? "s" :"", aModCount, aModCount!=1 ? "s" :"" ));
brandings = brd.build();
}
2012-07-24 01:20:37 +00:00
}
public List<String> getBrandings()
{
if (brandings == null)
{
computeBranding();
}
2012-07-24 01:20:37 +00:00
return ImmutableList.copyOf(brandings);
}
2012-06-01 02:09:45 +00:00
/**
* @return
*/
public IFMLSidedHandler getSidedDelegate()
{
return sidedDelegate;
}
2012-07-06 14:29:17 +00:00
public void onPostServerTick()
{
tickEnd(EnumSet.of(TickType.SERVER), Side.SERVER);
2012-07-06 14:29:17 +00:00
}
/**
* Every tick just after world and other ticks occur
*/
public void onPostWorldTick(Object world)
{
tickEnd(EnumSet.of(TickType.WORLD), Side.SERVER, world);
2012-07-06 14:29:17 +00:00
}
public void onPreServerTick()
{
tickStart(EnumSet.of(TickType.SERVER), Side.SERVER);
2012-07-06 14:29:17 +00:00
}
/**
* Every tick just before world and other ticks occur
*/
public void onPreWorldTick(Object world)
{
tickStart(EnumSet.of(TickType.WORLD), Side.SERVER, world);
2012-07-06 14:29:17 +00:00
}
public void onWorldLoadTick(World[] worlds)
2012-07-06 02:31:46 +00:00
{
rescheduleTicks(Side.SERVER);
for (World w : worlds)
{
tickStart(EnumSet.of(TickType.WORLDLOAD), Side.SERVER, w);
}
2012-07-06 02:31:46 +00:00
}
public void handleServerStarting(MinecraftServer server)
{
Loader.instance().serverStarting(server);
}
public void handleServerStarted()
{
Loader.instance().serverStarted();
}
public void handleServerStopping()
{
Loader.instance().serverStopping();
}
2012-08-02 19:20:30 +00:00
public MinecraftServer getMinecraftServerInstance()
{
//TODO
return null;
}
2012-08-08 04:31:24 +00:00
public void showGuiScreen(Object clientGuiElement)
{
sidedDelegate.showGuiScreen(clientGuiElement);
}
2012-08-09 05:58:14 +00:00
public Entity spawnEntityIntoClientWorld(Class<? extends Entity> cls, EntitySpawnPacket entitySpawnPacket)
{
return sidedDelegate.spawnEntityIntoClientWorld(cls, entitySpawnPacket);
}
2012-08-09 12:40:32 +00:00
public void adjustEntityLocationOnClient(EntitySpawnAdjustmentPacket entitySpawnAdjustmentPacket)
{
sidedDelegate.adjustEntityLocationOnClient(entitySpawnAdjustmentPacket);
}
public void onServerStart(DedicatedServer dedicatedServer)
{
try
{
// Done this way so that the client doesn't depend on server side handler
Class<?> cls = Class.forName("cpw.mods.fml.server.FMLServerHandler", true, getClass().getClassLoader());
}
catch (ClassNotFoundException e)
{
FMLLog.log(Level.SEVERE, e, "Unable to load the FML server handler");
throw Throwables.propagate(e);
}
sidedDelegate.beginServerLoading(dedicatedServer);
}
public void onServerStarted()
{
sidedDelegate.finishServerLoading();
}
public void onPreClientTick()
{
tickStart(EnumSet.of(TickType.CLIENT), Side.CLIENT);
}
public void onPostClientTick()
{
tickEnd(EnumSet.of(TickType.CLIENT), Side.CLIENT);
}
public void onRenderTickStart(float timer)
{
tickStart(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
}
public void onRenderTickEnd(float timer)
{
tickEnd(EnumSet.of(TickType.RENDER), Side.CLIENT, timer);
}
public void onPlayerPreTick(EntityPlayer player)
{
tickStart(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
}
public void onPlayerPostTick(EntityPlayer player)
{
tickEnd(EnumSet.of(TickType.PLAYER), Side.SERVER, player);
}
2012-03-30 14:11:13 +00:00
}