2012-03-30 14:11:13 +00:00
|
|
|
/*
|
2012-03-30 15:35:04 +00:00
|
|
|
* The FML Forge Mod Loader suite.
|
2012-03-30 14:11:13 +00:00
|
|
|
* Copyright (C) 2012 cpw
|
2012-04-05 14:07:52 +00:00
|
|
|
*
|
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-04-05 14:07:52 +00:00
|
|
|
*
|
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-04-05 14:07:52 +00:00
|
|
|
*
|
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
|
|
|
|
*/
|
2012-04-02 22:09:06 +00:00
|
|
|
package cpw.mods.fml.common;
|
|
|
|
|
2012-04-05 20:22:47 +00:00
|
|
|
import java.io.File;
|
2012-05-11 19:18:26 +00:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
2012-06-07 23:25:49 +00:00
|
|
|
import java.lang.reflect.InvocationTargetException;
|
2012-05-07 05:39:55 +00:00
|
|
|
import java.util.ArrayList;
|
2012-05-11 05:45:36 +00:00
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collections;
|
2012-06-07 17:53:16 +00:00
|
|
|
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;
|
2012-06-07 23:44:03 +00:00
|
|
|
import java.util.Random;
|
2012-08-09 13:21:16 +00:00
|
|
|
import java.util.logging.Level;
|
2012-04-05 15:34:57 +00:00
|
|
|
import java.util.logging.Logger;
|
2012-05-11 19:18:26 +00:00
|
|
|
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;
|
|
|
|
|
2012-08-02 04:38:30 +00:00
|
|
|
import net.minecraft.server.MinecraftServer;
|
2012-08-09 13:21:16 +00:00
|
|
|
import net.minecraft.src.DedicatedServer;
|
2012-08-09 05:58:14 +00:00
|
|
|
import net.minecraft.src.Entity;
|
2012-08-10 21:11:01 +00:00
|
|
|
import net.minecraft.src.EntityPlayer;
|
2012-08-09 05:58:14 +00:00
|
|
|
import net.minecraft.src.World;
|
2012-08-02 04:38:30 +00:00
|
|
|
|
2012-07-24 01:20:37 +00:00
|
|
|
import com.google.common.base.Strings;
|
2012-08-09 13:21:16 +00:00
|
|
|
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
|
|
|
|
2012-04-05 20:22:47 +00:00
|
|
|
/**
|
|
|
|
* The main class for non-obfuscated hook handling code
|
2012-06-26 20:24:50 +00:00
|
|
|
*
|
|
|
|
* Anything that doesn't require obfuscated or client/server specific code should
|
2012-04-05 20:22:47 +00:00
|
|
|
* go in this handler
|
2012-06-26 20:24:50 +00:00
|
|
|
*
|
2012-04-05 20:22:47 +00:00
|
|
|
* 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
|
2012-06-26 20:24:50 +00:00
|
|
|
*
|
2012-04-05 20:22:47 +00:00
|
|
|
* @author cpw
|
|
|
|
*
|
|
|
|
*/
|
2012-04-05 15:34:57 +00:00
|
|
|
public class FMLCommonHandler
|
2012-04-05 14:07:52 +00:00
|
|
|
{
|
2012-04-05 20:22:47 +00:00
|
|
|
/**
|
|
|
|
* The singleton
|
|
|
|
*/
|
2012-04-05 15:34:57 +00:00
|
|
|
private static final FMLCommonHandler INSTANCE = new FMLCommonHandler();
|
2012-04-05 20:22:47 +00:00
|
|
|
/**
|
2012-06-26 20:24:50 +00:00
|
|
|
* The delegate for side specific data and functions
|
2012-04-05 20:22:47 +00:00
|
|
|
*/
|
2012-04-05 15:34:57 +00:00
|
|
|
private IFMLSidedHandler sidedDelegate;
|
2012-06-26 20:24:50 +00:00
|
|
|
|
2012-08-10 20:37:06 +00:00
|
|
|
private List<IScheduledTickHandler> scheduledClientTicks = Lists.newArrayList();
|
|
|
|
private List<IScheduledTickHandler> scheduledServerTicks = Lists.newArrayList();
|
2012-06-29 03:37:30 +00:00
|
|
|
|
2012-06-07 23:25:49 +00:00
|
|
|
public void beginLoading(IFMLSidedHandler handler)
|
2012-04-05 16:36:54 +00:00
|
|
|
{
|
|
|
|
sidedDelegate = handler;
|
2012-07-23 19:03:17 +00:00
|
|
|
FMLLog.info("Attempting early MinecraftForge initialization");
|
2012-06-07 23:25:49 +00:00
|
|
|
callForgeMethod("initialize");
|
2012-07-23 19:03:17 +00:00
|
|
|
FMLLog.info("Completed early MinecraftForge initialization");
|
2012-04-05 15:34:57 +00:00
|
|
|
}
|
2012-04-05 16:36:54 +00:00
|
|
|
|
2012-08-10 20:37:06 +00:00
|
|
|
public void rescheduleTicks(Side side)
|
2012-04-05 14:07:52 +00:00
|
|
|
{
|
2012-06-29 03:37:30 +00:00
|
|
|
sidedDelegate.profileStart("modTickScheduling");
|
2012-08-10 20:37:06 +00:00
|
|
|
TickRegistry.updateTickQueue(side.isClient() ? scheduledClientTicks : scheduledServerTicks, side);
|
2012-06-29 03:37:30 +00:00
|
|
|
sidedDelegate.profileEnd();
|
|
|
|
}
|
2012-08-10 20:37:06 +00:00
|
|
|
public void tickStart(EnumSet<TickType> ticks, Side side, Object ... data)
|
2012-06-29 03:37:30 +00:00
|
|
|
{
|
2012-08-10 20:37:06 +00:00
|
|
|
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
|
|
|
|
|
2012-06-29 03:37:30 +00:00
|
|
|
if (scheduledTicks.size()==0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sidedDelegate.profileStart("modTickStart$"+ticks);
|
|
|
|
for (IScheduledTickHandler ticker : scheduledTicks)
|
|
|
|
{
|
2012-06-07 17:53:16 +00:00
|
|
|
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
|
|
|
|
ticksToRun.removeAll(EnumSet.complementOf(ticks));
|
|
|
|
if (!ticksToRun.isEmpty())
|
2012-06-07 15:12:51 +00:00
|
|
|
{
|
2012-06-07 17:53:16 +00:00
|
|
|
sidedDelegate.profileStart(ticker.getLabel());
|
|
|
|
ticker.tickStart(ticksToRun, data);
|
2012-06-07 15:12:51 +00:00
|
|
|
sidedDelegate.profileEnd();
|
|
|
|
}
|
|
|
|
}
|
2012-05-14 15:38:54 +00:00
|
|
|
sidedDelegate.profileEnd();
|
2012-05-07 05:39:55 +00:00
|
|
|
}
|
2012-06-26 20:24:50 +00:00
|
|
|
|
2012-08-10 20:37:06 +00:00
|
|
|
public void tickEnd(EnumSet<TickType> ticks, Side side, Object ... data)
|
2012-05-07 05:39:55 +00:00
|
|
|
{
|
2012-08-10 20:37:06 +00:00
|
|
|
List<IScheduledTickHandler> scheduledTicks = side.isClient() ? scheduledClientTicks : scheduledServerTicks;
|
|
|
|
|
2012-06-29 03:37:30 +00:00
|
|
|
if (scheduledTicks.size()==0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2012-06-07 17:53:16 +00:00
|
|
|
sidedDelegate.profileStart("modTickEnd$"+ticks);
|
2012-06-29 03:37:30 +00:00
|
|
|
for (IScheduledTickHandler ticker : scheduledTicks)
|
2012-06-07 15:12:51 +00:00
|
|
|
{
|
2012-06-07 17:53:16 +00:00
|
|
|
EnumSet<TickType> ticksToRun = EnumSet.copyOf(ticker.ticks());
|
|
|
|
ticksToRun.removeAll(EnumSet.complementOf(ticks));
|
|
|
|
if (!ticksToRun.isEmpty())
|
2012-06-07 15:12:51 +00:00
|
|
|
{
|
2012-06-07 17:53:16 +00:00
|
|
|
sidedDelegate.profileStart(ticker.getLabel());
|
|
|
|
ticker.tickEnd(ticksToRun, data);
|
2012-06-07 15:12:51 +00:00
|
|
|
sidedDelegate.profileEnd();
|
|
|
|
}
|
|
|
|
}
|
2012-05-14 15:38:54 +00:00
|
|
|
sidedDelegate.profileEnd();
|
2012-04-05 14:07:52 +00:00
|
|
|
}
|
2012-06-26 20:24:50 +00:00
|
|
|
|
2012-04-05 14:07:52 +00:00
|
|
|
/**
|
|
|
|
* @return the instance
|
|
|
|
*/
|
2012-04-05 15:34:57 +00:00
|
|
|
public static FMLCommonHandler instance()
|
2012-04-05 14:07:52 +00:00
|
|
|
{
|
|
|
|
return INSTANCE;
|
2012-03-30 14:11:13 +00:00
|
|
|
}
|
2012-06-26 20:24:50 +00:00
|
|
|
/**
|
|
|
|
* Find the container that associates with the supplied mod object
|
|
|
|
* @param mod
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public ModContainer findContainerFor(Object mod)
|
|
|
|
{
|
2012-08-11 06:43:04 +00:00
|
|
|
return Loader.instance().getReversedModObjectList().get(mod);
|
2012-06-26 20:24:50 +00:00
|
|
|
}
|
2012-04-05 20:22:47 +00:00
|
|
|
/**
|
|
|
|
* Get the forge mod loader logging instance (goes to the forgemodloader log file)
|
|
|
|
* @return
|
|
|
|
*/
|
2012-04-05 16:36:54 +00:00
|
|
|
public Logger getFMLLogger()
|
|
|
|
{
|
2012-07-30 02:54:59 +00:00
|
|
|
return FMLLog.getLogger();
|
2012-04-05 15:34:57 +00:00
|
|
|
}
|
2012-04-05 16:36:54 +00:00
|
|
|
|
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
|
|
|
|
2012-06-02 19:13:55 +00:00
|
|
|
public Side getSide()
|
2012-05-07 04:54:18 +00:00
|
|
|
{
|
2012-06-02 19:13:55 +00:00
|
|
|
return sidedDelegate.getSide();
|
2012-05-07 04:54:18 +00:00
|
|
|
}
|
2012-06-26 20:24:50 +00:00
|
|
|
|
2012-05-10 22:54:25 +00:00
|
|
|
/**
|
|
|
|
* Raise an exception
|
2012-06-26 20:24:50 +00:00
|
|
|
*
|
2012-05-10 22:54:25 +00:00
|
|
|
* @param exception
|
|
|
|
* @param message
|
|
|
|
* @param stopGame
|
|
|
|
*/
|
|
|
|
public void raiseException(Throwable exception, String message, boolean stopGame)
|
2012-05-07 05:39:55 +00:00
|
|
|
{
|
2012-05-10 22:54:25 +00:00
|
|
|
FMLCommonHandler.instance().getFMLLogger().throwing("FMLHandler", "raiseException", exception);
|
2012-07-04 02:39:35 +00:00
|
|
|
if (stopGame)
|
|
|
|
{
|
|
|
|
getSidedDelegate().haltGame(message,exception);
|
|
|
|
}
|
2012-05-07 05:39:55 +00:00
|
|
|
}
|
2012-05-10 22:54:25 +00:00
|
|
|
|
2012-06-26 20:24:50 +00:00
|
|
|
|
2012-06-07 23:25:49 +00:00
|
|
|
private Class<?> forge;
|
|
|
|
private boolean noForge;
|
2012-07-24 01:20:37 +00:00
|
|
|
private List<String> brandings;
|
2012-06-07 23:25:49 +00:00
|
|
|
private Class<?> findMinecraftForge()
|
|
|
|
{
|
|
|
|
if (forge==null && !noForge)
|
|
|
|
{
|
|
|
|
try {
|
2012-08-06 21:27:21 +00:00
|
|
|
forge = Class.forName("net.minecraftforge.common.MinecraftForge");
|
2012-06-07 23:25:49 +00:00
|
|
|
} catch (Exception ex) {
|
2012-08-06 21:27:21 +00:00
|
|
|
noForge = true;
|
2012-06-07 23:25:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return forge;
|
|
|
|
}
|
2012-06-26 20:24:50 +00:00
|
|
|
|
2012-06-07 23:25:49 +00:00
|
|
|
private Object callForgeMethod(String method)
|
|
|
|
{
|
|
|
|
if (noForge)
|
|
|
|
return null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return findMinecraftForge().getMethod(method).invoke(null);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
// No Forge installation
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2012-05-11 05:45:36 +00:00
|
|
|
/**
|
|
|
|
* @param string
|
|
|
|
* @return
|
|
|
|
*/
|
2012-07-24 01:20:37 +00:00
|
|
|
public void computeBranding()
|
2012-05-11 05:45:36 +00:00
|
|
|
{
|
2012-07-24 01:20:37 +00:00
|
|
|
if (brandings == null)
|
2012-06-07 23:25:49 +00:00
|
|
|
{
|
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-05-11 05:45:36 +00:00
|
|
|
}
|
2012-07-24 01:20:37 +00:00
|
|
|
}
|
|
|
|
public List<String> getBrandings()
|
|
|
|
{
|
|
|
|
if (brandings == null)
|
|
|
|
{
|
|
|
|
computeBranding();
|
2012-05-11 05:45:36 +00:00
|
|
|
}
|
2012-07-24 01:20:37 +00:00
|
|
|
return ImmutableList.copyOf(brandings);
|
2012-05-11 05:45:36 +00:00
|
|
|
}
|
|
|
|
|
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()
|
|
|
|
{
|
2012-08-10 20:37:06 +00:00
|
|
|
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)
|
|
|
|
{
|
2012-08-10 20:37:06 +00:00
|
|
|
tickEnd(EnumSet.of(TickType.WORLD), Side.SERVER, world);
|
2012-07-06 14:29:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void onPreServerTick()
|
|
|
|
{
|
2012-08-10 20:37:06 +00:00
|
|
|
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)
|
|
|
|
{
|
2012-08-10 20:37:06 +00:00
|
|
|
tickStart(EnumSet.of(TickType.WORLD), Side.SERVER, world);
|
2012-07-06 14:29:17 +00:00
|
|
|
}
|
|
|
|
|
2012-08-10 21:11:01 +00:00
|
|
|
public void onWorldLoadTick(World[] worlds)
|
2012-07-06 02:31:46 +00:00
|
|
|
{
|
2012-08-10 21:11:01 +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
|
|
|
}
|
2012-08-06 13:52:42 +00:00
|
|
|
|
2012-08-02 04:38:30 +00:00
|
|
|
public void handleServerStarting(MinecraftServer server)
|
|
|
|
{
|
|
|
|
Loader.instance().serverStarting(server);
|
|
|
|
}
|
2012-08-06 13:52:42 +00:00
|
|
|
|
2012-08-02 04:38:30 +00:00
|
|
|
public void handleServerStarted()
|
|
|
|
{
|
|
|
|
Loader.instance().serverStarted();
|
|
|
|
}
|
2012-08-06 13:52:42 +00:00
|
|
|
|
2012-08-02 04:38:30 +00:00
|
|
|
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);
|
|
|
|
}
|
2012-08-09 13:21:16 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2012-08-10 20:37:06 +00:00
|
|
|
|
2012-08-09 13:21:16 +00:00
|
|
|
public void onServerStarted()
|
|
|
|
{
|
|
|
|
sidedDelegate.finishServerLoading();
|
|
|
|
}
|
2012-08-10 20:37:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2012-08-10 21:11:01 +00:00
|
|
|
|
|
|
|
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
|
|
|
}
|