mirror of
https://git.krews.org/morningstar/Arcturus-Community.git
synced 2024-11-23 07:20:50 +01:00
Merge branch 'feature/crypto' into 'add-crypto'
Added crypto and netty pipeline improvements See merge request morningstar/Arcturus-Community!133
This commit is contained in:
commit
6a0371c8f4
@ -1,9 +1,6 @@
|
||||
package com.eu.habbo;
|
||||
|
||||
import com.eu.habbo.core.CleanerThread;
|
||||
import com.eu.habbo.core.ConfigurationManager;
|
||||
import com.eu.habbo.core.Logging;
|
||||
import com.eu.habbo.core.TextsManager;
|
||||
import com.eu.habbo.core.*;
|
||||
import com.eu.habbo.core.consolecommands.ConsoleCommand;
|
||||
import com.eu.habbo.database.Database;
|
||||
import com.eu.habbo.habbohotel.GameEnvironment;
|
||||
@ -63,6 +60,7 @@ public final class Emulator {
|
||||
private static int timeStarted = 0;
|
||||
private static Runtime runtime;
|
||||
private static ConfigurationManager config;
|
||||
private static CryptoConfig crypto;
|
||||
private static TextsManager texts;
|
||||
private static GameServer gameServer;
|
||||
private static RCONServer rconServer;
|
||||
@ -106,6 +104,11 @@ public final class Emulator {
|
||||
|
||||
Emulator.runtime = Runtime.getRuntime();
|
||||
Emulator.config = new ConfigurationManager("config.ini");
|
||||
Emulator.crypto = new CryptoConfig(
|
||||
Emulator.getConfig().getBoolean("enc.enabled", false),
|
||||
Emulator.getConfig().getValue("enc.e"),
|
||||
Emulator.getConfig().getValue("enc.n"),
|
||||
Emulator.getConfig().getValue("enc.d"));
|
||||
Emulator.database = new Database(Emulator.getConfig());
|
||||
Emulator.config.loaded = true;
|
||||
Emulator.config.loadFromDatabase();
|
||||
@ -274,6 +277,10 @@ public final class Emulator {
|
||||
return config;
|
||||
}
|
||||
|
||||
public static CryptoConfig getCrypto() {
|
||||
return crypto;
|
||||
}
|
||||
|
||||
public static TextsManager getTexts() {
|
||||
return texts;
|
||||
}
|
||||
|
33
src/main/java/com/eu/habbo/core/CryptoConfig.java
Normal file
33
src/main/java/com/eu/habbo/core/CryptoConfig.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.eu.habbo.core;
|
||||
|
||||
public class CryptoConfig {
|
||||
|
||||
private final boolean enabled;
|
||||
private final String exponent;
|
||||
private final String modulus;
|
||||
private final String privateExponent;
|
||||
|
||||
public CryptoConfig(boolean enabled, String exponent, String modulus, String privateExponent) {
|
||||
this.enabled = enabled;
|
||||
this.exponent = exponent;
|
||||
this.modulus = modulus;
|
||||
this.privateExponent = privateExponent;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String getExponent() {
|
||||
return exponent;
|
||||
}
|
||||
|
||||
public String getModulus() {
|
||||
return modulus;
|
||||
}
|
||||
|
||||
public String getPrivateExponent() {
|
||||
return privateExponent;
|
||||
}
|
||||
|
||||
}
|
108
src/main/java/com/eu/habbo/crypto/HabboDiffieHellman.java
Normal file
108
src/main/java/com/eu/habbo/crypto/HabboDiffieHellman.java
Normal file
@ -0,0 +1,108 @@
|
||||
package com.eu.habbo.crypto;
|
||||
|
||||
import com.eu.habbo.crypto.exceptions.HabboCryptoException;
|
||||
import com.eu.habbo.crypto.utils.BigIntegerUtils;
|
||||
import com.eu.habbo.crypto.utils.HexUtils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class HabboDiffieHellman {
|
||||
|
||||
private static final int DH_PRIMES_BIT_SIZE = 128;
|
||||
private static final int DH_KEY_BIT_SIZE = 128;
|
||||
|
||||
private final HabboRSACrypto crypto;
|
||||
|
||||
private BigInteger DHPrime;
|
||||
private BigInteger DHGenerator;
|
||||
private BigInteger DHPrivate;
|
||||
private BigInteger DHPublic;
|
||||
|
||||
public HabboDiffieHellman(HabboRSACrypto crypto) {
|
||||
this.crypto = crypto;
|
||||
this.generateDHPrimes();
|
||||
this.generateDHKeys();
|
||||
}
|
||||
|
||||
public BigInteger getDHPrime() {
|
||||
return DHPrime;
|
||||
}
|
||||
|
||||
public BigInteger getDHGenerator() {
|
||||
return DHGenerator;
|
||||
}
|
||||
|
||||
private void generateDHPrimes() {
|
||||
this.DHPrime = BigInteger.probablePrime(DH_PRIMES_BIT_SIZE, ThreadLocalRandom.current());
|
||||
this.DHGenerator = BigInteger.probablePrime(DH_PRIMES_BIT_SIZE, ThreadLocalRandom.current());
|
||||
|
||||
if (this.DHGenerator.compareTo(this.DHPrime) > 0) {
|
||||
BigInteger temp = this.DHPrime;
|
||||
|
||||
this.DHPrime = this.DHGenerator;
|
||||
this.DHGenerator = temp;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDHKeys() {
|
||||
this.DHPrivate = BigInteger.probablePrime(DH_KEY_BIT_SIZE, ThreadLocalRandom.current());
|
||||
this.DHPublic = this.DHGenerator.modPow(this.DHPrivate, this.DHPrime);
|
||||
}
|
||||
|
||||
private String encryptBigInteger(BigInteger integer) throws HabboCryptoException {
|
||||
String str = integer.toString(10);
|
||||
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] encrypted = this.crypto.Sign(bytes);
|
||||
|
||||
return HexUtils.toHex(encrypted).toLowerCase();
|
||||
}
|
||||
|
||||
private BigInteger decryptBigInteger(String str) throws HabboCryptoException {
|
||||
byte[] bytes = HexUtils.toBytes(str);
|
||||
byte[] decrypted = this.crypto.Decrypt(bytes);
|
||||
String intStr = new String(decrypted, StandardCharsets.UTF_8);
|
||||
|
||||
return new BigInteger(intStr, 10);
|
||||
}
|
||||
|
||||
public String getPublicKey() throws HabboCryptoException {
|
||||
return encryptBigInteger(this.DHPublic);
|
||||
}
|
||||
|
||||
public String getSignedPrime() throws HabboCryptoException {
|
||||
return encryptBigInteger(this.DHPrime);
|
||||
}
|
||||
|
||||
public String getSignedGenerator() throws HabboCryptoException {
|
||||
return encryptBigInteger(this.DHGenerator);
|
||||
}
|
||||
|
||||
public void doHandshake(String signedPrime, String signedGenerator) throws HabboCryptoException {
|
||||
this.DHPrime = decryptBigInteger(signedPrime);
|
||||
this.DHGenerator = decryptBigInteger(signedGenerator);
|
||||
|
||||
if (this.DHPrime == null || this.DHGenerator == null) {
|
||||
throw new HabboCryptoException("DHPrime or DHGenerator was null.");
|
||||
}
|
||||
|
||||
if (this.DHPrime.compareTo(BigInteger.valueOf(2)) < 1) {
|
||||
throw new HabboCryptoException("Prime cannot be <= 2!\nPrime: " + this.DHPrime.toString());
|
||||
}
|
||||
|
||||
if (this.DHGenerator.compareTo(this.DHPrime) > -1) {
|
||||
throw new HabboCryptoException("Generator cannot be >= Prime!\nPrime: " + this.DHPrime.toString() + "\nGenerator: " + this.DHGenerator.toString());
|
||||
}
|
||||
|
||||
generateDHKeys();
|
||||
}
|
||||
|
||||
public byte[] getSharedKey(String publicKeyStr) throws HabboCryptoException {
|
||||
BigInteger publicKey = this.decryptBigInteger(publicKeyStr);
|
||||
BigInteger sharedKey = publicKey.modPow(this.DHPrivate, this.DHPrime);
|
||||
|
||||
return BigIntegerUtils.toUnsignedByteArray(sharedKey);
|
||||
}
|
||||
|
||||
}
|
21
src/main/java/com/eu/habbo/crypto/HabboEncryption.java
Normal file
21
src/main/java/com/eu/habbo/crypto/HabboEncryption.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.eu.habbo.crypto;
|
||||
|
||||
public class HabboEncryption {
|
||||
|
||||
private final HabboRSACrypto crypto;
|
||||
private final HabboDiffieHellman diffie;
|
||||
|
||||
public HabboEncryption(String e, String n, String d) {
|
||||
this.crypto = new HabboRSACrypto(e, n, d);
|
||||
this.diffie = new HabboDiffieHellman(this.crypto);
|
||||
}
|
||||
|
||||
public HabboRSACrypto getCrypto() {
|
||||
return crypto;
|
||||
}
|
||||
|
||||
public HabboDiffieHellman getDiffie() {
|
||||
return diffie;
|
||||
}
|
||||
|
||||
}
|
46
src/main/java/com/eu/habbo/crypto/HabboRC4.java
Normal file
46
src/main/java/com/eu/habbo/crypto/HabboRC4.java
Normal file
@ -0,0 +1,46 @@
|
||||
package com.eu.habbo.crypto;
|
||||
|
||||
public class HabboRC4 {
|
||||
|
||||
private int i;
|
||||
private int j;
|
||||
private final int[] table = new int[256];
|
||||
|
||||
public HabboRC4(byte[] key) {
|
||||
int length = key.length;
|
||||
|
||||
while (this.i < 256) {
|
||||
table[this.i] = this.i;
|
||||
this.i++;
|
||||
}
|
||||
|
||||
this.i = 0;
|
||||
this.j = 0;
|
||||
|
||||
while (this.i < 256) {
|
||||
this.j = ((this.j + this.table[this.i]) + (key[this.i % length] & 0xff)) % 256;
|
||||
this.swap(this.i, this.j);
|
||||
this.i++;
|
||||
}
|
||||
|
||||
this.i = 0;
|
||||
this.j = 0;
|
||||
}
|
||||
|
||||
private void swap(int a, int b) {
|
||||
int num = table[a];
|
||||
table[a] = table[b];
|
||||
table[b] = num;
|
||||
}
|
||||
|
||||
public void parse(byte[] bytes) {
|
||||
for (int index1 = 0; index1 < bytes.length; index1++) {
|
||||
this.i = (this.i + 1) % 256;
|
||||
this.j = (this.j + this.table[this.i]) % 256;
|
||||
this.swap(this.i, this.j);
|
||||
|
||||
bytes[index1] = (byte) ((bytes[index1] & 0xFF) ^ this.table[(this.table[this.i] + this.table[this.j]) % 256]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
168
src/main/java/com/eu/habbo/crypto/HabboRSACrypto.java
Normal file
168
src/main/java/com/eu/habbo/crypto/HabboRSACrypto.java
Normal file
@ -0,0 +1,168 @@
|
||||
package com.eu.habbo.crypto;
|
||||
|
||||
import com.eu.habbo.crypto.exceptions.HabboCryptoException;
|
||||
import com.eu.habbo.crypto.utils.BigIntegerUtils;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class HabboRSACrypto {
|
||||
|
||||
private final BigInteger e;
|
||||
private final BigInteger n;
|
||||
private final BigInteger d;
|
||||
private final int blockSize;
|
||||
|
||||
public HabboRSACrypto(String e, String n) {
|
||||
this.e = new BigInteger(e, 16);
|
||||
this.n = new BigInteger(n, 16);
|
||||
this.d = null;
|
||||
this.blockSize = (this.n.bitLength() + 7) / 8;
|
||||
}
|
||||
|
||||
public HabboRSACrypto(String e, String n, String d) {
|
||||
this.e = new BigInteger(e, 16);
|
||||
this.n = new BigInteger(n, 16);
|
||||
this.d = new BigInteger(d, 16);
|
||||
this.blockSize = (this.n.bitLength() + 7) / 8;
|
||||
}
|
||||
|
||||
public byte[] Encrypt(byte[] data) throws HabboCryptoException {
|
||||
return DoEncrypt(data, true, 2);
|
||||
}
|
||||
|
||||
public byte[] Decrypt(byte[] data) throws HabboCryptoException {
|
||||
return DoDecrypt(data, false, 2);
|
||||
}
|
||||
|
||||
public byte[] Sign(byte[] data) throws HabboCryptoException {
|
||||
return DoEncrypt(data, false, 1);
|
||||
}
|
||||
|
||||
public byte[] Verify(byte[] data) throws HabboCryptoException {
|
||||
return DoDecrypt(data, true, 1);
|
||||
}
|
||||
|
||||
private BigInteger DoPublic(BigInteger x) {
|
||||
return x.modPow(this.e, this.n);
|
||||
}
|
||||
|
||||
private BigInteger DoPrivate(BigInteger x) {
|
||||
return x.modPow(this.d, this.n);
|
||||
}
|
||||
|
||||
private byte[] DoEncrypt(byte[] data, boolean isPublic, int padType) throws HabboCryptoException {
|
||||
try (ByteArrayOutputStream dst = new ByteArrayOutputStream()) {
|
||||
int bl = this.blockSize;
|
||||
int end = data.length;
|
||||
MutableInt pos = new MutableInt(0);
|
||||
|
||||
while (pos.intValue() < end) {
|
||||
byte[] padded = Pkcs1Pad(data, pos, end, bl, padType);
|
||||
BigInteger block = new BigInteger(padded);
|
||||
BigInteger chunk = isPublic ? DoPublic(block) : DoPrivate(block);
|
||||
|
||||
for (int b = (int) (bl - Math.ceil(chunk.bitLength() / 8.0)); b > 0; --b) {
|
||||
dst.write(0x00);
|
||||
}
|
||||
|
||||
dst.write(BigIntegerUtils.toUnsignedByteArray(chunk));
|
||||
}
|
||||
|
||||
return dst.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new HabboCryptoException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] DoDecrypt(byte[] data, boolean isPublic, int padType) throws HabboCryptoException {
|
||||
if (data.length % this.blockSize != 0) {
|
||||
throw new HabboCryptoException("Decryption data was not in blocks of " + this.blockSize + " bytes, total " + data.length + ".");
|
||||
}
|
||||
|
||||
try (ByteArrayOutputStream dst = new ByteArrayOutputStream()) {
|
||||
int end = data.length;
|
||||
int pos = 0;
|
||||
|
||||
while (pos < end) {
|
||||
byte[] blockData = new byte[this.blockSize];
|
||||
System.arraycopy(data, pos, blockData, 0, this.blockSize);
|
||||
|
||||
BigInteger block = new BigInteger(1, blockData);
|
||||
BigInteger chunk = isPublic ? DoPublic(block) : DoPrivate(block);
|
||||
byte[] unpadded = Pkcs1Unpad(chunk.toByteArray(), this.blockSize, padType);
|
||||
|
||||
pos += this.blockSize;
|
||||
dst.write(unpadded);
|
||||
}
|
||||
|
||||
return dst.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new HabboCryptoException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] Pkcs1Pad(byte[] src, MutableInt pos, int end, int n, int padType) {
|
||||
byte[] result = new byte[n];
|
||||
int p = pos.intValue();
|
||||
end = Math.min(end, Math.min(src.length, p + n - 11));
|
||||
pos.setValue(end);
|
||||
int i = end - 1;
|
||||
|
||||
while (i >= p && n > 11) {
|
||||
result[--n] = src[i--];
|
||||
}
|
||||
|
||||
result[--n] = 0;
|
||||
|
||||
if (padType == 2) {
|
||||
while (n > 2) {
|
||||
result[--n] = (byte) ThreadLocalRandom.current().nextInt(1, 256);
|
||||
}
|
||||
} else {
|
||||
while (n > 2) {
|
||||
result[--n] = (byte) 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
result[--n] = (byte) padType;
|
||||
result[--n] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] Pkcs1Unpad(byte[] b, int n, int padType) throws HabboCryptoException {
|
||||
byte[] result = new byte[n];
|
||||
int resultPos = 0;
|
||||
int i = 0;
|
||||
|
||||
while (i < b.length && b[i] == 0) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (b.length - i != n - 1 || b[i] != padType) {
|
||||
throw new HabboCryptoException("PKCS#1 unpad: i=" + i + ", expected b[i]==" + padType + ", got b[i]=" + b[i]);
|
||||
}
|
||||
|
||||
++i;
|
||||
|
||||
while (b[i] != 0) {
|
||||
if (++i >= b.length) {
|
||||
throw new HabboCryptoException("PKCS#1 unpad: i=" + i + ", b[i-1]!=0 (=" + b[i-1] + ")");
|
||||
}
|
||||
}
|
||||
|
||||
while (++i < b.length) {
|
||||
result[resultPos++] = b[i];
|
||||
}
|
||||
|
||||
byte[] resultCopy = new byte[resultPos];
|
||||
System.arraycopy(result, 0, resultCopy, 0, resultPos);
|
||||
|
||||
return resultCopy;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.eu.habbo.crypto.exceptions;
|
||||
|
||||
public class HabboCryptoException extends Exception {
|
||||
|
||||
public HabboCryptoException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public HabboCryptoException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public HabboCryptoException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
17
src/main/java/com/eu/habbo/crypto/utils/BigIntegerUtils.java
Normal file
17
src/main/java/com/eu/habbo/crypto/utils/BigIntegerUtils.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.eu.habbo.crypto.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class BigIntegerUtils {
|
||||
|
||||
public static byte[] toUnsignedByteArray(BigInteger bigInteger) {
|
||||
byte[] bytes = bigInteger.toByteArray();
|
||||
if (bytes[0] == 0) {
|
||||
bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/com/eu/habbo/crypto/utils/HexUtils.java
Normal file
27
src/main/java/com/eu/habbo/crypto/utils/HexUtils.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.eu.habbo.crypto.utils;
|
||||
|
||||
public class HexUtils {
|
||||
|
||||
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static String toHex(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
||||
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
public static byte[] toBytes(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;
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.gameclients;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.core.Logging;
|
||||
import com.eu.habbo.crypto.HabboEncryption;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.messages.PacketManager;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
@ -18,87 +19,36 @@ import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class GameClient {
|
||||
public final ConcurrentHashMap<Integer, Integer> incomingPacketCounter = new ConcurrentHashMap<>(25);
|
||||
|
||||
private final Channel channel;
|
||||
public long lastPacketCounterCleared = Emulator.getIntUnixTimestamp();
|
||||
private final HabboEncryption encryption;
|
||||
|
||||
private Habbo habbo;
|
||||
private boolean handshakeFinished;
|
||||
private String machineId = "";
|
||||
|
||||
public final ConcurrentHashMap<Integer, Integer> incomingPacketCounter = new ConcurrentHashMap<>(25);
|
||||
public final ConcurrentHashMap<Class<? extends MessageHandler>, Long> messageTimestamps = new ConcurrentHashMap<>();
|
||||
public long lastPacketCounterCleared = Emulator.getIntUnixTimestamp();
|
||||
|
||||
public GameClient(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
|
||||
public void sendResponse(MessageComposer composer) {
|
||||
if (this.channel.isOpen()) {
|
||||
try {
|
||||
ServerMessage msg = composer.compose();
|
||||
this.sendResponse(msg);
|
||||
} catch (Exception e) {
|
||||
Emulator.getLogging().logPacketError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendResponse(ServerMessage response) {
|
||||
if (this.channel.isOpen()) {
|
||||
if (response == null || response.getHeader() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PacketManager.DEBUG_SHOW_PACKETS)
|
||||
Emulator.getLogging().logPacketLine("[" + Logging.ANSI_PURPLE + "SERVER" + Logging.ANSI_RESET + "] => [" + response.getHeader() + "] -> " + response.getBodyString());
|
||||
|
||||
this.channel.write(response.get(), this.channel.voidPromise());
|
||||
this.channel.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendResponses(ArrayList<ServerMessage> responses) {
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
|
||||
if (this.channel.isOpen()) {
|
||||
for (ServerMessage response : responses) {
|
||||
if (response == null || response.getHeader() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PacketManager.DEBUG_SHOW_PACKETS)
|
||||
Emulator.getLogging().logPacketLine("[" + Logging.ANSI_PURPLE + "SERVER" + Logging.ANSI_RESET + "] => [" + response.getHeader() + "] -> " + response.getBodyString());
|
||||
|
||||
buffer.writeBytes(response.get());
|
||||
}
|
||||
this.channel.write(buffer.copy(), this.channel.voidPromise());
|
||||
this.channel.flush();
|
||||
}
|
||||
buffer.release();
|
||||
}
|
||||
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
this.channel.close();
|
||||
|
||||
if (this.habbo != null) {
|
||||
if (this.habbo.isOnline()) {
|
||||
this.habbo.getHabboInfo().setOnline(false);
|
||||
this.habbo.disconnect();
|
||||
}
|
||||
|
||||
this.habbo = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Emulator.getLogging().logErrorLine(e);
|
||||
}
|
||||
this.encryption = Emulator.getCrypto().isEnabled()
|
||||
? new HabboEncryption(
|
||||
Emulator.getCrypto().getExponent(),
|
||||
Emulator.getCrypto().getModulus(),
|
||||
Emulator.getCrypto().getPrivateExponent())
|
||||
: null;
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
public HabboEncryption getEncryption() {
|
||||
return encryption;
|
||||
}
|
||||
|
||||
public Habbo getHabbo() {
|
||||
return this.habbo;
|
||||
}
|
||||
@ -107,6 +57,14 @@ public class GameClient {
|
||||
this.habbo = habbo;
|
||||
}
|
||||
|
||||
public boolean isHandshakeFinished() {
|
||||
return handshakeFinished;
|
||||
}
|
||||
|
||||
public void setHandshakeFinished(boolean handshakeFinished) {
|
||||
this.handshakeFinished = handshakeFinished;
|
||||
}
|
||||
|
||||
public String getMachineId() {
|
||||
return this.machineId;
|
||||
}
|
||||
@ -127,4 +85,57 @@ public class GameClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendResponse(MessageComposer composer) {
|
||||
if (this.channel.isOpen()) {
|
||||
try {
|
||||
this.channel.write(composer, this.channel.voidPromise());
|
||||
this.channel.flush();
|
||||
} catch (Exception e) {
|
||||
Emulator.getLogging().logPacketError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendResponse(ServerMessage response) {
|
||||
if (this.channel.isOpen()) {
|
||||
if (response == null || response.getHeader() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.channel.write(response, this.channel.voidPromise());
|
||||
this.channel.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendResponses(ArrayList<ServerMessage> responses) {
|
||||
if (this.channel.isOpen()) {
|
||||
for (ServerMessage response : responses) {
|
||||
if (response == null || response.getHeader() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.channel.write(response);
|
||||
}
|
||||
|
||||
this.channel.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
this.channel.close();
|
||||
|
||||
if (this.habbo != null) {
|
||||
if (this.habbo.isOnline()) {
|
||||
this.habbo.getHabboInfo().setOnline(false);
|
||||
this.habbo.disconnect();
|
||||
}
|
||||
|
||||
this.habbo = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Emulator.getLogging().logErrorLine(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package com.eu.habbo.habbohotel.gameclients;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
@ -12,7 +13,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class GameClientManager {
|
||||
public static final AttributeKey<GameClient> CLIENT = AttributeKey.valueOf("GameClient");
|
||||
|
||||
private final ConcurrentMap<ChannelId, GameClient> clients;
|
||||
|
||||
public GameClientManager() {
|
||||
@ -34,7 +35,7 @@ public class GameClientManager {
|
||||
}
|
||||
});
|
||||
|
||||
ctx.channel().attr(CLIENT).set(client);
|
||||
ctx.channel().attr(GameServerAttributes.CLIENT).set(client);
|
||||
ctx.fireChannelRegistered();
|
||||
|
||||
return this.clients.putIfAbsent(ctx.channel().id(), client) == null;
|
||||
@ -46,13 +47,13 @@ public class GameClientManager {
|
||||
}
|
||||
|
||||
private void disposeClient(Channel channel) {
|
||||
GameClient client = channel.attr(CLIENT).get();
|
||||
GameClient client = channel.attr(GameServerAttributes.CLIENT).get();
|
||||
|
||||
if (client != null) {
|
||||
client.dispose();
|
||||
}
|
||||
channel.deregister();
|
||||
channel.attr(CLIENT).set(null);
|
||||
channel.attr(GameServerAttributes.CLIENT).set(null);
|
||||
channel.closeFuture();
|
||||
channel.close();
|
||||
this.clients.remove(channel.id());
|
||||
|
@ -78,4 +78,8 @@ public class ClientMessage {
|
||||
return this.buffer.readableBytes();
|
||||
}
|
||||
|
||||
public boolean release() {
|
||||
return this.buffer.release();
|
||||
}
|
||||
|
||||
}
|
@ -260,8 +260,8 @@ public class PacketManager {
|
||||
|
||||
private void registerHandshake() throws Exception {
|
||||
this.registerHandler(Incoming.ReleaseVersionEvent, ReleaseVersionEvent.class);
|
||||
this.registerHandler(Incoming.GenerateSecretKeyEvent, GenerateSecretKeyEvent.class);
|
||||
this.registerHandler(Incoming.RequestBannerToken, RequestBannerToken.class);
|
||||
this.registerHandler(Incoming.InitDiffieHandshake, InitDiffieHandshakeEvent.class);
|
||||
this.registerHandler(Incoming.CompleteDiffieHandshake, CompleteDiffieHandshakeEvent.class);
|
||||
this.registerHandler(Incoming.SecureLoginEvent, SecureLoginEvent.class);
|
||||
this.registerHandler(Incoming.MachineIDEvent, MachineIDEvent.class);
|
||||
this.registerHandler(Incoming.UsernameEvent, UsernameEvent.class);
|
||||
|
@ -1,401 +0,0 @@
|
||||
package com.eu.habbo.messages;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.messages.incoming.Incoming;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.incoming.achievements.RequestAchievementsEvent;
|
||||
import com.eu.habbo.messages.incoming.ambassadors.AmbassadorAlertCommandEvent;
|
||||
import com.eu.habbo.messages.incoming.ambassadors.AmbassadorVisitCommandEvent;
|
||||
import com.eu.habbo.messages.incoming.catalog.*;
|
||||
import com.eu.habbo.messages.incoming.catalog.marketplace.*;
|
||||
import com.eu.habbo.messages.incoming.catalog.recycler.OpenRecycleBoxEvent;
|
||||
import com.eu.habbo.messages.incoming.catalog.recycler.RecycleEvent;
|
||||
import com.eu.habbo.messages.incoming.catalog.recycler.ReloadRecyclerEvent;
|
||||
import com.eu.habbo.messages.incoming.catalog.recycler.RequestRecyclerLogicEvent;
|
||||
import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorRequestBlockedTilesEvent;
|
||||
import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorRequestDoorSettingsEvent;
|
||||
import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorSaveEvent;
|
||||
import com.eu.habbo.messages.incoming.friends.*;
|
||||
import com.eu.habbo.messages.incoming.guilds.*;
|
||||
import com.eu.habbo.messages.incoming.handshake.*;
|
||||
import com.eu.habbo.messages.incoming.helper.RequestTalentTrackEvent;
|
||||
import com.eu.habbo.messages.incoming.hotelview.HotelViewDataEvent;
|
||||
import com.eu.habbo.messages.incoming.hotelview.HotelViewEvent;
|
||||
import com.eu.habbo.messages.incoming.hotelview.HotelViewRequestBonusRareEvent;
|
||||
import com.eu.habbo.messages.incoming.hotelview.RequestNewsListEvent;
|
||||
import com.eu.habbo.messages.incoming.inventory.RequestInventoryBadgesEvent;
|
||||
import com.eu.habbo.messages.incoming.inventory.RequestInventoryBotsEvent;
|
||||
import com.eu.habbo.messages.incoming.inventory.RequestInventoryItemsEvent;
|
||||
import com.eu.habbo.messages.incoming.inventory.RequestInventoryPetsEvent;
|
||||
import com.eu.habbo.messages.incoming.modtool.*;
|
||||
import com.eu.habbo.messages.incoming.navigator.*;
|
||||
import com.eu.habbo.messages.incoming.polls.AnswerPollEvent;
|
||||
import com.eu.habbo.messages.incoming.polls.CancelPollEvent;
|
||||
import com.eu.habbo.messages.incoming.polls.GetPollDataEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.*;
|
||||
import com.eu.habbo.messages.incoming.rooms.bots.BotPickupEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.bots.BotPlaceEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.bots.BotSaveSettingsEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.bots.BotSettingsEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.items.*;
|
||||
import com.eu.habbo.messages.incoming.rooms.items.jukebox.JukeBoxEventOne;
|
||||
import com.eu.habbo.messages.incoming.rooms.items.jukebox.JukeBoxEventTwo;
|
||||
import com.eu.habbo.messages.incoming.rooms.items.jukebox.JukeBoxRequestPlayListEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceCancelEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.items.rentablespace.RentSpaceEvent;
|
||||
import com.eu.habbo.messages.incoming.rooms.pets.*;
|
||||
import com.eu.habbo.messages.incoming.rooms.users.*;
|
||||
import com.eu.habbo.messages.incoming.trading.*;
|
||||
import com.eu.habbo.messages.incoming.unknown.RequestResolutionEvent;
|
||||
import com.eu.habbo.messages.incoming.unknown.UnknownEvent1;
|
||||
import com.eu.habbo.messages.incoming.users.*;
|
||||
import com.eu.habbo.messages.incoming.wired.WiredConditionSaveDataEvent;
|
||||
import com.eu.habbo.messages.incoming.wired.WiredEffectSaveDataEvent;
|
||||
import com.eu.habbo.messages.incoming.wired.WiredTriggerSaveDataEvent;
|
||||
import gnu.trove.map.hash.THashMap;
|
||||
|
||||
public class PacketManager_1006 {
|
||||
|
||||
private final THashMap<Integer, Class<? extends MessageHandler>> incoming;
|
||||
|
||||
public PacketManager_1006() {
|
||||
this.incoming = new THashMap<>();
|
||||
|
||||
this.registerCatalog();
|
||||
this.registerHandshake();
|
||||
this.registerFriends();
|
||||
this.registerNavigator();
|
||||
this.registerUsers();
|
||||
this.registerHotelview();
|
||||
this.registerInventory();
|
||||
this.registerRooms();
|
||||
this.registerPolls();
|
||||
this.registerUnknown();
|
||||
this.registerModTool();
|
||||
this.registerTrading();
|
||||
this.registerGuilds();
|
||||
this.registerPets();
|
||||
this.registerWired();
|
||||
this.registerAchievements();
|
||||
this.registerFloorPlanEditor();
|
||||
this.registerAmbassadors();
|
||||
}
|
||||
|
||||
void registerHandler(Integer header, Class<? extends MessageHandler> handler) {
|
||||
this.incoming.putIfAbsent(header, handler);
|
||||
}
|
||||
|
||||
public void handlePacket(GameClient client, ClientMessage packet) {
|
||||
if (client == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
if (this.isRegistered(packet.getMessageId())) {
|
||||
if (Emulator.getConfig().getBoolean("debug.show.packets"))
|
||||
Emulator.getLogging().logPacketLine("[CLIENT][" + packet.getMessageId() + "] => " + packet.getMessageBody());
|
||||
|
||||
MessageHandler handler = this.incoming.get(packet.getMessageId()).newInstance();
|
||||
|
||||
handler.client = client;
|
||||
handler.packet = packet;
|
||||
|
||||
handler.handle();
|
||||
|
||||
} else {
|
||||
if (Emulator.getConfig().getBoolean("debug.show.packets"))
|
||||
Emulator.getLogging().logPacketLine("[CLIENT][UNDEFINED][" + packet.getMessageId() + "] => " + packet.getMessageBody());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Emulator.getLogging().logErrorLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isRegistered(int header) {
|
||||
return this.incoming.containsKey(header);
|
||||
}
|
||||
|
||||
private void registerAmbassadors() {
|
||||
this.registerHandler(Incoming.AmbassadorAlertCommandEvent, AmbassadorAlertCommandEvent.class);
|
||||
this.registerHandler(Incoming.AmbassadorVisitCommandEvent, AmbassadorVisitCommandEvent.class);
|
||||
}
|
||||
|
||||
private void registerCatalog() {
|
||||
this.registerHandler(Incoming.RequestRecylerLogicEvent, RequestRecyclerLogicEvent.class);
|
||||
this.registerHandler(Incoming.RequestDiscountEvent, RequestDiscountEvent.class);
|
||||
this.registerHandler(Incoming.RequestGiftConfigurationEvent, RequestGiftConfigurationEvent.class);
|
||||
this.registerHandler(Incoming.GetMarketplaceConfigEvent, RequestMarketplaceConfigEvent.class);
|
||||
this.registerHandler(Incoming.RequestCatalogModeEvent, RequestCatalogModeEvent.class);
|
||||
this.registerHandler(Incoming.RequestCatalogIndexEvent, RequestCatalogIndexEvent.class);
|
||||
this.registerHandler(Incoming.RequestCatalogPageEvent, RequestCatalogPageEvent.class);
|
||||
this.registerHandler(Incoming.CatalogBuyItemAsGiftEvent, CatalogBuyItemAsGiftEvent.class);
|
||||
this.registerHandler(Incoming.CatalogBuyItemEvent, CatalogBuyItemEvent.class);
|
||||
this.registerHandler(Incoming.RedeemVoucherEvent, RedeemVoucherEvent.class);
|
||||
this.registerHandler(Incoming.ReloadRecyclerEvent, ReloadRecyclerEvent.class);
|
||||
this.registerHandler(Incoming.RecycleEvent, RecycleEvent.class);
|
||||
this.registerHandler(Incoming.OpenRecycleBoxEvent, OpenRecycleBoxEvent.class);
|
||||
this.registerHandler(Incoming.RequestOwnItemsEvent, RequestOwnItemsEvent.class);
|
||||
this.registerHandler(Incoming.TakeBackItemEvent, TakeBackItemEvent.class);
|
||||
this.registerHandler(Incoming.RequestOffersEvent, RequestOffersEvent.class);
|
||||
this.registerHandler(Incoming.RequestItemInfoEvent, RequestItemInfoEvent.class);
|
||||
this.registerHandler(Incoming.BuyItemEvent, BuyItemEvent.class);
|
||||
this.registerHandler(Incoming.RequestSellItemEvent, RequestSellItemEvent.class);
|
||||
this.registerHandler(Incoming.SellItemEvent, SellItemEvent.class);
|
||||
this.registerHandler(Incoming.RequestCreditsEvent, RequestCreditsEvent.class);
|
||||
this.registerHandler(Incoming.RequestPetBreedsEvent, RequestPetBreedsEvent.class);
|
||||
this.registerHandler(Incoming.CheckPetNameEvent, CheckPetNameEvent.class);
|
||||
this.registerHandler(Incoming.GetClubDataEvent, RequestClubDataEvent.class);
|
||||
this.registerHandler(Incoming.RequestClubGiftsEvent, RequestClubGiftsEvent.class);
|
||||
this.registerHandler(Incoming.CatalogSearchedItemEvent, CatalogSearchedItemEvent.class);
|
||||
}
|
||||
|
||||
private void registerHandshake() {
|
||||
this.registerHandler(Incoming.ReleaseVersionEvent, ReleaseVersionEvent.class);
|
||||
this.registerHandler(Incoming.GenerateSecretKeyEvent, GenerateSecretKeyEvent.class);
|
||||
this.registerHandler(Incoming.RequestBannerToken, RequestBannerToken.class);
|
||||
this.registerHandler(Incoming.SecureLoginEvent, SecureLoginEvent.class);
|
||||
this.registerHandler(Incoming.MachineIDEvent, MachineIDEvent.class);
|
||||
this.registerHandler(Incoming.UsernameEvent, UsernameEvent.class);
|
||||
this.registerHandler(Incoming.PingEvent, PingEvent.class);
|
||||
}
|
||||
|
||||
private void registerFriends() {
|
||||
this.registerHandler(Incoming.RequestFriendsEvent, RequestFriendsEvent.class);
|
||||
this.registerHandler(Incoming.ChangeRelationEvent, ChangeRelationEvent.class);
|
||||
this.registerHandler(Incoming.RemoveFriendEvent, RemoveFriendEvent.class);
|
||||
this.registerHandler(Incoming.SearchUserEvent, SearchUserEvent.class);
|
||||
this.registerHandler(Incoming.FriendRequestEvent, FriendRequestEvent.class);
|
||||
this.registerHandler(Incoming.AcceptFriendRequest, AcceptFriendRequestEvent.class);
|
||||
this.registerHandler(Incoming.FriendPrivateMessageEvent, FriendPrivateMessageEvent.class);
|
||||
this.registerHandler(Incoming.RequestFriendRequestEvent, RequestFriendRequestsEvent.class);
|
||||
this.registerHandler(Incoming.StalkFriendEvent, StalkFriendEvent.class);
|
||||
this.registerHandler(Incoming.RequestInitFriendsEvent, RequestInitFriendsEvent.class);
|
||||
this.registerHandler(Incoming.FindNewFriendsEvent, FindNewFriendsEvent.class);
|
||||
this.registerHandler(Incoming.InviteFriendsEvent, InviteFriendsEvent.class);
|
||||
}
|
||||
|
||||
private void registerUsers() {
|
||||
this.registerHandler(Incoming.RequestUserDataEvent, RequestUserDataEvent.class);
|
||||
this.registerHandler(Incoming.RequestUserCreditsEvent, RequestUserCreditsEvent.class);
|
||||
this.registerHandler(Incoming.RequestUserClubEvent, RequestUserClubEvent.class);
|
||||
this.registerHandler(Incoming.RequestMeMenuSettingsEvent, RequestMeMenuSettingsEvent.class);
|
||||
this.registerHandler(Incoming.RequestUserCitizinShipEvent, RequestUserCitizinShipEvent.class);
|
||||
this.registerHandler(Incoming.RequestUserProfileEvent, RequestUserProfileEvent.class);
|
||||
this.registerHandler(Incoming.RequestProfileFriendsEvent, RequestProfileFriendsEvent.class);
|
||||
this.registerHandler(Incoming.RequestUserWardrobeEvent, RequestUserWardrobeEvent.class);
|
||||
this.registerHandler(Incoming.SaveWardrobeEvent, SaveWardrobeEvent.class);
|
||||
this.registerHandler(Incoming.SaveMottoEvent, SaveMottoEvent.class);
|
||||
this.registerHandler(Incoming.UserSaveLookEvent, UserSaveLookEvent.class);
|
||||
this.registerHandler(Incoming.UserWearBadgeEvent, UserWearBadgeEvent.class);
|
||||
this.registerHandler(Incoming.RequestWearingBadgesEvent, RequestWearingBadgesEvent.class);
|
||||
this.registerHandler(Incoming.SaveUserVolumesEvent, SaveUserVolumesEvent.class);
|
||||
this.registerHandler(Incoming.SaveBlockCameraFollowEvent, SaveBlockCameraFollowEvent.class);
|
||||
this.registerHandler(Incoming.SaveIgnoreRoomInvitesEvent, SaveIgnoreRoomInvitesEvent.class);
|
||||
this.registerHandler(Incoming.SavePreferOldChatEvent, SavePreferOldChatEvent.class);
|
||||
}
|
||||
|
||||
private void registerNavigator() {
|
||||
this.registerHandler(Incoming.RequestRoomCategoriesEvent, RequestRoomCategoriesEvent.class);
|
||||
this.registerHandler(Incoming.RequestPublicRoomsEvent, RequestPublicRoomsEvent.class);
|
||||
this.registerHandler(Incoming.RequestPopularRoomsEvent, RequestPopularRoomsEvent.class);
|
||||
this.registerHandler(Incoming.RequestHighestScoreRoomsEvent, RequestHighestScoreRoomsEvent.class);
|
||||
this.registerHandler(Incoming.RequestMyRoomsEvent, RequestMyRoomsEvent.class);
|
||||
this.registerHandler(Incoming.RequestCanCreateRoomEvent, RequestCanCreateRoomEvent.class);
|
||||
this.registerHandler(Incoming.RequestPromotedRoomsEvent, RequestPromotedRoomsEvent.class);
|
||||
this.registerHandler(Incoming.RequestCreateRoomEvent, RequestCreateRoomEvent.class);
|
||||
this.registerHandler(Incoming.RequestTagsEvent, RequestTagsEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsByTagEvent, SearchRoomsByTagEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsEvent, SearchRoomsEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsFriendsNowEvent, SearchRoomsFriendsNowEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsFriendsOwnEvent, SearchRoomsFriendsOwnEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsWithRightsEvent, SearchRoomsWithRightsEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsInGroupEvent, SearchRoomsInGroupEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsMyFavoriteEvent, SearchRoomsMyFavouriteEvent.class);
|
||||
this.registerHandler(Incoming.SearchRoomsVisitedEvent, SearchRoomsVisitedEvent.class);
|
||||
this.registerHandler(Incoming.RequestNewNavigatorDataEvent, RequestNewNavigatorDataEvent.class);
|
||||
this.registerHandler(Incoming.RequestNewNavigatorRoomsEvent, RequestNewNavigatorRoomsEvent.class);
|
||||
this.registerHandler(Incoming.NewNavigatorActionEvent, NewNavigatorActionEvent.class);
|
||||
}
|
||||
|
||||
private void registerHotelview() {
|
||||
this.registerHandler(Incoming.HotelViewEvent, HotelViewEvent.class);
|
||||
this.registerHandler(Incoming.HotelViewRequestBonusRareEvent, HotelViewRequestBonusRareEvent.class);
|
||||
this.registerHandler(Incoming.RequestNewsListEvent, RequestNewsListEvent.class);
|
||||
this.registerHandler(Incoming.HotelViewDataEvent, HotelViewDataEvent.class);
|
||||
}
|
||||
|
||||
private void registerInventory() {
|
||||
this.registerHandler(Incoming.RequestInventoryBadgesEvent, RequestInventoryBadgesEvent.class);
|
||||
this.registerHandler(Incoming.RequestInventoryBotsEvent, RequestInventoryBotsEvent.class);
|
||||
this.registerHandler(Incoming.RequestInventoryItemsEvent, RequestInventoryItemsEvent.class);
|
||||
this.registerHandler(Incoming.HotelViewInventoryEvent, RequestInventoryItemsEvent.class);
|
||||
this.registerHandler(Incoming.RequestInventoryPetsEvent, RequestInventoryPetsEvent.class);
|
||||
}
|
||||
|
||||
void registerRooms() {
|
||||
this.registerHandler(Incoming.RequestRoomLoadEvent, RequestRoomLoadEvent.class);
|
||||
this.registerHandler(Incoming.RequestHeightmapEvent, RequestRoomHeightmapEvent.class);
|
||||
this.registerHandler(Incoming.RequestRoomHeightmapEvent, RequestRoomHeightmapEvent.class);
|
||||
this.registerHandler(Incoming.RoomVoteEvent, RoomVoteEvent.class);
|
||||
this.registerHandler(Incoming.RequestRoomDataEvent, RequestRoomDataEvent.class);
|
||||
this.registerHandler(Incoming.RoomSettingsSaveEvent, RoomSettingsSaveEvent.class);
|
||||
this.registerHandler(Incoming.RoomPlaceItemEvent, RoomPlaceItemEvent.class);
|
||||
this.registerHandler(Incoming.RotateMoveItemEvent, RotateMoveItemEvent.class);
|
||||
this.registerHandler(Incoming.MoveWallItemEvent, MoveWallItemEvent.class);
|
||||
this.registerHandler(Incoming.RoomPickupItemEvent, RoomPickupItemEvent.class);
|
||||
this.registerHandler(Incoming.RoomPlacePaintEvent, RoomPlacePaintEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserStartTypingEvent, RoomUserStartTypingEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserStopTypingEvent, RoomUserStopTypingEvent.class);
|
||||
this.registerHandler(Incoming.ToggleFloorItemEvent, ToggleFloorItemEvent.class);
|
||||
this.registerHandler(Incoming.ToggleWallItemEvent, ToggleWallItemEvent.class);
|
||||
this.registerHandler(Incoming.RoomBackgroundEvent, RoomBackgroundEvent.class);
|
||||
this.registerHandler(Incoming.MannequinSaveNameEvent, MannequinSaveNameEvent.class);
|
||||
this.registerHandler(Incoming.MannequinSaveLookEvent, MannequinSaveLookEvent.class);
|
||||
this.registerHandler(Incoming.AdvertisingSaveEvent, AdvertisingSaveEvent.class);
|
||||
this.registerHandler(Incoming.RequestRoomSettingsEvent, RequestRoomSettingsEvent.class);
|
||||
this.registerHandler(Incoming.MoodLightSettingsEvent, MoodLightSettingsEvent.class);
|
||||
this.registerHandler(Incoming.MoodLightTurnOnEvent, MoodLightTurnOnEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserDropHandItemEvent, RoomUserDropHandItemEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserLookAtPoint, RoomUserLookAtPoint.class);
|
||||
this.registerHandler(Incoming.RoomUserTalkEvent, RoomUserTalkEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserShoutEvent, RoomUserShoutEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserWhisperEvent, RoomUserWhisperEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserActionEvent, RoomUserActionEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserSitEvent, RoomUserSitEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserDanceEvent, RoomUserDanceEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserSignEvent, RoomUserSignEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserWalkEvent, RoomUserWalkEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserGiveRespectEvent, RoomUserGiveRespectEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserGiveRightsEvent, RoomUserGiveRightsEvent.class);
|
||||
this.registerHandler(Incoming.RequestRoomRightsEvent, RequestRoomRightsEvent.class);
|
||||
this.registerHandler(Incoming.RoomRemoveAllRightsEvent, RoomRemoveAllRightsEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserRemoveRightsEvent, RoomUserRemoveRightsEvent.class);
|
||||
this.registerHandler(Incoming.BotPlaceEvent, BotPlaceEvent.class);
|
||||
this.registerHandler(Incoming.BotPickupEvent, BotPickupEvent.class);
|
||||
this.registerHandler(Incoming.BotSaveSettingsEvent, BotSaveSettingsEvent.class);
|
||||
this.registerHandler(Incoming.BotSettingsEvent, BotSettingsEvent.class);
|
||||
this.registerHandler(Incoming.TriggerDiceEvent, TriggerDiceEvent.class);
|
||||
this.registerHandler(Incoming.CloseDiceEvent, CloseDiceEvent.class);
|
||||
this.registerHandler(Incoming.TriggerColorWheelEvent, TriggerColorWheelEvent.class);
|
||||
this.registerHandler(Incoming.RedeemItemEvent, RedeemItemEvent.class);
|
||||
this.registerHandler(Incoming.PetPlaceEvent, PetPlaceEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserKickEvent, RoomUserKickEvent.class);
|
||||
this.registerHandler(Incoming.SetStackHelperHeightEvent, SetStackHelperHeightEvent.class);
|
||||
this.registerHandler(Incoming.TriggerOneWayGateEvent, TriggerOneWayGateEvent.class);
|
||||
this.registerHandler(Incoming.HandleDoorbellEvent, HandleDoorbellEvent.class);
|
||||
this.registerHandler(Incoming.RedeemClothingEvent, RedeemClothingEvent.class);
|
||||
this.registerHandler(Incoming.PostItPlaceEvent, PostItPlaceEvent.class);
|
||||
this.registerHandler(Incoming.PostItRequestDataEvent, PostItRequestDataEvent.class);
|
||||
this.registerHandler(Incoming.PostItSaveDataEvent, PostItSaveDataEvent.class);
|
||||
this.registerHandler(Incoming.PostItDeleteEvent, PostItDeleteEvent.class);
|
||||
this.registerHandler(Incoming.MoodLightSaveSettingsEvent, MoodLightSaveSettingsEvent.class);
|
||||
this.registerHandler(Incoming.RentSpaceEvent, RentSpaceEvent.class);
|
||||
this.registerHandler(Incoming.RentSpaceCancelEvent, RentSpaceCancelEvent.class);
|
||||
this.registerHandler(Incoming.SetHomeRoomEvent, SetHomeRoomEvent.class);
|
||||
this.registerHandler(Incoming.RoomUserGiveHandItemEvent, RoomUserGiveHandItemEvent.class);
|
||||
this.registerHandler(Incoming.RoomMuteEvent, RoomMuteEvent.class);
|
||||
this.registerHandler(Incoming.RequestRoomWordFilterEvent, RequestRoomWordFilterEvent.class);
|
||||
this.registerHandler(Incoming.RoomWordFilterModifyEvent, RoomWordFilterModifyEvent.class);
|
||||
this.registerHandler(Incoming.RoomStaffPickEvent, RoomStaffPickEvent.class);
|
||||
this.registerHandler(Incoming.RoomRequestBannedUsersEvent, RoomRequestBannedUsersEvent.class);
|
||||
this.registerHandler(Incoming.JukeBoxRequestTrackCodeEvent, JukeBoxRequestTrackCodeEvent.class);
|
||||
this.registerHandler(Incoming.JukeBoxRequestTrackDataEvent, JukeBoxRequestTrackDataEvent.class);
|
||||
this.registerHandler(Incoming.JukeBoxRequestPlayListEvent, JukeBoxRequestPlayListEvent.class);
|
||||
this.registerHandler(Incoming.JukeBoxEventOne, JukeBoxEventOne.class);
|
||||
this.registerHandler(Incoming.JukeBoxEventTwo, JukeBoxEventTwo.class);
|
||||
}
|
||||
|
||||
void registerPolls() {
|
||||
this.registerHandler(Incoming.CancelPollEvent, CancelPollEvent.class);
|
||||
this.registerHandler(Incoming.GetPollDataEvent, GetPollDataEvent.class);
|
||||
this.registerHandler(Incoming.AnswerPollEvent, AnswerPollEvent.class);
|
||||
}
|
||||
|
||||
void registerModTool() {
|
||||
this.registerHandler(Incoming.ModToolRequestRoomInfoEvent, ModToolRequestRoomInfoEvent.class);
|
||||
this.registerHandler(Incoming.ModToolRequestRoomChatlogEvent, ModToolRequestRoomChatlogEvent.class);
|
||||
this.registerHandler(Incoming.ModToolRequestUserInfoEvent, ModToolRequestUserInfoEvent.class);
|
||||
this.registerHandler(Incoming.ModToolPickTicketEvent, ModToolPickTicketEvent.class);
|
||||
this.registerHandler(Incoming.ModToolCloseTicketEvent, ModToolCloseTicketEvent.class);
|
||||
this.registerHandler(Incoming.ModToolReleaseTicketEvent, ModToolReleaseTicketEvent.class);
|
||||
this.registerHandler(Incoming.ModToolAlertEvent, ModToolAlertEvent.class);
|
||||
this.registerHandler(Incoming.ModToolWarnEvent, ModToolAlertEvent.class);
|
||||
this.registerHandler(Incoming.ModToolKickEvent, ModToolKickEvent.class);
|
||||
this.registerHandler(Incoming.ModToolRoomAlertEvent, ModToolRoomAlertEvent.class);
|
||||
this.registerHandler(Incoming.ModToolRequestUserChatlogEvent, ModToolRequestUserChatlogEvent.class);
|
||||
this.registerHandler(Incoming.ModToolChangeRoomSettingsEvent, ModToolChangeRoomSettingsEvent.class);
|
||||
this.registerHandler(Incoming.ModToolRequestRoomVisitsEvent, ModToolRequestRoomVisitsEvent.class);
|
||||
this.registerHandler(Incoming.ModToolRequestIssueChatlogEvent, ModToolRequestIssueChatlogEvent.class);
|
||||
this.registerHandler(Incoming.ModToolRequestRoomUserChatlogEvent, ModToolRequestRoomUserChatlogEvent.class);
|
||||
|
||||
this.registerHandler(Incoming.RequestReportRoomEvent, RequestReportRoomEvent.class);
|
||||
this.registerHandler(Incoming.ReportEvent, ReportEvent.class);
|
||||
}
|
||||
|
||||
void registerTrading() {
|
||||
this.registerHandler(Incoming.TradeStartEvent, TradeStartEvent.class);
|
||||
this.registerHandler(Incoming.TradeOfferItemEvent, TradeOfferItemEvent.class);
|
||||
this.registerHandler(Incoming.TradeCancelOfferItemEvent, TradeCancelOfferItemEvent.class);
|
||||
this.registerHandler(Incoming.TradeAcceptEvent, TradeAcceptEvent.class);
|
||||
this.registerHandler(Incoming.TradeUnAcceptEvent, TradeUnAcceptEvent.class);
|
||||
this.registerHandler(Incoming.TradeConfirmEvent, TradeConfirmEvent.class);
|
||||
this.registerHandler(Incoming.TradeCloseEvent, TradeCloseEvent.class);
|
||||
}
|
||||
|
||||
void registerGuilds() {
|
||||
this.registerHandler(Incoming.RequestGuildBuyRoomsEvent, RequestGuildBuyRoomsEvent.class);
|
||||
this.registerHandler(Incoming.RequestGuildPartsEvent, RequestGuildPartsEvent.class);
|
||||
this.registerHandler(Incoming.RequestGuildBuyEvent, RequestGuildBuyEvent.class);
|
||||
this.registerHandler(Incoming.RequestGuildInfoEvent, RequestGuildInfoEvent.class);
|
||||
this.registerHandler(Incoming.RequestGuildManageEvent, RequestGuildManageEvent.class);
|
||||
this.registerHandler(Incoming.RequestGuildMembersEvent, RequestGuildMembersEvent.class);
|
||||
this.registerHandler(Incoming.RequestGuildJoinEvent, RequestGuildJoinEvent.class);
|
||||
this.registerHandler(Incoming.GuildChangeNameDescEvent, GuildChangeNameDescEvent.class);
|
||||
this.registerHandler(Incoming.GuildChangeBadgeEvent, GuildChangeBadgeEvent.class);
|
||||
this.registerHandler(Incoming.GuildChangeColorsEvent, GuildChangeColorsEvent.class);
|
||||
this.registerHandler(Incoming.GuildRemoveAdminEvent, GuildRemoveAdminEvent.class);
|
||||
this.registerHandler(Incoming.GuildRemoveMemberEvent, GuildRemoveMemberEvent.class);
|
||||
this.registerHandler(Incoming.GuildChangeSettingsEvent, GuildChangeSettingsEvent.class);
|
||||
this.registerHandler(Incoming.GuildAcceptMembershipEvent, GuildAcceptMembershipEvent.class);
|
||||
this.registerHandler(Incoming.GuildDeclineMembershipEvent, GuildDeclineMembershipEvent.class);
|
||||
this.registerHandler(Incoming.GuildSetAdminEvent, GuildSetAdminEvent.class);
|
||||
this.registerHandler(Incoming.GuildSetFavoriteEvent, GuildSetFavoriteEvent.class);
|
||||
this.registerHandler(Incoming.RequestOwnGuildsEvent, RequestOwnGuildsEvent.class);
|
||||
this.registerHandler(Incoming.RequestGuildFurniWidgetEvent, RequestGuildFurniWidgetEvent.class);
|
||||
this.registerHandler(Incoming.GuildConfirmRemoveMemberEvent, GuildConfirmRemoveMemberEvent.class);
|
||||
//this.registerHandler(Incoming.GuildRemoveFavoriteEvent, GuildRemoveFavoriteEvent.class);
|
||||
this.registerHandler(Incoming.GuildDeleteEvent, GuildDeleteEvent.class);
|
||||
}
|
||||
|
||||
void registerPets() {
|
||||
this.registerHandler(Incoming.RequestPetInformationEvent, RequestPetInformationEvent.class);
|
||||
this.registerHandler(Incoming.PetPickupEvent, PetPickupEvent.class);
|
||||
this.registerHandler(Incoming.ScratchPetEvent, ScratchPetEvent.class);
|
||||
this.registerHandler(Incoming.RequestPetTrainingPanelEvent, RequestPetTrainingPanelEvent.class);
|
||||
this.registerHandler(Incoming.PetUseItemEvent, PetUseItemEvent.class);
|
||||
this.registerHandler(Incoming.HorseRideSettingsEvent, PetRideSettingsEvent.class);
|
||||
this.registerHandler(Incoming.HorseRideEvent, PetRideEvent.class);
|
||||
}
|
||||
|
||||
void registerWired() {
|
||||
this.registerHandler(Incoming.WiredTriggerSaveDataEvent, WiredTriggerSaveDataEvent.class);
|
||||
this.registerHandler(Incoming.WiredEffectSaveDataEvent, WiredEffectSaveDataEvent.class);
|
||||
this.registerHandler(Incoming.WiredConditionSaveDataEvent, WiredConditionSaveDataEvent.class);
|
||||
}
|
||||
|
||||
void registerUnknown() {
|
||||
this.registerHandler(Incoming.RequestResolutionEvent, RequestResolutionEvent.class);
|
||||
this.registerHandler(Incoming.RequestTalenTrackEvent, RequestTalentTrackEvent.class); //TODO
|
||||
this.registerHandler(Incoming.UnknownEvent1, UnknownEvent1.class);
|
||||
}
|
||||
|
||||
void registerFloorPlanEditor() {
|
||||
this.registerHandler(Incoming.FloorPlanEditorSaveEvent, FloorPlanEditorSaveEvent.class);
|
||||
this.registerHandler(Incoming.FloorPlanEditorRequestBlockedTilesEvent, FloorPlanEditorRequestBlockedTilesEvent.class);
|
||||
this.registerHandler(Incoming.FloorPlanEditorRequestDoorSettingsEvent, FloorPlanEditorRequestDoorSettingsEvent.class);
|
||||
}
|
||||
|
||||
void registerAchievements() {
|
||||
this.registerHandler(Incoming.RequestAchievementsEvent, RequestAchievementsEvent.class);
|
||||
}
|
||||
}
|
@ -191,4 +191,9 @@ public class ServerMessage {
|
||||
|
||||
return this.channelBuffer.copy();
|
||||
}
|
||||
|
||||
public void release() {
|
||||
this.channelBuffer.release();
|
||||
}
|
||||
|
||||
}
|
@ -18,7 +18,6 @@ public class Incoming {
|
||||
public static final int HorseRideEvent = 1036;
|
||||
public static final int RequestCreateRoomEvent = 2752;
|
||||
public static final int SaveMottoEvent = 2228;
|
||||
public static final int GenerateSecretKeyEvent = -1;//3575
|
||||
public static final int ModToolAlertEvent = 1840;
|
||||
public static final int TradeAcceptEvent = 3863;
|
||||
public static final int RequestCatalogModeEvent = 1195;
|
||||
@ -78,7 +77,6 @@ public class Incoming {
|
||||
public static final int MannequinSaveNameEvent = 2850;
|
||||
public static final int SellItemEvent = 3447;
|
||||
public static final int GuildAcceptMembershipEvent = 3386;
|
||||
public static final int RequestBannerToken = -1;//2619
|
||||
public static final int RequestRecylerLogicEvent = 398;
|
||||
public static final int RequestGuildJoinEvent = 998;
|
||||
public static final int RequestCatalogIndexEvent = 2529;
|
||||
@ -111,6 +109,8 @@ public class Incoming {
|
||||
public static final int AcceptFriendRequest = 137;
|
||||
public static final int DeclineFriendRequest = 2890; //835; //TODO
|
||||
public static final int ReleaseVersionEvent = 4000;//4000
|
||||
public static final int InitDiffieHandshake = 3110;
|
||||
public static final int CompleteDiffieHandshake = 773;
|
||||
public static final int SearchRoomsMyFavoriteEvent = 2578;
|
||||
public static final int TradeStartEvent = 1481;
|
||||
public static final int RequestTargetOfferEvent = 2487;
|
||||
|
@ -0,0 +1,34 @@
|
||||
package com.eu.habbo.messages.incoming.handshake;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.crypto.HabboRC4;
|
||||
import com.eu.habbo.messages.NoAuthMessage;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.handshake.CompleteDiffieHandshakeComposer;
|
||||
import com.eu.habbo.networking.gameserver.decoders.GameByteDecryption;
|
||||
import com.eu.habbo.networking.gameserver.encoders.GameByteEncryption;
|
||||
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
||||
|
||||
@NoAuthMessage
|
||||
public class CompleteDiffieHandshakeEvent extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (this.client.getEncryption() == null) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] sharedKey = this.client.getEncryption().getDiffie().getSharedKey(this.packet.readString());
|
||||
|
||||
this.client.setHandshakeFinished(true);
|
||||
this.client.sendResponse(new CompleteDiffieHandshakeComposer(this.client.getEncryption().getDiffie().getPublicKey()));
|
||||
|
||||
this.client.getChannel().attr(GameServerAttributes.CRYPTO_CLIENT).set(new HabboRC4(sharedKey));
|
||||
this.client.getChannel().attr(GameServerAttributes.CRYPTO_SERVER).set(new HabboRC4(sharedKey));
|
||||
|
||||
this.client.getChannel().pipeline().addFirst(new GameByteDecryption());
|
||||
this.client.getChannel().pipeline().addFirst(new GameByteEncryption());
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.eu.habbo.messages.incoming.handshake;
|
||||
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
|
||||
public class GenerateSecretKeyEvent extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
this.packet.readString();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.eu.habbo.messages.incoming.handshake;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.messages.NoAuthMessage;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.handshake.InitDiffieHandshakeComposer;
|
||||
|
||||
@NoAuthMessage
|
||||
public class InitDiffieHandshakeEvent extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (this.client.getEncryption() == null) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
return;
|
||||
}
|
||||
|
||||
this.client.sendResponse(new InitDiffieHandshakeComposer(
|
||||
this.client.getEncryption().getDiffie().getSignedPrime(),
|
||||
this.client.getEncryption().getDiffie().getSignedGenerator()));
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.eu.habbo.messages.incoming.handshake;
|
||||
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.handshake.BannerTokenComposer;
|
||||
|
||||
public class RequestBannerToken extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
this.client.sendResponse(new BannerTokenComposer("Stop loggin, Imma ban your ass", false));
|
||||
}
|
||||
}
|
@ -51,6 +51,11 @@ public class SecureLoginEvent extends MessageHandler {
|
||||
if (!Emulator.isReady)
|
||||
return;
|
||||
|
||||
if (Emulator.getCrypto().isEnabled() && !this.client.isHandshakeFinished()) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
return;
|
||||
}
|
||||
|
||||
String sso = this.packet.readString().replace(" ", "");
|
||||
|
||||
if (Emulator.getPluginManager().fireEvent(new SSOAuthenticationEvent(sso)).isCancelled()) {
|
||||
|
@ -66,7 +66,8 @@ public class Outgoing {
|
||||
public final static int UserBadgesComposer = 1087;
|
||||
public final static int GuildManageComposer = 3965;
|
||||
public final static int RemoveFriendComposer = -1;//error 404
|
||||
public final static int BannerTokenComposer = -1;//error 404
|
||||
public final static int InitDiffieHandshakeComposer = 1347;
|
||||
public final static int CompleteDiffieHandshakeComposer = 3885;
|
||||
public final static int UserDataComposer = 2725;
|
||||
public final static int UserSearchResultComposer = 973;
|
||||
public final static int ModToolUserRoomVisitsComposer = 1752;
|
||||
|
@ -1,24 +0,0 @@
|
||||
package com.eu.habbo.messages.outgoing.handshake;
|
||||
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
public class BannerTokenComposer extends MessageComposer {
|
||||
private final String token;
|
||||
private final boolean unknown;
|
||||
|
||||
public BannerTokenComposer(String token, boolean unknown) {
|
||||
this.token = token;
|
||||
this.unknown = unknown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerMessage compose() {
|
||||
this.response.init(Outgoing.BannerTokenComposer);
|
||||
this.response.appendString(this.token);
|
||||
this.response.appendBoolean(this.unknown);
|
||||
|
||||
return this.response;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.eu.habbo.messages.outgoing.handshake;
|
||||
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
public class CompleteDiffieHandshakeComposer extends MessageComposer {
|
||||
|
||||
private final String publicKey;
|
||||
private final boolean clientEncryption;
|
||||
|
||||
public CompleteDiffieHandshakeComposer(String publicKey) {
|
||||
this(publicKey, true);
|
||||
}
|
||||
|
||||
public CompleteDiffieHandshakeComposer(String publicKey, boolean clientEncryption) {
|
||||
this.publicKey = publicKey;
|
||||
this.clientEncryption = clientEncryption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerMessage compose() {
|
||||
this.response.init(Outgoing.CompleteDiffieHandshakeComposer);
|
||||
this.response.appendString(this.publicKey);
|
||||
this.response.appendBoolean(this.clientEncryption);
|
||||
return this.response;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.eu.habbo.messages.outgoing.handshake;
|
||||
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import com.eu.habbo.messages.outgoing.Outgoing;
|
||||
|
||||
public class InitDiffieHandshakeComposer extends MessageComposer {
|
||||
|
||||
private final String signedPrime;
|
||||
private final String signedGenerator;
|
||||
|
||||
public InitDiffieHandshakeComposer(String signedPrime, String signedGenerator) {
|
||||
this.signedPrime = signedPrime;
|
||||
this.signedGenerator = signedGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerMessage compose() {
|
||||
this.response.init(Outgoing.InitDiffieHandshakeComposer);
|
||||
this.response.appendString(this.signedPrime);
|
||||
this.response.appendString(this.signedGenerator);
|
||||
return this.response;
|
||||
}
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.eu.habbo.networking.gameserver;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GameByteDecoder extends ByteToMessageDecoder {
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
|
||||
in.markReaderIndex();
|
||||
|
||||
//4 bytes length + 2 bytes header
|
||||
if (in.readableBytes() < 6) {
|
||||
in.resetReaderIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
int length = in.readInt();
|
||||
|
||||
//if(length > 5120 && (length >> 24 != 60))
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
if (length == 1014001516) {
|
||||
in.resetReaderIndex();
|
||||
//in.readBytes(in.readableBytes());
|
||||
|
||||
ChannelFuture f = ctx.writeAndFlush(Unpooled.copiedBuffer("<?xml version=\"1.0\"?>\n" +
|
||||
" <!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n" +
|
||||
" <cross-domain-policy>\n" +
|
||||
" <allow-access-from domain=\"*\" to-ports=\"1-31111\" />\n" +
|
||||
" </cross-domain-policy>" + (char) 0, CharsetUtil.UTF_8));
|
||||
|
||||
f.channel().close();
|
||||
ctx.channel().close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (in.readableBytes() < length || length < 0) {
|
||||
in.resetReaderIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
in.resetReaderIndex();
|
||||
ByteBuf read = in.readBytes(length + 4);
|
||||
out.add(read);
|
||||
}
|
||||
}
|
@ -4,6 +4,10 @@ import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.gameclients.GameClientManager;
|
||||
import com.eu.habbo.messages.PacketManager;
|
||||
import com.eu.habbo.networking.Server;
|
||||
import com.eu.habbo.networking.gameserver.decoders.*;
|
||||
import com.eu.habbo.networking.gameserver.encoders.MessageComposerEncoder;
|
||||
import com.eu.habbo.networking.gameserver.encoders.ServerMessageEncoder;
|
||||
import com.eu.habbo.networking.gameserver.encoders.GameServerMessageLogger;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
@ -26,8 +30,24 @@ public class GameServer extends Server {
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
ch.pipeline().addLast("logger", new LoggingHandler());
|
||||
ch.pipeline().addLast("bytesDecoder", new GameByteDecoder());
|
||||
ch.pipeline().addLast(new GameMessageHandler());
|
||||
|
||||
// Decoders.
|
||||
ch.pipeline().addLast(
|
||||
new GamePolicyDecoder(),
|
||||
new GameByteFrameDecoder(),
|
||||
new GameByteDecoder(),
|
||||
new GameMessageRateLimit(),
|
||||
new GameMessageHandler()
|
||||
);
|
||||
|
||||
// Encoders.
|
||||
ch.pipeline().addLast(new ServerMessageEncoder());
|
||||
|
||||
if (PacketManager.DEBUG_SHOW_PACKETS) {
|
||||
ch.pipeline().addLast(new GameServerMessageLogger());
|
||||
}
|
||||
|
||||
ch.pipeline().addLast(new MessageComposerEncoder());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.eu.habbo.networking.gameserver;
|
||||
|
||||
import com.eu.habbo.crypto.HabboRC4;
|
||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
public class GameServerAttributes {
|
||||
|
||||
public static final AttributeKey<GameClient> CLIENT = AttributeKey.valueOf("GameClient");
|
||||
public static final AttributeKey<HabboRC4> CRYPTO_CLIENT = AttributeKey.valueOf("CryptoClient");
|
||||
public static final AttributeKey<HabboRC4> CRYPTO_SERVER = AttributeKey.valueOf("CryptoServer");
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.eu.habbo.networking.gameserver.decoders;
|
||||
|
||||
import com.eu.habbo.messages.ClientMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GameByteDecoder extends ByteToMessageDecoder {
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
|
||||
short header = in.readShort();
|
||||
ByteBuf body = Unpooled.copiedBuffer(in.readBytes(in.readableBytes()));
|
||||
|
||||
out.add(new ClientMessage(header, body));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.eu.habbo.networking.gameserver.decoders;
|
||||
|
||||
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GameByteDecryption extends ByteToMessageDecoder {
|
||||
|
||||
public GameByteDecryption() {
|
||||
setSingleDecode(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
|
||||
// Read all available bytes.
|
||||
byte[] data = in.readBytes(in.readableBytes()).array();
|
||||
|
||||
// Decrypt.
|
||||
ctx.channel().attr(GameServerAttributes.CRYPTO_CLIENT).get().parse(data);
|
||||
|
||||
// Continue in the pipeline.
|
||||
out.add(Unpooled.wrappedBuffer(data));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.eu.habbo.networking.gameserver.decoders;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
||||
|
||||
public class GameByteFrameDecoder extends LengthFieldBasedFrameDecoder {
|
||||
|
||||
private static final int MAX_PACKET_LENGTH = 8192 * 4;
|
||||
private static final int LENGTH_FIELD_OFFSET = 0;
|
||||
private static final int LENGTH_FIELD_LENGTH = 4;
|
||||
private static final int LENGTH_FIELD_ADJUSTMENT = 0;
|
||||
private static final int INITIAL_BYTES_TO_STRIP = 4;
|
||||
|
||||
public GameByteFrameDecoder()
|
||||
{
|
||||
super(MAX_PACKET_LENGTH, LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_FIELD_ADJUSTMENT, INITIAL_BYTES_TO_STRIP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception
|
||||
{
|
||||
return super.decode(ctx, in);
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +1,19 @@
|
||||
package com.eu.habbo.networking.gameserver;
|
||||
package com.eu.habbo.networking.gameserver.decoders;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.messages.ClientMessage;
|
||||
import com.eu.habbo.messages.PacketManager;
|
||||
import com.eu.habbo.threading.runnables.ChannelReadHandler;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.codec.TooLongFrameException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class GameMessageHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext ctx) {
|
||||
if (!Emulator.getGameServer().getGameClientManager().addClient(ctx)) {
|
||||
@ -25,8 +28,10 @@ public class GameMessageHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
ClientMessage message = (ClientMessage) msg;
|
||||
|
||||
try {
|
||||
ChannelReadHandler handler = new ChannelReadHandler(ctx, msg);
|
||||
ChannelReadHandler handler = new ChannelReadHandler(ctx, message);
|
||||
|
||||
if (PacketManager.MULTI_THREADED_PACKET_HANDLING) {
|
||||
Emulator.getThreading().run(handler);
|
||||
@ -46,12 +51,18 @@ public class GameMessageHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
if (cause instanceof Exception) {
|
||||
if (!(cause instanceof IOException)) {
|
||||
// cause.printStackTrace(Logging.getErrorsRuntimeWriter());
|
||||
if (cause instanceof TooLongFrameException) {
|
||||
Emulator.getLogging().logErrorLine("Disconnecting client, reason: \"" + cause.getMessage() + "\".");
|
||||
} else {
|
||||
Emulator.getLogging().logErrorLine("Disconnecting client, exception in GameMessageHander:");
|
||||
Emulator.getLogging().logErrorLine(cause.toString());
|
||||
|
||||
for (StackTraceElement element : cause.getStackTrace()) {
|
||||
Emulator.getLogging().logErrorLine(element.toString());
|
||||
}
|
||||
}
|
||||
|
||||
ctx.channel().close();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.eu.habbo.networking.gameserver.decoders;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.messages.ClientMessage;
|
||||
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GameMessageRateLimit extends MessageToMessageDecoder<ClientMessage> {
|
||||
|
||||
private static final int RESET_TIME = 1;
|
||||
private static final int MAX_COUNTER = 10;
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ClientMessage message, List<Object> out) throws Exception {
|
||||
GameClient client = ctx.channel().attr(GameServerAttributes.CLIENT).get();
|
||||
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
// Check if reset time has passed.
|
||||
int timestamp = Emulator.getIntUnixTimestamp();
|
||||
if (timestamp - client.lastPacketCounterCleared > RESET_TIME) {
|
||||
// Reset counter.
|
||||
client.incomingPacketCounter.clear();
|
||||
client.lastPacketCounterCleared = timestamp;
|
||||
} else {
|
||||
// Get stored count for message id.
|
||||
count = client.incomingPacketCounter.getOrDefault(message.getMessageId(), 0);
|
||||
}
|
||||
|
||||
// If we exceeded the counter, drop the packet.
|
||||
if (count > MAX_COUNTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
client.incomingPacketCounter.put(message.getMessageId(), ++count);
|
||||
|
||||
// Continue processing.
|
||||
out.add(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.eu.habbo.networking.gameserver.decoders;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.util.CharsetUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GamePolicyDecoder extends ByteToMessageDecoder {
|
||||
|
||||
private static final String POLICY = "<?xml version=\"1.0\"?>\n" +
|
||||
" <!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n" +
|
||||
" <cross-domain-policy>\n" +
|
||||
" <allow-access-from domain=\"*\" to-ports=\"1-31111\" />\n" +
|
||||
" </cross-domain-policy>" + (char) 0;
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||
in.markReaderIndex();
|
||||
|
||||
byte b = in.readByte();
|
||||
if (b == '<') {
|
||||
in.resetReaderIndex();
|
||||
ctx.writeAndFlush(Unpooled.copiedBuffer(POLICY, CharsetUtil.UTF_8))
|
||||
.addListener(ChannelFutureListener.CLOSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove ourselves since the first packet was not a policy request.
|
||||
ctx.pipeline().remove(this);
|
||||
|
||||
// Continue to the other pipelines.
|
||||
in.resetReaderIndex();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.eu.habbo.networking.gameserver.encoders;
|
||||
|
||||
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
|
||||
public class GameByteEncryption extends ChannelOutboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
// Convert msg to ByteBuf.
|
||||
ByteBuf out = (ByteBuf) msg;
|
||||
|
||||
// Read all available bytes.
|
||||
byte[] data;
|
||||
|
||||
if (out.hasArray()) {
|
||||
data = out.array();
|
||||
} else {
|
||||
data = out.readBytes(out.readableBytes()).array();
|
||||
}
|
||||
|
||||
// Encrypt.
|
||||
ctx.channel().attr(GameServerAttributes.CRYPTO_SERVER).get().parse(data);
|
||||
|
||||
// Continue in the pipeline.
|
||||
ctx.write(Unpooled.wrappedBuffer(data));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.eu.habbo.networking.gameserver.encoders;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.core.Logging;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GameServerMessageLogger extends MessageToMessageEncoder<ServerMessage> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ServerMessage message, List<Object> out) throws Exception {
|
||||
Emulator.getLogging().logPacketLine("[" + Logging.ANSI_PURPLE + "SERVER" + Logging.ANSI_RESET + "] => [" + message.getHeader() + "] -> " + message.getBodyString());
|
||||
|
||||
out.add(message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.eu.habbo.networking.gameserver.encoders;
|
||||
|
||||
import com.eu.habbo.messages.outgoing.MessageComposer;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MessageComposerEncoder extends MessageToMessageEncoder<MessageComposer> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, MessageComposer message, List<Object> out) throws Exception {
|
||||
out.add(message.compose());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.eu.habbo.networking.gameserver.encoders;
|
||||
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
public class ServerMessageEncoder extends MessageToByteEncoder<ServerMessage> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ServerMessage message, ByteBuf out) {
|
||||
ByteBuf buf = message.get();
|
||||
|
||||
try {
|
||||
out.writeBytes(buf);
|
||||
} finally {
|
||||
buf.release();
|
||||
message.release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,69 +2,29 @@ package com.eu.habbo.threading.runnables;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.habbohotel.gameclients.GameClientManager;
|
||||
import com.eu.habbo.messages.ClientMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import com.eu.habbo.networking.gameserver.GameServerAttributes;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
public class ChannelReadHandler implements Runnable {
|
||||
private final ChannelHandlerContext ctx;
|
||||
private final Object msg;
|
||||
//private int _header;
|
||||
|
||||
public ChannelReadHandler(ChannelHandlerContext ctx, Object msg) {
|
||||
private final ChannelHandlerContext ctx;
|
||||
private final ClientMessage message;
|
||||
|
||||
public ChannelReadHandler(ChannelHandlerContext ctx, ClientMessage message) {
|
||||
this.ctx = ctx;
|
||||
this.msg = msg;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
ByteBuf m = (ByteBuf) this.msg;
|
||||
int length = m.readInt();
|
||||
short header = m.readShort();
|
||||
//_header = header;
|
||||
GameClient client = this.ctx.channel().attr(GameClientManager.CLIENT).get();
|
||||
|
||||
if (m.readableBytes() + 2 < length) {
|
||||
return;
|
||||
}
|
||||
GameClient client = this.ctx.channel().attr(GameServerAttributes.CLIENT).get();
|
||||
|
||||
if (client != null) {
|
||||
int count = 0;
|
||||
int timestamp = Emulator.getIntUnixTimestamp();
|
||||
if (timestamp - client.lastPacketCounterCleared > 1) {
|
||||
client.incomingPacketCounter.clear();
|
||||
client.lastPacketCounterCleared = timestamp;
|
||||
} else {
|
||||
if (m.readableBytes() + 2 < length) {
|
||||
m.resetReaderIndex();
|
||||
client.incomingPacketCounter.put((int) header, 0);
|
||||
count = 0;
|
||||
return;
|
||||
} else {
|
||||
count = client.incomingPacketCounter.getOrDefault(header, 0);
|
||||
Emulator.getGameServer().getPacketManager().handlePacket(client, message);
|
||||
}
|
||||
}
|
||||
|
||||
if (count <= 10) {
|
||||
count++;
|
||||
if (m.readableBytes() + 2 < length) {
|
||||
m.resetReaderIndex();
|
||||
client.incomingPacketCounter.put((int) header, 0);
|
||||
count = 0;
|
||||
return;
|
||||
}
|
||||
client.incomingPacketCounter.put((int) header, count);
|
||||
ByteBuf body = Unpooled.wrappedBuffer(m.readBytes(m.readableBytes()));
|
||||
Emulator.getGameServer().getPacketManager().handlePacket(client, new ClientMessage(header, body));
|
||||
body.release();
|
||||
}
|
||||
}
|
||||
|
||||
m.release();
|
||||
} catch (Exception e) {
|
||||
//System.out.println("Potential packet overflow occurring, careful! header: " + _header + e.getMessage());
|
||||
} finally {
|
||||
this.message.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user