2012-07-22 14:26:38 +00:00
/ *
2013-03-08 00:25:48 +00:00
* Forge Mod Loader
* Copyright ( c ) 2012 - 2013 cpw .
* All rights reserved . This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v2 . 1
* which accompanies this distribution , and is available at
* http : //www.gnu.org/licenses/old-licenses/gpl-2.0.html
2013-07-10 19:47:13 +00:00
*
2013-03-08 00:25:48 +00:00
* Contributors :
* cpw - implementation
2012-07-22 14:26:38 +00:00
* /
package cpw.mods.fml.common ;
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-03-24 23:36:37 +00:00
import java.util.HashMap ;
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
2013-12-27 16:48:55 +00:00
import net.minecraft.item.Item ;
2012-12-10 03:00:51 +00:00
import net.minecraft.nbt.NBTBase ;
import net.minecraft.nbt.NBTTagCompound ;
import net.minecraft.nbt.NBTTagList ;
2012-12-09 04:21:03 +00:00
import net.minecraft.world.storage.SaveHandler ;
import net.minecraft.world.storage.WorldInfo ;
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
2013-12-10 02:36:49 +00:00
import com.google.common.collect.Maps ;
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
2013-08-27 16:31:37 +00:00
import cpw.mods.fml.client.FMLFileResourcePack ;
import cpw.mods.fml.client.FMLFolderResourcePack ;
import cpw.mods.fml.common.asm.FMLSanityChecker ;
2013-12-09 06:22:24 +00:00
import cpw.mods.fml.common.event.FMLConstructionEvent ;
import cpw.mods.fml.common.network.NetworkCheckHandler ;
2013-12-06 08:11:03 +00:00
import cpw.mods.fml.common.network.NetworkRegistry ;
2013-12-12 00:07:59 +00:00
import cpw.mods.fml.common.network.internal.FMLNetworkHandler ;
2012-12-10 03:00:51 +00:00
import cpw.mods.fml.common.registry.GameData ;
2013-12-06 08:11:03 +00:00
import cpw.mods.fml.relauncher.Side ;
2012-12-07 06:52:16 +00:00
2012-07-22 14:26:38 +00:00
/ * *
* @author cpw
*
* /
2013-12-06 08:11:03 +00:00
public 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-01-09 19:55:52 +00:00
meta . authorList = Arrays . asList ( " cpw " , " LexManos " ) ;
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 " ;
meta . updateUrl = " 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
}
@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 ( ) ;
NBTTagList list = new NBTTagList ( ) ;
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 ( ) ) ;
list . appendTag ( mod ) ;
2012-10-03 01:54:47 +00:00
}
2014-03-19 07:15:53 +00:00
fmlData . setTag ( " ModList " , list ) ;
2014-03-24 23:36:37 +00:00
// name <-> id mappings
2013-12-10 02:36:49 +00:00
NBTTagList dataList = new NBTTagList ( ) ;
2014-03-19 07:15:53 +00:00
FMLLog . fine ( " Gathering id map for writing to world save %s " , info . getWorldName ( ) ) ;
2013-12-10 02:36:49 +00:00
Map < String , Integer > itemList = GameData . buildItemDataList ( ) ;
for ( Entry < String , Integer > item : itemList . entrySet ( ) )
{
NBTTagCompound tag = new NBTTagCompound ( ) ;
2014-03-19 07:15:53 +00:00
tag . setString ( " K " , item . getKey ( ) ) ;
tag . setInteger ( " V " , item . getValue ( ) ) ;
dataList . appendTag ( tag ) ;
2013-12-10 02:36:49 +00:00
}
2014-03-19 07:15:53 +00:00
fmlData . setTag ( " ItemData " , dataList ) ;
2014-03-24 23:36:37 +00:00
// blocked ids
2014-04-01 05:00:20 +00:00
fmlData . setIntArray ( " BlockedItemIds " , GameData . getBlockedIds ( ) ) ;
2014-03-24 23:36:37 +00:00
// block aliases
NBTTagList blockAliasList = new NBTTagList ( ) ;
for ( Entry < String , String > entry : GameData . getBlockRegistry ( ) . getAliases ( ) . entrySet ( ) )
{
NBTTagCompound tag = new NBTTagCompound ( ) ;
2014-04-01 05:00:20 +00:00
tag . setString ( " K " , entry . getKey ( ) ) ;
tag . setString ( " V " , entry . getValue ( ) ) ;
blockAliasList . appendTag ( tag ) ;
2014-03-24 23:36:37 +00:00
}
2014-04-01 05:00:20 +00:00
fmlData . setTag ( " BlockAliases " , blockAliasList ) ;
2014-03-24 23:36:37 +00:00
// item aliases
NBTTagList itemAliasList = new NBTTagList ( ) ;
for ( Entry < String , String > entry : GameData . getItemRegistry ( ) . getAliases ( ) . entrySet ( ) )
{
NBTTagCompound tag = new NBTTagCompound ( ) ;
2014-04-01 05:00:20 +00:00
tag . setString ( " K " , entry . getKey ( ) ) ;
tag . setString ( " V " , entry . getValue ( ) ) ;
itemAliasList . appendTag ( tag ) ;
2014-03-24 23:36:37 +00:00
}
2014-04-01 05:00:20 +00:00
fmlData . setTag ( " ItemAliases " , itemAliasList ) ;
2014-03-24 23:36:37 +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-03-19 07:15:53 +00:00
if ( tag . hasKey ( " ModItemData " ) )
2012-12-07 06:52:16 +00:00
{
2013-12-27 16:48:55 +00:00
FMLLog . info ( " Attempting to convert old world data to new system. This may be trouble! " ) ;
2014-03-19 07:15:53 +00:00
NBTTagList modList = tag . getTagList ( " ModItemData " , ( byte ) 10 ) ;
2013-12-27 16:48:55 +00:00
Map < String , Integer > dataList = Maps . newLinkedHashMap ( ) ;
2014-03-19 07:15:53 +00:00
for ( int i = 0 ; i < modList . tagCount ( ) ; i + + )
2013-12-27 16:48:55 +00:00
{
2014-03-19 07:15:53 +00:00
NBTTagCompound itemTag = modList . getCompoundTagAt ( i ) ;
String modId = itemTag . getString ( " ModId " ) ;
String itemType = itemTag . getString ( " ItemType " ) ;
int itemId = itemTag . getInteger ( " ItemId " ) ;
int ordinal = itemTag . getInteger ( " ordinal " ) ;
String forcedModId = itemTag . hasKey ( " ForcedModId " ) ? itemTag . getString ( " ForcedModId " ) : null ;
String forcedName = itemTag . hasKey ( " ForcedName " ) ? itemTag . getString ( " ForcedName " ) : null ;
2013-12-27 16:48:55 +00:00
if ( forcedName = = null )
{
FMLLog . warning ( " Found unlabelled item in world save, this may cause problems. The item type %s:%d will not be present " , itemType , ordinal ) ;
}
else
{
boolean isItem ;
try {
Class < ? > clazz = Class . forName ( itemType ) ;
clazz . asSubclass ( Item . class ) ;
isItem = true ;
}
catch ( ClassNotFoundException cnfs )
{
FMLLog . warning ( " The old item %s is not present in this game, it's type cannot be inferred - it will be skipped " , itemType ) ;
// MISSING, skip
continue ;
}
catch ( ClassCastException ccs )
{
isItem = false ;
}
String itemLabel = String . format ( " %c%s:%s " , isItem ? '\u0002' : '\u0001' , forcedModId ! = null ? forcedModId : modId , forcedName ) ;
dataList . put ( itemLabel , itemId ) ;
}
}
2014-04-01 12:30:47 +00:00
failedElements = GameData . injectWorldIDMap ( dataList , true , true ) ;
2012-12-07 06:52:16 +00:00
}
2014-03-19 07:15:53 +00:00
else if ( tag . hasKey ( " ItemData " ) )
2012-12-07 06:52:16 +00:00
{
2014-03-24 23:36:37 +00:00
// name <-> id mappings
2014-04-01 05:00:20 +00:00
NBTTagList list = tag . getTagList ( " ItemData " , 10 ) ;
2013-12-10 02:36:49 +00:00
Map < String , Integer > dataList = Maps . newLinkedHashMap ( ) ;
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-03-19 07:15:53 +00:00
NBTTagCompound dataTag = list . getCompoundTagAt ( i ) ;
dataList . put ( dataTag . getString ( " K " ) , dataTag . 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 > ( ) ;
2014-04-01 05:00:20 +00:00
if ( ! tag . hasKey ( " BlockedItemIds " ) ) // no blocked id info -> old 1.7 save
2014-03-30 15:17:54 +00:00
{
2014-04-01 19:56:53 +00:00
// old early 1.7 save potentially affected by the registry mapping bug
2014-03-30 15:17:54 +00:00
// fix the ids the best we can...
2014-04-04 23:47:19 +00:00
GameData . fixBrokenIds ( dataList , blockedIds ) ;
2014-03-30 15:17:54 +00:00
}
2014-03-24 23:36:37 +00:00
// blocked ids
2014-04-04 23:47:19 +00:00
for ( int id : tag . getIntArray ( " BlockedItemIds " ) )
{
blockedIds . add ( id ) ;
}
2014-03-24 23:36:37 +00:00
// block aliases
Map < String , String > blockAliases = new HashMap < String , String > ( ) ;
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 ) ;
blockAliases . put ( dataTag . getString ( " K " ) , dataTag . getString ( " V " ) ) ;
2014-03-24 23:36:37 +00:00
}
// item aliases
Map < String , String > itemAliases = new HashMap < String , String > ( ) ;
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 ) ;
itemAliases . put ( dataTag . getString ( " K " ) , dataTag . getString ( " V " ) ) ;
2014-03-24 23:36:37 +00:00
}
2014-03-24 20:16:36 +00:00
2014-04-01 12:30:47 +00:00
failedElements = GameData . injectWorldIDMap ( dataList , blockedIds , blockAliases , itemAliases , true , true ) ;
}
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 ( )
{
return " cpw.mods.fml.client.FMLConfigGuiFactory " ;
}
2014-01-20 21:06:50 +00:00
@Override
public Object getMod ( )
{
return this ;
}
2012-07-22 14:26:38 +00:00
}