Revert buildin Nitro Websocket

This commit is contained in:
DuckieTM 2024-03-28 19:52:31 +01:00
parent f6d11fd5a8
commit 0acdcbb749
8 changed files with 1 additions and 233 deletions

2
Emulator/.gitignore vendored
View File

@ -5,12 +5,10 @@ compiled-builds/
target/**
TODO.txt
packet.pkt
plugins/**
src/test/
target/
config.ini
*.txt
*.jar
*.log
*.zip
.DS_Store

Binary file not shown.

View File

@ -10,16 +10,13 @@ import com.eu.habbo.habbohotel.GameEnvironment;
import com.eu.habbo.networking.camera.CameraClient;
import com.eu.habbo.networking.gameserver.GameServer;
import com.eu.habbo.networking.rconserver.RCONServer;
import com.eu.habbo.networking.websockets.NetworkChannelInitializer;
import com.eu.habbo.plugin.PluginManager;
import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorLoadedEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorStartShutdownEvent;
import com.eu.habbo.plugin.events.emulator.EmulatorStoppedEvent;
import com.eu.habbo.plugin.events.users.UserGetIPAddressEvent;
import com.eu.habbo.threading.ThreadPooling;
import com.eu.habbo.util.imager.badges.BadgeImager;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
@ -145,15 +142,7 @@ public final class Emulator {
Emulator.rconServer.initializePipeline();
Emulator.rconServer.connect();
Emulator.badgeImager = new BadgeImager();
Emulator.getConfig().register("websockets.whitelist", "localhost");
Emulator.getConfig().register("ws.nitro.host", "0.0.0.0");
Emulator.getConfig().register("ws.nitro.port", "2096");
Emulator.getConfig().register("ws.nitro.ip.header", "");
NetworkChannelInitializer wsChannelHandler = new NetworkChannelInitializer();
Emulator.getGameServer().getServerBootstrap().childHandler(wsChannelHandler);
Emulator.getGameServer().getServerBootstrap().bind(Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0"), Emulator.getConfig().getInt("ws.nitro.port", 2096)).sync();
log.info("Websockets has started!");
log.info("Websockets Listening on " + (wsChannelHandler.isSSL() ? "wss://" : "ws://") + Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0") + ":" + Emulator.getConfig().getInt("ws.nitro.port", 2096));
log.info("Arcturus Morningstar has successfully loaded.");
log.info("System launched in: {}ms. Using {} threads!", (System.nanoTime() - startTime) / 1e6, Runtime.getRuntime().availableProcessors() * 2);
log.info("Memory: {}/{}MB", (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024), (runtime.freeMemory()) / (1024 * 1024));
@ -343,19 +332,6 @@ public final class Emulator {
return rconServer;
}
public void onUserGetIPEvent(UserGetIPAddressEvent e) {
Channel channel = e.habbo.getClient().getChannel();
if(channel != null && channel.hasAttr(Emulator.WS_IP)) {
String ip = channel.attr(Emulator.WS_IP).get();
if(!ip.isEmpty()) {
e.setUpdatedIp(ip);
}
}
}
/**
* @deprecated Do not use. Please use LoggerFactory.getLogger(YourClass.class) to log.
*/
@Deprecated
public static Logging getLogging() {
return logging;

View File

@ -1,74 +0,0 @@
package com.eu.habbo.networking.websockets;
import com.eu.habbo.messages.PacketManager;
import com.eu.habbo.networking.gameserver.decoders.*;
import com.eu.habbo.networking.gameserver.encoders.GameServerMessageEncoder;
import com.eu.habbo.networking.gameserver.encoders.GameServerMessageLogger;
import com.eu.habbo.networking.gameserver.handlers.IdleTimeoutHandler;
import com.eu.habbo.networking.websockets.codec.WebSocketCodec;
import com.eu.habbo.networking.websockets.handlers.CustomHTTPHandler;
import com.eu.habbo.networking.websockets.ssl.SSLCertificateLoader;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolConfig;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
public class NetworkChannelInitializer extends ChannelInitializer<SocketChannel> {
private static final int MAX_FRAME_SIZE = 500000;
private final SslContext context;
private final boolean isSSL;
private final WebSocketServerProtocolConfig config;
public NetworkChannelInitializer() {
context = SSLCertificateLoader.getContext();
isSSL = context != null;
config = WebSocketServerProtocolConfig.newBuilder()
.websocketPath("/")
.checkStartsWith(true)
.maxFramePayloadLength(MAX_FRAME_SIZE)
.build();
}
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast("logger", new LoggingHandler());
if(isSSL) {
ch.pipeline().addLast(context.newHandler(ch.alloc()));
}
ch.pipeline().addLast("httpCodec", new HttpServerCodec());
ch.pipeline().addLast("objectAggregator", new HttpObjectAggregator(MAX_FRAME_SIZE));
ch.pipeline().addLast("customHttpHandler", new CustomHTTPHandler());
ch.pipeline().addLast("protocolHandler", new WebSocketServerProtocolHandler(config));
ch.pipeline().addLast("websocketCodec", new WebSocketCodec());
// Decoders.
ch.pipeline().addLast(new GamePolicyDecoder());
ch.pipeline().addLast(new GameByteFrameDecoder());
ch.pipeline().addLast(new GameByteDecoder());
if (PacketManager.DEBUG_SHOW_PACKETS) {
ch.pipeline().addLast(new GameClientMessageLogger());
}
ch.pipeline().addLast("idleEventHandler", new IdleTimeoutHandler(30, 60));
ch.pipeline().addLast(new GameMessageRateLimit());
ch.pipeline().addLast(new GameMessageHandler());
// Encoders.
ch.pipeline().addLast("messageEncoder", new GameServerMessageEncoder());
if (PacketManager.DEBUG_SHOW_PACKETS) {
ch.pipeline().addLast(new GameServerMessageLogger());
}
}
public boolean isSSL() {
return isSSL;
}
}

View File

@ -1,22 +0,0 @@
package com.eu.habbo.networking.websockets.codec;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import java.util.List;
public class WebSocketCodec extends MessageToMessageCodec<WebSocketFrame, ByteBuf> {
@Override
protected void encode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
out.add(new BinaryWebSocketFrame(in).retain());
}
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame in, List<Object> out) {
out.add(in.content().retain());
}
}

View File

@ -1,64 +0,0 @@
package com.eu.habbo.networking.websockets.handlers;
import com.eu.habbo.Emulator;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import io.netty.util.ReferenceCountUtil;
import com.eu.habbo.networking.websockets.utils.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CustomHTTPHandler extends ChannelInboundHandlerAdapter {
private static final String ORIGIN_HEADER = "Origin";
private static final Logger LOGGER = LoggerFactory.getLogger(CustomHTTPHandler.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(msg instanceof HttpMessage) {
if(!handleHttpRequest(ctx, (HttpMessage) msg))
{
ReferenceCountUtil.release(msg);//discard message
return;
}
}
super.channelRead(ctx, msg);
ctx.pipeline().remove(this);
}
public boolean handleHttpRequest(ChannelHandlerContext ctx, HttpMessage req) {
String origin = "error";
String clientIP;
String header = Emulator.getConfig().getValue("ws.nitro.ip.header", "");
// Check if X-Forwarded-For header is present and use the first IP as the client IP if available
if (req.headers().contains(header)) {
String xForwardedFor = req.headers().get(header);
clientIP = xForwardedFor.split(",")[0].trim(); // Get the first IP in the list
} else {
clientIP = ctx.channel().remoteAddress().toString().substring(1).split(":")[0]; // Get the client's IP address
}
try {
if(req.headers().contains(ORIGIN_HEADER)) {
origin = Utils.getDomainNameFromUrl(req.headers().get(ORIGIN_HEADER));
}
} catch (Exception ignored) { }
if(!Utils.isWhitelisted(origin, Emulator.getConfig().getValue("websockets.whitelist", "localhost").split(","))) {
LOGGER.warn("Access denied for IP: {}", clientIP);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN, Unpooled.wrappedBuffer("W.T.F are you doing?".getBytes()));
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
return false;
}
if(!header.isEmpty() && req.headers().contains(header)) {
String ip = req.headers().get(header);
ctx.channel().attr(Emulator.WS_IP).set(ip);
}
return true;
}
}

View File

@ -1,24 +0,0 @@
package com.eu.habbo.networking.websockets.ssl;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
public class SSLCertificateLoader {
private static final String filePath = "ssl";
private static final Logger LOGGER = LoggerFactory.getLogger(SSLCertificateLoader.class);
public static SslContext getContext() {
SslContext context;
try {
context = SslContextBuilder.forServer(new File( filePath + File.separator + "cert.pem" ), new File( filePath + File.separator + "privkey.pem" )).build();
} catch ( Exception e ) {
LOGGER.info("Unable to load ssl: " + e.getMessage());
context = null;
}
return context;
}
}

View File

@ -1,22 +0,0 @@
package com.eu.habbo.networking.websockets.utils;
import java.net.URI;
public class Utils {
public static String getDomainNameFromUrl(String url) throws Exception {
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
public static boolean isWhitelisted(String toCheck, String[] whitelist) {
for(String whitelistEntry : whitelist) {
if(whitelistEntry.startsWith("*")) {
if(toCheck.endsWith(whitelistEntry.substring(1)) || ("." + toCheck).equals(whitelistEntry.substring(1))) return true;
} else {
if(toCheck.equals(whitelistEntry)) return true;
}
}
return false;
}
}