BrowserArgument.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using Ryujinx.HLE.HOS.Services.Account.Acc;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Runtime.CompilerServices;
  5. using System.Text;
  6. namespace Ryujinx.HLE.HOS.Applets.Browser
  7. {
  8. class BrowserArgument
  9. {
  10. public WebArgTLVType Type { get; }
  11. public byte[] Value { get; }
  12. public BrowserArgument(WebArgTLVType type, byte[] value)
  13. {
  14. Type = type;
  15. Value = value;
  16. }
  17. private static readonly Dictionary<WebArgTLVType, Type> _typeRegistry = new Dictionary<WebArgTLVType, Type>
  18. {
  19. { WebArgTLVType.InitialURL, typeof(string) },
  20. { WebArgTLVType.CallbackUrl, typeof(string) },
  21. { WebArgTLVType.CallbackableUrl, typeof(string) },
  22. { WebArgTLVType.ApplicationId, typeof(ulong) },
  23. { WebArgTLVType.DocumentPath, typeof(string) },
  24. { WebArgTLVType.DocumentKind, typeof(DocumentKind) },
  25. { WebArgTLVType.SystemDataId, typeof(ulong) },
  26. { WebArgTLVType.Whitelist, typeof(string) },
  27. { WebArgTLVType.NewsFlag, typeof(bool) },
  28. { WebArgTLVType.UserID, typeof(UserId) },
  29. { WebArgTLVType.ScreenShotEnabled, typeof(bool) },
  30. { WebArgTLVType.EcClientCertEnabled, typeof(bool) },
  31. { WebArgTLVType.UnknownFlag0x14, typeof(bool) },
  32. { WebArgTLVType.UnknownFlag0x15, typeof(bool) },
  33. { WebArgTLVType.PlayReportEnabled, typeof(bool) },
  34. { WebArgTLVType.BootDisplayKind, typeof(BootDisplayKind) },
  35. { WebArgTLVType.FooterEnabled, typeof(bool) },
  36. { WebArgTLVType.PointerEnabled, typeof(bool) },
  37. { WebArgTLVType.LeftStickMode, typeof(LeftStickMode) },
  38. { WebArgTLVType.KeyRepeatFrame1, typeof(int) },
  39. { WebArgTLVType.KeyRepeatFrame2, typeof(int) },
  40. { WebArgTLVType.BootAsMediaPlayerInverted, typeof(bool) },
  41. { WebArgTLVType.DisplayUrlKind, typeof(bool) },
  42. { WebArgTLVType.BootAsMediaPlayer, typeof(bool) },
  43. { WebArgTLVType.ShopJumpEnabled, typeof(bool) },
  44. { WebArgTLVType.MediaAutoPlayEnabled, typeof(bool) },
  45. { WebArgTLVType.LobbyParameter, typeof(string) },
  46. { WebArgTLVType.JsExtensionEnabled, typeof(bool) },
  47. { WebArgTLVType.AdditionalCommentText, typeof(string) },
  48. { WebArgTLVType.TouchEnabledOnContents, typeof(bool) },
  49. { WebArgTLVType.UserAgentAdditionalString, typeof(string) },
  50. { WebArgTLVType.MediaPlayerAutoCloseEnabled, typeof(bool) },
  51. { WebArgTLVType.PageCacheEnabled, typeof(bool) },
  52. { WebArgTLVType.WebAudioEnabled, typeof(bool) },
  53. { WebArgTLVType.PageFadeEnabled, typeof(bool) },
  54. { WebArgTLVType.BootLoadingIconEnabled, typeof(bool) },
  55. { WebArgTLVType.PageScrollIndicatorEnabled, typeof(bool) },
  56. { WebArgTLVType.MediaPlayerSpeedControlEnabled, typeof(bool) },
  57. { WebArgTLVType.OverrideWebAudioVolume, typeof(float) },
  58. { WebArgTLVType.OverrideMediaAudioVolume, typeof(float) },
  59. { WebArgTLVType.MediaPlayerUiEnabled, typeof(bool) },
  60. };
  61. public static (ShimKind, List<BrowserArgument>) ParseArguments(ReadOnlySpan<byte> data)
  62. {
  63. List<BrowserArgument> browserArguments = new List<BrowserArgument>();
  64. WebArgHeader header = IApplet.ReadStruct<WebArgHeader>(data.Slice(0, 8));
  65. ReadOnlySpan<byte> rawTLVs = data.Slice(8);
  66. for (int i = 0; i < header.Count; i++)
  67. {
  68. WebArgTLV tlv = IApplet.ReadStruct<WebArgTLV>(rawTLVs);
  69. ReadOnlySpan<byte> tlvData = rawTLVs.Slice(Unsafe.SizeOf<WebArgTLV>(), tlv.Size);
  70. browserArguments.Add(new BrowserArgument((WebArgTLVType)tlv.Type, tlvData.ToArray()));
  71. rawTLVs = rawTLVs.Slice(Unsafe.SizeOf<WebArgTLV>() + tlv.Size);
  72. }
  73. return (header.ShimKind, browserArguments);
  74. }
  75. public object GetValue()
  76. {
  77. if (_typeRegistry.TryGetValue(Type, out Type valueType))
  78. {
  79. if (valueType == typeof(string))
  80. {
  81. return Encoding.UTF8.GetString(Value);
  82. }
  83. else if (valueType == typeof(bool))
  84. {
  85. return Value[0] == 1;
  86. }
  87. else if (valueType == typeof(uint))
  88. {
  89. return BitConverter.ToUInt32(Value);
  90. }
  91. else if (valueType == typeof(int))
  92. {
  93. return BitConverter.ToInt32(Value);
  94. }
  95. else if (valueType == typeof(ulong))
  96. {
  97. return BitConverter.ToUInt64(Value);
  98. }
  99. else if (valueType == typeof(long))
  100. {
  101. return BitConverter.ToInt64(Value);
  102. }
  103. else if (valueType == typeof(float))
  104. {
  105. return BitConverter.ToSingle(Value);
  106. }
  107. else if (valueType == typeof(UserId))
  108. {
  109. return new UserId(Value);
  110. }
  111. else if (valueType.IsEnum)
  112. {
  113. return Enum.ToObject(valueType, BitConverter.ToInt32(Value));
  114. }
  115. return $"{valueType.Name} parsing not implemented";
  116. }
  117. return $"Unknown value format (raw length: {Value.Length})";
  118. }
  119. }
  120. }