Skip the experimental complain screen
This commit is contained in:
parent
29e6569f3c
commit
94dcd5f2d7
3 changed files with 199 additions and 5 deletions
149
src/main/java/biomesoplenty/client/handler/GuiEventHandler.java
Normal file
149
src/main/java/biomesoplenty/client/handler/GuiEventHandler.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,28 +8,66 @@
|
||||||
package biomesoplenty.common.world;
|
package biomesoplenty.common.world;
|
||||||
|
|
||||||
import biomesoplenty.core.BiomesOPlenty;
|
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.DedicatedServer;
|
||||||
import net.minecraft.server.dedicated.ServerProperties;
|
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.ChunkGenerator;
|
||||||
import net.minecraft.world.gen.DimensionSettings;
|
import net.minecraft.world.gen.DimensionSettings;
|
||||||
import net.minecraft.world.gen.NoiseChunkGenerator;
|
import net.minecraft.world.gen.NoiseChunkGenerator;
|
||||||
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
|
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
|
||||||
import net.minecraft.world.storage.ServerWorldInfo;
|
import net.minecraft.world.storage.ServerWorldInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class BOPWorldTypeUtil
|
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");
|
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");
|
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)
|
public static ChunkGenerator createChunkGenerator(long seed)
|
||||||
{
|
{
|
||||||
return new NoiseChunkGenerator(new BOPBiomeProvider(seed), seed, DimensionSettings.Preset.OVERWORLD.settings());
|
return new NoiseChunkGenerator(new BOPBiomeProvider(seed), seed, DimensionSettings.Preset.OVERWORLD.settings());
|
||||||
|
@ -43,7 +81,7 @@ public class BOPWorldTypeUtil
|
||||||
public static void setupForDedicatedServer(DedicatedServer server)
|
public static void setupForDedicatedServer(DedicatedServer server)
|
||||||
{
|
{
|
||||||
// Ensure we are using the bop world type
|
// Ensure we are using the bop world type
|
||||||
if (!isUsingBopWorldType(server))
|
if (!isServerLevelTypeBop(server))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ServerProperties properties = server.getProperties();
|
ServerProperties properties = server.getProperties();
|
||||||
|
|
|
@ -4,6 +4,13 @@ public net.minecraft.world.gen.feature.TreeFeature *()
|
||||||
public-f net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens *
|
public-f net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens *
|
||||||
public net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens <init>(Ljava/lang/String;)V
|
public net.minecraft.client.gui.screen.BiomeGeneratorTypeScreens <init>(Ljava/lang/String;)V
|
||||||
public net.minecraft.block.Blocks *()
|
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
|
# server.properties world type hackery
|
||||||
public-f net.minecraft.server.dedicated.ServerProperties *
|
public-f net.minecraft.server.dedicated.ServerProperties *
|
||||||
|
|
Loading…
Reference in a new issue