NtpSyncModule.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #if DEBUG && !UNITY_WP_8_1 && !UNITY_WSA_8_1
  2. using System;
  3. using System.Threading;
  4. namespace FlyingWormConsole3.LiteNetLib
  5. {
  6. public class NtpSyncModule
  7. {
  8. public DateTime? SyncedTime { get; private set; }
  9. private readonly NetSocket _socket;
  10. private readonly NetEndPoint _ntpEndPoint;
  11. private readonly ManualResetEvent _waiter = new ManualResetEvent(false);
  12. public NtpSyncModule(string ntpServer)
  13. {
  14. _ntpEndPoint = new NetEndPoint(ntpServer, 123);
  15. _socket = new NetSocket(OnMessageReceived);
  16. _socket.Bind(0, false);
  17. SyncedTime = null;
  18. }
  19. private void OnMessageReceived(byte[] data, int length, int errorCode, NetEndPoint remoteEndPoint)
  20. {
  21. if (errorCode != 0)
  22. {
  23. _waiter.Set();
  24. return;
  25. }
  26. ulong intPart = (ulong)data[40] << 24 | (ulong)data[41] << 16 | (ulong)data[42] << 8 | (ulong)data[43];
  27. ulong fractPart = (ulong)data[44] << 24 | (ulong)data[45] << 16 | (ulong)data[46] << 8 | (ulong)data[47];
  28. var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
  29. SyncedTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);
  30. _waiter.Set();
  31. }
  32. public void GetNetworkTime()
  33. {
  34. if (SyncedTime != null)
  35. return;
  36. var ntpData = new byte[48];
  37. //LeapIndicator = 0 (no warning)
  38. //VersionNum = 3
  39. //Mode = 3 (Client Mode)
  40. ntpData[0] = 0x1B;
  41. //send
  42. int errorCode = 0;
  43. _socket.SendTo(ntpData, 0, ntpData.Length, _ntpEndPoint, ref errorCode);
  44. if(errorCode == 0)
  45. _waiter.WaitOne(1000);
  46. }
  47. }
  48. }
  49. #endif