private byte[] CalculateFileHash(ContentFile file, ref MD5 md5)
 {
     using (var stream = File.OpenRead(file.path))
     {
         return(md5.ComputeHash(stream));
     }
 }
        private void LoadConfig(ContentFile config)
        {
            try
            {
                XDocument doc = XMLExtensions.TryLoadXml(config.Path);
                if (doc == null)
                {
                    return;
                }
                var mainElement = doc.Root;
                if (mainElement.IsOverride())
                {
                    mainElement = doc.Root.FirstElement();
                    prefabs.Clear();
                    DebugConsole.NewMessage($"Overriding all background creatures with '{config.Path}'", Color.Yellow);
                }
                else if (prefabs.Any())
                {
                    DebugConsole.NewMessage($"Loading additional background creatures from file '{config.Path}'");
                }

                foreach (XElement element in mainElement.Elements())
                {
                    prefabs.Add(new BackgroundCreaturePrefab(element));
                }
                ;
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError(String.Format("Failed to load BackgroundCreatures from {0}", config.Path), e);
            }
        }
        public DecalPrefab(XElement element, ContentFile file)
        {
            Name = element.Name.ToString();

            Identifier = Name.ToLowerInvariant();

            FilePath = file.Path;

            ContentPackage = file.ContentPackage;

            Sprites = new List <Sprite>();

            foreach (XElement subElement in element.Elements())
            {
                if (subElement.Name.ToString().Equals("sprite", StringComparison.OrdinalIgnoreCase))
                {
                    Sprites.Add(new Sprite(subElement));
                }
            }

            Color = element.GetAttributeColor("color", Color.White);

            LifeTime    = element.GetAttributeFloat("lifetime", 10.0f);
            FadeOutTime = Math.Min(LifeTime, element.GetAttributeFloat("fadeouttime", 1.0f));
            FadeInTime  = Math.Min(LifeTime - FadeOutTime, element.GetAttributeFloat("fadeintime", 0.0f));
        }
Beispiel #4
0
        private byte[] CalculateFileHash(ContentFile file)
        {
            using (MD5 md5 = MD5.Create())
            {
                List <string> filePaths = new List <string> {
                    file.Path
                };
                List <byte> data = new List <byte>();

                switch (file.Type)
                {
                case ContentType.Character:
                    XDocument doc           = XMLExtensions.TryLoadXml(file.Path);
                    var       rootElement   = doc.Root;
                    var       element       = rootElement.IsOverride() ? rootElement.FirstElement() : rootElement;
                    var       ragdollFolder = RagdollParams.GetFolder(doc, file.Path).CleanUpPathCrossPlatform(true);
                    if (Directory.Exists(ragdollFolder))
                    {
                        Directory.GetFiles(ragdollFolder, "*.xml").ForEach(f => filePaths.Add(f));
                    }
                    var animationFolder = AnimationParams.GetFolder(doc, file.Path).CleanUpPathCrossPlatform(true);
                    if (Directory.Exists(animationFolder))
                    {
                        Directory.GetFiles(animationFolder, "*.xml").ForEach(f => filePaths.Add(f));
                    }
                    break;
                }

                if (filePaths.Count > 1)
                {
                    using (MD5 tempMd5 = MD5.Create())
                    {
                        filePaths = filePaths.OrderBy(f => ToolBox.StringToUInt32Hash(f.CleanUpPathCrossPlatform(true).ToLowerInvariant(), tempMd5)).ToList();
                    }
                }

                foreach (string filePath in filePaths)
                {
                    if (!File.Exists(filePath))
                    {
                        continue;
                    }

                    using (var stream = File.OpenRead(filePath))
                    {
                        byte[] fileData = new byte[stream.Length];
                        stream.Read(fileData, 0, (int)stream.Length);
                        if (filePath.EndsWith(".xml", true, System.Globalization.CultureInfo.InvariantCulture))
                        {
                            string text = System.Text.Encoding.UTF8.GetString(fileData);
                            text     = text.Replace("\n", "").Replace("\r", "").Replace("\\", "/");
                            fileData = System.Text.Encoding.UTF8.GetBytes(text);
                        }
                        data.AddRange(fileData);
                    }
                }
                return(md5.ComputeHash(data.ToArray()));
            }
        }
 public void RemoveFile(ContentFile file)
 {
     if (filesToAdd.Contains(file))
     {
         filesToAdd.Remove(file);
     }
     if (files.Contains(file) && !filesToRemove.Contains(file))
     {
         filesToRemove.Add(file);
     }
 }
        public ContentFile AddFile(string path, ContentType type)
        {
            if (Files.Find(file => file.Path == path && file.Type == type) != null)
            {
                return(null);
            }

            ContentFile cf = new ContentFile(path, type);

            Files.Add(cf);

            return(cf);
        }
        public void AddFile(ContentFile file)
        {
            if (filesToRemove.Contains(file))
            {
                filesToRemove.Remove(file);
            }
            if (Files.Concat(FilesToAdd).Any(f => f.Path == file.Path && f.Type == file.Type))
            {
                return;
            }

            filesToAdd.Add(file);
        }
        private byte[] CalculateFileHash(ContentFile file)
        {
            var md5 = MD5.Create();

            List <string> filePaths = new List <string> {
                file.Path
            };
            List <byte> data = new List <byte>();

            switch (file.Type)
            {
            case ContentType.Character:
                XDocument doc           = XMLExtensions.TryLoadXml(file.Path);
                var       rootElement   = doc.Root;
                var       element       = rootElement.IsOverride() ? rootElement.FirstElement() : rootElement;
                var       speciesName   = element.GetAttributeString("speciesname", element.GetAttributeString("name", ""));
                var       ragdollFolder = RagdollParams.GetFolder(speciesName);
                if (Directory.Exists(ragdollFolder))
                {
                    Directory.GetFiles(ragdollFolder, "*.xml").ForEach(f => filePaths.Add(f));
                }
                var animationFolder = AnimationParams.GetFolder(speciesName);
                if (Directory.Exists(animationFolder))
                {
                    Directory.GetFiles(animationFolder, "*.xml").ForEach(f => filePaths.Add(f));
                }
                break;
            }

            foreach (string filePath in filePaths)
            {
                if (!File.Exists(filePath))
                {
                    continue;
                }
                using (var stream = File.OpenRead(filePath))
                {
                    byte[] fileData = new byte[stream.Length];
                    stream.Read(fileData, 0, (int)stream.Length);
                    if (filePath.EndsWith(".xml", true, System.Globalization.CultureInfo.InvariantCulture))
                    {
                        string text = System.Text.Encoding.UTF8.GetString(fileData);
                        text     = text.Replace("\n", "").Replace("\r", "");
                        fileData = System.Text.Encoding.UTF8.GetBytes(text);
                    }
                    data.AddRange(fileData);
                }
            }
            return(md5.ComputeHash(data.ToArray()));
        }
        public ContentFile AddFile(string path, ContentType type)
        {
            if (Files.Concat(FilesToAdd).Any(file => file.Path == path && file.Type == type))
            {
                return(null);
            }

            ContentFile cf = new ContentFile(path, type)
            {
                ContentPackage = this
            };

            filesToAdd.Add(cf);

            return(cf);
        }
Beispiel #10
0
        public static void LoadFromFile(ContentFile file)
        {
            DebugConsole.Log("Loading talent prefab: " + file.Path);
            RemoveByFile(file.Path);

            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }

            var rootElement = doc.Root;

            switch (rootElement.Name.ToString().ToLowerInvariant())
            {
            case "talent":
                TalentPrefabs.Add(new TalentPrefab(rootElement, file.Path), false);
                break;

            case "talents":
                foreach (var element in rootElement.Elements())
                {
                    if (element.IsOverride())
                    {
                        var itemElement = element.GetChildElement("talent");
                        if (itemElement != null)
                        {
                            TalentPrefabs.Add(new TalentPrefab(rootElement, file.Path), true);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Cannot find a talent element from the children of the override element defined in {file.Path}");
                        }
                    }
                    else
                    {
                        TalentPrefabs.Add(new TalentPrefab(element, file.Path), false);
                    }
                }
                break;

            default:
                DebugConsole.ThrowError($"Invalid XML root element: '{rootElement.Name.ToString()}' in {file.Path}");
                break;
            }
        }
Beispiel #11
0
        private byte[] CalculateFileHash(ContentFile file)
        {
            var md5 = MD5.Create();

            List <string> filePaths = new List <string> {
                file.Path
            };
            List <byte> data = new List <byte>();

            switch (file.Type)
            {
            case ContentType.Character:
                XDocument doc         = XMLExtensions.TryLoadXml(file.Path);
                string    speciesName = doc.Root.GetAttributeString("name", "");
                //TODO: check non-default paths if defined
                filePaths.Add(RagdollParams.GetDefaultFile(speciesName, this));
                foreach (AnimationType animationType in Enum.GetValues(typeof(AnimationType)))
                {
                    filePaths.Add(AnimationParams.GetDefaultFile(speciesName, animationType, this));
                }
                break;
            }

            foreach (string filePath in filePaths)
            {
                if (!File.Exists(filePath))
                {
                    continue;
                }
                using (var stream = File.OpenRead(filePath))
                {
                    byte[] fileData = new byte[stream.Length];
                    stream.Read(fileData, 0, (int)stream.Length);
                    if (filePath.EndsWith(".xml", true, System.Globalization.CultureInfo.InvariantCulture))
                    {
                        string text = System.Text.Encoding.UTF8.GetString(fileData);
                        text     = text.Replace("\n", "").Replace("\r", "");
                        fileData = System.Text.Encoding.UTF8.GetBytes(text);
                    }
                    data.AddRange(fileData);
                }
            }
            return(md5.ComputeHash(data.ToArray()));
        }
        private byte[] CalculateXmlHash(ContentFile file, ref MD5 md5) //todo: Change ref to in (in C# 7.2)
        {
            var doc = XMLExtensions.TryLoadXml(file.path);

            if (doc == null)
            {
                throw new Exception($"file {file.path} could not be opened as XML document");
            }

            using (var memoryStream = new MemoryStream())
            {
                using (var writer = new StreamWriter(memoryStream))
                {
                    writer.Write(doc.ToString());
                    writer.Flush();

                    memoryStream.Position = 0;
                    return(md5.ComputeHash(memoryStream));
                }
            }
        }
        public static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }
            var mainElement = doc.Root.IsOverride() ? doc.Root.FirstElement() : doc.Root;

            if (doc.Root.IsOverride())
            {
                DebugConsole.ThrowError($"Error in '{file.Path}': Cannot override all job prefabs, because many of them are required by the main game! Please try overriding jobs one by one.");
            }
            foreach (XElement element in mainElement.Elements())
            {
                if (element.Name.ToString().Equals("nojob", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                if (element.IsOverride())
                {
                    var job = new JobPrefab(element.FirstElement(), file.Path)
                    {
                        ContentPackage = file.ContentPackage
                    };
                    Prefabs.Add(job, true);
                }
                else
                {
                    var job = new JobPrefab(element, file.Path)
                    {
                        ContentPackage = file.ContentPackage
                    };
                    Prefabs.Add(job, false);
                }
            }
            NoJobElement = NoJobElement ?? mainElement.Element("NoJob");
            NoJobElement = NoJobElement ?? mainElement.Element("nojob");
        }
        public static bool IsModFilePathAllowed(ContentFile contentFile)
        {
            string path = contentFile.Path;

            while (true)
            {
                string temp = System.IO.Path.GetDirectoryName(path);
                if (string.IsNullOrEmpty(temp))
                {
                    break;
                }
                path = temp;
            }
            switch (contentFile.Type)
            {
            case ContentType.Submarine:
                return(path == "Submarines" || path == "Mods");

            default:
                return(path == "Mods");
            }
        }
Beispiel #15
0
        private static void Load(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }
            var  mainElement     = doc.Root;
            bool allowOverriding = false;

            if (doc.Root.IsOverride())
            {
                mainElement     = doc.Root.FirstElement();
                allowOverriding = true;
            }
            foreach (XElement subElement in mainElement.Elements())
            {
                var    element    = subElement.IsOverride() ? subElement.FirstElement() : subElement;
                string identifier = element.Name.ToString();
                var    duplicate  = List.FirstOrDefault(e => e.Identifier.ToString().Equals(identifier, StringComparison.OrdinalIgnoreCase));
                if (duplicate != null)
                {
                    if (allowOverriding || subElement.IsOverride())
                    {
                        DebugConsole.NewMessage($"Overriding the existing preset '{identifier}' in the event manager settings using the file '{file.Path}'", Color.Yellow);
                        List.Remove(duplicate);
                    }
                    else
                    {
                        DebugConsole.ThrowError($"Error in '{file.Path}': Another element with the name '{identifier}' found! Each element must have a unique name. Use <override></override> tags if you want to override an existing preset.");
                        continue;
                    }
                }
                List.Add(new EventManagerSettings(element));
            }
            List.Sort((x, y) => { return(Math.Sign((x.MinLevelDifficulty + x.MaxLevelDifficulty) / 2.0f - (y.MinLevelDifficulty + y.MaxLevelDifficulty) / 2.0f)); });
        }
Beispiel #16
0
        public static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }
            var rootElement = doc.Root;

            if (rootElement.IsOverride())
            {
                foreach (var element in rootElement.Elements())
                {
                    foreach (var childElement in element.Elements())
                    {
                        Load(childElement, true, file);
                    }
                }
            }
            else
            {
                foreach (var element in rootElement.Elements())
                {
                    if (element.IsOverride())
                    {
                        foreach (var childElement in element.Elements())
                        {
                            Load(childElement, true, file);
                        }
                    }
                    else
                    {
                        Load(element, false, file);
                    }
                }
            }
        }
Beispiel #17
0
        public static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }

            string language   = doc.Root.GetAttributeString("Language", "English");
            string identifier = doc.Root.GetAttributeString("identifier", null);

            if (string.IsNullOrWhiteSpace(identifier))
            {
                DebugConsole.ThrowError($"Conversations file '{file.Path}' has no identifier!");
                return;
            }

            foreach (XElement subElement in doc.Root.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "conversation":
                    if (!allConversations.ContainsKey(identifier))
                    {
                        allConversations.Add(identifier, new ConversationCollection(identifier));
                    }
                    allConversations[identifier].Add(language, file.Path, subElement);
                    break;

                case "personalitytrait":
                    new NPCPersonalityTrait(subElement, file.Path);
                    break;
                }
            }
        }
        public static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            var rootElement = doc?.Root;

            if (rootElement == null)
            {
                return;
            }

            switch (rootElement.Name.ToString().ToLowerInvariant())
            {
            case "ballastflorabehavior":
            {
                new BallastFloraPrefab(rootElement, file.Path, false)
                {
                    ContentPackage = file.ContentPackage
                };
                break;
            }

            case "ballastflorabehaviors":
            {
                foreach (var element in rootElement.Elements())
                {
                    if (element.IsOverride())
                    {
                        XElement upgradeElement = element.GetChildElement("mapcreature");
                        if (upgradeElement != null)
                        {
                            new BallastFloraPrefab(upgradeElement, file.Path, true)
                            {
                                ContentPackage = file.ContentPackage
                            };
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Cannot find a map creature element from the children of the override element defined in {file.Path}");
                        }
                    }
                    else
                    {
                        if (element.Name.ToString().Equals("mapcreature", StringComparison.OrdinalIgnoreCase))
                        {
                            new BallastFloraPrefab(element, file.Path, false)
                            {
                                ContentPackage = file.ContentPackage
                            };
                        }
                    }
                }

                break;
            }

            case "override":
            {
                XElement mapCreatures = rootElement.GetChildElement("ballastflorabehaviors");
                if (mapCreatures != null)
                {
                    foreach (XElement element in mapCreatures.Elements())
                    {
                        new BallastFloraPrefab(element, file.Path, true)
                        {
                            ContentPackage = file.ContentPackage
                        };
                    }
                }

                foreach (XElement element in rootElement.GetChildElements("ballastflorabehavior"))
                {
                    new BallastFloraPrefab(element, file.Path, true)
                    {
                        ContentPackage = file.ContentPackage
                    };
                }

                break;
            }

            default:
            {
                DebugConsole.ThrowError($"Invalid XML root element: '{rootElement.Name}' in {file.Path}\n " +
                                        "Valid elements are: \"MapCreature\", \"MapCreatures\" and \"Override\".");
                break;
            }
            }
        }
Beispiel #19
0
        private static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            var rootElement = doc?.Root;

            if (rootElement == null)
            {
                return;
            }

            switch (rootElement.Name.ToString().ToLowerInvariant())
            {
            case "upgrademodule":
            {
                new UpgradePrefab(rootElement, file.Path, false)
                {
                    ContentPackage = file.ContentPackage
                };
                break;
            }

            case "upgradecategory":
            {
                new UpgradeCategory(rootElement);
                break;
            }

            case "upgrademodules":
            {
                foreach (var element in rootElement.Elements())
                {
                    if (element.IsOverride())
                    {
                        var upgradeElement = element.GetChildElement("upgradeprefab");
                        if (upgradeElement != null)
                        {
                            new UpgradePrefab(upgradeElement, file.Path, true)
                            {
                                ContentPackage = file.ContentPackage
                            };
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Cannot find an upgrade element from the children of the override element defined in {file.Path}");
                        }
                    }
                    else
                    {
                        switch (element.Name.ToString().ToLowerInvariant())
                        {
                        case "upgrademodule":
                        {
                            new UpgradePrefab(element, file.Path, false)
                            {
                                ContentPackage = file.ContentPackage
                            };
                            break;
                        }

                        case "upgradecategory":
                        {
                            new UpgradeCategory(element);
                            break;
                        }
                        }
                    }
                }

                break;
            }

            case "override":
            {
                var upgrades = rootElement.GetChildElement("upgrademodules");
                if (upgrades != null)
                {
                    foreach (var element in upgrades.Elements())
                    {
                        new UpgradePrefab(element, file.Path, true)
                        {
                            ContentPackage = file.ContentPackage
                        };
                    }
                }

                foreach (var element in rootElement.GetChildElements("upgrademodule"))
                {
                    new UpgradePrefab(element, file.Path, true)
                    {
                        ContentPackage = file.ContentPackage
                    };
                }

                break;
            }

            default:
                DebugConsole.ThrowError($"Invalid XML root element: '{rootElement.Name}' in {file.Path}\n " +
                                        "Valid elements are: \"UpgradeModule\", \"UpgradeModules\" and \"Override\".");
                break;
            }
        }
Beispiel #20
0
        private byte[] CalculateFileHash(ContentFile file)
        {
            using (MD5 md5 = MD5.Create())
            {
                List <string> filePaths = new List <string> {
                    file.Path
                };
                List <byte> data = new List <byte>();

                switch (file.Type)
                {
                case ContentType.Character:
                    XDocument doc           = XMLExtensions.TryLoadXml(file.Path);
                    var       rootElement   = doc.Root;
                    var       element       = rootElement.IsOverride() ? rootElement.FirstElement() : rootElement;
                    var       ragdollFolder = RagdollParams.GetFolder(doc, file.Path).CleanUpPathCrossPlatform(true);
                    if (Directory.Exists(ragdollFolder))
                    {
                        Directory.GetFiles(ragdollFolder, "*.xml").ForEach(f => filePaths.Add(f));
                    }
                    var animationFolder = AnimationParams.GetFolder(doc, file.Path).CleanUpPathCrossPlatform(true);
                    if (Directory.Exists(animationFolder))
                    {
                        Directory.GetFiles(animationFolder, "*.xml").ForEach(f => filePaths.Add(f));
                    }
                    break;
                }

                if (filePaths.Count > 1)
                {
                    using (MD5 tempMd5 = MD5.Create())
                    {
                        // TODO: ToLower() fixes discrepencies between windows folder name capitalization for server/client interactions.
                        // The proper fix would probably be to save both a case-sensitive and non-casesensitive hash on the server,
                        //     and only compare case-sensitive clients with the case-sensitive hash, and case-insensitive clients with the
                        //     case insensitive hash.
                        // Though ultimately, the only case where this will cause issues is if someone made a mod with identical folder names in the same path.
                        // Windows... 😩
                        filePaths = filePaths.OrderBy(f => ToolBox.StringToUInt32Hash(f.CleanUpPathCrossPlatform(true).ToLower(), tempMd5)).ToList();
                    }
                }

                foreach (string filePath in filePaths)
                {
                    if (!File.Exists(filePath))
                    {
                        continue;
                    }

                    using (var stream = File.OpenRead(filePath))
                    {
                        byte[] fileData = new byte[stream.Length];
                        stream.Read(fileData, 0, (int)stream.Length);
                        if (filePath.EndsWith(".xml", true, System.Globalization.CultureInfo.InvariantCulture))
                        {
                            string text = System.Text.Encoding.UTF8.GetString(fileData);
                            text     = text.Replace("\n", "").Replace("\r", "").Replace("\\", "/");
                            fileData = System.Text.Encoding.UTF8.GetBytes(text);
                        }
                        data.AddRange(fileData);
                    }
                }
                return(md5.ComputeHash(data.ToArray()));
            }
        }
        public static bool IsModFilePathAllowed(ContentFile contentFile)
        {
            string path = contentFile.Path;

            return(IsModFilePathAllowed(path));
        }
Beispiel #22
0
        public static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }
            var mainElement = doc.Root.IsOverride() ? doc.Root.FirstElement() : doc.Root;

            if (doc.Root.IsOverride())
            {
                DebugConsole.ThrowError("Cannot override all afflictions, because many of them are required by the main game! Please try overriding them one by one.");
            }
            foreach (XElement element in mainElement.Elements())
            {
                bool     isOverride    = element.IsOverride();
                XElement sourceElement = isOverride ? element.FirstElement() : element;
                string   elementName   = sourceElement.Name.ToString().ToLowerInvariant();
                string   identifier    = sourceElement.GetAttributeString("identifier", null);
                if (!elementName.Equals("cprsettings", StringComparison.OrdinalIgnoreCase) &&
                    !elementName.Equals("damageoverlay", StringComparison.OrdinalIgnoreCase))
                {
                    if (string.IsNullOrWhiteSpace(identifier))
                    {
                        DebugConsole.ThrowError($"No identifier defined for the affliction '{elementName}' in file '{file.Path}'");
                        continue;
                    }
                    if (Prefabs.ContainsKey(identifier))
                    {
                        if (isOverride)
                        {
                            DebugConsole.NewMessage($"Overriding an affliction or a buff with the identifier '{identifier}' using the file '{file.Path}'", Color.Yellow);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Duplicate affliction: '{identifier}' defined in {elementName} of '{file.Path}'");
                            continue;
                        }
                    }
                }
                string type = sourceElement.GetAttributeString("type", "");
                switch (sourceElement.Name.ToString().ToLowerInvariant())
                {
                case "cprsettings":
                    type = "cprsettings";
                    break;

                case "damageoverlay":
                    type = "damageoverlay";
                    break;
                }

                AfflictionPrefab prefab = null;
                switch (type)
                {
                case "damageoverlay":
#if CLIENT
                    if (CharacterHealth.DamageOverlay != null)
                    {
                        if (isOverride)
                        {
                            DebugConsole.NewMessage($"Overriding damage overlay with '{file.Path}'", Color.Yellow);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Error in '{file.Path}': damage overlay already loaded. Add <override></override> tags as the parent of the custom damage overlay sprite to allow overriding the vanilla one.");
                            break;
                        }
                    }
                    CharacterHealth.DamageOverlay?.Remove();
                    CharacterHealth.DamageOverlay     = new Sprite(element);
                    CharacterHealth.DamageOverlayFile = file.Path;
#endif
                    break;

                case "bleeding":
                    prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(AfflictionBleeding));
                    break;

                case "huskinfection":
                    prefab = new AfflictionPrefabHusk(sourceElement, file.Path, typeof(AfflictionHusk));
                    break;

                case "cprsettings":
                    if (CPRSettings.IsLoaded)
                    {
                        if (isOverride)
                        {
                            DebugConsole.NewMessage($"Overriding the CPR settings with '{file.Path}'", Color.Yellow);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Error in '{file.Path}': CPR settings already loaded. Add <override></override> tags as the parent of the custom CPRSettings to allow overriding the vanilla values.");
                            break;
                        }
                    }
                    CPRSettings.Load(sourceElement, file.Path);
                    break;

                case "damage":
                case "burn":
                case "oxygenlow":
                case "bloodloss":
                case "stun":
                case "pressure":
                case "internaldamage":
                    prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(Affliction))
                    {
                        ContentPackage = file.ContentPackage
                    };
                    break;

                default:
                    prefab = new AfflictionPrefab(sourceElement, file.Path)
                    {
                        ContentPackage = file.ContentPackage
                    };
                    break;
                }
                switch (identifier)
                {
                case "internaldamage":
                    InternalDamage = prefab;
                    break;

                case "bleeding":
                    Bleeding = prefab;
                    break;

                case "burn":
                    Burn = prefab;
                    break;

                case "oxygenlow":
                    OxygenLow = prefab;
                    break;

                case "bloodloss":
                    Bloodloss = prefab;
                    break;

                case "pressure":
                    Pressure = prefab;
                    break;

                case "stun":
                    Stun = prefab;
                    break;
                }
                if (prefab != null)
                {
                    Prefabs.Add(prefab, isOverride);
                }
            }

            using MD5 md5 = MD5.Create();
            foreach (AfflictionPrefab prefab in Prefabs)
            {
                prefab.UIntIdentifier = ToolBox.StringToUInt32Hash(prefab.Identifier, md5);

                //it's theoretically possible for two different values to generate the same hash, but the probability is astronomically small
                var collision = Prefabs.Find(p => p != prefab && p.UIntIdentifier == prefab.UIntIdentifier);
                if (collision != null)
                {
                    DebugConsole.ThrowError("Hashing collision when generating uint identifiers for Afflictions: " + prefab.Identifier + " has the same identifier as " + collision.Identifier + " (" + prefab.UIntIdentifier + ")");
                    collision.UIntIdentifier++;
                }
            }
        }
Beispiel #23
0
        public static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }
            var mainElement = doc.Root.IsOverride() ? doc.Root.FirstElement() : doc.Root;

            if (doc.Root.IsOverride())
            {
                DebugConsole.ThrowError("Cannot override all afflictions, because many of them are required by the main game! Please try overriding them one by one.");
            }

            List <(AfflictionPrefab prefab, XElement element)> loadedAfflictions = new List <(AfflictionPrefab prefab, XElement element)>();

            foreach (XElement element in mainElement.Elements())
            {
                bool     isOverride    = element.IsOverride();
                XElement sourceElement = isOverride ? element.FirstElement() : element;
                string   elementName   = sourceElement.Name.ToString().ToLowerInvariant();
                string   identifier    = sourceElement.GetAttributeString("identifier", null);
                if (!elementName.Equals("cprsettings", StringComparison.OrdinalIgnoreCase) &&
                    !elementName.Equals("damageoverlay", StringComparison.OrdinalIgnoreCase))
                {
                    if (string.IsNullOrWhiteSpace(identifier))
                    {
                        DebugConsole.ThrowError($"No identifier defined for the affliction '{elementName}' in file '{file.Path}'");
                        continue;
                    }
                    if (Prefabs.ContainsKey(identifier))
                    {
                        if (isOverride)
                        {
                            DebugConsole.NewMessage($"Overriding an affliction or a buff with the identifier '{identifier}' using the file '{file.Path}'", Color.Yellow);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Duplicate affliction: '{identifier}' defined in {elementName} of '{file.Path}'");
                            continue;
                        }
                    }
                }
                string type = sourceElement.GetAttributeString("type", "");
                switch (sourceElement.Name.ToString().ToLowerInvariant())
                {
                case "cprsettings":
                    type = "cprsettings";
                    break;

                case "damageoverlay":
                    type = "damageoverlay";
                    break;
                }

                AfflictionPrefab prefab = null;
                switch (type)
                {
                case "damageoverlay":
#if CLIENT
                    if (CharacterHealth.DamageOverlay != null)
                    {
                        if (isOverride)
                        {
                            DebugConsole.NewMessage($"Overriding damage overlay with '{file.Path}'", Color.Yellow);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Error in '{file.Path}': damage overlay already loaded. Add <override></override> tags as the parent of the custom damage overlay sprite to allow overriding the vanilla one.");
                            break;
                        }
                    }
                    CharacterHealth.DamageOverlay?.Remove();
                    CharacterHealth.DamageOverlay     = new Sprite(element);
                    CharacterHealth.DamageOverlayFile = file.Path;
#endif
                    break;

                case "bleeding":
                    prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(AfflictionBleeding));
                    break;

                case "huskinfection":
                case "alieninfection":
                    prefab = new AfflictionPrefabHusk(sourceElement, file.Path, typeof(AfflictionHusk));
                    break;

                case "cprsettings":
                    if (CPRSettings.IsLoaded)
                    {
                        if (isOverride)
                        {
                            DebugConsole.NewMessage($"Overriding the CPR settings with '{file.Path}'", Color.Yellow);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Error in '{file.Path}': CPR settings already loaded. Add <override></override> tags as the parent of the custom CPRSettings to allow overriding the vanilla values.");
                            break;
                        }
                    }
                    CPRSettings.Load(sourceElement, file.Path);
                    break;

                case "damage":
                case "burn":
                case "oxygenlow":
                case "bloodloss":
                case "stun":
                case "pressure":
                case "internaldamage":
                    prefab = new AfflictionPrefab(sourceElement, file.Path, typeof(Affliction))
                    {
                        ContentPackage = file.ContentPackage
                    };
                    break;

                default:
                    prefab = new AfflictionPrefab(sourceElement, file.Path)
                    {
                        ContentPackage = file.ContentPackage
                    };
                    break;
                }
                switch (identifier)
                {
                case "internaldamage":
                    InternalDamage = prefab;
                    break;

                case "blunttrauma":
                    ImpactDamage = prefab;
                    break;

                case "bleeding":
                    Bleeding = prefab;
                    break;

                case "burn":
                    Burn = prefab;
                    break;

                case "oxygenlow":
                    OxygenLow = prefab;
                    break;

                case "bloodloss":
                    Bloodloss = prefab;
                    break;

                case "pressure":
                    Pressure = prefab;
                    break;

                case "stun":
                    Stun = prefab;
                    break;

                case "radiationsickness":
                    RadiationSickness = prefab;
                    break;
                }
                if (ImpactDamage == null)
                {
                    ImpactDamage = InternalDamage;
                }

                if (prefab != null)
                {
                    loadedAfflictions.Add((prefab, sourceElement));
                    Prefabs.Add(prefab, isOverride);
                    prefab.CalculatePrefabUIntIdentifier(Prefabs);
                }
            }

            //load the effects after all the afflictions in the file have been instantiated
            //otherwise afflictions can't inflict other afflictions that are defined at a later point in the file
            foreach ((AfflictionPrefab prefab, XElement element) in loadedAfflictions)
            {
                prefab.LoadEffects(element);
            }
        }
 public void RemoveFile(ContentFile file)
 {
     Files.Remove(file);
 }
Beispiel #25
0
        public static void LoadFromFile(ContentFile file)
        {
            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }
            var mainElement = doc.Root.IsOverride() ? doc.Root.FirstElement() : doc.Root;

            if (doc.Root.IsOverride())
            {
                DebugConsole.ThrowError($"Error in '{file.Path}': Cannot override all job prefabs, because many of them are required by the main game! Please try overriding jobs one by one.");
            }
            foreach (XElement element in mainElement.Elements())
            {
                if (element.IsOverride())
                {
                    var job = new JobPrefab(element.FirstElement(), file.Path)
                    {
                        ContentPackage = file.ContentPackage
                    };
                    Prefabs.Add(job, true);
                }
                else
                {
                    if (!element.Name.ToString().Equals("job", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }
                    var job = new JobPrefab(element, file.Path)
                    {
                        ContentPackage = file.ContentPackage
                    };
                    Prefabs.Add(job, false);
                }
            }
            NoJobElement ??= mainElement.GetChildElement("nojob");
            var itemRepairPrioritiesElement = mainElement.GetChildElement("ItemRepairPriorities");

            if (itemRepairPrioritiesElement != null)
            {
                foreach (var subElement in itemRepairPrioritiesElement.Elements())
                {
                    string tag = subElement.GetAttributeString("tag", null);
                    if (tag != null)
                    {
                        float priority = subElement.GetAttributeFloat("priority", -1f);
                        if (priority >= 0)
                        {
                            _itemRepairPriorities.TryAdd(tag, priority);
                        }
                        else
                        {
                            DebugConsole.AddWarning($"The 'priority' attribute is missing from the the item repair priorities definition in {subElement} of {file.Path}.");
                        }
                    }
                    else
                    {
                        DebugConsole.AddWarning($"The 'tag' attribute is missing from the the item repair priorities definition in {subElement} of {file.Path}.");
                    }
                }
            }
        }
Beispiel #26
0
        public void LoadFromFile(ContentFile configFile)
        {
            XDocument doc = XMLExtensions.TryLoadXml(configFile.Path);

            if (doc == null)
            {
                return;
            }

            if (grimeSpritesByFile.ContainsKey(configFile.Path))
            {
                foreach (Sprite sprite in grimeSpritesByFile[configFile.Path])
                {
                    sprite.Remove();
                    GrimeSprites.Remove(sprite);
                }
                grimeSpritesByFile.Remove(configFile.Path);
            }

            bool allowOverriding = false;
            var  mainElement     = doc.Root;

            if (doc.Root.IsOverride())
            {
                mainElement     = doc.Root.FirstElement();
                allowOverriding = true;
            }

            foreach (XElement sourceElement in mainElement.Elements())
            {
                var    element = sourceElement.IsOverride() ? sourceElement.FirstElement() : sourceElement;
                string name    = element.Name.ToString().ToLowerInvariant();

                switch (name)
                {
                case "grime":
                    if (!grimeSpritesByFile.ContainsKey(configFile.Path))
                    {
                        grimeSpritesByFile.Add(configFile.Path, new List <Sprite>());
                    }
                    var grimeSprite = new Sprite(element);
                    GrimeSprites.Add(grimeSprite);
                    grimeSpritesByFile[configFile.Path].Add(grimeSprite);
                    break;

                default:
                    if (Prefabs.ContainsKey(name))
                    {
                        if (allowOverriding || sourceElement.IsOverride())
                        {
                            DebugConsole.NewMessage($"Overriding the existing decal prefab '{name}' using the file '{configFile.Path}'", Color.Yellow);
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Error in '{configFile.Path}': Duplicate decal prefab '{name}' found in '{configFile.Path}'! Each decal prefab must have a unique name. " +
                                                    "Use <override></override> tags to override prefabs.");
                            continue;
                        }
                    }
                    Prefabs.Add(new DecalPrefab(element, configFile), allowOverriding || sourceElement.IsOverride());
                    break;
                }
            }

            using MD5 md5 = MD5.Create();
            foreach (DecalPrefab prefab in Prefabs)
            {
                prefab.UIntIdentifier = ToolBox.StringToUInt32Hash(prefab.Identifier, md5);

                //it's theoretically possible for two different values to generate the same hash, but the probability is astronomically small
                var collision = Prefabs.Find(p => p != prefab && p.UIntIdentifier == prefab.UIntIdentifier);
                if (collision != null)
                {
                    DebugConsole.ThrowError("Hashing collision when generating uint identifiers for Decals: " + prefab.Identifier + " has the same identifier as " + collision.Identifier + " (" + prefab.UIntIdentifier + ")");
                    collision.UIntIdentifier++;
                }
            }
        }
Beispiel #27
0
        private static StructurePrefab Load(XElement element, bool allowOverride, ContentFile file)
        {
            StructurePrefab sp = new StructurePrefab
            {
                originalName   = element.GetAttributeString("name", ""),
                FilePath       = file.Path,
                ContentPackage = file.ContentPackage
            };

            sp.name          = sp.originalName;
            sp.ConfigElement = element;
            sp.identifier    = element.GetAttributeString("identifier", "");

            var parentType = element.Parent?.GetAttributeString("prefabtype", "") ?? string.Empty;

            string nameIdentifier        = element.GetAttributeString("nameidentifier", "");
            string descriptionIdentifier = element.GetAttributeString("descriptionidentifier", "");

            if (string.IsNullOrEmpty(sp.originalName))
            {
                if (string.IsNullOrEmpty(nameIdentifier))
                {
                    sp.name = TextManager.Get("EntityName." + sp.identifier, true) ?? string.Empty;
                }
                else
                {
                    sp.name = TextManager.Get("EntityName." + nameIdentifier, true) ?? string.Empty;
                }
            }

            if (string.IsNullOrEmpty(sp.name))
            {
                sp.name = TextManager.Get("EntityName." + sp.identifier, returnNull: true) ?? $"Not defined ({sp.identifier})";
            }
            sp.Tags = new HashSet <string>();
            string joinedTags = element.GetAttributeString("tags", "");

            if (string.IsNullOrEmpty(joinedTags))
            {
                joinedTags = element.GetAttributeString("Tags", "");
            }
            foreach (string tag in joinedTags.Split(','))
            {
                sp.Tags.Add(tag.Trim().ToLowerInvariant());
            }

            if (element.Attribute("ishorizontal") != null)
            {
                sp.IsHorizontal = element.GetAttributeBool("ishorizontal", false);
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString())
                {
                case "sprite":
                    sp.sprite = new Sprite(subElement, lazyLoad: true);
                    if (subElement.Attribute("sourcerect") == null)
                    {
                        DebugConsole.ThrowError("Warning - sprite sourcerect not configured for structure \"" + sp.name + "\"!");
                    }
#if CLIENT
                    if (subElement.GetAttributeBool("fliphorizontal", false))
                    {
                        sp.sprite.effects = SpriteEffects.FlipHorizontally;
                    }
                    if (subElement.GetAttributeBool("flipvertical", false))
                    {
                        sp.sprite.effects = SpriteEffects.FlipVertically;
                    }
#endif
                    sp.canSpriteFlipX = subElement.GetAttributeBool("canflipx", true);
                    sp.canSpriteFlipY = subElement.GetAttributeBool("canflipy", true);

                    if (subElement.Attribute("name") == null && !string.IsNullOrWhiteSpace(sp.Name))
                    {
                        sp.sprite.Name = sp.Name;
                    }
                    sp.sprite.EntityID = sp.identifier;
                    break;

                case "backgroundsprite":
                    sp.BackgroundSprite = new Sprite(subElement, lazyLoad: true);
                    if (subElement.Attribute("sourcerect") == null && sp.sprite != null)
                    {
                        sp.BackgroundSprite.SourceRect     = sp.sprite.SourceRect;
                        sp.BackgroundSprite.size           = sp.sprite.size;
                        sp.BackgroundSprite.size.X        *= sp.sprite.SourceRect.Width;
                        sp.BackgroundSprite.size.Y        *= sp.sprite.SourceRect.Height;
                        sp.BackgroundSprite.RelativeOrigin = subElement.GetAttributeVector2("origin", new Vector2(0.5f, 0.5f));
                    }
#if CLIENT
                    if (subElement.GetAttributeBool("fliphorizontal", false))
                    {
                        sp.BackgroundSprite.effects = SpriteEffects.FlipHorizontally;
                    }
                    if (subElement.GetAttributeBool("flipvertical", false))
                    {
                        sp.BackgroundSprite.effects = SpriteEffects.FlipVertically;
                    }
                    sp.BackgroundSpriteColor = subElement.GetAttributeColor("color", Color.White);
#endif
                    break;

                case "decorativesprite":
#if CLIENT
                    string decorativeSpriteFolder = "";
                    if (!subElement.GetAttributeString("texture", "").Contains("/"))
                    {
                        decorativeSpriteFolder = Path.GetDirectoryName(file.Path);
                    }

                    int groupID = 0;
                    DecorativeSprite decorativeSprite = null;
                    if (subElement.Attribute("texture") == null)
                    {
                        groupID = subElement.GetAttributeInt("randomgroupid", 0);
                    }
                    else
                    {
                        decorativeSprite = new DecorativeSprite(subElement, decorativeSpriteFolder, lazyLoad: true);
                        sp.DecorativeSprites.Add(decorativeSprite);
                        groupID = decorativeSprite.RandomGroupID;
                    }
                    if (!sp.DecorativeSpriteGroups.ContainsKey(groupID))
                    {
                        sp.DecorativeSpriteGroups.Add(groupID, new List <DecorativeSprite>());
                    }
                    sp.DecorativeSpriteGroups[groupID].Add(decorativeSprite);
#endif
                    break;
                }
            }

            if (string.Equals(parentType, "wrecked", StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrEmpty(sp.Name))
                {
                    sp.name = TextManager.GetWithVariable("wreckeditemformat", "[name]", sp.name);
                }
            }

            string categoryStr = element.GetAttributeString("category", "Structure");
            if (!Enum.TryParse(categoryStr, true, out MapEntityCategory category))
            {
                category = MapEntityCategory.Structure;
            }
            sp.Category = category;

            if (category.HasFlag(MapEntityCategory.Legacy))
            {
                if (string.IsNullOrWhiteSpace(sp.identifier))
                {
                    sp.identifier = "legacystructure_" + sp.name.ToLowerInvariant().Replace(" ", "");
                }
            }

            sp.Aliases =
                (element.GetAttributeStringArray("aliases", null) ??
                 element.GetAttributeStringArray("Aliases", new string[0])).ToHashSet();

            string nonTranslatedName = element.GetAttributeString("name", null) ?? element.Name.ToString();
            sp.Aliases.Add(nonTranslatedName.ToLowerInvariant());

            SerializableProperty.DeserializeProperties(sp, element);
            if (sp.Body)
            {
                sp.Tags.Add("wall");
            }

            if (string.IsNullOrEmpty(sp.Description))
            {
                if (!string.IsNullOrEmpty(descriptionIdentifier))
                {
                    sp.Description = TextManager.Get("EntityDescription." + descriptionIdentifier, returnNull: true) ?? string.Empty;
                }
                else if (string.IsNullOrEmpty(nameIdentifier))
                {
                    sp.Description = TextManager.Get("EntityDescription." + sp.identifier, returnNull: true) ?? string.Empty;
                }
                else
                {
                    sp.Description = TextManager.Get("EntityDescription." + nameIdentifier, true) ?? string.Empty;
                }
            }

            //backwards compatibility
            if (element.Attribute("size") == null)
            {
                sp.size = Vector2.Zero;
                if (element.Attribute("width") == null && element.Attribute("height") == null)
                {
                    sp.size.X = sp.sprite.SourceRect.Width;
                    sp.size.Y = sp.sprite.SourceRect.Height;
                }
                else
                {
                    sp.size.X = element.GetAttributeFloat("width", 0.0f);
                    sp.size.Y = element.GetAttributeFloat("height", 0.0f);
                }
            }

            //backwards compatibility
            if (categoryStr.Equals("Thalamus", StringComparison.OrdinalIgnoreCase))
            {
                sp.Category    = MapEntityCategory.Wrecked;
                sp.Subcategory = "Thalamus";
            }

            if (string.IsNullOrEmpty(sp.identifier))
            {
                DebugConsole.ThrowError(
                    "Structure prefab \"" + sp.name + "\" has no identifier. All structure prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
            }
            Prefabs.Add(sp, allowOverride);
            return(sp);
        }
Beispiel #28
0
 public static bool LoadFromFile(ContentFile file, bool forceOverride = false)
 {
     return(LoadFromFile(file.Path, file.ContentPackage, forceOverride));
 }
Beispiel #29
0
        public static void LoadFromFile(ContentFile file)
        {
            DebugConsole.Log("*** " + file.Path + " ***");
            RemoveByFile(file.Path);

            XDocument doc = XMLExtensions.TryLoadXml(file.Path);

            if (doc == null)
            {
                return;
            }

            var rootElement = doc.Root;

            switch (rootElement.Name.ToString().ToLowerInvariant())
            {
            case "item":
                new ItemPrefab(rootElement, file.Path, false)
                {
                    ContentPackage = file.ContentPackage
                };
                break;

            case "items":
                foreach (var element in rootElement.Elements())
                {
                    if (element.IsOverride())
                    {
                        var itemElement = element.GetChildElement("item");
                        if (itemElement != null)
                        {
                            new ItemPrefab(itemElement, file.Path, true)
                            {
                                ContentPackage = file.ContentPackage,
                                IsOverride     = true
                            };
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Cannot find an item element from the children of the override element defined in {file.Path}");
                        }
                    }
                    else
                    {
                        new ItemPrefab(element, file.Path, false)
                        {
                            ContentPackage = file.ContentPackage
                        };
                    }
                }
                break;

            case "override":
                var items = rootElement.GetChildElement("items");
                if (items != null)
                {
                    foreach (var element in items.Elements())
                    {
                        new ItemPrefab(element, file.Path, true)
                        {
                            ContentPackage = file.ContentPackage,
                            IsOverride     = true
                        };
                    }
                }
                foreach (var element in rootElement.GetChildElements("item"))
                {
                    new ItemPrefab(element, file.Path, true)
                    {
                        ContentPackage = file.ContentPackage
                    };
                }
                break;

            default:
                DebugConsole.ThrowError($"Invalid XML root element: '{rootElement.Name.ToString()}' in {file.Path}");
                break;
            }
        }