IPrepoService.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using MsgPack;
  2. using MsgPack.Serialization;
  3. using Ryujinx.Common;
  4. using Ryujinx.Common.Logging;
  5. using Ryujinx.Common.Utilities;
  6. using Ryujinx.HLE.HOS.Services.Account.Acc;
  7. using Ryujinx.HLE.Utilities;
  8. using System.Text;
  9. namespace Ryujinx.HLE.HOS.Services.Prepo
  10. {
  11. [Service("prepo:a")]
  12. [Service("prepo:a2")]
  13. [Service("prepo:u")]
  14. class IPrepoService : IpcService
  15. {
  16. public IPrepoService(ServiceCtx context) { }
  17. [Command(10100)] // 1.0.0-5.1.0
  18. // SaveReport(u64, pid, buffer<u8, 9>, buffer<bytes, 5>)
  19. public ResultCode SaveReportOld(ServiceCtx context)
  20. {
  21. // We don't care about the differences since we don't use the play report.
  22. return ProcessReport(context, withUserID: false);
  23. }
  24. [Command(10101)] // 1.0.0-5.1.0
  25. // SaveReportWithUserOld(nn::account::Uid, u64, pid, buffer<u8, 9>, buffer<bytes, 5>)
  26. public ResultCode SaveReportWithUserOld(ServiceCtx context)
  27. {
  28. // We don't care about the differences since we don't use the play report.
  29. return ProcessReport(context, withUserID: true);
  30. }
  31. [Command(10102)] // 6.0.0+
  32. // SaveReport(u64, pid, buffer<u8, 9>, buffer<bytes, 5>)
  33. public ResultCode SaveReport(ServiceCtx context)
  34. {
  35. // We don't care about the differences since we don't use the play report.
  36. return ProcessReport(context, withUserID: false);
  37. }
  38. [Command(10103)] // 6.0.0+
  39. // SaveReportWithUser(nn::account::Uid, u64, pid, buffer<u8, 9>, buffer<bytes, 5>)
  40. public ResultCode SaveReportWithUser(ServiceCtx context)
  41. {
  42. // We don't care about the differences since we don't use the play report.
  43. return ProcessReport(context, withUserID: true);
  44. }
  45. [Command(10200)]
  46. // RequestImmediateTransmission()
  47. public ResultCode RequestImmediateTransmission(ServiceCtx context)
  48. {
  49. // It signals an event of nn::prepo::detail::service::core::TransmissionStatusManager that requests the transmission of the report.
  50. // Since we don't use reports it's fine to do nothing.
  51. return ResultCode.Success;
  52. }
  53. [Command(10300)]
  54. // GetTransmissionStatus() -> u32
  55. public ResultCode GetTransmissionStatus(ServiceCtx context)
  56. {
  57. // It returns the transmission result of nn::prepo::detail::service::core::TransmissionStatusManager.
  58. // Since we don't use reports it's fine to return ResultCode.Success.
  59. context.ResponseData.Write((int)ResultCode.Success);
  60. return ResultCode.Success;
  61. }
  62. private ResultCode ProcessReport(ServiceCtx context, bool withUserID)
  63. {
  64. UserId userId = withUserID ? context.RequestData.ReadStruct<UserId>() : new UserId();
  65. string gameRoom = StringUtils.ReadUtf8String(context);
  66. if (withUserID)
  67. {
  68. if (userId.IsNull)
  69. {
  70. return ResultCode.InvalidArgument;
  71. }
  72. }
  73. if (gameRoom == string.Empty)
  74. {
  75. return ResultCode.InvalidState;
  76. }
  77. long inputPosition = context.Request.SendBuff[0].Position;
  78. long inputSize = context.Request.SendBuff[0].Size;
  79. if (inputSize == 0)
  80. {
  81. return ResultCode.InvalidBufferSize;
  82. }
  83. byte[] inputBuffer = new byte[inputSize];
  84. context.Memory.Read((ulong)inputPosition, inputBuffer);
  85. Logger.PrintInfo(LogClass.ServicePrepo, ReadReportBuffer(inputBuffer, gameRoom, userId));
  86. return ResultCode.Success;
  87. }
  88. private string ReadReportBuffer(byte[] buffer, string room, UserId userId)
  89. {
  90. StringBuilder builder = new StringBuilder();
  91. MessagePackObject deserializedReport = MessagePackSerializer.UnpackMessagePackObject(buffer);
  92. builder.AppendLine();
  93. builder.AppendLine("PlayReport log:");
  94. if (!userId.IsNull)
  95. {
  96. builder.AppendLine($" UserId: {userId.ToString()}");
  97. }
  98. builder.AppendLine($" Room: {room}");
  99. builder.AppendLine($" Report: {MessagePackObjectFormatter.Format(deserializedReport)}");
  100. return builder.ToString();
  101. }
  102. }
  103. }