ISystemClock.cs 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System;
  2. namespace Ryujinx.HLE.HOS.Services.Time
  3. {
  4. class ISystemClock : IpcService
  5. {
  6. private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
  7. private SystemClockType _clockType;
  8. private DateTime _systemClockContextEpoch;
  9. private long _systemClockTimePoint;
  10. private byte[] _systemClockContextEnding;
  11. private long _timeOffset;
  12. public ISystemClock(SystemClockType clockType)
  13. {
  14. _clockType = clockType;
  15. _systemClockContextEpoch = System.Diagnostics.Process.GetCurrentProcess().StartTime;
  16. _systemClockContextEnding = new byte[0x10];
  17. _timeOffset = 0;
  18. if (clockType == SystemClockType.User ||
  19. clockType == SystemClockType.Network)
  20. {
  21. _systemClockContextEpoch = _systemClockContextEpoch.ToUniversalTime();
  22. }
  23. _systemClockTimePoint = (long)(_systemClockContextEpoch - Epoch).TotalSeconds;
  24. }
  25. [Command(0)]
  26. // GetCurrentTime() -> nn::time::PosixTime
  27. public long GetCurrentTime(ServiceCtx context)
  28. {
  29. DateTime currentTime = DateTime.Now;
  30. if (_clockType == SystemClockType.User ||
  31. _clockType == SystemClockType.Network)
  32. {
  33. currentTime = currentTime.ToUniversalTime();
  34. }
  35. context.ResponseData.Write((long)((currentTime - Epoch).TotalSeconds) + _timeOffset);
  36. return 0;
  37. }
  38. [Command(1)]
  39. // SetCurrentTime(nn::time::PosixTime)
  40. public long SetCurrentTime(ServiceCtx context)
  41. {
  42. DateTime currentTime = DateTime.Now;
  43. if (_clockType == SystemClockType.User ||
  44. _clockType == SystemClockType.Network)
  45. {
  46. currentTime = currentTime.ToUniversalTime();
  47. }
  48. _timeOffset = (context.RequestData.ReadInt64() - (long)(currentTime - Epoch).TotalSeconds);
  49. return 0;
  50. }
  51. [Command(2)]
  52. // GetSystemClockContext() -> nn::time::SystemClockContext
  53. public long GetSystemClockContext(ServiceCtx context)
  54. {
  55. context.ResponseData.Write((long)(_systemClockContextEpoch - Epoch).TotalSeconds);
  56. // The point in time, TODO: is there a link between epoch and this?
  57. context.ResponseData.Write(_systemClockTimePoint);
  58. // This seems to be some kind of identifier?
  59. for (int i = 0; i < 0x10; i++)
  60. {
  61. context.ResponseData.Write(_systemClockContextEnding[i]);
  62. }
  63. return 0;
  64. }
  65. [Command(3)]
  66. // SetSystemClockContext(nn::time::SystemClockContext)
  67. public long SetSystemClockContext(ServiceCtx context)
  68. {
  69. long newSystemClockEpoch = context.RequestData.ReadInt64();
  70. long newSystemClockTimePoint = context.RequestData.ReadInt64();
  71. _systemClockContextEpoch = Epoch.Add(TimeSpan.FromSeconds(newSystemClockEpoch));
  72. _systemClockTimePoint = newSystemClockTimePoint;
  73. _systemClockContextEnding = context.RequestData.ReadBytes(0x10);
  74. return 0;
  75. }
  76. }
  77. }