Beispiel #1
0
        private Dictionary <int, CPOffset> ReadOffsets(BinaryReader br)
        {
            var size   = br.ReadInt32();
            var offset = br.BaseStream.Position;
            var result = new Dictionary <int, CPOffset>(size >> 3);            // set initial capacity

            while (br.BaseStream.Position < offset + size)
            {
                var position = (int)(br.BaseStream.Position - offset);
                var count    = br.ReadUInt16();
                var cpoff    = new CPOffset(count, position);
                for (int a1 = 0; a1 < count; ++a1)
                {
                    cpoff.AttribOffsets.Add(br.ReadUInt16());
                }

                result[position >> 1] = cpoff;
            }

            return(result);
        }
Beispiel #2
0
        private Dictionary <int, int> MakeOffsetList(Dictionary <int, int> attrib_dict, out byte[] offset_buffer)
        {
            // Initialize stack
            var offset_map  = new Dictionary <int, int>();            // CPOffset to AttribOffset
            var offset_dict = new Dictionary <int, int>();            // RealCarPart to AttribOffset

            offset_buffer = null;
            int length = 0;
            int key    = 0;

            // Initialize streams
            using var ms = new MemoryStream();
            using var bw = new BinaryWriter(ms);

            // Iterate through every model in the database
            foreach (var model in this)
            {
                // Iterate through every RealCarPart in a model
                foreach (Parts.CarParts.RealCarPart realpart in model.ModelCarParts)
                {
                    // Skip if no attributes
                    if (realpart.Attributes.Count == 0)
                    {
                        offset_dict[realpart.GetHashCode()] = -1;
                        continue;
                    }

                    // Initialize new CPOffset and store all attribute offsets in it
                    var offset = new CPOffset(realpart.Attributes.Count);

                    foreach (var attrib in realpart.Attributes)
                    {
                        var index = attrib_dict[attrib.GetHashCode()];                         // get index
                        offset.AttribOffsets.Add((ushort)index);                               // add to CPOffset
                    }

                    offset.AttribOffsets.Sort();
                    key = offset.GetHashCode();

                    if (!offset_map.ContainsKey(key))                     // if CPOffset exists, skip
                    {
                        offset_map[key] = length;                         // write length to map
                        bw.Write((ushort)offset.AttribOffsets.Count);     // write count

                        foreach (var attrib in offset.AttribOffsets)      // write all attributes
                        {
                            bw.Write(attrib);
                        }

                        length += 1 + offset.AttribOffsets.Count;                         // increase length
                    }

                    offset_dict[realpart.GetHashCode()] = offset_map[key];                     // store to main map
                }
            }

            // Return prepared dictionary
            var dif = 0x10 - ((int)ms.Length + 0xC) % 0x10;

            if (dif != 0x10)
            {
                bw.WriteBytes(0, dif);
            }

            offset_buffer = ms.ToArray();
            return(offset_dict);
        }
        private Dictionary <int, int> MakeOffsetList(Dictionary <int, int> attrib_dict, out byte[] offset_buffer)
        {
            // Initialize stack
            var offset_map  = new Dictionary <int, int>();            // CPOffset to AttribOffset
            var offset_dict = new Dictionary <int, int>();            // RealCarPart to AttribOffset
            var offset_list = new Dictionary <int, CPOffset>();       // for debugging

            offset_buffer = null;
            int length = 0;
            int key    = 0;

            // Initialize streams
            using var ms = new MemoryStream();
            using var bw = new BinaryWriter(ms);

            // Iterate through every model in the database
            foreach (var model in this)
            {
                // Iterate through every RealCarPart in a model
                foreach (Parts.CarParts.RealCarPart realpart in model.ModelCarParts)
                {
                    // Skip if no attributes
                    if (realpart.Attributes.Count == 0)
                    {
                        offset_dict[realpart.GetHashCode()] = -1;
                        continue;
                    }

                    // Initialize new CPOffset and store all attribute offsets in it
                    var offset = new CPOffset(realpart.Attributes.Count);

                    foreach (var attrib in realpart.Attributes)
                    {
                        var index = attrib_dict[attrib.GetHashCode()];                         // get index
                        offset.AttribOffsets.Add((ushort)index);                               // add to CPOffset
                    }

                    offset.AttribOffsets.Sort();
                    key = offset.GetHashCode();

                    if (!offset_map.ContainsKey(key))                     // if CPOffset exists, skip
                    {
                        offset_map[key]  = length;                        // write length to map
                        offset_list[key] = offset;                        // save offset for debug

                        bw.Write((ushort)offset.AttribOffsets.Count);     // write count

                        foreach (var attrib in offset.AttribOffsets)      // write all attributes
                        {
                            bw.Write(attrib);
                        }

                        length += 1 + offset.AttribOffsets.Count;                         // increase length
                    }
                    else
                    {
                        var original = offset_list[key];

                        if (original != offset)
                        {
                            var logger = new Logger("MainLog.txt", "Nikki.dll : Carbon DatabaseSaver", true);

                            logger.WriteLine("Internal error has occurred: DBMP:AO Key Exception");
                            logger.WriteLine($"Comparing keys 9x{original.GetHashCode():X8} vs 0x{offset.GetHashCode():X8}");

                            logger.WriteLine($"Currently stored: {original}");
                            logger.WriteLine($"Attempted to add: {offset}");

                            logger.WriteLine("---------------------------------------------------------------------------");
                            logger.WriteLine("Currently stored information");
                            original.WriteToLog(logger);

                            logger.WriteLine("---------------------------------------------------------------------------");
                            logger.WriteLine("Attempted to add information");
                            offset.WriteToLog(logger);

                            throw new Exception("Internal error has occurred: DBMP:AO Key Exception. Please report to the developer immediately, " +
                                                "and try resaving the file!");
                        }
                    }

                    offset_dict[realpart.GetHashCode()] = offset_map[key];                     // store to main map
                }
            }

            // Return prepared dictionary
            var dif = 0x10 - ((int)ms.Length + 4) % 0x10;

            if (dif != 0x10)
            {
                bw.WriteBytes(0, dif);
            }

            offset_buffer = ms.ToArray();
            return(offset_dict);
        }