Repositories / GSConfigTool / GsConfigTool / Services / ConfigImportService.cs
ConfigImportService.cs 12.6 KB
git clone https://rl-dev.de/git/gsconfigtool Raw Download
using GsConfigTool.Models;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;

namespace GsConfigTool.Services;

public static class ConfigImportService
{
    public static ArkServerSettings ImportArk(string gusContent, string gameIniContent)
    {
        var s = new ArkServerSettings();
        var gus = ParseIni(gusContent);
        var game = ParseIni(gameIniContent);

        // Session
        s.ServerName = gus.Get("SessionSettings", "SessionName", s.ServerName);
        s.ServerPassword = gus.Get("SessionSettings", "ServerPassword", s.ServerPassword);
        s.AdminPassword = gus.Get("SessionSettings", "ServerAdminPassword", s.AdminPassword);
        s.MaxPlayers = gus.GetInt("SessionSettings", "MaxPlayers", s.MaxPlayers);
        s.QueryPort = gus.GetInt("SessionSettings", "QueryPort", s.QueryPort);

        // ServerSettings
        s.PvE = gus.GetBool("ServerSettings", "ServerPVE", s.PvE);
        s.ServerHardcore = gus.GetBool("ServerSettings", "ServerHardcore", s.ServerHardcore);
        s.CrosshairEnabled = gus.GetBool("ServerSettings", "ServerCrosshair", s.CrosshairEnabled);
        s.MapPlayerLocation = gus.GetBool("ServerSettings", "MapPlayerLocation", s.MapPlayerLocation);
        s.PreventOfflinePvP = gus.GetBool("ServerSettings", "PreventOfflinePvP", s.PreventOfflinePvP);
        s.PreventTribeAlliances = gus.GetBool("ServerSettings", "PreventTribeAlliances", s.PreventTribeAlliances);
        s.AllowThirdPersonPlayer = gus.GetBool("ServerSettings", "AllowThirdPersonPlayer", s.AllowThirdPersonPlayer);
        s.DifficultyOffset = gus.GetFloat("ServerSettings", "DifficultyOffset", s.DifficultyOffset);
        s.OverrideOfficialDifficulty = gus.GetFloat("ServerSettings", "OverrideOfficialDifficulty", s.OverrideOfficialDifficulty);
        s.XPMultiplier = gus.GetFloat("ServerSettings", "XPMultiplier", s.XPMultiplier);
        s.TamingSpeedMultiplier = gus.GetFloat("ServerSettings", "TamingSpeedMultiplier", s.TamingSpeedMultiplier);
        s.HarvestAmountMultiplier = gus.GetFloat("ServerSettings", "HarvestAmountMultiplier", s.HarvestAmountMultiplier);
        s.HarvestHealthMultiplier = gus.GetFloat("ServerSettings", "HarvestHealthMultiplier", s.HarvestHealthMultiplier);
        s.ResourcesRespawnPeriodMultiplier = gus.GetFloat("ServerSettings", "ResourcesRespawnPeriodMultiplier", s.ResourcesRespawnPeriodMultiplier);
        s.MatingIntervalMultiplier = gus.GetFloat("ServerSettings", "MatingIntervalMultiplier", s.MatingIntervalMultiplier);
        s.EggHatchSpeedMultiplier = gus.GetFloat("ServerSettings", "EggHatchSpeedMultiplier", s.EggHatchSpeedMultiplier);
        s.BabyMatureSpeedMultiplier = gus.GetFloat("ServerSettings", "BabyMatureSpeedMultiplier", s.BabyMatureSpeedMultiplier);
        s.BabyFoodConsumptionSpeedMultiplier = gus.GetFloat("ServerSettings", "BabyFoodConsumptionSpeedMultiplier", s.BabyFoodConsumptionSpeedMultiplier);
        s.DayCycleSpeedScale = gus.GetFloat("ServerSettings", "DayCycleSpeedScale", s.DayCycleSpeedScale);
        s.DayTimeSpeedScale = gus.GetFloat("ServerSettings", "DayTimeSpeedScale", s.DayTimeSpeedScale);
        s.NightTimeSpeedScale = gus.GetFloat("ServerSettings", "NightTimeSpeedScale", s.NightTimeSpeedScale);
        s.PlayerDamageMultiplier = gus.GetFloat("ServerSettings", "PlayerDamageMultiplier", s.PlayerDamageMultiplier);
        s.PlayerResistanceMultiplier = gus.GetFloat("ServerSettings", "PlayerResistanceMultiplier", s.PlayerResistanceMultiplier);
        s.PlayerWaterDrainMultiplier = gus.GetFloat("ServerSettings", "PlayerWaterDrainMultiplier", s.PlayerWaterDrainMultiplier);
        s.PlayerFoodDrainMultiplier = gus.GetFloat("ServerSettings", "PlayerFoodDrainMultiplier", s.PlayerFoodDrainMultiplier);
        s.PlayerStaminaDrainMultiplier = gus.GetFloat("ServerSettings", "PlayerStaminaDrainMultiplier", s.PlayerStaminaDrainMultiplier);
        s.PlayerHealthRecoveryMultiplier = gus.GetFloat("ServerSettings", "PlayerHealthRecoveryMultiplier", s.PlayerHealthRecoveryMultiplier);
        s.DinoDamageMultiplier = gus.GetFloat("ServerSettings", "DinoDamageMultiplier", s.DinoDamageMultiplier);
        s.DinoResistanceMultiplier = gus.GetFloat("ServerSettings", "DinoResistanceMultiplier", s.DinoResistanceMultiplier);
        s.TamedDinoDamageMultiplier = gus.GetFloat("ServerSettings", "TamedDinoDamageMultiplier", s.TamedDinoDamageMultiplier);
        s.TamedDinoResistanceMultiplier = gus.GetFloat("ServerSettings", "TamedDinoResistanceMultiplier", s.TamedDinoResistanceMultiplier);
        s.MaxTamedDinos = gus.GetInt("ServerSettings", "MaxTamedDinos", s.MaxTamedDinos);
        s.GlobalSpoilingTimeMultiplier = gus.GetFloat("ServerSettings", "GlobalSpoilingTimeMultiplier", s.GlobalSpoilingTimeMultiplier);
        s.GlobalItemDecompositionTimeMultiplier = gus.GetFloat("ServerSettings", "GlobalItemDecompositionTimeMultiplier", s.GlobalItemDecompositionTimeMultiplier);
        s.DisableStructureDecayPvE = gus.GetBool("ServerSettings", "DisableStructureDecayPvE", s.DisableStructureDecayPvE);
        s.MaxNumberOfPlayersInTribe = gus.GetInt("ServerSettings", "MaxNumberOfPlayersInTribe", s.MaxNumberOfPlayersInTribe);

        // Mods
        s.ActiveMods = gus.Get("ModInstaller", "ModIDs", s.ActiveMods);

        // PerLevelStats from Game.ini
        var ps = s.PerLevelStats;
        bool hasPerLevel = false;
        for (int i = 0; i < 12; i++)
        {
            var pKey = $"PerLevelStatsMultiplier_Player[{i}]";
            var dKey = $"PerLevelStatsMultiplier_DinoWild[{i}]";
            var dtKey = $"PerLevelStatsMultiplier_DinoTamed[{i}]";
            if (game.GetRaw("/script/shootergame.shootergamemode", pKey) is string pVal)
            {
                ps.Player[i] = ParseFloat(pVal); hasPerLevel = true;
            }
            if (game.GetRaw("/script/shootergame.shootergamemode", dKey) is string dVal)
                ps.DinoWild[i] = ParseFloat(dVal);
            if (game.GetRaw("/script/shootergame.shootergamemode", dtKey) is string dtVal)
                ps.DinoTamed[i] = ParseFloat(dtVal);
        }
        s.UseCustomPerLevelStats = hasPerLevel;

        return s;
    }

    public static PalworldServerSettings ImportPalworld(string iniContent)
    {
        var s = new PalworldServerSettings();
        var rawLine = iniContent.Split('\n')
            .Select(l => l.Trim())
            .FirstOrDefault(l => l.StartsWith("OptionSettings=("));
        if (rawLine == null) return s;

        var inner = rawLine.Substring("OptionSettings=(".Length).TrimEnd(')');
        foreach (var pair in SplitTopLevel(inner))
        {
            var eq = pair.IndexOf('=');
            if (eq < 0) continue;
            var key = pair[..eq].Trim();
            var val = pair[(eq + 1)..].Trim().Trim('"');

            switch (key)
            {
                case "Difficulty": s.Difficulty = val; break;
                case "DayTimeSpeedRate": s.DayTimeSpeedRate = ParseFloat(val); break;
                case "NightTimeSpeedRate": s.NightTimeSpeedRate = ParseFloat(val); break;
                case "ExpRate": s.ExpRate = ParseFloat(val); break;
                case "PalCaptureRate": s.PalCaptureRate = ParseFloat(val); break;
                case "PalSpawnNumRate": s.PalSpawnNumRate = ParseFloat(val); break;
                case "PalDamageRateAttack": s.PalDamageRateAttack = ParseFloat(val); break;
                case "PalDamageRateDefense": s.PalDamageRateDefense = ParseFloat(val); break;
                case "PlayerDamageRateAttack": s.PlayerDamageRateAttack = ParseFloat(val); break;
                case "PlayerDamageRateDefense": s.PlayerDamageRateDefense = ParseFloat(val); break;
                case "EnemyDropItemRate": s.EnemyDropItemRate = ParseFloat(val); break;
                case "DeathPenalty": s.DeathPenalty = val; break;
                case "bIsPvP": s.bIsPvP = val == "True"; break;
                case "bEnablePlayerToPlayerDamage": s.bEnablePlayerToPlayerDamage = val == "True"; break;
                case "bEnableFriendlyFire": s.bEnableFriendlyFire = val == "True"; break;
                case "ServerName": s.ServerName = val; break;
                case "ServerDescription": s.ServerDescription = val; break;
                case "AdminPassword": s.AdminPassword = val; break;
                case "ServerPassword": s.ServerPassword = val; break;
                case "PublicPort": s.PublicPort = ParseInt(val); break;
                case "PublicIP": s.PublicIP = val; break;
                case "ServerPlayerMaxNum": s.ServerPlayerMaxNum = ParseInt(val); break;
                case "RCONEnabled": s.RCONEnabled = val == "True"; break;
                case "RCONPort": s.RCONPort = ParseInt(val); break;
                case "CollectionDropRate": s.CollectionDropRate = ParseFloat(val); break;
                case "CollectionObjectHpRate": s.CollectionObjectHpRate = ParseFloat(val); break;
                case "CollectionObjectRespawnSpeedRate": s.CollectionObjectRespawnSpeedRate = ParseFloat(val); break;
                case "BuildObjectDamageRate": s.BuildObjectDamageRate = ParseFloat(val); break;
                case "BuildObjectDeteriorationDamageRate": s.BuildObjectDeteriorationDamageRate = ParseFloat(val); break;
                case "BaseCampMaxNum": s.BaseCampMaxNum = ParseInt(val); break;
                case "BaseCampWorkerMaxNum": s.BaseCampWorkerMaxNum = ParseInt(val); break;
                case "DropItemMaxNum": s.DropItemMaxNum = ParseInt(val); break;
                case "bEnableFastTravel": s.bEnableFastTravel = val == "True"; break;
                case "bIsStartLocationSelectByMap": s.bIsStartLocationSelectByMap = val == "True"; break;
                case "bEnableNonLoginPenalty": s.bEnableNonLoginPenalty = val == "True"; break;
                case "bEnableInvaderEnemy": s.bEnableInvaderEnemy = val == "True"; break;
                case "bUseAuth": s.bUseAuth = val == "True"; break;
                case "BanListURL": s.BanListURL = val; break;
            }
        }
        return s;
    }

    private static IEnumerable<string> SplitTopLevel(string s)
    {
        int depth = 0;
        int start = 0;
        for (int i = 0; i < s.Length; i++)
        {
            if (s[i] == '(') depth++;
            else if (s[i] == ')') depth--;
            else if (s[i] == ',' && depth == 0)
            {
                yield return s[start..i];
                start = i + 1;
            }
        }
        if (start < s.Length) yield return s[start..];
    }

    private static float ParseFloat(string v) =>
        float.TryParse(v, NumberStyles.Float, CultureInfo.InvariantCulture, out var r) ? r : 0f;

    private static int ParseInt(string v) =>
        int.TryParse(v, out var r) ? r : 0;

    private static IniData ParseIni(string content)
    {
        var data = new IniData();
        string currentSection = "";
        foreach (var rawLine in content.Split('\n'))
        {
            var line = rawLine.Trim();
            if (string.IsNullOrEmpty(line) || line.StartsWith(';') || line.StartsWith('#')) continue;
            if (line.StartsWith('[') && line.EndsWith(']'))
            {
                currentSection = line[1..^1].ToLowerInvariant();
                continue;
            }
            var eq = line.IndexOf('=');
            if (eq < 0) continue;
            var key = line[..eq].Trim();
            var val = line[(eq + 1)..].Trim();
            data.Set(currentSection, key, val);
        }
        return data;
    }

    private class IniData
    {
        private readonly Dictionary<string, Dictionary<string, string>> _data = new();

        public void Set(string section, string key, string value)
        {
            var s = section.ToLowerInvariant();
            if (!_data.ContainsKey(s)) _data[s] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
            _data[s][key] = value;
        }

        public string? GetRaw(string section, string key)
        {
            var s = section.ToLowerInvariant();
            return _data.TryGetValue(s, out var dict) && dict.TryGetValue(key, out var v) ? v : null;
        }

        public string Get(string section, string key, string def = "")
            => GetRaw(section, key) ?? def;

        public float GetFloat(string section, string key, float def = 0f)
            => float.TryParse(GetRaw(section, key), NumberStyles.Float, CultureInfo.InvariantCulture, out var r) ? r : def;

        public int GetInt(string section, string key, int def = 0)
            => int.TryParse(GetRaw(section, key), out var r) ? r : def;

        public bool GetBool(string section, string key, bool def = false)
        {
            var v = GetRaw(section, key);
            if (v == null) return def;
            return v.Equals("True", StringComparison.OrdinalIgnoreCase) || v == "1";
        }
    }
}
24Fire Wuppertaler Tafel Romeo