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

namespace GsConfigTool.Services;

public static class ArkConfigGeneratorService
{
    private static string F(float val) =>
        val.ToString("0.000000", CultureInfo.InvariantCulture);

    public static (string gameIni, string gameUserSettings) Generate(ArkServerSettings s)
    {
        return (BuildGameIni(s), BuildGameUserSettings(s));
    }

    private static string BuildGameIni(ArkServerSettings s)
    {
        var sb = new StringBuilder();
        sb.AppendLine("[/script/shootergame.shootergamemode]");

        if (s.UnlockAllEngrams)
            sb.AppendLine("bAutoUnlockAllEngrams=True");

        foreach (var eng in s.EngramOverrides)
        {
            sb.Append("OverrideNamedEngramEntries=(EngramClassName=\"");
            sb.Append(eng.EngramClassName);
            sb.Append("\",EngramHidden=");
            sb.Append(eng.Hidden ? "True" : "False");
            if (eng.EngramPointsCost >= 0)
            {
                sb.Append(",EngramPointsCost=");
                sb.Append(eng.EngramPointsCost);
            }
            if (eng.EngramLevelRequirement >= 0)
            {
                sb.Append(",EngramLevelRequirement=");
                sb.Append(eng.EngramLevelRequirement);
            }
            if (eng.RemoveEngramPreReq)
                sb.Append(",RemoveEngramPreReq=True");
            sb.AppendLine(")");
        }

        foreach (var cr in s.CreatureMultipliers)
        {
            if (cr.Disabled) continue;
            sb.Append("DinoClassDamageMultipliers=(ClassName=\"");
            sb.Append(cr.DinoClassName);
            sb.Append("\",Multiplier=");
            sb.Append(F(cr.DinoDamageMultiplier));
            sb.AppendLine(")");

            sb.Append("DinoClassResistanceMultipliers=(ClassName=\"");
            sb.Append(cr.DinoClassName);
            sb.Append("\",Multiplier=");
            sb.Append(F(cr.DinoResistanceMultiplier));
            sb.AppendLine(")");

            sb.Append("TamedDinoClassDamageMultipliers=(ClassName=\"");
            sb.Append(cr.DinoClassName);
            sb.Append("\",Multiplier=");
            sb.Append(F(cr.TamingSpeedMultiplier));
            sb.AppendLine(")");
        }

        // ── PerLevelStats ────────────────────────────────────────────────
        if (s.UseCustomPerLevelStats)
        {
            var ps = s.PerLevelStats;
            for (int i = 0; i < 12; i++)
            {
                sb.AppendLine($"PerLevelStatsMultiplier_Player[{i}]={F(ps.Player[i])}");
                sb.AppendLine($"PerLevelStatsMultiplier_DinoWild[{i}]={F(ps.DinoWild[i])}");
                sb.AppendLine($"PerLevelStatsMultiplier_DinoTamed[{i}]={F(ps.DinoTamed[i])}");
                sb.AppendLine($"PerLevelStatsMultiplier_DinoTamed_Add[{i}]={F(ps.DinoTamedAdd[i])}");
                sb.AppendLine($"PerLevelStatsMultiplier_DinoTamed_Affinity[{i}]={F(ps.DinoTamedAffinity[i])}");
            }
        }

        // ── Harvest Multipliers ──────────────────────────────────────────
        foreach (var h in s.HarvestMultipliers)
        {
            sb.AppendLine($"HarvestResourceItemAmountClassMultipliers=(ClassName=\"{h.ClassName}\",Multiplier={F(h.Multiplier)})");
        }

        // ── Stack Size Overrides ─────────────────────────────────────────
        foreach (var st in s.StackSizeOverrides)
        {
            sb.AppendLine($"ConfigOverrideItemMaxQuantity=(ItemClassString=\"{st.ItemClassString}\",Quantity=(MaxItemQuantity={st.MaxItemQuantity},bIgnoreMultiplier={B(st.bIgnoreMultiplier)}))");
        }

        // ── Spawn Overrides ──────────────────────────────────────────────
        foreach (var spawn in s.SpawnOverrides)
        {
            sb.Append($"NPCSpawnEntriesContainerClassOverrides=(ContainerClassString=\"{spawn.NPCSpawnEntriesContainerClassString}\",bAddToExistingSet={B(spawn.bAddToExistingSet)},NPCSpawnEntries=(");
            for (int ei = 0; ei < spawn.Entries.Count; ei++)
            {
                var entry = spawn.Entries[ei];
                if (ei > 0) sb.Append(",");
                sb.Append($"(AnEntryName=\"{entry.AnEntryName}\",EntryWeight={F(entry.EntryWeight)},NPCsToSpawn=(");
                for (int ni = 0; ni < entry.NPCsToSpawn.Count; ni++)
                {
                    var npc = entry.NPCsToSpawn[ni];
                    if (ni > 0) sb.Append(",");
                    sb.Append($"\"{npc.NPCClass}\"");
                }
                sb.Append("),NPCsToSpawnPercentageChance=(");
                for (int ni = 0; ni < entry.NPCsToSpawn.Count; ni++)
                {
                    if (ni > 0) sb.Append(",");
                    sb.Append(F(entry.NPCsToSpawn[ni].SpawnPercentageChance));
                }
                sb.Append("))");
            }
            sb.AppendLine("),NPCSpawnLimits=())");
        }

        foreach (var drop in s.LootDropOverrides)
        {
            sb.Append("ConfigOverrideSupplyCrateItems=(SupplyCrateClassString=\"");
            sb.Append(drop.SupplyCrateClassString);
            sb.Append("\",MinQualityMultiplier=");
            sb.Append(F(drop.MinQualityMultiplier));
            sb.Append(",MaxQualityMultiplier=");
            sb.Append(F(drop.MaxQualityMultiplier));
            sb.Append(",bNoRepeats=");
            sb.Append(drop.bNoRepeats ? "True" : "False");
            sb.Append(",bSetsRandomWithoutReplacement=");
            sb.Append(drop.bSetsRandomWithoutReplacement ? "True" : "False");
            sb.Append(",bAppendItemSets=");
            sb.Append(drop.bAppendItemSets ? "True" : "False");
            sb.Append(",NumItemSetsPower=1.0,ItemSets=(");

            for (int si = 0; si < drop.ItemSets.Count; si++)
            {
                var set = drop.ItemSets[si];
                if (si > 0) sb.Append(",");
                sb.Append("(MinNumItems=");
                sb.Append(F(set.MinNumItems));
                sb.Append(",MaxNumItems=");
                sb.Append(F(set.MaxNumItems));
                sb.Append(",NumItemsPower=");
                sb.Append(F(set.NumItemsPower));
                sb.Append(",SetWeight=");
                sb.Append(F(set.SetWeight));
                sb.Append(",bItemsRandomWithoutReplacement=");
                sb.Append(set.bItemsRandomWithoutReplacement ? "True" : "False");
                sb.Append(",ItemEntries=(");

                for (int ii = 0; ii < set.Items.Count; ii++)
                {
                    var item = set.Items[ii];
                    if (ii > 0) sb.Append(",");
                    sb.Append("(ItemClassStrings=(\"");
                    sb.Append(item.ItemClassString);
                    sb.Append("\"),MinQuantity=");
                    sb.Append(F(item.MinQuantity));
                    sb.Append(",MaxQuantity=");
                    sb.Append(F(item.MaxQuantity));
                    sb.Append(",MinQuality=");
                    sb.Append(F(item.MinQuality));
                    sb.Append(",MaxQuality=");
                    sb.Append(F(item.MaxQuality));
                    sb.Append(",bForceBlueprint=");
                    sb.Append(item.bForceBlueprint ? "True" : "False");
                    sb.Append(",ItemWeight=");
                    sb.Append(F(item.ItemWeight));
                    sb.Append(",ChanceToBeBlueprint=");
                    sb.Append(F(item.ChanceToBeBlueprint));
                    sb.Append(")");
                }
                sb.Append("))");
            }
            sb.AppendLine(")");
        }

        return sb.ToString();
    }

    private static string BuildGameUserSettings(ArkServerSettings s)
    {
        var sb = new StringBuilder();
        sb.AppendLine("[ServerSettings]");
        sb.AppendLine($"ServerCrosshair={B(s.CrosshairEnabled)}");
        sb.AppendLine($"MapPlayerLocation={B(s.MapPlayerLocation)}");
        sb.AppendLine($"ServerHardcore={B(s.ServerHardcore)}");
        sb.AppendLine($"ServerPVE={B(s.PvE)}");
        sb.AppendLine($"PreventOfflinePvP={B(s.PreventOfflinePvP)}");
        sb.AppendLine($"PreventTribeAlliances={B(s.PreventTribeAlliances)}");
        sb.AppendLine($"AllowThirdPersonPlayer={B(s.AllowThirdPersonPlayer)}");
        sb.AppendLine($"KickIdlePlayersPeriod={F(s.KickIdlePlayersPeriod)}");
        sb.AppendLine($"DifficultyOffset={F(s.DifficultyOffset)}");
        sb.AppendLine($"OverrideOfficialDifficulty={F(s.OverrideOfficialDifficulty)}");
        sb.AppendLine($"XPMultiplier={F(s.XPMultiplier)}");
        sb.AppendLine($"TamingSpeedMultiplier={F(s.TamingSpeedMultiplier)}");
        sb.AppendLine($"HarvestAmountMultiplier={F(s.HarvestAmountMultiplier)}");
        sb.AppendLine($"HarvestHealthMultiplier={F(s.HarvestHealthMultiplier)}");
        sb.AppendLine($"ResourcesRespawnPeriodMultiplier={F(s.ResourcesRespawnPeriodMultiplier)}");
        sb.AppendLine($"DayCycleSpeedScale={F(s.DayCycleSpeedScale)}");
        sb.AppendLine($"DayTimeSpeedScale={F(s.DayTimeSpeedScale)}");
        sb.AppendLine($"NightTimeSpeedScale={F(s.NightTimeSpeedScale)}");
        sb.AppendLine($"MatingIntervalMultiplier={F(s.MatingIntervalMultiplier)}");
        sb.AppendLine($"MatingSpeedMultiplier={F(s.MatingSpeedMultiplier)}");
        sb.AppendLine($"EggHatchSpeedMultiplier={F(s.EggHatchSpeedMultiplier)}");
        sb.AppendLine($"BabyMatureSpeedMultiplier={F(s.BabyMatureSpeedMultiplier)}");
        sb.AppendLine($"BabyFoodConsumptionSpeedMultiplier={F(s.BabyFoodConsumptionSpeedMultiplier)}");
        sb.AppendLine($"BabyCuddleIntervalMultiplier={F(s.BabyCuddleIntervalMultiplier)}");
        sb.AppendLine($"BabyImprintAmountMultiplier={F(s.BabyImprintAmountMultiplier)}");
        sb.AppendLine($"BabyImprintingStatScaleMultiplier={F(s.BabyImprintingStatScaleMultiplier)}");
        sb.AppendLine($"LayEggIntervalMultiplier={F(s.LayEggIntervalMultiplier)}");
        sb.AppendLine($"PlayerDamageMultiplier={F(s.PlayerDamageMultiplier)}");
        sb.AppendLine($"PlayerResistanceMultiplier={F(s.PlayerResistanceMultiplier)}");
        sb.AppendLine($"PlayerWaterDrainMultiplier={F(s.PlayerWaterDrainMultiplier)}");
        sb.AppendLine($"PlayerFoodDrainMultiplier={F(s.PlayerFoodDrainMultiplier)}");
        sb.AppendLine($"PlayerStaminaDrainMultiplier={F(s.PlayerStaminaDrainMultiplier)}");
        sb.AppendLine($"PlayerHealthRecoveryMultiplier={F(s.PlayerHealthRecoveryMultiplier)}");
        sb.AppendLine($"PlayerHarvestingDamageMultiplier={F(s.PlayerHarvestingDamageMultiplier)}");
        sb.AppendLine($"PlayerTurretDamageMultiplier={F(s.PlayerTurretDamageMultiplier)}");
        sb.AppendLine($"DinoDamageMultiplier={F(s.DinoDamageMultiplier)}");
        sb.AppendLine($"DinoResistanceMultiplier={F(s.DinoResistanceMultiplier)}");
        sb.AppendLine($"TamedDinoDamageMultiplier={F(s.TamedDinoDamageMultiplier)}");
        sb.AppendLine($"TamedDinoResistanceMultiplier={F(s.TamedDinoResistanceMultiplier)}");
        sb.AppendLine($"DinoHarvestingDamageMultiplier={F(s.DinoHarvestingDamageMultiplier)}");
        sb.AppendLine($"DinoTurretDamageMultiplier={F(s.DinoTurretDamageMultiplier)}");
        sb.AppendLine($"MaxTamedDinos={s.MaxTamedDinos}");
        sb.AppendLine($"MaxPersonalTamedDinos={s.MaxPersonalTamedDinos}");
        sb.AppendLine($"DisableStructureDecayPvE={B(s.DisableStructureDecayPvE)}");
        sb.AppendLine($"StructureResistanceMultiplier={F(s.StructureResistanceMultiplier)}");
        sb.AppendLine($"StructureDamageRepairCooldown={F(s.StructureDamageRepairCooldown)}");
        sb.AppendLine($"PerPlatformMaxStructuresMultiplier={F(s.PerPlatformMaxStructuresMultiplier)}");
        sb.AppendLine($"bAllowFlyerCarryPvE={B(s.AllowFlyerCarryPvE)}");
        sb.AppendLine($"MaxNumberOfPlayersInTribe={s.MaxNumberOfPlayersInTribe}");
        sb.AppendLine($"MaxAlliancesPerTribe={s.MaxAlliancesPerTribe}");
        sb.AppendLine($"MaxTribesPerAlliance={s.MaxTribesPerAlliance}");
        sb.AppendLine($"GlobalSpoilingTimeMultiplier={F(s.GlobalSpoilingTimeMultiplier)}");
        sb.AppendLine($"GlobalItemDecompositionTimeMultiplier={F(s.GlobalItemDecompositionTimeMultiplier)}");
        sb.AppendLine($"GlobalCorpseDecompositionTimeMultiplier={F(s.GlobalCorpseDecompositionTimeMultiplier)}");
        sb.AppendLine($"CropGrowthSpeedMultiplier={F(s.CropGrowthSpeedMultiplier)}");
        sb.AppendLine($"FuelConsumptionIntervalMultiplier={F(s.FuelConsumptionIntervalMultiplier)}");
        sb.AppendLine($"CustomRecipeEffectivenessMultiplier={F(s.CustomRecipeEffectivenessMultiplier)}");
        sb.AppendLine($"CustomRecipeSkillMultiplier={F(s.CustomRecipeSkillMultiplier)}");
        sb.AppendLine($"PassiveTameFoodConsumptionMultiplier={F(s.PassiveTameFoodConsumptionMultiplier)}");
        if (s.OverrideMaxExperiencePointsPlayer > 0)
            sb.AppendLine($"OverrideMaxExperiencePointsPlayer={s.OverrideMaxExperiencePointsPlayer}");
        if (s.OverrideMaxExperiencePointsDino > 0)
            sb.AppendLine($"OverrideMaxExperiencePointsDino={s.OverrideMaxExperiencePointsDino}");

        sb.AppendLine();
        sb.AppendLine("[SessionSettings]");
        sb.AppendLine($"SessionName={s.ServerName}");
        sb.AppendLine($"MaxPlayers={s.MaxPlayers}");
        if (!string.IsNullOrWhiteSpace(s.ServerPassword))
            sb.AppendLine($"ServerPassword={s.ServerPassword}");
        sb.AppendLine($"ServerAdminPassword={s.AdminPassword}");
        sb.AppendLine($"QueryPort={s.QueryPort}");

        sb.AppendLine();
        sb.AppendLine("[/Script/Engine.GameSession]");
        sb.AppendLine($"MaxPlayers={s.MaxPlayers}");

        if (!string.IsNullOrWhiteSpace(s.ActiveMods))
        {
            sb.AppendLine();
            sb.AppendLine("[ModInstaller]");
            sb.AppendLine($"ModIDs={s.ActiveMods}");
        }

        // ── Cluster Settings ─────────────────────────────────────────────
        var c = s.Cluster;
        if (!string.IsNullOrWhiteSpace(c.ClusterID))
        {
            sb.AppendLine();
            sb.AppendLine("[ServerSettings]");
            sb.AppendLine($"ClusterID={c.ClusterID}");
            if (!string.IsNullOrWhiteSpace(c.ClusterPassword))
                sb.AppendLine($"ClusterPassword={c.ClusterPassword}");
            sb.AppendLine($"PreventDownloadSurvivors={B(c.PreventDownloadSurvivors)}");
            sb.AppendLine($"PreventDownloadItems={B(c.PreventDownloadItems)}");
            sb.AppendLine($"PreventDownloadDinos={B(c.PreventDownloadDinos)}");
            sb.AppendLine($"PreventUploadSurvivors={B(c.PreventUploadSurvivors)}");
            sb.AppendLine($"PreventUploadItems={B(c.PreventUploadItems)}");
            sb.AppendLine($"PreventUploadDinos={B(c.PreventUploadDinos)}");
            sb.AppendLine($"NoTributeDownloads={B(c.NoTributeDownloads)}");
            sb.AppendLine($"TributeItemExpirationSeconds={c.TributeItemExpirationSeconds}");
            sb.AppendLine($"TributeDinoExpirationSeconds={c.TributeDinoExpirationSeconds}");
            sb.AppendLine($"TributeCharacterExpirationSeconds={c.TributeCharacterExpirationSeconds}");
            sb.AppendLine($"bAllowUnlimitedRespecs={B(c.bAllowUnlimitedRespecs)}");
            sb.AppendLine($"MaxTribeLogs={c.MaxTribeLogs}");
        }

        // ── RCON ─────────────────────────────────────────────────────────
        if (s.RCON.RCONEnabled)
        {
            sb.AppendLine();
            sb.AppendLine("[RCONEnabled]");
            sb.AppendLine($"RCONEnabled={B(s.RCON.RCONEnabled)}");
            sb.AppendLine($"RCONPort={s.RCON.RCONPort}");
            sb.AppendLine($"RCONServerGameLogBuffer={s.RCON.RCONServerGameLogBuffer}");
        }

        return sb.ToString();
    }

    private static string B(bool val) => val ? "True" : "False";
}
24Fire Wuppertaler Tafel Romeo