From 7eb0d9efce404c562b855487d762397519effda6 Mon Sep 17 00:00:00 2001 From: Kilobyte22 Date: Sun, 30 Jan 2022 00:24:31 +0100 Subject: [PATCH] Add initial work on the NetworkPortalBlock --- src/main/java/li/cil/oc2/common/Config.java | 6 ++ src/main/java/li/cil/oc2/common/Main.java | 6 ++ .../oc2/common/block/NetworkPortalBlock.java | 35 ++++++++ .../cil/oc2/common/vxlan/TunnelManager.java | 82 +++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 src/main/java/li/cil/oc2/common/block/NetworkPortalBlock.java create mode 100644 src/main/java/li/cil/oc2/common/vxlan/TunnelManager.java diff --git a/src/main/java/li/cil/oc2/common/Config.java b/src/main/java/li/cil/oc2/common/Config.java index c54f96d2..32f178e8 100644 --- a/src/main/java/li/cil/oc2/common/Config.java +++ b/src/main/java/li/cil/oc2/common/Config.java @@ -45,6 +45,12 @@ public final class Config { @Path("admin.virtual_network") public static int ethernetFrameTimeToLive = 12; @Path("admin.virtual_network") public static int hubEthernetFramesPerTick = 32; + @Path("vxlan") public static boolean enable = false; + @Path("vxlan") public static String remoteHost = "::1"; + @Path("vxlan") public static int remotePort = 4789; + @Path("vxlan") public static String bindHost = "::1"; + @Path("vxlan") public static int bindPort = 4789; + public static boolean computersUseEnergy() { return computerEnergyPerTick > 0 && computerEnergyStorage > 0; } diff --git a/src/main/java/li/cil/oc2/common/Main.java b/src/main/java/li/cil/oc2/common/Main.java index f9a3d9b2..1f94a903 100644 --- a/src/main/java/li/cil/oc2/common/Main.java +++ b/src/main/java/li/cil/oc2/common/Main.java @@ -22,7 +22,11 @@ import li.cil.oc2.common.tags.BlockTags; import li.cil.oc2.common.tags.ItemTags; import li.cil.oc2.common.util.RegistryUtils; import li.cil.oc2.common.util.SoundEvents; +<<<<<<< HEAD import li.cil.oc2.common.vm.provider.DeviceTreeProviders; +======= +import li.cil.oc2.common.vxlan.TunnelManager; +>>>>>>> 7a7b14ef (Add initial work on the NetworkPortalBlock) import li.cil.sedna.Sedna; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; @@ -54,8 +58,10 @@ public final class Main { ProviderRegistry.initialize(); DeviceTypes.initialize(); + BlockDeviceDataRegistry.initialize(); FirmwareRegistry.initialize(); + TunnelManager.initialize(); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> Manuals::initialize); diff --git a/src/main/java/li/cil/oc2/common/block/NetworkPortalBlock.java b/src/main/java/li/cil/oc2/common/block/NetworkPortalBlock.java new file mode 100644 index 00000000..de701756 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/block/NetworkPortalBlock.java @@ -0,0 +1,35 @@ +package li.cil.oc2.common.block; + +import li.cil.oc2.common.blockentity.BlockEntities; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Material; +import org.jetbrains.annotations.Nullable; + +public class NetworkPortalBlock extends HorizontalDirectionalBlock implements EntityBlock { + + public NetworkPortalBlock() { + super(Properties + .of(Material.METAL) + .sound(SoundType.METAL) + .strength(1.5f, 6.0f)); + registerDefaultState(getStateDefinition().any().setValue(FACING, Direction.NORTH)); + } + + @Override + public BlockState getStateForPlacement(final BlockPlaceContext context) { + return super.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite()); + } + + @Nullable + @Override + public BlockEntity newBlockEntity(final BlockPos pos, final BlockState state) { + return BlockEntities.NETWORK_HUB.get().create(pos, state); + } +} diff --git a/src/main/java/li/cil/oc2/common/vxlan/TunnelManager.java b/src/main/java/li/cil/oc2/common/vxlan/TunnelManager.java new file mode 100644 index 00000000..1b641523 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/vxlan/TunnelManager.java @@ -0,0 +1,82 @@ +package li.cil.oc2.common.vxlan; + +import li.cil.oc2.api.capabilities.NetworkInterface; +import li.cil.oc2.common.Config; + +import java.io.IOException; +import java.net.*; +import java.util.HashMap; + +public class TunnelManager { + + private final HashMap tunnels = new HashMap<>(); + private final DatagramSocket socket; + private static TunnelManager INSTANCE; + + public TunnelManager(InetAddress bindHost, short bindPort, InetAddress remoteHost, short remotePort) throws SocketException { + socket = new DatagramSocket(bindPort, bindHost); + socket.connect(remoteHost, remotePort); + } + + public static void initialize() { + if (Config.enable) { + try { + INSTANCE = new TunnelManager( + InetAddress.getByName(Config.bindHost), Config.bindPort, + InetAddress.getByName(Config.remoteHost), Config.remotePort + ); + } catch (SocketException | UnknownHostException e) { + e.printStackTrace(); + } + + new Thread(new Runnable() { + @Override + public void run() { + INSTANCE.listen(); + } + }).start(); + } + } + + public void listen() { + byte[] buffer = new byte[65535]; + try { + while (true) { + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + socket.receive(packet); + + if (packet.getData().length < 8) { + continue; + } + + byte flags = packet.getData()[0]; + int vni_1 = packet.getData()[4]; + + if ((flags & 0x08) != 0x08) { + continue; + } + + NetworkInterface iface = tunnels.get(vni); + + if (iface != null) { + byte[] inner = new byte[packet.getData().length - 8]; + copyBytes(packet.getData(), inner, 8, 0, packet.getData().length - 8); + + iface.writeEthernetFrame(null, inner, 255); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static TunnelManager instance() { + return INSTANCE; + } + + private void copyBytes(byte[] input, byte[] output, int inputOffset, int outputOffset, int length) { + for (int i = 0; i < length; i++) { + output[outputOffset + i] = input[inputOffset + i]; + } + } +}