This commit is contained in:
s809
2024-02-22 23:06:40 +05:00
9 changed files with 113 additions and 67 deletions
+9 -1
View File
@@ -20,6 +20,14 @@ If you want to see a quick demo, check out a video covering the mod here:
### This branch supports the following versions of Minecraft:
#### 1.20.4, 1.20.3 (Default)
Fabric: 0.15.1\
Fabric API: 0.91.2+1.20.4\
Forge: 49.0.16\
NeoForge: 20.4.83-beta\
Parchment: 1.20.2:2023.12.10\
Modmenu: 9.0.0-pre.1
#### 1.20.2
Fabric: 0.14.24\
Fabric API: 0.90.4+1.20.2\
@@ -27,7 +35,7 @@ Forge: 48.0.13\
Parchment: 1.20.1:2023.09.03\
Modmenu: 8.0.0
#### 1.20.1, 1.20 (Default)
#### 1.20.1, 1.20
Fabric: 0.14.24\
Fabric API: 0.90.4+1.20.1\
Forge: 47.2.1\
@@ -66,13 +66,6 @@ public class UpdateModScreen extends DhScreen
try
{
// We cannot get assets from the root of the mod so we use this hack
// TODO: Load the icon.png and logo.png in the mod initialise rather than here
ResourceLocation logoLocation = new ResourceLocation(ModInfo.ID, "logo.png");
Minecraft.getInstance().getTextureManager().register(
logoLocation,
new DynamicTexture(NativeImage.read(JarUtils.accessFile("logo.png")))
);
// Logo image
@@ -84,7 +77,7 @@ public class UpdateModScreen extends DhScreen
// Offset
0, 0,
// Some textuary stuff
0, logoLocation, 130, 65,
0, new ResourceLocation(ModInfo.ID, "logo.png"), 130, 65,
// Create the button and tell it where to go
// For now it goes to the client option by default
(buttonWidget) -> System.out.println("Nice, you found an easter egg :)"), // TODO: Add a proper easter egg to pressing the logo (maybe with confetti)
@@ -70,6 +70,7 @@ import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.chunk.storage.IOWorker;
import net.minecraft.world.level.chunk.storage.RegionFileStorage;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.FlatLevelSource;
@@ -381,22 +382,50 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
{
ServerLevel level = this.params.level;
//====================//
// get the chunk data //
//====================//
CompoundTag chunkData = null;
try
{
// Warning: if multiple threads attempt to access this method at the same time,
// it can throw EOFExceptions that are caught and logged by Minecraft
//chunkData = level.getChunkSource().chunkMap.readChunk(chunkPos);
IOWorker ioWorker = level.getChunkSource().chunkMap.worker;
RegionFileStorage storage = this.params.level.getChunkSource().chunkMap.worker.storage;
RegionFileStorageExternalCache cache = this.getOrCreateRegionFileCache(storage);
chunkData = cache.read(chunkPos);
#if MC_VER <= MC_1_18_2
chunkData = ioWorker.load(chunkPos);
#else
// timeout should prevent locking up the thread if the ioWorker dies or has issues
int maxGetTimeInSec = Config.Client.Advanced.WorldGenerator.worldGenerationTimeoutLengthInSeconds.get();
CompletableFuture<Optional<CompoundTag>> future = ioWorker.loadAsync(chunkPos);
try
{
Optional<CompoundTag> data = future.get(maxGetTimeInSec, TimeUnit.SECONDS);
if (data.isPresent())
{
chunkData = data.get();
}
}
catch (Exception e)
{
LOAD_LOGGER.warn("Unable to get chunk at pos ["+chunkPos+"] after ["+maxGetTimeInSec+"] milliseconds.", e);
future.cancel(true);
}
#endif
}
catch (Exception e)
{
LOAD_LOGGER.error("DistantHorizons: Couldn't load or make chunk " + chunkPos + ". Error: " + e.getMessage(), e);
}
//========================//
// convert the chunk data //
//========================//
if (chunkData == null)
{
return EmptyChunk(level, chunkPos);
@@ -17,6 +17,12 @@ import java.nio.file.Path;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.ReentrantLock;
/**
* @deprecated should be replaced with net.minecraft.world.level.chunk.storage.IOWorker to
* prevent potential file corruption and issues with the C2ME mod.
* Generally this would be done via (MC ServerLevel) level.getChunkSource().chunkMap.worker#loadAsync()
*/
@Deprecated
public class RegionFileStorageExternalCache implements AutoCloseable
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
@@ -28,56 +28,66 @@ public class MixinChunkMap
@Final
ServerLevel level;
@Inject(method = "save", at = @At(value = "INVOKE", target = CHUNK_SERIALIZER_WRITE))
// firing at INVOKE causes issues with C2ME and is probably unnecessary since we
// don't need the chunk(s) before MC has finished saving them
@Inject(method = "save", at = @At(value = "RETURN", target = CHUNK_SERIALIZER_WRITE))
private void onChunkSave(ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
{
//=====================================//
// corrupt/incomplete chunk validation //
//=====================================//
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
// this logic should prevent that from happening
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
// true means a chunk was saved to disk
if (ci.getReturnValue())
{
return;
// TODO is this validation necessary since we are checking above if
// the callback return value should state if the chunk was actually saved or not?
// Do we trust it to always be correct?
//=====================================//
// corrupt/incomplete chunk validation //
//=====================================//
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
// this logic should prevent that from happening
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
{
return;
}
#else
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect())
{
return;
}
#endif
//==================//
// biome validation //
//==================//
// some chunks may be missing their biomes, which cause issues when attempting to save them
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
if (chunk.getBiomes() == null)
{
return;
}
#else
try
{
// this will throw an exception if the biomes aren't set up
chunk.getNoiseBiome(0,0,0);
}
catch (Exception e)
{
return;
}
#endif
ServerApi.INSTANCE.serverChunkSaveEvent(
new ChunkWrapper(chunk, this.level, ServerLevelWrapper.getWrapper(this.level)),
ServerLevelWrapper.getWrapper(this.level)
);
}
#else
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect())
{
return;
}
#endif
//==================//
// biome validation //
//==================//
// some chunks may be missing their biomes, which cause issues when attempting to save them
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
if (chunk.getBiomes() == null)
{
return;
}
#else
try
{
// this will throw an exception if the biomes aren't set up
chunk.getNoiseBiome(0,0,0);
}
catch (Exception e)
{
return;
}
#endif
ServerApi.INSTANCE.serverChunkSaveEvent(
new ChunkWrapper(chunk, this.level, ServerLevelWrapper.getWrapper(this.level)),
ServerLevelWrapper.getWrapper(this.level)
);
}
}
+1 -1
View File
@@ -17,7 +17,7 @@
},
"license": "LGPL-3",
"icon": "icon.png",
"icon": "assets/distanthorizons/icon.png",
"accessWidener": "distanthorizons.accesswidener",
+2 -2
View File
@@ -12,8 +12,8 @@ issueTrackerURL = "${issues}"
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
displayURL = "${homepage}"
description = "${description}" #//mandatory. The description text for the mod
logoFile = "logo.png"
catalogueImageIcon = "icon.png"
logoFile = "assets/distanthorizons/logo.png"
catalogueImageIcon = "assets/distanthorizons/icon.png"
credits = "Massive thanks to: Leonardo, Cola, Ran, CoolGi, and Leetom. For their hard work to bring Distant Horizons to where it is today. - James"
#// if not set defaults to "false"
clientSideOnly = "true"
@@ -12,8 +12,8 @@ issueTrackerURL = "${issues}"
#//updateJSONURL="https://change.me.example.invalid/updates.json" # A URL to query for updates for this mod. See the JSON update specification https://mcforge.readthedocs.io/en/latest/gettingstarted/autoupdate/
displayURL = "${homepage}"
description = "${description}" #//mandatory. The description text for the mod
logoFile = "logo.png"
catalogueImageIcon = "icon.png"
logoFile = "assets/distanthorizons/logo.png"
catalogueImageIcon = "assets/distanthorizons/icon.png"
credits = "Massive thanks to: Leonardo, Cola, Ran, CoolGi, and Leetom. For their hard work to bring Distant Horizons to where it is today. - James"
#// if not set defaults to "false"
clientSideOnly = "true"