Пример #1
0
        // Reads all records in SaveTree
        // Reader must be positioned at start of first RecordElement
        void ReadRecords(BinaryReader reader)
        {
            RecordDictionary.Clear();
            RootRecord = new SaveTreeBaseRecord();
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                // Read record length and skip empty records as they have no data
                int length = reader.ReadInt32();
                if (length <= 0)
                {
                    continue;
                }

                // Handle potential stream overflow (e.g. corrupt save, something went wrong)
                if (reader.BaseStream.Position + length >= reader.BaseStream.Length)
                {
                    break;
                }

                // Peek record type from RecordRoot so we can instantiate record class based on type
                RecordTypes type = PeekRecordType(reader);

                // Add record based on type
                SaveTreeBaseRecord record;
                switch (type)
                {
                case RecordTypes.Item:
                    record = new ItemRecord(reader, length);
                    break;

                case RecordTypes.Character:
                    record = new CharacterRecord(reader, length);
                    break;

                case RecordTypes.Spell:
                    record = new SpellRecord(reader, length);
                    break;

                case RecordTypes.Container:
                    record = new ContainerRecord(reader, length);
                    break;

                //case RecordTypes.Door:
                //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                //    continue;
                //case RecordTypes.DungeonData:
                //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                //    continue;
                default:
                    record = new SaveTreeBaseRecord(reader, length);
                    break;
                }
                AddRecord(record);
            }

            LinkChildren();
        }
Пример #2
0
        /// <summary>
        /// Finds first record of type in tree starting from root record.
        /// </summary>
        /// <param name="type">Type of record to search for.</param>
        /// <param name="root">Root record to start searching from. If null, will start from RecordRoot.</param>
        /// <returns>Found item or null if not found.</returns>
        public SaveTreeBaseRecord FindRecord(RecordTypes type, SaveTreeBaseRecord root = null)
        {
            List <SaveTreeBaseRecord> records = FindRecords(type, root);

            if (records.Count == 0)
            {
                return(null);
            }

            return(records[0]);
        }
Пример #3
0
        // Recursively search for record type
        void FindRecordsByType(RecordTypes type, SaveTreeBaseRecord parent, List <SaveTreeBaseRecord> recordList)
        {
            if (parent.RecordType == type)
            {
                recordList.Add(parent);
            }

            for (int i = 0; i < parent.Children.Count; i++)
            {
                FindRecordsByType(type, parent.Children[i], recordList);
            }
        }
Пример #4
0
        /// <summary>
        /// Finds all instances of a specific record type in tree starting from root record.
        /// </summary>
        /// <param name="type">Type of record to search for.</param>
        /// <param name="root">Root record to start searching from. If null, will start from RecordRoot.</param>
        /// <returns>List of records found. May contain 0 records.</returns>
        public List <SaveTreeBaseRecord> FindRecords(RecordTypes type, SaveTreeBaseRecord root = null)
        {
            List <SaveTreeBaseRecord> recordList = new List <SaveTreeBaseRecord>();

            if (root == null)
            {
                root = RootRecord;
            }

            FindRecordsByType(type, root, recordList);

            return(recordList);
        }
Пример #5
0
        /// <summary>
        /// Shallow copy record data from this record to another.
        /// </summary>
        /// <param name="other">Other record to receive data.</param>
        public virtual void CopyTo(SaveTreeBaseRecord other)
        {
            if (other == null)
            {
                return;
            }

            other.streamPosition = this.streamPosition;
            other.streamLength   = this.streamLength;
            other.streamData     = (byte[])this.streamData.Clone();
            other.recordType     = this.recordType;
            other.recordRoot     = this.recordRoot;
            other.parent         = this.parent;
            other.children.AddRange(this.children.ToArray());
        }
Пример #6
0
 // Populates children of parent records
 void LinkChildren()
 {
     foreach (var kvp in RecordDictionary)
     {
         uint parentKey = kvp.Value.RecordRoot.ParentRecordID;
         if (RecordDictionary.ContainsKey(parentKey))
         {
             SaveTreeBaseRecord parent = RecordDictionary[parentKey];
             parent.Children.Add(kvp.Value);
         }
         else
         {
             RootRecord.Children.Add(kvp.Value);
         }
     }
 }
Пример #7
0
        // Adds record to dictionary
        bool AddRecord(SaveTreeBaseRecord record)
        {
            // Count duplicate IDs and ignore record
            uint myKey = record.RecordRoot.RecordID;

            if (RecordDictionary.ContainsKey(myKey))
            {
                duplicateKeysFound++;
                return(false);
            }

            // Add record to dictionary
            RecordDictionary.Add(myKey, record);

            return(true);
        }
        void DisplaySaveTree(SaveTreeBaseRecord parent)
        {
            for (int i = 0; i < parent.Children.Count; i++)
            {
                RecordTypes recordType = parent.Children[i].RecordType;
                if (recordType == RecordTypes.UnknownTownLink || recordType == RecordTypes.UnknownItemRecord)
                    continue;

                string textLabel = recordType.ToString();
                if (recordType == RecordTypes.Item || recordType == RecordTypes.Spell)
                {
                    textLabel += string.Format(" [{0}]", GetItemOrSpellName(parent.Children[i]));
                }

                // Check if item equipped
                if (recordType == RecordTypes.Item)
                {
                    //ItemRecord itemRecord = (ItemRecord)parent.Children[i];
                    //textLabel += string.Format(" [id={0}]", itemRecord.RecordRoot.RecordID);

                    int equippedIndex = GetEquippedIndex(parent.Children[i] as ItemRecord);
                    if (equippedIndex != -1)
                    {
                        //textLabel = string.Format("(*={0:00}) {1}", equippedIndex, textLabel);
                    }
                }

                // Tag wagon container
                if (recordType == RecordTypes.Container && parent.RecordType == RecordTypes.Character)
                {
                    ContainerRecord containerRecord = (ContainerRecord)parent.Children[i];
                    if (containerRecord.IsWagon)
                        textLabel += " [Wagon]";
                }

                EditorGUILayout.LabelField(textLabel);
                GUILayoutHelper.Indent(() =>
                {
                    DisplaySaveTree(parent.Children[i]);
                });
            }
        }
Пример #9
0
        /// <summary>
        /// Finds all instances of a specific record type in tree starting from root record.
        /// </summary>
        /// <param name="type">Type of record to search for.</param>
        /// <param name="root">Root record to start searching from. If null, will start from RecordRoot.</param>
        /// <returns>List of records found. May contain 0 records.</returns>
        public List<SaveTreeBaseRecord> FindRecords(RecordTypes type, SaveTreeBaseRecord root = null)
        {
            List<SaveTreeBaseRecord> recordList = new List<SaveTreeBaseRecord>();

            if (root == null)
                root = RootRecord;

            FindRecordsByType(type, root, recordList);

            return recordList;
        }
Пример #10
0
        // Adds record to dictionary
        bool AddRecord(SaveTreeBaseRecord record)
        {
            // Count duplicate IDs and ignore record
            uint myKey = record.RecordRoot.RecordID;
            if (RecordDictionary.ContainsKey(myKey))
            {
                duplicateKeysFound++;
                return false;
            }

            // Add record to dictionary
            RecordDictionary.Add(myKey, record);

            return true;
        }
Пример #11
0
        // Reads all records in SaveTree
        // Reader must be positioned at start of first RecordElement
        void ReadRecords(BinaryReader reader)
        {
            RecordDictionary.Clear();
            RootRecord = new SaveTreeBaseRecord();
            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                // Read record length and skip empty records as they have no data
                int length = reader.ReadInt32();
                if (length <= 0)
                    continue;

                // Handle potential stream overflow (e.g. corrupt save, something went wrong)
                if (reader.BaseStream.Position + length >= reader.BaseStream.Length)
                    break;

                // Peek record type from RecordRoot so we can instantiate record class based on type
                RecordTypes type = PeekRecordType(reader);

                // Add record based on type
                SaveTreeBaseRecord record;
                switch (type)
                {
                    case RecordTypes.Item:
                        record = new ItemRecord(reader, length);
                        break;
                    case RecordTypes.Spell:
                        record = new SpellRecord(reader, length);
                        break;
                    case RecordTypes.Character:
                        record = new CharacterRecord(reader, length);
                        break;
                    //case RecordTypes.UnknownTownLink:
                    //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                    //    continue;
                    //case RecordTypes.DungeonData:
                    //    record = new SaveTreeBaseRecord(reader, length);    // Read then skip these records for now
                    //    continue;
                    default:
                        record = new SaveTreeBaseRecord(reader, length);
                        break;
                }
                AddRecord(record);
            }

            LinkChildren();
        }
Пример #12
0
        // Recursively search for record type
        void FindRecordsByType(RecordTypes type, SaveTreeBaseRecord parent, List<SaveTreeBaseRecord> recordList)
        {
            if (parent.RecordType == type)
                recordList.Add(parent);

            for (int i = 0; i < parent.Children.Count; i++)
            {
                FindRecordsByType(type, parent.Children[i], recordList);
            }
        }
        string GetItemOrSpellName(SaveTreeBaseRecord record)
        {
            string result = string.Empty;

            byte[] recordData = record.RecordData;
            MemoryStream stream = new MemoryStream(recordData);
            BinaryReader reader = new BinaryReader(stream);

            if (record.RecordType == RecordTypes.Item)
            {
                result = FileProxy.ReadCString(reader);         // Name starts at offset 0
            }
            else if (record.RecordType == RecordTypes.Spell)
            {
                reader.BaseStream.Position += 47;               // Name starts at offset 47
                result = FileProxy.ReadCString(reader);
            }

            reader.Close();

            return result;
        }
 void ExportGUI(SaveTreeBaseRecord[] records, string name)
 {
     string path = EditorUtility.OpenFolderPanel("Export Path (Note: Place in subfolder as many files will be created)", "", "");
     if (!string.IsNullOrEmpty(path))
     {
         int index = 0;
         foreach(SaveTreeBaseRecord record in records)
         {
             string filename = Path.Combine(path, string.Format("{0}-{1}", name, index++));
             File.WriteAllBytes(filename, record.StreamData);
         }
         EditorUtility.DisplayDialog("Finished", string.Format("Exported {0} records.", index), "Close");
     }
 }
        /// <summary>
        /// Finds first record of type in tree starting from root record.
        /// </summary>
        /// <param name="type">Type of record to search for.</param>
        /// <param name="root">Root record to start searching from. If null, will start from RecordRoot.</param>
        /// <returns>Found item or null if not found.</returns>
        public SaveTreeBaseRecord FindRecord(RecordTypes type, SaveTreeBaseRecord root = null)
        {
            List<SaveTreeBaseRecord> records = FindRecords(type, root);
            if (records.Count == 0)
                return null;

            return records[0];
        }
Пример #16
0
        void DisplaySaveTree(SaveTreeBaseRecord parent)
        {
            for (int i = 0; i < parent.Children.Count; i++)
            {
                RecordTypes recordType = parent.Children[i].RecordType;
                if (recordType == RecordTypes.UnknownTownLink || recordType == RecordTypes.UnknownItemRecord)
                    continue;

                string textLabel = recordType.ToString();
                if (recordType == RecordTypes.Item || recordType == RecordTypes.Spell)
                {
                    textLabel += string.Format(" [{0}]", GetItemOrSpellName(parent.Children[i]));
                }

                EditorGUILayout.LabelField(textLabel);
                GUILayoutHelper.Indent(() =>
                {
                    DisplaySaveTree(parent.Children[i]);
                });
            }
        }
        /// <summary>
        /// Shallow copy record data from this record to another.
        /// </summary>
        /// <param name="other">Other record to receive data.</param>
        public virtual void CopyTo(SaveTreeBaseRecord other)
        {
            if (other == null)
                return;

            other.streamPosition = this.streamPosition;
            other.streamLength = this.streamLength;
            other.streamData = (byte[])this.streamData.Clone();
            other.recordType = this.recordType;
            other.recordRoot = this.recordRoot;
            other.parent = this.parent;
            other.children.AddRange(this.children.ToArray());
        }