2018-06-21 19:37:32 +00:00
/ *
* Minecraft Forge
* Copyright ( c ) 2016 - 2018 .
*
* 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
* /
package net.minecraftforge.fml ;
import java.util.HashMap ;
import java.util.Map ;
import java.util.Map.Entry ;
import java.util.Optional ;
import com.google.common.collect.Multimap ;
2018-08-27 17:10:07 +00:00
import net.minecraft.nbt.INBTBase ;
2018-06-21 19:37:32 +00:00
import net.minecraft.nbt.NBTTagCompound ;
import net.minecraft.nbt.NBTTagList ;
import net.minecraft.util.ResourceLocation ;
import net.minecraft.world.storage.SaveHandler ;
import net.minecraft.world.storage.WorldInfo ;
import net.minecraftforge.registries.ForgeRegistry ;
import net.minecraftforge.registries.GameData ;
import net.minecraftforge.registries.RegistryManager ;
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
import org.apache.logging.log4j.Marker ;
import org.apache.logging.log4j.MarkerManager ;
/ * *
* @author cpw
*
* /
public final class FMLWorldPersistenceHook implements WorldPersistenceHooks . WorldPersistenceHook
{
2018-08-27 17:10:07 +00:00
private static final Logger LOGGER = LogManager . getLogger ( ) ;
2018-06-21 19:37:32 +00:00
private static final Marker WORLDPERSISTENCE = MarkerManager . getMarker ( " WP " ) ;
@Override
public String getModId ( )
{
return " fml " ;
}
@Override
public NBTTagCompound getDataForWriting ( SaveHandler handler , WorldInfo info )
{
NBTTagCompound fmlData = new NBTTagCompound ( ) ;
NBTTagList modList = new NBTTagList ( ) ;
ModList . get ( ) . getMods ( ) . forEach ( mi - >
{
final NBTTagCompound mod = new NBTTagCompound ( ) ;
mod . setString ( " ModId " , mi . getModId ( ) ) ;
mod . setString ( " ModVersion " , mi . getVersion ( ) . getVersionString ( ) ) ;
2018-08-27 17:10:07 +00:00
modList . add ( mod ) ;
2018-06-21 19:37:32 +00:00
} ) ;
fmlData . setTag ( " LoadingModList " , modList ) ;
NBTTagCompound registries = new NBTTagCompound ( ) ;
fmlData . setTag ( " Registries " , registries ) ;
LOGGER . debug ( WORLDPERSISTENCE , " Gathering id map for writing to world save {} " , info . getWorldName ( ) ) ;
for ( Map . Entry < ResourceLocation , ForgeRegistry . Snapshot > e : RegistryManager . ACTIVE . takeSnapshot ( true ) . entrySet ( ) )
{
registries . setTag ( e . getKey ( ) . toString ( ) , e . getValue ( ) . write ( ) ) ;
}
return fmlData ;
}
@Override
2018-08-27 17:10:07 +00:00
public void readData ( SaveHandler handler , WorldInfo info , NBTTagCompound tag )
2018-06-21 19:37:32 +00:00
{
if ( tag . hasKey ( " LoadingModList " ) )
{
NBTTagList modList = tag . getTagList ( " LoadingModList " , ( byte ) 10 ) ;
2018-08-27 17:10:07 +00:00
for ( int i = 0 ; i < modList . size ( ) ; i + + )
2018-06-21 19:37:32 +00:00
{
NBTTagCompound mod = modList . getCompoundTagAt ( i ) ;
String modId = mod . getString ( " ModId " ) ;
String modVersion = mod . getString ( " ModVersion " ) ;
Optional < ? extends ModContainer > container = ModList . get ( ) . getModContainerById ( modId ) ;
if ( ! container . isPresent ( ) )
{
LOGGER . error ( WORLDPERSISTENCE , " This world was saved with mod {} which appears to be missing, things may not work well " , modId ) ;
continue ;
}
if ( ! modVersion . equals ( container . get ( ) . getModInfo ( ) . getVersion ( ) . getVersionString ( ) ) )
{
LOGGER . info ( WORLDPERSISTENCE , " This world was saved with mod {} version {} and it is now at version {}, things may not work well " , modId , modVersion , container . get ( ) . getModInfo ( ) . getVersion ( ) . getVersionString ( ) ) ;
}
}
}
Multimap < ResourceLocation , ResourceLocation > failedElements = null ;
if ( tag . hasKey ( " ModItemData " ) | | tag . hasKey ( " ItemData " ) ) // Pre 1.7
{
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 ( ) ;
}
else if ( tag . hasKey ( " Registries " ) ) // 1.8, genericed out the 'registries' list
{
Map < ResourceLocation , ForgeRegistry . Snapshot > snapshot = new HashMap < > ( ) ;
NBTTagCompound regs = tag . getCompoundTag ( " Registries " ) ;
for ( String key : regs . getKeySet ( ) )
{
snapshot . put ( new ResourceLocation ( key ) , ForgeRegistry . Snapshot . read ( regs . getCompoundTag ( key ) ) ) ;
}
failedElements = GameData . injectSnapshot ( snapshot , true , true ) ;
}
if ( failedElements ! = null & & ! failedElements . isEmpty ( ) )
{
StringBuilder buf = new StringBuilder ( ) ;
buf . append ( " Forge Mod Loader could not load this save. \ n \ n " )
. append ( " There are " ) . append ( failedElements . size ( ) ) . append ( " unassigned registry entries in this save. \ n " )
. append ( " You will not be able to load until they are present again. \ n \ n " ) ;
failedElements . asMap ( ) . forEach ( ( name , entries ) - >
{
buf . append ( " Missing " ) . append ( name ) . append ( " : \ n " ) ;
entries . forEach ( rl - > buf . append ( " " ) . append ( rl ) . append ( " \ n " ) ) ;
} ) ;
StartupQuery . notify ( buf . toString ( ) ) ;
StartupQuery . abort ( ) ;
}
}
}