diff --git a/gestalt-networking/build.gradle b/gestalt-networking/build.gradle new file mode 100644 index 00000000..2b48219c --- /dev/null +++ b/gestalt-networking/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java' +} + +group 'org.terasology.gestalt' +version '8.0.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' + implementation group: 'io.netty', name: 'netty-all', version: '4.1.53.Final' + +} + +test { + useJUnitPlatform() +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/NetworkConfig.java b/gestalt-networking/src/main/java/org/terasology/networking/NetworkConfig.java new file mode 100644 index 00000000..2f29d348 --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/NetworkConfig.java @@ -0,0 +1,35 @@ +/* + reliable.io + + Copyright © 2017 - 2019, The Network Protocol Company, Inc. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package org.terasology.networking; + +public class NetworkConfig { + public int fragmentAbove; + + public NetworkConfig setFragmentAbove(int size) { + this.fragmentAbove = size; + return this; + } + +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/PacketChannel.java b/gestalt-networking/src/main/java/org/terasology/networking/PacketChannel.java new file mode 100644 index 00000000..d9992854 --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/PacketChannel.java @@ -0,0 +1,66 @@ +package org.terasology.networking; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.socket.DuplexChannel; + +public class PacketChannel { + private final DuplexChannel channel; + + double time; + float packetLost; + float sendBandwidthKbps; + float receivedBandwidthKbps; + float ackedBandwidthKbps; + + int sequence; + int numberAcks; + byte[] acks; + + SequenceBuffer SentPacketBuffer; + SequenceBuffer receivedPacketBuffer; + SequenceBuffer fragmentReassemblyBuffer; + + public static class SequenceBuffer { + int sequence; + T[] buffer; + int[] entries; + + public int getAcks() { + return sequence - 1; + } + + + } + + public static class SentPacketData { + public double time; + public boolean acked; + public int packetBytes; + } + + public static class ReceivedPacketData { + public double time; + public int packetBytes; + } + + public static class FragmentReassemblyData { + public short sequence; + public short ack; + public int acks; + public int numberFragmentsReceived; + public int numberFragmentsTotal; + public ByteBuf packedData; + public int packedBytes; + public int packedHeaderBytes; + public ByteBuf fragmentReceived; + } + public int generateAckBits(int ackBits) { + return 0; + } + + + + public PacketChannel(DuplexChannel channel) { + this.channel = channel; + } +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/PacketInboundReceiver.java b/gestalt-networking/src/main/java/org/terasology/networking/PacketInboundReceiver.java new file mode 100644 index 00000000..cab46923 --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/PacketInboundReceiver.java @@ -0,0 +1,15 @@ +package org.terasology.networking; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class PacketInboundReceiver extends ChannelInboundHandlerAdapter { + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ByteBuf packet = (ByteBuf) msg; + + super.channelRead(ctx, msg); + } +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/Server.java b/gestalt-networking/src/main/java/org/terasology/networking/Server.java new file mode 100644 index 00000000..ab4fa929 --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/Server.java @@ -0,0 +1,29 @@ +package org.terasology.networking; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioDatagramChannel; +import org.terasology.networking.internal.InboundPacketHandler; +import org.terasology.networking.internal.OutboundPacketHandler; + +public class Server { + + public void main() { + EventLoopGroup main = new NioEventLoopGroup(); // (1) + Bootstrap bootstrap = new Bootstrap(); + bootstrap.group(main) + .channel(NioDatagramChannel.class) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { +// PacketChannel channel = new PacketChannel(ch, null); +// ch.pipeline().addLast(new InboundPacketHandler(channel)); +// +// ch.pipeline().addLast(new OutboundPacketHandler(channel)); + } + }); + } +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/ServerConnectionHandler.java b/gestalt-networking/src/main/java/org/terasology/networking/ServerConnectionHandler.java new file mode 100644 index 00000000..65b0215e --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/ServerConnectionHandler.java @@ -0,0 +1,15 @@ +package org.terasology.networking; + +import io.netty.channel.ChannelHandlerAdapter; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public class ServerConnectionHandler extends ChannelHandlerAdapter { + + public ServerConnectionHandler() { + + } + + + +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/internal/InboundPacketHandler.java b/gestalt-networking/src/main/java/org/terasology/networking/internal/InboundPacketHandler.java new file mode 100644 index 00000000..f4d12f86 --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/internal/InboundPacketHandler.java @@ -0,0 +1,23 @@ +package org.terasology.networking.internal; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import io.netty.handler.codec.MessageToMessageDecoder; +import org.terasology.networking.PacketChannel; + +import java.util.List; + +public class InboundPacketHandler extends MessageToMessageDecoder { + private final PacketChannel channel; + + public InboundPacketHandler(PacketChannel channel) { + this.channel = channel; + + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { + + } +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/internal/OutboundPacketHandler.java b/gestalt-networking/src/main/java/org/terasology/networking/internal/OutboundPacketHandler.java new file mode 100644 index 00000000..1c8c83f8 --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/internal/OutboundPacketHandler.java @@ -0,0 +1,36 @@ +package org.terasology.networking.internal; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageEncoder; +import org.terasology.networking.NetworkConfig; +import org.terasology.networking.PacketChannel; + +import java.util.List; + +public class OutboundPacketHandler extends MessageToMessageEncoder { + private final PacketChannel channel; + private final NetworkConfig config; + public OutboundPacketHandler(NetworkConfig config, PacketChannel channel) { + super(null); + this.channel = channel; + this.config = config; + } + + @Override + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { + if (msg.readableBytes() <= config.fragmentAbove) { + + } + } + + + // @Override +// protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception { +// ByteBuf buffer = (ByteBuf) msg; +// +// +// if (buffer.readableBytes() <= config.fragmentAbove) { +// } +// } +} diff --git a/gestalt-networking/src/main/java/org/terasology/networking/piplineFactory/PacketPipeline.java b/gestalt-networking/src/main/java/org/terasology/networking/piplineFactory/PacketPipeline.java new file mode 100644 index 00000000..e33bb7c7 --- /dev/null +++ b/gestalt-networking/src/main/java/org/terasology/networking/piplineFactory/PacketPipeline.java @@ -0,0 +1,28 @@ +package org.terasology.networking.piplineFactory; + +import io.netty.channel.ChannelInitializer; +import io.netty.channel.socket.DuplexChannel; +import io.netty.handler.codec.DatagramPacketDecoder; +import io.netty.handler.codec.DatagramPacketEncoder; +import org.terasology.networking.NetworkConfig; +import org.terasology.networking.PacketChannel; +import org.terasology.networking.internal.InboundPacketHandler; +import org.terasology.networking.internal.OutboundPacketHandler; + +public class PacketPipeline extends ChannelInitializer { + public static String InboundPackets = "INBOUND_PACKETS"; + public static String OutboundPackets = "INBOUND_PACKETS"; + + private final NetworkConfig config; + + public PacketPipeline(NetworkConfig config) { + this.config = config; + } + + @Override + protected void initChannel(DuplexChannel ch) throws Exception { + PacketChannel channel = new PacketChannel(ch); + ch.pipeline().addLast(InboundPackets, new DatagramPacketDecoder(new InboundPacketHandler(channel))); + ch.pipeline().addLast(OutboundPackets, new DatagramPacketEncoder<>(new OutboundPacketHandler(config, channel))); + } +} diff --git a/settings.gradle b/settings.gradle index dbcf025b..32dccbef 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,3 +5,5 @@ if (rootProject.projectDir.toPath().resolve("local.properties").toFile().exists( } else { println "No local.properties file found, bypassing Android elements" } +include 'gestalt-networking' +