Add Chunk data save and load events, closes #89 (#92)

* Created Chunk save and load event. Closes #89

* Fixed missing licence

* Update common/src/main/java/me/shedaniel/architectury/event/events/ChunkEvent.java

* Update common/src/main/java/me/shedaniel/architectury/event/events/ChunkEvent.java

* Update common/src/main/java/me/shedaniel/architectury/event/events/ChunkEvent.java

* Supply ServerLevel in ChunkEvent.LOAD, style cleanup

Signed-off-by: shedaniel <daniel@shedaniel.me>

* Add "Data" suffix to Chunk IO Events and mark level as nullable for load

* Update common/src/main/java/me/shedaniel/architectury/event/events/ChunkEvent.java

* Bump to 1.16

Co-authored-by: shedaniel <daniel@shedaniel.me>
Co-authored-by: Max <maxh2709@gmail.com>
This commit is contained in:
canitzp
2021-05-27 01:03:20 +02:00
committed by GitHub
parent d737e8e2b7
commit 582ededddd
10 changed files with 309 additions and 1 deletions

View File

@@ -31,6 +31,7 @@ import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.event.CommandEvent;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.ServerChatEvent;
@@ -49,6 +50,7 @@ import net.minecraftforge.event.entity.player.PlayerEvent.*;
import net.minecraftforge.event.world.BlockEvent.BreakEvent;
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
import net.minecraftforge.event.world.BlockEvent.FarmlandTrampleEvent;
import net.minecraftforge.event.world.ChunkDataEvent;
import net.minecraftforge.event.world.ExplosionEvent.Detonate;
import net.minecraftforge.event.world.ExplosionEvent.Start;
import net.minecraftforge.event.world.WorldEvent;
@@ -371,6 +373,28 @@ public class EventHandlerImplCommon {
}
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(ChunkDataEvent.Save event) {
if (event.getWorld() instanceof ServerLevel) {
ChunkEvent.SAVE_DATA.invoker().save(event.getChunk(), (ServerLevel) event.getWorld(), event.getData());
}
}
@SubscribeEvent(priority = EventPriority.HIGH)
public static void event(ChunkDataEvent.Load event) {
LevelAccessor level = event.getChunk().getWorldForge();
if (!(level instanceof ServerLevel)) {
level = ((WorldEventAttachment) event).architectury$getAttachedLevel();
}
ChunkEvent.LOAD_DATA.invoker().load(event.getChunk(), level instanceof ServerLevel ? (ServerLevel) level : null, event.getData());
}
public interface WorldEventAttachment {
LevelAccessor architectury$getAttachedLevel();
void architectury$attachLevel(LevelAccessor level);
}
public static class ModBasedEventHandler {
}

View File

@@ -0,0 +1,65 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.mixin.forge;
import me.shedaniel.architectury.event.forge.EventHandlerImplCommon;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.village.poi.PoiManager;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.storage.ChunkSerializer;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraftforge.event.world.ChunkDataEvent;
import net.minecraftforge.eventbus.api.Event;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.lang.ref.WeakReference;
@Mixin(ChunkSerializer.class)
public class MixinChunkSerializer {
@Unique
private static ThreadLocal<WeakReference<ServerLevel>> level = new ThreadLocal<>();
@Inject(method = "read", at = @At("HEAD"))
private static void read(ServerLevel worldIn, StructureManager templateManagerIn, PoiManager poiManager, ChunkPos pos, CompoundTag compound, CallbackInfoReturnable<ProtoChunk> cir) {
level.set(new WeakReference<>(worldIn));
}
@ModifyArg(method = "read", at = @At(value = "INVOKE",
ordinal = 1,
target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z"),
index = 0)
private static Event modifyProtoChunkLevel(Event event) {
// We should get this PRed to Forge
WeakReference<ServerLevel> levelRef = level.get();
if (levelRef != null && event instanceof ChunkDataEvent.Load) {
ChunkDataEvent.Load load = (ChunkDataEvent.Load) event;
((EventHandlerImplCommon.WorldEventAttachment) load).architectury$attachLevel(levelRef.get());
}
level.set(null);
return event;
}
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of architectury.
* Copyright (C) 2020, 2021 architectury
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package me.shedaniel.architectury.mixin.forge;
import me.shedaniel.architectury.event.forge.EventHandlerImplCommon;
import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.event.world.WorldEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import java.lang.ref.WeakReference;
@Mixin(WorldEvent.class)
public class MixinWorldEvent implements EventHandlerImplCommon.WorldEventAttachment {
@Unique
private WeakReference<LevelAccessor> level;
@Override
public LevelAccessor architectury$getAttachedLevel() {
return level == null ? null : level.get();
}
@Override
public void architectury$attachLevel(LevelAccessor level) {
this.level = new WeakReference<>(level);
}
}

View File

@@ -15,9 +15,11 @@
"GameRulesAccessor$IntegerValueSimple",
"MixinBlockEntity",
"MixinBlockEntityExtension",
"MixinChunkSerializer",
"MixinClientLevel",
"MixinItemExtension",
"MixinRegistryEntry",
"MixinWorldEvent",
"MobSpawnSettingsBuilderAccessor"
],
"injectors": {