diff --git a/G-Earth/pom.xml b/G-Earth/pom.xml index 53526ad..3c4a4ff 100644 --- a/G-Earth/pom.xml +++ b/G-Earth/pom.xml @@ -10,7 +10,7 @@ 1.8 - 9.4.48.v20220622 + 9.4.50.v20221201 1.3.5 @@ -238,14 +238,11 @@ maven-artifact 3.6.3 - - javax.websocket javax.websocket-api 1.1 - org.eclipse.jetty jetty-server diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java index f85854e..d7f4665 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/websocket/NitroSession.java @@ -1,6 +1,6 @@ package gearth.protocol.connection.proxy.nitro.websocket; -import javax.websocket.Session; +import org.eclipse.jetty.websocket.api.Session; public interface NitroSession { 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 d003c31..7ebfc7d 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 @@ -50,6 +50,7 @@ public class NitroWebsocketClient implements NitroSession { activeSession = (JsrSession) session; activeSession.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE); + activeSession.setMaxTextMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE); // Set proper headers to spoof being a real client. final Map> headers = new HashMap<>(activeSession.getUpgradeRequest().getHeaders()); @@ -94,7 +95,7 @@ public class NitroWebsocketClient implements NitroSession { } @Override - public Session getSession() { + public org.eclipse.jetty.websocket.api.Session getSession() { return activeSession; } 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 3df6cb7..37ca63d 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 @@ -5,17 +5,28 @@ import gearth.protocol.HMessage; import gearth.protocol.connection.proxy.nitro.NitroConstants; import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.nitro.NitroPacketHandler; -import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig; -import org.eclipse.jetty.websocket.jsr356.JsrExtension; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketListener; +import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; +import org.eclipse.jetty.websocket.client.WebSocketClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.websocket.*; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.net.URI; -import java.util.*; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; -public class NitroWebsocketServer extends Endpoint implements NitroSession { +public class NitroWebsocketServer implements WebSocketListener, NitroSession { private static final Logger logger = LoggerFactory.getLogger(NitroWebsocketServer.class); @@ -39,66 +50,31 @@ public class NitroWebsocketServer extends Endpoint implements NitroSession { public void connect(String websocketUrl, Map> clientHeaders) throws IOException { try { - logger.info("Connecting to origin websocket at {}", websocketUrl); + logger.info("Building origin websocket connection ({})", websocketUrl); - ClientEndpointConfig.Builder builder = ClientEndpointConfig.Builder.create(); + final WebSocketClient client = createWebSocketClient(); - builder.extensions(Collections.singletonList(new JsrExtension(new ExtensionConfig("permessage-deflate;client_max_window_bits")))); + final ClientUpgradeRequest request = new ClientUpgradeRequest(); - builder.configurator(new ClientEndpointConfig.Configurator() { - @Override - public void beforeRequest(Map> headers) { - clientHeaders.forEach((key, value) -> { - if (SKIP_HEADERS.contains(key)) { - return; - } - - headers.remove(key); - headers.put(key, value); - }); + clientHeaders.forEach((key, value) -> { + if (SKIP_HEADERS.contains(key)) { + return; } + + request.setHeader(key, value); }); - ClientEndpointConfig config = builder.build(); + logger.info("Connecting to origin websocket at {}", websocketUrl); - ContainerProvider.getWebSocketContainer().connectToServer(this, config, URI.create(websocketUrl)); + client.start(); + client.connect(this, URI.create(websocketUrl), request); logger.info("Connected to origin websocket"); - } catch (DeploymentException e) { - throw new IOException("Failed to deploy websocket client", e); + } catch (Exception e) { + throw new IOException("Failed to start websocket client to origin " + websocketUrl, e); } } - @Override - public void onOpen(Session session, EndpointConfig config) { - this.activeSession = session; - this.activeSession.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE); - this.activeSession.addMessageHandler(new MessageHandler.Whole() { - @Override - public void onMessage(byte[] message) { - try { - packetHandler.act(message); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - } - - @Override - public void onClose(Session session, CloseReason closeReason) { - // Hotel closed connection. - client.shutdownProxy(); - } - - @Override - public void onError(Session session, Throwable throwable) { - throwable.printStackTrace(); - - // Shutdown. - client.shutdownProxy(); - } - @Override public Session getSession() { return activeSession; @@ -118,10 +94,86 @@ public class NitroWebsocketServer extends Endpoint implements NitroSession { try { activeSession.close(); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } finally { activeSession = null; } } + + @Override + public void onWebSocketBinary(byte[] bytes, int i, int i1) { + try { + packetHandler.act(bytes); + } catch (IOException e) { + logger.error("Failed to handle packet", e); + } + } + + @Override + public void onWebSocketText(String s) { + logger.warn("Received text message from hotel"); + } + + @Override + public void onWebSocketClose(int i, String s) { + // Hotel closed connection. + client.shutdownProxy(); + } + + @Override + public void onWebSocketConnect(org.eclipse.jetty.websocket.api.Session session) { + activeSession = session; + } + + @Override + public void onWebSocketError(Throwable throwable) { + throwable.printStackTrace(); + + // Shutdown. + client.shutdownProxy(); + } + + private SSLContext createSSLContext() { + final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + }}; + + try { + final SSLContext sslContext = SSLContext.getInstance("TLS"); + + sslContext.init(null, trustAllCerts, new SecureRandom()); + + return sslContext; + } catch (Exception e) { + throw new RuntimeException("Failed to setup ssl context", e); + } + } + + private HttpClient createHttpClient() { + final SslContextFactory.Client factory = new SslContextFactory.Client(); + + factory.setSslContext(createSSLContext()); + + return new HttpClient(factory); + } + + private WebSocketClient createWebSocketClient() { + final WebSocketClient client = new WebSocketClient(createHttpClient()); + + client.setMaxBinaryMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE); + client.setMaxTextMessageBufferSize(NitroConstants.WEBSOCKET_BUFFER_SIZE); + + return client; + } } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java index d8b69b0..fc72f34 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/nitro/NitroPacketHandler.java @@ -6,13 +6,17 @@ 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 org.eclipse.jetty.websocket.api.Session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import javax.websocket.Session; import java.io.IOException; import java.nio.ByteBuffer; public class NitroPacketHandler extends PacketHandler { + private static final Logger logger = LoggerFactory.getLogger(NitroPacketHandler.class); + private final HMessage.Direction direction; private final NitroSession session; private final PayloadBuffer payloadBuffer; @@ -39,7 +43,13 @@ public class NitroPacketHandler extends PacketHandler { buffer = buffer.clone(); } - localSession.getAsyncRemote().sendBinary(ByteBuffer.wrap(buffer)); + try { + localSession.getRemote().sendBytes(ByteBuffer.wrap(buffer)); + } catch (IOException e) { + logger.error("Error sending packet to nitro client", e); + return false; + } + return true; } diff --git a/G-Earth/src/main/resources/gearth/ui/translations/messages_pt.properties b/G-Earth/src/main/resources/gearth/ui/translations/messages_pt.properties index 0363432..a7ea675 100644 --- a/G-Earth/src/main/resources/gearth/ui/translations/messages_pt.properties +++ b/G-Earth/src/main/resources/gearth/ui/translations/messages_pt.properties @@ -147,7 +147,7 @@ alert.outdated.content.newversion=Uma nova versão do G-Earth foi encontrada alert.outdated.content.update=Atualizar para a versão mais recente ### Alert - Invalid connection -alert.invalidconnection.content=Você entrou com inforções de conexão inválidas, o G-Earth não conseguiu se conectar +alert.invalidconnection.content=Você entrou com informações de conexão inválidas, o G-Earth não conseguiu se conectar ### Alert - Nitro root certificate alert.rootcertificate.title=Instalação de certificado do root @@ -169,7 +169,7 @@ alert.somethingwentwrong.content=Algo inesperado aconteceu!\n\ Vá para nossa página de Solução de problemas para resolver o ocorrido: ### Alert - Allow extension connection -alert.extconnection.content=Exntesão "%s" tentou se conectar mas é desconcida pelo G-Earth,\n\ +alert.extconnection.content=Extensão "%s" tentou se conectar mas é desconhecida pelo G-Earth,\n\ aceitar essa conexão? ### Alert - G-Python error @@ -183,8 +183,8 @@ alert.gpythonerror.content=Algo inesperado aconteceu executando o terminal G-Pyt ## Internal extension ### Internal extension - G-ExtensionStore -ext.store.elapsedtime.second.single=secondo -ext.store.elapsedtime.second.multiple=secondos +ext.store.elapsedtime.second.single=segundo +ext.store.elapsedtime.second.multiple=segundos ext.store.elapsedtime.minute.single=minuto ext.store.elapsedtime.minute.multiple=minutos ext.store.elapsedtime.hour.single=hora @@ -219,7 +219,7 @@ ext.store.extension.details.screenshot=Captura de tela ext.store.extension.author.reputation=reputação ext.store.extension.author.releases=lançamentos -ext.store.extension.warning.requirement=Aviso: o framework requer --url:instalações adicionais- +ext.store.extension.warning.requirement=Aviso: o framework requer --url:additional installations- ! IMPORTANT: the previous line has to end with the --url component like the english version ext.store.extension.warning.unstable=Aviso: esta extensão foi marcada como instável! @@ -272,17 +272,17 @@ ext.store.categories.title=Categorias ext.store.categories.description=Explore os diferentes tipos de extensões que o G-Earth tem a oferecer ext.store.categories.contenttitle=Categorias -ext.store.fail.unzip=Error while unzipping -ext.store.fail.invalidurl=Invalid extension URL -ext.store.fail.notavailable=Extension not available in repository -ext.store.fail.alreadyexists=Something went wrong creating the extension directory, does the extension already exist? -ext.store.fail.notfound=Extension wasn't found -ext.store.fail.uninstall=Something went wrong with uninstalling the extension, make sure to disconnect the extension if it was still running. +ext.store.fail.unzip=Erro ao descompactar +ext.store.fail.invalidurl=URL de extensão inválida +ext.store.fail.notavailable=Extensão não disponível no repositório +ext.store.fail.alreadyexists=Algo deu errado ao criar o diretório de extensão, a extensão já existe? +ext.store.fail.notfound=Extensão não foi encontrada +ext.store.fail.uninstall=Algo deu errado ao desinstalar a extensão, certifique-se de desconectar a extensão se ela ainda estiver em execução. -ext.store.ordering.rating=Rating -ext.store.ordering.alphabetical=Alphabetical -ext.store.ordering.lastupdated=Last updated -ext.store.ordering.newreleases=New releases +ext.store.ordering.rating=Avaliação +ext.store.ordering.alphabetical=Alfabético +ext.store.ordering.lastupdated=Última atualização +ext.store.ordering.newreleases=Novos lançamentos ### Internal extension - Logger ext.logger.menu.window=Janela @@ -307,7 +307,7 @@ ext.logger.menu.packets.displaydetails.byterep.legacy=Legado ext.logger.menu.packets.displaydetails.byterep.hexdump=Hexdump ext.logger.menu.packets.displaydetails.byterep.rawhex=Hex cru ext.logger.menu.packets.displaydetails.byterep.none=Nenhum -ext.logger.menu.packets.displaydetails.message=Menssagem +ext.logger.menu.packets.displaydetails.message=Mensagem ext.logger.menu.packets.displaydetails.message.name=Nome ext.logger.menu.packets.displaydetails.message.hash=Hash ext.logger.menu.packets.displaydetails.message.id=Id