/* * Decompiled with CFR 0.152. */ package gearth.extensions; import gearth.extensions.ExtensionBase; import gearth.extensions.ExtensionInfo; import gearth.misc.HostInfo; import gearth.protocol.HMessage; import gearth.protocol.HPacket; import gearth.protocol.connection.HClient; import gearth.services.Constants; import gearth.services.packet_info.PacketInfoManager; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public abstract class Extension extends ExtensionBase { protected ExtensionBase.FlagsCheckListener flagRequestCallback = null; private String[] args; private volatile boolean isCorrupted = false; private static final String[] PORT_FLAG = new String[]{"--port", "-p"}; private static final String[] FILE_FLAG = new String[]{"--filename", "-f"}; private static final String[] COOKIE_FLAG = new String[]{"--auth-token", "-c"}; private volatile boolean delayed_init = false; private OutputStream out = null; private String getArgument(String[] args, String ... arg) { for (int i = 0; i < args.length - 1; ++i) { for (String str : arg) { if (!args[i].toLowerCase().equals(str.toLowerCase())) continue; return args[i + 1]; } } return null; } public Extension(String[] args) { this.args = args; if (this.getInfoAnnotations() == null) { System.err.println("Extension info not found\n\nUsage:\n@ExtensionInfo ( \n Title = \"...\",\n Description = \"...\",\n Version = \"...\",\n Author = \"...\"\n)"); this.isCorrupted = true; } if (this.getArgument(args, PORT_FLAG) == null) { System.err.println("Don't forget to include G-Earth's port in your program parameters (-p {port})"); this.isCorrupted = true; } } /* * WARNING - Removed try catching itself - possible behaviour change. */ public void run() { if (this.isCorrupted) { return; } int port = Integer.parseInt(this.getArgument(this.args, PORT_FLAG)); String file = this.getArgument(this.args, FILE_FLAG); String cookie = this.getArgument(this.args, COOKIE_FLAG); Socket gEarthExtensionServer = null; try { gEarthExtensionServer = new Socket("127.0.0.1", port); gEarthExtensionServer.setTcpNoDelay(true); InputStream in = gEarthExtensionServer.getInputStream(); DataInputStream dIn = new DataInputStream(in); this.out = gEarthExtensionServer.getOutputStream(); while (!gEarthExtensionServer.isClosed()) { int length; try { length = dIn.readInt(); } catch (EOFException exception) { break; } byte[] headerandbody = new byte[length + 4]; for (int amountRead = 0; amountRead < length; amountRead += dIn.read(headerandbody, 4 + amountRead, Math.min(dIn.available(), length - amountRead))) { } HPacket packet = new HPacket(headerandbody); packet.fixLength(); if (packet.headerId() == 2) { ExtensionInfo info = this.getInfoAnnotations(); HPacket response = new HPacket(1); response.appendString(info.Title()).appendString(info.Author()).appendString(info.Version()).appendString(info.Description()).appendBoolean(this.isOnClickMethodUsed()).appendBoolean(file != null).appendString(file == null ? "" : file).appendString(cookie == null ? "" : cookie).appendBoolean(this.canLeave()).appendBoolean(this.canDelete()); this.writeToStream(response.toBytes()); continue; } if (packet.headerId() == 5) { String host = packet.readString(); int connectionPort = packet.readInteger(); String hotelVersion = packet.readString(); String clientIdentifier = packet.readString(); HClient clientType = HClient.valueOf(packet.readString()); this.setPacketInfoManager(PacketInfoManager.readFromPacket(packet)); boolean bl = Constants.UNITY_PACKETS = clientType == HClient.UNITY; if (this.delayed_init) { this.initExtension(); this.delayed_init = false; } this.getOnConnectionObservable().fireEvent(l -> l.onConnection(host, connectionPort, hotelVersion, clientIdentifier, clientType)); this.onStartConnection(); continue; } if (packet.headerId() == 6) { this.onEndConnection(); continue; } if (packet.headerId() == 4) { if (this.flagRequestCallback != null) { int arraysize = packet.readInteger(); String[] gEarthArgs = new String[arraysize]; for (int i = 0; i < gEarthArgs.length; ++i) { gEarthArgs[i] = packet.readString(); } this.flagRequestCallback.act(gEarthArgs); } this.flagRequestCallback = null; continue; } if (packet.headerId() == 7) { this.delayed_init = packet.readBoolean(); HostInfo hostInfo = HostInfo.fromPacket(packet); this.updateHostInfo(hostInfo); if (!this.delayed_init) { this.initExtension(); } this.writeToConsole("green", "Extension \"" + this.getInfoAnnotations().Title() + "\" successfully initialized", false); continue; } if (packet.headerId() == 1) { this.onClick(); continue; } if (packet.headerId() == 3) { String stringifiedMessage = packet.readLongString(); HMessage habboMessage = new HMessage(stringifiedMessage); this.modifyMessage(habboMessage); HPacket response = new HPacket(2); response.appendLongString(habboMessage.stringify()); this.writeToStream(response.toBytes()); continue; } if (packet.headerId() != 10) continue; HostInfo hostInfo = HostInfo.fromPacket(packet); this.updateHostInfo(hostInfo); } } catch (IOException | ArrayIndexOutOfBoundsException e) { System.err.println("Connection failed; is G-Earth active?"); e.printStackTrace(); } finally { if (gEarthExtensionServer != null && !gEarthExtensionServer.isClosed()) { try { gEarthExtensionServer.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* * WARNING - Removed try catching itself - possible behaviour change. */ private void writeToStream(byte[] bytes) throws IOException { Extension extension = this; synchronized (extension) { this.out.write(bytes); } } @Override public boolean sendToClient(HPacket packet) { return this.send(packet, HMessage.Direction.TOCLIENT); } @Override public boolean sendToServer(HPacket packet) { return this.send(packet, HMessage.Direction.TOSERVER); } private boolean send(HPacket packet, HMessage.Direction direction) { if (packet.isCorrupted()) { return false; } if (!packet.isPacketComplete()) { packet.completePacket(this.packetInfoManager); } if (!packet.isPacketComplete()) { return false; } HPacket packet1 = new HPacket(4); packet1.appendByte(direction == HMessage.Direction.TOCLIENT ? (byte)0 : 1); packet1.appendInt(packet.getBytesLength()); packet1.appendBytes(packet.toBytes()); try { this.writeToStream(packet1.toBytes()); return true; } catch (IOException e) { return false; } } @Override public boolean requestFlags(ExtensionBase.FlagsCheckListener flagRequestCallback) { if (this.flagRequestCallback != null) { return false; } this.flagRequestCallback = flagRequestCallback; try { this.writeToStream(new HPacket(3).toBytes()); return true; } catch (IOException e) { e.printStackTrace(); return false; } } @Override public void writeToConsole(String colorClass, String s) { this.writeToConsole(colorClass, s, true); } private void writeToConsole(String colorClass, String s, boolean mentionTitle) { String text = "[" + colorClass + "]" + (mentionTitle ? this.getInfoAnnotations().Title() + " --> " : "") + s; HPacket packet = new HPacket(98); packet.appendString(text); try { this.writeToStream(packet.toBytes()); } catch (IOException e) { e.printStackTrace(); } } @Override protected void initExtension() { } @Override protected void onStartConnection() { } @Override protected void onEndConnection() { } @Override protected boolean canLeave() { return true; } @Override protected boolean canDelete() { return true; } }