diff --git a/G-Earth/pom.xml b/G-Earth/pom.xml index 9164616..f403a49 100644 --- a/G-Earth/pom.xml +++ b/G-Earth/pom.xml @@ -235,8 +235,8 @@ G-Earth - G-Wasm - 1.0.1 + G-Wasm-Minimal + 1.0.3 diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java index ca7e88b..c940962 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketClient.java @@ -5,6 +5,7 @@ import gearth.protocol.HMessage; import gearth.protocol.connection.*; import gearth.protocol.connection.proxy.nitro.NitroConstants; import gearth.protocol.connection.proxy.nitro.NitroProxyProvider; +import gearth.protocol.packethandler.nitro.NitroPacketHandler; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java index b54b96c..86c5ad0 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroWebsocketServer.java @@ -4,6 +4,7 @@ import gearth.protocol.HConnection; import gearth.protocol.HMessage; import gearth.protocol.connection.proxy.nitro.NitroConstants; import gearth.protocol.packethandler.PacketHandler; +import gearth.protocol.packethandler.nitro.NitroPacketHandler; import javax.websocket.*; import java.io.IOException; diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java index a0d2677..9748dd3 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java @@ -32,4 +32,15 @@ public abstract class PacketHandler { message.getPacket().resetReadIndex(); } + protected void awaitListeners(HMessage message, PacketSender packetSender) { + notifyListeners(0, message); + notifyListeners(1, message); + extensionHandler.handle(message, message2 -> { + notifyListeners(2, message2); + if (!message2.isBlocked()) { + packetSender.send(message2); + } + }); + } + } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/PacketSender.java b/G-Earth/src/main/java/gearth/protocol/packethandler/PacketSender.java new file mode 100644 index 0000000..62b69ac --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/PacketSender.java @@ -0,0 +1,9 @@ +package gearth.protocol.packethandler; + +import gearth.protocol.HMessage; + +public interface PacketSender { + + void send(HMessage hMessage); + +} diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/flash/FlashPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/FlashPacketHandler.java index 018bca1..98b7ffe 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/flash/FlashPacketHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/FlashPacketHandler.java @@ -8,7 +8,6 @@ import gearth.protocol.crypto.RC4; import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.PayloadBuffer; import gearth.services.extension_handler.ExtensionHandler; -import gearth.services.extension_handler.OnHMessageHandled; import java.io.IOException; import java.io.OutputStream; @@ -116,10 +115,14 @@ public abstract class FlashPacketHandler extends PacketHandler { } public boolean sendToStream(byte[] buffer) { + return sendToStream(buffer, isEncryptedStream); + } + + private boolean sendToStream(byte[] buffer, boolean isEncrypted) { synchronized (sendLock) { try { out.write( - (!isEncryptedStream) + (!isEncrypted) ? buffer : encryptcipher.rc4(buffer) ); @@ -139,29 +142,11 @@ public abstract class FlashPacketHandler extends PacketHandler { HMessage hMessage = new HMessage(hpacket, getMessageSide(), currentIndex); boolean isencrypted = isEncryptedStream; - OnHMessageHandled afterExtensionIntercept = hMessage1 -> { - if (isDataStream) { - notifyListeners(2, hMessage1); - } - - if (!hMessage1.isBlocked()) { - synchronized (sendLock) { - out.write( - (!isencrypted) - ? hMessage1.getPacket().toBytes() - : encryptcipher.rc4(hMessage1.getPacket().toBytes()) - ); - } - } - }; - if (isDataStream) { - notifyListeners(0, hMessage); - notifyListeners(1, hMessage); - extensionHandler.handle(hMessage, afterExtensionIntercept); + awaitListeners(hMessage, hMessage1 -> sendToStream(hMessage1.getPacket().toBytes(), isencrypted)); } else { - afterExtensionIntercept.finished(hMessage); + sendToStream(hMessage.getPacket().toBytes(), isencrypted); } currentIndex++; diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java similarity index 68% rename from G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroPacketHandler.java rename to G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java index 70ed0cb..d8b69b0 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroPacketHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java @@ -1,11 +1,11 @@ -package gearth.protocol.connection.proxy.nitro.websocket; +package gearth.protocol.packethandler.nitro; import gearth.protocol.HMessage; import gearth.protocol.HPacket; +import gearth.protocol.connection.proxy.nitro.websocket.NitroSession; import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.PayloadBuffer; import gearth.services.extension_handler.ExtensionHandler; -import gearth.services.extension_handler.OnHMessageHandled; import javax.websocket.Session; import java.io.IOException; @@ -18,7 +18,7 @@ public class NitroPacketHandler extends PacketHandler { private final PayloadBuffer payloadBuffer; private final Object payloadLock; - protected NitroPacketHandler(HMessage.Direction direction, NitroSession session, ExtensionHandler extensionHandler, Object[] trafficObservables) { + public NitroPacketHandler(HMessage.Direction direction, NitroSession session, ExtensionHandler extensionHandler, Object[] trafficObservables) { super(extensionHandler, trafficObservables); this.direction = direction; this.session = session; @@ -50,19 +50,7 @@ public class NitroPacketHandler extends PacketHandler { synchronized (payloadLock) { for (HPacket packet : payloadBuffer.receive()) { HMessage hMessage = new HMessage(packet, direction, currentIndex); - - OnHMessageHandled afterExtensionIntercept = hMessage1 -> { - notifyListeners(2, hMessage1); - - if (!hMessage1.isBlocked()) { - sendToStream(hMessage1.getPacket().toBytes()); - } - }; - - notifyListeners(0, hMessage); - notifyListeners(1, hMessage); - extensionHandler.handle(hMessage, afterExtensionIntercept); - + awaitListeners(hMessage, hMessage1 -> sendToStream(hMessage1.getPacket().toBytes())); currentIndex++; } } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/unity/UnityPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/unity/UnityPacketHandler.java index 6bcca62..f85e55b 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/unity/UnityPacketHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/unity/UnityPacketHandler.java @@ -5,7 +5,6 @@ import gearth.protocol.HPacket; import gearth.protocol.packethandler.ByteArrayUtils; import gearth.protocol.packethandler.PacketHandler; import gearth.services.extension_handler.ExtensionHandler; -import gearth.services.extension_handler.OnHMessageHandled; import javax.websocket.Session; import java.io.IOException; @@ -34,19 +33,7 @@ public class UnityPacketHandler extends PacketHandler { @Override public void act(byte[] buffer) throws IOException { HMessage hMessage = new HMessage(new HPacket(buffer), direction, currentIndex); - - OnHMessageHandled afterExtensionIntercept = hMessage1 -> { - notifyListeners(2, hMessage1); - - if (!hMessage1.isBlocked()) { - sendToStream(hMessage1.getPacket().toBytes()); - } - }; - - notifyListeners(0, hMessage); - notifyListeners(1, hMessage); - extensionHandler.handle(hMessage, afterExtensionIntercept); - + awaitListeners(hMessage, hMessage1 -> sendToStream(hMessage1.getPacket().toBytes())); currentIndex++; } } diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/GExtensionStoreController.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/GExtensionStoreController.java index d22ae0e..f01de68 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/GExtensionStoreController.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/GExtensionStoreController.java @@ -7,6 +7,7 @@ import gearth.services.internal_extensions.extensionstore.application.entities.c import gearth.services.internal_extensions.extensionstore.application.entities.installed.InstalledOverview; import gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews.ByDateOverview; import gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews.ByRatingOverview; +import gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews.ByUpdateOverview; import gearth.services.internal_extensions.extensionstore.application.entities.search.SearchOverview; import gearth.services.internal_extensions.extensionstore.repository.StoreRepository; import javafx.application.Platform; @@ -47,20 +48,20 @@ public class GExtensionStoreController implements Initializable { JSObject window = (JSObject) webView.getEngine().executeScript("window"); window.setMember("app", extensionStore); - Element by_date_link = webView.getEngine().getDocument().getElementById("overview_by_date"); + Element by_update_link = webView.getEngine().getDocument().getElementById("overview_by_update"); Element by_rating_link = webView.getEngine().getDocument().getElementById("overview_by_rating"); Element by_category_link = webView.getEngine().getDocument().getElementById("overview_by_category"); Element installed_link = webView.getEngine().getDocument().getElementById("overview_installed"); Element seach_link = webView.getEngine().getDocument().getElementById("search_page"); Map> hOverviewSupplier = new HashMap<>(); - hOverviewSupplier.put(by_date_link, () -> new ByDateOverview(null, 0, GExtensionStore.PAGESIZE, getStoreRepository())); + hOverviewSupplier.put(by_update_link, () -> new ByUpdateOverview(null, 0, GExtensionStore.PAGESIZE, getStoreRepository())); hOverviewSupplier.put(by_rating_link, () -> new ByRatingOverview(null, 0, GExtensionStore.PAGESIZE, getStoreRepository())); hOverviewSupplier.put(by_category_link, () -> new CategoryOverview(null, 0, GExtensionStore.PAGESIZE, getStoreRepository())); hOverviewSupplier.put(installed_link, () -> new InstalledOverview(null, 0, GExtensionStore.PAGESIZE, getStoreRepository())); hOverviewSupplier.put(seach_link, () -> new SearchOverview(null, getStoreRepository())); - Arrays.asList(by_date_link, by_rating_link, by_category_link, installed_link, seach_link).forEach(l -> + Arrays.asList(by_update_link, by_rating_link, by_category_link, installed_link, seach_link).forEach(l -> ((EventTarget) l).addEventListener("click", event -> { if (initialized) setRootOverview(hOverviewSupplier.get(l).get()); }, true)); @@ -210,7 +211,7 @@ public class GExtensionStoreController implements Initializable { private void onFullInitialize() { initialized = true; - setRootOverview(new ByDateOverview(null, 0, GExtensionStore.PAGESIZE, getStoreRepository())); + setRootOverview(new ByUpdateOverview(null, 0, GExtensionStore.PAGESIZE, getStoreRepository())); } public void gExtensionStore(GExtensionStore gExtensionStore) { diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java index df581c2..e4a335e 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/extensiondetails/StoreExtensionDetailsItem.java @@ -49,8 +49,12 @@ public class StoreExtensionDetailsItem implements ContentItem { .append("*Author(s):* ").append(storeExtension.getAuthors().stream().map(StoreExtension.Author::getName).collect(Collectors.joining(", "))).append("\n\n") .append("*Categories:* ").append(storeExtension.getCategories().stream().map(ExtCategory::getName).collect(Collectors.joining(", "))).append("\n\n"); - contentBuilder.append("*Technical information*").append("\n") - .append("> Language: ").append(storeExtension.getLanguage()).append("\n") + contentBuilder.append("*Technical information*").append("\n"); + + if(storeExtension.getReleases() != null) + contentBuilder.append("> Releases: --url:Click Here-").append(storeExtension.getReleases()).append("\n"); + + contentBuilder.append("> Language: ").append(storeExtension.getLanguage()).append("\n") .append("> Source: --url:Click Here-").append(storeExtension.getSource()).append("\n") .append("> Framework: ").append(storeExtension.getFramework().getFramework().getName()).append(" - v").append(storeExtension.getFramework().getVersion()).append("\n") .append("> Systems: ").append(String.join(", ", storeExtension.getCompatibility().getSystems())).append("\n \n"); diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/queriedoverviews/ByUpdateOverview.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/queriedoverviews/ByUpdateOverview.java new file mode 100644 index 0000000..36137ba --- /dev/null +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/application/entities/queriedoverviews/ByUpdateOverview.java @@ -0,0 +1,54 @@ +package gearth.services.internal_extensions.extensionstore.application.entities.queriedoverviews; + +import gearth.misc.OSValidator; +import gearth.services.internal_extensions.extensionstore.application.entities.HOverview; +import gearth.services.internal_extensions.extensionstore.repository.StoreRepository; +import gearth.services.internal_extensions.extensionstore.repository.models.StoreExtension; +import gearth.services.internal_extensions.extensionstore.repository.querying.ExtensionOrdering; + +import java.util.Collections; +import java.util.List; + +public class ByUpdateOverview extends QueriedExtensionOverview { + + + public ByUpdateOverview(HOverview parent, int startIndex, int size, StoreRepository storeRepository) { + super(parent, startIndex, size, storeRepository); + } + + protected List query(int startIndex, int size) { + return storeRepository.getExtensions(startIndex, size, "", ExtensionOrdering.LAST_UPDATED, + Collections.singletonList(OSValidator.getOSFull()), null, null, null, false, false); + } + + @Override + public Header header() { + return new Header() { + @Override + public String iconUrl() { + return "images/overviews/clock.png"; + } + + @Override + public String title() { + return "Recently Updated"; + } + + @Override + public String description() { + return "Extensions that were recently updated"; + } + + @Override + public String contentTitle() { + return "Recently Updated"; + } + }; + } + + + @Override + public HOverview getNewPage(int startIndex, int size) { + return new ByUpdateOverview(parent, startIndex, size, storeRepository); + } +} diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreFetch.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreFetch.java index a35ae94..5788e43 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreFetch.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreFetch.java @@ -34,11 +34,11 @@ public class StoreFetch { new URL(String.format("https://raw.githubusercontent.com/%s/repo/%s/store/config.json", source, version)) .openStream(), StandardCharsets.UTF_8)); - JSONArray exensions = new JSONArray(IOUtils.toString( + JSONArray extensions = new JSONArray(IOUtils.toString( new URL(String.format("https://raw.githubusercontent.com/%s/repo/%s/.auto-generated/extensions.json", source, version)) .openStream(), StandardCharsets.UTF_8)); - storeFetchListener.success(new StoreRepository(new StoreData(config, exensions), version, source)); + storeFetchListener.success(new StoreRepository(new StoreData(config, extensions), version, source)); } catch (Exception e) { storeFetchListener.fail(e.getLocalizedMessage()); diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreRepository.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreRepository.java index b3f21f3..3eabb45 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreRepository.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/StoreRepository.java @@ -78,7 +78,7 @@ public class StoreRepository { } public List getClients() { - return Arrays.asList("Unity", "Flash"); + return Arrays.asList("Unity", "Flash", "Nitro"); } public List getLanguages() { diff --git a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/models/StoreExtension.java b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/models/StoreExtension.java index d876081..eb33e61 100644 --- a/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/models/StoreExtension.java +++ b/G-Earth/src/main/java/gearth/services/internal_extensions/extensionstore/repository/models/StoreExtension.java @@ -10,7 +10,7 @@ import java.util.stream.Collectors; public class StoreExtension { - public StoreExtension(String title, String description, List authors, String version, List categories, String source, String readme, boolean stable, Framework framework, String language, Commands commands, Compatibility compatibility, LocalDateTime submissionDate, LocalDateTime updateDate, boolean isOutdated, int rating) { + public StoreExtension(String title, String description, List authors, String version, List categories, String source, String readme, String releases, boolean stable, Framework framework, String language, Commands commands, Compatibility compatibility, LocalDateTime submissionDate, LocalDateTime updateDate, boolean isOutdated, int rating) { this.title = title; this.description = description; this.authors = authors; @@ -18,6 +18,7 @@ public class StoreExtension { this.categories = categories; this.source = source; this.readme = readme; + this.releases = releases; this.stable = stable; this.framework = framework; this.language = language; @@ -38,6 +39,7 @@ public class StoreExtension { .toList().stream().anyMatch(j -> j.equals(c.getName()))).collect(Collectors.toList()); this.source = object.getString("source"); this.readme = object.has("readme") ? object.getString("readme") : null; + this.releases = object.has("releases") ? object.getString("releases") : null; this.stable = object.getBoolean("stable"); this.framework = new Framework(object.getJSONObject("framework"), storeConfig); this.language = object.getString("language"); @@ -201,6 +203,7 @@ public class StoreExtension { private final String source; private final String readme; + private final String releases; private final boolean stable; @@ -246,6 +249,10 @@ public class StoreExtension { return readme; } + public String getReleases() { + return releases; + } + public boolean isStable() { return stable; } 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..f10ec50 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 { @@ -76,10 +76,16 @@ public class GUnityFileServer extends HttpServlet } - private void fileResponse(String file, HttpServletResponse response, String contentType) throws IOException { + private void fileResponse(String file, HttpServletResponse response, String contentType, boolean gzip) throws IOException { ServletOutputStream out = response.getOutputStream(); InputStream in = new FileInputStream(file); -// response.setContentType(contentType); + if (contentType != null) { + response.setContentType(contentType); + } + + if (gzip) { + response.setHeader("Content-Encoding", "gzip"); + } byte[] bytes = new byte[4096]; int bytesRead; @@ -93,31 +99,28 @@ 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 - fileResponse(getDir(revision) + UnityWebModifyer.UNITY_DATA, response, "application/vnd.unity"); + modifyer.modifyAllFiles(revision, getDir(revision)); + + fileResponse(getDir(revision) + UnityWebModifyer.UNITY_DATA, response, null, true); } private void getWasmCode(String revision, HttpServletResponse response) throws IOException { - fileResponse(getDir(revision) + UnityWebModifyer.UNITY_CODE, response, "application/vnd.unity"); + modifyer.modifyAllFiles(revision, getDir(revision)); + + fileResponse(getDir(revision) + UnityWebModifyer.UNITY_CODE, response, "application/wasm", true); } private void getWasmFramework(String revision, HttpServletResponse response) throws IOException { - fileResponse(getDir(revision) + UnityWebModifyer.UNITY_FRAMEWORK, response, "application/vnd.unity"); + modifyer.modifyAllFiles(revision, getDir(revision)); + + fileResponse(getDir(revision) + UnityWebModifyer.UNITY_FRAMEWORK, response, "text/javascript", true); } - 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"); + fileResponse(getDir(revision) + UnityWebModifyer.UNITY_LOADER, response, "text/javascript", false); } private void getVersion(String revision, HttpServletResponse response, String url) throws IOException { 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..e0cc5fb 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 @@ -1,5 +1,6 @@ package gearth.services.unity_tools; +import org.apache.commons.io.IOUtils; import org.codehaus.plexus.util.FileUtils; import wasm.disassembly.InvalidOpCodeException; @@ -10,36 +11,34 @@ import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; 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_DATA = "habbo2020-global-prod.data.gz"; + 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 +56,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 +67,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); @@ -131,7 +109,7 @@ public class UnityWebModifyer { downloadToFile(frameworkUrl, frameworkFile); - byte[] encoded = Files.readAllBytes(Paths.get(frameworkFile.getAbsolutePath())); + byte[] encoded = IOUtils.toByteArray(new GZIPInputStream(new FileInputStream(frameworkFile))); String contents = new String(encoded, StandardCharsets.UTF_8); contents = insertFrameworkCode(contents, 0, "js_code/unity_code.js"); @@ -147,9 +125,10 @@ public class UnityWebModifyer { contents = contents .replace("var _free", "_free") .replace("var _malloc", "_malloc") + .replace("var Module=typeof Module!==\"undefined\"?Module:{};", "var Module=typeof Module!==\"undefined\"?Module:{}; _module = Module") .replace("{{RevisionName}}", revision); - BufferedWriter writer = new BufferedWriter(new FileWriter(frameworkFile)); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new GZIPOutputStream(new FileOutputStream(frameworkFile)))); writer.write(contents); writer.close(); } @@ -162,14 +141,14 @@ public class UnityWebModifyer { 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)", + contents = contents.replace("o.result.responseHeaders[e]==s.getResponseHeader(e)", "false"); + contents = contents.replace("a.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" + + " a.responseHeaders[e] = \"W/\\\"\" + genRanHex(6) + \"-\" + genRanHex(13) + \"\\\"\"\n" + " }\n" + " else {\n" + - " i.responseHeaders[e] = o.getResponseHeader(e)\n" + + " a.responseHeaders[e] = o.getResponseHeader(e)\n" + " }"); BufferedWriter writer = new BufferedWriter(new FileWriter(loaderFile)); diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/WasmCodePatcher.java b/G-Earth/src/main/java/gearth/services/unity_tools/WasmCodePatcher.java index ba2831b..95c87f7 100644 --- a/G-Earth/src/main/java/gearth/services/unity_tools/WasmCodePatcher.java +++ b/G-Earth/src/main/java/gearth/services/unity_tools/WasmCodePatcher.java @@ -19,12 +19,12 @@ public class WasmCodePatcher { } public void patch() throws IOException, InvalidOpCodeException { - Module module = new Module(file, Arrays.asList( + Module module = new Module(file, true, Arrays.asList( new SetKeyPatcher(), new ReturnBytePatcher(), new OutgoingPacketPatcher(), new IncomingPacketPatcher() )); - module.assembleToFile(file); + module.assembleToFile(file, true); } } 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); -// } -// -//} diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/IncomingPacketPatcher.java b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/IncomingPacketPatcher.java index b3482cd..227fc8a 100644 --- a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/IncomingPacketPatcher.java +++ b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/IncomingPacketPatcher.java @@ -2,6 +2,10 @@ package gearth.services.unity_tools.codepatcher; import wasm.disassembly.instructions.Instr; import wasm.disassembly.instructions.InstrType; +import wasm.disassembly.instructions.control.IfElseInstr; +import wasm.disassembly.instructions.memory.MemArg; +import wasm.disassembly.instructions.memory.MemInstr; +import wasm.disassembly.instructions.variable.LocalVariableInstr; import wasm.disassembly.modules.sections.code.Func; import wasm.disassembly.modules.sections.code.Locals; import wasm.disassembly.types.FuncType; @@ -52,6 +56,9 @@ public class IncomingPacketPatcher implements StreamReplacement { if (instr.getInstrType() != expectedExpr.get(j)) return false; } + if (((MemInstr)(code.getExpression().getInstructions().get(5))).getMemArg().getAlign() != 2 || + ((MemInstr)(code.getExpression().getInstructions().get(5))).getMemArg().getOffset() != 32) return false; + return true; } diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/OutgoingPacketPatcher.java b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/OutgoingPacketPatcher.java index 026fee3..2410f56 100644 --- a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/OutgoingPacketPatcher.java +++ b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/OutgoingPacketPatcher.java @@ -2,6 +2,7 @@ package gearth.services.unity_tools.codepatcher; import wasm.disassembly.instructions.Instr; import wasm.disassembly.instructions.InstrType; +import wasm.disassembly.instructions.variable.LocalVariableInstr; import wasm.disassembly.modules.sections.code.Func; import wasm.disassembly.types.FuncType; import wasm.disassembly.types.ResultType; @@ -45,6 +46,8 @@ public class OutgoingPacketPatcher implements StreamReplacement { if (expression.get(4).getInstrType() != InstrType.I32_CONST) return false; if (expression.get(5).getInstrType() != InstrType.CALL) return false; + if (((LocalVariableInstr)(expression.get(2))).getLocalIdx().getX() != 1) return false; + return true; } } diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/ReturnBytePatcher.java b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/ReturnBytePatcher.java index 6f8040c..c2ac300 100644 --- a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/ReturnBytePatcher.java +++ b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/ReturnBytePatcher.java @@ -37,7 +37,7 @@ public class ReturnBytePatcher implements StreamReplacement { @Override public boolean codeMatches(Func code) { if (code.getLocalss().size() != 0) return false; - if (code.getExpression().getInstructions().size() != 30) return false; + if (code.getExpression().getInstructions().size() != 26) return false; List expr = code.getExpression().getInstructions(); if (expr.get(expr.size() - 1).getInstrType() != InstrType.I32_XOR) return false; return true; diff --git a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/SetKeyPatcher.java b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/SetKeyPatcher.java index 41fab8a..e012d15 100644 --- a/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/SetKeyPatcher.java +++ b/G-Earth/src/main/java/gearth/services/unity_tools/codepatcher/SetKeyPatcher.java @@ -2,6 +2,8 @@ package gearth.services.unity_tools.codepatcher; import wasm.disassembly.instructions.Instr; import wasm.disassembly.instructions.InstrType; +import wasm.disassembly.instructions.numeric.NumericI32ConstInstr; +import wasm.disassembly.instructions.variable.LocalVariableInstr; import wasm.disassembly.modules.sections.code.Func; import wasm.disassembly.modules.sections.code.Locals; import wasm.disassembly.types.FuncType; @@ -40,18 +42,20 @@ public class SetKeyPatcher implements StreamReplacement { public boolean codeMatches(Func code) { if (!(code.getLocalss().equals(Collections.singletonList(new Locals(1, ValType.I32))))) return false; - 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); + List expression = code.getExpression().getInstructions(); + List expectedExpr = Arrays.asList(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 ); - if (code.getExpression().getInstructions().size() != expectedExpr.size()) return false; + if (expression.size() != expectedExpr.size()) return false; - for (int j = 0; j < code.getExpression().getInstructions().size(); j++) { - Instr instr = code.getExpression().getInstructions().get(j); + for (int j = 0; j < expression.size(); j++) { + Instr instr = expression.get(j); if (instr.getInstrType() != expectedExpr.get(j)) return false; } +// if (((NumericI32ConstInstr)(expression.get(5))).getConstValue() != 14) return false; + return true; } } diff --git a/G-Earth/src/main/java/gearth/ui/info/InfoController.java b/G-Earth/src/main/java/gearth/ui/info/InfoController.java index 9cd30c4..fc03f3f 100644 --- a/G-Earth/src/main/java/gearth/ui/info/InfoController.java +++ b/G-Earth/src/main/java/gearth/ui/info/InfoController.java @@ -14,12 +14,12 @@ import javafx.scene.web.WebView; */ public class InfoController extends SubForm { public ImageView img_logo; - public Hyperlink link_ase; public Hyperlink link_darkbox; - public Hyperlink link_d_harble; public Hyperlink link_g_gearth; public Hyperlink link_g_tanji; public Hyperlink link_d_gearth; + public Hyperlink link_g_store; + public Hyperlink link_t_gearth; public Label version; @@ -38,19 +38,19 @@ public class InfoController extends SubForm { img_logo.setImage(new Image(String.format("/gearth/themes/%s/logo.png", Main.theme))); - link_ase.setTooltip(new Tooltip("https://allseeingeye.to")); link_darkbox.setTooltip(new Tooltip("https://darkbox.nl")); - link_d_harble.setTooltip(new Tooltip("https://discord.gg/CzRuHvW")); link_d_gearth.setTooltip(new Tooltip("https://discord.gg/AVkcF8y")); link_g_gearth.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth")); link_g_tanji.setTooltip(new Tooltip("https://github.com/ArachisH/Tanji")); + link_g_store.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-ExtensionStore")); + link_t_gearth.setTooltip(new Tooltip("https://twitter.com/Scripting_Habbo")); - activateHyperlink(link_ase); activateHyperlink(link_darkbox); - activateHyperlink(link_d_harble); activateHyperlink(link_d_gearth); activateHyperlink(link_g_gearth); activateHyperlink(link_g_tanji); + activateHyperlink(link_g_store); + activateHyperlink(link_t_gearth); } public void donate(ActionEvent actionEvent) { diff --git a/G-Earth/src/main/resources/build/cache/cache.json b/G-Earth/src/main/resources/build/cache/cache.json index 6bb9e30..a62339b 100644 --- a/G-Earth/src/main/resources/build/cache/cache.json +++ b/G-Earth/src/main/resources/build/cache/cache.json @@ -1,3 +1,3 @@ { - "theme": "Tanji" + "theme": "G-Earth" } \ No newline at end of file diff --git a/G-Earth/src/main/resources/build/windows/32bit/G-Earth.exe b/G-Earth/src/main/resources/build/windows/32bit/G-Earth.exe new file mode 100644 index 0000000..7916bf1 Binary files /dev/null and b/G-Earth/src/main/resources/build/windows/32bit/G-Earth.exe differ diff --git a/G-Earth/src/main/resources/build/windows/32bit/Tanji.exe b/G-Earth/src/main/resources/build/windows/32bit/Tanji.exe deleted file mode 100644 index f17c94c..0000000 Binary files a/G-Earth/src/main/resources/build/windows/32bit/Tanji.exe and /dev/null differ diff --git a/G-Earth/src/main/resources/build/windows/64bit/G-Earth.exe b/G-Earth/src/main/resources/build/windows/64bit/G-Earth.exe new file mode 100644 index 0000000..59ad4ef Binary files /dev/null and b/G-Earth/src/main/resources/build/windows/64bit/G-Earth.exe differ diff --git a/G-Earth/src/main/resources/build/windows/64bit/Tanji.exe b/G-Earth/src/main/resources/build/windows/64bit/Tanji.exe deleted file mode 100644 index f17c94c..0000000 Binary files a/G-Earth/src/main/resources/build/windows/64bit/Tanji.exe and /dev/null differ diff --git a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html index 71a837a..e24148e 100644 --- a/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html +++ b/G-Earth/src/main/resources/gearth/services/internal_extensions/extensionstore/application/webview/index.html @@ -36,7 +36,7 @@