diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index d63c27e5..930ddff6 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -20,6 +20,7 @@ import carpet.commands.TestCommand; import carpet.commands.TickCommand; import carpet.network.ServerNetworkHandler; import carpet.helpers.HopperCounter; +import carpet.helpers.ParticleDisplay; import carpet.helpers.TickSpeed; import carpet.logging.LoggerRegistry; import carpet.script.CarpetScriptServer; @@ -194,6 +195,7 @@ public class CarpetServer // static for now - easier to handle all around the co LoggerRegistry.stopLoggers(); HUDController.resetScarpetHUDs(); + ParticleDisplay.resetCache(); extensions.forEach(e -> e.onServerClosed(server)); minecraft_server = null; } diff --git a/src/main/java/carpet/helpers/ParticleDisplay.java b/src/main/java/carpet/helpers/ParticleDisplay.java index 5cc0b5db..086a8c23 100644 --- a/src/main/java/carpet/helpers/ParticleDisplay.java +++ b/src/main/java/carpet/helpers/ParticleDisplay.java @@ -5,42 +5,45 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.HashMap; import java.util.Map; import net.minecraft.commands.arguments.ParticleArgument; +import net.minecraft.core.HolderLookup; import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; import net.minecraft.core.registries.Registries; -import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.phys.Vec3; public class ParticleDisplay { - private static Map particleCache = new HashMap<>(); + private static final Map particleCache = new HashMap<>(); // we reset this on reloads, but probably need something better - private static ParticleOptions parseParticle(String name, ServerLevel level) // [SCARY SHIT] persistent caches over server reloads + private static ParticleOptions parseParticle(String name, HolderLookup> lookup) { try { - return ParticleArgument.readParticle(new StringReader(name), level.holderLookup(Registries.PARTICLE_TYPE)); + return ParticleArgument.readParticle(new StringReader(name), lookup); } catch (CommandSyntaxException e) { - throw new RuntimeException("No such particle: "+name); + throw new IllegalArgumentException("No such particle: " + name); } } - public static ParticleOptions getEffect(String name, ServerLevel level) + public static ParticleOptions getEffect(String name, HolderLookup> lookup) { if (name == null) return null; - ParticleOptions res = particleCache.get(name); - if (res != null) return res; - particleCache.put(name, parseParticle(name, level)); - return particleCache.get(name); + return particleCache.computeIfAbsent(name, particle -> parseParticle(particle, lookup)); + } + + public static void resetCache() { + particleCache.clear(); } public static void drawParticleLine(ServerPlayer player, Vec3 from, Vec3 to, String main, String accent, int count, double spread) { - ParticleOptions accentParticle = getEffect(accent, player.getLevel()); - ParticleOptions mainParticle = getEffect(main, player.getLevel()); + HolderLookup> lookup = player.getLevel().holderLookup(Registries.PARTICLE_TYPE); + ParticleOptions accentParticle = getEffect(accent, lookup); + ParticleOptions mainParticle = getEffect(main, lookup); - if (accentParticle != null) ((ServerLevel)player.level).sendParticles( + if (accentParticle != null) player.getLevel().sendParticles( player, accentParticle, true, @@ -52,10 +55,10 @@ public class ParticleDisplay Vec3 incvec = to.subtract(from).normalize();// multiply(50/sqrt(lineLengthSq)); for (Vec3 delta = new Vec3(0.0,0.0,0.0); - delta.lengthSqr() particleCache = new HashMap<>(); public static record ShapeWithConfig(ExpiringShape shape, Map config) {} public static ShapeWithConfig fromFunctionArgs( @@ -177,19 +171,14 @@ public class ShapeDispatcher public static ParticleOptions getParticleData(String name, RegistryAccess regs) { - ParticleOptions particle = particleCache.get(name); // [SCARY SHIT] cache should be cleared between worlds - if (particle != null) - return particle; try { - particle = ParticleArgument.readParticle(new StringReader(name), regs.lookupOrThrow(Registries.PARTICLE_TYPE)); + return ParticleDisplay.getEffect(name, regs.lookupOrThrow(Registries.PARTICLE_TYPE)); } - catch (CommandSyntaxException e) + catch (IllegalArgumentException e) { throw new ThrowStatement(name, Throwables.UNKNOWN_PARTICLE); } - particleCache.put(name, particle); - return particle; } public static Map parseParams(List items) @@ -261,7 +250,7 @@ public class ShapeDispatcher public abstract static class ExpiringShape { - public static final Map, RegistryAccess, ExpiringShape>> shapeProviders = new HashMap, RegistryAccess, ExpiringShape>>(){{ + public static final Map, RegistryAccess, ExpiringShape>> shapeProviders = new HashMap<>(){{ put("line", creator(Line::new)); put("box", creator(Box::new)); put("sphere", creator(Sphere::new)); @@ -1200,7 +1189,7 @@ public class ShapeDispatcher "GROUND", "FIXED") { - public Value validate(Map o, MinecraftServer s, Value v) + public Value validate(Map o, MinecraftServer s, Value v) { return super.validate(o, s ,new StringValue(v.getString().toUpperCase(Locale.ROOT))); }