Merge pull request #19 from Tarnadas/master
[sm64o.git] / SM64O / NetworkHelper.cs
blob94cfe108cd5ac5482413aa2728d98df76224d9c4
1 using System;
2 using System.Net;
3 using System.Runtime.CompilerServices;
4 using System.Threading;
5 using System.Threading.Tasks;
7 namespace SM64O
9 public static class NetworkHelper
11 public static string ExternalIp;
12 public static int ConfirmedOpenPort;
14 private const string ServiceAddress = "napi.sm64o.com";
15 private const int ServicePort = 6460;
17 private static EndPoint Service = null;
19 private static bool _success; // this is dirty
21 private static bool _errOnce = false; // only show err message once
23 public static async Task<bool> RequestAssistance(int port)
25 /* if (ConfirmedOpenPort == port)
26 return true;
28 if (Service == null)
30 IPAddress address = Program.ResolveAddress(ServiceAddress);
32 // If api.sm64o.com closed
33 if (address == null)
34 return true;
35 Service = new IPEndPoint(address, ServicePort);
38 var server = ((UdpConnectionListener) new ConnectionListener());
40 if (server == null) return false;
42 _success = false;
43 ConfirmedOpenPort = 0;
44 ExternalIp = null;
46 server.UnconnectedDataReceived += DataReceived;
48 int tries = 1;
49 byte[] packet = BuildStartPacket((short) port);
53 await Task.Run(() => server.SendUnconnectedBytes(packet, Service));
55 await Task.Delay(1000 * tries);
56 tries++;
57 } while (tries < 4 && !_success);
59 server.UnconnectedDataReceived -= DataReceived;
61 if (_success)
62 ConfirmedOpenPort = port;
64 return _success;
67 private static void DataReceived(object sender/*, UnconnectedDataReceivedEventArgs e*/)
70 // We only want data from the source
71 if (e.Sender.GetHashCode() != Service.GetHashCode())
72 return;
74 // check response data
75 var response = System.Text.Encoding.ASCII.GetString(e.Data);
77 if (response.StartsWith("BADVER"))
79 if (!_errOnce)
80 System.Windows.Forms.MessageBox.Show("Failed to communicate with Net64 open port checker - your application is out-of-date.", "Out Of Date", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
81 _errOnce = true;
82 return;
85 if (response.StartsWith("OK "))
87 // read our IP
88 var wbf = response.Substring(3);
89 IPAddress add = IPAddress.Parse(wbf);
90 ExternalIp = add.ToString();
93 // Don't need to send back ACK
95 byte[] ack = new byte[4];
97 ack[0] = 0x41;
98 ack[0] = 0x43;
99 ack[0] = 0x4b;
100 ack[0] = 0x00;
102 ((UdpConnectionListener)Form1.listener).SendUnconnectedBytes(ack, Service);
104 // _success = true;
108 private static byte[] BuildStartPacket(short port)
110 byte[] buffer = new byte[400];
112 buffer[0] = 0x6e; // 'n'
113 buffer[1] = 0x65; // 'e'
114 buffer[2] = 0x74; // 't'
115 buffer[3] = 0x36; // '6'
116 buffer[4] = 0x34; // '4'
117 buffer[5] = 0x69; // 'i'
118 buffer[6] = 0x70; // 'p'
119 buffer[7] = 0x63; // 'c'
120 buffer[8] = 0x30; // '0'
121 buffer[9] = 0x30; // '0'
122 buffer[10] = 0x30; // '0'
123 buffer[11] = 0x30; // '0'
125 Array.Copy(BitConverter.GetBytes(port), 0, buffer, 12, 2);
127 return buffer;