first commit

This commit is contained in:
2025-07-06 00:23:46 +02:00
commit 38f50c8819
1788 changed files with 112878 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
#nullable enable
using System;
using Newtonsoft.Json.Linq;
namespace NitroxServer.Serialization.SaveDataUpgrades
{
public static class NewtonsoftExtensions
{
public static void Rename(this JToken token, string newName)
{
if (token == null)
{
throw new ArgumentNullException("token", "Cannot rename a null token");
}
JProperty property;
if (token.Type == JTokenType.Property)
{
if (token.Parent == null)
{
throw new InvalidOperationException("Cannot rename a property with no parent");
}
property = (JProperty)token;
}
else
{
if (token.Parent == null || token.Parent.Type != JTokenType.Property)
{
throw new InvalidOperationException("This token's parent is not a JProperty; cannot rename");
}
property = (JProperty)token.Parent;
}
// Note: to avoid triggering a clone of the existing property's value,
// we need to save a reference to it and then null out property.Value
// before adding the value to the new JProperty.
// Thanks to @dbc for the suggestion.
JToken? existingValue = property.Value;
property.Value = null!;
JProperty? newProperty = new JProperty(newName, existingValue);
property.Replace(newProperty);
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using NitroxServer.Serialization.Json;
namespace NitroxServer.Serialization.Upgrade
{
public abstract class SaveDataUpgrade
{
private readonly JsonConverter[] converters = { new NitroxIdConverter(), new TechTypeConverter(), new VersionConverter(), new KeyValuePairConverter(), new StringEnumConverter() };
public abstract Version TargetVersion { get; }
public static readonly Version MinimumSaveVersion = new(1, 8, 0, 0);
public void UpgradeSaveFiles(string saveDir, string fileEnding)
{
Log.Info($"┌── Executing {GetType().Name}");
string baseDataPath = Path.Combine(saveDir, $"BaseData{fileEnding}");
string playerDataPath = Path.Combine(saveDir, $"PlayerData{fileEnding}");
string worldDataPath = Path.Combine(saveDir, $"WorldData{fileEnding}");
string entityDataPath = Path.Combine(saveDir, $"EntityData{fileEnding}");
Log.Info("├── Parsing raw json");
JObject baseData = JObject.Parse(File.ReadAllText(baseDataPath));
JObject playerData = JObject.Parse(File.ReadAllText(playerDataPath));
JObject worldData = JObject.Parse(File.ReadAllText(worldDataPath));
JObject entityData = JObject.Parse(File.ReadAllText(entityDataPath));
Log.Info("├── Applying upgrade scripts");
UpgradeBaseData(baseData);
UpgradePlayerData(playerData);
UpgradeWorldData(worldData);
UpgradeEntityData(entityData);
Log.Info("└── Saving to disk");
File.WriteAllText(baseDataPath, baseData.ToString(Formatting.None, converters));
File.WriteAllText(playerDataPath, playerData.ToString(Formatting.None, converters));
File.WriteAllText(worldDataPath, worldData.ToString(Formatting.None, converters));
File.WriteAllText(entityDataPath, entityData.ToString(Formatting.None, converters));
}
protected virtual void UpgradeBaseData(JObject data) { }
protected virtual void UpgradePlayerData(JObject data) { }
protected virtual void UpgradeWorldData(JObject data) { }
protected virtual void UpgradeEntityData(JObject data) { }
}
}

View File

@@ -0,0 +1,22 @@
using System;
using Newtonsoft.Json.Linq;
using NitroxServer.Serialization.Upgrade;
namespace NitroxServer.Serialization.SaveDataUpgrades
{
public sealed class Upgrade_V1500 : SaveDataUpgrade
{
public override Version TargetVersion { get; } = new Version(1, 5, 0, 0);
protected override void UpgradeWorldData(JObject data)
{
data["GameData"]["StoryTiming"] = data["StoryTimingData"];
data.Property("StoryTimingData")?.Remove();
data["Seed"] = "TCCBIBZXAB"; //Default seed so life pod should stay the same
data["InventoryData"]["Modules"] = new JArray();
Log.Warn("Plants will still be counted as normal items with no growth progression. Re adding them to a container should fix this.");
Log.Warn("The precursor incubator may be unpowered and hatching progress will be reset");
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;
using NitroxServer.Serialization.Upgrade;
namespace NitroxServer.Serialization.SaveDataUpgrades
{
public class Upgrade_V1600 : SaveDataUpgrade
{
public override Version TargetVersion { get; } = new Version(1, 6, 0, 0);
protected override void UpgradeWorldData(JObject data)
{
List<string> cleanUnlockedTechTypes = data["GameData"]["PDAState"]["UnlockedTechTypes"].ToObject<List<string>>().Distinct().ToList();
List<string> cleanKnownTechTypes = data["GameData"]["PDAState"]["KnownTechTypes"].ToObject<List<string>>().Distinct().ToList();
List<string> cleanEncyclopediaEntries = data["GameData"]["PDAState"]["EncyclopediaEntries"].ToObject<List<string>>().Distinct().ToList();
data["GameData"]["PDAState"]["UnlockedTechTypes"] = new JArray(cleanUnlockedTechTypes);
data["GameData"]["PDAState"]["KnownTechTypes"] = new JArray(cleanKnownTechTypes);
data["GameData"]["PDAState"]["EncyclopediaEntries"] = new JArray(cleanEncyclopediaEntries);
List<JToken> cleanPdaLog = new List<JToken>();
List<JToken> pdaLog = data["GameData"]["PDAState"]["PdaLog"].ToObject<List<JToken>>();
foreach (JToken pdaLogEntry in pdaLog)
{
string Key = pdaLogEntry["Key"].ToString();
if (cleanPdaLog.All(entry => entry["Key"].ToString() != Key))
{
cleanPdaLog.Add(pdaLogEntry);
}
}
data["GameData"]["PDAState"]["PdaLog"] = new JArray(cleanPdaLog);
data.Property("ServerStartTime")?.Remove();
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using NitroxModel.DataStructures;
using NitroxServer.Serialization.Upgrade;
namespace NitroxServer.Serialization.SaveDataUpgrades
{
public class Upgrade_V1601 : SaveDataUpgrade
{
public override Version TargetVersion { get; } = new Version(1, 6, 0, 1);
protected override void UpgradeWorldData(JObject data)
{
List<string> modules = new();
foreach (JToken moduleEntry in data["InventoryData"]["Modules"])
{
JToken itemId = moduleEntry["ItemId"];
if (modules.Contains(itemId.ToString()))
{
itemId = new NitroxId().ToString();
// this line is enough to modify the original data
moduleEntry["ItemId"] = itemId;
}
modules.Add(itemId.ToString());
}
}
}
}