mirror of
https://git.krews.org/morningstar/nitrowebsockets-for-ms
synced 2024-11-22 15:00:52 +01:00
initial commit
This commit is contained in:
commit
f0edaeae90
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.idea
|
||||||
|
.idea/workspace.xml
|
||||||
|
target/
|
30
pom.xml
Normal file
30
pom.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.krews.nitro</groupId>
|
||||||
|
<artifactId>NitroWebsockets</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>6</source>
|
||||||
|
<target>6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.eu.habbo</groupId>
|
||||||
|
<artifactId>Habbo</artifactId>
|
||||||
|
<version>2.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
45
src/main/java/com/krews/plugin/nitro/main.java
Normal file
45
src/main/java/com/krews/plugin/nitro/main.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package com.krews.plugin.nitro;
|
||||||
|
|
||||||
|
import com.eu.habbo.Emulator;
|
||||||
|
import com.eu.habbo.habbohotel.users.Habbo;
|
||||||
|
import com.eu.habbo.plugin.EventHandler;
|
||||||
|
import com.eu.habbo.plugin.EventListener;
|
||||||
|
import com.eu.habbo.plugin.HabboPlugin;
|
||||||
|
import com.eu.habbo.plugin.events.emulator.EmulatorLoadedEvent;
|
||||||
|
import com.krews.plugin.nitro.websockets.NetworkChannelInitializer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class main extends HabboPlugin implements EventListener {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Emulator.class);
|
||||||
|
|
||||||
|
public void onEnable() throws Exception {
|
||||||
|
Emulator.getPluginManager().registerEvents(this, this);
|
||||||
|
if(Emulator.isReady && !Emulator.isShuttingDown) {
|
||||||
|
this.onEmulatorLoadedEvent(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDisable() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPermission(Habbo habbo, String s) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onEmulatorLoadedEvent (EmulatorLoadedEvent e) {
|
||||||
|
//add missing db entry
|
||||||
|
Emulator.getConfig().register("websockets.whitelist", "localhost");
|
||||||
|
Emulator.getConfig().register("ws.nitro.host", "0.0.0.0");
|
||||||
|
Emulator.getConfig().register("ws.nitro.port", "2096");
|
||||||
|
|
||||||
|
Emulator.getGameServer().getServerBootstrap().childHandler(new NetworkChannelInitializer());
|
||||||
|
|
||||||
|
Emulator.getGameServer().getServerBootstrap().bind(Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0"), Emulator.getConfig().getInt("ws.nitro.port", 2096)).syncUninterruptibly();
|
||||||
|
|
||||||
|
LOGGER.info("OFFICIAL PLUGIN - Nitro Websockets has started!");
|
||||||
|
LOGGER.info("Nitro Websockets Listening on " + Emulator.getConfig().getValue("ws.nitro.host", "0.0.0.0") + ":" + Emulator.getConfig().getInt("ws.nitro.port", 2096));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.krews.plugin.nitro.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.krews.plugin.nitro.websockets.handlers.MessageInterceptorHandler;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.handler.logging.LoggingHandler;
|
||||||
|
|
||||||
|
public class NetworkChannelInitializer extends ChannelInitializer<SocketChannel> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
ch.pipeline().addLast("logger", new LoggingHandler());
|
||||||
|
|
||||||
|
ch.pipeline().addLast("messageInterceptor", new MessageInterceptorHandler());
|
||||||
|
|
||||||
|
// 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(new GameMessageRateLimit());
|
||||||
|
ch.pipeline().addLast(new GameMessageHandler());
|
||||||
|
|
||||||
|
// Encoders.
|
||||||
|
ch.pipeline().addLast("messageEncoder", new GameServerMessageEncoder());
|
||||||
|
|
||||||
|
if (PacketManager.DEBUG_SHOW_PACKETS) {
|
||||||
|
ch.pipeline().addLast(new GameServerMessageLogger());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.krews.plugin.nitro.websockets.codec;
|
||||||
|
|
||||||
|
import com.eu.habbo.messages.ServerMessage;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||||
|
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
|
||||||
|
import io.netty.util.IllegalReferenceCountException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HabboFrameToWebSocketFrameEncoder extends MessageToMessageEncoder<ServerMessage> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext channelHandlerContext, ServerMessage message, List<Object> out) throws Exception {
|
||||||
|
try {
|
||||||
|
BinaryWebSocketFrame frame = new BinaryWebSocketFrame(message.get());
|
||||||
|
try {
|
||||||
|
out.add(frame.retain());
|
||||||
|
} finally {
|
||||||
|
// Release copied buffer.
|
||||||
|
frame.release();
|
||||||
|
}
|
||||||
|
} catch (IllegalReferenceCountException e) {
|
||||||
|
throw new IOException(String.format("IllegalReferenceCountException happened for ServerMessage with packet id %d.", message.getHeader()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.krews.plugin.nitro.websockets.codec;
|
||||||
|
|
||||||
|
import com.eu.habbo.Emulator;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||||
|
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
|
||||||
|
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class WebSocketFrameToHabboFrameDecoder extends MessageToMessageDecoder<WebSocketFrame> {
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, WebSocketFrame in, List<Object> out) {
|
||||||
|
out.add(in.content().retain());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||||
|
// only allow websockets connections from the whitelist
|
||||||
|
if(evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
|
||||||
|
WebSocketServerProtocolHandler.HandshakeComplete handshake = (WebSocketServerProtocolHandler.HandshakeComplete)evt;
|
||||||
|
String origin = getDomainName(handshake.requestHeaders().get("Origin"));
|
||||||
|
|
||||||
|
if(!isWhitelisted(origin)) {
|
||||||
|
ctx.channel().writeAndFlush(new CloseWebSocketFrame(403, "Origin forbidden")).addListener(ChannelFutureListener.CLOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.userEventTriggered(ctx, evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDomainName(String url) throws URISyntaxException {
|
||||||
|
URI uri = new URI(url);
|
||||||
|
String domain = uri.getHost();
|
||||||
|
return domain.startsWith("www.") ? domain.substring(4) : domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isWhitelisted(String origin) {
|
||||||
|
String[] allowedOrigins = Emulator.getConfig().getValue("websockets.whitelist", "localhost").split(",");
|
||||||
|
for(String entry : allowedOrigins) {
|
||||||
|
if(entry.startsWith("*")) {
|
||||||
|
if(origin.endsWith(entry.substring(1)) || ("." + origin).equals(entry.substring(1))) return true;
|
||||||
|
} else {
|
||||||
|
if(origin.equals(entry)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.krews.plugin.nitro.websockets.handlers;
|
||||||
|
|
||||||
|
import com.krews.plugin.nitro.websockets.codec.HabboFrameToWebSocketFrameEncoder;
|
||||||
|
import com.krews.plugin.nitro.websockets.codec.WebSocketFrameToHabboFrameDecoder;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
|
import io.netty.handler.codec.http.HttpObjectAggregator;
|
||||||
|
import io.netty.handler.codec.http.HttpServerCodec;
|
||||||
|
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MessageInterceptorHandler extends ByteToMessageDecoder {
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
|
if(in.toString(CharsetUtil.UTF_8).startsWith("GET")) {
|
||||||
|
// this is a websocket upgrade request, so add the appropriate decoders/encoders
|
||||||
|
ctx.pipeline().addAfter("messageInterceptor", "websocketHandler", new WebSocketFrameToHabboFrameDecoder());
|
||||||
|
ctx.pipeline().addAfter("messageInterceptor", "protocolHandler", new WebSocketServerProtocolHandler("/", true));
|
||||||
|
ctx.pipeline().addAfter("messageInterceptor", "objectAggregator", new HttpObjectAggregator(65536));
|
||||||
|
ctx.pipeline().addAfter("messageInterceptor", "httpCodec", new HttpServerCodec());
|
||||||
|
ctx.pipeline().replace("messageEncoder", "websocketFrameEncoder", new HabboFrameToWebSocketFrameEncoder());
|
||||||
|
}
|
||||||
|
// Remove ourselves
|
||||||
|
ctx.pipeline().remove(this);
|
||||||
|
}
|
||||||
|
}
|
5
src/main/resources/plugin.json
Normal file
5
src/main/resources/plugin.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"main" : "com.krews.plugin.nitro.main",
|
||||||
|
"name" : "Nitro Websockets",
|
||||||
|
"author" : "Krews"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user