Ver código fonte

prepo IPrepoService accurate parsing for report (#905)

* prepo IPrepoService accurate parsing for report

I've found they use msgpack for the report, so I've added a nuget package and deserialize the report in the right way.

Close #838

* jD requested changes

* Change nuget to MsgPack.Cli

* Use var instead of explicit cast
Ac_K 6 anos atrás
pai
commit
d218c2eead

+ 18 - 97
Ryujinx.HLE/HOS/Services/Prepo/IPrepoService.cs

@@ -1,7 +1,7 @@
+using MsgPack.Serialization;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.Utilities;
-using System;
-using System.Buffers.Binary;
+using System.Collections.Generic;
 using System.IO;
 using System.Text;
 
@@ -79,7 +79,7 @@ namespace Ryujinx.HLE.HOS.Services.Prepo
             return ResultCode.Success;
         }
 
-        public string ReadReportBuffer(byte[] buffer, string room, UInt128 userId)
+        private string ReadReportBuffer(byte[] buffer, string room, UInt128 userId)
         {
             StringBuilder sb = new StringBuilder();
 
@@ -93,103 +93,24 @@ namespace Ryujinx.HLE.HOS.Services.Prepo
 
             sb.AppendLine($" Room: {room}");
 
-            try
-            {
-                using (MemoryStream stream = new MemoryStream(buffer))
-                using (BinaryReader reader = new BinaryReader(stream))
-                {
-                    byte  unknown1 = reader.ReadByte();  // Version ?
-                    short unknown2 = reader.ReadInt16(); // Size ?
-
-                    bool isValue = false;
-
-                    string fieldStr = string.Empty;
-
-                    while (stream.Position != stream.Length)
-                    {
-                        byte descriptor = reader.ReadByte();
-
-                        if (!isValue)
-                        {
-                            byte[] key = reader.ReadBytes(descriptor - 0xA0);
-
-                            fieldStr = $"  Key: {Encoding.ASCII.GetString(key)}";
-
-                            isValue = true;
-                        }
-                        else
-                        {
-                            if (descriptor > 0xD0) // Int value.
-                            {
-                                if (descriptor - 0xD0 == 1)
-                                {
-                                    fieldStr += $", Value: {BinaryPrimitives.ReverseEndianness(reader.ReadUInt16())}";
-                                }
-                                else if (descriptor - 0xD0 == 2)
-                                {
-                                    fieldStr += $", Value: {BinaryPrimitives.ReverseEndianness(reader.ReadInt32())}";
-                                }
-                                else if (descriptor - 0xD0 == 4)
-                                {
-                                    fieldStr += $", Value: {BinaryPrimitives.ReverseEndianness(reader.ReadInt64())}";
-                                }
-                                else
-                                {
-                                    // Unknown.
-                                    break;
-                                }
-                            }
-                            else if (descriptor > 0xA0 && descriptor < 0xD0) // String value, max size = 0x20 bytes ?
-                            {
-                                int    size      = descriptor - 0xA0;
-                                string value     = string.Empty;
-                                byte[] rawValues = new byte[0];
-
-                                for (int i = 0; i < size; i++)
-                                {
-                                    byte chr = reader.ReadByte();
-
-                                    if (chr >= 0x20 && chr < 0x7f)
-                                    {
-                                        value += (char)chr;
-                                    }
-                                    else
-                                    {
-                                        Array.Resize(ref rawValues, rawValues.Length + 1);
-
-                                        rawValues[rawValues.Length - 1] = chr;
-                                    }
-                                }
-
-                                if (value != string.Empty)
-                                { 
-                                    fieldStr += $", Value: {value}";
-                                }
-
-                                // TODO(Ac_K): Determine why there are non-alphanumeric values sometimes.
-                                if (rawValues.Length > 0)
-                                {
-                                    fieldStr += $", RawValue: 0x{BitConverter.ToString(rawValues).Replace("-", "")}";
-                                }
-                            }
-                            else // Byte value.
-                            {
-                                fieldStr += $", Value: {descriptor}";
-                            }
-
-                            sb.AppendLine(fieldStr);
-
-                            isValue = false;
-                        }
-                    }
-                }
-            }
-            catch (Exception)
+            var payload = Deserialize<IDictionary<string, object>>(buffer);
+
+            foreach (var field in payload)
             {
-                sb.AppendLine("  Error while parsing the report buffer.");
+                sb.AppendLine($"  Key: {field.Key}, Value: {field.Value}");
             }
 
             return sb.ToString();
         }
+
+        private static T Deserialize<T>(byte[] bytes)
+        {
+            MessagePackSerializer serializer = MessagePackSerializer.Get<T>();
+
+            using (MemoryStream byteStream = new MemoryStream(bytes))
+            {
+                return (T)serializer.Unpack(byteStream);
+            }
+        }
     }
-}
+}

+ 1 - 0
Ryujinx.HLE/Ryujinx.HLE.csproj

@@ -53,6 +53,7 @@
   <ItemGroup>
     <PackageReference Include="Concentus" Version="1.1.7" />
     <PackageReference Include="LibHac" Version="0.8.2" />
+    <PackageReference Include="MsgPack.Cli" Version="1.0.1" />
     <PackageReference Include="TimeZoneConverter.Posix" Version="2.1.0" />
   </ItemGroup>