2012-07-22 14:26:38 +00:00
/ *
2016-06-23 03:49:47 +00:00
* Minecraft Forge
* Copyright ( c ) 2016 .
2013-07-10 19:47:13 +00:00
*
2016-06-23 03:49:47 +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 version 2 . 1
* of the License .
*
* 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
2012-07-22 14:26:38 +00:00
* /
2014-09-23 05:01:24 +00:00
package net.minecraftforge.fml.common ;
2012-07-22 14:26:38 +00:00
2013-08-27 16:31:37 +00:00
import java.io.File ;
2012-12-24 03:27:02 +00:00
import java.security.cert.Certificate ;
2012-07-22 14:26:38 +00:00
import java.util.Arrays ;
2014-04-04 23:47:19 +00:00
import java.util.HashSet ;
2014-02-08 17:18:34 +00:00
import java.util.List ;
2012-10-03 01:54:47 +00:00
import java.util.Map ;
2013-12-09 06:22:24 +00:00
import java.util.Map.Entry ;
2014-04-04 23:47:19 +00:00
import java.util.Set ;
2014-04-01 12:30:47 +00:00
2012-12-10 03:00:51 +00:00
import net.minecraft.nbt.NBTBase ;
import net.minecraft.nbt.NBTTagCompound ;
import net.minecraft.nbt.NBTTagList ;
2015-11-28 08:01:31 +00:00
import net.minecraft.util.ResourceLocation ;
2012-12-09 04:21:03 +00:00
import net.minecraft.world.storage.SaveHandler ;
import net.minecraft.world.storage.WorldInfo ;
2014-09-23 05:01:24 +00:00
import net.minecraftforge.fml.client.FMLFileResourcePack ;
import net.minecraftforge.fml.client.FMLFolderResourcePack ;
import net.minecraftforge.fml.common.asm.FMLSanityChecker ;
import net.minecraftforge.fml.common.event.FMLConstructionEvent ;
2015-04-01 19:56:48 +00:00
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent ;
2014-09-23 05:01:24 +00:00
import net.minecraftforge.fml.common.network.NetworkCheckHandler ;
import net.minecraftforge.fml.common.network.NetworkRegistry ;
import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler ;
2016-04-10 05:33:39 +00:00
import net.minecraftforge.fml.common.registry.ForgeRegistries ;
2015-11-28 08:01:31 +00:00
import net.minecraftforge.fml.common.registry.PersistentRegistryManager ;
2015-04-01 19:56:48 +00:00
import net.minecraftforge.fml.common.registry.VillagerRegistry ;
2014-09-23 05:01:24 +00:00
import net.minecraftforge.fml.relauncher.Side ;
2014-03-24 20:16:36 +00:00
2014-02-08 17:18:34 +00:00
import org.apache.logging.log4j.Level ;
2014-03-24 20:16:36 +00:00
2012-08-04 15:26:51 +00:00
import com.google.common.eventbus.EventBus ;
2013-12-09 06:22:24 +00:00
import com.google.common.eventbus.Subscribe ;
2014-03-24 20:16:36 +00:00
2012-07-22 14:26:38 +00:00
/ * *
* @author cpw
*
* /
2016-04-01 21:13:06 +00:00
public final class FMLContainer extends DummyModContainer implements WorldAccessContainer
2012-07-22 14:26:38 +00:00
{
2013-12-06 08:11:03 +00:00
public FMLContainer ( )
2012-07-22 14:26:38 +00:00
{
super ( new ModMetadata ( ) ) ;
ModMetadata meta = getMetadata ( ) ;
meta . modId = " FML " ;
meta . name = " Forge Mod Loader " ;
meta . version = Loader . instance ( ) . getFMLVersionString ( ) ;
meta . credits = " Made possible with help from many people " ;
2014-04-19 15:38:46 +00:00
meta . authorList = Arrays . asList ( " cpw " , " LexManos " , " Player " ) ;
2012-07-22 14:26:38 +00:00
meta . description = " The Forge Mod Loader provides the ability for systems to load mods " +
" from the file system. It also provides key capabilities for mods to be able " +
2013-11-10 18:15:26 +00:00
" to cooperate and provide a good modding environment. " ;
2013-01-19 02:26:43 +00:00
meta . url = " https://github.com/MinecraftForge/FML/wiki " ;
2012-07-22 14:26:38 +00:00
meta . screenshots = new String [ 0 ] ;
meta . logoFile = " " ;
}
2012-08-04 15:26:51 +00:00
@Override
public boolean registerBus ( EventBus bus , LoadController controller )
{
2013-12-09 06:22:24 +00:00
bus . register ( this ) ;
2012-08-04 15:26:51 +00:00
return true ;
}
2012-10-03 01:54:47 +00:00
2013-12-09 06:22:24 +00:00
@Subscribe
public void modConstruction ( FMLConstructionEvent evt )
{
NetworkRegistry . INSTANCE . register ( this , this . getClass ( ) , null , evt . getASMHarvestedData ( ) ) ;
2013-12-11 23:46:25 +00:00
FMLNetworkHandler . registerChannel ( this , evt . getSide ( ) ) ;
2013-12-09 06:22:24 +00:00
}
2015-04-01 19:56:48 +00:00
@Subscribe
public void modPreinitialization ( FMLPreInitializationEvent evt )
{
2016-04-10 05:33:39 +00:00
// Initialize all Forge/Vanilla registries {invoke the static init)
if ( ForgeRegistries . ITEMS = = null )
throw new RuntimeException ( " Something horrible went wrong in init, ForgeRegistres didn't create... " ) ;
2015-04-01 19:56:48 +00:00
}
2013-12-09 06:22:24 +00:00
@NetworkCheckHandler
public boolean checkModLists ( Map < String , String > modList , Side side )
{
return Loader . instance ( ) . checkRemoteModList ( modList , side ) ;
}
2012-10-03 01:54:47 +00:00
@Override
public NBTTagCompound getDataForWriting ( SaveHandler handler , WorldInfo info )
{
NBTTagCompound fmlData = new NBTTagCompound ( ) ;
2014-10-01 08:07:23 +00:00
NBTTagList modList = new NBTTagList ( ) ;
2012-10-03 01:54:47 +00:00
for ( ModContainer mc : Loader . instance ( ) . getActiveModList ( ) )
{
NBTTagCompound mod = new NBTTagCompound ( ) ;
2014-03-19 07:15:53 +00:00
mod . setString ( " ModId " , mc . getModId ( ) ) ;
mod . setString ( " ModVersion " , mc . getVersion ( ) ) ;
2014-10-01 08:07:23 +00:00
modList . appendTag ( mod ) ;
2012-10-03 01:54:47 +00:00
}
2014-10-01 08:07:23 +00:00
fmlData . setTag ( " ModList " , modList ) ;
NBTTagCompound registries = new NBTTagCompound ( ) ;
fmlData . setTag ( " Registries " , registries ) ;
2014-03-19 07:15:53 +00:00
FMLLog . fine ( " Gathering id map for writing to world save %s " , info . getWorldName ( ) ) ;
2015-11-28 08:01:31 +00:00
PersistentRegistryManager . GameDataSnapshot dataSnapshot = PersistentRegistryManager . takeSnapshot ( ) ;
2014-03-24 23:36:37 +00:00
2015-11-28 08:01:31 +00:00
for ( Map . Entry < ResourceLocation , PersistentRegistryManager . GameDataSnapshot . Entry > e : dataSnapshot . entries . entrySet ( ) )
2014-08-01 23:36:18 +00:00
{
2014-10-01 08:07:23 +00:00
NBTTagCompound data = new NBTTagCompound ( ) ;
2015-11-28 08:01:31 +00:00
registries . setTag ( e . getKey ( ) . toString ( ) , data ) ;
2014-10-01 08:07:23 +00:00
NBTTagList ids = new NBTTagList ( ) ;
2015-11-28 08:01:31 +00:00
for ( Entry < ResourceLocation , Integer > item : e . getValue ( ) . ids . entrySet ( ) )
2014-10-01 08:07:23 +00:00
{
NBTTagCompound tag = new NBTTagCompound ( ) ;
2015-11-28 08:01:31 +00:00
tag . setString ( " K " , item . getKey ( ) . toString ( ) ) ;
2014-10-01 08:07:23 +00:00
tag . setInteger ( " V " , item . getValue ( ) ) ;
ids . appendTag ( tag ) ;
}
data . setTag ( " ids " , ids ) ;
NBTTagList aliases = new NBTTagList ( ) ;
2015-11-28 08:01:31 +00:00
for ( Entry < ResourceLocation , ResourceLocation > entry : e . getValue ( ) . aliases . entrySet ( ) )
2014-10-01 08:07:23 +00:00
{
NBTTagCompound tag = new NBTTagCompound ( ) ;
2015-11-28 08:01:31 +00:00
tag . setString ( " K " , entry . getKey ( ) . toString ( ) ) ;
tag . setString ( " V " , entry . getValue ( ) . toString ( ) ) ;
2014-10-01 08:07:23 +00:00
aliases . appendTag ( tag ) ;
}
data . setTag ( " aliases " , aliases ) ;
NBTTagList subs = new NBTTagList ( ) ;
2015-11-28 08:01:31 +00:00
for ( ResourceLocation entry : e . getValue ( ) . substitutions )
2014-10-01 08:07:23 +00:00
{
NBTTagCompound tag = new NBTTagCompound ( ) ;
2015-11-28 08:01:31 +00:00
tag . setString ( " K " , entry . toString ( ) ) ;
2014-10-01 08:07:23 +00:00
subs . appendTag ( tag ) ;
}
data . setTag ( " substitutions " , subs ) ;
int [ ] blocked = new int [ e . getValue ( ) . blocked . size ( ) ] ;
int idx = 0 ;
for ( Integer i : e . getValue ( ) . blocked )
{
blocked [ idx + + ] = i ;
}
data . setIntArray ( " blocked " , blocked ) ;
2015-12-31 22:58:30 +00:00
NBTTagList dummied = new NBTTagList ( ) ;
for ( ResourceLocation entry : e . getValue ( ) . dummied )
{
NBTTagCompound tag = new NBTTagCompound ( ) ;
tag . setString ( " K " , entry . toString ( ) ) ;
dummied . appendTag ( tag ) ;
}
data . setTag ( " dummied " , dummied ) ;
2014-08-01 23:36:18 +00:00
}
2012-10-03 01:54:47 +00:00
return fmlData ;
}
@Override
public void readData ( SaveHandler handler , WorldInfo info , Map < String , NBTBase > propertyMap , NBTTagCompound tag )
{
2014-03-19 07:15:53 +00:00
if ( tag . hasKey ( " ModList " ) )
2012-10-03 01:54:47 +00:00
{
2014-03-19 07:15:53 +00:00
NBTTagList modList = tag . getTagList ( " ModList " , ( byte ) 10 ) ;
for ( int i = 0 ; i < modList . tagCount ( ) ; i + + )
2012-10-03 01:54:47 +00:00
{
2014-03-19 07:15:53 +00:00
NBTTagCompound mod = modList . getCompoundTagAt ( i ) ;
String modId = mod . getString ( " ModId " ) ;
String modVersion = mod . getString ( " ModVersion " ) ;
2012-10-03 01:54:47 +00:00
ModContainer container = Loader . instance ( ) . getIndexedModList ( ) . get ( modId ) ;
if ( container = = null )
{
2013-12-16 16:47:48 +00:00
FMLLog . log ( " fml.ModTracker " , Level . ERROR , " This world was saved with mod %s which appears to be missing, things may not work well " , modId ) ;
2012-10-03 01:54:47 +00:00
continue ;
}
if ( ! modVersion . equals ( container . getVersion ( ) ) )
{
2013-01-30 23:57:21 +00:00
FMLLog . log ( " fml.ModTracker " , Level . INFO , " This world was saved with mod %s version %s and it is now at version %s, things may not work well " , modId , modVersion , container . getVersion ( ) ) ;
2012-10-03 01:54:47 +00:00
}
}
}
2014-04-01 12:30:47 +00:00
List < String > failedElements = null ;
2014-10-01 08:07:23 +00:00
if ( tag . hasKey ( " ModItemData " ) ) // Pre 1.7
2012-12-07 06:52:16 +00:00
{
2015-11-28 08:01:31 +00:00
StartupQuery . notify ( " This save predates 1.7.10, it can no longer be loaded here. Please load in 1.7.10 or 1.8 first " ) ;
StartupQuery . abort ( ) ;
2012-12-07 06:52:16 +00:00
}
2014-10-01 08:07:23 +00:00
else if ( tag . hasKey ( " ItemData " ) ) // 1.7
2012-12-07 06:52:16 +00:00
{
2015-11-28 08:01:31 +00:00
if ( ! tag . hasKey ( " BlockedItemIds " ) ) // no blocked id info -> old 1.7 save
{
StartupQuery . notify ( " This save predates 1.7.10, it can no longer be loaded here. Please load in 1.7.10 or 1.8 first " ) ;
StartupQuery . abort ( ) ;
}
PersistentRegistryManager . GameDataSnapshot snapshot = new PersistentRegistryManager . GameDataSnapshot ( ) ;
PersistentRegistryManager . GameDataSnapshot . Entry blocks = new PersistentRegistryManager . GameDataSnapshot . Entry ( ) ;
PersistentRegistryManager . GameDataSnapshot . Entry items = new PersistentRegistryManager . GameDataSnapshot . Entry ( ) ;
snapshot . entries . put ( PersistentRegistryManager . BLOCKS , blocks ) ;
snapshot . entries . put ( PersistentRegistryManager . ITEMS , items ) ;
2014-10-01 08:07:23 +00:00
2014-04-01 05:00:20 +00:00
NBTTagList list = tag . getTagList ( " ItemData " , 10 ) ;
2014-03-19 07:15:53 +00:00
for ( int i = 0 ; i < list . tagCount ( ) ; i + + )
2013-12-10 02:36:49 +00:00
{
2014-10-01 08:07:23 +00:00
NBTTagCompound e = list . getCompoundTagAt ( i ) ;
String name = e . getString ( " K " ) ;
if ( name . charAt ( 0 ) = = '\u0001' )
2015-11-28 08:01:31 +00:00
blocks . ids . put ( new ResourceLocation ( name . substring ( 1 ) ) , e . getInteger ( " V " ) ) ;
2014-10-01 08:07:23 +00:00
else if ( name . charAt ( 0 ) = = '\u0002' )
2015-11-28 08:01:31 +00:00
items . ids . put ( new ResourceLocation ( name . substring ( 1 ) ) , e . getInteger ( " V " ) ) ;
2013-12-10 02:36:49 +00:00
}
2014-03-30 15:17:54 +00:00
2014-04-04 23:47:19 +00:00
Set < Integer > blockedIds = new HashSet < Integer > ( ) ;
2015-11-28 08:01:31 +00:00
for ( int id : tag . getIntArray ( " BlockedItemIds " ) )
2014-03-30 15:17:54 +00:00
{
2015-11-28 08:01:31 +00:00
blockedIds . add ( id ) ;
2014-04-04 23:47:19 +00:00
}
2014-10-01 08:07:23 +00:00
blocks . blocked . addAll ( blockedIds ) ;
items . blocked . addAll ( blockedIds ) ;
2014-04-01 05:00:20 +00:00
list = tag . getTagList ( " BlockAliases " , 10 ) ;
for ( int i = 0 ; i < list . tagCount ( ) ; i + + )
2014-03-24 23:36:37 +00:00
{
2014-04-01 05:00:20 +00:00
NBTTagCompound dataTag = list . getCompoundTagAt ( i ) ;
2015-11-28 08:01:31 +00:00
blocks . aliases . put ( new ResourceLocation ( dataTag . getString ( " K " ) ) , new ResourceLocation ( dataTag . getString ( " V " ) ) ) ;
2014-03-24 23:36:37 +00:00
}
2014-10-01 08:07:23 +00:00
2014-08-20 14:28:39 +00:00
if ( tag . hasKey ( " BlockSubstitutions " , 9 ) )
2014-08-01 23:36:18 +00:00
{
2014-08-20 14:28:39 +00:00
list = tag . getTagList ( " BlockSubstitutions " , 10 ) ;
2014-08-01 23:36:18 +00:00
for ( int i = 0 ; i < list . tagCount ( ) ; i + + )
{
NBTTagCompound dataTag = list . getCompoundTagAt ( i ) ;
2015-11-28 08:01:31 +00:00
blocks . substitutions . add ( new ResourceLocation ( dataTag . getString ( " K " ) ) ) ;
2014-08-01 23:36:18 +00:00
}
}
2014-10-01 08:07:23 +00:00
2014-04-01 05:00:20 +00:00
list = tag . getTagList ( " ItemAliases " , 10 ) ;
for ( int i = 0 ; i < list . tagCount ( ) ; i + + )
2014-03-24 23:36:37 +00:00
{
2014-04-01 05:00:20 +00:00
NBTTagCompound dataTag = list . getCompoundTagAt ( i ) ;
2015-11-28 08:01:31 +00:00
items . aliases . put ( new ResourceLocation ( dataTag . getString ( " K " ) ) , new ResourceLocation ( dataTag . getString ( " V " ) ) ) ;
2014-03-24 23:36:37 +00:00
}
2014-03-24 20:16:36 +00:00
2014-08-20 14:28:39 +00:00
if ( tag . hasKey ( " ItemSubstitutions " , 9 ) )
2014-08-01 23:36:18 +00:00
{
2014-08-20 14:28:39 +00:00
list = tag . getTagList ( " ItemSubstitutions " , 10 ) ;
2014-08-01 23:36:18 +00:00
for ( int i = 0 ; i < list . tagCount ( ) ; i + + )
{
NBTTagCompound dataTag = list . getCompoundTagAt ( i ) ;
2015-11-28 08:01:31 +00:00
items . substitutions . add ( new ResourceLocation ( dataTag . getString ( " K " ) ) ) ;
2014-10-01 08:07:23 +00:00
}
}
2015-11-28 08:01:31 +00:00
failedElements = PersistentRegistryManager . injectSnapshot ( snapshot , true , true ) ;
2014-10-01 08:07:23 +00:00
}
else if ( tag . hasKey ( " Registries " ) ) // 1.8, genericed out the 'registries' list
{
2015-11-28 08:01:31 +00:00
PersistentRegistryManager . GameDataSnapshot snapshot = new PersistentRegistryManager . GameDataSnapshot ( ) ;
2014-10-01 08:07:23 +00:00
NBTTagCompound regs = tag . getCompoundTag ( " Registries " ) ;
2015-11-28 08:01:31 +00:00
for ( String key : regs . getKeySet ( ) )
2014-10-01 08:07:23 +00:00
{
2015-11-28 08:01:31 +00:00
PersistentRegistryManager . GameDataSnapshot . Entry entry = new PersistentRegistryManager . GameDataSnapshot . Entry ( ) ;
2015-12-12 23:53:13 +00:00
ResourceLocation entryLoc ;
if ( " fml:blocks " . equals ( key ) ) entryLoc = PersistentRegistryManager . BLOCKS ;
else if ( " fml:items " . equals ( key ) ) entryLoc = PersistentRegistryManager . ITEMS ;
2015-12-21 21:42:40 +00:00
else if ( " fmlgr:villagerprofessions " . equals ( key ) ) entryLoc = VillagerRegistry . PROFESSIONS ;
2015-12-12 23:53:13 +00:00
else entryLoc = new ResourceLocation ( key ) ;
snapshot . entries . put ( entryLoc , entry ) ;
2014-10-01 08:07:23 +00:00
NBTTagList list = regs . getCompoundTag ( key ) . getTagList ( " ids " , 10 ) ;
for ( int x = 0 ; x < list . tagCount ( ) ; x + + )
{
NBTTagCompound e = list . getCompoundTagAt ( x ) ;
2015-11-28 08:01:31 +00:00
entry . ids . put ( new ResourceLocation ( e . getString ( " K " ) ) , e . getInteger ( " V " ) ) ;
2014-10-01 08:07:23 +00:00
}
list = regs . getCompoundTag ( key ) . getTagList ( " aliases " , 10 ) ;
for ( int x = 0 ; x < list . tagCount ( ) ; x + + )
{
NBTTagCompound e = list . getCompoundTagAt ( x ) ;
2015-11-28 08:01:31 +00:00
entry . aliases . put ( new ResourceLocation ( e . getString ( " K " ) ) , new ResourceLocation ( e . getString ( " V " ) ) ) ;
2014-10-01 08:07:23 +00:00
}
list = regs . getCompoundTag ( key ) . getTagList ( " substitutions " , 10 ) ;
for ( int x = 0 ; x < list . tagCount ( ) ; x + + )
{
NBTTagCompound e = list . getCompoundTagAt ( x ) ;
2015-11-28 08:01:31 +00:00
entry . substitutions . add ( new ResourceLocation ( e . getString ( " K " ) ) ) ;
2014-10-01 08:07:23 +00:00
}
int [ ] blocked = regs . getCompoundTag ( key ) . getIntArray ( " blocked " ) ;
for ( int i : blocked )
{
entry . blocked . add ( i ) ;
2014-08-01 23:36:18 +00:00
}
2016-02-17 20:06:57 +00:00
if ( regs . getCompoundTag ( key ) . hasKey ( " dummied " ) ) // Added in 1.8.9 dev, some worlds may not have it.
2015-12-31 22:58:30 +00:00
{
2016-02-17 20:06:57 +00:00
list = regs . getCompoundTag ( key ) . getTagList ( " dummied " , 10 ) ;
for ( int x = 0 ; x < list . tagCount ( ) ; x + + )
{
NBTTagCompound e = list . getCompoundTagAt ( x ) ;
entry . dummied . add ( new ResourceLocation ( e . getString ( " K " ) ) ) ;
}
2015-12-31 22:58:30 +00:00
}
2014-08-01 23:36:18 +00:00
}
2015-11-28 08:01:31 +00:00
failedElements = PersistentRegistryManager . injectSnapshot ( snapshot , true , true ) ;
2014-04-01 12:30:47 +00:00
}
if ( failedElements ! = null & & ! failedElements . isEmpty ( ) )
{
2014-04-01 19:56:53 +00:00
String text = " Forge Mod Loader could not load this save. \ n \ n " +
" There are " + failedElements . size ( ) + " unassigned blocks and items in this save. \ n " +
" You will not be able to load until they are present again. \ n \ n " +
" Missing Blocks/Items: \ n " ;
2014-04-01 12:30:47 +00:00
for ( String s : failedElements ) text + = s + " \ n " ;
StartupQuery . notify ( text ) ;
StartupQuery . abort ( ) ;
2012-12-07 06:52:16 +00:00
}
2012-10-03 01:54:47 +00:00
}
2012-12-07 06:52:16 +00:00
2012-12-24 03:27:02 +00:00
@Override
public Certificate getSigningCertificate ( )
{
Certificate [ ] certificates = getClass ( ) . getProtectionDomain ( ) . getCodeSource ( ) . getCertificates ( ) ;
return certificates ! = null ? certificates [ 0 ] : null ;
}
2013-07-10 19:47:13 +00:00
2013-08-27 16:31:37 +00:00
@Override
public File getSource ( )
{
return FMLSanityChecker . fmlLocation ;
}
2013-12-06 08:11:03 +00:00
2013-07-10 19:47:13 +00:00
@Override
public Class < ? > getCustomResourcePackClass ( )
{
2013-08-27 16:31:37 +00:00
return getSource ( ) . isDirectory ( ) ? FMLFolderResourcePack . class : FMLFileResourcePack . class ;
2013-07-10 19:47:13 +00:00
}
2014-01-02 16:51:16 +00:00
@Override
public String getGuiClassName ( )
{
2014-09-23 05:01:24 +00:00
return " net.minecraftforge.fml.client.FMLConfigGuiFactory " ;
2014-01-02 16:51:16 +00:00
}
2014-01-20 21:06:50 +00:00
@Override
public Object getMod ( )
{
return this ;
}
2012-07-22 14:26:38 +00:00
}