use of net.minecraft.util.registry.IRegistry in project FoamFix by asiekierka.
the class Deduplicator method deduplicateObject.
public Object deduplicateObject(Object o, int recursion) {
if (o == null || recursion > maxRecursion)
return o;
Class c = o.getClass();
if (!shouldCheckClass(c))
return o;
if (!deduplicatedObjects.add(o))
return o;
boolean canTrim = o instanceof Predicate || TRIM_ARRAYS_CLASSES.contains(c);
if (canTrim) {
if (c == SimpleBakedModel.class) {
for (EnumFacing facing : EnumFacing.VALUES) {
List l = ((SimpleBakedModel) o).getQuads(null, facing, 0);
trimArray(l);
}
}
}
if (o instanceof IBakedModel) {
if (o instanceof PerspectiveMapWrapper) {
try {
Object to = IPAM_MW_TRANSFORMS_GETTER.invoke(o);
Object toD = deduplicate0(to);
if (toD != null && to != toD) {
IPAM_MW_TRANSFORMS_SETTER.invoke(o, toD);
}
} catch (Throwable t) {
t.printStackTrace();
}
} else if ("net.minecraftforge.client.model.BakedItemModel".equals(c.getName())) {
try {
Object to = BIM_TRANSFORMS_GETTER.invoke(o);
Object toD = deduplicate0(to);
if (toD != null && to != toD) {
BIM_TRANSFORMS_SETTER.invoke(o, toD);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
if (c == BlockPartFace.class) {
((BlockPartFace) o).blockFaceUV.uvs = (float[]) deduplicate0(((BlockPartFace) o).blockFaceUV.uvs);
return o;
}
if (o instanceof BakedQuad) {
if (c == BakedQuad.class) {
if (FoamFixShared.config.expUnpackBakedQuads) {
BakedQuad quad = (BakedQuad) o;
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(quad.getFormat());
quad.pipe(builder);
o = builder.build();
c = UnpackedBakedQuad.class;
}
}
if (c == UnpackedBakedQuad.class) {
try {
float[][][] array = (float[][][]) FIELD_UNPACKED_DATA_GETTER.invokeExact((UnpackedBakedQuad) o);
// float[][][]s are not currently deduplicated
deduplicate0(array);
} catch (Throwable t) {
t.printStackTrace();
}
}
} else if (o instanceof ResourceLocation || c == TRSRTransformation.class || c == Style.class) {
return deduplicate0(o);
} else if (c == ItemCameraTransforms.class || c == Vec3d.class || c == Vec3i.class || c == BlockPos.class) {
return deduplicate0(o);
/* if (d != o)
return d;
TODO: Add ItemTransformVec3f dedup, maybe
return o; */
} else if (o instanceof Item || o instanceof Block || o instanceof World || o instanceof Entity || o instanceof Logger || o instanceof IRegistry) {
BLACKLIST_CLASS.add(c);
return o;
} else if (o instanceof ItemOverrideList && o != ItemOverrideList.NONE) {
try {
List list = (List) IOL_OVERRIDES_GETTER.invokeExact((ItemOverrideList) o);
if (list.isEmpty()) {
if (c == ItemOverrideList.class) {
successfuls++;
return ItemOverrideList.NONE;
} else if (c == AnimationItemOverrideList.class) {
IOL_OVERRIDES_SETTER.invokeExact((ItemOverrideList) o, (List) ImmutableList.of());
successfuls++;
}
}
} catch (Throwable t) {
}
} else if (o instanceof java.util.Optional) {
java.util.Optional opt = (java.util.Optional) o;
if (opt.isPresent()) {
Object b = deduplicateObject(opt.get(), recursion + 1);
if (b != null) {
if (JAVA_OPTIONALS.containsKey(b)) {
successfuls++;
return JAVA_OPTIONALS.get(b);
}
if (b != opt.get()) {
java.util.Optional opt2 = java.util.Optional.of(b);
JAVA_OPTIONALS.put(b, opt2);
return opt2;
} else {
JAVA_OPTIONALS.put(opt.get(), opt);
return opt;
}
}
} else {
return opt;
}
} else if (o instanceof com.google.common.base.Optional) {
Optional opt = (Optional) o;
if (opt.isPresent()) {
Object b = deduplicateObject(opt.get(), recursion + 1);
if (b != null) {
if (GUAVA_OPTIONALS.containsKey(b)) {
successfuls++;
return GUAVA_OPTIONALS.get(b);
}
if (b != opt.get()) {
com.google.common.base.Optional opt2 = com.google.common.base.Optional.of(b);
GUAVA_OPTIONALS.put(b, opt2);
return opt2;
} else {
GUAVA_OPTIONALS.put(opt.get(), opt);
return opt;
}
}
} else {
return opt;
}
} else if (o instanceof Multimap) {
if (o instanceof ImmutableMultimap || o instanceof SortedSetMultimap) {
for (Object value : ((Multimap) o).values()) {
deduplicateObject(value, recursion + 1);
}
} else {
for (Object key : ((Multimap) o).keySet()) {
List l = Lists.newArrayList(((Multimap) o).values());
for (int i = 0; i < l.size(); i++) {
l.set(i, deduplicateObject(l.get(i), recursion + 1));
}
((Multimap) o).replaceValues(key, l);
}
}
} else if (o instanceof Map) {
for (Object v : ((Map) o).keySet()) {
deduplicateObject(v, recursion + 1);
}
if (o instanceof SortedMap || IMMUTABLE_CLASS.contains(c)) {
for (Object v : ((Map) o).values()) {
deduplicateObject(v, recursion + 1);
}
} else if (o instanceof ImmutableMap) {
ImmutableMap im = (ImmutableMap) o;
ImmutableMap.Builder newMap = (o instanceof ImmutableBiMap) ? ImmutableBiMap.builder() : ImmutableMap.builder();
boolean deduplicated = false;
for (Object key : im.keySet()) {
Object a = im.get(key);
Object b = deduplicateObject(a, recursion + 1);
newMap.put(key, b != null ? b : a);
if (b != null && b != a)
deduplicated = true;
}
return deduplicated ? newMap.build() : o;
} else {
try {
for (Object key : ((Map) o).keySet()) {
Object value = ((Map) o).get(key);
Object valueD = deduplicateObject(value, recursion + 1);
if (valueD != null && value != valueD)
((Map) o).put(key, valueD);
}
} catch (UnsupportedOperationException e) {
IMMUTABLE_CLASS.add(c);
for (Object v : ((Map) o).values()) {
deduplicateObject(v, recursion + 1);
}
}
}
} else if (o instanceof List) {
if (IMMUTABLE_CLASS.contains(c)) {
List l = (List) o;
for (int i = 0; i < l.size(); i++) {
deduplicateObject(l.get(i), recursion + 1);
}
} else if (o instanceof ImmutableList) {
ImmutableList il = (ImmutableList) o;
ImmutableList.Builder builder = ImmutableList.builder();
boolean deduplicated = false;
for (int i = 0; i < il.size(); i++) {
Object a = il.get(i);
Object b = deduplicateObject(a, recursion + 1);
builder.add(b != null ? b : a);
if (b != null && b != a)
deduplicated = true;
}
if (deduplicated) {
return builder.build();
}
} else {
List l = (List) o;
try {
for (int i = 0; i < l.size(); i++) {
l.set(i, deduplicateObject(l.get(i), recursion + 1));
}
} catch (UnsupportedOperationException e) {
IMMUTABLE_CLASS.add(c);
for (int i = 0; i < l.size(); i++) {
deduplicateObject(l.get(i), recursion + 1);
}
}
}
} else if (o instanceof ImmutableSet) {
if (!(o instanceof ImmutableSortedSet)) {
ImmutableSet.Builder builder = new ImmutableSet.Builder();
for (Object o1 : ((Set) o)) {
builder.add(deduplicateObject(o1, recursion + 1));
}
o = builder.build();
} else {
for (Object o1 : ((Set) o)) {
deduplicateObject(o1, recursion + 1);
}
}
} else if (o instanceof Collection) {
if (!(o instanceof SortedSet)) {
if (!COLLECTION_CONSTRUCTORS.containsKey(c)) {
try {
COLLECTION_CONSTRUCTORS.put(c, MethodHandles.publicLookup().findConstructor(c, MethodType.methodType(void.class)));
} catch (Exception e) {
COLLECTION_CONSTRUCTORS.put(c, null);
}
}
MethodHandle constructor = COLLECTION_CONSTRUCTORS.get(c);
if (constructor != null) {
try {
Collection nc = (Collection) constructor.invoke();
if (nc != null) {
for (Object o1 : ((Collection) o)) {
nc.add(deduplicateObject(o1, recursion + 1));
}
return nc;
}
} catch (Throwable t) {
COLLECTION_CONSTRUCTORS.put(c, null);
}
}
}
// fallback
for (Object o1 : ((Collection) o)) {
deduplicateObject(o1, recursion + 1);
}
} else if (c.isArray()) {
for (int i = 0; i < Array.getLength(o); i++) {
Object entry = Array.get(o, i);
Object entryD = deduplicateObject(entry, recursion + 1);
if (entryD != null && entry != entryD)
Array.set(o, i, entryD);
}
} else {
if (!CLASS_FIELDS.containsKey(c)) {
ImmutableSet.Builder<MethodHandle[]> fsBuilder = ImmutableSet.builder();
Class cc = c;
do {
for (Field f : cc.getDeclaredFields()) {
if ((f.getModifiers() & Modifier.STATIC) != 0)
continue;
if (shouldCheckClass(f.getType())) {
try {
f.setAccessible(true);
fsBuilder.add(new MethodHandle[] { MethodHandles.lookup().unreflectGetter(f), MethodHandles.lookup().unreflectSetter(f) });
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
} while ((cc = cc.getSuperclass()) != Object.class);
CLASS_FIELDS.put(c, fsBuilder.build());
}
for (MethodHandle[] mh : CLASS_FIELDS.get(c)) {
try {
// System.out.println("-" + Strings.repeat("-", recursion) + "* " + f.getName());
Object value = mh[0].invoke(o);
Object valueD = deduplicateObject(value, recursion + 1);
if (canTrim)
trimArray(valueD);
if (valueD != null && value != valueD)
mh[1].invoke(o, valueD);
} catch (IllegalAccessException e) {
} catch (Throwable t) {
t.printStackTrace();
}
}
}
return o;
}
use of net.minecraft.util.registry.IRegistry in project FoamFix by asiekierka.
the class FoamFixModelRegistryDuplicateWipe method onTextureStitchPost.
@SubscribeEvent
public void onTextureStitchPost(TextureStitchEvent.Post event) {
ItemModelMesher imm = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();
BlockModelShapes bms = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
ModelManager mgr = bms.getModelManager();
Field f = ReflectionHelper.findField(ModelManager.class, "modelRegistry", "field_174958_a");
try {
IRegistry<ModelResourceLocation, IBakedModel> registry = (IRegistry<ModelResourceLocation, IBakedModel>) f.get(mgr);
FoamFix.logger.info("Clearing unnecessary model registry of size " + registry.getKeys().size() + ".");
for (ModelResourceLocation l : registry.getKeys()) {
registry.putObject(l, ProxyClient.DUMMY_MODEL);
}
} catch (Exception e) {
e.printStackTrace();
}
f = ReflectionHelper.findField(BlockModelShapes.class, "bakedModelStore", "field_178129_a");
try {
Map<IBlockState, IBakedModel> modelStore = (Map<IBlockState, IBakedModel>) f.get(bms);
FoamFix.logger.info("Clearing unnecessary model store of size " + modelStore.size() + ".");
modelStore.clear();
} catch (Exception e) {
e.printStackTrace();
}
if (imm instanceof ItemModelMesherForge) {
f = ReflectionHelper.findField(ItemModelMesherForge.class, "models");
try {
Map<IRegistryDelegate<Item>, TIntObjectHashMap<IBakedModel>> modelStore = (Map<IRegistryDelegate<Item>, TIntObjectHashMap<IBakedModel>>) f.get(imm);
FoamFix.logger.info("Clearing unnecessary item shapes cache of size " + modelStore.size() + ".");
modelStore.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Aggregations