diff --git a/src/net/PeytonPlayz585/Client.java b/src/net/PeytonPlayz585/Client.java index f8991b0..1b68331 100644 --- a/src/net/PeytonPlayz585/Client.java +++ b/src/net/PeytonPlayz585/Client.java @@ -144,10 +144,10 @@ public class Client { StringBuilder str = new StringBuilder(); str.append("Minecraft has crashed!").append('\n'); - str.append("If this has happened more than once then please copy the text on this screen and publish it in the issues feed of this fork's GitHub repository.\n\nThe URL to this fork's GitHub repository is: " + "https://github.com/PeytonPlayz595/1.2.5" + "\n\n"); + str.append("If this has happened more than once then please copy the text on this screen and publish it in the issues feed of this fork's GitHub repository.\n\nThe URL to this fork's GitHub repository is: " + "https://github.com/PeytonPlayz595/Beta-1.7.3" + "\n\n"); str.append(t); str.append('\n').append('\n'); - str.append("minecraft.version = \"1.2.5\"\n"); + str.append("minecraft.version = \"Beta 1.7.3\"\n"); str.append("minecraft.author = \"PeytonPlayz585\"\n"); str.append("minecraft.brand = \"eaglercraft\"\n"); str.append('\n'); diff --git a/src/net/PeytonPlayz585/EPKCompiler.java b/src/net/PeytonPlayz585/EPKCompiler.java new file mode 100644 index 0000000..bdd1eb0 --- /dev/null +++ b/src/net/PeytonPlayz585/EPKCompiler.java @@ -0,0 +1,61 @@ +package net.PeytonPlayz585; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.nio.charset.Charset; + +import org.lwjgl.opengl.GL11; + +import com.jcraft.jzlib.Deflater; +import com.jcraft.jzlib.DeflaterOutputStream; + +public class EPKCompiler { + + private final ByteArrayOutputStream osb; + private DataOutputStream os; + private Deflater d; + private final GL11.SHA1Digest dig = new GL11.SHA1Digest(); + + public EPKCompiler(String name, int initialSize) { + try { + osb = new ByteArrayOutputStream(initialSize); + d = new Deflater(9); + os = new DataOutputStream(osb); + os.write("EAGPKG!!".getBytes(Charset.forName("UTF-8"))); + os.writeUTF("\n\n # eaglercraft package file - " + name + "\n # eagler eagler eagler eagler eagler eagler eagler\n\n"); + d = new Deflater(9); + os = new DataOutputStream(new DeflaterOutputStream(osb, d)); + }catch(Throwable t) { + throw new RuntimeException("this happened somehow", t); + } + } + + public void append(String name, byte[] dat) { + try { + os.writeUTF(""); + os.writeUTF(name); + byte[] v = dat; + dig.update(v, 0, v.length); + byte[] final_ = new byte[20]; + dig.doFinal(final_, 0); + os.write(final_); + os.writeInt(v.length); + os.write(v); + os.writeUTF(""); + }catch(Throwable t) { + throw new RuntimeException("this happened somehow", t); + } + } + + public byte[] complete() { + try { + os.writeUTF(" end"); + os.flush(); + os.close(); + return osb.toByteArray(); + }catch(Throwable t) { + throw new RuntimeException("this happened somehow", t); + } + } + +} \ No newline at end of file diff --git a/src/net/PeytonPlayz585/EPKDecompiler.java b/src/net/PeytonPlayz585/EPKDecompiler.java new file mode 100644 index 0000000..a5e9880 --- /dev/null +++ b/src/net/PeytonPlayz585/EPKDecompiler.java @@ -0,0 +1,63 @@ +package net.PeytonPlayz585; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; + +import org.lwjgl.opengl.GL11; + +import com.jcraft.jzlib.InflaterInputStream; + +public class EPKDecompiler { + + public static class FileEntry { + public final String name; + public final byte[] data; + protected FileEntry(String name, byte[] data) { + this.name = name; + this.data = data; + } + } + + private final ByteArrayInputStream in2; + private DataInputStream in; + private GL11.SHA1Digest dg = new GL11.SHA1Digest(); + private boolean isFinished = false; + + public EPKDecompiler(byte[] data) throws IOException { + in2 = new ByteArrayInputStream(data); + in = new DataInputStream(in2); + byte[] header = new byte[8]; + in.read(header); + if(!"EAGPKG!!".equals(new String(header, Charset.forName("UTF-8")))) throw new IOException("invalid epk file"); + in.readUTF(); + in = new DataInputStream(new InflaterInputStream(in2)); + } + + public FileEntry readFile() throws IOException { + if(isFinished) { + return null; + } + String s = in.readUTF(); + if(s.equals(" end")) { + isFinished = true; + return null; + }else if(!s.equals("")) { + throw new IOException("invalid epk file"); + } + String path = in.readUTF(); + byte[] digest = new byte[20]; + byte[] digest2 = new byte[20]; + in.read(digest); + int len = in.readInt(); + byte[] file = new byte[len]; + in.read(file); + dg.update(file, 0, len); dg.doFinal(digest2, 0); + if(!Arrays.equals(digest, digest2)) throw new IOException("invalid file hash for "+path); + if(!"".equals(in.readUTF())) throw new IOException("invalid epk file"); + return new FileEntry(path, file); + } + +} \ No newline at end of file diff --git a/src/net/PeytonPlayz585/GuiSomethingFailed.java b/src/net/PeytonPlayz585/GuiSomethingFailed.java new file mode 100644 index 0000000..6bcc08e --- /dev/null +++ b/src/net/PeytonPlayz585/GuiSomethingFailed.java @@ -0,0 +1,41 @@ +package net.PeytonPlayz585; + +import net.minecraft.src.GuiButton; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.StringTranslate; + +public class GuiSomethingFailed extends GuiScreen { + + private final String title; + private final String[] description; + private final GuiScreen cont; + + public GuiSomethingFailed(GuiScreen cont, String title, String... description) { + this.cont = cont; + this.title = title; + this.description = description; + } + + public void initGui() { + controlList.add(new GuiButton(0, (width - 200) / 2, height / 4 + 32 + description.length * 10, StringTranslate.getInstance().translateKey("gui.cancel"))); + } + + public void drawScreen(int i, int j, float f) { + drawDefaultBackground(); + int h = height / 4; + drawCenteredString(fontRenderer, title, width / 2, h, 0xffffff); + h += 16; + for(String s : description) { + drawCenteredString(fontRenderer, s, width / 2, h, 0xffcccc); + h += 10; + } + super.drawScreen(i, j, f); + } + + public void actionPerformed(GuiButton bnt) { + if(bnt.id == 0) { + mc.displayGuiScreen(cont); + } + } + +} \ No newline at end of file diff --git a/src/net/PeytonPlayz585/ImportExport.java b/src/net/PeytonPlayz585/ImportExport.java new file mode 100644 index 0000000..ab7c16a --- /dev/null +++ b/src/net/PeytonPlayz585/ImportExport.java @@ -0,0 +1,207 @@ +package net.PeytonPlayz585; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.function.Consumer; + +import org.lwjgl.opengl.GL11; + +import net.PeytonPlayz585.fileutils.File; +import net.PeytonPlayz585.fileutils.FileEntry; +import net.PeytonPlayz585.fileutils.FilesystemUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.src.IProgressUpdate; +import net.minecraft.src.NBTBase; +import net.minecraft.src.NBTTagCompound; + +public class ImportExport { + + private static IProgressUpdate prog = null; + private static String progressTitle = null; + private static long lastProgressUpdate = 0l; + + public static String importWorld(IProgressUpdate loadingScreen, byte[] data, String fileName) { + progressTitle = "Importing World"; + prog = loadingScreen; + lastProgressUpdate = System.currentTimeMillis(); + loadingScreen.displayLoadingString("Importing World", "(please wait)"); + //GL11.EaglerAdapterImpl2.openFileChooser("epk", "application/epk"); + +// byte[] loaded; +// while((loaded = GL11.EaglerAdapterImpl2.getFileChooserResult()) == null) { +// long t = System.currentTimeMillis(); +// if(t - lastProgressUpdate < 100l) { +// continue; +// } +// lastProgressUpdate = t; +// loadingScreen.displayLoadingString("Importing World", "(please wait)"); +// } + + if(data == null || data.length == 0) { + return "$cancelled$"; + } + + String name = fileName; + name = name.replaceAll("[^A-Za-z0-9\\-_]", "_").trim(); + + while(File.exists(Minecraft.getMinecraft().getSaveDir() + "/saves/" + name)) { + name = "_" + name; + } + + loadingScreen.displayLoadingString("Importing World", "Extracting EPK"); + + try { + EPKDecompiler loader = new EPKDecompiler(data); + int counter = 0; + EPKDecompiler.FileEntry f; + while((f = loader.readFile()) != null) { + File.writeFile(Minecraft.getMinecraft().getSaveDir() + "/saves/" + name + "/" + f.name, f.data); + counter += f.data.length; + progress(counter); + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + + try { + System.out.println(); + NBTBase b = NBTBase.readTag(new DataInputStream(new ByteArrayInputStream(File.readFile(Minecraft.getMinecraft().getSaveDir() + "/saves/" + name + "/level.dat")))); + if(!(b instanceof NBTTagCompound)) { + throw new IOException("NBT in saves/" + name + "/level.dat is corrupt!"); + } + }catch(IOException e) { + e.printStackTrace(); + System.err.println("The folder 'saves/" + name + "/' will be deleted"); + FilesystemUtils.recursiveDeleteDirectory(Minecraft.getMinecraft().getSaveDir() + "/saves/" + name); + } + + return name; + } + + public static void renameImportedWorld(String name, String displayName) { + byte[] lvl = File.readFile(Minecraft.getMinecraft().getSaveDir() + "/saves/" + name + "/level.dat"); + if(lvl != null) { + try { + NBTBase nbt = NBTBase.readTag(new DataInputStream(new ByteArrayInputStream(lvl))); + if(nbt instanceof NBTTagCompound) { + NBTTagCompound w = (NBTTagCompound)nbt; + w.setString("LevelName", displayName); + ByteArrayOutputStream out = new ByteArrayOutputStream(lvl.length + 16 + displayName.length() * 2); // should be large enough + NBTBase.writeTag(w, new DataOutputStream(out)); + File.writeFile(Minecraft.getMinecraft().getSaveDir() + "/saves/" + name + "/level.dat", out.toByteArray()); + }else { + throw new IOException("file 'saves/" + name + "/level.dat' does not contain an NBTTagCompound"); + } + }catch(IOException e) { + System.err.println("Failed to modify world data for 'saves/" + name + "/level.dat'"); + System.err.println("It will be kept for future recovery"); + e.printStackTrace(); + } + } + } + + public static boolean exportWorld(IProgressUpdate loadingScreen, String name, String downloadName) { + progressTitle = "Exporting World"; + prog = loadingScreen; + loadingScreen.displayLoadingString("Exporting World", "(please wait)"); + + if(name.contains("saves/")) { + name = name.replace("saves/", ""); + } + + if(!File.exists(Minecraft.getMinecraft().getSaveDir() + "/saves/" + name + "/level.dat")) { + System.err.println("world " + name + " does not exist!"); + return false; + } + + int size = 0; + String dir = Minecraft.getMinecraft().getSaveDir() + "/saves/" + name; + + try { + EPKCompiler comp = new EPKCompiler(dir, 409600000); + Collection lst = File.listFilesRecursive(dir); + Iterator itr = lst.iterator(); + while(itr.hasNext()) { + FileEntry t = itr.next(); + if(t.path.startsWith(dir + "/")) { + byte[] dat = File.readFile(t.path); + if(dat != null) { + String fn = t.path.substring(dir.length() + 1); + comp.append(fn, dat); + size += dat.length; + progress(size); + } + } + } + loadingScreen.displayLoadingString("Exporting World", "finishing..."); + GL11.EaglerAdapterImpl2.downloadFile(downloadName, comp.complete()); + return true; + }catch(Throwable t) { + System.err.println("Export of '" + name + "' failed!"); + t.printStackTrace(); + return false; + } + +// try { +// EPKCompiler comp = new EPKCompiler(dir, 409600000); +// Collection lst = File.listFilesAndDirectories(dir); +// Iterator itr = lst.iterator(); +// while(itr.hasNext()) { +// FileEntry t = itr.next(); +// if(t.path.startsWith(dir + "/")) { +// byte[] dat = File.readFile(t.path); +// if(dat != null) { +// String fn = t.path.substring(dir.length() + 1); +// comp.append(fn, dat); +// size += dat.length; +// progress(size); +// System.out.println(t.path); +// } +// } +// } +// loadingScreen.displayLoadingString("Exporting World", "finishing..."); +// GL11.EaglerAdapterImpl2.downloadFile(downloadName, comp.complete()); +// return true; +// }catch(Throwable t) { +// System.err.println("Export of '" + name + "' failed!"); +// t.printStackTrace(); +// return false; +// } + + } + + private static void progress(int p) { + long t = System.currentTimeMillis(); + if(t - lastProgressUpdate < 100l) { + return; + } + lastProgressUpdate = t; + String s; + if(p < 1000) { + s = "" + p + " B"; + }else if(p < 1000000) { + s = "" + formatFloat(p / 1000f) + " kB"; + }else { + s = "" + formatFloat(p / 1000000f) + " MB"; + } + prog.displayLoadingString(progressTitle, s); + } + + private static String formatFloat(float f) { + String ret = Float.toString(f); + int idx = ret.indexOf('.'); + if(ret.length() >= (idx + 3)) { + ret = ret.substring(0, idx + 3); + } + return ret; + } + +} diff --git a/src/net/PeytonPlayz585/fileutils/FileChooserResult.java b/src/net/PeytonPlayz585/fileutils/FileChooserResult.java new file mode 100644 index 0000000..cbf0b21 --- /dev/null +++ b/src/net/PeytonPlayz585/fileutils/FileChooserResult.java @@ -0,0 +1,13 @@ +package net.PeytonPlayz585.fileutils; + +public class FileChooserResult { + + public final String fileName; + public final byte[] fileData; + + public FileChooserResult(String fileName, byte[] fileData) { + this.fileName = fileName; + this.fileData = fileData; + } + +} \ No newline at end of file diff --git a/src/net/PeytonPlayz585/fileutils/FilesystemUtils.java b/src/net/PeytonPlayz585/fileutils/FilesystemUtils.java index ea7b456..051660c 100644 --- a/src/net/PeytonPlayz585/fileutils/FilesystemUtils.java +++ b/src/net/PeytonPlayz585/fileutils/FilesystemUtils.java @@ -16,7 +16,10 @@ public class FilesystemUtils { File.deleteFile(t.path); } } - File.deleteFile(dir); + + + //Why THE FUCK was this even here in the first place + //File.deleteFile(dir); } } \ No newline at end of file diff --git a/src/net/minecraft/client/Minecraft.java b/src/net/minecraft/client/Minecraft.java index 7c880d7..d296df4 100644 --- a/src/net/minecraft/client/Minecraft.java +++ b/src/net/minecraft/client/Minecraft.java @@ -61,6 +61,7 @@ import net.minecraft.src.RenderEngine; import net.minecraft.src.RenderGlobal; import net.minecraft.src.RenderManager; import net.minecraft.src.ScaledResolution; +import net.minecraft.src.ScreenShotHelper; import net.minecraft.src.Session; import net.minecraft.src.SoundManager; import net.minecraft.src.StatFileWriter; @@ -242,6 +243,10 @@ public class Minecraft implements Runnable { var9.addVertexWithUV((double)(var1 + 0), (double)(var2 + 0), 0.0D, (double)((float)(var3 + 0) * var7), (double)((float)(var4 + 0) * var8)); var9.draw(); } + + public String getSaveDir() { + return this.minecraftDir; + } public ISaveFormat getSaveLoader() { return this.saveLoader; @@ -777,20 +782,24 @@ public class Minecraft implements Runnable { if(Keyboard.getEventKey() == 1) { this.displayInGameMenu(); } - - if(Keyboard.getEventKey() == 33 && Keyboard.isKeyDown(2)) { + + if(Keyboard.isFunctionKeyDown(this.gameSettings.keyBindToggleFog.keyCode, 2)) { this.gameSettings.hideGUI = !this.gameSettings.hideGUI; } - - if(Keyboard.getEventKey() == 33 && Keyboard.isKeyDown(4)) { + + if(Keyboard.isFunctionKeyDown(this.gameSettings.keyBindToggleFog.keyCode, 3)) { + this.ingameGUI.addChatMessage(ScreenShotHelper.saveScreenshot()); + } + + if(Keyboard.isFunctionKeyDown(this.gameSettings.keyBindToggleFog.keyCode, 4)) { this.gameSettings.showDebugInfo = !this.gameSettings.showDebugInfo; } - - if(Keyboard.getEventKey() == 33 && Keyboard.isKeyDown(6)) { + + if(Keyboard.isFunctionKeyDown(this.gameSettings.keyBindToggleFog.keyCode, 6)) { this.gameSettings.thirdPersonView = !this.gameSettings.thirdPersonView; } - - if(Keyboard.getEventKey() == 33 && Keyboard.isKeyDown(9)) { + + if(Keyboard.isFunctionKeyDown(this.gameSettings.keyBindToggleFog.keyCode, 9)) { this.gameSettings.smoothCamera = !this.gameSettings.smoothCamera; } @@ -808,14 +817,15 @@ public class Minecraft implements Runnable { } for(int var6 = 0; var6 < 9; ++var6) { - if(Keyboard.getEventKey() == 2 + var6) { + if(Keyboard.getEventKey() == 2 + var6 && !Keyboard.isKeyDown(this.gameSettings.keyBindToggleFog.keyCode)) { this.thePlayer.inventory.currentItem = var6; } } - if(Keyboard.getEventKey() == this.gameSettings.keyBindToggleFog.keyCode) { - this.gameSettings.setOptionValue(EnumOptions.RENDER_DISTANCE, !Keyboard.isKeyDown(42) && !Keyboard.isKeyDown(54) ? 1 : -1); - } + //rip + //if(Keyboard.getEventKey() == this.gameSettings.keyBindToggleFog.keyCode) { + //this.gameSettings.setOptionValue(EnumOptions.RENDER_DISTANCE, !Keyboard.isKeyDown(42) && !Keyboard.isKeyDown(54) ? 1 : -1); + //} } } } diff --git a/src/net/minecraft/src/EaglerSaveFormat.java b/src/net/minecraft/src/EaglerSaveFormat.java index d96b245..fd6da38 100644 --- a/src/net/minecraft/src/EaglerSaveFormat.java +++ b/src/net/minecraft/src/EaglerSaveFormat.java @@ -13,6 +13,7 @@ import java.util.function.Consumer; import net.PeytonPlayz585.fileutils.File; import net.PeytonPlayz585.fileutils.FileEntry; +import net.PeytonPlayz585.fileutils.FilesystemUtils; public class EaglerSaveFormat implements ISaveFormat { diff --git a/src/net/minecraft/src/FilesystemUtils.java b/src/net/minecraft/src/FilesystemUtils.java index 290af3b..1a11837 100644 --- a/src/net/minecraft/src/FilesystemUtils.java +++ b/src/net/minecraft/src/FilesystemUtils.java @@ -1,25 +1,25 @@ -package net.minecraft.src; - -import java.util.Collection; - -import net.PeytonPlayz585.fileutils.File; -import net.PeytonPlayz585.fileutils.FileEntry; - -public class FilesystemUtils { - - public static void recursiveDeleteDirectory(String dir) { - Collection lst = File.listFiles(dir, true, true); - for(FileEntry t : lst) { - if(!t.isDirectory) { - File.deleteFile(t.path); - } - } - for(FileEntry t : lst) { - if(t.isDirectory) { - File.deleteFile(t.path); - } - } - File.deleteFile(dir); - } - -} +//package net.minecraft.src; +// +//import java.util.Collection; +// +//import net.PeytonPlayz585.fileutils.File; +//import net.PeytonPlayz585.fileutils.FileEntry; +// +//public class FilesystemUtils { +// +// public static void recursiveDeleteDirectory(String dir) { +// Collection lst = File.listFiles(dir, true, true); +// for(FileEntry t : lst) { +// if(!t.isDirectory) { +// File.deleteFile(t.path); +// } +// } +// for(FileEntry t : lst) { +// if(t.isDirectory) { +// File.deleteFile(t.path); +// } +// } +// File.deleteFile(dir); +// } +// +//} diff --git a/src/net/minecraft/src/GameSettings.java b/src/net/minecraft/src/GameSettings.java index 996af1d..0ff4530 100644 --- a/src/net/minecraft/src/GameSettings.java +++ b/src/net/minecraft/src/GameSettings.java @@ -36,7 +36,7 @@ public class GameSettings { public KeyBinding keyBindInventory = new KeyBinding("key.inventory", 18); public KeyBinding keyBindDrop = new KeyBinding("key.drop", 16); public KeyBinding keyBindChat = new KeyBinding("key.chat", 20); - public KeyBinding keyBindToggleFog = new KeyBinding("key.fog", 33); + public KeyBinding keyBindToggleFog = new KeyBinding("Function", 33); public KeyBinding keyBindSneak = new KeyBinding("key.sneak", 42); public KeyBinding[] keyBindings = new KeyBinding[]{this.keyBindForward, this.keyBindLeft, this.keyBindBack, this.keyBindRight, this.keyBindJump, this.keyBindSneak, this.keyBindDrop, this.keyBindInventory, this.keyBindChat, this.keyBindToggleFog}; protected Minecraft mc; diff --git a/src/net/minecraft/src/GuiCreateOrImport.java b/src/net/minecraft/src/GuiCreateOrImport.java new file mode 100644 index 0000000..31620db --- /dev/null +++ b/src/net/minecraft/src/GuiCreateOrImport.java @@ -0,0 +1,84 @@ +package net.minecraft.src; + +import java.util.function.Consumer; + +import org.lwjgl.opengl.GL11; + +import net.PeytonPlayz585.GuiSomethingFailed; +import net.PeytonPlayz585.ImportExport; +import net.PeytonPlayz585.fileutils.FileChooserResult; +import net.minecraft.src.GuiButton; +import net.minecraft.src.GuiCreateWorld; +import net.minecraft.src.GuiScreen; +import net.minecraft.src.PlayerControllerSP; +import net.minecraft.src.StringTranslate; + +public class GuiCreateOrImport extends GuiScreen { + + private final GuiScreen parent; + private String title; + + public GuiCreateOrImport(GuiScreen parent) { + this.parent = parent; + this.title = StringTranslate.getInstance().translateKey("What do you want to do?"); + } + + public void initGui() { + StringTranslate st = StringTranslate.getInstance(); + controlList.add(new GuiButton(0, (width - 200) / 2, height / 3 + 5, st.translateKey("selectWorld.create"))); + controlList.add(new GuiButton(1, (width - 200) / 2, height / 3 + 29, st.translateKey("Import Existing World"))); + controlList.add(new GuiButton(2, (width - 200) / 2, height / 3 + 53, st.translateKey("gui.cancel"))); + } + + protected void actionPerformed(GuiButton guibutton) { + if(guibutton.id == 0) { + mc.displayGuiScreen(new GuiCreateWorld(parent)); + }else if(guibutton.id == 1) { + GL11.EaglerAdapterImpl2.displayFileChooser("epk", "application/epk"); +// final String folder = ImportExport.importWorld(mc.loadingScreen); +// if(folder == null) { +// mc.displayGuiScreen(new GuiSomethingFailed(parent, "Import Failed", "the world is incompatible or corrupt", "maybe use an EPK decompiler to debug")); +// }else if(folder.equals("$cancelled$")) { +// mc.displayGuiScreen(parent); +// }else { +// mc.displayGuiScreen(new GuiWhatDoYouWantToName(folder, new Consumer() { +// @Override +// public void accept(String str) { +// ImportExport.renameImportedWorld(folder, str); +// mc.playerController = new PlayerControllerSP(mc); +// mc.startWorld(folder, str, 0l); +// mc.displayGuiScreen(null); +// } +// })); +// } + }else if(guibutton.id == 2) { + mc.displayGuiScreen(parent); + } + } + + public void drawScreen(int i, int j, float f) { + drawDefaultBackground(); + drawCenteredString(fontRenderer, title, width / 2, height / 4, 0xffffff); + super.drawScreen(i, j, f); + + if(GL11.EaglerAdapterImpl2.fileChooserHasResult()) { + FileChooserResult result = GL11.EaglerAdapterImpl2.getFileChooserResult(); + final String folder = ImportExport.importWorld(mc.loadingScreen, result.fileData, result.fileName); + if(folder == null) { + mc.displayGuiScreen(new GuiSomethingFailed(parent, "Import Failed", "the world is incompatible or corrupt", "maybe use an EPK decompiler to debug")); + }else if(folder.equals("$cancelled$")) { + mc.displayGuiScreen(parent); + }else { + mc.displayGuiScreen(new GuiWhatDoYouWantToName(folder, new Consumer() { + @Override + public void accept(String str) { + ImportExport.renameImportedWorld(folder, str); + mc.playerController = new PlayerControllerSP(mc); + mc.startWorld(folder, str, 0l); + mc.displayGuiScreen(null); + } + })); + } + } + } +} \ No newline at end of file diff --git a/src/net/minecraft/src/GuiSelectWorld.java b/src/net/minecraft/src/GuiSelectWorld.java index 6a182c4..b3ea6cd 100644 --- a/src/net/minecraft/src/GuiSelectWorld.java +++ b/src/net/minecraft/src/GuiSelectWorld.java @@ -5,6 +5,9 @@ import java.text.SimpleDateFormat; import java.util.Collections; import java.util.List; +import net.PeytonPlayz585.GuiSomethingFailed; +import net.PeytonPlayz585.ImportExport; + public class GuiSelectWorld extends GuiScreen { private final DateFormat dateFormatter = new SimpleDateFormat(); protected GuiScreen parentScreen; @@ -19,6 +22,7 @@ public class GuiSelectWorld extends GuiScreen { private GuiButton buttonRename; private GuiButton buttonSelect; private GuiButton buttonDelete; + private GuiButton export; public GuiSelectWorld(GuiScreen var1) { this.parentScreen = var1; @@ -62,10 +66,12 @@ public class GuiSelectWorld extends GuiScreen { this.controlList.add(this.buttonRename = new GuiButton(6, this.width / 2 - 154, this.height - 28, 70, 20, var1.translateKey("selectWorld.rename"))); this.controlList.add(this.buttonDelete = new GuiButton(2, this.width / 2 - 74, this.height - 28, 70, 20, var1.translateKey("selectWorld.delete"))); this.controlList.add(new GuiButton(3, this.width / 2 + 4, this.height - 52, 150, 20, var1.translateKey("selectWorld.create"))); - this.controlList.add(new GuiButton(0, this.width / 2 + 4, this.height - 28, 150, 20, var1.translateKey("gui.cancel"))); + this.controlList.add(export = new GuiButton(3000, this.width / 2 + 4, this.height - 28, 70, 20, var1.translateKey("Export"))); + this.controlList.add(new GuiButton(0, this.width / 2 + 84, this.height - 28, 70, 20, var1.translateKey("gui.cancel"))); this.buttonSelect.enabled = false; this.buttonRename.enabled = false; this.buttonDelete.enabled = false; + this.export.enabled = false; } protected void actionPerformed(GuiButton var1) { @@ -85,11 +91,20 @@ public class GuiSelectWorld extends GuiScreen { } else if(var1.id == 1) { this.selectWorld(this.selectedWorld); } else if(var1.id == 3) { - this.mc.displayGuiScreen(new GuiCreateWorld(this)); + mc.displayGuiScreen(new GuiCreateOrImport(this)); } else if(var1.id == 6) { this.mc.displayGuiScreen(new GuiRenameWorld(this, this.getSaveFileName(this.selectedWorld))); } else if(var1.id == 0) { this.mc.displayGuiScreen(this.parentScreen); + } else if(var1.id == 3000) { + String var2 = this.getSaveFileName(selectedWorld); + if(var2 != null) { + if(!ImportExport.exportWorld(mc.loadingScreen, getSaveFileName(this.selectedWorld), getSaveName(this.selectedWorld) + ".epk")) { + mc.displayGuiScreen(new GuiSomethingFailed(this, "Export Failed", "An exception was encountered while exporting '" + getSaveFileName(this.selectedWorld) + "'", "Check the game's console")); + }else { + mc.displayGuiScreen(this); + } + } } else { this.worldSlotContainer.actionPerformed(var1); } @@ -156,6 +171,10 @@ public class GuiSelectWorld extends GuiScreen { static GuiButton getDeleteButton(GuiSelectWorld var0) { return var0.buttonDelete; } + + static GuiButton getExportButton(GuiSelectWorld var0) { + return var0.export; + } static String func_22087_f(GuiSelectWorld var0) { return var0.field_22098_o; diff --git a/src/net/minecraft/src/GuiWhatDoYouWantToName.java b/src/net/minecraft/src/GuiWhatDoYouWantToName.java new file mode 100644 index 0000000..d392ea2 --- /dev/null +++ b/src/net/minecraft/src/GuiWhatDoYouWantToName.java @@ -0,0 +1,50 @@ +package net.minecraft.src; + +import java.util.function.Consumer; + +public class GuiWhatDoYouWantToName extends GuiScreen { + + private final Consumer cont; + private final String defaultName; + private final String title; + private GuiTextField nameField; + + public GuiWhatDoYouWantToName(String defaultName, Consumer cont) { + this.defaultName = defaultName; + this.cont = cont; + this.title = StringTranslate.getInstance().translateKey("What do you want to name this world?"); + } + + public void initGui() { + nameField = new GuiTextField(this, fontRenderer, width / 2 - 100, height / 3, 200, 20, defaultName); + controlList.add(new GuiButton(0, (width - 200) / 2, height / 3 + 35, StringTranslate.getInstance().translateKey("gui.done"))); + } + + public void drawScreen(int i, int j, float f) { + drawDefaultBackground(); + drawCenteredString(fontRenderer, title, width / 2, height / 4, 0xFFFFFF); + nameField.drawTextBox(); + super.drawScreen(i, j, f); + } + + public void actionPerformed(GuiButton bnt) { + if(bnt.id == 0) { + String s = nameField.getText(); + if (MathHelper.stringNullOrLengthZero(s)) { + s = defaultName; + } + cont.accept(s); + } + } + + protected void keyTyped(char c, int i) { + super.keyTyped(c, i); + nameField.textboxKeyTyped(c, i); + } + + protected void mouseClicked(int i, int j, int k) { + super.mouseClicked(i, j, k); + nameField.mouseClicked(i, j, k); + } + +} \ No newline at end of file diff --git a/src/net/minecraft/src/GuiWorldSlot.java b/src/net/minecraft/src/GuiWorldSlot.java index 8c4fe4f..c9ae3c1 100644 --- a/src/net/minecraft/src/GuiWorldSlot.java +++ b/src/net/minecraft/src/GuiWorldSlot.java @@ -20,6 +20,7 @@ class GuiWorldSlot extends GuiSlot { GuiSelectWorld.getSelectButton(this.parentWorldGui).enabled = var3; GuiSelectWorld.getRenameButton(this.parentWorldGui).enabled = var3; GuiSelectWorld.getDeleteButton(this.parentWorldGui).enabled = var3; + GuiSelectWorld.getExportButton(this.parentWorldGui).enabled = var3; if(var2 && var3) { this.parentWorldGui.selectWorld(var1); } diff --git a/src/net/minecraft/src/IProgressUpdate.java b/src/net/minecraft/src/IProgressUpdate.java index df867cb..2bd5194 100644 --- a/src/net/minecraft/src/IProgressUpdate.java +++ b/src/net/minecraft/src/IProgressUpdate.java @@ -6,4 +6,6 @@ public interface IProgressUpdate { void displayLoadingString(String var1); void setLoadingProgress(int var1); + + void displayLoadingString(String string, String string2); } diff --git a/src/net/minecraft/src/LoadingScreenRenderer.java b/src/net/minecraft/src/LoadingScreenRenderer.java index 5270d3d..b214553 100644 --- a/src/net/minecraft/src/LoadingScreenRenderer.java +++ b/src/net/minecraft/src/LoadingScreenRenderer.java @@ -43,6 +43,23 @@ public class LoadingScreenRenderer implements IProgressUpdate { GL11.glTranslatef(0.0F, 0.0F, -200.0F); } } + + public void displayLoadingString(String s, String s1) { + if (!mc.running) { + if (field_1005_e) { + return; + } else { + throw new MinecraftError(); + } + } else { + field_1006_d = 0L; + field_1004_a = s1; + field_1007_c = s; + setLoadingProgress(-1); + field_1006_d = 0L; + return; + } + } public void displayLoadingString(String var1) { if(!this.mc.running) { diff --git a/src/net/minecraft/src/ScreenShotHelper.java b/src/net/minecraft/src/ScreenShotHelper.java new file mode 100644 index 0000000..51fde99 --- /dev/null +++ b/src/net/minecraft/src/ScreenShotHelper.java @@ -0,0 +1,11 @@ +package net.minecraft.src; + +import org.lwjgl.opengl.GL11; + +public class ScreenShotHelper { + + public static String saveScreenshot() { + return "Saved screenshot as " + GL11.EaglerAdapterImpl2.saveScreenshot(); + } + +} diff --git a/src/org/lwjgl/input/Keyboard.java b/src/org/lwjgl/input/Keyboard.java index 941a240..55861e8 100644 --- a/src/org/lwjgl/input/Keyboard.java +++ b/src/org/lwjgl/input/Keyboard.java @@ -42,5 +42,9 @@ public class Keyboard { public static char getEventCharacter() { return GL11.EaglerAdapterImpl2.getEventChar(); } + + public static boolean isFunctionKeyDown(int p1, int p2) { + return isKeyDown(p1) && getEventKey() == p2; + } } diff --git a/src/org/lwjgl/opengl/GL11.java b/src/org/lwjgl/opengl/GL11.java index 5d60295..efb391a 100644 --- a/src/org/lwjgl/opengl/GL11.java +++ b/src/org/lwjgl/opengl/GL11.java @@ -30,6 +30,7 @@ import org.teavm.interop.AsyncCallback; import org.teavm.jso.JSBody; import org.teavm.jso.JSFunctor; import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; import org.teavm.jso.ajax.ReadyStateChangeHandler; import org.teavm.jso.ajax.XMLHttpRequest; import org.teavm.jso.browser.Storage; @@ -49,7 +50,9 @@ import org.teavm.jso.dom.html.HTMLCanvasElement; import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLElement; import org.teavm.jso.dom.html.HTMLImageElement; +import org.teavm.jso.dom.html.HTMLInputElement; import org.teavm.jso.typedarrays.ArrayBuffer; +import org.teavm.jso.typedarrays.ArrayBufferView; import org.teavm.jso.typedarrays.DataView; import org.teavm.jso.typedarrays.Float32Array; import org.teavm.jso.typedarrays.Int32Array; @@ -82,6 +85,7 @@ import com.jcraft.jzlib.InflaterInputStream; import net.PeytonPlayz585.Client; import net.PeytonPlayz585.awt.image.BufferedImage; import net.PeytonPlayz585.awt.image.ImageIO; +import net.PeytonPlayz585.fileutils.FileChooserResult; import net.PeytonPlayz585.glemu.FixedFunctionShader; import net.PeytonPlayz585.glemu.StreamBuffer; import net.PeytonPlayz585.glemu.StreamBuffer.StreamBufferInstance; @@ -1227,6 +1231,8 @@ public class GL11 implements JSObject { } public static final void glPolygonOffset(float p1, float p2) { + p1 = -p1; + p2 = -p2; if(p1 != polygonOffset1 || p2 != polygonOffset2) { _wglPolygonOffset(p1, p2); polygonOffset1 = p1; @@ -5533,7 +5539,7 @@ public class GL11 implements JSObject { cc.setFillStyle("black"); cc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); cc.drawImage(canvas, 0, 0, canvas.getWidth(), canvas.getHeight()); - String s = "screenshot_" + dateFormatSS.format(new Date()).toString() + ".png"; + String s = "" + dateFormatSS.format(new Date()) + ".png"; saveScreenshot(s, retardedCanvas); return s; } @@ -5944,6 +5950,91 @@ public class GL11 implements JSObject { }catch(Throwable t) { } } + + @JSBody(params = { "name", "cvs" }, script = "var a=document.createElement(\"a\");a.href=URL.createObjectURL(new Blob([cvs],{type:\"application/octet-stream\"}));a.download=name;a.click();URL.revokeObjectURL(a.href);") + private static native void downloadFile0(String name, ArrayBuffer cvs); + + public static final void downloadFile(String filename, byte[] data) { + Uint8Array b = Uint8Array.create(data.length); + b.set(data); + downloadFile0(filename, b.getBuffer()); + } + + @JSFunctor + private static interface FileChooserCallback extends JSObject { + void accept(String name, ArrayBuffer buffer); + } + + private static class FileChooserCallbackImpl implements FileChooserCallback { + + private static final FileChooserCallbackImpl instance = new FileChooserCallbackImpl(); + + @Override + public void accept(String name, ArrayBuffer buffer) { + fileChooserHasResult = true; + if(name == null) { + fileChooserResultObject = null; + }else { + fileChooserResultObject = new FileChooserResult(name, TeaVMUtils.wrapUnsignedByteArray(Uint8Array.create(buffer))); + } + } + + } + + private static volatile boolean fileChooserHasResult = false; + private static volatile FileChooserResult fileChooserResultObject = null; + + @JSBody(params = { "inputElement", "callback" }, script = + "if(inputElement.files.length > 0) {" + + "const value = inputElement.files[0];" + + "value.arrayBuffer().then(function(arr){ callback(value.name, arr); })" + + ".catch(function(){ callback(null, null); });" + + "} else callback(null, null);") + private static native void getFileChooserResult(HTMLInputElement inputElement, FileChooserCallback callback); + + @JSBody(params = { "inputElement", "value" }, script = "inputElement.accept = value;") + private static native void setAcceptSelection(HTMLInputElement inputElement, String value); + + @JSBody(params = { "inputElement", "enable" }, script = "inputElement.multiple = enable;") + private static native void setMultipleSelection(HTMLInputElement inputElement, boolean enable); + + public static void displayFileChooser(String ext, String mime) { + final HTMLInputElement inputElement = (HTMLInputElement) Window.current().getDocument().createElement("input"); + inputElement.setType("file"); + if(mime == null) { + setAcceptSelection(inputElement, "." + ext); + }else { + setAcceptSelection(inputElement, mime); + } + setMultipleSelection(inputElement, false); + inputElement.addEventListener("change", new EventListener() { + @Override + public void handleEvent(Event evt) { + getFileChooserResult(inputElement, FileChooserCallbackImpl.instance); + } + }); + inputElement.click(); + } + + public static boolean fileChooserHasResult() { + return fileChooserHasResult; + } + + public static FileChooserResult getFileChooserResult() { + fileChooserHasResult = false; + FileChooserResult res = fileChooserResultObject; + fileChooserResultObject = null; + return res; + } + + private static class TeaVMUtils { + @JSBody(params = { "buf" }, script = "return $rt_createByteArray(buf.buffer)") + private static native JSObject wrapByteArray0(JSObject buf); + + public static byte[] wrapUnsignedByteArray(Uint8Array buf) { + return (byte[])(Object)wrapByteArray0(buf); + } + } } @@ -6133,7 +6224,7 @@ public class GL11 implements JSObject { } @SuppressWarnings("unused") - private static class SHA1Digest extends GeneralDigest { + public static class SHA1Digest extends GeneralDigest { private static final int DIGEST_LENGTH = 20; private int H1, H2, H3, H4, H5;