Ejemplo n.º 1
0
        public AbilityInfo GetAbility(Common.STUGUID key)
        {
            STULoadout ability = GetInstance <STULoadout>(key);

            if (ability == null)
            {
                return(null);
            }

            return(new AbilityInfo(key, GetString(ability.Name), GetString(ability.Description), ability.Category.ToString()));
        }
Ejemplo n.º 2
0
        public static Asset Excavate(ushort type, ulong guid)
        {
            Asset asset = new Asset {
                GUID = IO.GetFileName(guid),
                SerializationType = SerializationType.Unknown
            };

            using (Stream file = IO.OpenFile(guid)) {
                if (file == null)
                {
                    return(asset);
                }
                using (BinaryReader reader = new BinaryReader(file)) {
                    if (Version1.IsValidVersion(reader))
                    {
                        reader.BaseStream.Position = 0;
                        asset.SerializationType    = SerializationType.STUv1;
                        asset.STUInstances         = new HashSet <string>();
                        asset.GUIDs = new HashSet <string>();

                        reader.BaseStream.Position = 0;

                        // try and auto detect padding that is before a guid
                        int maxCount = 0;
                        for (int i = 0; i < reader.BaseStream.Length; i++)
                        {
                            byte b = reader.ReadByte();
                            if (b == 255)
                            {
                                maxCount++;
                            }
                            if (maxCount >= 8 && b != 255)
                            {
                                if (reader.BaseStream.Length - reader.BaseStream.Position > 8)
                                {
                                    reader.BaseStream.Position -= 1; // before b
                                    Common.STUGUID rawGUID = new Common.STUGUID(reader.ReadUInt64());
                                    reader.BaseStream.Position -= 7; // back to after b
                                    if (GUID.Type(rawGUID) > 1)
                                    {
                                        asset.GUIDs.Add(rawGUID.ToString());
                                    }
                                }
                            }
                            if (b != 255 && maxCount > 0)
                            {
                                maxCount = 0;
                            }
                        }
                    }
                    else if (type == 0xBC)
                    {
                        asset.SerializationType    = SerializationType.MapData;
                        asset.GUIDs                = new HashSet <string>();
                        asset.STUInstances         = new HashSet <string>();
                        reader.BaseStream.Position = 0;
                        Map map = new Map(file, uint.MaxValue);
                        foreach (ISTU stu in map.STUs)
                        {
                            asset.GUIDs = new HashSet <string>(asset.GUIDs.Concat(GetGUIDs(stu)).ToList());
                            foreach (Common.STUInstance stuInstance in stu.Instances)
                            {
                                STUAttribute attr = stuInstance?.GetType().GetCustomAttributes <STUAttribute>().FirstOrDefault();
                                if (attr == null)
                                {
                                    continue;
                                }
                                asset.STUInstances.Add(attr.Checksum.ToString("X8"));
                            }
                        }
                    }
                    else if (type == 0x6)
                    {
                        asset.SerializationType = SerializationType.Raw;

                        reader.BaseStream.Position = 0x18L;
                        ulong effectKey = reader.ReadUInt64();

                        reader.BaseStream.Position = 0;
                        Animation        animation = new Animation(reader.BaseStream);
                        HashSet <string> guids     = new HashSet <string>();
                        if (animation.Header.F08Key != 0)
                        {
                            guids.Add(IO.GetFileName(animation.Header.F08Key));
                        }
                        if (effectKey != 0)
                        {
                            guids.Add(IO.GetFileName(effectKey));
                        }

                        asset.GUIDs = guids;
                    }
                    else
                    {
                        if (Version2.IsValidVersion(reader))     // why is there no magic, blizz pls
                        {
                            reader.BaseStream.Position = 0;
                            Version2 stuVersion2 = null;
                            try {
                                stuVersion2             = new Version2(file, uint.MaxValue);
                                asset.SerializationType = SerializationType.STUv2;
                                asset.GUIDs             = new HashSet <string>();
                                asset.STUInstances      = new HashSet <string>();
                            } catch (Exception) {
                                asset.SerializationType = SerializationType.Unknown;
                            }
                            if (stuVersion2 != null)
                            {
                                asset.GUIDs = GetGUIDs(stuVersion2);
                                // broken: todo
                                // foreach (uint typeHash in stuVersion2.TypeHashes) {
                                //     asset.STUInstances.Add(typeHash.ToString("X8"));
                                // }
                                asset.JSONDump = "";
                                StringBuilder sb = new StringBuilder();

                                int i = 0;
                                foreach (Common.STUInstance stuInstance in stuVersion2.Instances.Concat(stuVersion2.HiddenInstances))
                                {
                                    STUAttribute attr = stuInstance?.GetType().GetCustomAttributes <STUAttribute>().FirstOrDefault();
                                    if (attr == null)
                                    {
                                        continue;
                                    }
                                    asset.STUInstances.Add($"{attr.Checksum:X8}");

                                    if (stuInstance.Usage != Common.InstanceUsage.Root)
                                    {
                                        continue;
                                    }
                                    if (i != 0)
                                    {
                                        sb.AppendLine();
                                    }
                                    sb.AppendLine($"{attr.Checksum:X8}:");
                                    sb.AppendLine(JsonConvert.SerializeObject(stuInstance, Formatting.Indented));
                                    i++;
                                }
                                asset.JSONDump = sb.ToString();
                            }
                        }
                    }
                }
            }
            return(asset);
        }
Ejemplo n.º 3
0
        protected FieldGuessData[] GuessFields(STUInstanceField[] definedFields, BinaryReader reader,
                                               uint instanceChecksum = 0)
        {
            FieldGuessData[] output = new FieldGuessData[definedFields.Length];
            // FieldLocationInfo[] fieldSizes = GetFieldSizes(definedFields, reader); // todo: use this for something

            uint outputIndex = 0;

            foreach (STUInstanceField field in definedFields)
            {
                FieldGuessData fieldOutput = new FieldGuessData {
                    Size = field.FieldSize, Checksum = field.FieldChecksum
                };

                if (instanceChecksum != 0)
                {
                    foreach (KeyValuePair <uint, List <ChainedInstanceInfo> > pair in ChainedInstances
                             ) // if (pair.Key != instanceChecksum) continue;
                    {
                        foreach (ChainedInstanceInfo info in pair.Value)
                        {
                            if (info.OwnerChecksum != instanceChecksum || info.OwnerField != field.FieldChecksum)
                            {
                                continue;
                            }
                            fieldOutput.IsChained = true;
                            fieldOutput.ChainedInstanceChecksum = info.Checksum;
                            break;
                        }
                    }
                }

                if (field.FieldSize == 0)
                {
                    TryReadInlineStandard(fieldOutput, reader);
                    TryReadInlineArray(fieldOutput, reader);

                    uint size = reader.ReadUInt32();

                    reader.BaseStream.Position += size;
                }
                else
                {
                    TryReadArray(fieldOutput, field, reader);
                    if (fieldOutput.IsArray)
                    {
                        TryReadArrayItems(fieldOutput);
                    }

                    long startPosition = reader.BaseStream.Position;

                    using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) {
                        byte[] fieldSHA1Demangle = null;
                        if (field.FieldSize == 8)
                        {
                            Common.STUGUID f = new Common.STUGUID(reader.ReadUInt64());
                            DemangleInstance(f, field.FieldChecksum);
                            fieldSHA1Demangle          = sha1.ComputeHash(BitConverter.GetBytes(f)); // is this bad?
                            reader.BaseStream.Position = startPosition;
                        }
                        byte[] fieldSHA1 = sha1.ComputeHash(reader.ReadBytes((int)field.FieldSize));

                        fieldOutput.SHA1         = fieldSHA1;
                        fieldOutput.DemangleSHA1 = fieldSHA1Demangle;
                    }
                }

                output[outputIndex] = fieldOutput;
                outputIndex++;
            }
            return(output);
        }