2012-05-04 21:02:12 +00:00
/ *
* 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
* /
2014-09-23 05:01:24 +00:00
package net.minecraftforge.fml.client ;
2012-05-04 21:02:12 +00:00
2014-01-19 03:25:35 +00:00
import java.io.File ;
import java.io.FileInputStream ;
2014-09-20 00:24:36 +00:00
import java.io.IOException ;
2014-05-06 05:14:13 +00:00
import java.lang.ref.WeakReference ;
2012-05-04 21:02:12 +00:00
import java.util.ArrayList ;
2012-06-02 03:07:32 +00:00
import java.util.Arrays ;
2014-01-07 04:48:53 +00:00
import java.util.Collections ;
2012-05-07 21:44:49 +00:00
import java.util.List ;
2012-05-11 20:23:26 +00:00
import java.util.Map ;
2012-12-13 00:23:40 +00:00
import java.util.Map.Entry ;
2014-01-17 22:47:30 +00:00
import java.util.Set ;
2014-01-13 18:47:18 +00:00
import java.util.concurrent.CountDownLatch ;
import java.util.concurrent.TimeUnit ;
2014-04-01 12:30:47 +00:00
2012-05-04 21:02:12 +00:00
import net.minecraft.client.Minecraft ;
2014-09-20 00:24:36 +00:00
import net.minecraft.client.entity.EntityPlayerSP ;
2014-01-07 04:48:53 +00:00
import net.minecraft.client.gui.Gui ;
2014-01-01 05:57:24 +00:00
import net.minecraft.client.gui.GuiIngameMenu ;
2014-01-13 18:47:18 +00:00
import net.minecraft.client.gui.GuiMainMenu ;
2012-12-09 04:21:03 +00:00
import net.minecraft.client.gui.GuiScreen ;
2014-01-19 03:25:35 +00:00
import net.minecraft.client.gui.GuiSelectWorld ;
2014-04-01 12:30:47 +00:00
import net.minecraft.client.gui.ScaledResolution ;
2014-01-07 04:48:53 +00:00
import net.minecraft.client.gui.ServerListEntryNormal ;
2014-01-13 18:47:18 +00:00
import net.minecraft.client.multiplayer.GuiConnecting ;
2014-01-07 04:48:53 +00:00
import net.minecraft.client.multiplayer.ServerData ;
2012-12-09 04:21:03 +00:00
import net.minecraft.client.multiplayer.WorldClient ;
2014-01-16 19:58:28 +00:00
import net.minecraft.client.network.NetHandlerPlayClient ;
2014-01-13 18:47:18 +00:00
import net.minecraft.client.network.OldServerPinger ;
2015-06-26 19:53:53 +00:00
import net.minecraft.client.renderer.GlStateManager ;
2015-04-11 04:31:09 +00:00
import net.minecraft.client.resources.AbstractResourcePack ;
import net.minecraft.client.resources.FallbackResourceManager ;
2013-12-03 04:46:42 +00:00
import net.minecraft.client.resources.IReloadableResourceManager ;
import net.minecraft.client.resources.IResourcePack ;
2015-04-11 04:31:09 +00:00
import net.minecraft.client.resources.SimpleReloadableResourceManager ;
2012-12-09 04:21:03 +00:00
import net.minecraft.crash.CrashReport ;
import net.minecraft.entity.player.EntityPlayer ;
2013-09-27 14:45:20 +00:00
import net.minecraft.launchwrapper.Launch ;
2014-01-19 03:25:35 +00:00
import net.minecraft.nbt.CompressedStreamTools ;
import net.minecraft.nbt.NBTTagCompound ;
2013-12-31 14:45:26 +00:00
import net.minecraft.network.INetHandler ;
2014-01-17 00:45:42 +00:00
import net.minecraft.network.NetHandlerPlayServer ;
2013-12-06 16:17:40 +00:00
import net.minecraft.network.NetworkManager ;
2014-01-07 04:48:53 +00:00
import net.minecraft.network.ServerStatusResponse ;
2014-12-14 01:45:38 +00:00
import net.minecraft.network.handshake.INetHandlerHandshakeServer ;
import net.minecraft.network.login.INetHandlerLoginClient ;
import net.minecraft.network.login.INetHandlerLoginServer ;
import net.minecraft.network.play.INetHandlerPlayClient ;
import net.minecraft.network.play.INetHandlerPlayServer ;
import net.minecraft.network.status.INetHandlerStatusClient ;
import net.minecraft.network.status.INetHandlerStatusServer ;
2012-08-09 13:21:16 +00:00
import net.minecraft.server.MinecraftServer ;
2014-12-14 01:45:38 +00:00
import net.minecraft.util.IThreadListener ;
2014-01-07 04:48:53 +00:00
import net.minecraft.util.ResourceLocation ;
2015-05-17 14:11:41 +00:00
import net.minecraft.util.StringUtils ;
2014-01-18 21:05:18 +00:00
import net.minecraft.world.WorldSettings ;
2014-04-04 23:47:19 +00:00
import net.minecraft.world.storage.SaveFormatOld ;
2014-10-20 00:05:39 +00:00
import net.minecraftforge.fml.client.registry.RenderingRegistry ;
2014-09-23 05:01:24 +00:00
import net.minecraftforge.fml.common.DummyModContainer ;
import net.minecraftforge.fml.common.DuplicateModsFoundException ;
import net.minecraftforge.fml.common.FMLCommonHandler ;
2015-05-11 03:55:11 +00:00
import net.minecraftforge.fml.common.FMLContainerHolder ;
2014-09-23 05:01:24 +00:00
import net.minecraftforge.fml.common.FMLLog ;
import net.minecraftforge.fml.common.IFMLSidedHandler ;
import net.minecraftforge.fml.common.Loader ;
import net.minecraftforge.fml.common.LoaderException ;
import net.minecraftforge.fml.common.MetadataCollection ;
import net.minecraftforge.fml.common.MissingModsException ;
import net.minecraftforge.fml.common.ModContainer ;
import net.minecraftforge.fml.common.ModMetadata ;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper ;
import net.minecraftforge.fml.common.StartupQuery ;
import net.minecraftforge.fml.common.WrongMinecraftVersionException ;
import net.minecraftforge.fml.common.eventhandler.EventBus ;
import net.minecraftforge.fml.common.network.FMLNetworkEvent ;
import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler ;
import net.minecraftforge.fml.common.registry.LanguageRegistry ;
2015-11-28 08:01:31 +00:00
import net.minecraftforge.fml.common.registry.PersistentRegistryManager ;
2014-09-23 05:01:24 +00:00
import net.minecraftforge.fml.common.toposort.ModSortingException ;
import net.minecraftforge.fml.relauncher.Side ;
2014-04-01 12:30:47 +00:00
2013-12-26 17:41:49 +00:00
import org.apache.logging.log4j.Level ;
2015-04-11 04:31:09 +00:00
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
2015-04-21 01:42:59 +00:00
import org.lwjgl.LWJGLUtil ;
2014-04-01 12:30:47 +00:00
import org.lwjgl.input.Mouse ;
2015-04-21 01:42:59 +00:00
import org.lwjgl.opengl.Display ;
2014-04-01 12:30:47 +00:00
2015-06-02 23:32:10 +00:00
import com.google.common.base.CharMatcher ;
2015-05-20 15:43:52 +00:00
import com.google.common.base.Objects ;
2014-01-02 16:51:16 +00:00
import com.google.common.base.Strings ;
2012-08-17 13:24:38 +00:00
import com.google.common.base.Throwables ;
2014-01-02 16:51:16 +00:00
import com.google.common.collect.BiMap ;
2015-04-11 16:12:37 +00:00
import com.google.common.collect.HashBasedTable ;
2014-01-02 16:51:16 +00:00
import com.google.common.collect.HashBiMap ;
2015-04-11 04:31:09 +00:00
import com.google.common.collect.HashMultimap ;
2012-11-17 03:39:47 +00:00
import com.google.common.collect.ImmutableList ;
2012-08-17 13:24:38 +00:00
import com.google.common.collect.ImmutableMap ;
2014-01-19 03:25:35 +00:00
import com.google.common.collect.ImmutableMap.Builder ;
2013-07-10 19:47:13 +00:00
import com.google.common.collect.Maps ;
2015-05-11 03:55:11 +00:00
import com.google.common.collect.SetMultimap ;
import com.google.common.collect.Sets ;
2015-04-11 16:12:37 +00:00
import com.google.common.collect.Table ;
2014-01-19 03:25:35 +00:00
import com.google.gson.JsonArray ;
import com.google.gson.JsonElement ;
2014-01-07 04:48:53 +00:00
import com.google.gson.JsonObject ;
2014-04-01 12:30:47 +00:00
2012-05-11 19:18:26 +00:00
2012-05-04 21:02:12 +00:00
/ * *
* Handles primary communication from hooked code into the system
2012-06-26 19:29:34 +00:00
*
2013-07-02 23:39:02 +00:00
* The FML entry point is { @link # beginMinecraftLoading ( Minecraft , List ) } called from
2012-09-16 01:04:56 +00:00
* { @link Minecraft }
2012-06-26 19:29:34 +00:00
*
2012-05-04 21:02:12 +00:00
* Obfuscated code should focus on this class and other members of the " server "
* ( or " client " ) code
2012-06-26 19:29:34 +00:00
*
2012-05-04 21:02:12 +00:00
* The actual mod loading is handled at arms length by { @link Loader }
2012-06-26 19:29:34 +00:00
*
2012-05-04 21:02:12 +00:00
* It is expected that a similar class will exist for each target environment :
* Bukkit and Client side .
2012-06-26 19:29:34 +00:00
*
2012-05-04 21:02:12 +00:00
* It should not be directly modified .
2012-06-26 19:29:34 +00:00
*
2012-05-04 21:02:12 +00:00
* @author cpw
2012-06-26 19:29:34 +00:00
*
2012-05-04 21:02:12 +00:00
* /
public class FMLClientHandler implements IFMLSidedHandler
{
/ * *
* The singleton
* /
private static final FMLClientHandler INSTANCE = new FMLClientHandler ( ) ;
/ * *
* A reference to the server itself
* /
private Minecraft client ;
2012-06-26 19:29:34 +00:00
2012-07-23 19:03:17 +00:00
private DummyModContainer optifineContainer ;
2012-06-26 19:29:34 +00:00
2012-08-23 17:43:25 +00:00
private MissingModsException modsMissing ;
2013-05-27 14:28:00 +00:00
private ModSortingException modSorting ;
2013-07-28 18:52:12 +00:00
private boolean loading = true ;
2012-08-29 02:15:18 +00:00
2012-10-02 05:29:46 +00:00
private WrongMinecraftVersionException wrongMC ;
2012-10-16 16:39:04 +00:00
private CustomModLoadingErrorDisplayException customError ;
2014-07-31 12:47:11 +00:00
private DuplicateModsFoundException dupesFound ;
2012-10-24 13:41:46 +00:00
2012-12-07 06:52:16 +00:00
private boolean serverShouldBeKilledQuietly ;
2013-12-03 04:46:42 +00:00
private List < IResourcePack > resourcePackList ;
2013-07-02 05:39:40 +00:00
2013-12-03 04:46:42 +00:00
private Map < String , IResourcePack > resourcePackMap ;
2013-07-10 19:47:13 +00:00
2014-01-02 16:51:16 +00:00
private BiMap < ModContainer , IModGuiFactory > guiFactories ;
2014-01-07 04:48:53 +00:00
private Map < ServerStatusResponse , JsonObject > extraServerListData ;
private Map < ServerData , ExtendedServerListData > serverDataTag ;
2014-05-06 05:14:13 +00:00
private WeakReference < NetHandlerPlayClient > currentPlayClient ;
2014-01-17 22:00:55 +00:00
2012-09-16 01:04:56 +00:00
/ * *
2012-10-25 20:18:42 +00:00
* Called to start the whole game off
2012-09-16 01:04:56 +00:00
*
2012-10-25 20:18:42 +00:00
* @param minecraft The minecraft instance being launched
2013-07-02 23:39:02 +00:00
* @param resourcePackList The resource pack list we will populate with mods
2013-07-10 19:47:13 +00:00
* @param resourceManager The resource manager
2012-09-16 01:04:56 +00:00
* /
2013-11-10 16:49:06 +00:00
@SuppressWarnings ( " unchecked " )
2013-12-03 04:46:42 +00:00
public void beginMinecraftLoading ( Minecraft minecraft , @SuppressWarnings ( " rawtypes " ) List resourcePackList , IReloadableResourceManager resourceManager )
2012-05-04 21:02:12 +00:00
{
2015-04-25 19:05:28 +00:00
detectOptifine ( ) ;
2015-04-21 01:42:59 +00:00
SplashProgress . start ( ) ;
2013-03-10 06:15:16 +00:00
client = minecraft ;
2013-07-02 05:39:40 +00:00
this . resourcePackList = resourcePackList ;
2013-07-10 19:47:13 +00:00
this . resourcePackMap = Maps . newHashMap ( ) ;
2014-03-19 07:15:53 +00:00
if ( minecraft . isDemo ( ) )
2012-07-24 01:20:37 +00:00
{
FMLLog . severe ( " DEMO MODE DETECTED, FML will not work. Finishing now. " ) ;
haltGame ( " FML will not run in demo mode " , new RuntimeException ( ) ) ;
return ;
}
2012-07-31 02:31:07 +00:00
2012-06-07 23:25:49 +00:00
FMLCommonHandler . instance ( ) . beginLoading ( this ) ;
2012-06-01 18:55:49 +00:00
try
2012-07-04 02:39:35 +00:00
{
Loader . instance ( ) . loadMods ( ) ;
}
2012-10-02 05:29:46 +00:00
catch ( WrongMinecraftVersionException wrong )
{
wrongMC = wrong ;
}
2012-10-24 13:41:46 +00:00
catch ( DuplicateModsFoundException dupes )
{
2014-07-31 12:47:11 +00:00
dupesFound = dupes ;
2012-10-24 13:41:46 +00:00
}
2012-08-23 17:43:25 +00:00
catch ( MissingModsException missing )
{
modsMissing = missing ;
}
2013-05-27 14:28:00 +00:00
catch ( ModSortingException sorting )
{
modSorting = sorting ;
}
2012-10-16 16:39:04 +00:00
catch ( CustomModLoadingErrorDisplayException custom )
{
2013-12-16 16:47:48 +00:00
FMLLog . log ( Level . ERROR , custom , " A custom exception was thrown by a mod, the game will now halt " ) ;
2012-10-16 16:39:04 +00:00
customError = custom ;
}
2012-07-04 02:39:35 +00:00
catch ( LoaderException le )
{
haltGame ( " There was a severe problem during mod loading that has caused the game to fail " , le ) ;
return ;
}
2014-05-08 14:22:02 +00:00
finally
{
client . refreshResources ( ) ;
}
2013-09-27 14:45:20 +00:00
2014-05-08 14:22:02 +00:00
try
{
Loader . instance ( ) . preinitializeMods ( ) ;
}
catch ( CustomModLoadingErrorDisplayException custom )
{
FMLLog . log ( Level . ERROR , custom , " A custom exception was thrown by a mod, the game will now halt " ) ;
customError = custom ;
}
catch ( LoaderException le )
{
haltGame ( " There was a severe problem during mod loading that has caused the game to fail " , le ) ;
return ;
}
2013-09-27 14:45:20 +00:00
Map < String , Map < String , String > > sharedModList = ( Map < String , Map < String , String > > ) Launch . blackboard . get ( " modList " ) ;
if ( sharedModList = = null )
{
sharedModList = Maps . newHashMap ( ) ;
Launch . blackboard . put ( " modList " , sharedModList ) ;
}
for ( ModContainer mc : Loader . instance ( ) . getActiveModList ( ) )
{
Map < String , String > sharedModDescriptor = mc . getSharedModDescriptor ( ) ;
if ( sharedModDescriptor ! = null )
{
String sharedModId = " fml: " + mc . getModId ( ) ;
sharedModList . put ( sharedModId , sharedModDescriptor ) ;
}
}
2012-05-04 21:02:12 +00:00
}
2015-04-25 19:05:28 +00:00
private void detectOptifine ( )
{
try
{
Class < ? > optifineConfig = Class . forName ( " Config " , false , Loader . instance ( ) . getModClassLoader ( ) ) ;
String optifineVersion = ( String ) optifineConfig . getField ( " VERSION " ) . get ( null ) ;
Map < String , Object > dummyOptifineMeta = ImmutableMap . < String , Object > builder ( ) . put ( " name " , " Optifine " ) . put ( " version " , optifineVersion ) . build ( ) ;
ModMetadata optifineMetadata = MetadataCollection . from ( getClass ( ) . getResourceAsStream ( " optifinemod.info " ) , " optifine " ) . getMetadataForId ( " optifine " , dummyOptifineMeta ) ;
optifineContainer = new DummyModContainer ( optifineMetadata ) ;
FMLLog . info ( " Forge Mod Loader has detected optifine %s, enabling compatibility features " , optifineContainer . getVersion ( ) ) ;
}
catch ( Exception e )
{
optifineContainer = null ;
}
}
2012-05-04 21:02:12 +00:00
2012-07-04 02:39:35 +00:00
@Override
public void haltGame ( String message , Throwable t )
{
2015-04-21 04:28:19 +00:00
SplashProgress . finish ( ) ;
2014-03-19 07:15:53 +00:00
client . displayCrashReport ( new CrashReport ( message , t ) ) ;
2012-07-24 01:20:37 +00:00
throw Throwables . propagate ( t ) ;
2012-07-04 02:39:35 +00:00
}
2012-05-04 21:02:12 +00:00
/ * *
2012-05-07 21:44:49 +00:00
* Called a bit later on during initialization to finish loading mods
* Also initializes key bindings
2012-06-26 19:29:34 +00:00
*
2012-05-04 21:02:12 +00:00
* /
2012-08-02 04:38:30 +00:00
public void finishMinecraftLoading ( )
2012-05-04 21:02:12 +00:00
{
2013-05-27 14:28:00 +00:00
if ( modsMissing ! = null | | wrongMC ! = null | | customError ! = null | | dupesFound ! = null | | modSorting ! = null )
2012-08-23 17:43:25 +00:00
{
2015-04-21 04:28:19 +00:00
SplashProgress . finish ( ) ;
2012-08-23 17:43:25 +00:00
return ;
}
2012-07-04 02:39:35 +00:00
try
{
Loader . instance ( ) . initializeMods ( ) ;
}
2012-10-16 16:39:04 +00:00
catch ( CustomModLoadingErrorDisplayException custom )
{
2013-12-16 16:47:48 +00:00
FMLLog . log ( Level . ERROR , custom , " A custom exception was thrown by a mod, the game will now halt " ) ;
2012-10-16 16:39:04 +00:00
customError = custom ;
2015-04-21 04:28:19 +00:00
SplashProgress . finish ( ) ;
2012-10-16 16:39:04 +00:00
return ;
}
2012-07-04 02:39:35 +00:00
catch ( LoaderException le )
{
haltGame ( " There was a severe problem during mod loading that has caused the game to fail " , le ) ;
return ;
}
2013-11-10 16:49:06 +00:00
2014-05-08 13:56:43 +00:00
// Reload resources
2014-03-19 07:15:53 +00:00
client . refreshResources ( ) ;
2014-01-02 16:51:16 +00:00
guiFactories = HashBiMap . create ( ) ;
for ( ModContainer mc : Loader . instance ( ) . getActiveModList ( ) )
{
String className = mc . getGuiClassName ( ) ;
if ( Strings . isNullOrEmpty ( className ) )
{
continue ;
}
try
{
Class < ? > clazz = Class . forName ( className , true , Loader . instance ( ) . getModClassLoader ( ) ) ;
Class < ? extends IModGuiFactory > guiClassFactory = clazz . asSubclass ( IModGuiFactory . class ) ;
IModGuiFactory guiFactory = guiClassFactory . newInstance ( ) ;
guiFactory . initialize ( client ) ;
guiFactories . put ( mc , guiFactory ) ;
} catch ( Exception e )
{
FMLLog . log ( Level . ERROR , e , " A critical error occurred instantiating the gui factory for mod %s " , mc . getModId ( ) ) ;
}
}
2012-08-29 02:15:18 +00:00
loading = false ;
2014-03-19 07:15:53 +00:00
client . gameSettings . loadOptions ( ) ; //Reload options to load any mod added keybindings.
2012-08-13 23:57:40 +00:00
}
2012-07-30 02:54:59 +00:00
2013-09-27 14:45:20 +00:00
public void extendModList ( )
{
2013-11-10 16:49:06 +00:00
@SuppressWarnings ( " unchecked " )
2013-09-27 14:45:20 +00:00
Map < String , Map < String , String > > modList = ( Map < String , Map < String , String > > ) Launch . blackboard . get ( " modList " ) ;
if ( modList ! = null )
{
for ( Entry < String , Map < String , String > > modEntry : modList . entrySet ( ) )
{
String sharedModId = modEntry . getKey ( ) ;
String system = sharedModId . split ( " : " ) [ 0 ] ;
if ( " fml " . equals ( system ) )
{
continue ;
}
2015-11-27 03:38:21 +00:00
/ *
2013-09-27 14:45:20 +00:00
Map < String , String > mod = modEntry . getValue ( ) ;
String modSystem = mod . get ( " modsystem " ) ; // the modsystem (FML uses FML or ModLoader)
String modId = mod . get ( " id " ) ; // unique ID
String modVersion = mod . get ( " version " ) ; // version
String modName = mod . get ( " name " ) ; // a human readable name
String modURL = mod . get ( " url " ) ; // a URL for the mod (can be empty string)
String modAuthors = mod . get ( " authors " ) ; // a csv of authors (can be empty string)
String modDescription = mod . get ( " description " ) ; // a (potentially) multiline description (can be empty string)
2015-11-27 03:38:21 +00:00
* /
2013-09-27 14:45:20 +00:00
}
}
}
2012-08-23 17:43:25 +00:00
public void onInitializationComplete ( )
2012-08-13 23:57:40 +00:00
{
2015-06-26 19:53:53 +00:00
// re-sync TEXTURE_2D, splash screen disables it with a direct GL call
GlStateManager . disableTexture2D ( ) ;
GlStateManager . enableTexture2D ( ) ;
2012-10-02 05:29:46 +00:00
if ( wrongMC ! = null )
{
2013-12-03 04:46:42 +00:00
showGuiScreen ( new GuiWrongMinecraft ( wrongMC ) ) ;
2012-10-02 05:29:46 +00:00
}
else if ( modsMissing ! = null )
2012-08-23 17:43:25 +00:00
{
2013-12-03 04:46:42 +00:00
showGuiScreen ( new GuiModsMissing ( modsMissing ) ) ;
2012-08-23 17:43:25 +00:00
}
2012-10-24 13:41:46 +00:00
else if ( dupesFound ! = null )
{
2013-12-03 04:46:42 +00:00
showGuiScreen ( new GuiDupesFound ( dupesFound ) ) ;
2012-10-24 13:41:46 +00:00
}
2013-05-27 14:28:00 +00:00
else if ( modSorting ! = null )
{
2013-12-03 04:46:42 +00:00
showGuiScreen ( new GuiSortingProblem ( modSorting ) ) ;
2013-05-27 14:28:00 +00:00
}
2014-07-31 12:47:11 +00:00
else if ( customError ! = null )
2012-10-16 16:39:04 +00:00
{
2014-07-31 12:47:11 +00:00
showGuiScreen ( new GuiCustomModLoadingErrorScreen ( customError ) ) ;
2012-10-16 16:39:04 +00:00
}
2012-08-23 17:43:25 +00:00
else
{
2015-04-25 04:41:50 +00:00
Loader . instance ( ) . loadingComplete ( ) ;
SplashProgress . finish ( ) ;
2012-08-23 17:43:25 +00:00
}
2015-04-11 04:31:09 +00:00
logMissingTextureErrors ( ) ;
2012-05-04 21:02:12 +00:00
}
/ * *
* Get the server instance
* /
public Minecraft getClient ( )
{
return client ;
}
/ * *
* @return the instance
* /
public static FMLClientHandler instance ( )
{
return INSTANCE ;
}
2012-05-07 21:44:49 +00:00
/ * *
* @param player
* @param gui
* /
public void displayGuiScreen ( EntityPlayer player , GuiScreen gui )
{
2014-03-19 07:15:53 +00:00
if ( client . thePlayer = = player & & gui ! = null ) {
client . displayGuiScreen ( gui ) ;
2012-05-07 21:44:49 +00:00
}
}
2012-06-01 18:55:49 +00:00
/ * *
* @param mods
* /
public void addSpecialModEntries ( ArrayList < ModContainer > mods )
{
if ( optifineContainer ! = null ) {
mods . add ( optifineContainer ) ;
}
}
2012-06-02 03:07:32 +00:00
@Override
public List < String > getAdditionalBrandingInformation ( )
{
if ( optifineContainer ! = null )
{
return Arrays . asList ( String . format ( " Optifine %s " , optifineContainer . getVersion ( ) ) ) ;
} else {
2012-11-17 03:39:47 +00:00
return ImmutableList . < String > of ( ) ;
2012-06-02 03:07:32 +00:00
}
}
2012-06-02 19:13:55 +00:00
@Override
public Side getSide ( )
{
return Side . CLIENT ;
}
2012-07-31 02:31:07 +00:00
public boolean hasOptifine ( )
{
return optifineContainer ! = null ;
2012-07-06 14:29:17 +00:00
}
2012-08-08 04:31:24 +00:00
@Override
public void showGuiScreen ( Object clientGuiElement )
{
GuiScreen gui = ( GuiScreen ) clientGuiElement ;
2014-03-19 07:15:53 +00:00
client . displayGuiScreen ( gui ) ;
2012-08-08 04:31:24 +00:00
}
2012-08-09 05:58:14 +00:00
2014-04-01 12:30:47 +00:00
@Override
public void queryUser ( StartupQuery query ) throws InterruptedException
{
if ( query . getResult ( ) = = null )
{
client . displayGuiScreen ( new GuiNotification ( query ) ) ;
}
else
{
client . displayGuiScreen ( new GuiConfirmation ( query ) ) ;
}
2014-04-01 19:56:53 +00:00
if ( query . isSynchronous ( ) )
{
2014-04-03 15:58:53 +00:00
while ( client . currentScreen instanceof GuiNotification )
2014-04-01 19:56:53 +00:00
{
if ( Thread . interrupted ( ) ) throw new InterruptedException ( ) ;
2014-09-20 00:24:36 +00:00
client . loadingScreen . displayLoadingString ( " " ) ;
2014-04-01 19:56:53 +00:00
Thread . sleep ( 50 ) ;
}
2014-04-06 12:49:59 +00:00
2014-09-20 00:24:36 +00:00
client . loadingScreen . displayLoadingString ( " " ) ; // make sure the blank screen is being drawn at the end
2014-04-01 19:56:53 +00:00
}
2014-04-01 12:30:47 +00:00
}
2014-09-20 00:24:36 +00:00
public boolean handleLoadingScreen ( ScaledResolution scaledResolution ) throws IOException
2014-04-01 12:30:47 +00:00
{
2014-04-03 15:58:53 +00:00
if ( client . currentScreen instanceof GuiNotification )
2014-04-01 12:30:47 +00:00
{
int width = scaledResolution . getScaledWidth ( ) ;
int height = scaledResolution . getScaledHeight ( ) ;
int mouseX = Mouse . getX ( ) * width / client . displayWidth ;
int mouseZ = height - Mouse . getY ( ) * height / client . displayHeight - 1 ;
client . currentScreen . drawScreen ( mouseX , mouseZ , 0 ) ;
client . currentScreen . handleInput ( ) ;
return true ;
}
2014-04-03 15:58:53 +00:00
else
{
return false ;
}
2014-04-01 12:30:47 +00:00
}
2013-12-11 23:46:25 +00:00
public WorldClient getWorldClient ( )
2012-08-09 05:58:14 +00:00
{
2014-03-19 07:15:53 +00:00
return client . theWorld ;
2013-12-11 23:46:25 +00:00
}
2012-08-09 05:58:14 +00:00
2014-09-20 00:24:36 +00:00
public EntityPlayerSP getClientPlayerEntity ( )
2013-12-11 23:46:25 +00:00
{
2014-03-19 07:15:53 +00:00
return client . thePlayer ;
2012-08-09 05:58:14 +00:00
}
2012-08-09 12:40:32 +00:00
2012-08-09 13:21:16 +00:00
@Override
public void beginServerLoading ( MinecraftServer server )
{
2012-12-07 06:52:16 +00:00
serverShouldBeKilledQuietly = false ;
2012-08-09 13:21:16 +00:00
// NOOP
}
@Override
public void finishServerLoading ( )
{
// NOOP
}
2012-08-11 15:01:18 +00:00
2014-04-01 19:56:53 +00:00
@Override
2014-04-04 23:47:19 +00:00
public File getSavesDirectory ( )
2014-04-01 19:56:53 +00:00
{
2014-04-04 23:47:19 +00:00
return ( ( SaveFormatOld ) client . getSaveLoader ( ) ) . savesDirectory ;
2014-04-01 19:56:53 +00:00
}
2012-08-11 15:01:18 +00:00
@Override
public MinecraftServer getServer ( )
{
2014-03-19 07:15:53 +00:00
return client . getIntegratedServer ( ) ;
2012-08-11 15:01:18 +00:00
}
2012-08-13 02:45:18 +00:00
2013-12-10 22:29:26 +00:00
public void displayMissingMods ( Object modMissingPacket )
2012-08-27 02:13:43 +00:00
{
2013-12-10 22:29:26 +00:00
// showGuiScreen(new GuiModsMissingForServer(modMissingPacket));
2012-08-27 02:13:43 +00:00
}
2012-08-29 02:15:18 +00:00
/ * *
* If the client is in the midst of loading , we disable saving so that custom settings aren ' t wiped out
* /
public boolean isLoading ( )
{
return loading ;
}
2012-09-06 14:03:30 +00:00
2012-12-07 06:52:16 +00:00
@Override
public boolean shouldServerShouldBeKilledQuietly ( )
{
return serverShouldBeKilledQuietly ;
}
2013-04-21 02:55:56 +00:00
/ * *
* Is this GUI type open ?
*
* @param gui The type of GUI to test for
* @return if a GUI of this type is open
* /
public boolean isGUIOpen ( Class < ? extends GuiScreen > gui )
{
2014-03-19 07:15:53 +00:00
return client . currentScreen ! = null & & client . currentScreen . getClass ( ) . equals ( gui ) ;
2013-04-21 02:55:56 +00:00
}
2013-07-02 05:39:40 +00:00
@Override
public void addModAsResource ( ModContainer container )
{
2014-01-17 22:47:30 +00:00
LanguageRegistry . instance ( ) . loadLanguagesFor ( container , Side . CLIENT ) ;
2013-07-02 15:11:50 +00:00
Class < ? > resourcePackType = container . getCustomResourcePackClass ( ) ;
if ( resourcePackType ! = null )
2013-07-02 05:39:40 +00:00
{
2013-07-02 15:11:50 +00:00
try
{
2013-12-03 04:46:42 +00:00
IResourcePack pack = ( IResourcePack ) resourcePackType . getConstructor ( ModContainer . class ) . newInstance ( container ) ;
2013-07-02 15:11:50 +00:00
resourcePackList . add ( pack ) ;
2013-07-10 19:47:13 +00:00
resourcePackMap . put ( container . getModId ( ) , pack ) ;
2013-07-02 15:11:50 +00:00
}
catch ( NoSuchMethodException e )
{
2013-12-16 16:47:48 +00:00
FMLLog . log ( Level . ERROR , " The container %s (type %s) returned an invalid class for it's resource pack. " , container . getName ( ) , container . getClass ( ) . getName ( ) ) ;
2013-07-02 15:11:50 +00:00
return ;
}
catch ( Exception e )
{
2013-12-16 16:47:48 +00:00
FMLLog . log ( Level . ERROR , e , " An unexpected exception occurred constructing the custom resource pack for %s " , container . getName ( ) ) ;
2013-07-02 15:11:50 +00:00
throw Throwables . propagate ( e ) ;
}
2013-07-02 05:39:40 +00:00
}
}
2013-07-10 04:42:40 +00:00
2013-12-03 04:46:42 +00:00
public IResourcePack getResourcePackFor ( String modId )
2013-07-10 19:47:13 +00:00
{
return resourcePackMap . get ( modId ) ;
}
2013-09-14 00:04:25 +00:00
@Override
public String getCurrentLanguage ( )
{
2014-03-19 07:15:53 +00:00
return client . getLanguageManager ( ) . getCurrentLanguage ( ) . getLanguageCode ( ) ;
2013-09-14 00:04:25 +00:00
}
2013-09-20 21:02:56 +00:00
@Override
public void serverStopped ( )
{
// If the server crashes during startup, it might hang the client- reset the client so it can abend properly.
2013-09-22 15:56:24 +00:00
MinecraftServer server = getServer ( ) ;
2014-03-19 07:15:53 +00:00
if ( server ! = null & & ! server . serverIsInRunLoop ( ) )
2013-09-20 21:02:56 +00:00
{
2013-09-22 15:56:24 +00:00
ObfuscationReflectionHelper . setPrivateValue ( MinecraftServer . class , server , true , " field_71296 " + " _Q " , " serverIs " + " Running " ) ;
2013-09-20 21:02:56 +00:00
}
}
2013-12-06 16:17:40 +00:00
2013-12-31 14:45:26 +00:00
@Override
public INetHandler getClientPlayHandler ( )
{
2014-05-06 05:14:13 +00:00
return this . currentPlayClient = = null ? null : this . currentPlayClient . get ( ) ;
2013-12-31 14:45:26 +00:00
}
2013-12-06 16:17:40 +00:00
@Override
public NetworkManager getClientToServerNetworkManager ( )
{
2014-03-19 07:15:53 +00:00
return this . client . getNetHandler ( ) ! = null ? this . client . getNetHandler ( ) . getNetworkManager ( ) : null ;
2013-12-06 16:17:40 +00:00
}
2013-12-24 05:47:10 +00:00
2013-12-26 17:41:49 +00:00
public void handleClientWorldClosing ( WorldClient world )
2013-12-24 05:47:10 +00:00
{
2013-12-26 17:41:49 +00:00
NetworkManager client = getClientToServerNetworkManager ( ) ;
// ONLY revert a non-local connection
2014-03-19 07:15:53 +00:00
if ( client ! = null & & ! client . isLocalChannel ( ) )
2013-12-26 17:41:49 +00:00
{
2015-11-28 08:01:31 +00:00
PersistentRegistryManager . revertToFrozen ( ) ;
2013-12-26 17:41:49 +00:00
}
2013-12-24 05:47:10 +00:00
}
2013-12-28 22:51:40 +00:00
2014-01-18 21:05:18 +00:00
public void startIntegratedServer ( String id , String name , WorldSettings settings )
2013-12-28 22:51:40 +00:00
{
}
2014-01-01 05:57:24 +00:00
2014-01-19 03:25:35 +00:00
public File getSavesDir ( )
{
2014-03-19 07:15:53 +00:00
return new File ( client . mcDataDir , " saves " ) ;
2014-01-19 03:25:35 +00:00
}
public void tryLoadExistingWorld ( GuiSelectWorld selectWorldGUI , String dirName , String saveName )
{
File dir = new File ( getSavesDir ( ) , dirName ) ;
NBTTagCompound leveldat ;
try
{
2014-03-19 07:15:53 +00:00
leveldat = CompressedStreamTools . readCompressed ( new FileInputStream ( new File ( dir , " level.dat " ) ) ) ;
2014-01-19 03:25:35 +00:00
}
catch ( Exception e )
{
try
{
2014-03-19 07:15:53 +00:00
leveldat = CompressedStreamTools . readCompressed ( new FileInputStream ( new File ( dir , " level.dat_old " ) ) ) ;
2014-01-19 03:25:35 +00:00
}
catch ( Exception e1 )
{
FMLLog . warning ( " There appears to be a problem loading the save %s, both level files are unreadable. " , dirName ) ;
return ;
}
}
2014-03-19 07:15:53 +00:00
NBTTagCompound fmlData = leveldat . getCompoundTag ( " FML " ) ;
if ( fmlData . hasKey ( " ModItemData " ) )
2014-01-19 03:25:35 +00:00
{
showGuiScreen ( new GuiOldSaveLoadConfirm ( dirName , saveName , selectWorldGUI ) ) ;
}
else
{
2014-04-01 19:56:53 +00:00
try
{
client . launchIntegratedServer ( dirName , saveName , ( WorldSettings ) null ) ;
}
catch ( StartupQuery . AbortedException e )
{
// ignore
}
2014-02-08 17:18:34 +00:00
}
2014-01-19 03:25:35 +00:00
}
2014-01-01 05:57:24 +00:00
public void showInGameModOptions ( GuiIngameMenu guiIngameMenu )
{
2015-11-18 08:28:26 +00:00
showGuiScreen ( new GuiModList ( guiIngameMenu ) ) ;
2014-01-01 05:57:24 +00:00
}
2014-01-02 16:51:16 +00:00
public IModGuiFactory getGuiFactoryFor ( ModContainer selectedMod )
{
return guiFactories . get ( selectedMod ) ;
}
2014-01-07 04:48:53 +00:00
public void setupServerList ( )
{
extraServerListData = Collections . synchronizedMap ( Maps . < ServerStatusResponse , JsonObject > newHashMap ( ) ) ;
serverDataTag = Collections . synchronizedMap ( Maps . < ServerData , ExtendedServerListData > newHashMap ( ) ) ;
}
public void captureAdditionalData ( ServerStatusResponse serverstatusresponse , JsonObject jsonobject )
{
if ( jsonobject . has ( " modinfo " ) )
{
JsonObject fmlData = jsonobject . get ( " modinfo " ) . getAsJsonObject ( ) ;
extraServerListData . put ( serverstatusresponse , fmlData ) ;
}
}
public void bindServerListData ( ServerData data , ServerStatusResponse originalResponse )
{
if ( extraServerListData . containsKey ( originalResponse ) )
{
JsonObject jsonData = extraServerListData . get ( originalResponse ) ;
String type = jsonData . get ( " type " ) . getAsString ( ) ;
2014-01-19 03:25:35 +00:00
JsonArray modDataArray = jsonData . get ( " modList " ) . getAsJsonArray ( ) ;
2014-01-07 04:48:53 +00:00
boolean moddedClientAllowed = jsonData . has ( " clientModsAllowed " ) ? jsonData . get ( " clientModsAllowed " ) . getAsBoolean ( ) : true ;
2014-01-19 03:25:35 +00:00
Builder < String , String > modListBldr = ImmutableMap . < String , String > builder ( ) ;
for ( JsonElement obj : modDataArray )
{
JsonObject modObj = obj . getAsJsonObject ( ) ;
modListBldr . put ( modObj . get ( " modid " ) . getAsString ( ) , modObj . get ( " version " ) . getAsString ( ) ) ;
}
2014-05-01 02:47:10 +00:00
Map < String , String > modListMap = modListBldr . build ( ) ;
2014-05-26 18:57:14 +00:00
serverDataTag . put ( data , new ExtendedServerListData ( type , FMLNetworkHandler . checkModList ( modListMap , Side . SERVER ) = = null , modListMap , ! moddedClientAllowed ) ) ;
2014-01-07 04:48:53 +00:00
}
else
{
2014-03-19 07:15:53 +00:00
String serverDescription = data . serverMOTD ;
2014-01-07 04:48:53 +00:00
boolean moddedClientAllowed = true ;
if ( ! Strings . isNullOrEmpty ( serverDescription ) )
{
moddedClientAllowed = ! serverDescription . endsWith ( " :NOFML§r " ) ;
}
2014-01-19 03:25:35 +00:00
serverDataTag . put ( data , new ExtendedServerListData ( " VANILLA " , false , ImmutableMap . < String , String > of ( ) , ! moddedClientAllowed ) ) ;
2014-01-07 04:48:53 +00:00
}
2014-01-13 18:47:18 +00:00
startupConnectionData . countDown ( ) ;
2014-01-07 04:48:53 +00:00
}
private static final ResourceLocation iconSheet = new ResourceLocation ( " fml:textures/gui/icons.png " ) ;
2014-01-13 18:47:18 +00:00
private static final CountDownLatch startupConnectionData = new CountDownLatch ( 1 ) ;
2014-01-07 04:48:53 +00:00
public String enhanceServerListEntry ( ServerListEntryNormal serverListEntry , ServerData serverEntry , int x , int width , int y , int relativeMouseX , int relativeMouseY )
{
String tooltip ;
int idx ;
boolean blocked = false ;
if ( serverDataTag . containsKey ( serverEntry ) )
{
ExtendedServerListData extendedData = serverDataTag . get ( serverEntry ) ;
if ( " FML " . equals ( extendedData . type ) & & extendedData . isCompatible )
{
idx = 0 ;
2014-01-19 03:25:35 +00:00
tooltip = String . format ( " Compatible FML modded server \ n%d mods present " , extendedData . modData . size ( ) ) ;
2014-01-07 04:48:53 +00:00
}
else if ( " FML " . equals ( extendedData . type ) & & ! extendedData . isCompatible )
{
idx = 16 ;
2014-01-19 03:25:35 +00:00
tooltip = String . format ( " Incompatible FML modded server \ n%d mods present " , extendedData . modData . size ( ) ) ;
2014-01-07 04:48:53 +00:00
}
else if ( " BUKKIT " . equals ( extendedData . type ) )
{
idx = 32 ;
tooltip = String . format ( " Bukkit modded server " ) ;
}
else if ( " VANILLA " . equals ( extendedData . type ) )
{
idx = 48 ;
tooltip = String . format ( " Vanilla server " ) ;
}
else
{
idx = 64 ;
tooltip = String . format ( " Unknown server data " ) ;
}
blocked = extendedData . isBlocked ;
}
else
{
return null ;
}
2014-03-19 07:15:53 +00:00
this . client . getTextureManager ( ) . bindTexture ( iconSheet ) ;
2014-09-20 00:24:36 +00:00
Gui . drawModalRectWithCustomSizedTexture ( x + width - 18 , y + 10 , 0 , ( float ) idx , 16 , 16 , 256 . 0f , 256 . 0f ) ;
2014-01-07 04:48:53 +00:00
if ( blocked )
{
2014-09-20 00:24:36 +00:00
Gui . drawModalRectWithCustomSizedTexture ( x + width - 18 , y + 10 , 0 , 80 , 16 , 16 , 256 . 0f , 256 . 0f ) ;
2014-01-07 04:48:53 +00:00
}
return relativeMouseX > width - 15 & & relativeMouseX < width & & relativeMouseY > 10 & & relativeMouseY < 26 ? tooltip : null ;
}
public String fixDescription ( String description )
{
return description . endsWith ( " :NOFML§r " ) ? description . substring ( 0 , description . length ( ) - 8 ) + " §r " : description ;
}
2014-01-13 18:47:18 +00:00
public void connectToServerAtStartup ( String host , int port )
{
setupServerList ( ) ;
OldServerPinger osp = new OldServerPinger ( ) ;
2015-11-13 04:30:53 +00:00
ServerData serverData = new ServerData ( " Command Line " , host + " : " + port , false ) ;
2014-01-13 18:47:18 +00:00
try
{
2014-09-20 00:24:36 +00:00
osp . ping ( serverData ) ;
2014-01-13 18:47:18 +00:00
startupConnectionData . await ( 30 , TimeUnit . SECONDS ) ;
}
catch ( Exception e )
{
showGuiScreen ( new GuiConnecting ( new GuiMainMenu ( ) , client , host , port ) ) ;
return ;
}
connectToServer ( new GuiMainMenu ( ) , serverData ) ;
}
public void connectToServer ( GuiScreen guiMultiplayer , ServerData serverEntry )
{
ExtendedServerListData extendedData = serverDataTag . get ( serverEntry ) ;
2014-01-20 12:46:17 +00:00
if ( extendedData ! = null & & extendedData . isBlocked )
2014-01-13 18:47:18 +00:00
{
showGuiScreen ( new GuiAccessDenied ( guiMultiplayer , serverEntry ) ) ;
}
else
{
showGuiScreen ( new GuiConnecting ( guiMultiplayer , client , serverEntry ) ) ;
}
2014-01-16 19:58:28 +00:00
}
2014-09-20 00:24:36 +00:00
public void connectToRealmsServer ( String host , int port ) { }
2014-02-08 17:18:34 +00:00
2014-01-16 19:58:28 +00:00
public void setPlayClient ( NetHandlerPlayClient netHandlerPlayClient )
{
2014-05-08 14:22:02 +00:00
this . currentPlayClient = new WeakReference < NetHandlerPlayClient > ( netHandlerPlayClient ) ;
2014-01-16 19:58:28 +00:00
}
2014-01-17 00:45:42 +00:00
@Override
public void fireNetRegistrationEvent ( EventBus bus , NetworkManager manager , Set < String > channelSet , String channel , Side side )
{
if ( side = = Side . CLIENT )
{
bus . post ( new FMLNetworkEvent . CustomPacketRegistrationEvent < NetHandlerPlayClient > ( manager , channelSet , channel , side , NetHandlerPlayClient . class ) ) ;
}
else
{
bus . post ( new FMLNetworkEvent . CustomPacketRegistrationEvent < NetHandlerPlayServer > ( manager , channelSet , channel , side , NetHandlerPlayServer . class ) ) ;
}
}
2014-02-08 17:18:34 +00:00
2014-03-11 07:50:55 +00:00
@Override
public boolean shouldAllowPlayerLogins ( )
{
return true ; //Always true as the server has to be started before clicking 'Open to lan'
}
2014-08-13 14:22:25 +00:00
2014-07-31 12:47:11 +00:00
@Override
public void allowLogins ( ) {
// NOOP for integrated server
}
2014-12-14 01:45:38 +00:00
@Override
public IThreadListener getWorldThread ( INetHandler net )
{
if ( net instanceof INetHandlerPlayClient | |
net instanceof INetHandlerLoginClient | |
net instanceof INetHandlerStatusClient ) return getClient ( ) ;
if ( net instanceof INetHandlerHandshakeServer | |
net instanceof INetHandlerLoginServer | |
net instanceof INetHandlerPlayServer | |
net instanceof INetHandlerStatusServer ) return getServer ( ) ;
throw new RuntimeException ( " Unknown INetHandler: " + net ) ;
}
2015-04-11 04:31:09 +00:00
2015-04-11 16:12:37 +00:00
private SetMultimap < String , ResourceLocation > missingTextures = HashMultimap . create ( ) ;
private Set < String > badTextureDomains = Sets . newHashSet ( ) ;
private Table < String , String , Set < ResourceLocation > > brokenTextures = HashBasedTable . create ( ) ;
2015-04-11 04:31:09 +00:00
public void trackMissingTexture ( ResourceLocation resourceLocation )
{
2015-04-11 16:12:37 +00:00
badTextureDomains . add ( resourceLocation . getResourceDomain ( ) ) ;
2015-04-11 04:31:09 +00:00
missingTextures . put ( resourceLocation . getResourceDomain ( ) , resourceLocation ) ;
}
2015-04-21 01:42:59 +00:00
2015-04-11 16:12:37 +00:00
public void trackBrokenTexture ( ResourceLocation resourceLocation , String error )
{
badTextureDomains . add ( resourceLocation . getResourceDomain ( ) ) ;
Set < ResourceLocation > badType = brokenTextures . get ( resourceLocation . getResourceDomain ( ) , error ) ;
if ( badType = = null )
{
badType = Sets . newHashSet ( ) ;
2015-05-20 15:43:52 +00:00
brokenTextures . put ( resourceLocation . getResourceDomain ( ) , Objects . firstNonNull ( error , " Unknown error " ) , badType ) ;
2015-04-11 16:12:37 +00:00
}
badType . add ( resourceLocation ) ;
}
2015-04-11 04:31:09 +00:00
public void logMissingTextureErrors ( )
{
2015-04-25 04:41:50 +00:00
if ( missingTextures . isEmpty ( ) & & brokenTextures . isEmpty ( ) )
{
return ;
}
2015-04-11 04:31:09 +00:00
Logger logger = LogManager . getLogger ( " TEXTURE ERRORS " ) ;
logger . error ( Strings . repeat ( " += " , 25 ) ) ;
2015-04-11 16:12:37 +00:00
logger . error ( " The following texture errors were found. " ) ;
2015-04-11 04:31:09 +00:00
Map < String , FallbackResourceManager > resManagers = ObfuscationReflectionHelper . getPrivateValue ( SimpleReloadableResourceManager . class , ( SimpleReloadableResourceManager ) Minecraft . getMinecraft ( ) . getResourceManager ( ) , " domainResourceManagers " , " field_110548 " + " _a " ) ;
2015-11-05 19:52:09 +00:00
for ( String resourceDomain : badTextureDomains )
2015-04-11 04:31:09 +00:00
{
Set < ResourceLocation > missing = missingTextures . get ( resourceDomain ) ;
2015-04-11 16:12:37 +00:00
logger . error ( Strings . repeat ( " = " , 50 ) ) ;
2015-04-11 04:31:09 +00:00
logger . error ( " DOMAIN {} " , resourceDomain ) ;
2015-04-11 16:12:37 +00:00
logger . error ( Strings . repeat ( " - " , 50 ) ) ;
2015-04-11 04:31:09 +00:00
logger . error ( " domain {} is missing {} texture{} " , resourceDomain , missing . size ( ) , missing . size ( ) ! = 1 ? " s " : " " ) ;
FallbackResourceManager fallbackResourceManager = resManagers . get ( resourceDomain ) ;
if ( fallbackResourceManager = = null )
{
2015-04-11 16:12:37 +00:00
logger . error ( " domain {} is missing a resource manager - it is probably a side-effect of automatic texture processing " , resourceDomain ) ;
2015-04-11 04:31:09 +00:00
}
else
{
List < IResourcePack > resPacks = ObfuscationReflectionHelper . getPrivateValue ( FallbackResourceManager . class , fallbackResourceManager , " resourcePacks " , " field_110540 " + " _a " ) ;
logger . error ( " domain {} has {} location{}: " , resourceDomain , resPacks . size ( ) , resPacks . size ( ) ! = 1 ? " s " : " " ) ;
for ( IResourcePack resPack : resPacks )
{
if ( resPack instanceof FMLContainerHolder ) {
FMLContainerHolder containerHolder = ( FMLContainerHolder ) resPack ;
ModContainer fmlContainer = containerHolder . getFMLContainer ( ) ;
logger . error ( " mod {} resources at {} " , fmlContainer . getModId ( ) , fmlContainer . getSource ( ) . getPath ( ) ) ;
}
else if ( resPack instanceof AbstractResourcePack )
{
AbstractResourcePack resourcePack = ( AbstractResourcePack ) resPack ;
File resPath = ObfuscationReflectionHelper . getPrivateValue ( AbstractResourcePack . class , resourcePack , " resourcePackFile " , " field_110597 " + " _b " ) ;
logger . error ( " resource pack at path {} " , resPath . getPath ( ) ) ;
}
else
{
logger . error ( " unknown resourcepack type {} : {} " , resPack . getClass ( ) . getName ( ) , resPack . getPackName ( ) ) ;
}
}
}
logger . error ( Strings . repeat ( " - " , 25 ) ) ;
2015-11-05 19:52:09 +00:00
if ( missingTextures . containsKey ( resourceDomain ) ) {
logger . error ( " The missing resources for domain {} are: " , resourceDomain ) ;
for ( ResourceLocation rl : missing ) {
logger . error ( " {} " , rl . getResourcePath ( ) ) ;
}
logger . error ( Strings . repeat ( " - " , 25 ) ) ;
2015-04-11 04:31:09 +00:00
}
2015-04-11 16:12:37 +00:00
if ( ! brokenTextures . containsRow ( resourceDomain ) )
{
logger . error ( " No other errors exist for domain {} " , resourceDomain ) ;
}
else
{
logger . error ( " The following other errors were reported for domain {}: " , resourceDomain ) ;
Map < String , Set < ResourceLocation > > resourceErrs = brokenTextures . row ( resourceDomain ) ;
for ( String error : resourceErrs . keySet ( ) )
{
logger . error ( Strings . repeat ( " - " , 25 ) ) ;
logger . error ( " Problem: {} " , error ) ;
for ( ResourceLocation rl : resourceErrs . get ( error ) )
{
logger . error ( " {} " , rl . getResourcePath ( ) ) ;
}
}
}
logger . error ( Strings . repeat ( " = " , 50 ) ) ;
2015-04-11 04:31:09 +00:00
}
logger . error ( Strings . repeat ( " += " , 25 ) ) ;
}
2015-04-21 01:42:59 +00:00
@Override
public void processWindowMessages ( )
{
// workaround for windows requiring messages being processed on the main thread
2015-05-16 16:55:15 +00:00
if ( LWJGLUtil . getPlatform ( ) ! = LWJGLUtil . PLATFORM_WINDOWS ) return ;
// If we can't grab the mutex, the update call is blocked, probably in native code, just skip it and carry on
// We'll get another go next time
if ( ! SplashProgress . mutex . tryAcquire ( ) ) return ;
Display . processMessages ( ) ;
SplashProgress . mutex . release ( ) ;
2015-04-21 01:42:59 +00:00
}
2015-06-02 11:24:26 +00:00
// From FontRenderer.renderCharAtPos
private static final String ALLOWED_CHARS = " \ u00c0 \ u00c1 \ u00c2 \ u00c8 \ u00ca \ u00cb \ u00cd \ u00d3 \ u00d4 \ u00d5 \ u00da \ u00df \ u00e3 \ u00f5 \ u011f \ u0130 \ u0131 \ u0152 \ u0153 \ u015e \ u015f \ u0174 \ u0175 \ u017e \ u0207 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 \ u0000 ! \" #$%& \ '()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[ \\ ]^_`abcdefghijklmnopqrstuvwxyz{|}~ \ u0000 \ u00c7 \ u00fc \ u00e9 \ u00e2 \ u00e4 \ u00e0 \ u00e5 \ u00e7 \ u00ea \ u00eb \ u00e8 \ u00ef \ u00ee \ u00ec \ u00c4 \ u00c5 \ u00c9 \ u00e6 \ u00c6 \ u00f4 \ u00f6 \ u00f2 \ u00fb \ u00f9 \ u00ff \ u00d6 \ u00dc \ u00f8 \ u00a3 \ u00d8 \ u00d7 \ u0192 \ u00e1 \ u00ed \ u00f3 \ u00fa \ u00f1 \ u00d1 \ u00aa \ u00ba \ u00bf \ u00ae \ u00ac \ u00bd \ u00bc \ u00a1 \ u00ab \ u00bb \ u2591 \ u2592 \ u2593 \ u2502 \ u2524 \ u2561 \ u2562 \ u2556 \ u2555 \ u2563 \ u2551 \ u2557 \ u255d \ u255c \ u255b \ u2510 \ u2514 \ u2534 \ u252c \ u251c \ u2500 \ u253c \ u255e \ u255f \ u255a \ u2554 \ u2569 \ u2566 \ u2560 \ u2550 \ u256c \ u2567 \ u2568 \ u2564 \ u2565 \ u2559 \ u2558 \ u2552 \ u2553 \ u256b \ u256a \ u2518 \ u250c \ u2588 \ u2584 \ u258c \ u2590 \ u2580 \ u03b1 \ u03b2 \ u0393 \ u03c0 \ u03a3 \ u03c3 \ u03bc \ u03c4 \ u03a6 \ u0398 \ u03a9 \ u03b4 \ u221e \ u2205 \ u2208 \ u2229 \ u2261 \ u00b1 \ u2265 \ u2264 \ u2320 \ u2321 \ u00f7 \ u2248 \ u00b0 \ u2219 \ u00b7 \ u221a \ u207f \ u00b2 \ u25a0 \ u0000 " ;
2015-05-17 14:11:41 +00:00
@Override
public String stripSpecialChars ( String message )
{
2015-06-02 11:24:26 +00:00
// We can't handle many unicode points in the splash renderer
return CharMatcher . anyOf ( ALLOWED_CHARS ) . retainFrom ( StringUtils . stripControlCodes ( message ) ) ;
2015-04-21 01:42:59 +00:00
}
2012-05-04 21:02:12 +00:00
}