diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/api/client/effekseer/EffekseerManager.java b/common/src/main/java/mod/chloeprime/aaaparticles/api/client/effekseer/EffekseerManager.java index 01336ba..2687a9b 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/api/client/effekseer/EffekseerManager.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/api/client/effekseer/EffekseerManager.java @@ -1,7 +1,7 @@ package mod.chloeprime.aaaparticles.api.client.effekseer; import Effekseer.swig.EffekseerManagerCore; -import com.mojang.math.Matrix4f; +import org.joml.Matrix4f; import java.nio.FloatBuffer; @@ -83,7 +83,7 @@ public void setCameraMatrix(float[] m) { public void setCameraMatrix(Matrix4f m) { var buffer = FloatBuffer.wrap(MATRIX_BUFFER.get()); - m.store(buffer); + m.get(buffer); setCameraMatrix(buffer); } @@ -98,7 +98,7 @@ public void setCameraMatrix(FloatBuffer buf) { public void setProjectionMatrix(Matrix4f m) { var buffer = FloatBuffer.wrap(MATRIX_BUFFER.get()); - m.store(buffer); + m.get(buffer); setProjectionMatrix(buffer); } diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/api/common/AAALevel.java b/common/src/main/java/mod/chloeprime/aaaparticles/api/common/AAALevel.java index 060f885..8ee95a8 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/api/common/AAALevel.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/api/common/AAALevel.java @@ -30,7 +30,7 @@ public static void addParticle(Level level, double distance, ParticleEmitterInfo } private static void sendToPlayer(ServerPlayer player, Level level, S2CAddParticle packet, double sqrDistance) { - if (player.getLevel() != level) { + if (player.level() != level) { return; } if (packet.isPositionSet()) { diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/client/AAAParticlesClient.java b/common/src/main/java/mod/chloeprime/aaaparticles/client/AAAParticlesClient.java index d7dc23f..d2e0746 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/client/AAAParticlesClient.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/client/AAAParticlesClient.java @@ -49,7 +49,7 @@ private static void installNativeLibrary() { public static void addParticle(Level level, ParticleEmitterInfo info) { var player = Minecraft.getInstance().player; - if (player != null && player.level != level) { + if (player != null && player.level() != level) { return; } info.spawnInWorld(level, player); diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/client/ModClientHooks.java b/common/src/main/java/mod/chloeprime/aaaparticles/client/ModClientHooks.java index 5d37360..3de7b72 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/client/ModClientHooks.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/client/ModClientHooks.java @@ -10,6 +10,6 @@ public class ModClientHooks { public static void playLightningEffek(LightningBolt bolt) { var info = LIGHTNING_EFFEK_TEMPLATE.clone().position(bolt.position()); - AAALevel.addParticle(bolt.level, true, info); + AAALevel.addParticle(bolt.level(), true, info); } } diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/client/loader/EffekAssetLoader.java b/common/src/main/java/mod/chloeprime/aaaparticles/client/loader/EffekAssetLoader.java index e1ccc9f..9f3460d 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/client/loader/EffekAssetLoader.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/client/loader/EffekAssetLoader.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.IntFunction; @@ -48,38 +49,37 @@ public void forEach(BiConsumer action) { loadedEffects.forEach(action); } - /** - * @param name the minecraft asset path of .efkefc files. - * @return the loaded effect. - */ - private EffekseerEffect loadEffect(ResourceManager manager, ResourceLocation name) { - String modid = name.getNamespace(); - String path = "effeks/" + name.getPath() + ".efkefc"; - ResourceLocation assetLocation = new ResourceLocation(modid, path); - - try (Resource efkefc = manager.getResource(assetLocation)) { + private Optional loadEffect(ResourceManager manager, ResourceLocation name, Resource efkefc) { + try (var input = efkefc.open()) { EffekseerEffect effect = new EffekseerEffect(); - boolean success = effect.load(efkefc.getInputStream(), 1); + boolean success = effect.load(input, 1); if (!success) { - throw new EffekLoadException("Failed to load " + assetLocation); + LOGGER.error("Failed to load " + name); + return Optional.empty(); } - for (TextureType texType : TextureType.values()) { - int count = effect.textureCount(texType); - load( - manager, - name, count, - i -> effect.getTexturePath(i, texType), - (b, len, i) -> effect.loadTexture(b, len, i, texType) - ); + try { + for (TextureType texType : TextureType.values()) { + int count = effect.textureCount(texType); + load( + manager, + name, count, + i -> effect.getTexturePath(i, texType), + (b, len, i) -> effect.loadTexture(b, len, i, texType) + ); + } + load(manager, name, effect.modelCount(), effect::getModelPath, effect::loadModel); + load(manager, name, effect.curveCount(), effect::getCurvePath, effect::loadCurve); + load(manager, name, effect.materialCount(), effect::getMaterialPath, effect::loadMaterial); + return Optional.of(effect); + } catch (FileNotFoundException ex) { + LOGGER.error("Failed to load " + name, ex); + effect.close(); + return Optional.empty(); } - load(manager, name, effect.modelCount(), effect::getModelPath, effect::loadModel); - load(manager, name, effect.curveCount(), effect::getCurvePath, effect::loadCurve); - load(manager, name, effect.materialCount(), effect::getMaterialPath, effect::loadMaterial); - return effect; } catch (IOException ex) { handleCheckedException(ex); - return null; + return Optional.empty(); } } @@ -104,8 +104,10 @@ private void load( var main = new LimitlessResourceLocation(modid, mcAssetPath); var fallback = new LimitlessResourceLocation(modid, fallbackMcAssetPath); // Load from disk. - try (var resource = getResourceOrUseFallbackPath(manager, main, fallback)) { - byte[] bytes = IOUtils.toByteArray(resource.getInputStream()); + var resource = getResourceOrUseFallbackPath(manager, main, fallback) + .orElseThrow(() -> new FileNotFoundException("Failed to load %s or %s".formatted(main, fallback))); + try (var input = resource.open()) { + byte[] bytes = IOUtils.toByteArray(input); boolean success = loadMethod.accept(bytes, bytes.length, i); if (!success) { String info = String.format("Failed to load effek data %s", effekAssetPath); @@ -116,16 +118,12 @@ private void load( } } - private static Resource getResourceOrUseFallbackPath( + private static Optional getResourceOrUseFallbackPath( ResourceManager manager, ResourceLocation path, ResourceLocation fallback - ) throws IOException { - try { - return manager.getResource(path); - } catch (FileNotFoundException ignored) { - return manager.getResource(fallback); - } + ) { + return manager.getResource(path).or(() -> manager.getResource(fallback)); } protected static class Preparations { @@ -159,10 +157,10 @@ private static ResourceLocation createEffekName(ResourceLocation location) { protected void apply(Preparations prep_, ResourceManager manager, ProfilerFiller profilerFiller) { EffekRenderer.init(); var prep = new Preparations(); - for (var effek : manager.listResources("effeks", s -> s.endsWith(".efkefc"))) { - var name = createEffekName(effek); - prep.loadedEffects.put(name, new EffectDefinition().setEffect(loadEffect(manager, name))); - } + manager.listResources("effeks", rl -> rl.getPath().endsWith(".efkefc")).forEach((location, resource) -> { + var name = createEffekName(location); + loadEffect(manager, name, resource).ifPresent(effect -> prep.loadedEffects.put(name, new EffectDefinition().setEffect(effect))); + }); unloadAll(); loadedEffects.putAll(prep.loadedEffects); INSTANCE = this; diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/client/render/EffekRenderer.java b/common/src/main/java/mod/chloeprime/aaaparticles/client/render/EffekRenderer.java index 1294dc8..b63b5e7 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/client/render/EffekRenderer.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/client/render/EffekRenderer.java @@ -1,13 +1,13 @@ package mod.chloeprime.aaaparticles.client.render; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Matrix4f; import mod.chloeprime.aaaparticles.api.client.effekseer.DeviceType; import mod.chloeprime.aaaparticles.api.client.effekseer.Effekseer; import mod.chloeprime.aaaparticles.client.loader.EffekAssetLoader; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; +import org.joml.Matrix4f; import org.lwjgl.BufferUtils; import java.nio.FloatBuffer; @@ -52,7 +52,7 @@ private static void draw(float partialTick, PoseStack pose, Matrix4f projection, int w = MINECRAFT.getWindow().getWidth(); int h = MINECRAFT.getWindow().getHeight(); - projection.store(PROJECTION_BUFFER); + projection.get(PROJECTION_BUFFER); transposeMatrix(PROJECTION_BUFFER); PROJECTION_BUFFER.get(PROJECTION_MATRIX_DATA); @@ -60,7 +60,7 @@ private static void draw(float partialTick, PoseStack pose, Matrix4f projection, { pose.translate(-camera.getPosition().x(), -camera.getPosition().y(), -camera.getPosition().z()); - pose.last().pose().store(CAMERA_TRANSFORM_BUFFER); + pose.last().pose().get(CAMERA_TRANSFORM_BUFFER); transposeMatrix(CAMERA_TRANSFORM_BUFFER); CAMERA_TRANSFORM_BUFFER.get(CAMERA_TRANSFORM_DATA); } diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/common/network/S2CAddParticle.java b/common/src/main/java/mod/chloeprime/aaaparticles/common/network/S2CAddParticle.java index 0abded6..0c4f7d7 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/common/network/S2CAddParticle.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/common/network/S2CAddParticle.java @@ -43,6 +43,6 @@ public void encode(FriendlyByteBuf buf) { public void handle(Supplier ctx) { var context = ctx.get(); var player = context.getPlayer(); - context.queue(() -> spawnInWorld(player.getLevel(), player)); + context.queue(() -> spawnInWorld(player.level(), player)); } } diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/common/util/LimitlessResourceLocation.java b/common/src/main/java/mod/chloeprime/aaaparticles/common/util/LimitlessResourceLocation.java index 8ca5e4a..2dc036a 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/common/util/LimitlessResourceLocation.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/common/util/LimitlessResourceLocation.java @@ -3,10 +3,10 @@ import net.minecraft.resources.ResourceLocation; /** - * Implementation moved to {@link mod.chloeprime.aaaparticles.mixin.MixinResourceLocation} + * 仍然需要 {@link mod.chloeprime.aaaparticles.mixin.MixinResourceLocation} 才能完全去除 Path 的有效性验证 */ public class LimitlessResourceLocation extends ResourceLocation { public LimitlessResourceLocation(String namespace, String path) { - super(namespace, path); + super(namespace, path, null); } } diff --git a/common/src/main/java/mod/chloeprime/aaaparticles/mixin/MixinResourceLocation.java b/common/src/main/java/mod/chloeprime/aaaparticles/mixin/MixinResourceLocation.java index 3bfbce2..687a7b3 100644 --- a/common/src/main/java/mod/chloeprime/aaaparticles/mixin/MixinResourceLocation.java +++ b/common/src/main/java/mod/chloeprime/aaaparticles/mixin/MixinResourceLocation.java @@ -6,15 +6,15 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(value = ResourceLocation.class, priority = Integer.MAX_VALUE - 5) +@Mixin(value = ResourceLocation.class, priority = Integer.MAX_VALUE) public class MixinResourceLocation { + @Inject(method = "validPathChar", at = @At("HEAD"), cancellable = true) + private static void modernfixCompat(char c, CallbackInfoReturnable cir) { + cir.setReturnValue(true); + } + @Inject(method = "isValidPath", at = @At("HEAD"), cancellable = true) - private static void isValidPath(String string, CallbackInfoReturnable cir) { - if ("DUMMY".equals(string)) { - cir.setReturnValue(false); - } - if (string.startsWith("effeks/")) { - cir.setReturnValue(true); - } + private static void fixDfuCrash(String string, CallbackInfoReturnable cir) { + cir.setReturnValue(!"DUMMY".equals(string)); } } diff --git a/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForge.java b/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForge.java index 04a9e6a..3365492 100644 --- a/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForge.java +++ b/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForge.java @@ -8,17 +8,22 @@ import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.forgespi.Environment; @Mod(AAAParticles.MOD_ID) public class AAAParticlesForge { public AAAParticlesForge() { var modbus = FMLJavaModLoadingContext.get().getModEventBus(); + var forgebus = MinecraftForge.EVENT_BUS; EventBuses.registerModEventBus(AAAParticles.MOD_ID, modbus); AAAParticles.init(); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { + if (Environment.get().getDist().isClient()) { AAAParticlesClient.init(); - MinecraftForge.EVENT_BUS.addListener(AAAParticlesForgeClient::onClientSetup); - }); + modbus.addListener(AAAParticlesForgeClient::onClientSetup); + if (AAAParticlesForgeClient.USE_RENDER_EVENT) { + forgebus.addListener(AAAParticlesForgeClient::onRenderStage); + } + } } } \ No newline at end of file diff --git a/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForgeClient.java b/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForgeClient.java index 32ec032..c9ce9ef 100644 --- a/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForgeClient.java +++ b/forge/src/main/java/mod/chloeprime/aaaparticles/forge/AAAParticlesForgeClient.java @@ -1,9 +1,21 @@ package mod.chloeprime.aaaparticles.forge; import mod.chloeprime.aaaparticles.client.AAAParticlesClient; +import mod.chloeprime.aaaparticles.client.render.EffekRenderer; +import net.minecraftforge.client.event.RenderLevelStageEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; public class AAAParticlesForgeClient { + public static final boolean USE_RENDER_EVENT = false; + public static final RenderLevelStageEvent.Stage RENDER_STAGE = RenderLevelStageEvent.Stage.AFTER_LEVEL; + + static void onRenderStage(RenderLevelStageEvent e) { + if (e.getStage() != RENDER_STAGE) { + return; + } + EffekRenderer.onRenderWorldLast(e.getPartialTick(), e.getPoseStack(), e.getProjectionMatrix(), e.getCamera()); + } + static void onClientSetup(FMLClientSetupEvent e) { AAAParticlesClient.setup(); } diff --git a/forge/src/main/java/mod/chloeprime/aaaparticles/forge/mixin/client/MixinLevelRenderer.java b/forge/src/main/java/mod/chloeprime/aaaparticles/forge/mixin/client/MixinLevelRenderer.java index a1aa1f4..5d58cf4 100644 --- a/forge/src/main/java/mod/chloeprime/aaaparticles/forge/mixin/client/MixinLevelRenderer.java +++ b/forge/src/main/java/mod/chloeprime/aaaparticles/forge/mixin/client/MixinLevelRenderer.java @@ -1,13 +1,14 @@ package mod.chloeprime.aaaparticles.forge.mixin.client; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Matrix4f; import mod.chloeprime.aaaparticles.client.render.EffekRenderer; +import mod.chloeprime.aaaparticles.forge.AAAParticlesForgeClient; import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LightTexture; -import net.minecraftforge.client.MinecraftForgeClient; +import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -16,7 +17,10 @@ @Mixin(LevelRenderer.class) public class MixinLevelRenderer { @Inject(method = "renderLevel", at = @At("RETURN")) - private void onRenderLevelLast(PoseStack pose, float g, long m, boolean bl, Camera arg2, GameRenderer arg3, LightTexture arg4, Matrix4f arg5, CallbackInfo ci) { - EffekRenderer.onRenderWorldLast(MinecraftForgeClient.getPartialTick(), pose, arg5, arg2); + private void onRenderLevelLast(PoseStack pose, float g, long l, boolean bl, Camera camera, GameRenderer arg3, LightTexture arg4, Matrix4f projection, CallbackInfo ci) { + if (AAAParticlesForgeClient.USE_RENDER_EVENT) { + return; + } + EffekRenderer.onRenderWorldLast(Minecraft.getInstance().getPartialTick(), pose, projection, camera); } } diff --git a/gradle.properties b/gradle.properties index 97c2c78..ce60460 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ minecraft_version=1.20.1 enabled_platforms=fabric,forge archives_base_name=aaa_particles -mod_version=1.20.1-1.0.6 +mod_version=1.20.1-1.0.7 maven_group=mod.chloeprime architectury_version=9.2.14 @@ -12,4 +12,4 @@ architectury_version=9.2.14 fabric_loader_version=0.15.7 fabric_api_version=0.90.4+1.20.1 -forge_version=1.20.1-47.2.20 +forge_version=1.20.1-47.2.1