add firework boosting and elytra sound
This commit is contained in:
parent
a58a275824
commit
93bfd94628
|
@ -1580,6 +1580,12 @@
|
|||
"random/drink"
|
||||
]
|
||||
},
|
||||
"item.elytra.flying": {
|
||||
"category": "player",
|
||||
"sounds": [
|
||||
"item/elytra/elytra_loop"
|
||||
]
|
||||
},
|
||||
"random.eat": {
|
||||
"category": "player",
|
||||
"sounds": [
|
||||
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 211 B |
Binary file not shown.
81698
javascript/classes.js
81698
javascript/classes.js
File diff suppressed because it is too large
Load Diff
|
@ -3,31 +3,28 @@ package net.lax1dude.eaglercraft.v1_8;
|
|||
import java.math.BigInteger;
|
||||
|
||||
public class EaglercraftVersion {
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/// Customize these to fit your fork:
|
||||
|
||||
|
||||
public static final String projectForkName = "Eaglercraft Lambda";
|
||||
public static final String projectForkVersion = "2.0.0";
|
||||
public static final String projectForkVersion = "0.3.0";
|
||||
public static final String projectForkVendor = "hoosiertransfer";
|
||||
|
||||
|
||||
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public static final String projectOriginName = "EaglercraftX";
|
||||
public static final String projectOriginAuthor = "lax1dude";
|
||||
public static final String projectOriginRevision = "1.8";
|
||||
public static final String projectOriginRevision = "1.9";
|
||||
public static final String projectOriginVersion = "u29";
|
||||
|
||||
|
||||
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
|
||||
|
||||
|
||||
|
||||
|
||||
// Updating configuration
|
||||
|
||||
|
||||
public static final boolean enableUpdateService = false;
|
||||
|
||||
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
|
||||
|
@ -36,10 +33,9 @@ public class EaglercraftVersion {
|
|||
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;
|
||||
|
||||
// public key modulus for official 1.8 updates
|
||||
public static final BigInteger updateSignatureModulus = new BigInteger("14419476194820052109078379102436982757438300194194974078260570958862225232043861026588258585967060437391326494976080031137298500457111529693806931143421725626747051503616606418909609840275122831550688481329699012469742002429706330734797679859799085213517354399295425740214330234086361416936984593337389989505613123225737002654977194421571825036717017788527234114501215218715499682638139386636103589791643964827904791195488978835113700772208317974307363542114867750505953323167521731238542123593257269990619007858952216110012513121779359926747737258698347806747854986471035713105133999027704095451858121831297923962641");
|
||||
|
||||
|
||||
|
||||
public static final BigInteger updateSignatureModulus = new BigInteger(
|
||||
"14419476194820052109078379102436982757438300194194974078260570958862225232043861026588258585967060437391326494976080031137298500457111529693806931143421725626747051503616606418909609840275122831550688481329699012469742002429706330734797679859799085213517354399295425740214330234086361416936984593337389989505613123225737002654977194421571825036717017788527234114501215218715499682638139386636103589791643964827904791195488978835113700772208317974307363542114867750505953323167521731238542123593257269990619007858952216110012513121779359926747737258698347806747854986471035713105133999027704095451858121831297923962641");
|
||||
|
||||
// Miscellaneous variables:
|
||||
|
||||
public static final String mainMenuStringA = "Minecraft 1.8.8";
|
||||
|
|
|
@ -1676,7 +1676,7 @@ public class Block implements ILitBlock {
|
|||
if (flag1 || flag2 || flag3 || flag4 || flag5) {
|
||||
flag = true;
|
||||
}
|
||||
|
||||
flag |= block instanceof BlockLiquid;
|
||||
block13.useNeighborBrightness = flag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
|
|||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
|
@ -234,7 +233,6 @@ public abstract class BlockPurpurSlab extends BlockSlab {
|
|||
for (int i = 0; i < types.length; ++i) {
|
||||
META_LOOKUP[types[i].getMetadata()] = types[i];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package net.minecraft.client.audio;
|
||||
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class ElytraSound extends MovingSound {
|
||||
private final EntityPlayerSP player;
|
||||
private int time;
|
||||
|
||||
public ElytraSound(EntityPlayerSP p_i47113_1_) {
|
||||
super(new ResourceLocation("minecraft:item.elytra.flying"));
|
||||
this.player = p_i47113_1_;
|
||||
this.repeat = true;
|
||||
this.repeatDelay = 0;
|
||||
this.volume = 0.1F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the old updateEntity(), except more generic.
|
||||
*/
|
||||
public void update() {
|
||||
++this.time;
|
||||
|
||||
if (!this.player.isDead && (this.time <= 20 || this.player.isElytraFlying())) {
|
||||
this.xPosF = (float) this.player.posX;
|
||||
this.yPosF = (float) this.player.posY;
|
||||
this.zPosF = (float) this.player.posZ;
|
||||
float f = MathHelper.sqrt_double(this.player.motionX * this.player.motionX
|
||||
+ this.player.motionZ * this.player.motionZ + this.player.motionY * this.player.motionY);
|
||||
float f1 = f / 2.0F;
|
||||
|
||||
if ((double) f >= 0.01D) {
|
||||
this.volume = MathHelper.clamp_float(f1 * f1, 0.0F, 1.0F);
|
||||
} else {
|
||||
this.volume = 0.0F;
|
||||
}
|
||||
|
||||
if (this.time < 20) {
|
||||
this.volume = 0.0F;
|
||||
} else if (this.time < 40) {
|
||||
this.volume = (float) ((double) this.volume * ((double) (this.time - 20) / 20.0D));
|
||||
}
|
||||
|
||||
float f2 = 0.8F;
|
||||
|
||||
if (this.volume > 0.8F) {
|
||||
this.pitch = 1.0F + (this.volume - 0.8F);
|
||||
} else {
|
||||
this.pitch = 1.0F;
|
||||
}
|
||||
} else {
|
||||
this.donePlaying = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import net.hoosiertransfer.EaglerItems;
|
|||
import net.lax1dude.eaglercraft.v1_8.sp.lan.LANClientNetworkManager;
|
||||
import net.lax1dude.eaglercraft.v1_8.sp.socket.ClientIntegratedServerNetworkManager;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.ElytraSound;
|
||||
import net.minecraft.client.audio.MovingSoundMinecartRiding;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.client.gui.GuiCommandBlock;
|
||||
|
@ -755,7 +756,7 @@ public class EntityPlayerSP extends AbstractClientPlayer {
|
|||
this.sendQueue.addToSendQueue(new C0BPacketEntityAction(this,
|
||||
C0BPacketEntityAction.Action.START_FALL_FLYING));
|
||||
// TODO Eltrya sound
|
||||
// this.mc.getSoundHandler().playSound(new ElytraSound(this));
|
||||
this.mc.getSoundHandler().playSound(new ElytraSound(this));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,45 +13,47 @@ import net.minecraft.util.MathHelper;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class LayerElytra implements LayerRenderer<AbstractClientPlayer> {
|
||||
private static final ResourceLocation TEXTURE_ELYTRA = new ResourceLocation("textures/entity/elytra.png");
|
||||
private final RenderPlayer renderPlayer;
|
||||
private final ModelElytra modelElytra = new ModelElytra();
|
||||
private static final ResourceLocation TEXTURE_ELYTRA = new ResourceLocation("textures/entity/elytra.png");
|
||||
private final RenderPlayer renderPlayer;
|
||||
private final ModelElytra modelElytra = new ModelElytra();
|
||||
|
||||
public LayerElytra(RenderPlayer renderPlayerIn) {
|
||||
this.renderPlayer = renderPlayerIn;
|
||||
}
|
||||
public LayerElytra(RenderPlayer renderPlayerIn) {
|
||||
this.renderPlayer = renderPlayerIn;
|
||||
}
|
||||
|
||||
public void doRenderLayer(AbstractClientPlayer entitylivingbaseIn, float limbSwing, float limbSwingAmount,
|
||||
float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
|
||||
ItemStack itemstack = entitylivingbaseIn.getCurrentArmor(2);
|
||||
public void doRenderLayer(AbstractClientPlayer entitylivingbaseIn, float limbSwing, float limbSwingAmount,
|
||||
float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
|
||||
ItemStack itemstack = entitylivingbaseIn.getCurrentArmor(2);
|
||||
|
||||
if (itemstack != null && itemstack.getItem() == EaglerItems.getEaglerItem("elytra")) {
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.enableBlend();
|
||||
this.renderPlayer.bindTexture(TEXTURE_ELYTRA);
|
||||
if (itemstack != null && itemstack.getItem() == EaglerItems.getEaglerItem("elytra")) {
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.enableBlend();
|
||||
this.renderPlayer.bindTexture(TEXTURE_ELYTRA);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.0F, 0.0F, 0.125F);
|
||||
this.modelElytra.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw,
|
||||
headPitch, scale,
|
||||
entitylivingbaseIn);
|
||||
this.modelElytra.render(entitylivingbaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw,
|
||||
headPitch,
|
||||
scale);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.0F, 0.0F, 0.125F);
|
||||
this.modelElytra.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw,
|
||||
headPitch, scale,
|
||||
entitylivingbaseIn);
|
||||
this.modelElytra.render(entitylivingbaseIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw,
|
||||
headPitch,
|
||||
scale);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if (itemstack.isItemEnchanted()) {
|
||||
LayerArmorBase.renderEnchantedGlint(this.renderPlayer, entitylivingbaseIn,
|
||||
this.modelElytra, limbSwing,
|
||||
limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch,
|
||||
scale);
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
if (itemstack.isItemEnchanted()) {
|
||||
GlStateManager.pushMatrix();
|
||||
LayerArmorBase.renderEnchantedGlint(this.renderPlayer, entitylivingbaseIn,
|
||||
this.modelElytra, limbSwing,
|
||||
limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch,
|
||||
scale);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean shouldCombineTextures() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean shouldCombineTextures() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1459,6 +1459,10 @@ public abstract class EntityLivingBase extends Entity {
|
|||
this.attackEntityFrom(DamageSource.flyIntoWall, f5);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.onGround && !this.worldObj.isRemote) {
|
||||
this.setFlag(7, false);
|
||||
}
|
||||
} else {
|
||||
float f6 = 0.91F;
|
||||
if (this.onGround) {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package net.minecraft.entity.item;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
|
@ -41,6 +43,10 @@ public class EntityFireworkRocket extends Entity {
|
|||
private int fireworkAge;
|
||||
private int lifetime;
|
||||
|
||||
private EntityLivingBase creator;
|
||||
|
||||
private int creatorId;
|
||||
|
||||
public EntityFireworkRocket(World worldIn) {
|
||||
super(worldIn);
|
||||
this.setSize(0.25F, 0.25F);
|
||||
|
@ -81,6 +87,12 @@ public class EntityFireworkRocket extends Entity {
|
|||
this.lifetime = 10 * i + this.rand.nextInt(6) + this.rand.nextInt(7);
|
||||
}
|
||||
|
||||
public EntityFireworkRocket(World p_i47367_1_, ItemStack p_i47367_2_, EntityLivingBase p_i47367_3_) {
|
||||
this(p_i47367_1_, p_i47367_3_.posX, p_i47367_3_.posY, p_i47367_3_.posZ, p_i47367_2_);
|
||||
this.creatorId = p_i47367_3_.getEntityId();
|
||||
this.creator = p_i47367_3_;
|
||||
}
|
||||
|
||||
/**
|
||||
* +
|
||||
* Sets the velocity to the args. Args: x, y, z
|
||||
|
@ -108,10 +120,34 @@ public class EntityFireworkRocket extends Entity {
|
|||
this.lastTickPosY = this.posY;
|
||||
this.lastTickPosZ = this.posZ;
|
||||
super.onUpdate();
|
||||
this.motionX *= 1.15D;
|
||||
this.motionZ *= 1.15D;
|
||||
this.motionY += 0.04D;
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
|
||||
Entity entity = this.worldObj.getEntityByID(this.creatorId);
|
||||
|
||||
if (entity instanceof EntityLivingBase) {
|
||||
this.creator = (EntityLivingBase) entity;
|
||||
}
|
||||
|
||||
if (this.creator != null) {
|
||||
if (this.creator.isElytraFlying()) {
|
||||
Vec3 look = this.creator.getLookVec();
|
||||
double newMotionX = look.xCoord * 0.1D + (look.xCoord * 1.5D - this.creator.motionX) * 0.5D;
|
||||
double newMotionY = look.yCoord * 0.1D + (look.yCoord * 1.5D - this.creator.motionY) * 0.5D;
|
||||
double newMotionZ = look.zCoord * 0.1D + (look.zCoord * 1.5D - this.creator.motionZ) * 0.5D;
|
||||
|
||||
this.creator.addVelocity(newMotionX, newMotionY, newMotionZ);
|
||||
}
|
||||
|
||||
this.setPosition(this.creator.posX, this.creator.posY, this.creator.posZ);
|
||||
this.motionX = this.creator.motionX;
|
||||
this.motionY = this.creator.motionY;
|
||||
this.motionZ = this.creator.motionZ;
|
||||
} else {
|
||||
this.motionX *= 1.15D;
|
||||
this.motionZ *= 1.15D;
|
||||
this.motionY += 0.04D;
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
|
||||
float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
|
||||
this.rotationYaw = (float) (MathHelper.func_181159_b(this.motionX, this.motionZ) * 180.0D
|
||||
/ 3.1415927410125732D);
|
||||
|
|
|
@ -363,6 +363,12 @@ public abstract class EntityPlayer extends EntityLivingBase implements ICommandS
|
|||
if (this.isElytraFlying()) {
|
||||
f = 0.6F;
|
||||
f1 = 0.6F;
|
||||
} else if (this.isPlayerSleeping()) {
|
||||
f = 0.2F;
|
||||
f1 = 0.2F;
|
||||
} else if (this.isSneaking()) {
|
||||
f = 0.6F;
|
||||
f1 = 1.65F;
|
||||
} else {
|
||||
f = 0.6F;
|
||||
f1 = 1.8F;
|
||||
|
@ -373,7 +379,7 @@ public abstract class EntityPlayer extends EntityLivingBase implements ICommandS
|
|||
axisalignedbb = new AxisAlignedBB(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ,
|
||||
axisalignedbb.minX + (double) f, axisalignedbb.minY + (double) f1, axisalignedbb.minZ + (double) f);
|
||||
|
||||
if (!this.worldObj.checkBlockCollision(axisalignedbb)) {
|
||||
if (!this.worldObj.checkSolidBlockCollision(axisalignedbb)) {
|
||||
this.setSize(f, f1);
|
||||
}
|
||||
}
|
||||
|
@ -1589,6 +1595,7 @@ public abstract class EntityPlayer extends EntityLivingBase implements ICommandS
|
|||
super.moveEntityWithHeading(f, f1);
|
||||
this.motionY = d3 * 0.6D;
|
||||
this.jumpMovementFactor = f2;
|
||||
this.setFlag(7, false);
|
||||
} else {
|
||||
super.moveEntityWithHeading(f, f1);
|
||||
}
|
||||
|
|
|
@ -64,6 +64,19 @@ public class ItemFirework extends Item {
|
|||
}
|
||||
}
|
||||
|
||||
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer) {
|
||||
if (entityplayer.isElytraFlying() && !world.isRemote) {
|
||||
EntityFireworkRocket entityfireworkrocket = new EntityFireworkRocket(world, itemstack, entityplayer);
|
||||
world.spawnEntityInWorld(entityfireworkrocket);
|
||||
|
||||
if (!entityplayer.capabilities.isCreativeMode) {
|
||||
--itemstack.stackSize;
|
||||
}
|
||||
}
|
||||
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
/**
|
||||
* +
|
||||
* allows items to add custom lines of information to the
|
||||
|
|
|
@ -358,10 +358,6 @@ public class NetHandlerPlayServer implements INetHandlerPlayServer, ITickable {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.playerEntity.isInWater() || this.playerEntity.isInLava() || this.playerEntity.onGround) {
|
||||
this.playerEntity.clearElytraFlying();
|
||||
}
|
||||
|
||||
float f3 = 0.0625F;
|
||||
boolean flag = worldserver.getCollidingBoundingBoxes(this.playerEntity,
|
||||
this.playerEntity.getEntityBoundingBox().contract((double) f3, (double) f3, (double) f3))
|
||||
|
|
|
@ -1668,6 +1668,30 @@ public abstract class World implements IBlockAccess, ILightingEngineProvider, IL
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean checkSolidBlockCollision(AxisAlignedBB bb) {
|
||||
int i = MathHelper.floor_double(bb.minX);
|
||||
int j = MathHelper.floor_double(bb.maxX);
|
||||
int k = MathHelper.floor_double(bb.minY);
|
||||
int l = MathHelper.floor_double(bb.maxY);
|
||||
int i1 = MathHelper.floor_double(bb.minZ);
|
||||
int j1 = MathHelper.floor_double(bb.maxZ);
|
||||
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (int k1 = i; k1 <= j; ++k1) {
|
||||
for (int l1 = k; l1 <= l; ++l1) {
|
||||
for (int i2 = i1; i2 <= j1; ++i2) {
|
||||
Block block = this.getBlockState(blockpos$mutableblockpos.func_181079_c(k1, l1, i2)).getBlock();
|
||||
if (block.getMaterial() != Material.air || block.getMaterial() != Material.water
|
||||
|| block.getMaterial() != Material.lava) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* +
|
||||
* Returns if any of the blocks within the aabb are liquids.
|
||||
|
|
|
@ -14,14 +14,21 @@ import com.jcraft.jzlib.InflaterInputStream;
|
|||
/**
|
||||
* Copyright (c) 2022 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
|
@ -32,158 +39,160 @@ public class EPKLoader {
|
|||
loadEPK(epkFile, "", loadedFiles);
|
||||
}
|
||||
|
||||
public static final void loadEPK(ArrayBuffer epkFile, String path, Map<String, byte[]> loadedFiles) throws IOException {
|
||||
public static final void loadEPK(ArrayBuffer epkFile, String path, Map<String, byte[]> loadedFiles)
|
||||
throws IOException {
|
||||
int byteLength = epkFile.getByteLength();
|
||||
int l = byteLength - 16;
|
||||
if(l < 1) {
|
||||
if (l < 1) {
|
||||
throw new IOException("EPK file is incomplete");
|
||||
}
|
||||
|
||||
|
||||
ArrayBufferInputStream is = new ArrayBufferInputStream(epkFile, 0, byteLength - 8);
|
||||
|
||||
|
||||
byte[] header = new byte[8];
|
||||
is.read(header);
|
||||
String type = readASCII(header);
|
||||
|
||||
if(!"EAGPKG$$".equals(type)) {
|
||||
|
||||
if (!"EAGPKG$$".equals(type)) {
|
||||
throw new IOException("Invalid EPK file type '" + type + "'");
|
||||
}
|
||||
|
||||
|
||||
Uint8Array readEndCode = Uint8Array.create(epkFile, byteLength - 8, 8);
|
||||
|
||||
byte[] endCode = new byte[] { (byte)':', (byte)':', (byte)':', (byte)'Y',
|
||||
(byte)'E', (byte)'E', (byte)':', (byte)'>' };
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
if(readEndCode.get(i) != endCode[i]) {
|
||||
|
||||
byte[] endCode = new byte[] { (byte) ':', (byte) ':', (byte) ':', (byte) 'Y',
|
||||
(byte) 'E', (byte) 'E', (byte) ':', (byte) '>' };
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (readEndCode.get(i) != endCode[i]) {
|
||||
throw new IOException("EPK file is missing EOF code (:::YEE:>)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String vers = readASCII(is);
|
||||
if(!vers.startsWith("ver2.")) {
|
||||
if (!vers.startsWith("ver2.")) {
|
||||
throw new IOException("Unknown or invalid EPK version: " + vers);
|
||||
}
|
||||
|
||||
|
||||
is.skip(is.read()); // skip filename
|
||||
is.skip(loadShort(is)); // skip comment
|
||||
is.skip(8); // skip millis date
|
||||
|
||||
|
||||
int numFiles = loadInt(is);
|
||||
|
||||
char compressionType = (char)is.read();
|
||||
|
||||
|
||||
char compressionType = (char) is.read();
|
||||
|
||||
InputStream zis;
|
||||
switch(compressionType) {
|
||||
case 'G':
|
||||
zis = new GZIPInputStream(is);
|
||||
break;
|
||||
case 'Z':
|
||||
zis = new InflaterInputStream(is);
|
||||
break;
|
||||
case '0':
|
||||
zis = is;
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Invalid or unsupported EPK compression: " + compressionType);
|
||||
switch (compressionType) {
|
||||
case 'G':
|
||||
zis = new GZIPInputStream(is);
|
||||
break;
|
||||
case 'Z':
|
||||
zis = new InflaterInputStream(is);
|
||||
break;
|
||||
case '0':
|
||||
zis = is;
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Invalid or unsupported EPK compression: " + compressionType);
|
||||
}
|
||||
|
||||
int blockFile = ('F' << 24) | ('I' << 16) | ('L' << 8) | 'E';
|
||||
int blockEnd = ('E' << 24) | ('N' << 16) | ('D' << 8) | '$';
|
||||
int blockHead = ('H' << 24) | ('E' << 16) | ('A' << 8) | 'D';
|
||||
|
||||
if(path.length() > 0 && !path.endsWith("/")) {
|
||||
|
||||
if (path.length() > 0 && !path.endsWith("/")) {
|
||||
path = path + "/";
|
||||
}
|
||||
|
||||
|
||||
CRC32 crc32 = new CRC32();
|
||||
int blockType;
|
||||
for(int i = 0; i < numFiles; ++i) {
|
||||
|
||||
for (int i = 0; i < numFiles; ++i) {
|
||||
|
||||
blockType = loadInt(zis);
|
||||
|
||||
if(blockType == blockEnd) {
|
||||
|
||||
if (blockType == blockEnd) {
|
||||
throw new IOException("Unexpected END when there are still " + (numFiles - i) + " files remaining");
|
||||
}
|
||||
|
||||
|
||||
String name = readASCII(zis);
|
||||
int len = loadInt(zis);
|
||||
|
||||
if(i == 0) {
|
||||
if(blockType == blockHead) {
|
||||
|
||||
if (i == 0) {
|
||||
if (blockType == blockHead) {
|
||||
byte[] readType = new byte[len];
|
||||
zis.read(readType);
|
||||
if(!"file-type".equals(name) || !"epk/resources".equals(readASCII(readType))) {
|
||||
if (!"file-type".equals(name) || !"epk/resources".equals(readASCII(readType))) {
|
||||
throw new IOException("EPK is not of file-type 'epk/resources'!");
|
||||
}
|
||||
if(zis.read() != '>') {
|
||||
if (zis.read() != '>') {
|
||||
throw new IOException("Object '" + name + "' is incomplete");
|
||||
}
|
||||
continue;
|
||||
}else {
|
||||
throw new IOException("File '" + name + "' did not have a file-type block as the first entry in the file");
|
||||
} else {
|
||||
throw new IOException(
|
||||
"File '" + name + "' did not have a file-type block as the first entry in the file");
|
||||
}
|
||||
}
|
||||
|
||||
if(blockType == blockFile) {
|
||||
if(len < 5) {
|
||||
|
||||
if (blockType == blockFile) {
|
||||
if (len < 5) {
|
||||
throw new IOException("File '" + name + "' is incomplete");
|
||||
}
|
||||
|
||||
|
||||
int expectedCRC = loadInt(zis);
|
||||
|
||||
|
||||
byte[] load = new byte[len - 5];
|
||||
zis.read(load);
|
||||
|
||||
if(len > 5) {
|
||||
if (len > 5) {
|
||||
crc32.reset();
|
||||
crc32.update(load, 0, load.length);
|
||||
if(expectedCRC != (int)crc32.getValue()) {
|
||||
if (expectedCRC != (int) crc32.getValue()) {
|
||||
throw new IOException("File '" + name + "' has an invalid checksum");
|
||||
}
|
||||
}
|
||||
|
||||
if(zis.read() != ':') {
|
||||
|
||||
if (zis.read() != ':') {
|
||||
throw new IOException("File '" + name + "' is incomplete");
|
||||
}
|
||||
|
||||
|
||||
loadedFiles.put(path + name, load);
|
||||
}else {
|
||||
} else {
|
||||
zis.skip(len);
|
||||
}
|
||||
|
||||
if(zis.read() != '>') {
|
||||
if (zis.read() != '>') {
|
||||
throw new IOException("Object '" + name + "' is incomplete");
|
||||
}
|
||||
}
|
||||
|
||||
if(loadInt(zis) != blockEnd) {
|
||||
|
||||
if (loadInt(zis) != blockEnd) {
|
||||
throw new IOException("EPK missing END$ object");
|
||||
}
|
||||
|
||||
|
||||
zis.close();
|
||||
}
|
||||
|
||||
|
||||
private static final int loadShort(InputStream is) throws IOException {
|
||||
return (is.read() << 8) | is.read();
|
||||
}
|
||||
|
||||
|
||||
private static final int loadInt(InputStream is) throws IOException {
|
||||
return (is.read() << 24) | (is.read() << 16) | (is.read() << 8) | is.read();
|
||||
}
|
||||
|
||||
|
||||
private static final String readASCII(byte[] bytesIn) throws IOException {
|
||||
char[] charIn = new char[bytesIn.length];
|
||||
for(int i = 0; i < bytesIn.length; ++i) {
|
||||
charIn[i] = (char)((int)bytesIn[i] & 0xFF);
|
||||
for (int i = 0; i < bytesIn.length; ++i) {
|
||||
charIn[i] = (char) ((int) bytesIn[i] & 0xFF);
|
||||
}
|
||||
return new String(charIn);
|
||||
}
|
||||
|
||||
|
||||
private static final String readASCII(InputStream bytesIn) throws IOException {
|
||||
int len = bytesIn.read();
|
||||
char[] charIn = new char[len];
|
||||
for(int i = 0; i < len; ++i) {
|
||||
charIn[i] = (char)(bytesIn.read() & 0xFF);
|
||||
for (int i = 0; i < len; ++i) {
|
||||
charIn[i] = (char) (bytesIn.read() & 0xFF);
|
||||
}
|
||||
return new String(charIn);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue