diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/GUnityFileServer.java b/G-Earth/src/main/java/gearth/services/unity_tools/GUnityFileServer.java index 860545e..f5f4873 100644 --- a/G-Earth/src/main/java/gearth/services/unity_tools/GUnityFileServer.java +++ b/G-Earth/src/main/java/gearth/services/unity_tools/GUnityFileServer.java @@ -15,6 +15,7 @@ public class GUnityFileServer extends HttpServlet { public final static int FILESERVER_PORT = 9089; + private final static UnityWebModifyer modifyer = new UnityWebModifyer(); @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException @@ -38,11 +39,10 @@ public class GUnityFileServer extends HttpServlet String revision = url.split("/")[4]; - if (path.equals("/prod")) getProd(revision, response); - else if (path.equals("/data")) getData(revision, response); - else if (path.equals("/wasm/code")) getWasmCode(revision, response); - else if (path.equals("/wasm/framework")) getWasmFramework(revision, response); - else if (path.equals("/unityloader")) getUnityLoader(revision, response); + if (path.equals("/data")) getData(revision, response); + else if (path.equals("/wasm")) getWasmCode(revision, response); + else if (path.equals("/framework")) getWasmFramework(revision, response); + else if (path.equals("/loader")) getLoader(revision, response); else if (path.equals("/version")) getVersion(revision, response, url); else if (path.equals("/logo")) getLogo(response); else { @@ -93,29 +93,26 @@ public class GUnityFileServer extends HttpServlet } - private void getProd(String revision, HttpServletResponse response) throws IOException { - UnityWebModifyer unitywebModifyer = new UnityWebModifyer(revision, getDir(revision)); - unitywebModifyer.modifyAllFiles(); - - fileResponse(getDir(revision) + UnityWebModifyer.UNITY_PROD, response, "application/json"); - } - private void getData(String revision, HttpServletResponse response) throws IOException { - // application/vnd.unity + modifyer.modifyAllFiles(revision, getDir(revision)); + fileResponse(getDir(revision) + UnityWebModifyer.UNITY_DATA, response, "application/vnd.unity"); } private void getWasmCode(String revision, HttpServletResponse response) throws IOException { + modifyer.modifyAllFiles(revision, getDir(revision)); + fileResponse(getDir(revision) + UnityWebModifyer.UNITY_CODE, response, "application/vnd.unity"); } private void getWasmFramework(String revision, HttpServletResponse response) throws IOException { + modifyer.modifyAllFiles(revision, getDir(revision)); + fileResponse(getDir(revision) + UnityWebModifyer.UNITY_FRAMEWORK, response, "application/vnd.unity"); } - private void getUnityLoader(String revision, HttpServletResponse response) throws IOException { - UnityWebModifyer unitywebModifyer = new UnityWebModifyer(revision, getDir(revision)); - unitywebModifyer.modifyAllFiles(); + private void getLoader(String revision, HttpServletResponse response) throws IOException { + modifyer.modifyAllFiles(revision, getDir(revision)); fileResponse(getDir(revision) + UnityWebModifyer.UNITY_LOADER, response, "text/javascript"); } diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/UnityWebModifyer.java b/G-Earth/src/main/java/gearth/services/unity_tools/UnityWebModifyer.java index b1d407f..37dac28 100644 --- a/G-Earth/src/main/java/gearth/services/unity_tools/UnityWebModifyer.java +++ b/G-Earth/src/main/java/gearth/services/unity_tools/UnityWebModifyer.java @@ -13,33 +13,29 @@ import java.nio.file.Paths; public class UnityWebModifyer { - public final static String UNITY_PROD = "habbo2020-global-prod.json"; public final static String UNITY_DATA = "habbo2020-global-prod.data.unityweb"; - public final static String UNITY_CODE = "habbo2020-global-prod.wasm.code.unityweb"; - public final static String UNITY_FRAMEWORK = "habbo2020-global-prod.wasm.framework.unityweb"; - public final static String UNITY_LOADER = "UnityLoader.js"; + public final static String UNITY_CODE = "habbo2020-global-prod.wasm.gz"; + public final static String UNITY_FRAMEWORK = "habbo2020-global-prod.framework.js.gz"; + public final static String UNITY_LOADER = "habbo2020-global-prod.loader.js"; private final static String UNITYFILES_URL = "https://images.habbo.com/habbo-webgl-clients/{revision}/WebGL/habbo2020-global-prod/Build/"; - private final String revision; - private final File saveFolder; - private final String currentUrl; + private String revision; + private File saveFolder; + private String currentUrl; - public UnityWebModifyer(String revision, String saveFolder) { + public synchronized boolean modifyAllFiles(String revision, String saveFolderName) { this.revision = revision; - this.currentUrl = UNITYFILES_URL.replace("{revision}", revision); - this.saveFolder = new File(saveFolder); - } + currentUrl = UNITYFILES_URL.replace("{revision}", revision); + saveFolder = new File(saveFolderName); - public boolean modifyAllFiles() { if (saveFolder.exists()) { return true; } saveFolder.mkdirs(); try { - modifyProdFile(); modifyDataFile(); modifyCodeFile(); modifyFrameworkFile(); @@ -57,27 +53,6 @@ public class UnityWebModifyer { return true; } - // return urls for: data, code & framework file - private void modifyProdFile() throws IOException { - String prodUrl = currentUrl + UNITY_PROD; - - URLConnection connection = new URL(prodUrl).openConnection(); - InputStream is = connection.getInputStream(); - BufferedReader in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); - - FileWriter fileWriter = new FileWriter(new File(saveFolder, UNITY_PROD)); - BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); - - String line; - while ((line = in.readLine()) != null) { - bufferedWriter.write(line); - bufferedWriter.newLine(); - } - - bufferedWriter.close(); - in.close(); - } - private void downloadToFile(URL url, File file) throws IOException { BufferedInputStream in = new BufferedInputStream(url.openStream()); FileOutputStream fileOutputStream = new FileOutputStream(file); @@ -89,7 +64,7 @@ public class UnityWebModifyer { fileOutputStream.close(); in.close(); } - +// private void modifyDataFile() throws IOException { File dataFile = new File(saveFolder, UNITY_DATA); URL dataUrl = new URL(currentUrl + UNITY_DATA); diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/WasmCodePatcherOld.java b/G-Earth/src/main/java/gearth/services/unity_tools/WasmCodePatcherOld.java deleted file mode 100644 index aaef51b..0000000 --- a/G-Earth/src/main/java/gearth/services/unity_tools/WasmCodePatcherOld.java +++ /dev/null @@ -1,225 +0,0 @@ -//package gearth.services.unity_tools; -// -//import wasm.disassembly.InvalidOpCodeException; -//import wasm.disassembly.instructions.Expression; -//import wasm.disassembly.instructions.Instr; -//import wasm.disassembly.instructions.InstrType; -//import wasm.disassembly.instructions.control.CallInstr; -//import wasm.disassembly.instructions.variable.LocalVariableInstr; -//import wasm.disassembly.modules.Module; -//import wasm.disassembly.modules.indices.FuncIdx; -//import wasm.disassembly.modules.indices.LocalIdx; -//import wasm.disassembly.modules.indices.TypeIdx; -//import wasm.disassembly.modules.sections.code.Func; -//import wasm.disassembly.modules.sections.export.Export; -//import wasm.disassembly.modules.sections.export.ExportDesc; -//import wasm.disassembly.modules.sections.imprt.Import; -//import wasm.disassembly.modules.sections.imprt.ImportDesc; -//import wasm.disassembly.types.FuncType; -//import wasm.disassembly.types.ResultType; -//import wasm.disassembly.types.ValType; -//import wasm.misc.Function; -// -//import java.io.*; -//import java.util.*; -// -//public class WasmCodePatcherOld { -// -// private String file; -// -// public WasmCodePatcherOld(String file) { -// this.file = file; -// } -// -// public void patch() throws IOException, InvalidOpCodeException { -// Module module = new Module(file); -// -// FuncIdx returnByteId = findReturnByteFunc(module); -// FuncIdx setkey = findSetKeyFunc(module); -// FuncIdx outgoingIdx = findOutFunc(module); -// FuncIdx incomingIdx = findInFunc(module); -// -// hook(module, setkey, "g_chacha_setkey"); -// copyEmptyHook(module, returnByteId, "_gearth_returnbyte_copy", "g_chacha_returnbyte"); -// copyEmptyHook(module, outgoingIdx, "_gearth_outgoing_copy", "g_outgoing_packet"); -// copyEmptyHook(module, incomingIdx, "_gearth_incoming_copy", "g_incoming_packet"); -// -// module.assembleToFile(file); -// } -// -// -// private FuncIdx findOutFunc(Module module) { -// TypeIdx expectedTypeIdx = module.getTypeSection().getTypeIdxForFuncType(new FuncType( -// new ResultType(Arrays.asList(ValType.I32, ValType.I32, ValType.I32)), -// new ResultType(Collections.emptyList()) -// )); -// -// outerloop: -// for (int i = 0; i < module.getCodeSection().getCodesEntries().size(); i++) { -// FuncIdx currentIdx = new FuncIdx(i + module.getImportSection().getTotalFuncImports(), module); -// -// Func func = module.getCodeSection().getByIdx(currentIdx); -// if (func.getLocalss().size() != 0) continue; -// if (!module.getFunctionSection().getByIdx(currentIdx).equals(expectedTypeIdx)) continue; -// -// List expression = func.getExpression().getInstructions(); -// -// if (expression.size() != 6) continue; -// -// if (expression.get(0).getInstrType() != InstrType.LOCAL_GET) continue; -// if (expression.get(1).getInstrType() != InstrType.LOCAL_GET) continue; -// if (expression.get(2).getInstrType() != InstrType.LOCAL_GET) continue; -// if (expression.get(3).getInstrType() != InstrType.I32_LOAD) continue; -// if (expression.get(4).getInstrType() != InstrType.I32_CONST) continue; -// if (expression.get(5).getInstrType() != InstrType.CALL) continue; -// -// return currentIdx; -// } -// -// return null; -// } -// private FuncIdx findSetKeyFunc(Module module) { -// FuncType expectedType = new FuncType( -// new ResultType(Arrays.asList(ValType.I32, ValType.I32, ValType.I32, ValType.I32)), -// new ResultType(Collections.emptyList()) -// ); -// -// List expectedExpr = Arrays.asList(InstrType.I32_CONST, InstrType.I32_LOAD8_S, -// InstrType.I32_EQZ, InstrType.IF, InstrType.BLOCK, InstrType.LOCAL_GET, InstrType.I32_CONST, -// InstrType.LOCAL_GET, InstrType.I32_LOAD, InstrType.I32_CONST, InstrType.I32_CONST, InstrType.I32_CONST, -// InstrType.CALL); -// -// outerloop: -// for (int i = 0; i < module.getCodeSection().getCodesEntries().size(); i++) { -// FuncIdx funcIdx = new FuncIdx(i + module.getImportSection().getTotalFuncImports(), module); -// -// Function function = new Function(module, funcIdx); -// if (!function.getFuncType().equals(expectedType)) continue; -// if (!(function.getLocalsFloored().size() == 1 && function.getLocalsFloored().get(0) == ValType.I32)) continue; -// if (function.getCode().getInstructions().size() != expectedExpr.size()) continue; -// -// for (int j = 0; j < function.getCode().getInstructions().size(); j++) { -// Instr instr = function.getCode().getInstructions().get(j); -// if (instr.getInstrType() != expectedExpr.get(j)) continue outerloop; -// } -// -// return funcIdx; -// } -// -// return null; -// } -// private FuncIdx findReturnByteFunc(Module module) { -// FuncType expectedType = new FuncType( -// new ResultType(Arrays.asList(ValType.I32, ValType.I32, ValType.I32)), -// new ResultType(Collections.singletonList(ValType.I32)) -// ); -// -// outerloop: -// for (int i = 0; i < module.getCodeSection().getCodesEntries().size(); i++) { -// FuncIdx funcIdx = new FuncIdx(i + module.getImportSection().getTotalFuncImports(), module); -// -// Function function = new Function(module, funcIdx); -// if (!function.getFuncType().equals(expectedType)) continue; -// if (function.getLocalsFloored().size() != 0) continue; -// if (function.getCode().getInstructions().size() != 30) continue; -// -// List expr = function.getCode().getInstructions(); -// if (expr.get(expr.size() - 1).getInstrType() != InstrType.I32_XOR) continue; -// -// return funcIdx; -// } -// -// return null; -// } -// private FuncIdx findInFunc(Module module) { -// FuncType expectedType = new FuncType( -// new ResultType(Arrays.asList(ValType.I32, ValType.I32, ValType.I32, ValType.I32, ValType.I32)), -// new ResultType(Collections.emptyList()) -// ); -// -// List expectedExpr = Arrays.asList(InstrType.I32_CONST, InstrType.I32_LOAD8_S, -// InstrType.I32_EQZ, InstrType.IF, InstrType.LOCAL_GET, InstrType.I32_LOAD, InstrType.LOCAL_TEE, -// InstrType.IF); -// -// outerloop: -// for (int i = 0; i < module.getCodeSection().getCodesEntries().size(); i++) { -// FuncIdx funcIdx = new FuncIdx(i + module.getImportSection().getTotalFuncImports(), module); -// -// Function function = new Function(module, funcIdx); -// if (!function.getFuncType().equals(expectedType)) continue; -// if (!(function.getLocalsFloored().size() == 1 && function.getLocalsFloored().get(0) == ValType.I32)) continue; -// if (function.getCode().getInstructions().size() != expectedExpr.size()) continue; -// -// for (int j = 0; j < function.getCode().getInstructions().size(); j++) { -// Instr instr = function.getCode().getInstructions().get(j); -// if (instr.getInstrType() != expectedExpr.get(j)) continue outerloop; -// } -// -// return funcIdx; -// } -// -// return null; -// } -// -// private void copyEmptyHook(Module module, FuncIdx orgFuncIdx, String exportName, String hookname) throws InvalidOpCodeException, IOException { -// // copies the method, empties the first one -// // export the copy -// // hooks to the emptied one -// -// Func func = module.getCodeSection().getByIdx(orgFuncIdx); -// FuncType funcType = module.getTypeSection().getByFuncIdx(orgFuncIdx); -// -// // copy the function -// Function copy = new Function(funcType, func.getLocalss(), func.getExpression()); -// FuncIdx copyIdx = copy.addToModule(module); -// -// module.getExportSection().getExports().add(new Export(exportName, new ExportDesc(copyIdx))); -// -// -// // clear & hook original function, let it return whatever JS returns -// Import imp = new Import( -// "env", -// hookname, -// new ImportDesc(module.getTypeSection().getTypeIdxForFuncType(new FuncType( -// funcType.getParameterType(), -// funcType.getResultType() -// ))) -// ); -// FuncIdx hookIdx = module.getImportSection().importFunction(imp); -// -// CallInstr call = new CallInstr(hookIdx); -// List newInstrs = new ArrayList<>(); -// for (int i = 0; i < funcType.getParameterType().typeList().size(); i++) { -// newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(i))); -// } -// newInstrs.add(call); -// func.setExpression(new Expression(newInstrs)); -// -// } -// -// private void hook(Module module, FuncIdx funcIdx, String jsFunctionName) throws InvalidOpCodeException, IOException { -// FuncType funcType = module.getTypeSection().getByFuncIdx(funcIdx); -// -// Import imp = new Import( -// "env", -// jsFunctionName, -// new ImportDesc(module.getTypeSection().getTypeIdxForFuncType(new FuncType( -// funcType.getParameterType(), -// new ResultType(Collections.emptyList()) -// ))) -// ); -// FuncIdx hookIdx = module.getImportSection().importFunction(imp); -// -// CallInstr call = new CallInstr(hookIdx); -// -// Func root = module.getCodeSection().getByIdx(funcIdx); -// List newInstrs = new ArrayList<>(); -// for (int i = 0; i < funcType.getParameterType().typeList().size(); i++) { -// newInstrs.add(new LocalVariableInstr(InstrType.LOCAL_GET, new LocalIdx(i))); -// } -// newInstrs.add(call); -// newInstrs.addAll(root.getExpression().getInstructions()); -// root.getExpression().setInstructions(newInstrs); -// } -// -//}