v1.2.3 + fix

This commit is contained in:
radmanplays 2024-03-08 15:27:27 +03:30
parent 149227f121
commit 989647f9b1
53 changed files with 229 additions and 2191 deletions

View File

@ -1,4 +1,4 @@
# 143 files to delete: # 144 files to delete:
net/minecraft/client/renderer/VertexBufferUploader.java net/minecraft/client/renderer/VertexBufferUploader.java
net/minecraft/realms/DisconnectedRealmsScreen.java net/minecraft/realms/DisconnectedRealmsScreen.java
net/minecraft/client/stream/Metadata.java net/minecraft/client/stream/Metadata.java
@ -65,6 +65,7 @@ net/minecraft/client/shader/ShaderGroup.java
net/minecraft/server/management/UserListWhitelist.java net/minecraft/server/management/UserListWhitelist.java
net/minecraft/client/shader/ShaderLoader.java net/minecraft/client/shader/ShaderLoader.java
net/minecraft/realms/RealmsEditBox.java net/minecraft/realms/RealmsEditBox.java
net/minecraft/client/resources/ResourceIndex.java
net/minecraft/server/management/UserListEntry.java net/minecraft/server/management/UserListEntry.java
net/minecraft/network/NettyEncryptionTranslator.java net/minecraft/network/NettyEncryptionTranslator.java
net/minecraft/client/audio/SoundManager.java net/minecraft/client/audio/SoundManager.java

View File

@ -101,17 +101,7 @@
+ } + }
+ +
> CHANGE 132 : 133 @ 132 : 133 > CHANGE 247 : 248 @ 247 : 248
~ return this.fullCube && (!this.noRender);
> INSERT 67 : 70 @ 67
+ if (this.noRender || this.forceRender) {
+ return this.forceRender;
+ }
> CHANGE 47 : 48 @ 47 : 48
~ public void randomTick(World world, BlockPos blockpos, IBlockState iblockstate, EaglercraftRandom random) { ~ public void randomTick(World world, BlockPos blockpos, IBlockState iblockstate, EaglercraftRandom random) {

View File

@ -5,13 +5,8 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> INSERT 2 : 4 @ 2 > CHANGE 4 : 5 @ 4 : 5
+ import static net.lax1dude.eaglercraft.v1_8.EaglercraftVersion.projectForkName; ~ return "eagler";
+
> CHANGE 2 : 3 @ 2 : 3
~ return projectForkName;
> EOF > EOF

View File

@ -22,7 +22,7 @@
> DELETE 1 @ 1 : 4 > DELETE 1 @ 1 : 4
> CHANGE 1 : 58 @ 1 : 4 > CHANGE 1 : 57 @ 1 : 4
~ ~
~ import net.eaglerforge.EaglerForge; ~ import net.eaglerforge.EaglerForge;
@ -30,7 +30,6 @@
~ import net.eaglerforge.api.ModAPI; ~ import net.eaglerforge.api.ModAPI;
~ import net.eaglerforge.api.ModData; ~ import net.eaglerforge.api.ModData;
~ import net.eaglerforge.api.ModLoader; ~ import net.eaglerforge.api.ModLoader;
~ import net.eaglerforge.gui.EmptyGui;
~ import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput; ~ import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
~ ~
~ import org.apache.commons.lang3.Validate; ~ import org.apache.commons.lang3.Validate;
@ -138,14 +137,13 @@
> CHANGE 1 : 2 @ 1 : 2 > CHANGE 1 : 2 @ 1 : 2
~ public class Minecraft extends ModData implements IThreadListener { ~ public class Minecraft extends BaseData implements IThreadListener {
> CHANGE 2 : 4 @ 2 : 10 > CHANGE 2 : 3 @ 2 : 9
~ public static final boolean isRunningOnMac = false; ~ public static final boolean isRunningOnMac = false;
~ public ServerData currentServerData;
> DELETE 11 @ 11 : 13 > DELETE 12 @ 12 : 14
> INSERT 11 : 12 @ 11 > INSERT 11 : 12 @ 11
@ -751,7 +749,7 @@
> CHANGE 2 : 3 @ 2 : 6 > CHANGE 2 : 3 @ 2 : 6
~ return "true"; ~ return "Definitely Not; You're an eagler";
> DELETE 36 @ 36 : 41 > DELETE 36 @ 36 : 41

View File

@ -13,12 +13,15 @@
> DELETE 1 @ 1 : 2 > DELETE 1 @ 1 : 2
> INSERT 1 : 3 @ 1 > INSERT 1 : 2 @ 1
+ import net.minecraft.nbt.JsonToNBT;
+ import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.nbt.NBTTagCompound;
> INSERT 23 : 64 @ 23 > INSERT 5 : 6 @ 5
+ import net.minecraft.nbt.JsonToNBT;
> INSERT 18 : 59 @ 18
+ @Override + @Override
+ public ModData makeModData() { + public ModData makeModData() {

View File

@ -5,10 +5,13 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> INSERT 2 : 7 @ 2 > INSERT 2 : 10 @ 2
+ import java.util.ArrayList; + import java.util.ArrayList;
+ import java.util.Collection; + import java.util.Collection;
+
+ import net.eaglerforge.api.ModAPI;
+ import net.eaglerforge.api.ModData;
+ import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom; + import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
+ import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite; + import net.lax1dude.eaglercraft.v1_8.minecraft.EaglerTextureAtlasSprite;
+ +
@ -60,7 +63,12 @@
+ j -= 10; + j -= 10;
+ } + }
> INSERT 19 : 30 @ 19 > INSERT 14 : 16 @ 14
+ ModAPI.callEvent("drawhud", new ModData());
+
> INSERT 5 : 16 @ 5
+ public void renderGameOverlayCrosshairs(int scaledResWidth, int scaledResHeight) { + public void renderGameOverlayCrosshairs(int scaledResWidth, int scaledResHeight) {
+ if (this.showCrosshair()) { + if (this.showCrosshair()) {

View File

@ -5,9 +5,8 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> CHANGE 2 : 12 @ 2 : 9 > CHANGE 2 : 11 @ 2 : 9
~ import net.eaglerforge.gui.ModGUI;
~ import net.lax1dude.eaglercraft.v1_8.Mouse; ~ import net.lax1dude.eaglercraft.v1_8.Mouse;
~ import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; ~ import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
~ import net.lax1dude.eaglercraft.v1_8.sp.SingleplayerServerController; ~ import net.lax1dude.eaglercraft.v1_8.sp.SingleplayerServerController;
@ -18,11 +17,12 @@
~ import net.lax1dude.eaglercraft.v1_8.update.GuiUpdateCheckerOverlay; ~ import net.lax1dude.eaglercraft.v1_8.update.GuiUpdateCheckerOverlay;
~ import net.minecraft.client.audio.PositionedSoundRecord; ~ import net.minecraft.client.audio.PositionedSoundRecord;
> CHANGE 4 : 7 @ 4 : 5 > CHANGE 4 : 8 @ 4 : 5
~ import net.minecraft.util.ChatComponentText; ~ import net.minecraft.util.ChatComponentText;
~ import net.minecraft.util.EnumChatFormatting; ~ import net.minecraft.util.EnumChatFormatting;
~ import net.minecraft.util.ResourceLocation; ~ import net.minecraft.util.ResourceLocation;
~ import net.eaglerforge.gui.ModGUI;
> DELETE 2 @ 2 : 4 > DELETE 2 @ 2 : 4
@ -50,10 +50,8 @@
~ this.buttonList.add(lanButton = new GuiButton(7, this.width / 2 + 2, this.height / 4 + 96 + b0, 98, 20, ~ this.buttonList.add(lanButton = new GuiButton(7, this.width / 2 + 2, this.height / 4 + 96 + b0, 98, 20,
~ I18n.format(LANServerController.isLANOpen() ? "menu.closeLan" : "menu.openToLan", new Object[0]))); ~ I18n.format(LANServerController.isLANOpen() ? "menu.closeLan" : "menu.openToLan", new Object[0])));
> CHANGE 4 : 11 @ 4 : 5 > CHANGE 4 : 9 @ 4 : 5
~ this.buttonList.add(new GuiButton(69420, this.width / 2 - 100, this.height / 4 + 73 + b0,
~ I18n.format("eaglerforge.menu.mods", new Object[0])));
~ lanButton.enabled = SingleplayerServerController.isWorldRunning(); ~ lanButton.enabled = SingleplayerServerController.isWorldRunning();
~ if (!hasSentAutoSave) { ~ if (!hasSentAutoSave) {
~ hasSentAutoSave = true; ~ hasSentAutoSave = true;

View File

@ -5,11 +5,7 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> CHANGE 2 : 5 @ 2 : 3 > DELETE 2 @ 2 : 3
~ import static net.eaglerforge.api.ModLoader.returntotalloadedmods;
~ import static net.lax1dude.eaglercraft.v1_8.EaglercraftVersion.*;
~
> DELETE 3 @ 3 : 4 > DELETE 3 @ 3 : 4
@ -17,9 +13,10 @@
+ import java.util.Arrays; + import java.util.Arrays;
> CHANGE 2 : 29 @ 2 : 4 > CHANGE 2 : 30 @ 2 : 4
~ ~
~ import net.eaglerforge.gui.ModGUI;
~ import net.lax1dude.eaglercraft.v1_8.EagRuntime; ~ import net.lax1dude.eaglercraft.v1_8.EagRuntime;
~ import net.lax1dude.eaglercraft.v1_8.EaglerInputStream; ~ import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
~ import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom; ~ import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
@ -57,10 +54,7 @@
> DELETE 2 @ 2 : 3 > DELETE 2 @ 2 : 3
> CHANGE 1 : 3 @ 1 : 8 > DELETE 1 @ 1 : 8
~ import net.eaglerforge.gui.ModGUI;
~ import org.teavm.jso.JSBody;
> DELETE 2 @ 2 : 3 > DELETE 2 @ 2 : 3
@ -169,8 +163,9 @@
~ I18n.format("menu.editProfile", new Object[0]))); ~ I18n.format("menu.editProfile", new Object[0])));
~ ~
> CHANGE 1 : 5 @ 1 : 2 > CHANGE 1 : 6 @ 1 : 2
~
~ if (isFork) { ~ if (isFork) {
~ this.openGLWarning1 = EaglercraftVersion.mainMenuStringE; ~ this.openGLWarning1 = EaglercraftVersion.mainMenuStringE;
~ this.openGLWarning2 = EaglercraftVersion.mainMenuStringF; ~ this.openGLWarning2 = EaglercraftVersion.mainMenuStringF;

View File

@ -9,9 +9,10 @@
> DELETE 1 @ 1 : 3 > DELETE 1 @ 1 : 3
> INSERT 4 : 20 @ 4 > INSERT 4 : 21 @ 4
+ +
+ import net.eaglerforge.gui.ModGUI;
+ import org.apache.commons.lang3.StringUtils; + import org.apache.commons.lang3.StringUtils;
+ +
+ import com.google.common.base.Splitter; + import com.google.common.base.Splitter;
@ -53,20 +54,22 @@
~ for (int l = 0, m = this.labelList.size(); l < m; ++l) { ~ for (int l = 0, m = this.labelList.size(); l < m; ++l) {
> INSERT 3 : 33 @ 3 > CHANGE 3 : 14 @ 3 : 10
~ long millis = System.currentTimeMillis();
~ long closeKeyTimeout = millis - showingCloseKey;
~ if (closeKeyTimeout < 3000l) {
~ int alpha1 = 0xC0000000;
~ int alpha2 = 0xFF000000;
~ if (closeKeyTimeout > 2500l) {
~ float f = (float) (3000l - closeKeyTimeout) * 0.002f;
~ if (f < 0.03f)
~ f = 0.03f;
~ alpha1 = (int) (f * 192.0f) << 24;
~ alpha2 = (int) (f * 255.0f) << 24;
> INSERT 1 : 17 @ 1
+ long millis = System.currentTimeMillis();
+ long closeKeyTimeout = millis - showingCloseKey;
+ if (closeKeyTimeout < 3000l) {
+ int alpha1 = 0xC0000000;
+ int alpha2 = 0xFF000000;
+ if (closeKeyTimeout > 2500l) {
+ float f = (float) (3000l - closeKeyTimeout) * 0.002f;
+ if (f < 0.03f)
+ f = 0.03f;
+ alpha1 = (int) (f * 192.0f) << 24;
+ alpha2 = (int) (f * 255.0f) << 24;
+ }
+ String str; + String str;
+ int k = getCloseKey(); + int k = getCloseKey();
+ if (k == KeyboardConstants.KEY_GRAVE) { + if (k == KeyboardConstants.KEY_GRAVE) {
@ -83,10 +86,8 @@
+ fontRendererObj.drawStringWithShadow(str, x + 2, y + 2, 0xFFAAAA | alpha2); + fontRendererObj.drawStringWithShadow(str, x + 2, y + 2, 0xFFAAAA | alpha2);
+ if (closeKeyTimeout > 2500l) + if (closeKeyTimeout > 2500l)
+ GlStateManager.disableBlend(); + GlStateManager.disableBlend();
+ }
+
> CHANGE 2 : 14 @ 2 : 4 > CHANGE 4 : 23 @ 4 : 9
~ protected int getCloseKey() { ~ protected int getCloseKey() {
~ if (this instanceof GuiContainer) { ~ if (this instanceof GuiContainer) {
@ -100,16 +101,26 @@
~ if (((this.mc.theWorld == null || this.mc.thePlayer.getHealth() <= 0.0F) && parInt1 == 1) ~ if (((this.mc.theWorld == null || this.mc.thePlayer.getHealth() <= 0.0F) && parInt1 == 1)
~ || parInt1 == this.mc.gameSettings.keyBindClose.getKeyCode() ~ || parInt1 == this.mc.gameSettings.keyBindClose.getKeyCode()
~ || (parInt1 == 1 && (this.mc.gameSettings.keyBindClose.getKeyCode() == 0 || this.mc.areKeysLocked()))) { ~ || (parInt1 == 1 && (this.mc.gameSettings.keyBindClose.getKeyCode() == 0 || this.mc.areKeysLocked()))) {
~ if (!ModGUI.isGuiOpen()) {
~ this.mc.displayGuiScreen((GuiScreen) null);
~ if (this.mc.currentScreen == null) {
~ this.mc.setIngameFocus();
~ }
~ } else {
~ ModGUI.closeGui();
> INSERT 4 : 6 @ 4 > CHANGE 1 : 3 @ 1 : 3
+ } else if (parInt1 == 1) { ~ } else if (parInt1 == 1) {
+ showingCloseKey = System.currentTimeMillis(); ~ showingCloseKey = System.currentTimeMillis();
> DELETE 1 @ 1 : 2 > INSERT 1 : 2 @ 1
> CHANGE 3 : 4 @ 3 : 13 + }
> CHANGE 1 : 3 @ 1 : 2
~ public static String getClipboardString() {
~ return EagRuntime.getClipboard(); ~ return EagRuntime.getClipboard();
> CHANGE 4 : 5 @ 4 : 11 > CHANGE 4 : 5 @ 4 : 11

View File

@ -17,4 +17,9 @@
> DELETE 10 @ 10 : 12 > DELETE 10 @ 10 : 12
> CHANGE 50 : 52 @ 50 : 52
~ for (int j = 0, k = this.chunkListing.size(); j < k; ++j) {
~ this.chunkListing.get(j).func_150804_b(System.currentTimeMillis() - i > 5L);
> EOF > EOF

View File

@ -17,11 +17,7 @@
> DELETE 5 @ 5 : 6 > DELETE 5 @ 5 : 6
> CHANGE 11 : 12 @ 11 : 15 > CHANGE 211 : 212 @ 211 : 212
~ import net.minecraft.util.*;
> CHANGE 196 : 197 @ 196 : 197
~ EaglercraftRandom random = new EaglercraftRandom(); ~ EaglercraftRandom random = new EaglercraftRandom();
@ -29,8 +25,4 @@
~ return "Non-integrated multiplayer server"; ~ return "Non-integrated multiplayer server";
> INSERT 44 : 45 @ 44
+
> EOF > EOF

View File

@ -9,12 +9,9 @@
> DELETE 4 @ 4 : 6 > DELETE 4 @ 4 : 6
> INSERT 1 : 22 @ 1 > INSERT 1 : 19 @ 1
+ +
+ import net.eaglerforge.api.BaseData;
+ import net.eaglerforge.api.ModAPI;
+ import net.eaglerforge.api.ModData;
+ import net.lax1dude.eaglercraft.v1_8.EagRuntime; + import net.lax1dude.eaglercraft.v1_8.EagRuntime;
+ import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom; + import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
+ import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID; + import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
@ -59,11 +56,7 @@
> DELETE 32 @ 32 : 34 > DELETE 32 @ 32 : 34
> CHANGE 1 : 2 @ 1 : 2 > CHANGE 3 : 4 @ 3 : 4
~ public class NetHandlerPlayClient extends ModData implements INetHandlerPlayClient {
> CHANGE 1 : 2 @ 1 : 2
~ private final EaglercraftNetworkManager netManager; ~ private final EaglercraftNetworkManager netManager;
@ -155,22 +148,7 @@
> DELETE 7 @ 7 : 8 > DELETE 7 @ 7 : 8
> CHANGE 23 : 37 @ 23 : 24 > DELETE 23 @ 23 : 24
~ ModData eventData = new ModData();
~ eventData.set("preventDefault", false);
~ eventData.set("type", packetIn.type);
~ eventData.set("chat", packetIn.chatComponent.getFormattedText());
~ BaseData newEvent = ModAPI.callEvent("packetchat", eventData);
~ if (newEvent.has("preventDefault") && newEvent.getBoolean("preventDefault") == true) {
~ return;
~ }
~ packetIn.type = newEvent.has("type") ? newEvent.getByte("type") : packetIn.type;
~ if (newEvent.has("chat")
~ && (newEvent.getString("chat").length() != packetIn.chatComponent.getFormattedText().length())) {
~ packetIn.chatComponent = new ChatComponentText(newEvent.getString("chat"));
~ }
~
> DELETE 9 @ 9 : 10 > DELETE 9 @ 9 : 10

View File

@ -1,48 +0,0 @@
# Eagler Context Redacted Diff
# Copyright (c) 2024 lax1dude. All rights reserved.
# Version: 1.0
# Author: lax1dude
> DELETE 2 @ 2 : 18
> CHANGE 1 : 3 @ 1 : 3
~ // private static final Logger logger = LogManager.getLogger();
~ // private final Map<String, File> resourceMap = Maps.newHashMap();
> CHANGE 1 : 25 @ 1 : 6
~ // public ResourceIndex(File parFile, String parString1) {
~ /*
~ * if (parString1 != null) { File file1 = new File(parFile, "objects"); File
~ * file2 = new File(parFile, "indexes/" + parString1 + ".json"); BufferedReader
~ * bufferedreader = null;
~ *
~ * try { bufferedreader = Files.newReader(file2, Charsets.UTF_8); JsonObject
~ * jsonobject = (new JsonParser()).parse(bufferedreader).getAsJsonObject();
~ * JsonObject jsonobject1 = JsonUtils.getJsonObject(jsonobject, "objects",
~ * (JsonObject) null); if (jsonobject1 != null) { for (Entry entry :
~ * jsonobject1.entrySet()) { JsonObject jsonobject2 = (JsonObject)
~ * entry.getValue(); String s = (String) entry.getKey(); String[] astring =
~ * s.split("/", 2); String s1 = astring.length == 1 ? astring[0] : astring[0] +
~ * ":" + astring[1]; String s2 = JsonUtils.getString(jsonobject2, "hash"); File
~ * file3 = new File(file1, s2.substring(0, 2) + "/" + s2);
~ * this.resourceMap.put(s1, file3); } } } catch (JsonParseException var20) {
~ * logger.error("Unable to parse resource index file: " + file2); } catch
~ * (FileNotFoundException var21) {
~ * logger.error("Can\'t find the resource index file: " + file2); } finally {
~ * IOUtils.closeQuietly(bufferedreader); }
~ *
~ * }
~ */
~ // }
> CHANGE 1 : 4 @ 1 : 30
~ // public Map<String, File> getResourceMap() {
~ // return this.resourceMap;
~ // }
> EOF

View File

@ -438,21 +438,19 @@
+ return s + I18n.format("options.off"); + return s + I18n.format("options.off");
+ } + }
> INSERT 6 : 14 @ 6 > CHANGE 6 : 12 @ 6 : 10
+ byte[] options = EagRuntime.getStorage("g"); ~ byte[] options = EagRuntime.getStorage("g");
+ if (options == null) { ~ if (options == null) {
+ return; ~ return;
+ } ~ }
+ loadOptions(options); ~ loadOptions(options);
+ } ~ }
+
+ public void loadOptions(byte[] data) {
> DELETE 1 @ 1 : 4 > CHANGE 1 : 5 @ 1 : 2
> CHANGE 1 : 3 @ 1 : 2
~ public void loadOptions(byte[] data) {
~ try {
~ BufferedReader bufferedreader = new BufferedReader( ~ BufferedReader bufferedreader = new BufferedReader(
~ new InputStreamReader(EaglerZLIB.newGZIPInputStream(new EaglerInputStream(data)))); ~ new InputStreamReader(EaglerZLIB.newGZIPInputStream(new EaglerInputStream(data))));
@ -654,9 +652,8 @@
+ deferredShaderConf.writeOptions(printwriter); + deferredShaderConf.writeOptions(printwriter);
+ +
> INSERT 1 : 3 @ 1 > INSERT 1 : 2 @ 1
+
+ return bao.toByteArray(); + return bao.toByteArray();
> INSERT 2 : 3 @ 2 > INSERT 2 : 3 @ 2

View File

@ -9,4 +9,19 @@
+ +
> CHANGE 166 : 168 @ 166 : 168
~ for (int i = 0; i < this.enchantmentTypes.length; ++i) {
~ if (this.enchantmentTypes[i] == enchantmentType) {
> CHANGE 22 : 24 @ 22 : 23
~ for (int i = 0; i < Enchantment.enchantmentsBookList.length; ++i) {
~ Enchantment enchantment = Enchantment.enchantmentsBookList[i];
> CHANGE 3 : 5 @ 3 : 5
~ for (int j = 0; j < enchantmentType.length && !flag; ++j) {
~ if (enchantment.type == enchantmentType[j]) {
> EOF > EOF

View File

@ -19,26 +19,54 @@
~ private static final EaglercraftRandom enchantmentRand = new EaglercraftRandom(); ~ private static final EaglercraftRandom enchantmentRand = new EaglercraftRandom();
> CHANGE 211 : 213 @ 211 : 212 > CHANGE 76 : 78 @ 76 : 78
~ for (int k = 0; k < stacks.length; ++k) {
~ int j = getEnchantmentLevel(enchID, stacks[k]);
> CHANGE 26 : 28 @ 26 : 28
~ for (int k = 0; k < stacks.length; ++k) {
~ applyEnchantmentModifier(modifier, stacks[k]);
> CHANGE 96 : 99 @ 96 : 97
~ ItemStack[] stacks = parEntityLivingBase.getInventory();
~ for (int k = 0; k < stacks.length; ++k) {
~ ItemStack itemstack = stacks[k];
> CHANGE 8 : 10 @ 8 : 9
~ public static int calcItemStackEnchantability(EaglercraftRandom parRandom, int parInt1, int parInt2, ~ public static int calcItemStackEnchantability(EaglercraftRandom parRandom, int parInt1, int parInt2,
~ ItemStack parItemStack) { ~ ItemStack parItemStack) {
> CHANGE 14 : 15 @ 14 : 15 > CHANGE 14 : 16 @ 14 : 16
~ public static ItemStack addRandomEnchantment(EaglercraftRandom parRandom, ItemStack parItemStack, int parInt1) { ~ public static ItemStack addRandomEnchantment(EaglercraftRandom parRandom, ItemStack parItemStack, int parInt1) {
~ List<EnchantmentData> list = buildEnchantmentList(parRandom, parItemStack, parInt1);
> CHANGE 7 : 8 @ 7 : 8 > CHANGE 6 : 8 @ 6 : 7
~ for (EnchantmentData enchantmentdata : (List<EnchantmentData>) list) { ~ for (int i = 0, l = list.size(); i < l; ++i) {
~ EnchantmentData enchantmentdata = list.get(i);
> CHANGE 11 : 13 @ 11 : 12 > CHANGE 11 : 13 @ 11 : 12
~ public static List<EnchantmentData> buildEnchantmentList(EaglercraftRandom randomIn, ItemStack itemStackIn, ~ public static List<EnchantmentData> buildEnchantmentList(EaglercraftRandom randomIn, ItemStack itemStackIn,
~ int parInt1) { ~ int parInt1) {
> CHANGE 30 : 31 @ 30 : 31 > CHANGE 14 : 15 @ 14 : 15
~ for (EnchantmentData enchantmentdata1 : (List<EnchantmentData>) arraylist) { ~ ArrayList<EnchantmentData> arraylist = null;
> CHANGE 15 : 17 @ 15 : 16
~ for (int m = 0, n = arraylist.size(); m < n; ++m) {
~ EnchantmentData enchantmentdata1 = arraylist.get(m);
> CHANGE 30 : 32 @ 30 : 31
~ for (int j = 0; j < Enchantment.enchantmentsBookList.length; ++j) {
~ Enchantment enchantment = Enchantment.enchantmentsBookList[j];
> EOF > EOF

View File

@ -34,26 +34,11 @@
~ public abstract class Entity extends ModData implements ICommandSender { ~ public abstract class Entity extends ModData implements ICommandSender {
> CHANGE 12 : 17 @ 12 : 17 > CHANGE 44 : 45 @ 44 : 45
~ public static double posX;
~ public static double posY;
~ public static double posZ;
~ public static double motionX;
~ public static double motionY;
> CHANGE 27 : 29 @ 27 : 29
~ protected EaglercraftRandom rand; ~ protected EaglercraftRandom rand;
~ public static int ticksExisted;
> CHANGE 10 : 13 @ 10 : 13 > CHANGE 27 : 28 @ 27 : 28
~ public static int chunkCoordX;
~ public static int chunkCoordY;
~ public static int chunkCoordZ;
> CHANGE 13 : 14 @ 13 : 14
~ protected EaglercraftUUID entityUniqueID; ~ protected EaglercraftUUID entityUniqueID;

View File

@ -5,10 +5,8 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> INSERT 2 : 5 @ 2 > INSERT 2 : 3 @ 2
+ import net.eaglerforge.api.BaseData;
+ import net.eaglerforge.api.ModData;
+ import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.DynamicLightManager; + import net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.DynamicLightManager;
> INSERT 90 : 101 @ 90 > INSERT 90 : 101 @ 90

View File

@ -5,8 +5,9 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> INSERT 2 : 3 @ 2 > INSERT 2 : 4 @ 2
+ import net.eaglerforge.api.BaseData;
+ import net.eaglerforge.api.ModData; + import net.eaglerforge.api.ModData;
> DELETE 32 @ 32 : 33 > DELETE 32 @ 32 : 33
@ -233,4 +234,8 @@
~ ~
~ static void doBootstrap() { ~ static void doBootstrap() {
> INSERT 203 : 204 @ 203
+
> EOF > EOF

View File

@ -7,71 +7,17 @@
> DELETE 2 @ 2 : 4 > DELETE 2 @ 2 : 4
> INSERT 3 : 9 @ 3 > INSERT 3 : 7 @ 3
+ +
+ import com.google.common.collect.Lists; + import com.google.common.collect.Lists;
+ import com.google.common.collect.Sets; + import com.google.common.collect.Sets;
+ +
+ import net.eaglerforge.api.BaseData;
+ import net.eaglerforge.api.ModData;
> DELETE 2 @ 2 : 5 > DELETE 2 @ 2 : 5
> CHANGE 5 : 6 @ 5 : 6 > CHANGE 19 : 20 @ 19 : 20
~ public abstract class Container extends ModData {
> INSERT 1 : 42 @ 1
+
+ public void loadModData(BaseData data) {
+ BaseData[] parItemStacks = data.getBaseDataArr("inventoryItemStacks");
+ for (int i = 0; i < parItemStacks.length && i < inventoryItemStacks.size(); i++) {
+ if (inventoryItemStacks.get(i) != null) {
+ inventoryItemStacks.get(i).loadModData(parItemStacks[i]);
+ } else if (parItemStacks[i] != null && parItemStacks[i].getRef() instanceof ItemStack) {
+ inventoryItemStacks.set(i, (ItemStack) parItemStacks[i].getRef());
+ }
+ }
+ }
+
+ public ModData makeModData() {
+ ModData data = new ModData();
+ ModData[] parBaseDatas = new ModData[inventoryItemStacks.size()];
+ for (int i = 0; i < inventoryItemStacks.size(); i++) {
+ if (inventoryItemStacks.get(i) != null) {
+ parBaseDatas[i] = inventoryItemStacks.get(i).makeModData();
+ }
+ }
+ data.set("inventoryItemStacks", parBaseDatas);
+ data.setCallbackVoid("reload", () -> {
+ loadModData(data);
+ });
+ data.setCallbackObject("getRef", () -> {
+ return this;
+ });
+ data.setCallbackObjectArr("getPlayerList", () -> {
+ ModData[] parPlayerList = new ModData[playerList.size()];
+ int i = 0;
+ for (EntityPlayer player : playerList) {
+ if (player != null) {
+ parPlayerList[i] = player.makeModData();
+ }
+ i++;
+ }
+ return parPlayerList;
+ });
+ return data;
+ }
+
> CHANGE 12 : 13 @ 12 : 13
~ this.inventoryItemStacks.add((ItemStack) null); ~ this.inventoryItemStacks.add((ItemStack) null);
> INSERT 521 : 522 @ 521
+
> EOF > EOF

View File

@ -9,11 +9,8 @@
> DELETE 3 @ 3 : 4 > DELETE 3 @ 3 : 4
> INSERT 1 : 12 @ 1 > INSERT 1 : 9 @ 1
+
+ import net.eaglerforge.api.BaseData;
+ import net.eaglerforge.api.ModData;
+ import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom; + import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
+ import net.lax1dude.eaglercraft.v1_8.HString; + import net.lax1dude.eaglercraft.v1_8.HString;
+ import java.util.Set; + import java.util.Set;
@ -23,229 +20,13 @@
+ import com.google.common.collect.Multimap; + import com.google.common.collect.Multimap;
+ +
> CHANGE 13 : 14 @ 13 : 20 > DELETE 13 @ 13 : 17
~ import net.minecraft.nbt.*; > CHANGE 185 : 186 @ 185 : 186
> CHANGE 10 : 11 @ 10 : 11
~ public final class ItemStack extends ModData {
> INSERT 16 : 168 @ 16
+ public void loadModData(BaseData data) {
+ stackSize = data.getInt("amount");
+ animationsToGo = data.getInt("animationsToGo");
+ itemDamage = data.getInt("itemDamage");
+ if (itemFrame != null) {
+ itemFrame.loadModData(data.getBaseData("itemFrame"));
+ }
+ if (canDestroyCacheBlock != null) {
+ canDestroyCacheBlock.loadModData(data.getBaseData("canDestroyCacheBlock"));
+ }
+ if (canPlaceOnCacheBlock != null) {
+ canPlaceOnCacheBlock.loadModData(data.getBaseData("canPlaceOnCacheBlock"));
+ }
+ canDestroyCacheResult = data.getBoolean("canDestroyCacheResult");
+ canPlaceOnCacheResult = data.getBoolean("canPlaceOnCacheResult");
+ }
+
+ public static ItemStack fromModData(BaseData data) {
+ return new ItemStack(Item.getItemById(data.getInt("itemId")), data.getInt("amount"), data.getInt("itemDamage"));
+ }
+
+ public ModData makeModData() {
+ ModData data = new ModData();
+ data.set("amount", stackSize);
+ data.set("animationsToGo", animationsToGo);
+ data.set("itemId", item.getIdFromItem(item));
+ data.set("itemDamage", itemDamage);
+ if (itemFrame != null) {
+ data.set("itemFrame", itemFrame.makeModData());
+ }
+ data.setCallbackObject("getRef", () -> {
+ return this;
+ });
+ if (canDestroyCacheBlock != null) {
+ data.set("canDestroyCacheBlock", canDestroyCacheBlock.makeModData());
+ }
+ data.set("canDestroyCacheResult", canDestroyCacheResult);
+ if (canPlaceOnCacheBlock != null) {
+ data.set("canPlaceOnCacheBlock", canPlaceOnCacheBlock.makeModData());
+ }
+ data.set("canPlaceOnCacheResult", canPlaceOnCacheResult);
+
+ data.setCallbackVoid("reload", () -> {
+ loadModData(data);
+ });
+ data.setCallbackObject("getItem", () -> {
+ return getItem().makeModData();
+ });
+ data.setCallbackInt("getMaxStackSize", () -> {
+ return getMaxStackSize();
+ });
+ data.setCallbackBoolean("isStackable", () -> {
+ return isStackable();
+ });
+ data.setCallbackBoolean("isItemStackDamageable", () -> {
+ return isItemStackDamageable();
+ });
+ data.setCallbackBoolean("getHasSubtypes", () -> {
+ return getHasSubtypes();
+ });
+ data.setCallbackBoolean("isItemDamaged", () -> {
+ return isItemDamaged();
+ });
+ data.setCallbackInt("getItemDamage", () -> {
+ return getItemDamage();
+ });
+ data.setCallbackInt("getMetadata", () -> {
+ return getMetadata();
+ });
+ data.setCallbackVoidWithDataArg("setItemDamage", (BaseData params) -> {
+ setItemDamage(params.getInt("meta"));
+ });
+ data.setCallbackInt("getMaxDamage", () -> {
+ return getMaxDamage();
+ });
+ data.setCallbackObject("copy", () -> {
+ return copy().makeModData();
+ });
+ data.setCallbackString("getUnlocalizedName", () -> {
+ return getUnlocalizedName();
+ });
+ data.setCallbackString("toString", () -> {
+ return toString();
+ });
+ data.setCallbackInt("getMaxItemUseDuration", () -> {
+ return getMaxItemUseDuration();
+ });
+ data.setCallbackString("getDisplayName", () -> {
+ return getDisplayName();
+ });
+ data.setCallbackObjectWithDataArg("setDisplayName", (BaseData params) -> {
+ return setStackDisplayName(params.getString("displayName")).makeModData();
+ });
+ data.setCallbackVoid("clearCustomName", () -> {
+ clearCustomName();
+ });
+ data.setCallbackBoolean("hasDisplayName", () -> {
+ return hasDisplayName();
+ });
+ data.setCallbackBoolean("hasEffect", () -> {
+ return hasEffect();
+ });
+ data.setCallbackBoolean("isItemEnchantable", () -> {
+ return isItemEnchantable();
+ });
+ data.setCallbackVoidWithDataArg("addEnchantment", (BaseData params) -> {
+ if (params.getBaseData("ench") instanceof Enchantment) {
+ addEnchantment((Enchantment) params.getBaseData("ench"), params.getInt("level"));
+ }
+ });
+ data.setCallbackBoolean("isItemEnchanted", () -> {
+ return isItemEnchanted();
+ });
+ data.setCallbackBoolean("canEditBlocks", () -> {
+ return canEditBlocks();
+ });
+ data.setCallbackBoolean("isOnItemFrame", () -> {
+ return isOnItemFrame();
+ });
+ data.setCallbackInt("getRepairCost", () -> {
+ return getRepairCost();
+ });
+ data.setCallbackVoidWithDataArg("setRepairCost", (BaseData params) -> {
+ setRepairCost(params.getInt("cost"));
+ });
+ data.setCallbackVoidWithDataArg("setItem", (BaseData params) -> {
+ if (params.getBaseData("newItem") instanceof Item) {
+ setItem((Item) params.getBaseData("newItem"));
+ }
+ });
+ data.setCallbackBooleanWithDataArg("canDestroy", (BaseData params) -> {
+ return canDestroy(Block.getBlockById(params.getInt("blockId")));
+ });
+ data.setCallbackBooleanWithDataArg("canPlaceOn", (BaseData params) -> {
+ return canPlaceOn(Block.getBlockById(params.getInt("blockId")));
+ });
+ data.setCallbackString("toNBT", () -> {
+ return toNBT();
+ });
+ data.setCallbackVoidWithDataArg("fromNBT", (BaseData params) -> {
+ fromNBT(params.getString("nbt"));
+ });
+ data.setCallbackStringArr("getLore", () -> {
+ return getLore();
+ });
+ data.setCallbackVoidWithDataArg("setLore", (BaseData params) -> {
+ setLore(params.getStringArr("lore"));
+ });
+
+ return data;
+ }
+
> INSERT 91 : 106 @ 91
+ public String toNBT() {
+ NBTTagCompound nbt = new NBTTagCompound();
+ nbt = writeToNBT(nbt);
+ return nbt.toString();
+ }
+
+ public void fromNBT(String nbt) {
+ try {
+ NBTTagCompound nbtParsed = JsonToNBT.getTagFromJson(nbt);
+ this.readFromNBT(nbtParsed);
+ } catch (Exception e) {
+ // Swallowing the error!
+ }
+ }
+
> CHANGE 64 : 65 @ 64 : 65
~ public boolean attemptDamageItem(int amount, EaglercraftRandom rand) { ~ public boolean attemptDamageItem(int amount, EaglercraftRandom rand) {
> INSERT 210 : 244 @ 210 > CHANGE 249 : 250 @ 249 : 250
+ public void setLore(String[] loreIn) {
+ if (this.stackTagCompound == null) {
+ this.stackTagCompound = new NBTTagCompound();
+ }
+ if (!this.stackTagCompound.hasKey("display", 10)) {
+ this.stackTagCompound.setTag("display", new NBTTagCompound());
+ }
+ NBTTagCompound display = this.stackTagCompound.getCompoundTag("display");
+ NBTTagList lore = new NBTTagList();
+ for (String strIn : loreIn) {
+ lore.appendTag(new NBTTagString(strIn));
+ }
+ display.setTag("Lore", lore);
+ }
+
+ public String[] getLore() {
+ if (this.stackTagCompound == null) {
+ return new String[0];
+ }
+ if (!this.stackTagCompound.hasKey("display", 10)) {
+ return new String[0];
+ }
+ NBTTagCompound display = this.stackTagCompound.getCompoundTag("display");
+ if (!display.hasKey("Lore", 9)) {
+ return new String[0];
+ }
+ NBTTagList lore = (NBTTagList) display.getTag("Lore");
+ String[] outStrArr = new String[lore.tagCount()];
+ for (int i = 0; i < outStrArr.length; i++) {
+ outStrArr[i] = lore.getStringTagAt(i);
+ }
+ return outStrArr;
+ }
+
> CHANGE 39 : 40 @ 39 : 40
~ s = s + HString.format("#%04d/%d%s", ~ s = s + HString.format("#%04d/%d%s",

View File

@ -9,9 +9,4 @@
+ +
> CHANGE 6 : 8 @ 6 : 8
~ public IChatComponent chatComponent;
~ public byte type;
> EOF > EOF

View File

@ -5,11 +5,10 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> CHANGE 2 : 5 @ 2 : 6 > CHANGE 2 : 4 @ 2 : 6
~ import net.eaglerforge.api.BaseData; ~ import net.eaglerforge.api.BaseData;
~ import net.eaglerforge.api.ModData; ~ import net.eaglerforge.api.ModData;
~ import org.teavm.jso.JSObject;
> CHANGE 1 : 8 @ 1 : 8 > CHANGE 1 : 8 @ 1 : 8

View File

@ -5,11 +5,10 @@
# Version: 1.0 # Version: 1.0
# Author: lax1dude # Author: lax1dude
> CHANGE 2 : 5 @ 2 : 4 > CHANGE 2 : 4 @ 2 : 4
~ import net.eaglerforge.api.BaseData; ~ import net.eaglerforge.api.BaseData;
~ import net.eaglerforge.api.ModData; ~ import net.eaglerforge.api.ModData;
~ import org.teavm.jso.JSObject;
> CHANGE 1 : 5 @ 1 : 5 > CHANGE 1 : 5 @ 1 : 5
@ -18,7 +17,7 @@
~ public double yCoord; ~ public double yCoord;
~ public double zCoord; ~ public double zCoord;
> INSERT 142 : 216 @ 142 > INSERT 142 : 215 @ 142
+ +
+ public void loadModData(BaseData data) { + public void loadModData(BaseData data) {
@ -93,6 +92,5 @@
+ +
+ return data; + return data;
+ } + }
+
> EOF > EOF

View File

@ -41,4 +41,8 @@
+ } + }
+ +
> INSERT 37 : 38 @ 37
+
> EOF > EOF

View File

@ -146,4 +146,8 @@
+ .getBoolean("loadSpawnChunks")) + .getBoolean("loadSpawnChunks"))
+ return false; + return false;
> INSERT 6 : 7 @ 6
+
> EOF > EOF

View File

@ -1,42 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import com.google.common.collect.Sets;
import net.minecraft.client.resources.AbstractResourcePack;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Set;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class FolderResourcePack extends AbstractResourcePack {
public FolderResourcePack(String resourcePackFileIn, String prefix) {
super(resourcePackFileIn);
}
protected InputStream getInputStreamByName(String name) {
return new BufferedInputStream(new ByteArrayInputStream(new byte[0]));
}
protected boolean hasResourceName(String name) {
return false;
}
public Set<String> getResourceDomains() {
return Sets.<String>newHashSet();
}
}

View File

@ -1,42 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SYS {
public static final Object VFS = null;
public static final void loadRemoteResourcePack(String url, String hash, Consumer<String> cb, Consumer<Runnable> ast, Runnable loading) {
return;
}
public static final boolean loadResourcePack(String name, InputStream data, String hash) {
return false;
}
public static final List<String> getResourcePackNames() {
return new ArrayList<>();
}
public static final void deleteResourcePack(String packName) {
//
}
}

View File

@ -1,7 +1,5 @@
package net.eaglerforge.api; package net.eaglerforge.api;
import java.util.Map;
import org.teavm.jso.JSBody; import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
import org.teavm.jso.JSFunctor; import org.teavm.jso.JSFunctor;

View File

@ -1,6 +1,5 @@
package net.eaglerforge.api; package net.eaglerforge.api;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;

View File

@ -4,16 +4,14 @@ import net.eaglerforge.gui.EmptyGui;
import net.eaglerforge.gui.ModGUI; import net.eaglerforge.gui.ModGUI;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.minecraft.client.ClientBrandRetriever; import net.minecraft.client.ClientBrandRetriever;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.util.ChatComponentText; import net.minecraft.util.ChatComponentText;
import me.otterdev.UwUAPI; import me.otterdev.UwUAPI;
import org.teavm.jso.JSBody; import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
import net.eaglerforge.EaglerForge;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.init.Items; import net.minecraft.init.Items;
@ -87,7 +85,7 @@ public class ModAPI {
newEvent("postmotionupdate"); newEvent("postmotionupdate");
newEvent("motionupdate"); newEvent("motionupdate");
newEvent("premotionupdate"); newEvent("premotionupdate");
newEvent("sendchatmessage");
newEvent("update"); newEvent("update");
/*newEvent("packetjoingame"); /*newEvent("packetjoingame");
@ -188,7 +186,6 @@ public class ModAPI {
newEvent("sendpacketcustompayload"); newEvent("sendpacketcustompayload");
newEvent("sendpacketspectate"); newEvent("sendpacketspectate");
newEvent("sendpacketresourcepackstatus");*/ newEvent("sendpacketresourcepackstatus");*/
newEvent("packetchat");
globalsFunctor(this); globalsFunctor(this);
globalsRequireFunctor(this); globalsRequireFunctor(this);
globalsUpdateFunctor(this); globalsUpdateFunctor(this);
@ -218,6 +215,7 @@ public class ModAPI {
setGlobal("logger", LoggerAPI.makeModData()); setGlobal("logger", LoggerAPI.makeModData());
setGlobal("emptygui", EmptyGui.makeModData()); setGlobal("emptygui", EmptyGui.makeModData());
setGlobal("ScaledResolution", ScaledResolution.makeModData()); setGlobal("ScaledResolution", ScaledResolution.makeModData());
setGlobal("GlStateManager", GlStateManager.makeModData());
getModAPI().setCallbackString("currentScreen", () -> { getModAPI().setCallbackString("currentScreen", () -> {
return mc.currentScreen.toString(); return mc.currentScreen.toString();
}); });
@ -227,9 +225,15 @@ public class ModAPI {
getModAPI().setCallbackInt("getdisplayWidth", () -> { getModAPI().setCallbackInt("getdisplayWidth", () -> {
return mc.displayWidth; return mc.displayWidth;
}); });
getModAPI().setCallbackInt("getdisplayWidth", () -> {
return mc.displayWidth;
});
getModAPI().setCallbackInt("getFONT_HEIGHT", () -> { getModAPI().setCallbackInt("getFONT_HEIGHT", () -> {
return mc.fontRendererObj.FONT_HEIGHT; return mc.fontRendererObj.FONT_HEIGHT;
}); });
getModAPI().setCallbackIntWithDataArg("getStringWidth", (BaseData params) -> {
return mc.fontRendererObj.getStringWidth(params.getString("string"));
});
getModAPI().setCallbackVoidWithDataArg("drawStringWithShadow", (BaseData params) -> { getModAPI().setCallbackVoidWithDataArg("drawStringWithShadow", (BaseData params) -> {
mc.fontRendererObj.drawStringWithShadow(params.getString("msg"), params.getFloat("x"), params.getFloat("y"), params.getInt("color")); mc.fontRendererObj.drawStringWithShadow(params.getString("msg"), params.getFloat("x"), params.getFloat("y"), params.getInt("color"));
}); });

View File

@ -2,7 +2,6 @@ package net.eaglerforge.api;
import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime; import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.minecraft.client.Minecraft;
import org.teavm.jso.JSBody; import org.teavm.jso.JSBody;
// this is me.otterdev.PlatformAPI but modified to have more features and be more optimized // this is me.otterdev.PlatformAPI but modified to have more features and be more optimized

View File

@ -12,7 +12,6 @@ import java.util.List;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.vfs.SYS;
import net.lax1dude.eaglercraft.v1_8.internal.FileChooserResult; import net.lax1dude.eaglercraft.v1_8.internal.FileChooserResult;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
@ -50,7 +49,6 @@ public class WIP_GuiMods extends GuiScreen {
this.buttonList.add(btn = new GuiOptionButton(2, this.width / 2 - 154, this.height - 48, this.buttonList.add(btn = new GuiOptionButton(2, this.width / 2 - 154, this.height - 48,
I18n.format("eaglerforge.menu.mods.addmod" I18n.format("eaglerforge.menu.mods.addmod"
+ "", new Object[0]))); + "", new Object[0])));
btn.enabled = SYS.VFS != null;
this.buttonList.add( this.buttonList.add(
new GuiOptionButton(1, this.width / 2 + 4, this.height - 48, I18n.format("gui.done", new Object[0]))); new GuiOptionButton(1, this.width / 2 + 4, this.height - 48, I18n.format("gui.done", new Object[0])));
if (!this.changed) { if (!this.changed) {
@ -117,8 +115,6 @@ public class WIP_GuiMods extends GuiScreen {
protected void actionPerformed(GuiButton parGuiButton) { protected void actionPerformed(GuiButton parGuiButton) {
if (parGuiButton.enabled) { if (parGuiButton.enabled) {
if (parGuiButton.id == 2) { if (parGuiButton.id == 2) {
if (SYS.VFS == null)
return;
EagRuntime.displayFileChooser("text/javascript", "js"); EagRuntime.displayFileChooser("text/javascript", "js");
} else if (parGuiButton.id == 1) { } else if (parGuiButton.id == 1) {
if (this.changed) { if (this.changed) {
@ -162,7 +158,6 @@ public class WIP_GuiMods extends GuiScreen {
return; return;
logger.info("Loading resource pack: {}", packFile.fileName); logger.info("Loading resource pack: {}", packFile.fileName);
mc.loadingScreen.eaglerShow(I18n.format("resourcePack.load.loading"), packFile.fileName); mc.loadingScreen.eaglerShow(I18n.format("resourcePack.load.loading"), packFile.fileName);
SYS.loadResourcePack(packFile.fileName, new ByteArrayInputStream(packFile.fileData), null);
ArrayList arraylist = Lists.newArrayList(); ArrayList arraylist = Lists.newArrayList();

View File

@ -30,7 +30,7 @@ public class EaglercraftVersion {
// Updating configuration // Updating configuration
public static final boolean enableUpdateService = true; public static final boolean enableUpdateService = false;
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client"; public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
public static final int updateBundlePackageVersionInt = 26; public static final int updateBundlePackageVersionInt = 26;
@ -46,7 +46,7 @@ public class EaglercraftVersion {
public static int loadedmods = returntotalloadedmods(); public static int loadedmods = returntotalloadedmods();
public static final String mainMenuStringA = "Minecraft* 1.8.8"; public static final String mainMenuStringA = "Minecraft* 1.8.8";
public static String mainMenuStringB = projectForkName + " " + projectForkVersion + " (" + 0 + " Mods loaded)"; public static String mainMenuStringB = projectForkName + " " + projectForkVersion + " (" + loadedmods + " Mods loaded)";
public static final String mainMenuStringC = ""; public static final String mainMenuStringC = "";
public static final String mainMenuStringD = "Resources Copyright Mojang AB"; public static final String mainMenuStringD = "Resources Copyright Mojang AB";

View File

@ -1,5 +1,7 @@
package net.lax1dude.eaglercraft.v1_8.opengl; package net.lax1dude.eaglercraft.v1_8.opengl;
import net.eaglerforge.api.BaseData;
import net.eaglerforge.api.ModData;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer; import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
@ -25,7 +27,7 @@ import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
public class GlStateManager { public class GlStateManager extends ModData {
static final Logger logger = LogManager.getLogger("GlStateManager"); static final Logger logger = LogManager.getLogger("GlStateManager");
@ -1186,4 +1188,43 @@ public class GlStateManager {
public static void recompileShaders() { public static void recompileShaders() {
FixedFunctionPipeline.flushCache(); FixedFunctionPipeline.flushCache();
} }
public static ModData makeModData() {
ModData GlStateManagerglobal = new ModData();
GlStateManagerglobal.setCallbackVoid("reload", () -> {
loadModData(GlStateManagerglobal);
});
GlStateManagerglobal.setCallbackVoid("pushMatrix", () -> {
pushMatrix();
});
GlStateManagerglobal.setCallbackVoid("popMatrix", () -> {
popMatrix();
});
GlStateManagerglobal.setCallbackVoidWithDataArg("scale", (BaseData params) -> {
scale(params.getFloat("x"),params.getFloat("y"),params.getFloat("z"));
});
GlStateManagerglobal.setCallbackVoidWithDataArg("translate", (BaseData params) -> {
translate(params.getFloat("x"),params.getFloat("y"),params.getFloat("z"));
});
GlStateManagerglobal.setCallbackVoidWithDataArg("recompileShaders", (BaseData params) -> {
recompileShaders();
});
GlStateManagerglobal.setCallbackVoidWithDataArg("color", (BaseData params) -> {
color(params.getFloat("colorRed"),params.getFloat("colorGreen"),params.getFloat("colorBlue"),params.getFloat("colorAlpha"));
});
GlStateManagerglobal.setCallbackVoidWithDataArg("rotate", (BaseData params) -> {
rotate(params.getFloat("angle"),params.getFloat("x"),params.getFloat("y"),params.getFloat("z"));
});
GlStateManagerglobal.setCallbackVoidWithDataArg("matrixMode", (BaseData params) -> {
matrixMode(params.getInt("mode"));
});
return GlStateManagerglobal;
}
public static void loadModData(BaseData data) {
stateDepthMask = data.getBoolean("stateDepthMask");
stateCull = data.getBoolean("stateCull");
stateFog = data.getBoolean("stateFog");
stateGlobalBlend = data.getBoolean("stateGlobalBlend");
stateLighting = data.getBoolean("stateLighting");
}
} }

View File

@ -1,22 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.vfs;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class FolderResourcePack extends net.lax1dude.eaglercraft.v1_8.internal.vfs.FolderResourcePack {
public FolderResourcePack(String resourcePackFileIn, String prefix) {
super(resourcePackFileIn, prefix);
}
}

View File

@ -1,19 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.vfs;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SYS extends net.lax1dude.eaglercraft.v1_8.internal.vfs.SYS {
}

View File

@ -0,0 +1,4 @@
@echo off
title gradlew generateJavascript
gradlew generateJavascript
pause

View File

@ -0,0 +1,3 @@
#!/bin/sh
chmod +x gradlew
./gradlew generateJavascript

View File

@ -21,15 +21,12 @@ dependencies {
teavm(teavm.libs.jso) teavm(teavm.libs.jso)
teavm(teavm.libs.jsoApis) teavm(teavm.libs.jsoApis)
} }
dependencies {
implementation teavm.libs.jsoApis
}
teavm.js { teavm.js {
obfuscated = false; obfuscated = true
sourceMap = true sourceMap = true
targetFileName = "../classes.js" targetFileName = "../classes.js"
optimization = org.teavm.gradle.api.OptimizationLevel.AGGRESSIVE; optimization = org.teavm.gradle.api.OptimizationLevel.AGGRESSIVE
outOfProcess = false outOfProcess = false
fastGlobalAnalysis = false fastGlobalAnalysis = false
processMemory = 512 processMemory = 512

View File

@ -0,0 +1 @@
org.gradle.jvmargs=-Xmx2G -Xms2G

View File

@ -4,6 +4,7 @@ function initAPI(version) {
ModAPI.events.types = ["event"]; ModAPI.events.types = ["event"];
ModAPI.events.listeners = { "event": [] }; ModAPI.events.listeners = { "event": [] };
ModAPI.globals = {}; ModAPI.globals = {};
ModAPI.version = version;
ModAPI.addEventListener = function AddEventListener(name, callback) { ModAPI.addEventListener = function AddEventListener(name, callback) {
if (!callback) { if (!callback) {

View File

@ -42,6 +42,7 @@ function initAPI(version) {
ModAPI.events.types = ["event"]; ModAPI.events.types = ["event"];
ModAPI.events.listeners = { "event": [] }; ModAPI.events.listeners = { "event": [] };
ModAPI.globals = {}; ModAPI.globals = {};
ModAPI.version = version;
ModAPI.addEventListener = function AddEventListener(name, callback) { ModAPI.addEventListener = function AddEventListener(name, callback) {
if (!callback) { if (!callback) {

View File

@ -1,33 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
/**
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class BooleanResult {
public static final BooleanResult TRUE = new BooleanResult(true);
public static final BooleanResult FALSE = new BooleanResult(false);
public final boolean bool;
private BooleanResult(boolean b) {
bool = b;
}
public static BooleanResult _new(boolean b) {
return b ? TRUE : FALSE;
}
}

View File

@ -1,59 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import com.google.common.collect.Sets;
import net.minecraft.client.resources.AbstractResourcePack;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class FolderResourcePack extends AbstractResourcePack {
private final String prefix;
public FolderResourcePack(String resourcePackFileIn, String prefix) {
super(resourcePackFileIn);
this.prefix = prefix;
}
protected InputStream getInputStreamByName(String name) {
return SYS.VFS.getFile(prefix + this.resourcePackFile + "/" + name).getInputStream();
}
protected boolean hasResourceName(String name) {
return SYS.VFS.fileExists(prefix + this.resourcePackFile + "/" + name);
}
public Set<String> getResourceDomains() {
Set<String> set = Sets.<String>newHashSet();
String pfx = prefix + this.resourcePackFile + "/assets/";
List<String> files = SYS.VFS.listFiles(pfx);
for (String file : files) {
String s = file.substring(pfx.length());
int ind = s.indexOf('/');
if (ind != -1) s = s.substring(0, ind);
if (!s.equals(s.toLowerCase())) {
this.logNameNotLowercase(s);
} else {
set.add(s);
}
}
return set;
}
}

View File

@ -1,194 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.crypto.SHA1Digest;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.ArrayBufferInputStream;
import net.lax1dude.eaglercraft.v1_8.internal.vfs.VirtualFilesystem.VFSHandle;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SYS {
public static final VirtualFilesystem VFS;
static {
VFSHandle vh = VirtualFilesystem.openVFS("_net_lax1dude_eaglercraft_v1_8_VirtualFilesystem_");
if(vh.vfs == null) {
System.err.println("Could not init filesystem!");
}
VFS = vh.vfs;
List<String> srp = getResourcePackNames(true);
for (String name : srp) {
if (System.currentTimeMillis() - Long.parseLong(name.substring(name.lastIndexOf('_') + 1)) >= 604800000L) {
deleteResourcePack(name, true);
}
}
}
public static final void loadRemoteResourcePack(String url, String hash, Consumer<String> cb, Consumer<Runnable> ast, Runnable loading) {
if (!hash.matches("^[a-f0-9]{40}$")) {
cb.accept(null);
return;
}
List<String> srpPre = getResourcePackNames(true);
String alreadyHere = srpPre.stream().filter(s -> s.startsWith(hash + "_")).findFirst().orElse(null);
if (alreadyHere != null) {
cb.accept(alreadyHere);
return;
}
PlatformRuntime.downloadRemoteURI(url, ab -> {
ast.accept(() -> {
if (ab == null) {
cb.accept(null);
return;
}
List<String> srp = getResourcePackNames(true);
// delete old server resource packs - todo: test
if (srp.size() > 5) {
srp.sort(Comparator.comparingLong(val -> Long.parseLong(val.substring(val.lastIndexOf('_') + 1))));
for (int i = 0; i < srp.size() - 5; i++) {
deleteResourcePack(srp.get(i), true);
}
}
String packName = hash + "_" + System.currentTimeMillis();
loading.run();
boolean success = loadResourcePack(packName + ".zip", new ArrayBufferInputStream(ab), hash);
if (success) {
cb.accept(packName);
return;
}
cb.accept(null);
});
});
}
public static final boolean loadResourcePack(String name, InputStream is, String hash) {
BufferedInputStream bis = new BufferedInputStream(is);
bis.mark(Integer.MAX_VALUE);
if (hash != null) {
try {
SHA1Digest digest = new SHA1Digest();
byte[] buffer = new byte[16000];
int read = 0;
while ((read = bis.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
byte[] sha1sum = new byte[20];
digest.doFinal(sha1sum, 0);
bis.reset();
if (!hash.equals((new BigInteger(1, sha1sum)).toString(16))) {
return false;
}
} catch (IOException e) {
EagRuntime.debugPrintStackTrace(e);
return false;
}
}
String packName = name.substring(0, name.lastIndexOf('.')).replace('/', '_');
try {
int prefixLen = Integer.MAX_VALUE;
ZipInputStream ziss = new ZipInputStream(bis);
ZipEntry zipEntryy;
while ((zipEntryy = ziss.getNextEntry()) != null) {
String zn;
if (!zipEntryy.isDirectory() && ((zn = zipEntryy.getName()).equals("pack.mcmeta") || zn.endsWith("/pack.mcmeta"))) {
int currPrefixLen = zn.length() - 11;
if (prefixLen > currPrefixLen) {
prefixLen = currPrefixLen;
}
}
}
if (prefixLen == Integer.MAX_VALUE) {
prefixLen = 0;
}
bis.reset();
ZipInputStream zis = new ZipInputStream(bis);
byte[] bb = new byte[16000];
ZipEntry zipEntry;
while ((zipEntry = zis.getNextEntry()) != null) {
if (zipEntry.isDirectory()) continue;
if (zipEntry.getName().length() <= prefixLen) continue;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
while ((len = zis.read(bb)) != -1) {
baos.write(bb, 0, len);
}
baos.close();
SYS.VFS.getFile((hash == null ? "resourcepacks/" : "srp/") + packName + "/" + zipEntry.getName().substring(prefixLen)).setAllBytes(baos.toByteArray());
}
zis.closeEntry();
zis.close();
return true;
} catch (IOException e) {
EagRuntime.debugPrintStackTrace(e);
return false;
}
}
public static final List<String> getResourcePackNames() {
return getResourcePackNames(false);
}
private static final List<String> getResourcePackNames(boolean srp) {
List<String> res = new ArrayList<>();
List<String> resourcePackFiles = SYS.VFS.listFiles(srp ? "srp/" : "resourcepacks/");
for (String path : resourcePackFiles) {
String trimmed = path.substring(srp ? 4 : 14);
trimmed = trimmed.substring(0, trimmed.indexOf('/'));
boolean hasIt = false;
for (String alreadyHas : res) {
if (trimmed.equals(alreadyHas)) {
hasIt = true;
break;
}
}
if (hasIt) continue;
res.add(trimmed);
}
return res;
}
public static final void deleteResourcePack(String packName) {
deleteResourcePack(packName, false);
}
private static final void deleteResourcePack(String packName, boolean srp) {
SYS.VFS.deleteFiles((srp ? "srp/" : "resourcepacks/") + packName);
}
}

View File

@ -1,32 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface VFSIterator {
public static class BreakLoop extends RuntimeException {
public BreakLoop() {
super("iterator loop break request");
}
}
public default void end() {
throw new BreakLoop();
}
public void next(VIteratorFile entry);
}

View File

@ -1,242 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VFile {
public static final String pathSeperator = "/";
public static final String[] altPathSeperator = new String[] { "\\" };
public static String normalizePath(String p) {
for(int i = 0; i < altPathSeperator.length; ++i) {
p = p.replace(altPathSeperator[i], pathSeperator);
}
if(p.startsWith(pathSeperator)) {
p = p.substring(1);
}
if(p.endsWith(pathSeperator)) {
p = p.substring(0, p.length() - pathSeperator.length());
}
return p;
}
public static String[] splitPath(String p) {
String[] pth = normalizePath(p).split(pathSeperator);
for(int i = 0; i < pth.length; ++i) {
pth[i] = pth[i].trim();
}
return pth;
}
protected String path;
public static String createPath(Object... p) {
ArrayList<String> r = new ArrayList();
for(int i = 0; i < p.length; ++i) {
if(p[i] == null) {
continue;
}
String gg = p[i].toString();
if(gg == null) {
continue;
}
String[] parts = splitPath(gg);
for(int j = 0; j < parts.length; ++j) {
if(parts[j] == null || parts[j].equals(".")) {
continue;
}else if(parts[j].equals("..") && r.size() > 0) {
int k = r.size() - 1;
if(!r.get(k).equals("..")) {
r.remove(k);
}else {
r.add("..");
}
}else {
r.add(parts[j]);
}
}
}
if(r.size() > 0) {
StringBuilder s = new StringBuilder();
for(int i = 0; i < r.size(); ++i) {
if(i > 0) {
s.append(pathSeperator);
}
s.append(r.get(i));
}
return s.toString();
}else {
return null;
}
}
public VFile(Object... p) {
this.path = createPath(p);
}
public InputStream getInputStream() {
return isRelative() ? null : SYS.VFS.getFile(path).getInputStream();
}
public OutputStream getOutputStream() {
return isRelative() ? null : SYS.VFS.getFile(path).getOutputStream();
}
public String toString() {
return path;
}
public boolean isRelative() {
return path == null || path.contains("..");
}
public boolean canRead() {
return !isRelative() && SYS.VFS.fileExists(path);
}
public String getPath() {
return path.equals("unnamed") ? null : path;
}
public String getName() {
if(path == null) {
return null;
}
int i = path.indexOf(pathSeperator);
return i == -1 ? path : path.substring(i + 1);
}
public boolean canWrite() {
return !isRelative();
}
public String getParent() {
if(path == null) {
return null;
}
int i = path.indexOf(pathSeperator);
return i == -1 ? ".." : path.substring(0, i);
}
public int hashCode() {
return path == null ? 0 : path.hashCode();
}
public boolean equals(Object o) {
return path != null && o != null && (o instanceof VFile) && path.equals(((VFile)o).path);
}
public boolean exists() {
return !isRelative() && SYS.VFS.fileExists(path);
}
public boolean delete() {
return !isRelative() && SYS.VFS.deleteFile(path);
}
public boolean renameTo(String p, boolean copy) {
if(!isRelative() && SYS.VFS.renameFile(path, p, copy)) {
path = p;
return true;
}
return false;
}
public int length() {
return isRelative() ? -1 : SYS.VFS.getFile(path).getSize();
}
public void getBytes(int fileOffset, byte[] array, int offset, int length) {
if(isRelative()) {
throw new ArrayIndexOutOfBoundsException("File is relative");
}
SYS.VFS.getFile(path).getBytes(fileOffset, array, offset, length);
}
public void setCacheEnabled() {
if(isRelative()) {
throw new RuntimeException("File is relative");
}
SYS.VFS.getFile(path).setCacheEnabled();
}
public byte[] getAllBytes() {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllBytes();
}
public String getAllChars() {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllChars();
}
public String[] getAllLines() {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllLines();
}
public byte[] getAllBytes(boolean copy) {
if(isRelative()) {
return null;
}
return SYS.VFS.getFile(path).getAllBytes(copy);
}
public boolean setAllChars(String bytes) {
if(isRelative()) {
return false;
}
return SYS.VFS.getFile(path).setAllChars(bytes);
}
public boolean setAllBytes(byte[] bytes) {
if(isRelative()) {
return false;
}
return SYS.VFS.getFile(path).setAllBytes(bytes);
}
public boolean setAllBytes(byte[] bytes, boolean copy) {
if(isRelative()) {
return false;
}
return SYS.VFS.getFile(path).setAllBytes(bytes, copy);
}
public List<String> list() {
if(isRelative()) {
return Arrays.asList(path);
}
return SYS.VFS.listFiles(path);
}
public int deleteAll() {
return isRelative() ? 0 : SYS.VFS.deleteFiles(path);
}
}

View File

@ -1,299 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.Event;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.indexeddb.IDBCursor;
import org.teavm.jso.indexeddb.IDBRequest;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Uint8Array;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* Do not use an instance of this class outside of the VFSIterator.next() method
*/
public class VIteratorFile extends VFile {
static final VIteratorFile instance = new VIteratorFile();
private VIteratorFile() {
super("");
this.idx = -1;
this.cur = null;
this.vfs = null;
}
private static class VirtualIteratorOutputStream extends ByteArrayOutputStream {
private final VIteratorFile itr;
protected VirtualIteratorOutputStream(VIteratorFile itr) {
this.itr = itr;
}
public void close() throws IOException {
if(!itr.setAllBytes(super.toByteArray(), false)) {
throw new IOException("Could not close stream and write to \"" + itr.path + "\" on VFS \"" + itr.vfs.database + "\" (the file was probably deleted)");
}
}
}
private int idx;
private IDBCursor cur;
private VirtualFilesystem vfs;
private boolean wasDeleted;
@JSBody(params = { "k" }, script = "return ((typeof k) === \"string\") ? k : (((typeof k) === \"undefined\") ? null : (((typeof k[0]) === \"string\") ? k[0] : null));")
private static native String readKey(JSObject k);
static VIteratorFile create(int idx, VirtualFilesystem vfs, IDBCursor cur) {
String k = readKey(cur.getKey());
if(k == null) {
return null;
}
instance.update(idx, k, vfs, cur);
return instance;
}
public VFile makeVFile() {
return new VFile(path);
}
private void update(int idx, String path, VirtualFilesystem vfs, IDBCursor cur) {
this.idx = idx;
this.path = path;
this.vfs = vfs;
this.cur = cur;
this.wasDeleted = false;
}
public InputStream getInputStream() {
return !wasDeleted ? new ByteArrayInputStream(getAllBytes()) : null;
}
public OutputStream getOutputStream() {
return !wasDeleted ? new VirtualIteratorOutputStream(this) : null;
}
public String toString() {
return path;
}
public boolean isRelative() {
return false;
}
public boolean canRead() {
return !wasDeleted;
}
public String getPath() {
return path;
}
public String getName() {
if(path == null) {
return null;
}
int i = path.indexOf(pathSeperator);
return i == -1 ? path : path.substring(i + 1);
}
public boolean canWrite() {
return !wasDeleted;
}
public String getParent() {
if(path == null) {
return null;
}
int i = path.indexOf(pathSeperator);
return i == -1 ? ".." : path.substring(0, i);
}
public int hashCode() {
return path == null ? 0 : path.hashCode();
}
public boolean equals(Object o) {
return path != null && o != null && (o instanceof VFile) && path.equals(((VFile)o).path);
}
public boolean exists() {
return !wasDeleted;
}
public boolean delete() {
return wasDeleted = AsyncHandlers.awaitRequest(cur.delete()).bool;
}
public boolean renameTo(String p) {
byte[] data = getAllBytes();
String op = path;
path = p;
if(!setAllBytes(data)) {
path = op;
return false;
}
path = op;
if(!delete()) {
return false;
}
path = p;
return true;
}
public int length() {
JSObject obj = cur.getValue();
if(obj == null) {
throw new RuntimeException("Value of entry is missing");
}
ArrayBuffer arr = readRow(obj);
if(arr == null) {
throw new RuntimeException("Value of the fucking value of the entry is missing");
}
return arr.getByteLength();
}
public void getBytes(int fileOffset, byte[] array, int offset, int length) {
JSObject obj = cur.getValue();
if(obj == null) {
throw new ArrayIndexOutOfBoundsException("Value of entry is missing");
}
ArrayBuffer arr = readRow(obj);
if(arr == null) {
throw new ArrayIndexOutOfBoundsException("Value of the fucking value of the entry is missing");
}
Uint8Array a = Uint8Array.create(arr);
if(a.getLength() < fileOffset + length) {
throw new ArrayIndexOutOfBoundsException("file '" + path + "' size was "+a.getLength()+" but user tried to read index "+(fileOffset + length - 1));
}
for(int i = 0; i < length; ++i) {
array[i + offset] = (byte)a.get(i + fileOffset);
}
}
public void setCacheEnabled() {
// no
}
@JSBody(params = { "obj" }, script = "return (typeof obj === 'undefined') ? null : ((typeof obj.data === 'undefined') ? null : obj.data);")
private static native ArrayBuffer readRow(JSObject obj);
public byte[] getAllBytes() {
JSObject obj = cur.getValue();
if(obj == null) {
return null;
}
ArrayBuffer arr = readRow(obj);
if(arr == null) {
return null;
}
return TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(arr));
}
public String getAllChars() {
return VirtualFilesystem.utf8(getAllBytes());
}
public String[] getAllLines() {
return VirtualFilesystem.lines(VirtualFilesystem.utf8(getAllBytes()));
}
public byte[] getAllBytes(boolean copy) {
return getAllBytes();
}
public boolean setAllChars(String bytes) {
return setAllBytes(VirtualFilesystem.utf8(bytes));
}
public List<String> list() {
throw new RuntimeException("Cannot perform list all in VFS callback");
}
public int deleteAll() {
throw new RuntimeException("Cannot perform delete all in VFS callback");
}
@JSBody(params = { "pat", "dat" }, script = "return { path: pat, data: dat };")
private static native JSObject writeRow(String name, ArrayBuffer data);
public boolean setAllBytes(byte[] bytes) {
ArrayBuffer a = ArrayBuffer.create(bytes.length);
Uint8Array ar = Uint8Array.create(a);
ar.set(bytes);
JSObject obj = writeRow(path, a);
BooleanResult r = AsyncHandlers.awaitRequest(cur.update(obj));
return r.bool;
}
public boolean setAllBytes(byte[] bytes, boolean copy) {
return setAllBytes(bytes);
}
public static class AsyncHandlers {
@Async
public static native BooleanResult awaitRequest(IDBRequest r);
private static void awaitRequest(IDBRequest r, final AsyncCallback<BooleanResult> cb) {
r.addEventListener("success", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
cb.complete(BooleanResult._new(true));
}
});
r.addEventListener("error", new EventListener<Event>() {
@Override
public void handleEvent(Event evt) {
cb.complete(BooleanResult._new(false));
}
});
}
}
}

View File

@ -1,702 +0,0 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
import net.lax1dude.eaglercraft.v1_8.internal.teavm.TeaVMUtils;
import org.teavm.interop.Async;
import org.teavm.interop.AsyncCallback;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.indexeddb.EventHandler;
import org.teavm.jso.indexeddb.IDBCountRequest;
import org.teavm.jso.indexeddb.IDBCursor;
import org.teavm.jso.indexeddb.IDBCursorRequest;
import org.teavm.jso.indexeddb.IDBDatabase;
import org.teavm.jso.indexeddb.IDBFactory;
import org.teavm.jso.indexeddb.IDBGetRequest;
import org.teavm.jso.indexeddb.IDBObjectStoreParameters;
import org.teavm.jso.indexeddb.IDBOpenDBRequest;
import org.teavm.jso.indexeddb.IDBRequest;
import org.teavm.jso.indexeddb.IDBTransaction;
import org.teavm.jso.indexeddb.IDBVersionChangeEvent;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Uint8Array;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* 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)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VirtualFilesystem {
protected static class VirtualOutputStream extends ByteArrayOutputStream {
private final VFSFile file;
protected VirtualOutputStream(VFSFile file) {
this.file = file;
}
public void close() throws IOException {
if(!file.setAllBytes(super.toByteArray(), false)) {
throw new IOException("Could not close stream and write to \"" + file.filePath + "\" on VFS \"" + file.virtualFilesystem.database + "\" (the file was probably deleted)");
}
}
}
public static class VFSFile {
public final VirtualFilesystem virtualFilesystem;
protected boolean cacheEnabled;
protected String filePath;
protected int fileSize = -1;
protected boolean hasBeenDeleted = false;
protected boolean hasBeenAccessed = false;
protected boolean exists = false;
protected byte[] cache = null;
protected long cacheHit;
protected VFSFile(VirtualFilesystem vfs, String filePath, boolean cacheEnabled) {
this.virtualFilesystem = vfs;
this.filePath = filePath;
this.cacheHit = System.currentTimeMillis();
if(cacheEnabled) {
setCacheEnabled();
}
}
public boolean equals(Object o) {
return (o instanceof VFSFile) && ((VFSFile)o).filePath.equals(filePath);
}
public int hashCode() {
return filePath.hashCode();
}
public String getPath() {
return filePath;
}
public int getSize() {
cacheHit = System.currentTimeMillis();
if(fileSize < 0) {
if(cacheEnabled) {
byte[] b = getAllBytes(false);
if(b != null) {
fileSize = b.length;
}
}else {
ArrayBuffer dat = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
if(dat != null) {
fileSize = dat.getByteLength();
}
}
}
return fileSize;
}
public InputStream getInputStream() {
byte[] dat = getAllBytes(false);
if(dat == null) {
return null;
}
return new EaglerInputStream(dat);
}
public OutputStream getOutputStream() {
return new VirtualOutputStream(this);
}
public void getBytes(int fileOffset, byte[] array, int offset, int length) {
if(hasBeenDeleted) {
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' has been deleted");
}else if(hasBeenAccessed && !exists) {
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' does not exist");
}
cacheHit = System.currentTimeMillis();
if(cacheEnabled && cache != null) {
System.arraycopy(cache, fileOffset, array, offset, length);
}else {
ArrayBuffer aa = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
hasBeenAccessed = true;
if(aa != null) {
exists = true;
}else {
exists = false;
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' does not exist");
}
Uint8Array a = Uint8Array.create(aa);
this.fileSize = a.getByteLength();
if(cacheEnabled) {
cache = new byte[fileSize];
for(int i = 0; i < fileSize; ++i) {
cache[i] = (byte)a.get(i);
}
}
if(a.getLength() < fileOffset + length) {
throw new ArrayIndexOutOfBoundsException("file '" + filePath + "' size was "+a.getLength()+" but user tried to read index "+(fileOffset + length - 1));
}
for(int i = 0; i < length; ++i) {
array[i + offset] = (byte)a.get(i + fileOffset);
}
}
}
public void setCacheEnabled() {
if(!cacheEnabled && !hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = System.currentTimeMillis();
cache = getAllBytes(false);
cacheEnabled = true;
}
}
public byte[] getAllBytes() {
return getAllBytes(false);
}
public String getAllChars() {
return utf8(getAllBytes(false));
}
public String[] getAllLines() {
return lines(getAllChars());
}
public byte[] getAllBytes(boolean copy) {
if(hasBeenDeleted || (hasBeenAccessed && !exists)) {
return null;
}
cacheHit = System.currentTimeMillis();
if(cacheEnabled && cache != null) {
byte[] b = cache;
if(copy) {
b = new byte[cache.length];
System.arraycopy(cache, 0, b, 0, cache.length);
}
return b;
}else {
hasBeenAccessed = true;
ArrayBuffer b = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
if(b != null) {
exists = true;
}else {
exists = false;
return null;
}
Uint8Array a = Uint8Array.create(b);
this.fileSize = a.getByteLength();
byte[] array = TeaVMUtils.wrapUnsignedByteArray(a);
if(cacheEnabled) {
if(copy) {
cache = new byte[fileSize];
System.arraycopy(b, 0, cache, 0, cache.length);
}else {
cache = array;
}
}
return array;
}
}
public boolean setAllChars(String bytes) {
return setAllBytes(utf8(bytes), true);
}
public boolean setAllBytes(byte[] bytes) {
return setAllBytes(bytes, true);
}
public boolean setAllBytes(byte[] bytes, boolean copy) {
if(hasBeenDeleted || bytes == null) {
return false;
}
cacheHit = System.currentTimeMillis();
this.fileSize = bytes.length;
if(cacheEnabled) {
byte[] copz = bytes;
if(copy) {
copz = new byte[bytes.length];
System.arraycopy(bytes, 0, copz, 0, bytes.length);
}
cache = copz;
return sync();
}else {
boolean s = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, TeaVMUtils.unwrapUnsignedByteArray(bytes).getBuffer()).bool;
hasBeenAccessed = true;
exists = exists || s;
return s;
}
}
public boolean sync() {
if(cacheEnabled && cache != null && !hasBeenDeleted) {
cacheHit = System.currentTimeMillis();
boolean tryWrite = AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, filePath, TeaVMUtils.unwrapUnsignedByteArray(cache).getBuffer()).bool;
hasBeenAccessed = true;
exists = exists || tryWrite;
return tryWrite;
}
return false;
}
public boolean delete() {
if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = System.currentTimeMillis();
if(!AsyncHandlers.deleteFile(virtualFilesystem.indexeddb, filePath).bool) {
hasBeenAccessed = true;
return false;
}
virtualFilesystem.fileMap.remove(filePath);
hasBeenDeleted = true;
hasBeenAccessed = true;
exists = false;
return true;
}
return false;
}
public boolean rename(String newName, boolean copy) {
if(!hasBeenDeleted && !(hasBeenAccessed && !exists)) {
cacheHit = System.currentTimeMillis();
ArrayBuffer arr = AsyncHandlers.readWholeFile(virtualFilesystem.indexeddb, filePath);
hasBeenAccessed = true;
if(arr != null) {
exists = true;
if(!AsyncHandlers.writeWholeFile(virtualFilesystem.indexeddb, newName, arr).bool) {
return false;
}
if(!copy && !AsyncHandlers.deleteFile(virtualFilesystem.indexeddb, filePath).bool) {
return false;
}
}else {
exists = false;
}
if(!copy) {
virtualFilesystem.fileMap.remove(filePath);
filePath = newName;
virtualFilesystem.fileMap.put(newName, this);
}
return true;
}
return false;
}
public boolean exists() {
if(hasBeenDeleted) {
return false;
}
cacheHit = System.currentTimeMillis();
if(hasBeenAccessed) {
return exists;
}
exists = AsyncHandlers.fileExists(virtualFilesystem.indexeddb, filePath).bool;
hasBeenAccessed = true;
return exists;
}
}
private final HashMap<String, VFSFile> fileMap = new HashMap();
public final String database;
private final IDBDatabase indexeddb;
public static class VFSHandle {
public final boolean failedInit;
public final boolean failedLocked;
public final String failedError;
public final VirtualFilesystem vfs;
public VFSHandle(boolean init, boolean locked, String error, VirtualFilesystem db) {
failedInit = init;
failedLocked = locked;
failedError = error;
vfs = db;
}
public String toString() {
if(failedInit) {
return "IDBFactory threw an exception, IndexedDB is most likely not supported in this browser." + (failedError == null ? "" : "\n\n" + failedError);
}
if(failedLocked) {
return "The filesystem requested is already in use on a different tab.";
}
if(failedError != null) {
return "The IDBFactory.open() request failed, reason: " + failedError;
}
return "Virtual Filesystem Object: " + vfs.database;
}
}
public static VFSHandle openVFS(String db) {
DatabaseOpen evt = AsyncHandlers.openDB(db);
if(evt.failedInit) {
return new VFSHandle(true, false, evt.failedError, null);
}
if(evt.failedLocked) {
return new VFSHandle(false, true, null, null);
}
if(evt.failedError != null) {
return new VFSHandle(false, false, evt.failedError, null);
}
return new VFSHandle(false, false, null, new VirtualFilesystem(db, evt.database));
}
private VirtualFilesystem(String db, IDBDatabase idb) {
database = db;
indexeddb = idb;
}
public void close() {
indexeddb.close();
}
public VFSFile getFile(String path) {
return getFile(path, false);
}
public VFSFile getFile(String path, boolean cache) {
VFSFile f = fileMap.get(path);
if(f == null) {
fileMap.put(path, f = new VFSFile(this, path, cache));
}else {
if(cache) {
f.setCacheEnabled();
}
}
return f;
}
public boolean renameFile(String oldName, String newName, boolean copy) {
return getFile(oldName).rename(newName, copy);
}
public boolean deleteFile(String path) {
return getFile(path).delete();
}
public boolean fileExists(String path) {
return getFile(path).exists();
}
public List<String> listFiles(String prefix) {
final ArrayList<String> list = new ArrayList();
AsyncHandlers.iterateFiles(indexeddb, this, prefix, false, (v) -> {
list.add(v.getPath());
});
return list;
}
public int deleteFiles(String prefix) {
return AsyncHandlers.deleteFiles(indexeddb, prefix);
}
public int iterateFiles(String prefix, boolean rw, VFSIterator itr) {
return AsyncHandlers.iterateFiles(indexeddb, this, prefix, rw, itr);
}
public int renameFiles(String oldPrefix, String newPrefix, boolean copy) {
List<String> filesToCopy = listFiles(oldPrefix);
int i = 0;
for(String str : filesToCopy) {
String f = VFile.createPath(newPrefix, str.substring(oldPrefix.length()));
if(!renameFile(str, f, copy)) {
System.err.println("Could not " + (copy ? "copy" : "rename") + " file \"" + str + "\" to \"" + f + "\" for some reason");
}else {
++i;
}
}
return i;
}
public void flushCache(long age) {
long curr = System.currentTimeMillis();
Iterator<VFSFile> files = fileMap.values().iterator();
while(files.hasNext()) {
if(curr - files.next().cacheHit > age) {
files.remove();
}
}
}
protected static class DatabaseOpen {
protected final boolean failedInit;
protected final boolean failedLocked;
protected final String failedError;
protected final IDBDatabase database;
protected DatabaseOpen(boolean init, boolean locked, String error, IDBDatabase db) {
failedInit = init;
failedLocked = locked;
failedError = error;
database = db;
}
}
@JSBody(script = "return ((typeof indexedDB) !== 'undefined') ? indexedDB : null;")
protected static native IDBFactory createIDBFactory();
protected static class AsyncHandlers {
@Async
protected static native DatabaseOpen openDB(String name);
private static void openDB(String name, final AsyncCallback<DatabaseOpen> cb) {
IDBFactory i = createIDBFactory();
if(i == null) {
cb.complete(new DatabaseOpen(false, false, "window.indexedDB was null or undefined", null));
return;
}
final IDBOpenDBRequest f = i.open(name, 1);
f.setOnBlocked(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, true, null, null));
}
});
f.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, false, null, f.getResult()));
}
});
f.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(new DatabaseOpen(false, false, "open error", null));
}
});
f.setOnUpgradeNeeded(new EventListener<IDBVersionChangeEvent>() {
@Override
public void handleEvent(IDBVersionChangeEvent evt) {
f.getResult().createObjectStore("filesystem", IDBObjectStoreParameters.create().keyPath("path"));
}
});
}
@Async
protected static native BooleanResult deleteFile(IDBDatabase db, String name);
private static void deleteFile(IDBDatabase db, String name, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBRequest r = tx.objectStore("filesystem").delete(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(true));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(false));
}
});
}
@JSBody(params = { "obj" }, script = "return (typeof obj === 'undefined') ? null : ((typeof obj.data === 'undefined') ? null : obj.data);")
protected static native ArrayBuffer readRow(JSObject obj);
@JSBody(params = { "obj" }, script = "return [obj];")
private static native JSObject makeTheFuckingKeyWork(String k);
@Async
protected static native ArrayBuffer readWholeFile(IDBDatabase db, String name);
private static void readWholeFile(IDBDatabase db, String name, final AsyncCallback<ArrayBuffer> cb) {
IDBTransaction tx = db.transaction("filesystem", "readonly");
final IDBGetRequest r = tx.objectStore("filesystem").get(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(readRow(r.getResult()));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(null);
}
});
}
@JSBody(params = { "k" }, script = "return ((typeof k) === \"string\") ? k : (((typeof k) === \"undefined\") ? null : (((typeof k[0]) === \"string\") ? k[0] : null));")
private static native String readKey(JSObject k);
@JSBody(params = { "k" }, script = "return ((typeof k) === \"undefined\") ? null : (((typeof k.path) === \"undefined\") ? null : (((typeof k.path) === \"string\") ? k[0] : null));")
private static native String readRowKey(JSObject r);
@Async
protected static native Integer iterateFiles(IDBDatabase db, final VirtualFilesystem vfs, final String prefix, boolean rw, final VFSIterator itr);
private static void iterateFiles(IDBDatabase db, final VirtualFilesystem vfs, final String prefix, boolean rw, final VFSIterator itr, final AsyncCallback<Integer> cb) {
IDBTransaction tx = db.transaction("filesystem", rw ? "readwrite" : "readonly");
final IDBCursorRequest r = tx.objectStore("filesystem").openCursor();
final int[] res = new int[1];
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
IDBCursor c = r.getResult();
if(c == null || c.getKey() == null || c.getValue() == null) {
cb.complete(res[0]);
return;
}
String k = readKey(c.getKey());
if(k != null) {
if(k.startsWith(prefix)) {
int ci = res[0]++;
try {
itr.next(VIteratorFile.create(ci, vfs, c));
}catch(VFSIterator.BreakLoop ex) {
cb.complete(res[0]);
return;
}
}
}
c.doContinue();
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(res[0] > 0 ? res[0] : -1);
}
});
}
@Async
protected static native Integer deleteFiles(IDBDatabase db, final String prefix);
private static void deleteFiles(IDBDatabase db, final String prefix, final AsyncCallback<Integer> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBCursorRequest r = tx.objectStore("filesystem").openCursor();
final int[] res = new int[1];
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
IDBCursor c = r.getResult();
if(c == null || c.getKey() == null || c.getValue() == null) {
cb.complete(res[0]);
return;
}
String k = readKey(c.getKey());
if(k != null) {
if(k.startsWith(prefix)) {
c.delete();
++res[0];
}
}
c.doContinue();
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(res[0] > 0 ? res[0] : -1);
}
});
}
@Async
protected static native BooleanResult fileExists(IDBDatabase db, String name);
private static void fileExists(IDBDatabase db, String name, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readonly");
final IDBCountRequest r = tx.objectStore("filesystem").count(makeTheFuckingKeyWork(name));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(r.getResult() > 0));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(false));
}
});
}
@JSBody(params = { "pat", "dat" }, script = "return { path: pat, data: dat };")
protected static native JSObject writeRow(String name, ArrayBuffer data);
@Async
protected static native BooleanResult writeWholeFile(IDBDatabase db, String name, ArrayBuffer data);
private static void writeWholeFile(IDBDatabase db, String name, ArrayBuffer data, final AsyncCallback<BooleanResult> cb) {
IDBTransaction tx = db.transaction("filesystem", "readwrite");
final IDBRequest r = tx.objectStore("filesystem").put(writeRow(name, data));
r.setOnSuccess(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(true));
}
});
r.setOnError(new EventHandler() {
@Override
public void handleEvent() {
cb.complete(BooleanResult._new(false));
}
});
}
}
public static byte[] utf8(String str) {
if(str == null) return null;
return str.getBytes(Charset.forName("UTF-8"));
}
public static String utf8(byte[] str) {
if(str == null) return null;
return new String(str, Charset.forName("UTF-8"));
}
public static String CRLFtoLF(String str) {
if(str == null) return null;
str = str.indexOf('\r') != -1 ? str.replace("\r", "") : str;
str = str.trim();
if(str.endsWith("\n")) {
str = str.substring(0, str.length() - 1);
}
if(str.startsWith("\n")) {
str = str.substring(1);
}
return str;
}
public static String[] lines(String str) {
if(str == null) return null;
return CRLFtoLF(str).split("\n");
}
}