fix: retain the saved multipart scheduler clock

This commit is contained in:
Algent committed 2026-09-14 16:51:45 +02:00
1 parent a4e50ac85c
commit f96faff85e
3 files changed
+62 -6

No files matched your search

+1
View File
@@ -17,6 +17,7 @@ audit, before extending this list.
| Raw microblock recipe material lookup | Skips `MissingMicroMaterial`, whose recovery item is stone, so sawing stone selects the real stone material. Existing missing-material microblocks retain their recovery behavior. This fixes a pre-existing Scala bug. |
| `BlockMicroMaterial.createAndRegister(Block, Seq, String)` | Registers every supplied metadata value instead of only zero, including dark-oak logs and leaves and their legacy-name remaps. This fixes a pre-existing Scala bug; material IDs are rebuilt through the existing registry mapping. |
| Chunk scheduled-tick restoration | Reactivates chunks with restored scheduled ticks so their callbacks resume at the saved deadlines. The Scala implementation restored entries without activating their chunk. NBT layout and duplicate-scheduling behavior are unchanged. |
| World scheduler clock loading | Retains successfully loaded `schedTime` instead of overwriting it with total world time. Missing or unreadable files still fall back to world time. This fixes a pre-existing Scala bug and preserves the clock used by saved absolute tick deadlines; the file format is unchanged. |
| `IDWriter` before `setMax` | `read`/`write` throw `IllegalStateException` instead of `NullPointerException`. Uninitialized use is unsupported. |
| `PacketScheduler` invalid `maskWidth` | Throws `IllegalArgumentException` instead of `scala.MatchError`. Valid widths remain 1, 2, 4 and 8. |
| `NormalOcclusionTest.apply(Traversable, Traversable)` | Materializes both inputs into Java lists before testing instead of nested Scala `forall`. Finite, side-effect-free collections give the same result; eager traversal can change side effects, failure timing and termination for unusual inputs. |
@@ -146,15 +146,12 @@ public final class TickScheduler {
@Override
public void load() {
try {
FileInputStream in = new FileInputStream(saveFile());
try (FileInputStream in = new FileInputStream(saveFile())) {
loadTag(CompressedStreamTools.readCompressed(in));
in.close();
} catch (Exception e) {
// Matches the reference, which swallows any failure to read the saved schedule.
// Keep the world-time fallback for missing or unreadable saved schedules.
loadTag(new NBTTagCompound());
}
loadTag(new NBTTagCompound());
}
void loadTag(NBTTagCompound tag) {
@@ -0,0 +1,58 @@
package codechicken.multipart;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import net.minecraft.nbt.NBTTagCompound;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
class TickSchedulerClockRegressionTest {
@Test
void savedClockSurvivesReload(@TempDir Path directory) {
File file = directory.resolve("multipart.dat").toFile();
TickScheduler.WorldTickScheduler writer = scheduler(file);
NBTTagCompound tag = new NBTTagCompound();
tag.setLong("schedTime", 1234);
writer.loadTag(tag);
writer.save();
TickScheduler.WorldTickScheduler reader = scheduler(file);
reader.load();
assertEquals(1234, reader.saveTag().getLong("schedTime"));
}
@Test
void missingOrUnreadableClockStillUsesTheFallback(@TempDir Path directory) throws Exception {
File file = directory.resolve("multipart.dat").toFile();
TickScheduler.WorldTickScheduler scheduler = scheduler(file);
scheduler.load();
assertEquals(900, scheduler.saveTag().getLong("schedTime"));
Files.write(file.toPath(), new byte[] { 1, 2, 3 });
scheduler.load();
assertEquals(900, scheduler.saveTag().getLong("schedTime"));
}
private static TickScheduler.WorldTickScheduler scheduler(File file) {
return new TickScheduler.WorldTickScheduler(null) {
@Override
File saveFile() {
return file;
}
@Override
void loadTag(NBTTagCompound tag) {
// Supply a deterministic fallback clock without starting a Minecraft world.
if (!tag.hasKey("schedTime")) {
tag.setLong("schedTime", 900);
}
super.loadTag(tag);
}
};
}
}