From bfb981cd49a6bbcd15482dceeb4ab121c0408157 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 3 Jul 2022 23:12:06 -0300 Subject: [Project] Friend Code A Minecraft mod which adds friend codes, an easy way to play in the same world with remote friends. --- .../ganarchy/friendcode/client/I2PSamPinger.java | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/main/java/ganarchy/friendcode/client/I2PSamPinger.java (limited to 'src/main/java/ganarchy/friendcode/client/I2PSamPinger.java') diff --git a/src/main/java/ganarchy/friendcode/client/I2PSamPinger.java b/src/main/java/ganarchy/friendcode/client/I2PSamPinger.java new file mode 100644 index 0000000..96448db --- /dev/null +++ b/src/main/java/ganarchy/friendcode/client/I2PSamPinger.java @@ -0,0 +1,113 @@ +package ganarchy.friendcode.client; + +import ganarchy.friendcode.FriendCode; +import ganarchy.friendcode.sam.I2PSamControl; +import ganarchy.friendcode.sam.I2PSamStreamForwarder; +import net.minecraft.client.network.LanServerPinger; + +import java.io.*; + +public class I2PSamPinger extends LanServerPinger implements LanSendPing { + private final I2PSamControl sam; + private I2PSamStreamForwarder stream; + private final String port; + private volatile Status status = Status.IDLE; + private boolean hasWarned; + private volatile boolean stopSam; + + public I2PSamPinger(String motd, String port) throws IOException { + super(motd, port); + // cba to mixin + this.port = port; + this.sam = new I2PSamControl(true); + } + + @Override + public void run() { + try (final I2PSamControl sam = this.sam) { + if (!sam.connect()) { + this.status = Status.CONNECTION_FAILED; + // fall back to LAN server. + super.run(); + return; + } + + if (!sam.start()) { + this.status = Status.SETUP_FAILED; + // fall back to LAN server. + super.run(); + return; + } + + try (final I2PSamStreamForwarder stream = this.stream = sam.forwardStream(this.port)) { + if (!stream.connect()) { + this.status = Status.CONNECTION_FAILED; + super.run(); + return; + } + + if (!stream.start()) { + this.status = Status.SETUP_FAILED; + super.run(); + return; + } + + this.status = Status.RUNNING; + super.run(); + } catch (IOException ignored) { + } + } catch (IOException ignored) { + } + } + + @Override + public void friendcodeSendPing() { + if (this.stopSam) { + if (this.stream != null) { + try { + this.stream.close(); + } catch (IOException ignored) { + } + } + try { + this.sam.close(); + } catch (IOException ignored) { + } + this.status = Status.CONNECTION_CLOSED; + this.hasWarned = true; + return; + } + if (this.sam.sendPing() < 0) { + this.status = Status.CONNECTION_CLOSED; + } + if (this.stream != null) { + if (this.stream.sendPing() < 0) { + this.status = Status.CONNECTION_CLOSED; + } + } + if (this.status == Status.CONNECTION_CLOSED && !this.hasWarned) { + this.hasWarned = true; + FriendCode.LOGGER.warn("Friend Code connection closed!"); + } + } + + public Status status() { + return this.status; + } + + public String pubkey() { + return this.sam.pubkey(); + } + + public void stopSam() { + this.stopSam = true; + } + + public enum Status { + IDLE, + RUNNING, + CONNECTION_FAILED, + SETUP_FAILED, + CONNECTION_CLOSED; + } +} -- cgit 1.4.1