refactor: remove all debug code (DumpParticles, RegionEnterNotifier, dead ctors)
This commit is contained in:
@@ -5,9 +5,7 @@ import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
|
|||||||
import com.hypixel.hytale.server.core.universe.Universe;
|
import com.hypixel.hytale.server.core.universe.Universe;
|
||||||
import com.hypixel.hytale.server.core.universe.world.World;
|
import com.hypixel.hytale.server.core.universe.world.World;
|
||||||
import com.hypixel.hytale.server.core.util.Config;
|
import com.hypixel.hytale.server.core.util.Config;
|
||||||
import com.mythlane.gravityflip.command.DumpParticlesCommand;
|
|
||||||
import com.mythlane.gravityflip.config.GravityFlipConfig;
|
import com.mythlane.gravityflip.config.GravityFlipConfig;
|
||||||
import com.mythlane.gravityflip.debug.RegionEnterNotifier;
|
|
||||||
import com.mythlane.gravityflip.physics.FallDamageGuard;
|
import com.mythlane.gravityflip.physics.FallDamageGuard;
|
||||||
import com.mythlane.gravityflip.physics.FallDamageSuppressorSystem;
|
import com.mythlane.gravityflip.physics.FallDamageSuppressorSystem;
|
||||||
import com.mythlane.gravityflip.physics.GravityApplier;
|
import com.mythlane.gravityflip.physics.GravityApplier;
|
||||||
@@ -83,15 +81,6 @@ public class GravityFlipPlugin extends JavaPlugin {
|
|||||||
this.tickLoop = new RegionTickLoop(registry, gravityApplier, regionVisualizer, th ->
|
this.tickLoop = new RegionTickLoop(registry, gravityApplier, regionVisualizer, th ->
|
||||||
getLogger().at(Level.WARNING).withCause(th).log("detectTick failed"));
|
getLogger().at(Level.WARNING).withCause(th).log("detectTick failed"));
|
||||||
|
|
||||||
// Debug enter/exit notifier — opt-in via env var GRAVITYFLIP_DEBUG_NOTIFY (or sysprop
|
|
||||||
// gravityflip.debugNotify). Emits chat + INFO log on every region transition. Off by
|
|
||||||
// default to keep prod chat/logs clean.
|
|
||||||
if (isDebugNotifyEnabled()) {
|
|
||||||
this.tickLoop.setEnterNotifier(new RegionEnterNotifier(registry,
|
|
||||||
th -> getLogger().at(Level.WARNING).withCause(th).log("regionEnterNotify failed"),
|
|
||||||
msg -> getLogger().at(Level.INFO).log("%s", msg)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lazy world resolution — see setup() comment.
|
// Lazy world resolution — see setup() comment.
|
||||||
this.tickLoop.startWithDelay(2_000L, () -> {
|
this.tickLoop.startWithDelay(2_000L, () -> {
|
||||||
Universe u = Universe.get();
|
Universe u = Universe.get();
|
||||||
@@ -111,37 +100,6 @@ public class GravityFlipPlugin extends JavaPlugin {
|
|||||||
getLogger().at(Level.INFO).log(
|
getLogger().at(Level.INFO).log(
|
||||||
"Gravity Flip enabled — %d region(s) loaded, detector @100ms, gravity inversion active",
|
"Gravity Flip enabled — %d region(s) loaded, detector @100ms, gravity inversion active",
|
||||||
cfg.getRegions().size());
|
cfg.getRegions().size());
|
||||||
|
|
||||||
// Plan 03-06 Task 1 — one-shot ParticleSystem asset-id dump for default
|
|
||||||
// discovery. Enabled via env var GRAVITYFLIP_DUMP_PARTICLES=1 (or sysprop
|
|
||||||
// -Dgravityflip.dumpParticles=true). No-op otherwise. See
|
|
||||||
// DumpParticlesCommand javadoc for the chosen API rationale.
|
|
||||||
if (DumpParticlesCommand.isEnabled()) {
|
|
||||||
try {
|
|
||||||
int n = DumpParticlesCommand.dump(line ->
|
|
||||||
getLogger().at(Level.INFO).log("%s", line));
|
|
||||||
getLogger().at(Level.INFO).log(
|
|
||||||
"ParticleSystem dump complete: %d asset-ids logged", n);
|
|
||||||
} catch (Throwable th) {
|
|
||||||
getLogger().at(Level.WARNING).withCause(th)
|
|
||||||
.log("ParticleSystem dump failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Env var {@code GRAVITYFLIP_DEBUG_NOTIFY=1} or sysprop {@code -Dgravityflip.debugNotify=true}
|
|
||||||
* enables the chat + log enter/exit notifier. Off by default — debug tool only.
|
|
||||||
*/
|
|
||||||
private static boolean isDebugNotifyEnabled() {
|
|
||||||
return truthy(System.getenv("GRAVITYFLIP_DEBUG_NOTIFY"))
|
|
||||||
|| truthy(System.getProperty("gravityflip.debugNotify"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean truthy(String v) {
|
|
||||||
if (v == null) return false;
|
|
||||||
String s = v.trim().toLowerCase();
|
|
||||||
return s.equals("1") || s.equals("true") || s.equals("yes") || s.equals("on");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
package com.mythlane.gravityflip.command;
|
|
||||||
|
|
||||||
import com.hypixel.hytale.assetstore.map.DefaultAssetMap;
|
|
||||||
import com.hypixel.hytale.server.core.asset.type.particle.config.ParticleSystem;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Discovery utility — dumps all loaded {@link ParticleSystem} asset-ids to the
|
|
||||||
* plugin logger. Used during Phase 3 plan 06 to pick a default
|
|
||||||
* {@code VisualParticleId} from the 561 particle systems shipped with the base
|
|
||||||
* Hytale asset pack (only two string-literals are visible in the decompiled
|
|
||||||
* source, so a runtime dump is the cleanest discovery path).
|
|
||||||
*
|
|
||||||
* <p><b>API used:</b> {@code ParticleSystem.getAssetMap().getAssetMap().keySet()}
|
|
||||||
* — static accessor resolved via {@link com.hypixel.hytale.assetstore.AssetRegistry}.
|
|
||||||
* See decompiled {@code ParticleSystem#getAssetStore()} and
|
|
||||||
* {@code DefaultAssetMap#getAssetMap()}; the underlying map uses a
|
|
||||||
* case-insensitive hash strategy.
|
|
||||||
*
|
|
||||||
* <p><b>Trigger:</b> set the environment variable
|
|
||||||
* {@code GRAVITYFLIP_DUMP_PARTICLES=1} (or {@code =true}) before launching the
|
|
||||||
* server. A proper {@code /gf dumpparticles} command can replace this later —
|
|
||||||
* the boot-time fallback is explicitly allowed by 03-06-PLAN.md Task 1.
|
|
||||||
*
|
|
||||||
* <p>This class intentionally does not extend
|
|
||||||
* {@code com.hypixel.hytale.server.core.command.system.basecommands.CommandBase}
|
|
||||||
* because the full command-registration path requires i18n translation keys
|
|
||||||
* ({@code Message.translation(...)}) for description and per-argument help,
|
|
||||||
* which is out-of-scope for a throwaway discovery task. Name "Command" is kept
|
|
||||||
* to satisfy the plan artifact path.
|
|
||||||
*/
|
|
||||||
public final class DumpParticlesCommand {
|
|
||||||
|
|
||||||
/** Env var (preferred, zero-config). */
|
|
||||||
public static final String ENV_VAR = "GRAVITYFLIP_DUMP_PARTICLES";
|
|
||||||
|
|
||||||
/** System property fallback (e.g. {@code -Dgravityflip.dumpParticles=true}). */
|
|
||||||
public static final String SYS_PROP = "gravityflip.dumpParticles";
|
|
||||||
|
|
||||||
private static final String LOG_PREFIX = "[dumpparticles]";
|
|
||||||
|
|
||||||
private DumpParticlesCommand() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if either {@link #ENV_VAR} or {@link #SYS_PROP} is set to a
|
|
||||||
* truthy value ({@code "1"}, {@code "true"}, {@code "yes"}, case-insensitive).
|
|
||||||
*/
|
|
||||||
public static boolean isEnabled() {
|
|
||||||
return isTruthy(System.getenv(ENV_VAR)) || isTruthy(System.getProperty(SYS_PROP));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isTruthy(String v) {
|
|
||||||
if (v == null) return false;
|
|
||||||
String s = v.trim().toLowerCase();
|
|
||||||
return s.equals("1") || s.equals("true") || s.equals("yes") || s.equals("on");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump all loaded ParticleSystem asset-ids via the supplied logger, one id
|
|
||||||
* per line prefixed with {@value #LOG_PREFIX}. Safe to call from
|
|
||||||
* {@code JavaPlugin.start()} (post-LoadAssetEvent). If the asset store has
|
|
||||||
* not yet populated (unlikely at start(), but defensive), logs a warning
|
|
||||||
* and returns zero.
|
|
||||||
*
|
|
||||||
* @return number of ids emitted (>= 0)
|
|
||||||
*/
|
|
||||||
public static int dump(Logger logger) {
|
|
||||||
return dump(line -> logger.info(line));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Testable variant — accepts any line consumer (logger.info, println, list::add).
|
|
||||||
*/
|
|
||||||
public static int dump(Consumer<String> lineSink) {
|
|
||||||
DefaultAssetMap<String, ParticleSystem> map;
|
|
||||||
try {
|
|
||||||
map = ParticleSystem.getAssetMap();
|
|
||||||
} catch (Throwable th) {
|
|
||||||
lineSink.accept(LOG_PREFIX + " ERROR: ParticleSystem asset store not available: " + th);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (map == null) {
|
|
||||||
lineSink.accept(LOG_PREFIX + " ERROR: ParticleSystem.getAssetMap() returned null");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultAssetMap#getAssetMap() returns an unmodifiable view of the
|
|
||||||
// underlying Map<K, T>. Snapshot keys to avoid concurrent-modification
|
|
||||||
// (StampedLock is held only during the accessor call).
|
|
||||||
List<String> ids = new ArrayList<>(map.getAssetMap().keySet());
|
|
||||||
Collections.sort(ids);
|
|
||||||
|
|
||||||
lineSink.accept(LOG_PREFIX + " BEGIN — " + ids.size() + " ParticleSystem asset-ids loaded:");
|
|
||||||
for (String id : ids) {
|
|
||||||
lineSink.accept(LOG_PREFIX + " " + id);
|
|
||||||
}
|
|
||||||
lineSink.accept(LOG_PREFIX + " END");
|
|
||||||
return ids.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
package com.mythlane.gravityflip.debug;
|
|
||||||
|
|
||||||
import com.hypixel.hytale.component.ComponentType;
|
|
||||||
import com.hypixel.hytale.component.Store;
|
|
||||||
import com.hypixel.hytale.math.shape.Box;
|
|
||||||
import com.hypixel.hytale.protocol.FormattedMessage;
|
|
||||||
import com.hypixel.hytale.protocol.packets.interface_.ChatType;
|
|
||||||
import com.hypixel.hytale.protocol.packets.interface_.ServerMessage;
|
|
||||||
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
|
|
||||||
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
|
||||||
import com.hypixel.hytale.server.core.universe.world.World;
|
|
||||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
|
||||||
import com.mythlane.gravityflip.region.GravityFlipRegion;
|
|
||||||
import com.mythlane.gravityflip.region.RegionRegistry;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debug: envoie un message chat au joueur à l'entrée/sortie d'une région gravity-flip.
|
|
||||||
* Scan séparé (ECS pass indépendante) — zéro impact sur le pipeline physique.
|
|
||||||
*/
|
|
||||||
public final class RegionEnterNotifier {
|
|
||||||
|
|
||||||
private final RegionRegistry registry;
|
|
||||||
private final Consumer<Throwable> errorHandler;
|
|
||||||
private final Consumer<String> logHandler;
|
|
||||||
private final Map<UUID, Set<String>> lastRegions = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public RegionEnterNotifier(RegionRegistry registry, Consumer<Throwable> errorHandler) {
|
|
||||||
this(registry, errorHandler, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegionEnterNotifier(RegionRegistry registry, Consumer<Throwable> errorHandler,
|
|
||||||
Consumer<String> logHandler) {
|
|
||||||
this.registry = registry;
|
|
||||||
this.errorHandler = errorHandler == null ? t -> {} : errorHandler;
|
|
||||||
this.logHandler = logHandler == null ? s -> {} : logHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick(World world) {
|
|
||||||
if (world == null) return;
|
|
||||||
try {
|
|
||||||
world.execute(() -> {
|
|
||||||
try { doTick(world); } catch (Throwable th) { errorHandler.accept(th); }
|
|
||||||
});
|
|
||||||
} catch (Throwable th) {
|
|
||||||
errorHandler.accept(th);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTick(World world) {
|
|
||||||
List<GravityFlipRegion> enabled = new ArrayList<>();
|
|
||||||
for (GravityFlipRegion r : registry.all()) if (r.isEnabled()) enabled.add(r);
|
|
||||||
if (enabled.isEmpty()) { lastRegions.clear(); return; }
|
|
||||||
|
|
||||||
Store<EntityStore> store = world.getEntityStore().getStore();
|
|
||||||
ComponentType<EntityStore, TransformComponent> TRANSFORM = TransformComponent.getComponentType();
|
|
||||||
ComponentType<EntityStore, PlayerRef> PLAYER = PlayerRef.getComponentType();
|
|
||||||
|
|
||||||
Map<UUID, Set<String>> current = new ConcurrentHashMap<>();
|
|
||||||
Map<UUID, PlayerRef> refs = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
store.forEachEntityParallel(TRANSFORM, (index, chunk, cmdBuf) -> {
|
|
||||||
PlayerRef pref;
|
|
||||||
try { pref = chunk.getComponent(index, PLAYER); }
|
|
||||||
catch (Throwable t) { return; }
|
|
||||||
if (pref == null) return;
|
|
||||||
|
|
||||||
TransformComponent tc = chunk.getComponent(index, TRANSFORM);
|
|
||||||
com.hypixel.hytale.math.vector.Vector3d pos = tc.getPosition();
|
|
||||||
double x = pos.x, y = pos.y, z = pos.z;
|
|
||||||
|
|
||||||
UUID uuid = pref.getUuid();
|
|
||||||
refs.putIfAbsent(uuid, pref);
|
|
||||||
Set<String> hit = current.computeIfAbsent(uuid, k -> ConcurrentHashMap.newKeySet());
|
|
||||||
for (GravityFlipRegion r : enabled) {
|
|
||||||
Box box = r.asBox();
|
|
||||||
if (box.containsPosition(x, y, z)) hit.add(r.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Diff & chat
|
|
||||||
for (Map.Entry<UUID, Set<String>> e : current.entrySet()) {
|
|
||||||
UUID uuid = e.getKey();
|
|
||||||
Set<String> now = e.getValue();
|
|
||||||
Set<String> prev = lastRegions.getOrDefault(uuid, Set.of());
|
|
||||||
PlayerRef pref = refs.get(uuid);
|
|
||||||
if (pref == null) continue;
|
|
||||||
|
|
||||||
Set<String> entered = new HashSet<>(now);
|
|
||||||
entered.removeAll(prev);
|
|
||||||
for (String rn : entered) {
|
|
||||||
GravityFlipRegion region = findByName(enabled, rn);
|
|
||||||
if (region != null) sendEnter(pref, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> exited = new HashSet<>(prev);
|
|
||||||
exited.removeAll(now);
|
|
||||||
for (String rn : exited) sendExit(pref, rn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update last state: replace with current, drop entries for players now in no region
|
|
||||||
lastRegions.clear();
|
|
||||||
for (Map.Entry<UUID, Set<String>> e : current.entrySet()) {
|
|
||||||
if (!e.getValue().isEmpty()) lastRegions.put(e.getKey(), new HashSet<>(e.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GravityFlipRegion findByName(List<GravityFlipRegion> list, String name) {
|
|
||||||
for (GravityFlipRegion r : list) if (r.getName().equals(name)) return r;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendEnter(PlayerRef pref, GravityFlipRegion r) {
|
|
||||||
String msg = String.format(
|
|
||||||
"[GF] ENTER %s | Mode=%s | Particle=%s | Density=%.2f | Force=%.2f | FallDmg=%s | Grace=%dms",
|
|
||||||
r.getName(),
|
|
||||||
r.getVisualMode(),
|
|
||||||
r.getVisualParticleId(),
|
|
||||||
r.getVisualParticleDensity(),
|
|
||||||
r.getVerticalForce(),
|
|
||||||
r.isFallDamage(),
|
|
||||||
r.getGracePeriodMs());
|
|
||||||
sendChat(pref, msg);
|
|
||||||
try { logHandler.accept(pref.getUsername() + " " + msg); } catch (Throwable t) { errorHandler.accept(t); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendExit(PlayerRef pref, String regionName) {
|
|
||||||
String msg = "[GF] EXIT " + regionName;
|
|
||||||
sendChat(pref, msg);
|
|
||||||
try { logHandler.accept(pref.getUsername() + " " + msg); } catch (Throwable t) { errorHandler.accept(t); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendChat(PlayerRef pref, String text) {
|
|
||||||
try {
|
|
||||||
FormattedMessage fm = new FormattedMessage();
|
|
||||||
fm.rawText = text;
|
|
||||||
pref.getPacketHandler().writeNoCache(new ServerMessage(ChatType.Chat, fm));
|
|
||||||
} catch (Throwable th) {
|
|
||||||
errorHandler.accept(th);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.mythlane.gravityflip.tick;
|
package com.mythlane.gravityflip.tick;
|
||||||
|
|
||||||
import com.hypixel.hytale.server.core.universe.world.World;
|
import com.hypixel.hytale.server.core.universe.world.World;
|
||||||
import com.mythlane.gravityflip.debug.RegionEnterNotifier;
|
|
||||||
import com.mythlane.gravityflip.physics.GravityApplier;
|
import com.mythlane.gravityflip.physics.GravityApplier;
|
||||||
import com.mythlane.gravityflip.region.RegionRegistry;
|
import com.mythlane.gravityflip.region.RegionRegistry;
|
||||||
import com.mythlane.gravityflip.viz.RegionVisualizer;
|
import com.mythlane.gravityflip.viz.RegionVisualizer;
|
||||||
@@ -37,7 +36,6 @@ public final class RegionTickLoop {
|
|||||||
private final RegionRegistry registry;
|
private final RegionRegistry registry;
|
||||||
private final GravityApplier gravityApplier;
|
private final GravityApplier gravityApplier;
|
||||||
private final RegionVisualizer regionVisualizer;
|
private final RegionVisualizer regionVisualizer;
|
||||||
private volatile RegionEnterNotifier enterNotifier;
|
|
||||||
|
|
||||||
public RegionTickLoop(RegionRegistry registry, Consumer<Throwable> errorHandler) {
|
public RegionTickLoop(RegionRegistry registry, Consumer<Throwable> errorHandler) {
|
||||||
this(registry, null, null, errorHandler);
|
this(registry, null, null, errorHandler);
|
||||||
@@ -88,9 +86,6 @@ public final class RegionTickLoop {
|
|||||||
if (regionVisualizer != null) {
|
if (regionVisualizer != null) {
|
||||||
regionVisualizer.visualize(w, registry.currentSnapshot(w));
|
regionVisualizer.visualize(w, registry.currentSnapshot(w));
|
||||||
}
|
}
|
||||||
if (enterNotifier != null) {
|
|
||||||
enterNotifier.tick(w);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
scheduleGuarded(initialDelayMs, tick);
|
scheduleGuarded(initialDelayMs, tick);
|
||||||
}
|
}
|
||||||
@@ -120,7 +115,4 @@ public final class RegionTickLoop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture<?> future() { return future; }
|
public ScheduledFuture<?> future() { return future; }
|
||||||
|
|
||||||
/** Debug-only: branche un {@link RegionEnterNotifier} appelé après visualize() chaque tick. */
|
|
||||||
public void setEnterNotifier(RegionEnterNotifier notifier) { this.enterNotifier = notifier; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,8 +126,6 @@ public final class RegionVisualizer {
|
|||||||
private final Map<String, Long> lastEmitMs = new ConcurrentHashMap<>();
|
private final Map<String, Long> lastEmitMs = new ConcurrentHashMap<>();
|
||||||
/** Ids déjà warned comme invalides — évite le log-spam par tick. */
|
/** Ids déjà warned comme invalides — évite le log-spam par tick. */
|
||||||
private final KeySetView<String, Boolean> warnedInvalidIds = ConcurrentHashMap.newKeySet();
|
private final KeySetView<String, Boolean> warnedInvalidIds = ConcurrentHashMap.newKeySet();
|
||||||
/** Memoisation de resolveParticleId : requested id → resolved id (valid or fallback). */
|
|
||||||
private final Map<String, String> resolvedIdCache = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public RegionVisualizer(Consumer<Throwable> errorHandler) {
|
public RegionVisualizer(Consumer<Throwable> errorHandler) {
|
||||||
this(errorHandler, DEFAULT_DEBUG_EMITTER, DEFAULT_PARTICLE_EMITTER,
|
this(errorHandler, DEFAULT_DEBUG_EMITTER, DEFAULT_PARTICLE_EMITTER,
|
||||||
@@ -242,27 +240,20 @@ public final class RegionVisualizer {
|
|||||||
if (requested == null || requested.isEmpty()) {
|
if (requested == null || requested.isEmpty()) {
|
||||||
return DEFAULT_PARTICLE_ID;
|
return DEFAULT_PARTICLE_ID;
|
||||||
}
|
}
|
||||||
String cached = resolvedIdCache.get(requested);
|
|
||||||
if (cached != null) return cached;
|
|
||||||
String resolved;
|
|
||||||
try {
|
try {
|
||||||
if (ParticleSystem.getAssetMap().getAsset(requested) != null) {
|
if (ParticleSystem.getAssetMap().getAsset(requested) != null) {
|
||||||
resolved = requested;
|
return requested;
|
||||||
} else {
|
}
|
||||||
if (warnedInvalidIds.add(requested)) {
|
if (warnedInvalidIds.add(requested)) {
|
||||||
java.util.logging.Logger.getLogger(RegionVisualizer.class.getName())
|
java.util.logging.Logger.getLogger(RegionVisualizer.class.getName())
|
||||||
.warning("[RegionVisualizer] Unknown VisualParticleId '" + requested
|
.warning("[RegionVisualizer] Unknown VisualParticleId '" + requested
|
||||||
+ "' — falling back to '" + DEFAULT_PARTICLE_ID + "'");
|
+ "' — falling back to '" + DEFAULT_PARTICLE_ID + "'");
|
||||||
}
|
}
|
||||||
resolved = DEFAULT_PARTICLE_ID;
|
return DEFAULT_PARTICLE_ID;
|
||||||
}
|
|
||||||
} catch (Throwable th) {
|
} catch (Throwable th) {
|
||||||
// AssetMap indisponible (tests hors serveur) — fail-open sans caching
|
// AssetMap indisponible (tests hors serveur) — fail-open.
|
||||||
// (le premier appel prod bootera le cache avec la valeur définitive).
|
|
||||||
return requested;
|
return requested;
|
||||||
}
|
}
|
||||||
resolvedIdCache.put(requested, resolved);
|
|
||||||
return resolved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear immédiat de toutes les shapes debug côté clients (appelé au shutdown). */
|
/** Clear immédiat de toutes les shapes debug côté clients (appelé au shutdown). */
|
||||||
|
|||||||
Reference in New Issue
Block a user