Skip the experimental complain screen

This commit is contained in:
Adubbz 2020-07-10 18:41:04 +10:00
parent 29e6569f3c
commit 94dcd5f2d7
3 changed files with 199 additions and 5 deletions

View File

@ -0,0 +1,149 @@
package biomesoplenty.client.handler;
import biomesoplenty.common.world.BOPWorldTypeUtil;
import biomesoplenty.core.BiomesOPlenty;
import com.mojang.datafixers.util.Function4;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.*;
import net.minecraft.command.Commands;
import net.minecraft.resources.*;
import net.minecraft.server.IDynamicRegistries;
import net.minecraft.util.datafix.codec.DatapackCodec;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
import net.minecraft.world.storage.FolderName;
import net.minecraft.world.storage.IServerConfiguration;
import net.minecraft.world.storage.SaveFormat;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.Optional;
import java.util.function.Function;
@OnlyIn(Dist.CLIENT)
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE)
public class GuiEventHandler
{
private static String levelId = null;
private static ConfirmBackupScreen confirmScreen = null;
@SubscribeEvent
public static void onGuiOpened(GuiOpenEvent event)
{
Screen gui = event.getGui();
Minecraft mc = Minecraft.getInstance();
// Retain the last level that was selected
if (isDataReadScreen(gui))
{
Screen prevScreen = mc.screen;
if (prevScreen instanceof WorldSelectionScreen)
{
WorldSelectionScreen worldSelectionScreen = (WorldSelectionScreen)prevScreen;
Optional<WorldSelectionList.Entry> entry = worldSelectionScreen.list.getSelectedOpt();
if (entry.isPresent())
{
levelId = entry.get().summary.getLevelId();
}
}
else
{
cleanupGuiTracking();
}
}
else if (gui instanceof ConfirmBackupScreen && levelId != null)
{
confirmScreen = (ConfirmBackupScreen)gui;
// Don't show the confirmation screen immediately
event.setCanceled(true);
}
else
{
cleanupGuiTracking();
}
}
@SubscribeEvent
public static void onGuiDraw(GuiScreenEvent.DrawScreenEvent event)
{
Screen gui = event.getGui();
Minecraft mc = Minecraft.getInstance();
// We need to check if the bop world type is being used after the save has been unlocked.
// It is still locked during GuiOpenEvent.
if (isDataReadScreen(gui) && levelId != null && confirmScreen != null)
{
// Skip the confirm screen if this is the bop world type
if (isBopWorldType(mc, levelId))
{
confirmScreen.listener.proceed(false, false);
}
else
{
// Otherwise show the confirm screen
mc.setScreen(confirmScreen);
}
event.setCanceled(true);
cleanupGuiTracking();
}
}
private static void cleanupGuiTracking()
{
levelId = null;
confirmScreen = null;
}
private static boolean isDataReadScreen(Screen gui)
{
// The data read screen is a dirt message screen.
if (!(gui instanceof DirtMessageScreen))
return false;
ITextComponent title = gui.getTitle();
// Ensure text component is set as expected
if (!(title instanceof TranslationTextComponent) || !((TranslationTextComponent)title).getKey().equals("selectWorld.data_read"))
{
return false;
}
return true;
}
private static boolean isBopWorldType(Minecraft mc, String levelId)
{
try
(
SaveFormat.LevelSave save = mc.getLevelSource().createAccess(levelId);
Minecraft.PackManager packManager = createPackManager(IDynamicRegistries.builtin(), Minecraft::loadDataPacks, Minecraft::loadWorldData, save);
)
{
DimensionGeneratorSettings settings = packManager.worldData().worldGenSettings();
return BOPWorldTypeUtil.isUsingBopWorldType(settings);
}
catch (Exception exception)
{
BiomesOPlenty.logger.warn("Failed to load save.", (Throwable)exception);
return false;
}
}
private static Minecraft.PackManager createPackManager(IDynamicRegistries.Impl registries, Function<SaveFormat.LevelSave, DatapackCodec> dataPackLoader, Function4<SaveFormat.LevelSave, IDynamicRegistries.Impl, IResourceManager, DatapackCodec, IServerConfiguration> worldDataLoader, SaveFormat.LevelSave save)
{
DatapackCodec dataPackCodec = dataPackLoader.apply(save);
ResourcePackList<ResourcePackInfo> resourcePackList = new ResourcePackList<>(ResourcePackInfo::new, new ServerPackFinder(), new FolderPackFinder(save.getLevelPath(FolderName.DATAPACK_DIR).toFile(), IPackNameDecorator.WORLD));
DataPackRegistries dataPackRegistries = new DataPackRegistries(Commands.EnvironmentType.INTEGRATED, 2);
IServerConfiguration serverConfiguration = worldDataLoader.apply(save, registries, dataPackRegistries.getResourceManager(), dataPackCodec);
return new Minecraft.PackManager(resourcePackList, dataPackRegistries, serverConfiguration);
}
}

View File

@ -8,28 +8,66 @@
package biomesoplenty.common.world;
import biomesoplenty.core.BiomesOPlenty;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.dedicated.ServerProperties;
import net.minecraft.util.RegistryKey;
import net.minecraft.world.Dimension;
import net.minecraft.world.DimensionType;
import net.minecraft.world.biome.provider.EndBiomeProvider;
import net.minecraft.world.biome.provider.NetherBiomeProvider;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.DimensionSettings;
import net.minecraft.world.gen.NoiseChunkGenerator;
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
import net.minecraft.world.storage.ServerWorldInfo;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
public class BOPWorldTypeUtil
{
private static boolean isUsingBopWorldType(DedicatedServer server)
private static boolean isServerLevelTypeBop(DedicatedServer server)
{
String levelType = Optional.ofNullable((String)server.getProperties().properties.get("level-type")).map((str) -> str.toLowerCase(Locale.ROOT)).orElse("default");
return levelType.equals("biomesoplenty") || levelType.equals("biomesop");
}
// Derived from Dimension.stable
public static boolean isUsingBopWorldType(DimensionGeneratorSettings settings)
{
List<Map.Entry<RegistryKey<Dimension>, Dimension>> dimensions = Lists.newArrayList(settings.dimensions().entrySet());
Map.Entry<RegistryKey<Dimension>, Dimension> dimensionEntry0 = dimensions.get(0);
Map.Entry<RegistryKey<Dimension>, Dimension> dimensionEntry1 = dimensions.get(1);
Map.Entry<RegistryKey<Dimension>, Dimension> dimensionEntry2 = dimensions.get(2);
// BoP uses the standard dimension layout
if (dimensionEntry0.getKey() != Dimension.OVERWORLD || dimensionEntry1.getKey() != Dimension.NETHER && dimensionEntry2.getKey() != Dimension.END)
{
return false;
}
Dimension overworld = dimensionEntry0.getValue();
Dimension nether = dimensionEntry1.getValue();
Dimension end = dimensionEntry2.getValue();
// Ensure noise chunk generators are used in all dimensions
if (!(overworld.generator() instanceof NoiseChunkGenerator) || !(nether.generator() instanceof NoiseChunkGenerator) || !(end.generator() instanceof NoiseChunkGenerator))
{
return false;
}
// Ensure our nether and overworld biome providers are being used
if (!(overworld.generator().getBiomeSource() instanceof BOPBiomeProvider) || !(nether.generator().getBiomeSource() instanceof BOPNetherBiomeProvider))
{
return false;
}
return true;
}
public static ChunkGenerator createChunkGenerator(long seed)
{
return new NoiseChunkGenerator(new BOPBiomeProvider(seed), seed, DimensionSettings.Preset.OVERWORLD.settings());
@ -43,7 +81,7 @@ public class BOPWorldTypeUtil
public static void setupForDedicatedServer(DedicatedServer server)
{
// Ensure we are using the bop world type
if (!isUsingBopWorldType(server))
if (!isServerLevelTypeBop(server))
return;
ServerProperties properties = server.getProperties();

View File

@ -4,6 +4,13 @@ public net.minecraft.world.gen.feature.TreeFeature *()
public-f net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens *
public net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens <init>(Ljava/lang/String;)V
public net.minecraft.block.Blocks *()
public net.minecraft.client.Minecraft$PackManager *()
# Set worldtype as default and skip the confirm backup screen
public-f net.minecraft.client.gui.screen.ConfirmBackupScreen *
public-f net.minecraft.client.gui.screen.WorldOptionsScreen *
public net.minecraft.client.gui.screen.WorldSelectionScreen *
public net.minecraft.client.gui.screen.WorldSelectionList$Entry *
# server.properties world type hackery
public-f net.minecraft.server.dedicated.ServerProperties *