mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-23 08:50:52 +01:00
unity local fileserver
This commit is contained in:
parent
1ad3a52c33
commit
a29b620579
@ -1,4 +0,0 @@
|
|||||||
package gearth.services.g_chrome_tools;
|
|
||||||
|
|
||||||
public class UnityFileServer {
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
package gearth.services.g_chrome_tools;
|
|
||||||
|
|
||||||
public class UnitywebModifyer {
|
|
||||||
}
|
|
@ -0,0 +1,150 @@
|
|||||||
|
package gearth.services.unity_tools;
|
||||||
|
|
||||||
|
import gearth.Main;
|
||||||
|
import gearth.misc.Cacher;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class GUnityFileServer extends HttpServlet
|
||||||
|
{
|
||||||
|
|
||||||
|
public final static int FILESERVER_PORT = 9089;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
response.addHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
String path = request.getPathInfo();
|
||||||
|
|
||||||
|
if (path.equals("/ping")) {
|
||||||
|
response.setStatus(200);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = request.getParameter("blabla");
|
||||||
|
if (url == null || url.isEmpty()) {
|
||||||
|
response.setStatus(404);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.addHeader("ETag", createETag());
|
||||||
|
|
||||||
|
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);
|
||||||
|
else if (path.equals("/version")) getVersion(revision, response, url);
|
||||||
|
else if (path.equals("/logo")) getLogo(response);
|
||||||
|
else {
|
||||||
|
response.setStatus(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setStatus(200);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
response.setStatus(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getRandomHexString(int numchars){
|
||||||
|
Random r = new Random();
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
while(sb.length() < numchars){
|
||||||
|
sb.append(Integer.toHexString(r.nextInt()));
|
||||||
|
}
|
||||||
|
return sb.toString().substring(0, numchars);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createETag() {
|
||||||
|
return "W/\"" + getRandomHexString(6) + "-" + getRandomHexString(13) + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDir(String revision) {
|
||||||
|
return Cacher.getCacheDir() + File.separator + "UNITY-" + revision + File.separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void fileResponse(String file, HttpServletResponse response, String contentType) throws IOException {
|
||||||
|
ServletOutputStream out = response.getOutputStream();
|
||||||
|
InputStream in = new FileInputStream(file);
|
||||||
|
// response.setContentType(contentType);
|
||||||
|
|
||||||
|
byte[] bytes = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
while ((bytesRead = in.read(bytes)) != -1) {
|
||||||
|
out.write(bytes, 0, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
fileResponse(getDir(revision) + UnityWebModifyer.UNITY_DATA, response, "application/vnd.unity");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getWasmCode(String revision, HttpServletResponse response) throws IOException {
|
||||||
|
fileResponse(getDir(revision) + UnityWebModifyer.UNITY_CODE, response, "application/vnd.unity");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getWasmFramework(String revision, HttpServletResponse response) throws IOException {
|
||||||
|
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();
|
||||||
|
|
||||||
|
fileResponse(getDir(revision) + UnityWebModifyer.UNITY_LOADER, response, "text/javascript");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getVersion(String revision, HttpServletResponse response, String url) throws IOException {
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(new URL(url).openStream()));
|
||||||
|
|
||||||
|
String version = in.readLine();
|
||||||
|
String realVersion = version.split(" ")[0];
|
||||||
|
|
||||||
|
response.getOutputStream().print(realVersion + " - G-Earth by sirjonasxx");
|
||||||
|
response.getOutputStream().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getLogo(HttpServletResponse response) throws IOException {
|
||||||
|
OutputStream out = response.getOutputStream();
|
||||||
|
InputStream in = Main.class.getResourceAsStream("G-EarthLogo.png");
|
||||||
|
|
||||||
|
byte[] bytes = new byte[4096];
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
while ((bytesRead = in.read(bytes)) != -1) {
|
||||||
|
out.write(bytes, 0, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,177 @@
|
|||||||
|
package gearth.services.unity_tools;
|
||||||
|
|
||||||
|
import wasm.disassembly.InvalidOpCodeException;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
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";
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
public UnityWebModifyer(String revision, String saveFolder) {
|
||||||
|
this.revision = revision;
|
||||||
|
this.currentUrl = UNITYFILES_URL.replace("{revision}", revision);
|
||||||
|
this.saveFolder = new File(saveFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean modifyAllFiles() {
|
||||||
|
if (saveFolder.exists()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
saveFolder.mkdirs();
|
||||||
|
|
||||||
|
try {
|
||||||
|
modifyProdFile();
|
||||||
|
modifyDataFile();
|
||||||
|
modifyCodeFile();
|
||||||
|
modifyFrameworkFile();
|
||||||
|
modifyUnityLoader();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
saveFolder.delete();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
byte[] dataBuffer = new byte[1024];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||||
|
fileOutputStream.write(dataBuffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
fileOutputStream.close();
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyDataFile() throws IOException {
|
||||||
|
File dataFile = new File(saveFolder, UNITY_DATA);
|
||||||
|
URL dataUrl = new URL(currentUrl + UNITY_DATA);
|
||||||
|
downloadToFile(dataUrl, dataFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyCodeFile() throws IOException, InvalidOpCodeException {
|
||||||
|
File codeFile = new File(saveFolder, UNITY_CODE);
|
||||||
|
URL codeUrl = new URL(currentUrl + UNITY_CODE);
|
||||||
|
downloadToFile(codeUrl, codeFile);
|
||||||
|
|
||||||
|
WasmCodePatcher patcher = new WasmCodePatcher(codeFile.getAbsolutePath());
|
||||||
|
patcher.patch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String insertFrameworkCode(String fileContents, int index, String codeName) throws IOException {
|
||||||
|
BufferedReader code = new BufferedReader(new InputStreamReader(UnityWebModifyer.class.getResourceAsStream(codeName), StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
String firstPart = fileContents.substring(0, index);
|
||||||
|
String lastPart = fileContents.substring(index);
|
||||||
|
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.append(firstPart);
|
||||||
|
|
||||||
|
stringBuilder.append("\n");
|
||||||
|
String line;
|
||||||
|
while ((line = code.readLine()) != null) {
|
||||||
|
stringBuilder.append(line);
|
||||||
|
stringBuilder.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
stringBuilder.append(lastPart);
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyFrameworkFile() throws IOException {
|
||||||
|
File frameworkFile = new File(saveFolder, UNITY_FRAMEWORK);
|
||||||
|
URL frameworkUrl = new URL(currentUrl + UNITY_FRAMEWORK);
|
||||||
|
downloadToFile(frameworkUrl, frameworkFile);
|
||||||
|
|
||||||
|
|
||||||
|
byte[] encoded = Files.readAllBytes(Paths.get(frameworkFile.getAbsolutePath()));
|
||||||
|
String contents = new String(encoded, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
contents = insertFrameworkCode(contents, 0, "js_code/unity_code.js");
|
||||||
|
|
||||||
|
String exportSearch = "Module.asmLibraryArg,buffer);Module[\"asm\"]=asm;";
|
||||||
|
int exportIndex = contents.indexOf(exportSearch) + exportSearch.length();
|
||||||
|
contents = insertFrameworkCode(contents, exportIndex, "js_code/unity_exports.js");
|
||||||
|
|
||||||
|
String importSearch = "if(!env[\"tableBase\"]){env[\"tableBase\"]=0}";
|
||||||
|
int importIndex = contents.indexOf(importSearch) + importSearch.length();
|
||||||
|
contents = insertFrameworkCode(contents, importIndex, "js_code/unity_imports.js");
|
||||||
|
|
||||||
|
contents = contents
|
||||||
|
.replace("var _free", "_free")
|
||||||
|
.replace("var _malloc", "_malloc")
|
||||||
|
.replace("{{RevisionName}}", revision);
|
||||||
|
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter(frameworkFile));
|
||||||
|
writer.write(contents);
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyUnityLoader() throws IOException {
|
||||||
|
File loaderFile = new File(saveFolder, UNITY_LOADER);
|
||||||
|
URL loaderUrl = new URL(currentUrl + UNITY_LOADER);
|
||||||
|
downloadToFile(loaderUrl, loaderFile);
|
||||||
|
|
||||||
|
byte[] encoded = Files.readAllBytes(Paths.get(loaderFile.getAbsolutePath()));
|
||||||
|
String contents = new String(encoded, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
contents = contents.replace("o.result.responseHeaders[e]==a.getResponseHeader(e)", "false");
|
||||||
|
contents = contents.replace("i.responseHeaders[e]=o.getResponseHeader(e)",
|
||||||
|
"const genRanHex = size => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');\n" +
|
||||||
|
" if (e === \"ETag\") {\n" +
|
||||||
|
" i.responseHeaders[e] = \"W/\\\"\" + genRanHex(6) + \"-\" + genRanHex(13) + \"\\\"\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" else {\n" +
|
||||||
|
" i.responseHeaders[e] = o.getResponseHeader(e)\n" +
|
||||||
|
" }");
|
||||||
|
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter(loaderFile));
|
||||||
|
writer.write(contents);
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user