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 volatile boolean stopSam; public I2PSamPinger(String motd, String port, String privateKey) throws IOException { super(motd, port); // cba to mixin this.port = port; this.sam = new I2PSamControl(true, privateKey); } @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.status != Status.RUNNING) { return; } 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; 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) { FriendCode.LOGGER.warn("Friend Code connection closed!"); } } public Status status() { return this.status; } public String pubkey() { return this.sam.publicKey(); } public void stopSam() { this.stopSam = true; } public enum Status { IDLE, RUNNING, CONNECTION_FAILED, SETUP_FAILED, CONNECTION_CLOSED; } }