Merge pull request #19 from Tarnadas/master
[sm64o.git] / PortcheckService / Program.cs
blob12ae61a09f32c3032f8146b3216ef2f699a17c48
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Net;
6 using System.Net.Sockets;
7 using System.Threading.Tasks;
9 namespace PortcheckService
11 class Program
13 private static UdpClient _mainSocket;
14 private static readonly byte[] MagicSequence = new byte[4] { 0x43, 0x4f, 0x4e, 0x43 };
15 private static readonly byte[] OurSequence = new byte[] { 0x73, 0x6d, 0x36, 0x34, 0x6f, 0x69, 0x70, 0x63, 0x30, 0x30, 0x30, 0x30 };
17 static void Main(string[] args)
19 Console.WriteLine("portcheck service starting up...");
20 int port = 6460;
22 if (args.Length > 0 && int.TryParse(args[0], out port))
25 Console.WriteLine("using port " + port);
27 try
29 IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port);
30 _mainSocket = new UdpClient(localEP);
32 Receive().GetAwaiter().GetResult();
34 catch (Exception e)
36 Console.WriteLine(e);
40 static async Task Receive()
42 while (true)
44 UdpReceiveResult result = await _mainSocket.ReceiveAsync();
45 await HandlePacket(result);
49 private static async Task HandlePacket(UdpReceiveResult res)
51 if (!ArrayCompare(OurSequence, 0, res.Buffer, 0, OurSequence.Length))
52 return;
54 byte[] readbackArray = new byte[MagicSequence.Length + 4];
56 Array.Copy(MagicSequence, 0, readbackArray, 0, MagicSequence.Length);
58 Array.Copy(res.RemoteEndPoint.Address.GetAddressBytes(), 0, readbackArray, MagicSequence.Length, 4);
60 short theirPort = BitConverter.ToInt16(res.Buffer, OurSequence.Length);
62 var returnEndPoint = new IPEndPoint(res.RemoteEndPoint.Address, theirPort);
64 await _mainSocket.SendAsync(readbackArray, readbackArray.Length, returnEndPoint);
67 private static bool ArrayCompare<T>(T[] left, int leftStart, T[] right, int rightStart, int len)
69 for (int i = 0; i < len; i++)
70 if (!EqualityComparer<T>.Default.Equals(left[i], right[i]))
71 return false;
73 return true;