Exemple #1
0
        private static unsafe void CPE_Part56(byte *part5ptr_t, byte *part6ptr_t, Database.Underground2 db)
        {
            int len5 = *(int *)(part5ptr_t + 4); // size of part5
            int len6 = *(int *)(part6ptr_t + 4); // size of part6

            if (len5 + 8 < Assert.CPPart5_AssertSize)
            {
                throw new FileLoadException("Detected corrupted GlobalB.lzc CarParts block. Unable to load database.");
            }
            if (len6 + 8 < Assert.CPPart6_AssertSize)
            {
                throw new FileLoadException("Detected corrupted GlobalB.lzc CarParts block. Unable to load database.");
            }

            // Exclude padding
            while (*(int *)(part5ptr_t + len5 + 4) == 0)
            {
                len5 -= 4;
            }
            while (*(int *)(part6ptr_t + len6 + 4) == 0)
            {
                len6 -= 4;
            }
            len6 = len6 / 0xE * 0xE + 8;

            int off5 = 8; // offset in part5
            int off6 = 8; // offset in part6
            int size = 0; // size of one part in part6

            // Validation check
            int check = *(part6ptr_t + len6 - 7) + 1;
            int total = len5 / 4;

            if (check < total)
            {
                len5 = check * 4 + 8;
            }

            db.SlotTypes.Part56 = new List <Part56>();
            var CarCNames = new List <uint>();

            foreach (var car in db.CarTypeInfos.Collections)
            {
                CarCNames.Add(car.BinKey);
            }

            while (off5 < len5 + 8 && db.SlotTypes.Part56.Count < 75)
            {
                uint ckey = *(uint *)(part5ptr_t + off5);
                if (ckey == 0)
                {
                    break;            // padding means end
                }
                bool IsCar   = false;
                byte current = 0;
                byte index   = *(part6ptr_t + off6 + 7);
                while (true)
                {
                    if (off6 + size + 7 >= len6)
                    {
                        break;
                    }
                    current = *(part6ptr_t + off6 + size + 7);
                    if (current != index)
                    {
                        break;
                    }
                    else
                    {
                        size += 0xE;
                    }
                }
                if (CarCNames.Contains(ckey))
                {
                    IsCar = true;
                }
                var Part = new Part56(ckey, part6ptr_t + off6, size, IsCar);
                db.SlotTypes.Part56.Add(Part);
                off5 += 4;
                off6 += size;
                size  = 0;
            }
        }
Exemple #2
0
        /// <summary>
        /// Writes all car parts into the Global data.
        /// </summary>
        /// <param name="db">Database with classes.</param>
        /// <param name="bw">BinaryWriter for writing data.</param>
        private static void I_CarParts(Database.Carbon db, BinaryWriter bw)
        {
            bw.Write(Global.CarParts);
            bw.Write(0xFFFFFFFF); // temp size

            int initial_size  = (int)bw.BaseStream.Position;
            int CarIDOffset   = initial_size + 0x30;
            int PartNumOffset = initial_size + 0x40;
            int padding       = 0;

            var keylists   = new List <uint>();
            var Intermid56 = new List <Part56>();
            var UsedPart56 = new List <Part56>();

            // Copy for processing
            for (int a1 = 0; a1 < db.SlotTypes.Part56.Count; ++a1)
            {
                Intermid56.Add(db.SlotTypes.Part56[a1].MemoryCast());
            }

            // Go through all cartypeinfo, set correct usagetype and keys
            foreach (var car in db.CarTypeInfos.Collections)
            {
                bool CarDoesExist = false;
                int  index        = 0;
                uint ckey         = car.BinKey;
                uint okey         = Bin.Hash(car.OriginalName);
                keylists.Add(ckey);
                for (index = 0; index < Intermid56.Count; ++index)
                {
                    if (okey == Intermid56[index].Key)
                    {
                        CarDoesExist = true;
                        break;
                    }
                }
                if (CarDoesExist)
                {
                    if (ckey != okey)
                    {
                        Intermid56[index].Key = ckey;
                    }
                    if (car.Modified && car.UsageType != Intermid56[index].Usage)
                    {
                        Intermid56[index].SetUsage(car.UsageType);
                    }
                }
                else
                {
                    var Class = new Part56(car.CollectionName, (byte)index, car.UsageType);
                    Intermid56.Add(Class);
                }
            }

            // Make new list of only used Part56 to write
            byte curlength = 0;

            for (int a1 = 0; a1 < Intermid56.Count; ++a1)
            {
                if (Intermid56[a1].IsCar && !keylists.Contains(Intermid56[a1].Key))
                {
                    continue;
                }
                Intermid56[a1].SetIndex(curlength++);
                UsedPart56.Add(Intermid56[a1]);
            }

            // Write parts 1-4
            bw.Write(db.SlotTypes.Part0.Data);
            bw.Write(db.SlotTypes.Part1.Data);
            bw.Write(db.SlotTypes.Part2.Data);
            bw.Write(db.SlotTypes.Part3.Data);
            bw.Write(db.SlotTypes.Part4.Data);

            // Write part 5
            int part5size = UsedPart56.Count * 4;

            padding = 0x10 - ((part5size + 8) % 0x10);
            if (padding == 0x10)
            {
                padding = 0;
            }
            part5size += padding;
            bw.Write(CarParts.Part5);
            bw.Write(part5size);
            for (int a1 = 0; a1 < UsedPart56.Count; ++a1)
            {
                bw.Write(UsedPart56[a1].Key);
            }
            for (int a1 = 0; a1 < padding; ++a1)
            {
                bw.Write((byte)0);
            }

            // Write part 6
            int part6size = 0;

            bw.Write(CarParts.Part6);
            int size6off = (int)bw.BaseStream.Position;

            bw.Write(0xFFFFFFFF); // temp size
            for (int a1 = 0; a1 < UsedPart56.Count; ++a1)
            {
                bw.Write(UsedPart56[a1].Data);
                part6size += UsedPart56[a1].Data.Length;
            }
            padding = 0x10 - ((part6size + 8) % 0x10);
            if (padding == 0x10)
            {
                padding = 0;
            }
            for (int a1 = 0; a1 < padding; ++a1)
            {
                bw.Write((byte)0);
            }
            part6size += padding;
            bw.BaseStream.Position = size6off;
            bw.Write(part6size);

            // Quick editing
            bw.BaseStream.Position = CarIDOffset;
            bw.Write(UsedPart56.Count);
            bw.BaseStream.Position = PartNumOffset;
            bw.Write(part6size / 4);
            bw.BaseStream.Position = initial_size - 4;
            bw.Write((int)bw.BaseStream.Length - initial_size);
            bw.BaseStream.Position = bw.BaseStream.Length;
        }
Exemple #3
0
        private static unsafe void CPE_Part56(byte *part5ptr_t, byte *part6ptr_t, Database.MostWanted db)
        {
            int len5 = *(int *)(part5ptr_t + 4) + 8; // size of part5
            int len6 = *(int *)(part6ptr_t + 4);     // size of part6

            // Exclude padding
            while (*(int *)(part5ptr_t + len5 - 4) == 0)
            {
                len5 -= 4;
            }
            while (*(int *)(part6ptr_t + len6 + 4) == 0)
            {
                len6 -= 4;
            }
            len6 = len6 / 0xE * 0xE + 8;

            int off5 = 8; // offset in part5
            int off6 = 8; // offset in part6
            int size = 0; // size of one part in part6

            // Validation check
            int check = *(part6ptr_t + len6 - 7) + 1;
            int total = (len5 - 8) / 4;

            if (check < total)
            {
                len5 = check * 4 + 8;
            }

            db.SlotTypes.Part56 = new List <Part56>();
            var CarCNames = new List <uint>();

            foreach (var car in db.CarTypeInfos.Collections)
            {
                CarCNames.Add(car.BinKey);
            }

            while (off5 < len5)
            {
                uint ckey = *(uint *)(part5ptr_t + off5);
                if (ckey == 0)
                {
                    break;            // padding means end
                }
                bool IsCar   = false;
                byte current = 0;
                byte index   = *(part6ptr_t + off6 + 7);
                while (true)
                {
                    if (off6 + size + 7 >= len6)
                    {
                        break;
                    }
                    current = *(part6ptr_t + off6 + size + 7);
                    if (current != index)
                    {
                        break;
                    }
                    else
                    {
                        size += 0xE;
                    }
                }
                if (CarCNames.Contains(ckey))
                {
                    IsCar = true;
                }
                var Part = new Part56(ckey, part6ptr_t + off6, size, IsCar);
                db.SlotTypes.Part56.Add(Part);
                off5 += 4;
                off6 += size;
                size  = 0;
            }
        }