Make Ponies and metadata immutable

This commit is contained in:
Matthew Messinger 2017-06-16 01:41:36 -04:00
parent 825fc22f55
commit 62e77acc38
7 changed files with 79 additions and 85 deletions

View file

@ -14,71 +14,71 @@ import net.minecraft.client.resources.IResource;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
public class Pony { public class Pony {
private static final AtomicInteger ponyCount = new AtomicInteger(); private static final AtomicInteger ponyCount = new AtomicInteger();
private final int ponyId = ponyCount.getAndIncrement(); private final int ponyId = ponyCount.getAndIncrement();
private ResourceLocation textureResourceLocation; private final ResourceLocation texture;
public PonyData metadata = new PonyData(); private final PonyData metadata;
private int skinCheckCount;
private boolean skinChecked;
public Pony(AbstractClientPlayer player) { public Pony(AbstractClientPlayer player) {
this.textureResourceLocation = player.getLocationSkin(); this.texture = player.getLocationSkin();
MineLittlePony.logger.debug("+ Initialising new pony #{} for player {} ({}) with resource location {}.", this.ponyId, this.metadata = this.checkSkin(this.texture);
player.getName(), player.getUniqueID(), this.textureResourceLocation);
this.checkSkin(this.textureResourceLocation); MineLittlePony.logger.debug("+ Initialising new pony #{} for player {} ({}) with resource location {}.",
this.ponyId, player.getName(), player.getUniqueID(), this.texture);
} }
public Pony(ResourceLocation aTextureResourceLocation) { public Pony(ResourceLocation resourceLocation) {
this.textureResourceLocation = aTextureResourceLocation; this(resourceLocation, null);
MineLittlePony.logger.debug("+ Initialising new pony #{} with resource location {}.", this.ponyId, this.textureResourceLocation);
this.checkSkin(this.textureResourceLocation);
} }
public void invalidateSkinCheck() { public Pony(ResourceLocation aTextureResourceLocation, @Nullable PonyData meta) {
this.skinChecked = false; this.texture = aTextureResourceLocation;
metadata = new PonyData(); this.metadata = meta != null ? meta : this.checkSkin(this.texture);
MineLittlePony.logger.debug("+ Initialising new pony #{} with resource location {}.", this.ponyId, this.texture);
} }
public void checkSkin() { private PonyData checkSkin(ResourceLocation textureResourceLocation) {
if (!this.skinChecked) { PonyData data = checkPonyMeta(textureResourceLocation);
this.checkSkin(this.textureResourceLocation); if (data == null) {
}
}
private void checkSkin(ResourceLocation textureResourceLocation) {
if(!checkPonyMeta(textureResourceLocation)) {
BufferedImage skinImage = this.getBufferedImage(textureResourceLocation); BufferedImage skinImage = this.getBufferedImage(textureResourceLocation);
if (skinImage != null) { if (skinImage != null) {
this.checkSkin(skinImage); data = this.checkSkin(skinImage);
} else {
data = new PonyData();
} }
} }
return data;
} }
private boolean checkPonyMeta(ResourceLocation location) { @Nullable
private PonyData checkPonyMeta(ResourceLocation location) {
try { try {
IResource res = Minecraft.getMinecraft().getResourceManager().getResource(location); IResource res = Minecraft.getMinecraft().getResourceManager().getResource(location);
if (res.hasMetadata()) { if (res.hasMetadata()) {
PonyData data = res.getMetadata(PonyDataSerialzier.NAME); PonyData data = res.getMetadata(PonyDataSerialzier.NAME);
if (data != null) { if (data != null) {
metadata = data; return data;
this.skinChecked = true;
} }
return true;
} }
} catch (FileNotFoundException e) {
// Ignore uploaded texture
} catch (IOException e) { } catch (IOException e) {
MineLittlePony.logger.warn("Unable to read {} metadata", location, e); MineLittlePony.logger.warn("Unable to read {} metadata", location, e);
} }
return false; return null;
} }
@Nullable @Nullable
@ -113,10 +113,9 @@ public class Pony {
return skinImage; return skinImage;
} }
public void checkSkin(BufferedImage bufferedimage) { private PonyData checkSkin(BufferedImage bufferedimage) {
MineLittlePony.logger.debug("\tStart skin check #{} for pony #{} with image {}.", ++this.skinCheckCount, this.ponyId, bufferedimage); MineLittlePony.logger.debug("\tStart skin check for pony #{} with image {}.", this.ponyId, bufferedimage);
metadata = PonyData.parse(bufferedimage); return PonyData.parse(bufferedimage);
this.skinChecked = true;
} }
public boolean isPegasusFlying(EntityPlayer player) { public boolean isPegasusFlying(EntityPlayer player) {
@ -149,8 +148,11 @@ public class Pony {
return model; return model;
} }
public ResourceLocation getTextureResourceLocation() { public ResourceLocation getTexture() {
return this.textureResourceLocation; return this.texture;
} }
public PonyData getMetadata() {
return metadata;
}
} }

View file

@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableBiMap;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.Map; import java.util.Map;
import javax.annotation.concurrent.Immutable;
@Immutable
public class PonyData implements IPonyData { public class PonyData implements IPonyData {
private static final Map<Integer, PonyRace> RACE_COLORS = ImmutableBiMap.<Integer, PonyRace>builder() private static final Map<Integer, PonyRace> RACE_COLORS = ImmutableBiMap.<Integer, PonyRace>builder()
@ -26,11 +28,11 @@ public class PonyData implements IPonyData {
.put(0x534b76, PonySize.TALL) .put(0x534b76, PonySize.TALL)
.build(); .build();
private PonyRace race; private final PonyRace race;
private TailLengths tailSize; private final TailLengths tailSize;
private PonyGender gender; private final PonyGender gender;
private PonySize size; private final PonySize size;
private int glowColor; private final int glowColor;
public PonyData() { public PonyData() {
this(PonyRace.HUMAN, TailLengths.FULL, PonyGender.MARE, PonySize.NORMAL, 0x4444aa); this(PonyRace.HUMAN, TailLengths.FULL, PonyGender.MARE, PonySize.NORMAL, 0x4444aa);
@ -48,34 +50,18 @@ public class PonyData implements IPonyData {
return race; return race;
} }
public void setRace(PonyRace race) {
this.race = race;
}
public TailLengths getTail() { public TailLengths getTail() {
return tailSize; return tailSize;
} }
public void setTail(TailLengths tailSize) {
this.tailSize = tailSize;
}
public PonyGender getGender() { public PonyGender getGender() {
return gender; return gender;
} }
public void setGender(PonyGender gender) {
this.gender = gender;
}
public PonySize getSize() { public PonySize getSize() {
return MineLittlePony.getConfig().sizes ? size : PonySize.NORMAL; return MineLittlePony.getConfig().sizes ? size : PonySize.NORMAL;
} }
public void setSize(PonySize size) {
this.size = size;
}
public int getGlowColor() { public int getGlowColor() {
return glowColor; return glowColor;
} }
@ -84,10 +70,6 @@ public class PonyData implements IPonyData {
return this.race != null && this.race.hasHorn() && this.glowColor != 0; return this.race != null && this.race.hasHorn() && this.glowColor != 0;
} }
public void setGlowColor(int glowColor) {
this.glowColor = glowColor & 0xffffff;
}
static PonyData parse(BufferedImage image) { static PonyData parse(BufferedImage image) {
int racePx = TriggerPixels.RACE.readColor(image); int racePx = TriggerPixels.RACE.readColor(image);
PonyRace race = RACE_COLORS.getOrDefault(racePx, PonyRace.HUMAN); PonyRace race = RACE_COLORS.getOrDefault(racePx, PonyRace.HUMAN);

View file

@ -46,21 +46,25 @@ public class PonyManager implements IResourceManagerReloadListener {
MineLittlePony.logger.info("Done initializing models."); MineLittlePony.logger.info("Done initializing models.");
} }
public Pony getPonyFromResourceRegistry(ResourceLocation skinResourceLocation) { public Pony getPony(ResourceLocation skinResourceLocation) {
return this.poniesCache.computeIfAbsent(skinResourceLocation, Pony::new); return this.poniesCache.computeIfAbsent(skinResourceLocation, Pony::new);
} }
public Pony getPonyFromResourceRegistry(AbstractClientPlayer player) { public Pony getPony(AbstractClientPlayer player) {
Pony myLittlePony = this.poniesCache.computeIfAbsent(player.getLocationSkin(), res -> new Pony(player)); Pony myLittlePony = this.poniesCache.computeIfAbsent(player.getLocationSkin(), res -> new Pony(player));
if (config.getPonyLevel() == PonyLevel.PONIES && myLittlePony.metadata.getRace() == PonyRace.HUMAN) { if (config.getPonyLevel() == PonyLevel.PONIES && myLittlePony.getMetadata().getRace() == PonyRace.HUMAN) {
myLittlePony = this.getPonyFromBackgroundResourceRegistry(player); myLittlePony = this.getPonyFromBackgroundResourceRegistry(player);
} }
return myLittlePony; return myLittlePony;
} }
public Pony removePony(ResourceLocation location) {
return this.poniesCache.remove(location);
}
private ResourceLocation getBackgroundPonyResource(UUID id) { private ResourceLocation getBackgroundPonyResource(UUID id) {
if (getNumberOfPonies() > 0) { if (getNumberOfPonies() > 0) {
int backgroundIndex = id.hashCode() % this.getNumberOfPonies(); int backgroundIndex = id.hashCode() % this.getNumberOfPonies();

View file

@ -25,20 +25,20 @@ public class GuiSkinsMineLP extends GuiSkins {
@Override @Override
protected void onSetLocalSkin(BufferedImage skin, MinecraftProfileTexture.Type type) { protected void onSetLocalSkin(BufferedImage skin, MinecraftProfileTexture.Type type) {
MineLittlePony.logger.debug("Invalidating old local skin, checking updated local skin"); MineLittlePony.logger.debug("Invalidating old local skin, checking updated local skin");
ponyManager.getPonyFromResourceRegistry(this.localPlayer.getSkinTexture()).checkSkin(skin); ponyManager.removePony(this.localPlayer.getSkinTexture());
} }
@Override @Override
protected void onSetRemoteSkin(MinecraftProfileTexture.Type type) { protected void onSetRemoteSkin(MinecraftProfileTexture.Type type) {
MineLittlePony.logger.debug("Invalidating old remote skin, checking updated remote skin"); MineLittlePony.logger.debug("Invalidating old remote skin, checking updated remote skin");
ponyManager.getPonyFromResourceRegistry(this.remotePlayer.getSkinTexture()).invalidateSkinCheck(); ponyManager.removePony(this.remotePlayer.getSkinTexture());
} }
@Override @Override
public void onGuiClosed() { public void onGuiClosed() {
super.onGuiClosed(); super.onGuiClosed();
ponyManager.getPonyFromResourceRegistry(this.localPlayer.getSkinTexture()).invalidateSkinCheck(); ponyManager.removePony(this.localPlayer.getSkinTexture());
ponyManager.getPonyFromResourceRegistry(this.remotePlayer.getSkinTexture()).invalidateSkinCheck(); ponyManager.removePony(this.remotePlayer.getSkinTexture());
} }
} }

View file

@ -16,6 +16,7 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> { public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> {
@ -25,13 +26,15 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> {
@Override @Override
public ModelPlayer getEntityModel(EntityPonyModel playermodel) { public ModelPlayer getEntityModel(EntityPonyModel playermodel) {
Pony thePony = MineLittlePony.getInstance().getManager().getPonyFromResourceRegistry(this.getEntityTexture(playermodel)); ResourceLocation loc = this.getEntityTexture(playermodel);
thePony.invalidateSkinCheck(); if (loc == null) {
thePony.checkSkin(); return super.getEntityModel(playermodel);
}
Pony thePony = MineLittlePony.getInstance().getManager().getPony(loc);
// TODO small arms // TODO small arms
PlayerModel pm = thePony.getModel(true, false); PlayerModel pm = thePony.getModel(true, false);
pm.apply(thePony.metadata); pm.apply(thePony.getMetadata());
return pm.getModel(); return pm.getModel();
} }

View file

@ -79,7 +79,7 @@ public abstract class MixinRenderPlayer extends RenderLivingBase<AbstractClientP
this.playerModel.getModel().isSleeping = player.isPlayerSleeping(); this.playerModel.getModel().isSleeping = player.isPlayerSleeping();
if (MineLittlePony.getConfig().showscale && this.playerModel.getModel().metadata.getRace() != PonyRace.HUMAN) { if (MineLittlePony.getConfig().showscale && this.playerModel.getModel().metadata.getRace() != PonyRace.HUMAN) {
PonySize size = thePony.metadata.getSize(); PonySize size = thePony.getMetadata().getSize();
if (size == PonySize.FOAL) { if (size == PonySize.FOAL) {
this.shadowSize = 0.25F; this.shadowSize = 0.25F;
} else if (size == PonySize.NORMAL) { } else if (size == PonySize.NORMAL) {
@ -102,7 +102,7 @@ public abstract class MixinRenderPlayer extends RenderLivingBase<AbstractClientP
private void setupPlayerScale(AbstractClientPlayer player, double xPosition, double yPosition, double zPosition, CallbackInfo ci) { private void setupPlayerScale(AbstractClientPlayer player, double xPosition, double yPosition, double zPosition, CallbackInfo ci) {
if (MineLittlePony.getConfig().showscale && !(playerModel.getModel() instanceof ModelHumanPlayer)) { if (MineLittlePony.getConfig().showscale && !(playerModel.getModel() instanceof ModelHumanPlayer)) {
PonySize size = thePony.metadata.getSize(); PonySize size = thePony.getMetadata().getSize();
if (size == PonySize.LARGE) { if (size == PonySize.LARGE) {
GlStateManager.scale(0.9F, 0.9F, 0.9F); GlStateManager.scale(0.9F, 0.9F, 0.9F);
} else if (size == PonySize.NORMAL || size == PonySize.FOAL) { } else if (size == PonySize.NORMAL || size == PonySize.FOAL) {
@ -236,24 +236,22 @@ public abstract class MixinRenderPlayer extends RenderLivingBase<AbstractClientP
} }
private void updateModel(AbstractClientPlayer player) { private void updateModel(AbstractClientPlayer player) {
this.thePony = MineLittlePony.getInstance().getManager().getPonyFromResourceRegistry(player); this.thePony = MineLittlePony.getInstance().getManager().getPony(player);
thePony.invalidateSkinCheck();
thePony.checkSkin();
this.playerModel = this.getModel(player); this.playerModel = this.getModel(player);
this.mainModel = this.playerModel.getModel(); this.mainModel = this.playerModel.getModel();
this.playerModel.apply(thePony.metadata); this.playerModel.apply(thePony.getMetadata());
} }
@Override @Override
@Nonnull @Nonnull
public ResourceLocation getEntityTexture(AbstractClientPlayer player) { public ResourceLocation getEntityTexture(AbstractClientPlayer player) {
Pony thePony = MineLittlePony.getInstance().getManager().getPonyFromResourceRegistry(player); Pony thePony = MineLittlePony.getInstance().getManager().getPony(player);
return thePony.getTextureResourceLocation(); return thePony.getTexture();
} }
private PlayerModel getModel(AbstractClientPlayer player) { private PlayerModel getModel(AbstractClientPlayer player) {
ResourceLocation skin = getEntityTexture(player); ResourceLocation skin = getEntityTexture(player);
Pony thePony = MineLittlePony.getInstance().getManager().getPonyFromResourceRegistry(skin); Pony thePony = MineLittlePony.getInstance().getManager().getPony(skin);
return thePony.getModel(false, this.smallArms); return thePony.getModel(false, this.smallArms);
} }

View file

@ -18,11 +18,16 @@ public class RenderPonySkeleton<Skeleton extends AbstractSkeleton> extends Rende
public RenderPonySkeleton(RenderManager rm) { public RenderPonySkeleton(RenderManager rm) {
super(rm, PMAPI.skeleton); super(rm, PMAPI.skeleton);
}
@Override
protected void addLayers() {
super.addLayers();
this.addLayer(new LayerBipedArmor(this) { this.addLayer(new LayerBipedArmor(this) {
@Override @Override
protected void initArmor() { protected void initArmor() {
this.modelLeggings = PMAPI.skeleton.getArmor().modelArmor; this.modelLeggings = getPony().getArmor().modelArmor;
this.modelArmor = PMAPI.skeleton.getArmor().modelArmorChestplate; this.modelArmor = getPony().getArmor().modelArmorChestplate;
} }
}); });
} }