Remove internal phase comments and format code

Strip all Phase references, TODO/FUTURE roadmap notes, and internal
planning comments from the codebase. Run Prettier for consistent
formatting across all Java files.
This commit is contained in:
NotEvil
2026-04-12 01:24:49 +02:00
parent 73d70e212d
commit a71093ba9c
482 changed files with 8500 additions and 5155 deletions

View File

@@ -137,12 +137,18 @@ public class DataDrivenBondageItem extends AbstractV2BondageItem {
IV2BondageEquipment equip = V2EquipmentHelper.getEquipment(entity);
if (equip != null) {
int maxDifficulty = -1;
for (Map.Entry<BodyRegionV2, ItemStack> entry : equip.getAllEquipped().entrySet()) {
for (Map.Entry<BodyRegionV2, ItemStack> entry : equip
.getAllEquipped()
.entrySet()) {
ItemStack stack = entry.getValue();
if (stack.getItem() == this) {
DataDrivenItemDefinition def = DataDrivenItemRegistry.get(stack);
DataDrivenItemDefinition def =
DataDrivenItemRegistry.get(stack);
if (def != null) {
maxDifficulty = Math.max(maxDifficulty, def.escapeDifficulty());
maxDifficulty = Math.max(
maxDifficulty,
def.escapeDifficulty()
);
}
}
}
@@ -157,12 +163,18 @@ public class DataDrivenBondageItem extends AbstractV2BondageItem {
@Override
public void notifyStruggle(LivingEntity entity) {
// Play a generic chain sound for data-driven items
entity.level().playSound(
null, entity.getX(), entity.getY(), entity.getZ(),
net.minecraft.sounds.SoundEvents.CHAIN_STEP,
net.minecraft.sounds.SoundSource.PLAYERS,
0.4f, 1.0f
);
entity
.level()
.playSound(
null,
entity.getX(),
entity.getY(),
entity.getZ(),
net.minecraft.sounds.SoundEvents.CHAIN_STEP,
net.minecraft.sounds.SoundSource.PLAYERS,
0.4f,
1.0f
);
}
// ===== DISPLAY NAME =====
@@ -189,7 +201,9 @@ public class DataDrivenBondageItem extends AbstractV2BondageItem {
public static ItemStack createStack(ResourceLocation itemId) {
if (V2BondageItems.DATA_DRIVEN_ITEM == null) return ItemStack.EMPTY;
ItemStack stack = new ItemStack(V2BondageItems.DATA_DRIVEN_ITEM.get());
stack.getOrCreateTag().putString(DataDrivenItemRegistry.NBT_ITEM_ID, itemId.toString());
stack
.getOrCreateTag()
.putString(DataDrivenItemRegistry.NBT_ITEM_ID, itemId.toString());
return stack;
}
}

View File

@@ -78,7 +78,8 @@ public record DataDrivenItemDefinition(
* Optional per-item overrides for the movement style's default values.
* Requires {@code movementStyle} to be non-null (ignored otherwise).
*/
@Nullable com.tiedup.remake.v2.bondage.movement.MovementModifier movementModifier,
@Nullable
com.tiedup.remake.v2.bondage.movement.MovementModifier movementModifier,
/**
* Per-animation bone whitelist. Maps animation name (e.g. "idle", "struggle")

View File

@@ -52,7 +52,9 @@ import org.jetbrains.annotations.Nullable;
*/
public final class DataDrivenItemParser {
private static final Logger LOGGER = LogManager.getLogger("DataDrivenItems");
private static final Logger LOGGER = LogManager.getLogger(
"DataDrivenItems"
);
private DataDrivenItemParser() {}
@@ -64,7 +66,10 @@ public final class DataDrivenItemParser {
* @return the parsed definition, or null if the file is invalid
*/
@Nullable
public static DataDrivenItemDefinition parse(InputStream input, ResourceLocation fileId) {
public static DataDrivenItemDefinition parse(
InputStream input,
ResourceLocation fileId
) {
try {
JsonObject root = JsonParser.parseReader(
new InputStreamReader(input, StandardCharsets.UTF_8)
@@ -72,7 +77,11 @@ public final class DataDrivenItemParser {
return parseObject(root, fileId);
} catch (Exception e) {
LOGGER.error("[DataDrivenItems] Failed to parse JSON {}: {}", fileId, e.getMessage());
LOGGER.error(
"[DataDrivenItems] Failed to parse JSON {}: {}",
fileId,
e.getMessage()
);
return null;
}
}
@@ -85,19 +94,28 @@ public final class DataDrivenItemParser {
* @return the parsed definition, or null if validation fails
*/
@Nullable
public static DataDrivenItemDefinition parseObject(JsonObject root, ResourceLocation fileId) {
public static DataDrivenItemDefinition parseObject(
JsonObject root,
ResourceLocation fileId
) {
// Validate type field
String type = getStringOrNull(root, "type");
if (!"tiedup:bondage_item".equals(type)) {
LOGGER.error("[DataDrivenItems] Skipping {}: invalid or missing type '{}' (expected 'tiedup:bondage_item')",
fileId, type);
LOGGER.error(
"[DataDrivenItems] Skipping {}: invalid or missing type '{}' (expected 'tiedup:bondage_item')",
fileId,
type
);
return null;
}
// Required: display_name
String displayName = getStringOrNull(root, "display_name");
if (displayName == null || displayName.isEmpty()) {
LOGGER.error("[DataDrivenItems] Skipping {}: missing 'display_name'", fileId);
LOGGER.error(
"[DataDrivenItems] Skipping {}: missing 'display_name'",
fileId
);
return null;
}
@@ -107,33 +125,63 @@ public final class DataDrivenItemParser {
// Required: model
String modelStr = getStringOrNull(root, "model");
if (modelStr == null || modelStr.isEmpty()) {
LOGGER.error("[DataDrivenItems] Skipping {}: missing 'model'", fileId);
LOGGER.error(
"[DataDrivenItems] Skipping {}: missing 'model'",
fileId
);
return null;
}
ResourceLocation modelLocation = ResourceLocation.tryParse(modelStr);
if (modelLocation == null) {
LOGGER.error("[DataDrivenItems] Skipping {}: invalid model ResourceLocation '{}'", fileId, modelStr);
LOGGER.error(
"[DataDrivenItems] Skipping {}: invalid model ResourceLocation '{}'",
fileId,
modelStr
);
return null;
}
// Optional: slim_model
ResourceLocation slimModelLocation = parseOptionalResourceLocation(root, "slim_model", fileId);
ResourceLocation slimModelLocation = parseOptionalResourceLocation(
root,
"slim_model",
fileId
);
// Optional: texture
ResourceLocation texturePath = parseOptionalResourceLocation(root, "texture", fileId);
ResourceLocation texturePath = parseOptionalResourceLocation(
root,
"texture",
fileId
);
// Optional: animation_source
ResourceLocation animationSource = parseOptionalResourceLocation(root, "animation_source", fileId);
ResourceLocation animationSource = parseOptionalResourceLocation(
root,
"animation_source",
fileId
);
// Required: regions (non-empty)
Set<BodyRegionV2> occupiedRegions = parseRegions(root, "regions", fileId);
Set<BodyRegionV2> occupiedRegions = parseRegions(
root,
"regions",
fileId
);
if (occupiedRegions == null || occupiedRegions.isEmpty()) {
LOGGER.error("[DataDrivenItems] Skipping {}: missing or empty 'regions'", fileId);
LOGGER.error(
"[DataDrivenItems] Skipping {}: missing or empty 'regions'",
fileId
);
return null;
}
// Optional: blocked_regions (defaults to regions)
Set<BodyRegionV2> blockedRegions = parseRegions(root, "blocked_regions", fileId);
Set<BodyRegionV2> blockedRegions = parseRegions(
root,
"blocked_regions",
fileId
);
if (blockedRegions == null || blockedRegions.isEmpty()) {
blockedRegions = occupiedRegions;
}
@@ -148,13 +196,25 @@ public final class DataDrivenItemParser {
boolean lockable = getBooleanOrDefault(root, "lockable", true);
// Optional: supports_color (default false)
boolean supportsColor = getBooleanOrDefault(root, "supports_color", false);
boolean supportsColor = getBooleanOrDefault(
root,
"supports_color",
false
);
// Optional: tint_channels (default empty)
Map<String, Integer> tintChannels = parseTintChannels(root, "tint_channels", fileId);
Map<String, Integer> tintChannels = parseTintChannels(
root,
"tint_channels",
fileId
);
// Optional: icon (item model ResourceLocation for inventory sprite)
ResourceLocation icon = parseOptionalResourceLocation(root, "icon", fileId);
ResourceLocation icon = parseOptionalResourceLocation(
root,
"icon",
fileId
);
// Optional: movement_style (requires valid MovementStyle name)
MovementStyle movementStyle = null;
@@ -162,14 +222,21 @@ public final class DataDrivenItemParser {
if (movementStyleStr != null && !movementStyleStr.isEmpty()) {
movementStyle = MovementStyle.fromName(movementStyleStr);
if (movementStyle == null) {
LOGGER.warn("[DataDrivenItems] In {}: unknown movement_style '{}', ignoring",
fileId, movementStyleStr);
LOGGER.warn(
"[DataDrivenItems] In {}: unknown movement_style '{}', ignoring",
fileId,
movementStyleStr
);
}
}
// Optional: movement_modifier (requires movement_style to be set)
MovementModifier movementModifier = null;
if (movementStyle != null && root.has("movement_modifier") && root.get("movement_modifier").isJsonObject()) {
if (
movementStyle != null &&
root.has("movement_modifier") &&
root.get("movement_modifier").isJsonObject()
) {
JsonObject modObj = root.getAsJsonObject("movement_modifier");
Float speedMul = getFloatOrNull(modObj, "speed_multiplier");
Boolean jumpDis = getBooleanOrNull(modObj, "jump_disabled");
@@ -177,14 +244,22 @@ public final class DataDrivenItemParser {
movementModifier = new MovementModifier(speedMul, jumpDis);
}
} else if (movementStyle == null && root.has("movement_modifier")) {
LOGGER.warn("[DataDrivenItems] In {}: movement_modifier ignored because movement_style is absent",
fileId);
LOGGER.warn(
"[DataDrivenItems] In {}: movement_modifier ignored because movement_style is absent",
fileId
);
}
// Required: animation_bones (per-animation bone whitelist)
Map<String, Set<String>> animationBones = parseAnimationBones(root, fileId);
Map<String, Set<String>> animationBones = parseAnimationBones(
root,
fileId
);
if (animationBones == null) {
LOGGER.error("[DataDrivenItems] Skipping {}: missing or invalid 'animation_bones'", fileId);
LOGGER.error(
"[DataDrivenItems] Skipping {}: missing or invalid 'animation_bones'",
fileId
);
return null;
}
@@ -200,14 +275,30 @@ public final class DataDrivenItemParser {
if (idPath.endsWith(".json")) {
idPath = idPath.substring(0, idPath.length() - 5);
}
ResourceLocation id = new ResourceLocation(fileId.getNamespace(), idPath);
ResourceLocation id = new ResourceLocation(
fileId.getNamespace(),
idPath
);
return new DataDrivenItemDefinition(
id, displayName, translationKey, modelLocation, slimModelLocation,
texturePath, animationSource, occupiedRegions, blockedRegions,
posePriority, escapeDifficulty,
lockable, supportsColor, tintChannels, icon,
movementStyle, movementModifier, animationBones
id,
displayName,
translationKey,
modelLocation,
slimModelLocation,
texturePath,
animationSource,
occupiedRegions,
blockedRegions,
posePriority,
escapeDifficulty,
lockable,
supportsColor,
tintChannels,
icon,
movementStyle,
movementModifier,
animationBones
);
}
@@ -223,7 +314,11 @@ public final class DataDrivenItemParser {
}
}
private static int getIntOrDefault(JsonObject obj, String key, int defaultValue) {
private static int getIntOrDefault(
JsonObject obj,
String key,
int defaultValue
) {
if (!obj.has(key) || obj.get(key).isJsonNull()) return defaultValue;
try {
return obj.get(key).getAsInt();
@@ -232,7 +327,11 @@ public final class DataDrivenItemParser {
}
}
private static boolean getBooleanOrDefault(JsonObject obj, String key, boolean defaultValue) {
private static boolean getBooleanOrDefault(
JsonObject obj,
String key,
boolean defaultValue
) {
if (!obj.has(key) || obj.get(key).isJsonNull()) return defaultValue;
try {
return obj.get(key).getAsBoolean();
@@ -263,13 +362,20 @@ public final class DataDrivenItemParser {
@Nullable
private static ResourceLocation parseOptionalResourceLocation(
JsonObject obj, String key, ResourceLocation fileId
JsonObject obj,
String key,
ResourceLocation fileId
) {
String value = getStringOrNull(obj, key);
if (value == null || value.isEmpty()) return null;
ResourceLocation loc = ResourceLocation.tryParse(value);
if (loc == null) {
LOGGER.warn("[DataDrivenItems] In {}: invalid ResourceLocation for '{}': '{}'", fileId, key, value);
LOGGER.warn(
"[DataDrivenItems] In {}: invalid ResourceLocation for '{}': '{}'",
fileId,
key,
value
);
}
return loc;
}
@@ -279,7 +385,11 @@ public final class DataDrivenItemParser {
* Unknown region names are logged as warnings and skipped.
*/
@Nullable
private static Set<BodyRegionV2> parseRegions(JsonObject obj, String key, ResourceLocation fileId) {
private static Set<BodyRegionV2> parseRegions(
JsonObject obj,
String key,
ResourceLocation fileId
) {
if (!obj.has(key) || !obj.get(key).isJsonArray()) return null;
JsonArray arr = obj.getAsJsonArray(key);
@@ -293,12 +403,20 @@ public final class DataDrivenItemParser {
if (region != null) {
regions.add(region);
} else {
LOGGER.warn("[DataDrivenItems] In {}: unknown region '{}' in '{}', skipping",
fileId, name, key);
LOGGER.warn(
"[DataDrivenItems] In {}: unknown region '{}' in '{}', skipping",
fileId,
name,
key
);
}
} catch (Exception e) {
LOGGER.warn("[DataDrivenItems] In {}: invalid element in '{}': {}",
fileId, key, e.getMessage());
LOGGER.warn(
"[DataDrivenItems] In {}: invalid element in '{}': {}",
fileId,
key,
e.getMessage()
);
}
}
@@ -321,18 +439,29 @@ public final class DataDrivenItemParser {
* @param fileId the source file for error messages
* @return an unmodifiable map of channel names to RGB ints, or empty map if absent
*/
private static Map<String, Integer> parseTintChannels(JsonObject obj, String key, ResourceLocation fileId) {
private static Map<String, Integer> parseTintChannels(
JsonObject obj,
String key,
ResourceLocation fileId
) {
if (!obj.has(key) || !obj.get(key).isJsonObject()) return Map.of();
JsonObject channels = obj.getAsJsonObject(key);
Map<String, Integer> result = new LinkedHashMap<>();
for (Map.Entry<String, JsonElement> entry : channels.entrySet()) {
try {
String hex = entry.getValue().getAsString();
int color = Integer.parseInt(hex.startsWith("#") ? hex.substring(1) : hex, 16);
int color = Integer.parseInt(
hex.startsWith("#") ? hex.substring(1) : hex,
16
);
result.put(entry.getKey(), color);
} catch (NumberFormatException e) {
LOGGER.warn("[DataDrivenItems] In {}: invalid hex color '{}' for tint channel '{}'",
fileId, entry.getValue(), entry.getKey());
LOGGER.warn(
"[DataDrivenItems] In {}: invalid hex color '{}' for tint channel '{}'",
fileId,
entry.getValue(),
entry.getKey()
);
}
}
return Collections.unmodifiableMap(result);
@@ -340,7 +469,12 @@ public final class DataDrivenItemParser {
/** Valid PlayerAnimator bone names for animation_bones validation. */
private static final Set<String> VALID_BONE_NAMES = Set.of(
"head", "body", "rightArm", "leftArm", "rightLeg", "leftLeg"
"head",
"body",
"rightArm",
"leftArm",
"rightLeg",
"leftLeg"
);
/**
@@ -364,14 +498,23 @@ public final class DataDrivenItemParser {
* @return unmodifiable map of animation name to bone set, or null if absent/invalid
*/
@Nullable
private static Map<String, Set<String>> parseAnimationBones(JsonObject obj, ResourceLocation fileId) {
if (!obj.has("animation_bones") || !obj.get("animation_bones").isJsonObject()) {
private static Map<String, Set<String>> parseAnimationBones(
JsonObject obj,
ResourceLocation fileId
) {
if (
!obj.has("animation_bones") ||
!obj.get("animation_bones").isJsonObject()
) {
return null;
}
JsonObject bonesObj = obj.getAsJsonObject("animation_bones");
if (bonesObj.size() == 0) {
LOGGER.error("[DataDrivenItems] In {}: 'animation_bones' is empty", fileId);
LOGGER.error(
"[DataDrivenItems] In {}: 'animation_bones' is empty",
fileId
);
return null;
}
@@ -381,8 +524,11 @@ public final class DataDrivenItemParser {
JsonElement value = entry.getValue();
if (!value.isJsonArray()) {
LOGGER.warn("[DataDrivenItems] In {}: animation_bones['{}'] is not an array, skipping",
fileId, animName);
LOGGER.warn(
"[DataDrivenItems] In {}: animation_bones['{}'] is not an array, skipping",
fileId,
animName
);
continue;
}
@@ -394,29 +540,41 @@ public final class DataDrivenItemParser {
if (VALID_BONE_NAMES.contains(boneName)) {
bones.add(boneName);
} else {
LOGGER.warn("[DataDrivenItems] In {}: animation_bones['{}'] contains unknown bone '{}', skipping",
fileId, animName, boneName);
LOGGER.warn(
"[DataDrivenItems] In {}: animation_bones['{}'] contains unknown bone '{}', skipping",
fileId,
animName,
boneName
);
}
} catch (Exception e) {
LOGGER.warn("[DataDrivenItems] In {}: invalid element in animation_bones['{}']",
fileId, animName);
LOGGER.warn(
"[DataDrivenItems] In {}: invalid element in animation_bones['{}']",
fileId,
animName
);
}
}
if (!bones.isEmpty()) {
result.put(animName, Collections.unmodifiableSet(bones));
} else {
LOGGER.warn("[DataDrivenItems] In {}: animation_bones['{}'] resolved to empty set, skipping",
fileId, animName);
LOGGER.warn(
"[DataDrivenItems] In {}: animation_bones['{}'] resolved to empty set, skipping",
fileId,
animName
);
}
}
if (result.isEmpty()) {
LOGGER.error("[DataDrivenItems] In {}: 'animation_bones' has no valid entries", fileId);
LOGGER.error(
"[DataDrivenItems] In {}: 'animation_bones' has no valid entries",
fileId
);
return null;
}
return Collections.unmodifiableMap(result);
}
}

View File

@@ -29,7 +29,10 @@ public final class DataDrivenItemRegistry {
* Volatile reference to an unmodifiable map. Reload builds a new map
* and swaps atomically; consumer threads always see a consistent snapshot.
*/
private static volatile Map<ResourceLocation, DataDrivenItemDefinition> DEFINITIONS = Map.of();
private static volatile Map<
ResourceLocation,
DataDrivenItemDefinition
> DEFINITIONS = Map.of();
private DataDrivenItemRegistry() {}
@@ -39,7 +42,9 @@ public final class DataDrivenItemRegistry {
*
* @param newDefs the new definitions map (will be defensively copied)
*/
public static void reload(Map<ResourceLocation, DataDrivenItemDefinition> newDefs) {
public static void reload(
Map<ResourceLocation, DataDrivenItemDefinition> newDefs
) {
DEFINITIONS = Collections.unmodifiableMap(new HashMap<>(newDefs));
}
@@ -53,8 +58,12 @@ public final class DataDrivenItemRegistry {
*
* @param newDefs the definitions to merge (will overwrite existing entries with same key)
*/
public static void mergeAll(Map<ResourceLocation, DataDrivenItemDefinition> newDefs) {
Map<ResourceLocation, DataDrivenItemDefinition> merged = new HashMap<>(DEFINITIONS);
public static void mergeAll(
Map<ResourceLocation, DataDrivenItemDefinition> newDefs
) {
Map<ResourceLocation, DataDrivenItemDefinition> merged = new HashMap<>(
DEFINITIONS
);
merged.putAll(newDefs);
DEFINITIONS = Collections.unmodifiableMap(merged);
}
@@ -81,7 +90,9 @@ public final class DataDrivenItemRegistry {
if (stack.isEmpty()) return null;
CompoundTag tag = stack.getTag();
if (tag == null || !tag.contains(NBT_ITEM_ID)) return null;
ResourceLocation id = ResourceLocation.tryParse(tag.getString(NBT_ITEM_ID));
ResourceLocation id = ResourceLocation.tryParse(
tag.getString(NBT_ITEM_ID)
);
if (id == null) return null;
return DEFINITIONS.get(id);
}

View File

@@ -21,50 +21,80 @@ import org.apache.logging.log4j.Logger;
* <p>Follows the same pattern as {@link com.tiedup.remake.client.animation.context.ContextGlbRegistry}:
* prepare phase is a no-op, apply phase scans + parses + atomic-swaps the registry.</p>
*/
public class DataDrivenItemReloadListener extends SimplePreparableReloadListener<Void> {
public class DataDrivenItemReloadListener
extends SimplePreparableReloadListener<Void>
{
private static final Logger LOGGER = LogManager.getLogger("DataDrivenItems");
private static final Logger LOGGER = LogManager.getLogger(
"DataDrivenItems"
);
/** Resource directory containing item definition JSON files. */
private static final String DIRECTORY = "tiedup_items";
@Override
protected Void prepare(ResourceManager resourceManager, ProfilerFiller profiler) {
protected Void prepare(
ResourceManager resourceManager,
ProfilerFiller profiler
) {
// No preparation needed — parsing happens in apply phase
return null;
}
@Override
protected void apply(Void nothing, ResourceManager resourceManager, ProfilerFiller profiler) {
Map<ResourceLocation, DataDrivenItemDefinition> newDefs = new HashMap<>();
protected void apply(
Void nothing,
ResourceManager resourceManager,
ProfilerFiller profiler
) {
Map<ResourceLocation, DataDrivenItemDefinition> newDefs =
new HashMap<>();
Map<ResourceLocation, Resource> resources = resourceManager.listResources(
DIRECTORY, loc -> loc.getPath().endsWith(".json")
);
Map<ResourceLocation, Resource> resources =
resourceManager.listResources(DIRECTORY, loc ->
loc.getPath().endsWith(".json")
);
int skipped = 0;
for (Map.Entry<ResourceLocation, Resource> entry : resources.entrySet()) {
for (Map.Entry<
ResourceLocation,
Resource
> entry : resources.entrySet()) {
ResourceLocation fileId = entry.getKey();
Resource resource = entry.getValue();
try (InputStream input = resource.open()) {
DataDrivenItemDefinition def = DataDrivenItemParser.parse(input, fileId);
DataDrivenItemDefinition def = DataDrivenItemParser.parse(
input,
fileId
);
if (def != null) {
// Check for duplicate IDs
if (newDefs.containsKey(def.id())) {
LOGGER.warn("[DataDrivenItems] Duplicate item ID '{}' from file '{}' — overwriting previous definition",
def.id(), fileId);
LOGGER.warn(
"[DataDrivenItems] Duplicate item ID '{}' from file '{}' — overwriting previous definition",
def.id(),
fileId
);
}
newDefs.put(def.id(), def);
LOGGER.debug("[DataDrivenItems] Loaded: {} -> '{}'", def.id(), def.displayName());
LOGGER.debug(
"[DataDrivenItems] Loaded: {} -> '{}'",
def.id(),
def.displayName()
);
} else {
skipped++;
}
} catch (Exception e) {
LOGGER.error("[DataDrivenItems] Failed to read resource {}: {}", fileId, e.getMessage());
LOGGER.error(
"[DataDrivenItems] Failed to read resource {}: {}",
fileId,
e.getMessage()
);
skipped++;
}
}
@@ -73,7 +103,11 @@ public class DataDrivenItemReloadListener extends SimplePreparableReloadListener
// overwrite client-only definitions on integrated server
DataDrivenItemRegistry.mergeAll(newDefs);
LOGGER.info("[DataDrivenItems] Loaded {} item definitions ({} skipped) from {} JSON files",
newDefs.size(), skipped, resources.size());
LOGGER.info(
"[DataDrivenItems] Loaded {} item definitions ({} skipped) from {} JSON files",
newDefs.size(),
skipped,
resources.size()
);
}
}

View File

@@ -23,50 +23,80 @@ import org.apache.logging.log4j.Logger;
* <p>Registered via {@link net.minecraftforge.event.AddReloadListenerEvent} in
* {@link com.tiedup.remake.core.TiedUpMod.ForgeEvents}.</p>
*/
public class DataDrivenItemServerReloadListener extends SimplePreparableReloadListener<Void> {
public class DataDrivenItemServerReloadListener
extends SimplePreparableReloadListener<Void>
{
private static final Logger LOGGER = LogManager.getLogger("DataDrivenItems");
private static final Logger LOGGER = LogManager.getLogger(
"DataDrivenItems"
);
/** Resource directory containing item definition JSON files (under data/). */
private static final String DIRECTORY = "tiedup_items";
@Override
protected Void prepare(ResourceManager resourceManager, ProfilerFiller profiler) {
protected Void prepare(
ResourceManager resourceManager,
ProfilerFiller profiler
) {
// No preparation needed -- parsing happens in apply phase
return null;
}
@Override
protected void apply(Void nothing, ResourceManager resourceManager, ProfilerFiller profiler) {
Map<ResourceLocation, DataDrivenItemDefinition> newDefs = new HashMap<>();
protected void apply(
Void nothing,
ResourceManager resourceManager,
ProfilerFiller profiler
) {
Map<ResourceLocation, DataDrivenItemDefinition> newDefs =
new HashMap<>();
Map<ResourceLocation, Resource> resources = resourceManager.listResources(
DIRECTORY, loc -> loc.getPath().endsWith(".json")
);
Map<ResourceLocation, Resource> resources =
resourceManager.listResources(DIRECTORY, loc ->
loc.getPath().endsWith(".json")
);
int skipped = 0;
for (Map.Entry<ResourceLocation, Resource> entry : resources.entrySet()) {
for (Map.Entry<
ResourceLocation,
Resource
> entry : resources.entrySet()) {
ResourceLocation fileId = entry.getKey();
Resource resource = entry.getValue();
try (InputStream input = resource.open()) {
DataDrivenItemDefinition def = DataDrivenItemParser.parse(input, fileId);
DataDrivenItemDefinition def = DataDrivenItemParser.parse(
input,
fileId
);
if (def != null) {
// Check for duplicate IDs
if (newDefs.containsKey(def.id())) {
LOGGER.warn("[DataDrivenItems] Server: Duplicate item ID '{}' from file '{}' -- overwriting previous definition",
def.id(), fileId);
LOGGER.warn(
"[DataDrivenItems] Server: Duplicate item ID '{}' from file '{}' -- overwriting previous definition",
def.id(),
fileId
);
}
newDefs.put(def.id(), def);
LOGGER.debug("[DataDrivenItems] Server loaded: {} -> '{}'", def.id(), def.displayName());
LOGGER.debug(
"[DataDrivenItems] Server loaded: {} -> '{}'",
def.id(),
def.displayName()
);
} else {
skipped++;
}
} catch (Exception e) {
LOGGER.error("[DataDrivenItems] Server: Failed to read resource {}: {}", fileId, e.getMessage());
LOGGER.error(
"[DataDrivenItems] Server: Failed to read resource {}: {}",
fileId,
e.getMessage()
);
skipped++;
}
}
@@ -75,7 +105,11 @@ public class DataDrivenItemServerReloadListener extends SimplePreparableReloadLi
// definitions aren't overwritten on integrated server
DataDrivenItemRegistry.mergeAll(newDefs);
LOGGER.info("[DataDrivenItems] Server loaded {} item definitions ({} skipped) from {} JSON files",
newDefs.size(), skipped, resources.size());
LOGGER.info(
"[DataDrivenItems] Server loaded {} item definitions ({} skipped) from {} JSON files",
newDefs.size(),
skipped,
resources.size()
);
}
}