Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip #3

Merged
merged 1 commit into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id 'eclipse'
id 'maven-publish'
id 'net.minecraftforge.gradle' version '5.1.+'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
}

version = '3.0.1-1.19'
Expand All @@ -27,6 +28,7 @@ minecraft {
// Use non-default mappings at your own risk. They may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'official', version: '1.19'
// mappings channel: 'parchment', version: '2022.08.28-1.19.2'

// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default.

Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ pluginManagement {
repositories {
gradlePluginPortal()
maven { url = 'https://maven.minecraftforge.net/' }
maven { url = 'https://maven.parchmentmc.org' }
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package ca.fireball1725.devworld.client.events;

import ca.fireball1725.devworld.util.DevWorldUtils;
import com.mojang.logging.LogUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.PlainTextButton;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.server.WorldStem;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.common.MinecraftForge;
import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
import org.slf4j.Logger;

public class DevWorldClientEvents {
Expand All @@ -17,30 +23,56 @@ public class DevWorldClientEvents {
private int keyShiftCount = 0;

public DevWorldClientEvents() {
MinecraftForge.EVENT_BUS.addListener(this::keyPress);
MinecraftForge.EVENT_BUS.addListener(this::renderMainMenu);
MinecraftForge.EVENT_BUS.addListener(this::initMainMenu);
}

public void keyPress(ScreenEvent.KeyPressed.Post event) {
if (event.getScreen() instanceof TitleScreen titleScreen) {
LOGGER.info(">>> Key Press: " + event.getKeyCode());

if (event.getKeyCode() == 340)
keyShiftCount ++;

if (keyShiftCount >= 2)
buttonDelete.active = true;
}
}

public void renderMainMenu(ScreenEvent.Render.Post event) {
if (event.getScreen() instanceof TitleScreen titleScreen) {
buttonDelete.visible = true;
buttonCreate.visible = true;

//GuiComponent.drawCenteredString();
}
}

public void initMainMenu(ScreenEvent.Init.Post event) {
public void initMainMenu(ScreenEvent.Init event) {
if (event.getScreen() instanceof TitleScreen titleScreen) {
int buttonY = event.getScreen().height / 4 + 48;
int buttonY = event.getScreen().height / 4 + 38;
int buttonX = event.getScreen().width / 2 + 104;

PlainTextButton devWorldText = new PlainTextButton(buttonX, buttonY, 84, 20, Component.literal("DevWorld 3"), button -> {}, Minecraft.getInstance().font);


buttonY += 10;
buttonCreate = new Button(buttonX, buttonY, 84, 20, Component.translatable("devworld.menu.new"), button -> {
LOGGER.info(">>> Create new devworld");
titleScreen.renderables.clear();
try {
DevWorldUtils devWorldUtils = new DevWorldUtils();
devWorldUtils.createDevWorld();
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
});
buttonLoad = new Button(buttonX, buttonY, 40, 20, Component.translatable("devworld.menu.load"), button -> {

buttonLoad = new Button(buttonX, buttonY, 84, 20, Component.translatable("devworld.menu.load"), button -> {
LOGGER.info(">>> Load devworld");
});
buttonX += 44;
buttonDelete = new Button(buttonX, buttonY, 40, 20, Component.translatable("devworld.menu.delete"), button -> {

buttonY += 24;
buttonDelete = new Button(buttonX, buttonY, 84, 20, Component.translatable("devworld.menu.delete"), button -> {
LOGGER.info(">>> Delete devworld");
keyShiftCount = 0;
});
Expand All @@ -52,9 +84,10 @@ public void initMainMenu(ScreenEvent.Init.Post event) {

keyShiftCount = 0;

titleScreen.renderables.add(buttonCreate);
titleScreen.renderables.add(buttonLoad);
titleScreen.renderables.add(buttonDelete);
event.addListener(devWorldText);
event.addListener(buttonCreate);
event.addListener(buttonLoad);
event.addListener(buttonDelete);
}
}
}
267 changes: 267 additions & 0 deletions src/main/java/ca/fireball1725/devworld/util/DevWorldUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
package ca.fireball1725.devworld.util;

import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Codec;
import com.mojang.serialization.Lifecycle;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.toasts.SystemToast;
import net.minecraft.client.gui.screens.GenericDirtMessageScreen;
import net.minecraft.client.gui.screens.worldselection.WorldCreationContext;
import net.minecraft.client.gui.screens.worldselection.WorldGenSettingsComponent;
import net.minecraft.commands.Commands;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ReloadableServerResources;
import net.minecraft.server.WorldLoader;
import net.minecraft.server.WorldStem;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.server.packs.repository.ServerPacksSource;
import net.minecraft.world.Difficulty;
import net.minecraft.world.level.*;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.*;
import net.minecraft.world.level.levelgen.blending.Blender;
import net.minecraft.world.level.levelgen.flat.FlatLayerInfo;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraft.world.level.levelgen.presets.WorldPreset;
import net.minecraft.world.level.levelgen.presets.WorldPresets;
import net.minecraft.world.level.levelgen.structure.BuiltinStructureSets;
import net.minecraft.world.level.levelgen.structure.StructureSet;
import net.minecraft.world.level.storage.LevelResource;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.PrimaryLevelData;
import net.minecraft.world.level.storage.WorldData;
import org.slf4j.Logger;

import javax.annotation.Nullable;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Stream;

public class DevWorldUtils {
private final String worldName = "DevWorld";
private final Minecraft minecraft = Minecraft.getInstance();
private static final Component PREPARING_WORLD_DATA = Component.translatable("createWorld.preparing");
@Nullable
private Path tempDataPackDir;
String resultFolder;
private static final Logger LOGGER = LogUtils.getLogger();


// Create the world
public void createDevWorld() throws Exception {
this.resultFolder = this.worldName.trim();
Minecraft.getInstance().setScreen(null);
queueLoadScreen(minecraft, PREPARING_WORLD_DATA);

Optional<LevelStorageSource.LevelStorageAccess> optional = this.createNewWorldDirectory();
if (!optional.isEmpty()) {
this.removeTempDataPackDir();


HolderSet<StructureSet> holderset = HolderSet.direct(BuiltinRegistries.STRUCTURE_SETS.getHolderOrThrow(BuiltinStructureSets.STRONGHOLDS), BuiltinRegistries.STRUCTURE_SETS.getHolderOrThrow(BuiltinStructureSets.VILLAGES));

FlatLevelGeneratorSettings flatlevelgeneratorsettings = new FlatLevelGeneratorSettings(Optional.of(holderset), BuiltinRegistries.BIOME);
flatlevelgeneratorsettings.setBiome(BuiltinRegistries.BIOME.getOrCreateHolderOrThrow(Biomes.DESERT));
flatlevelgeneratorsettings.getLayersInfo().add(new FlatLayerInfo(1, Blocks.BEDROCK));
flatlevelgeneratorsettings.getLayersInfo().add(new FlatLayerInfo(3, Blocks.COBBLESTONE));
flatlevelgeneratorsettings.getLayersInfo().add(new FlatLayerInfo(130, Blocks.SANDSTONE));
flatlevelgeneratorsettings.updateLayers();


PackRepository packrepository = new PackRepository(PackType.SERVER_DATA, new ServerPacksSource());
WorldLoader.InitConfig worldloader$initconfig = createDefaultLoadConfig(packrepository, new DataPackConfig(ImmutableList.of("vanilla"), ImmutableList.of()));


// FlatGenerationSettings flatGenerationSettings = FlatGenerationSettings.createFlatGeneratorFromString("minecraft:bedrock,3*minecraft:stone,52*minecraft:sandstone;minecraft:desert;");

CompletableFuture<WorldCreationContext> completablefuture = WorldLoader.load(worldloader$initconfig, (resourceManager, dataPackConfig) -> {
RegistryAccess.Frozen registryaccess$frozen = RegistryAccess.builtinCopy().freeze();
WorldGenSettings worldgensettings = WorldPresets.createNormalWorldFromPreset(registryaccess$frozen, 0, true, false);
ChunkGenerator chunkgenerator = new FlatLevelSource(BuiltinRegistries.STRUCTURE_SETS, flatlevelgeneratorsettings);

worldgensettings = WorldGenSettings.replaceOverworldGenerator(registryaccess$frozen, worldgensettings, chunkgenerator);


//worldgensettings = flatWorldConfigurator(flatlevelgeneratorsettings).apply(registryaccess$frozen, worldgensettings);
return Pair.of(worldgensettings, registryaccess$frozen);
}, (closeableResourceManager, datapackResources, registryAccess, levelSeed) -> {
closeableResourceManager.close();
return new WorldCreationContext(levelSeed, Lifecycle.stable(), registryAccess, datapackResources);
}, Util.backgroundExecutor(), this.minecraft);

this.minecraft.managedBlock(completablefuture::isDone);

WorldCreationContext worldCreationContext = completablefuture.get();



//WorldCreationContext worldCreationContext = new WorldGenSettingsComponent(completablefuture.join(), Optional.of(WorldPresets.FLAT), OptionalLong.empty()).createFinalSettings(false);

WorldGenSettings worldGenSettings = worldCreationContext.worldGenSettings();







LevelSettings levelSettings = this.createLevelSettings();
WorldData worldData = new PrimaryLevelData(levelSettings, worldGenSettings, worldCreationContext.worldSettingsStability());

this.minecraft.createWorldOpenFlows().createLevelFromExistingSettings(optional.get(), worldCreationContext.dataPackResources(), worldCreationContext.registryAccess(), worldData);
}
}

private void queueLoadScreen(Minecraft minecraft, Component component) {
minecraft.forceSetScreen(new GenericDirtMessageScreen(component));
}

private LevelSettings createLevelSettings() {
String s = worldName.trim();
GameRules gameRules = new GameRules();
gameRules.getRule(GameRules.RULE_DAYLIGHT).set(false, (MinecraftServer)null);
gameRules.getRule(GameRules.RULE_WEATHER_CYCLE).set(false, (MinecraftServer)null);
return new LevelSettings(s, GameType.CREATIVE, false, Difficulty.NORMAL, true, gameRules, DataPackConfig.DEFAULT);
}

private static WorldCreationContext.Updater flatWorldConfigurator(FlatLevelGeneratorSettings flatLevelGeneratorSettings) {
return (registryAccess, worldGenSettings) -> {
Registry<StructureSet> registry = registryAccess.registryOrThrow(Registry.STRUCTURE_SET_REGISTRY);
ChunkGenerator chunkgenerator = new FlatLevelSource(registry, flatLevelGeneratorSettings);
return WorldGenSettings.replaceOverworldGenerator(registryAccess, worldGenSettings, chunkgenerator);
};
}

private static WorldLoader.InitConfig createDefaultLoadConfig(PackRepository p_232873_, DataPackConfig p_232874_) {
WorldLoader.PackConfig worldloader$packconfig = new WorldLoader.PackConfig(p_232873_, p_232874_, false);
return new WorldLoader.InitConfig(worldloader$packconfig, Commands.CommandSelection.INTEGRATED, 2);
}

private Optional<LevelStorageSource.LevelStorageAccess> createNewWorldDirectory() {
try {
LevelStorageSource.LevelStorageAccess levelstoragesource$levelstorageaccess = this.minecraft.getLevelSource().createAccess(this.resultFolder);

if (this.tempDataPackDir == null) {
return Optional.of(levelstoragesource$levelstorageaccess);
}

try {
Stream<Path> stream = Files.walk(this.tempDataPackDir);

Optional optional;
try {
Path path = levelstoragesource$levelstorageaccess.getLevelPath(LevelResource.DATAPACK_DIR);
Files.createDirectories(path);
stream.filter((p_232921_) -> {
return !p_232921_.equals(this.tempDataPackDir);
}).forEach((p_232945_) -> {
copyBetweenDirs(this.tempDataPackDir, path, p_232945_);
});
optional = Optional.of(levelstoragesource$levelstorageaccess);
} catch (Throwable throwable1) {
if (stream != null) {
try {
stream.close();
} catch (Throwable throwable) {
throwable1.addSuppressed(throwable);
}
}

throw throwable1;
}

if (stream != null) {
stream.close();
}

return optional;
} catch (UncheckedIOException | IOException ioexception) {
LOGGER.warn("Failed to copy datapacks to world {}", this.resultFolder, ioexception);
levelstoragesource$levelstorageaccess.close();
}
} catch (UncheckedIOException | IOException ioexception1) {
LOGGER.warn("Failed to create access for {}", this.resultFolder, ioexception1);
}

SystemToast.onPackCopyFailure(this.minecraft, this.resultFolder);
this.popScreen();
return Optional.empty();
}

private static void copyBetweenDirs(Path pFromDir, Path pToDir, Path pFilePath) {
try {
Util.copyBetweenDirs(pFromDir, pToDir, pFilePath);
} catch (IOException ioexception) {
LOGGER.warn("Failed to copy datapack file from {} to {}", pFilePath, pToDir);
throw new UncheckedIOException(ioexception);
}
}

public void popScreen() {
// this.minecraft.setScreen(this.lastScreen);
this.removeTempDataPackDir();
}

private void removeTempDataPackDir() {
if (this.tempDataPackDir != null) {
try {
Stream<Path> stream = Files.walk(this.tempDataPackDir);

try {
stream.sorted(Comparator.reverseOrder()).forEach((p_232942_) -> {
try {
Files.delete(p_232942_);
} catch (IOException ioexception1) {
LOGGER.warn("Failed to remove temporary file {}", p_232942_, ioexception1);
}

});
} catch (Throwable throwable1) {
if (stream != null) {
try {
stream.close();
} catch (Throwable throwable) {
throwable1.addSuppressed(throwable);
}
}

throw throwable1;
}

if (stream != null) {
stream.close();
}
} catch (IOException ioexception) {
LOGGER.warn("Failed to list temporary dir {}", (Object)this.tempDataPackDir);
}

this.tempDataPackDir = null;
}

}
}