Пример #1
0
        public static void UpdateConf(ConfBase conf, Record record)
        {
            var items = PatchManager.ByRecord(record);

            var set = items.Keys.ToHashSet();

            foreach (var item in conf.allConfBase)
            {
                // Narrowing to subtype
                var it = (ConfBaseItem)Il2CppHelper.Il2CppObjectPtrToIl2CppObjectByType(item.Pointer, record.ItemType);

                if (!items.TryGetValue(it.id, out var v))
                {
                    continue;
                }

                set.Remove(it.id);
                v.ApplyTo(it);
            }

            foreach (var item in set.Select(id => items[id]))
            {
                conf.allConfBase.Add(item.Construct());
            }
        }
Пример #2
0
        public static void DumpConf(ConfBase conf, Record record)
        {
            // Logger.Debug($"{conf.confName}, {record}");
            var confPath = Path.Combine(Env.BaseConfPath, $"{conf.confName}.json");

            using (var writer = new JsonTextWriter(new StreamWriter(confPath))
            {
                Indentation = 2,
                Formatting = Formatting.Indented
            })
            {
                writer.WriteStartArray();

                foreach (var item in conf.allConfBase)
                {
                    if (item == null)
                    {
                        // TODO: Find out why item could be null
                        continue;
                    }

                    // Narrowing to subtype
                    var it = Il2CppHelper.Il2CppObjectPtrToIl2CppObjectByType(item.Pointer, record.ItemType);

                    writer.WriteStartObject();

                    // `id` is a special case FieldsInfo missed
                    writer.WritePropertyName("id");
                    writer.WriteValue(item.id);
                    foreach (var p in record.FieldsInfo)
                    {
                        var field = p.Item1;

                        writer.WritePropertyName(field.Name);
                        // Assume all fields are serialized by writer
                        writer.WriteValue(field.GetValue(it));
                    }

                    writer.WriteEndObject();
                }

                writer.WriteEndArray();
            }
        }
Пример #3
0
            public Value(Type type, JValue value)
            {
                IsNone = value == null;

                @bool   = default;
                @byte   = default;
                @sbyte  = default;
                @short  = default;
                @ushort = default;
                @int    = default;
                @uint   = default;
                @long   = default;
                @ulong  = default;
                @char   = default;
                @double = default;
                @float  = default;
                @string = IL2CPP.ManagedStringToIl2Cpp("");

                if (type == typeof(string))
                {
                    tag = ValueType.String;
                    if (value == null)
                    {
                        return;
                    }
                    // FIXME:
                    //  The purpose of intern is to prevent GC from freeing our string to avoid UAF.
                    //  But intern will run into some performance problems sometimes.
                    //  Maybe making a reference circle is another solution.
                    @string = Il2CppHelper.il2cpp_string_intern(
                        IL2CPP.ManagedStringToIl2Cpp(value.Value <string>()));
                }
                else if (type == typeof(bool))
                {
                    tag = ValueType.Boolean;
                    if (value == null)
                    {
                        return;
                    }
                    @bool = value.Value <bool>();
                }
                else if (type == typeof(byte))
                {
                    tag = ValueType.Byte;
                    if (value == null)
                    {
                        return;
                    }
                    @byte = value.Value <byte>();
                }
                else if (type == typeof(sbyte))
                {
                    tag = ValueType.SByte;
                    if (value == null)
                    {
                        return;
                    }
                    @sbyte = value.Value <sbyte>();
                }
                else if (type == typeof(short))
                {
                    tag = ValueType.Int16;
                    if (value == null)
                    {
                        return;
                    }
                    @short = value.Value <short>();
                }
                else if (type == typeof(ushort))
                {
                    tag = ValueType.UInt16;
                    if (value == null)
                    {
                        return;
                    }
                    @ushort = value.Value <ushort>();
                }
                else if (type == typeof(int))
                {
                    tag = ValueType.Int32;
                    if (value == null)
                    {
                        return;
                    }
                    @int = value.Value <int>();
                }
                else if (type == typeof(uint))
                {
                    tag = ValueType.UInt32;
                    if (value == null)
                    {
                        return;
                    }
                    @uint = value.Value <uint>();
                }
                else if (type == typeof(long))
                {
                    tag = ValueType.Int64;
                    if (value == null)
                    {
                        return;
                    }
                    @long = value.Value <long>();
                }
                else if (type == typeof(ulong))
                {
                    tag = ValueType.UInt64;
                    if (value == null)
                    {
                        return;
                    }
                    @ulong = value.Value <ulong>();
                }
                else if (type == typeof(char))
                {
                    tag = ValueType.Char;
                    if (value == null)
                    {
                        return;
                    }
                    @char = value.Value <char>();
                }
                else if (type == typeof(double))
                {
                    tag = ValueType.Double;
                    if (value == null)
                    {
                        return;
                    }
                    @double = value.Value <double>();
                }
                else if (type == typeof(float))
                {
                    tag = ValueType.Single;
                    if (value == null)
                    {
                        return;
                    }
                    @float = value.Value <float>();
                }
                else
                {
                    throw new NotSupportedException($"Type {type} is not supported");
                }
            }
Пример #4
0
        public static void DumpConf(ConfBase conf, Record record)
        {
            // Logger.Debug($"{conf.confName}, {record}");
            var confPath = Path.Combine(Env.BaseConfPath, $"{conf.confName}.json");

            using (var writer = new JsonTextWriter(new StreamWriter(confPath))
            {
                Indentation = 2,
                Formatting = Formatting.Indented
            })
            {
                writer.WriteStartArray();

                foreach (var item in conf.allConfBase)
                {
                    if (item == null)
                    {
                        // TODO: Find out why item could be null
                        continue;
                    }

                    // Narrowing to subtype
                    var it = Il2CppHelper.Il2CppObjectPtrToIl2CppObjectByType(item.Pointer, record.ItemType);

                    writer.WriteStartObject();

                    // `id` is a special case FieldsInfo missed
                    writer.WritePropertyName("id");
                    writer.WriteValue(item.id);
                    foreach (var p in record.FieldsInfo)
                    {
                        var field = p.Item1;

                        writer.WritePropertyName(field.Name);

                        var v = field.GetValue(it);
                        // FIXME: It's a temporarily way and should be fixed later
                        if (field.PropertyType == typeof(Il2CppStructArray <int>))
                        {
                            writer.WriteStartArray();
                            foreach (var n in (Il2CppStructArray <int>)v)
                            {
                                writer.WriteValue(n);
                            }
                            writer.WriteEndArray();
                        }
                        else if (field.PropertyType == typeof(Il2CppStringArray))
                        {
                            writer.WriteStartArray();
                            foreach (var str in (Il2CppStringArray)v)
                            {
                                writer.WriteValue(str);
                            }
                            writer.WriteEndArray();
                        }
                        else if (field.PropertyType == typeof(Il2CppReferenceArray <Il2CppStructArray <float> >))
                        {
                            writer.WriteStartArray();
                            foreach (var a in (Il2CppReferenceArray <Il2CppStructArray <float> >)v)
                            {
                                writer.WriteStartArray();
                                foreach (var f in a)
                                {
                                    writer.WriteValue(f);
                                }
                                writer.WriteEndArray();
                            }
                            writer.WriteEndArray();
                        }
                        else if (field.PropertyType == typeof(Il2CppReferenceArray <Il2CppStructArray <int> >))
                        {
                            writer.WriteStartArray();
                            foreach (var ia in (Il2CppReferenceArray <Il2CppStructArray <int> >)v)
                            {
                                writer.WriteStartArray();
                                foreach (var i in ia)
                                {
                                    writer.WriteValue(i);
                                }
                                writer.WriteEndArray();
                            }
                            writer.WriteEndArray();
                        }
                        else if (field.PropertyType == typeof(Il2CppReferenceArray <Il2CppStringArray>))
                        {
                            writer.WriteStartArray();
                            foreach (var sa in (Il2CppReferenceArray <Il2CppStringArray>)v)
                            {
                                writer.WriteStartArray();
                                foreach (var s in sa)
                                {
                                    writer.WriteValue(s);
                                }
                                writer.WriteEndArray();
                            }
                            writer.WriteEndArray();
                        }
                        else
                        {
                            writer.WriteValue(v);
                        }
                    }

                    writer.WriteEndObject();
                }

                writer.WriteEndArray();
            }
        }