Archived
0

Ping-pong

This commit is contained in:
2018-04-10 09:39:52 +03:00
parent 858cc2965f
commit 704dd19488
9 changed files with 273 additions and 1 deletions

View File

@@ -0,0 +1,59 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-08
*/
package mc.core.netty.proto_125;
import lombok.extern.slf4j.Slf4j;
import mc.core.NetStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
@Slf4j
public class ByteArrayOutputNetStream extends NetStream {
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
@Override
public void writeString(String value) {
if (value.length() > 240) {
log.warn("String \"{}\" too long!", value);
byte[] buf = value.substring(0, 240).getBytes(StandardCharsets.UTF_16BE);
writeByte(240);
writeBytes(buf);
} else {
byte[] buf = value.getBytes(StandardCharsets.UTF_16BE);
writeByte(value.length());
writeBytes(buf);
}
}
@Override
public byte readByte() {
throw new UnsupportedOperationException();
}
@Override
public void readBytes(byte[] buffer) {
throw new UnsupportedOperationException();
}
@Override
public int readUnsignedShort() {
throw new UnsupportedOperationException();
}
@Override
public void writeByte(int value) {
baos.write(value);
}
@Override
public void writeBytes(byte[] buffer) {
baos.write(buffer, 0, buffer.length);
}
public byte[] toByteArray() {
return baos.toByteArray();
}
}

View File

@@ -24,7 +24,10 @@ public class NettyServer implements Server {
@Override
protected void initChannel(SocketChannel socketChannel) {
socketChannel.pipeline().addLast(
new LoggingHandler()
new LoggingHandler(),
new PacketDecoder(),
new PacketHandler(),
new PacketEncoder()
);
}
};

View File

@@ -0,0 +1,36 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-03-25
*/
package mc.core.netty.proto_125;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import mc.core.CSPacket;
import mc.core.NetStream;
import java.util.List;
@Slf4j
public class PacketDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
log.debug("ByteBuf readableBytes: {}", in.readableBytes());
int id = in.readUnsignedByte();
log.debug("Pkt-Id: {} / 0x{}", id, Integer.toHexString(id).toUpperCase());
Class<? extends CSPacket> packetClass = PacketManager.getClientSidePacket(id);
if (packetClass != null) {
NetStream netStream = new WrapperNetStream(in);
CSPacket packet = packetClass.newInstance();
packet.readSelf(netStream);
out.add(packet);
}
if (in.readableBytes() > 0)
in.skipBytes(in.readableBytes());
}
}

View File

@@ -0,0 +1,21 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-10
*/
package mc.core.netty.proto_125;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import mc.core.SCPacket;
public class PacketEncoder extends MessageToByteEncoder<SCPacket> {
@Override
protected void encode(ChannelHandlerContext ctx, SCPacket pkt, ByteBuf out) throws Exception {
Integer id = PacketManager.getServirSidePacket(pkt.getClass());
byte[] bytes = pkt.toByteArray();
out.writeByte(id);
out.writeBytes(bytes);
}
}

View File

@@ -0,0 +1,46 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-10
*/
package mc.core.netty.proto_125;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import mc.core.CSPacket;
import mc.core.Config;
import mc.core.Main;
import mc.core.netty.proto_125.packets.KickPacket;
import mc.core.netty.proto_125.packets.PingPacket;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;
@Slf4j
public class PacketHandler extends SimpleChannelInboundHandler<CSPacket> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, CSPacket packet) throws Exception {
log.debug("{}: {}", packet.getClass().getSimpleName(), packet.toString());
Optional<Method> optionalMethod = Arrays.stream(this.getClass().getDeclaredMethods())
.filter(method -> method.getName().equals("on" + packet.getClass().getSimpleName())
&& method.getParameterCount() == 2
&& method.getParameterTypes()[0].isAssignableFrom(Channel.class)
&& method.getParameterTypes()[1].isAssignableFrom(packet.getClass()))
.findFirst();
if (optionalMethod.isPresent()) {
Method method = optionalMethod.get();
method.invoke(this, ctx.channel(), packet);
}
}
public void onPingPacket(Channel channel, PingPacket packet) {
Config config = Main.appContext.getBean("config", Config.class);
KickPacket pkt = new KickPacket();
pkt.setPongMessage(config.getDescriptionServer(), 0, config.getMaxPlayers());
channel.writeAndFlush(pkt);
}
}

View File

@@ -0,0 +1,28 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-10
*/
package mc.core.netty.proto_125;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import mc.core.CSPacket;
import mc.core.SCPacket;
import mc.core.netty.proto_125.packets.KickPacket;
import mc.core.netty.proto_125.packets.PingPacket;
public class PacketManager {
private static final BiMap<Integer, Class<?>> packetMap = ImmutableBiMap.of(
0xFE, PingPacket.class,
0xFF, KickPacket.class
);
@SuppressWarnings("unchecked")
public static Class<? extends CSPacket> getClientSidePacket(int id) {
return (Class<? extends CSPacket>) packetMap.get(id);
}
public static Integer getServirSidePacket(Class<? extends SCPacket> clazz) {
return packetMap.inverse().get(clazz);
}
}

View File

@@ -0,0 +1,43 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-08
*/
package mc.core.netty.proto_125;
import io.netty.buffer.ByteBuf;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import mc.core.NetStream;
import java.nio.charset.StandardCharsets;
@Slf4j
@RequiredArgsConstructor
public class WrapperNetStream extends NetStream {
private final ByteBuf byteBuf;
@Override
public byte readByte() {
return byteBuf.readByte();
}
@Override
public void readBytes(byte[] buffer) {
byteBuf.readBytes(buffer);
}
@Override
public int readUnsignedShort() {
return byteBuf.readUnsignedShort();
}
@Override
public void writeByte(int value) {
byteBuf.writeByte(value);
}
@Override
public void writeBytes(byte[] buffer) {
byteBuf.writeBytes(buffer);
}
}

View File

@@ -0,0 +1,26 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-10
*/
package mc.core.netty.proto_125.packets;
import lombok.Setter;
import mc.core.SCPacket;
import mc.core.netty.proto_125.ByteArrayOutputNetStream;
public class KickPacket implements SCPacket {
@Setter
private String reason;
public void setPongMessage(String description, int online, int maxOnline) {
reason = String.format("%s§%d§%d", description, online, maxOnline);
}
@Override
public byte[] toByteArray() {
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
netStream.writeByte(0);
netStream.writeString(reason);
return netStream.toByteArray();
}
}

View File

@@ -0,0 +1,10 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-10
*/
package mc.core.netty.proto_125.packets;
import mc.core.CSPacket;
public class PingPacket implements CSPacket {
}