mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-27 10:50:50 +01:00
Added more extensive logging, cleaned up mac os habbo client
This commit is contained in:
parent
6a9b1201ac
commit
b40ad3a5dd
22
G-Earth/src/main/java/gearth/misc/StringUtils.java
Normal file
22
G-Earth/src/main/java/gearth/misc/StringUtils.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package gearth.misc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains utility methods for {@link String} conversions.
|
||||||
|
*/
|
||||||
|
public final class StringUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interprets the argued {@link String} as a hex-string and converts it to a byte array.
|
||||||
|
* @param hexString the {@link String} to be converted.
|
||||||
|
* @return a byte array containing the converted hex string values.
|
||||||
|
*/
|
||||||
|
public static byte[] hexStringToByteArray(String hexString) {
|
||||||
|
int len = hexString.length();
|
||||||
|
byte[] data = new byte[len / 2];
|
||||||
|
for (int i = 0; i < len; i += 2) {
|
||||||
|
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
|
||||||
|
+ Character.digit(hexString.charAt(i+1), 16));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@ import java.util.function.Consumer;
|
|||||||
public class HConnection {
|
public class HConnection {
|
||||||
|
|
||||||
public static volatile boolean DECRYPTPACKETS = true;
|
public static volatile boolean DECRYPTPACKETS = true;
|
||||||
public static volatile boolean DEBUG = false;
|
public static volatile boolean DEBUG = true;
|
||||||
|
|
||||||
private volatile ExtensionHandler extensionHandler = null;
|
private volatile ExtensionHandler extensionHandler = null;
|
||||||
|
|
||||||
@ -255,4 +255,12 @@ public class HConnection {
|
|||||||
public ProxyProvider getProxyProvider() {
|
public ProxyProvider getProxyProvider() {
|
||||||
return proxyProvider;
|
return proxyProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HConnection{" +
|
||||||
|
"state=" + state +
|
||||||
|
", proxy=" + proxy +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,4 +116,21 @@ public class HProxy {
|
|||||||
public PacketInfoManager getPacketInfoManager() {
|
public PacketInfoManager getPacketInfoManager() {
|
||||||
return packetInfoManager;
|
return packetInfoManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HProxy{" +
|
||||||
|
"hClient=" + hClient +
|
||||||
|
", input_domain='" + input_domain + '\'' +
|
||||||
|
", actual_domain='" + actual_domain + '\'' +
|
||||||
|
", actual_port=" + actual_port +
|
||||||
|
", intercept_port=" + intercept_port +
|
||||||
|
", intercept_host='" + intercept_host + '\'' +
|
||||||
|
", proxy_server=" + proxy_server +
|
||||||
|
", inHandler=" + inHandler +
|
||||||
|
", outHandler=" + outHandler +
|
||||||
|
", hotelVersion='" + hotelVersion + '\'' +
|
||||||
|
", clientIdentifier='" + clientIdentifier + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,18 @@ import gearth.protocol.connection.HState;
|
|||||||
import gearth.protocol.connection.HStateSetter;
|
import gearth.protocol.connection.HStateSetter;
|
||||||
import gearth.protocol.connection.proxy.ProxyProvider;
|
import gearth.protocol.connection.proxy.ProxyProvider;
|
||||||
import gearth.protocol.memory.Rc4Obtainer;
|
import gearth.protocol.memory.Rc4Obtainer;
|
||||||
|
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
||||||
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
|
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
|
||||||
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
|
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
|
||||||
import gearth.protocol.packethandler.flash.FlashPacketHandler;
|
|
||||||
import gearth.ui.titlebar.TitleBarController;
|
import gearth.ui.titlebar.TitleBarController;
|
||||||
import gearth.ui.translations.LanguageBundle;
|
import gearth.ui.translations.LanguageBundle;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.stage.Stage;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
@ -27,6 +27,7 @@ import java.util.concurrent.Semaphore;
|
|||||||
|
|
||||||
public abstract class FlashProxyProvider implements ProxyProvider {
|
public abstract class FlashProxyProvider implements ProxyProvider {
|
||||||
|
|
||||||
|
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
protected final HProxySetter proxySetter;
|
protected final HProxySetter proxySetter;
|
||||||
protected final HStateSetter stateSetter;
|
protected final HStateSetter stateSetter;
|
||||||
protected final HConnection hConnection;
|
protected final HConnection hConnection;
|
||||||
@ -47,7 +48,8 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
|||||||
client.setSoTimeout(0);
|
client.setSoTimeout(0);
|
||||||
server.setSoTimeout(0);
|
server.setSoTimeout(0);
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort());
|
logger.debug("Starting proxy thread at {}:{}", server.getLocalAddress().getHostAddress(), server.getLocalPort());
|
||||||
|
|
||||||
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
|
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
|
||||||
|
|
||||||
OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
|
OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
|
||||||
@ -73,13 +75,13 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
|||||||
try {
|
try {
|
||||||
if (!server.isClosed()) server.close();
|
if (!server.isClosed()) server.close();
|
||||||
if (!client.isClosed()) client.close();
|
if (!client.isClosed()) client.close();
|
||||||
if (HConnection.DEBUG) System.out.println("STOP");
|
logger.debug("Closed server {} and client {}, dataStreams {}", server, client, datastream);
|
||||||
if (datastream[0]) {
|
if (datastream[0]) {
|
||||||
onConnectEnd();
|
onConnectEnd();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
e.printStackTrace();
|
logger.error("Failed to gracefully stop", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +97,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException ignore) {
|
catch (IOException ignore) {
|
||||||
// System.err.println(packetHandler instanceof IncomingPacketHandler ? "incoming" : "outgoing");
|
// logger.error("Failed to read input stream from socket {}", socket, ignore);
|
||||||
// ignore.printStackTrace();
|
|
||||||
} finally {
|
} finally {
|
||||||
abort.release();
|
abort.release();
|
||||||
}
|
}
|
||||||
@ -132,9 +133,8 @@ public abstract class FlashProxyProvider implements ProxyProvider {
|
|||||||
try {
|
try {
|
||||||
TitleBarController.create(alert).showAlert();
|
TitleBarController.create(alert).showAlert();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
logger.error("Failed to create invalid connection error alert", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package gearth.protocol.connection.proxy.flash;
|
package gearth.protocol.connection.proxy.flash;
|
||||||
|
|
||||||
import gearth.GEarth;
|
|
||||||
import gearth.misc.Cacher;
|
import gearth.misc.Cacher;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.connection.*;
|
import gearth.protocol.connection.*;
|
||||||
@ -14,8 +13,6 @@ import gearth.ui.titlebar.TitleBarController;
|
|||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
import javafx.scene.image.Image;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
@ -26,7 +23,6 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
|
|
||||||
private List<String> potentialHosts;
|
private List<String> potentialHosts;
|
||||||
|
|
||||||
|
|
||||||
private static final HostReplacer hostsReplacer = HostReplacerFactory.get();
|
private static final HostReplacer hostsReplacer = HostReplacerFactory.get();
|
||||||
private volatile boolean hostRedirected = false;
|
private volatile boolean hostRedirected = false;
|
||||||
|
|
||||||
@ -113,7 +109,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
try {
|
try {
|
||||||
TitleBarController.create(a).showAlertAndWait();
|
TitleBarController.create(a).showAlertAndWait();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
ex.printStackTrace();
|
logger.error("Failed to create port in use error alert", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
@ -128,8 +124,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
Socket client = proxy_server.accept();
|
Socket client = proxy_server.accept();
|
||||||
proxy = potentialProxy;
|
proxy = potentialProxy;
|
||||||
closeAllProxies(proxy);
|
closeAllProxies(proxy);
|
||||||
if (HConnection.DEBUG) System.out.println("accepted a proxy");
|
logger.debug("Accepted proxy {}, starting proxy thread (useSocks={})",proxy, useSocks);
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Socket server;
|
Socket server;
|
||||||
@ -152,18 +147,14 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
// should only happen when SOCKS configured badly
|
// should only happen when SOCKS configured badly
|
||||||
showInvalidConnectionError();
|
showInvalidConnectionError();
|
||||||
abort();
|
abort();
|
||||||
e.printStackTrace();
|
logger.error("Failed to configure SOCKS proxy", e);
|
||||||
}
|
}
|
||||||
catch (InterruptedException | IOException e) {
|
catch (InterruptedException | IOException e) {
|
||||||
// TODO Auto-generated catch block
|
logger.error("An unexpected exception occurred", e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
// TODO Auto-generated catch block
|
logger.error("An unexpected exception occurred", e1);
|
||||||
// e1.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -171,10 +162,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
logger.debug("Done waiting for clients with connection state {}", hConnection.getState());
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println("done waiting for clients with: " + hConnection.getState() );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -233,12 +221,10 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
|
|||||||
try {
|
try {
|
||||||
proxy.getProxy_server().close();
|
proxy.getProxy_server().close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO Auto-generated catch block
|
logger.error("Failed to close all proxies", e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// potentialProxies = Collections.singletonList(except);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
|
|
||||||
maybeAddMapping();
|
maybeAddMapping();
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println("Added mapping for raw IP");
|
logger.debug("Added mapping for raw IP");
|
||||||
|
|
||||||
ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host()));
|
ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host()));
|
||||||
proxy.initProxy(proxy_server);
|
proxy.initProxy(proxy_server);
|
||||||
@ -62,10 +62,10 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
stateSetter.setState(HState.WAITING_FOR_CLIENT);
|
stateSetter.setState(HState.WAITING_FOR_CLIENT);
|
||||||
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
||||||
try {
|
try {
|
||||||
if (HConnection.DEBUG) System.out.println("try accept proxy");
|
logger.debug("Trying to accept a new proxy from {}", proxy_server);
|
||||||
Socket client = proxy_server.accept();
|
Socket client = proxy_server.accept();
|
||||||
|
|
||||||
if (HConnection.DEBUG) System.out.println("accepted a proxy");
|
logger.debug("Accepted a proxy {}", client);
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
@ -82,7 +82,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
logger.error("An unexpected exception occurred in proxy listener", e);
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
try {
|
try {
|
||||||
proxy.getProxy_server().close();
|
proxy.getProxy_server().close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
logger.error("Failed to close proxy server", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,6 +136,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
}
|
}
|
||||||
catch (SocketTimeoutException e) {
|
catch (SocketTimeoutException e) {
|
||||||
showInvalidConnectionError();
|
showInvalidConnectionError();
|
||||||
|
logger.error("Connection to proxy {} timed out", proxy, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
createSocksProxyThread(client);
|
createSocksProxyThread(client);
|
||||||
}
|
}
|
||||||
else if (preConnectedServerConnections.isEmpty()) {
|
else if (preConnectedServerConnections.isEmpty()) {
|
||||||
if (HConnection.DEBUG) System.out.println("pre-made server connections ran out of stock");
|
logger.error("pre-made server connections ran out of stock");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
startProxyThread(client, preConnectedServerConnections.poll(), proxy);
|
startProxyThread(client, preConnectedServerConnections.poll(), proxy);
|
||||||
@ -165,6 +166,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
maybeRemoveMapping();
|
maybeRemoveMapping();
|
||||||
stateSetter.setState(HState.NOT_CONNECTED);
|
stateSetter.setState(HState.NOT_CONNECTED);
|
||||||
showInvalidConnectionError();
|
showInvalidConnectionError();
|
||||||
|
logger.error("Failed to create socks proxy thread because configuration is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +179,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
maybeRemoveMapping();
|
maybeRemoveMapping();
|
||||||
stateSetter.setState(HState.NOT_CONNECTED);
|
stateSetter.setState(HState.NOT_CONNECTED);
|
||||||
showInvalidConnectionError();
|
showInvalidConnectionError();
|
||||||
e.printStackTrace();
|
logger.error("Failed to create socks proxy thread", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +190,5 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
|
|||||||
|
|
||||||
protected void maybeRemoveMapping() {
|
protected void maybeRemoveMapping() {
|
||||||
ipMapper.deleteMapping(proxy.getActual_domain(), proxy.getActual_port(), proxy.getIntercept_port());
|
ipMapper.deleteMapping(proxy.getActual_domain(), proxy.getActual_port(), proxy.getIntercept_port());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
package gearth.protocol.hostreplacer.hostsfile;
|
package gearth.protocol.hostreplacer.hostsfile;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Jonas on 04/04/18.
|
* Created by Jonas on 04/04/18.
|
||||||
*/
|
*/
|
||||||
class UnixHostReplacer implements HostReplacer {
|
class UnixHostReplacer implements HostReplacer {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(UnixHostReplacer.class);
|
||||||
|
|
||||||
protected String hostsFileLocation;
|
protected String hostsFileLocation;
|
||||||
|
|
||||||
UnixHostReplacer() {
|
UnixHostReplacer() {
|
||||||
@ -17,23 +24,24 @@ class UnixHostReplacer implements HostReplacer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRedirect(String[] lines) {
|
public void addRedirect(String[] lines) {
|
||||||
List<String> adders = new ArrayList<>();
|
|
||||||
for (int i = 0; i < lines.length; i++) {
|
|
||||||
adders.add(lines[i] + "\t# G-Earth replacement");
|
|
||||||
}
|
|
||||||
|
|
||||||
FileReader fr = null;
|
final List<String> adders = appendCommentToEachLine(lines);
|
||||||
BufferedReader br = null;
|
|
||||||
FileWriter fw = null;
|
|
||||||
BufferedWriter out = null;
|
|
||||||
|
|
||||||
|
FileReader fr;
|
||||||
|
BufferedReader br;
|
||||||
|
FileWriter fw;
|
||||||
|
BufferedWriter out;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ArrayList<String> fileLines = new ArrayList<>();
|
final ArrayList<String> fileLines = new ArrayList<>();
|
||||||
File f1 = new File(hostsFileLocation);
|
final File hostsFile = new File(hostsFileLocation);
|
||||||
fr = new FileReader(f1);
|
|
||||||
|
LOGGER.debug("Replacing hosts at {}", hostsFile.getAbsolutePath());
|
||||||
|
|
||||||
|
fr = new FileReader(hostsFile);
|
||||||
br = new BufferedReader(fr);
|
br = new BufferedReader(fr);
|
||||||
String line = null;
|
|
||||||
|
String line;
|
||||||
while ((line = br.readLine()) != null)
|
while ((line = br.readLine()) != null)
|
||||||
{
|
{
|
||||||
adders.remove(line);
|
adders.remove(line);
|
||||||
@ -42,7 +50,7 @@ class UnixHostReplacer implements HostReplacer {
|
|||||||
fr.close();
|
fr.close();
|
||||||
br.close();
|
br.close();
|
||||||
|
|
||||||
fw = new FileWriter(f1);
|
fw = new FileWriter(hostsFile);
|
||||||
out = new BufferedWriter(fw);
|
out = new BufferedWriter(fw);
|
||||||
|
|
||||||
for (String li : adders) {
|
for (String li : adders) {
|
||||||
@ -58,29 +66,26 @@ class UnixHostReplacer implements HostReplacer {
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ex.printStackTrace();
|
LOGGER.error("Failed to add host redirects", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeRedirect(String[] lines) {
|
public void removeRedirect(String[] lines) {
|
||||||
ArrayList<String> removers = new ArrayList<>();
|
final List<String> removers = appendCommentToEachLine(lines);
|
||||||
for (int i = 0; i < lines.length; i++) {
|
|
||||||
removers.add(lines[i] + "\t# G-Earth replacement");
|
|
||||||
}
|
|
||||||
|
|
||||||
FileReader fr = null;
|
FileReader fr;
|
||||||
BufferedReader br = null;
|
BufferedReader br;
|
||||||
FileWriter fw = null;
|
FileWriter fw;
|
||||||
BufferedWriter out = null;
|
BufferedWriter out;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ArrayList<String> fileLines = new ArrayList<String>();
|
final ArrayList<String> fileLines = new ArrayList<>();
|
||||||
File f1 = new File(hostsFileLocation);
|
final File hostsFile = new File(hostsFileLocation);
|
||||||
fr = new FileReader(f1);
|
fr = new FileReader(hostsFile);
|
||||||
br = new BufferedReader(fr);
|
br = new BufferedReader(fr);
|
||||||
String line = null;
|
String line;
|
||||||
while ((line = br.readLine()) != null)
|
while ((line = br.readLine()) != null)
|
||||||
{
|
{
|
||||||
if (!removers.contains(line))
|
if (!removers.contains(line))
|
||||||
@ -89,12 +94,13 @@ class UnixHostReplacer implements HostReplacer {
|
|||||||
fr.close();
|
fr.close();
|
||||||
br.close();
|
br.close();
|
||||||
|
|
||||||
fw = new FileWriter(f1);
|
fw = new FileWriter(hostsFile);
|
||||||
out = new BufferedWriter(fw);
|
out = new BufferedWriter(fw);
|
||||||
|
|
||||||
for (int i = 0; i < fileLines.size(); i++) {
|
for (int i = 0; i < fileLines.size(); i++) {
|
||||||
out.write(fileLines.get(i));
|
out.write(fileLines.get(i));
|
||||||
if (i != fileLines.size() - 1) out.write(System.getProperty("line.separator"));
|
if (i != fileLines.size() - 1)
|
||||||
|
out.write(System.getProperty("line.separator"));
|
||||||
}
|
}
|
||||||
out.flush();
|
out.flush();
|
||||||
fw.close();
|
fw.close();
|
||||||
@ -102,7 +108,14 @@ class UnixHostReplacer implements HostReplacer {
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ex.printStackTrace();
|
LOGGER.error("Failed to remove host replace lines", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<String> appendCommentToEachLine(String[] lines) {
|
||||||
|
return Arrays
|
||||||
|
.stream(lines)
|
||||||
|
.map(line -> line + "\t# G-Earth replacement")
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ import javafx.scene.control.Hyperlink;
|
|||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.FlowPane;
|
import javafx.scene.layout.FlowPane;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -25,7 +27,9 @@ import java.util.List;
|
|||||||
|
|
||||||
public class Rc4Obtainer {
|
public class Rc4Obtainer {
|
||||||
|
|
||||||
public static final boolean DEBUG = false;
|
private static final Logger LOGGER = LoggerFactory.getLogger(Rc4Obtainer.class);
|
||||||
|
|
||||||
|
public static final boolean DEBUG = true;
|
||||||
|
|
||||||
private final HabboClient client;
|
private final HabboClient client;
|
||||||
private List<FlashPacketHandler> flashPacketHandlers;
|
private List<FlashPacketHandler> flashPacketHandlers;
|
||||||
@ -58,8 +62,7 @@ public class Rc4Obtainer {
|
|||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
if (DEBUG) System.out.println("[+] send encrypted");
|
LOGGER.debug("[+] send encrypted");
|
||||||
|
|
||||||
boolean worked = false;
|
boolean worked = false;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (!worked && i < 4) {
|
while (!worked && i < 4) {
|
||||||
@ -70,8 +73,7 @@ public class Rc4Obtainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!worked) {
|
if (!worked) {
|
||||||
System.err.println("COULD NOT FIND RC4 TABLE");
|
LOGGER.error("COULD NOT FIND RC4 TABLE");
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Alert alert = new Alert(Alert.AlertType.WARNING, LanguageBundle.get("alert.somethingwentwrong.title"), ButtonType.OK);
|
Alert alert = new Alert(Alert.AlertType.WARNING, LanguageBundle.get("alert.somethingwentwrong.title"), ButtonType.OK);
|
||||||
|
|
||||||
@ -90,14 +92,13 @@ public class Rc4Obtainer {
|
|||||||
try {
|
try {
|
||||||
TitleBarController.create(alert).showAlert();
|
TitleBarController.create(alert).showAlert();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
LOGGER.error("Failed to create error alert", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final long endTime = System.currentTimeMillis();
|
final long endTime = System.currentTimeMillis();
|
||||||
if (DEBUG)
|
LOGGER.debug("Cracked RC4 in " + (endTime - startTime) + "ms");
|
||||||
System.out.println("Cracked RC4 in " + (endTime - startTime) + "ms");
|
|
||||||
|
|
||||||
flashPacketHandlers.forEach(FlashPacketHandler::unblock);
|
flashPacketHandlers.forEach(FlashPacketHandler::unblock);
|
||||||
}).start();
|
}).start();
|
||||||
|
@ -3,7 +3,7 @@ package gearth.protocol.memory.habboclient;
|
|||||||
import gearth.misc.OSValidator;
|
import gearth.misc.OSValidator;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.memory.habboclient.linux.LinuxHabboClient;
|
import gearth.protocol.memory.habboclient.linux.LinuxHabboClient;
|
||||||
import gearth.protocol.memory.habboclient.macOs.MacOsHabboClient;
|
import gearth.protocol.memory.habboclient.macos.MacOSHabboClient;
|
||||||
import gearth.protocol.memory.habboclient.windows.WindowsHabboClient;
|
import gearth.protocol.memory.habboclient.windows.WindowsHabboClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +15,7 @@ public class HabboClientFactory {
|
|||||||
public static HabboClient get(HConnection connection) {
|
public static HabboClient get(HConnection connection) {
|
||||||
if (OSValidator.isUnix()) return new LinuxHabboClient(connection);
|
if (OSValidator.isUnix()) return new LinuxHabboClient(connection);
|
||||||
if (OSValidator.isWindows()) return new WindowsHabboClient(connection);
|
if (OSValidator.isWindows()) return new WindowsHabboClient(connection);
|
||||||
if (OSValidator.isMac()) return new MacOsHabboClient(connection);
|
if (OSValidator.isMac()) return new MacOSHabboClient(connection);
|
||||||
|
|
||||||
// todo use rust if beneficial
|
// todo use rust if beneficial
|
||||||
|
|
||||||
|
@ -1,144 +0,0 @@
|
|||||||
package gearth.protocol.memory.habboclient.macOs;
|
|
||||||
|
|
||||||
import gearth.misc.Cacher;
|
|
||||||
import gearth.protocol.HConnection;
|
|
||||||
import gearth.protocol.HMessage;
|
|
||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.StringJoiner;
|
|
||||||
|
|
||||||
public class MacOsHabboClient extends HabboClient {
|
|
||||||
|
|
||||||
public MacOsHabboClient(HConnection connection) {
|
|
||||||
super(connection);
|
|
||||||
|
|
||||||
connection.addTrafficListener(0, message -> {
|
|
||||||
if (message.getDestination() == HMessage.Direction.TOSERVER && message.getPacket().headerId() == PRODUCTION_ID) {
|
|
||||||
production = message.getPacket().readString();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static final String OFFSETS_CACHE_KEY = "RC4Offsets";
|
|
||||||
private static final int PRODUCTION_ID = 4000;
|
|
||||||
private String production = "";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4cached() {
|
|
||||||
List<byte[]> result = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
List<String> possibleResults = readPossibleBytes(true);
|
|
||||||
|
|
||||||
if (possibleResults == null)
|
|
||||||
return new ArrayList<>();
|
|
||||||
|
|
||||||
for (String s : possibleResults)
|
|
||||||
result.add(hexStringToByteArray(s));
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<String> readPossibleBytes(boolean useCache) throws IOException, URISyntaxException {
|
|
||||||
ProcessBuilder pb;
|
|
||||||
|
|
||||||
JSONObject revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
|
|
||||||
if (revisionList == null) {
|
|
||||||
Cacher.put(OFFSETS_CACHE_KEY, new JSONObject());
|
|
||||||
revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert revisionList != null;
|
|
||||||
JSONArray cachedOffsets;
|
|
||||||
if (revisionList.has(production))
|
|
||||||
cachedOffsets = (JSONArray) revisionList.get(production);
|
|
||||||
else
|
|
||||||
cachedOffsets = null;
|
|
||||||
|
|
||||||
StringJoiner joiner = new StringJoiner(" ");
|
|
||||||
|
|
||||||
if (useCache) {
|
|
||||||
if (cachedOffsets == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Object s : cachedOffsets) {
|
|
||||||
joiner.add((String)s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String g_mem = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "/G-Mem";
|
|
||||||
if (!useCache)
|
|
||||||
pb = new ProcessBuilder(g_mem, hConnection.getClientHost() , Integer.toString(hConnection.getClientPort()));
|
|
||||||
else
|
|
||||||
pb = new ProcessBuilder(g_mem, hConnection.getClientHost() , Integer.toString(hConnection.getClientPort()), "-c" + joiner.toString());
|
|
||||||
|
|
||||||
|
|
||||||
Process p = pb.start();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
|
||||||
|
|
||||||
String line;
|
|
||||||
ArrayList<String> possibleData = new ArrayList<>();
|
|
||||||
|
|
||||||
if (cachedOffsets == null) {
|
|
||||||
cachedOffsets = new JSONArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
while((line = reader.readLine()) != null) {
|
|
||||||
if (line.length() > 1) {
|
|
||||||
if (!useCache && (count++ % 2 == 0)) {
|
|
||||||
if (!cachedOffsets.toList().contains(line)) {
|
|
||||||
cachedOffsets.put(line);
|
|
||||||
System.out.println("[+] " + line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
possibleData.add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
revisionList.put(production, cachedOffsets);
|
|
||||||
Cacher.put(OFFSETS_CACHE_KEY, revisionList);
|
|
||||||
p.destroy();
|
|
||||||
return possibleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<byte[]> getRC4possibilities() {
|
|
||||||
List<byte[]> result = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
ArrayList<String> possibleData = readPossibleBytes(false);
|
|
||||||
|
|
||||||
for (String possibleHexStr : possibleData) {
|
|
||||||
result.add(hexStringToByteArray(possibleHexStr));
|
|
||||||
}
|
|
||||||
} catch (IOException | URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] hexStringToByteArray(String s) {
|
|
||||||
int len = s.length();
|
|
||||||
byte[] data = new byte[len / 2];
|
|
||||||
for (int i = 0; i < len; i += 2) {
|
|
||||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
|
||||||
+ Character.digit(s.charAt(i+1), 16));
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,104 @@
|
|||||||
|
package gearth.protocol.memory.habboclient.macos;
|
||||||
|
|
||||||
|
import gearth.misc.StringUtils;
|
||||||
|
import gearth.protocol.HConnection;
|
||||||
|
import gearth.protocol.HMessage;
|
||||||
|
import gearth.protocol.HPacket;
|
||||||
|
import gearth.protocol.memory.habboclient.HabboClient;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a {@link HabboClient} implementation for the MacOS operating system.
|
||||||
|
*
|
||||||
|
* @author sirjonasxx / dorving (revised)
|
||||||
|
*/
|
||||||
|
public class MacOSHabboClient extends HabboClient {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(MacOSHabboClient.class);
|
||||||
|
|
||||||
|
private static final String G_MEM_EXECUTABLE_FILE_NAME = "/g_mem_mac";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The header id (opcode) of the packet that contains the value for the {@link #production} field.
|
||||||
|
*/
|
||||||
|
private static final int PRODUCTION_ID = 4000;
|
||||||
|
|
||||||
|
private String production = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link MacOSHabboClient} instance.
|
||||||
|
*
|
||||||
|
* @param connection the {@link HConnection connection} with the Habbo server.
|
||||||
|
*/
|
||||||
|
public MacOSHabboClient(HConnection connection) {
|
||||||
|
super(connection);
|
||||||
|
listenForProductionPacket(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void listenForProductionPacket(HConnection connection) {
|
||||||
|
connection.addTrafficListener(0, message -> {
|
||||||
|
if (message.getDestination() == HMessage.Direction.TOSERVER) {
|
||||||
|
final HPacket packet = message.getPacket();
|
||||||
|
if (packet.headerId() == PRODUCTION_ID) {
|
||||||
|
production = packet.readString();
|
||||||
|
LOGGER.debug("Read production packet from connection {}, set `production` to {}", connection, production);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<byte[]> getRC4cached() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<byte[]> getRC4possibilities() {
|
||||||
|
final List<byte[]> result = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
for (String possibleHexStr : readPossibleBytes())
|
||||||
|
result.add(StringUtils.hexStringToByteArray(possibleHexStr));
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
LOGGER.error("Failed to parse line as hex string", e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> readPossibleBytes() throws IOException, URISyntaxException {
|
||||||
|
final String pathToGMemExecutable = getPathToGMemExecutable();
|
||||||
|
final String clientHost = hConnection.getClientHost();
|
||||||
|
final String clientPort = Integer.toString(hConnection.getClientPort());
|
||||||
|
LOGGER.debug("Attempting to execute G-Mem executable {} with host {} at port {}", pathToGMemExecutable, clientHost, clientPort);
|
||||||
|
final Process process = new ProcessBuilder(pathToGMemExecutable, clientHost, clientPort)
|
||||||
|
.start();
|
||||||
|
final ArrayList<String> possibleData = new ArrayList<>();
|
||||||
|
try(BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||||
|
int count = 0;
|
||||||
|
String line;
|
||||||
|
while((line = reader.readLine()) != null) {
|
||||||
|
if (line.length() > 1 && (count++ % 2 != 0))
|
||||||
|
possibleData.add(line);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.error("Failed to execute G-Mem", e);
|
||||||
|
} finally {
|
||||||
|
process.destroy();
|
||||||
|
}
|
||||||
|
LOGGER.debug("Read {} from G-Mem output stream", possibleData);
|
||||||
|
return possibleData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPathToGMemExecutable() throws URISyntaxException {
|
||||||
|
return new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + G_MEM_EXECUTABLE_FILE_NAME;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package gearth.protocol.memory.habboclient.rust;
|
package gearth.protocol.memory.habboclient.rust;
|
||||||
|
|
||||||
|
import gearth.misc.StringUtils;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
import gearth.protocol.memory.habboclient.HabboClient;
|
||||||
|
|
||||||
@ -48,18 +49,9 @@ public class RustHabboClient extends HabboClient {
|
|||||||
List<byte[]> ret = new ArrayList<>();
|
List<byte[]> ret = new ArrayList<>();
|
||||||
|
|
||||||
for (String possibleHexStr : possibleData)
|
for (String possibleHexStr : possibleData)
|
||||||
ret.add(hexStringToByteArray(possibleHexStr));
|
ret.add(StringUtils.hexStringToByteArray(possibleHexStr));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] hexStringToByteArray(String s) {
|
|
||||||
int len = s.length();
|
|
||||||
byte[] data = new byte[len / 2];
|
|
||||||
for (int i = 0; i < len; i += 2) {
|
|
||||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
|
||||||
+ Character.digit(s.charAt(i+1), 16));
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package gearth.protocol.memory.habboclient.windows;
|
package gearth.protocol.memory.habboclient.windows;
|
||||||
|
|
||||||
import gearth.misc.Cacher;
|
import gearth.misc.Cacher;
|
||||||
|
import gearth.misc.StringUtils;
|
||||||
import gearth.protocol.HConnection;
|
import gearth.protocol.HConnection;
|
||||||
import gearth.protocol.HMessage;
|
import gearth.protocol.HMessage;
|
||||||
import gearth.protocol.memory.habboclient.HabboClient;
|
import gearth.protocol.memory.habboclient.HabboClient;
|
||||||
@ -44,7 +45,7 @@ public class WindowsHabboClient extends HabboClient {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
|
|
||||||
for (String s : possibleResults)
|
for (String s : possibleResults)
|
||||||
result.add(hexStringToByteArray(s));
|
result.add(StringUtils.hexStringToByteArray(s));
|
||||||
} catch (IOException | URISyntaxException e) {
|
} catch (IOException | URISyntaxException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -124,23 +125,12 @@ public class WindowsHabboClient extends HabboClient {
|
|||||||
List<byte[]> result = new ArrayList<>();
|
List<byte[]> result = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
ArrayList<String> possibleData = readPossibleBytes(false);
|
ArrayList<String> possibleData = readPossibleBytes(false);
|
||||||
|
|
||||||
for (String possibleHexStr : possibleData) {
|
for (String possibleHexStr : possibleData) {
|
||||||
result.add(hexStringToByteArray(possibleHexStr));
|
result.add(StringUtils.hexStringToByteArray(possibleHexStr));
|
||||||
}
|
}
|
||||||
} catch (IOException | URISyntaxException e) {
|
} catch (IOException | URISyntaxException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] hexStringToByteArray(String s) {
|
|
||||||
int len = s.length();
|
|
||||||
byte[] data = new byte[len / 2];
|
|
||||||
for (int i = 0; i < len; i += 2) {
|
|
||||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
|
||||||
+ Character.digit(s.charAt(i+1), 16));
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public abstract class FlashPacketHandler extends PacketHandler {
|
public abstract class FlashPacketHandler extends PacketHandler {
|
||||||
|
|
||||||
protected static final boolean DEBUG = false;
|
protected static final boolean DEBUG = true;
|
||||||
|
|
||||||
private volatile OutputStream out;
|
private volatile OutputStream out;
|
||||||
private volatile boolean isTempBlocked = false;
|
private volatile boolean isTempBlocked = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user