fix: Adds Created, LastSerialized, and BeforeSerialize for all entities. (#775)

* Adds `BeforeSerialized` for entities to handle cleanup.
* Adds `Created` and `LastSerialized` fields to all entities. While this is a big bloat, this will be necessary for identifying dangling references to other invalid entities.
* Changes formula for determining a valid reference to be _not null, not deleted, and reference's created date must be at or before the entities last serialized date_.
* Adds versioning to idx file and serializes `Created` and `LastSerialized`.
* Fixes Save Stats and also disables it by default.
This commit is contained in:
Kamron Batman 2021-09-26 01:09:45 -07:00 • committed by GitHub
parent 3f6a87483b
commit fa5eafdaff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 325 additions and 88 deletions

View file

@ -47,6 +47,7 @@ namespace Server
private static string _tempSavePath; // Path to the temporary folder for the save
private static string _savePath; // Path to "Saves" folder
private static bool _enableSaveStats;
public const bool DirtyTrackingEnabled = false;
public const uint ItemOffset = 0x40000000;
@ -144,6 +145,7 @@ namespace Server
_tempSavePath = Path.Combine(Core.BaseDirectory, tempSavePath);
var savePath = ServerConfiguration.GetOrUpdateSetting("world.savePath", "Saves");
_savePath = Path.Combine(Core.BaseDirectory, savePath);
_enableSaveStats = ServerConfiguration.GetOrUpdateSetting("world.enableSaveStats", false);
// Mobiles & Items
Persistence.Register("Mobiles & Items", SaveEntities, WriteEntities, LoadEntities, 1);
@ -341,7 +343,10 @@ namespace Server
int count = 0;
var timestamp = Utility.GetTimeStamp();
using var op = new StreamWriter("Logs/Saves/Save-Stats-{0}.log", true);
var saveStatsPath = Path.Combine(Core.BaseDirectory, $"Logs/Saves/Save-Stats-{timestamp}.log");
AssemblyHandler.EnsureDirectory(saveStatsPath);
using var op = new StreamWriter(saveStatsPath, true);
for (var i = 0; i < entityTypes.Length; i++)
{
@ -373,7 +378,10 @@ namespace Server
EntityPersistence.WriteEntities(itemIndexInfo, Items, ItemTypes, basePath, out var itemCounts);
EntityPersistence.WriteEntities(guildIndexInfo, Guilds, GuildTypes, basePath, out var guildCounts);
TraceSave(mobileCounts?.ToList(), itemCounts?.ToList(), guildCounts?.ToList());
if (_enableSaveStats)
{
TraceSave(mobileCounts?.ToList(), itemCounts?.ToList(), guildCounts?.ToList());
}
}
public static void WriteFiles(object state)
@ -652,13 +660,24 @@ namespace Server
Serial serial = reader.ReadSerial();
var typeT = typeof(T);
T entity;
// Add to this list when creating new serializable types
if (typeof(BaseGuild).IsAssignableTo(typeT))
{
return FindGuild(serial) as T;
entity = FindGuild(serial) as T;
}
else
{
entity = FindEntity<IEntity>(serial) as T;
}
return FindEntity<IEntity>(serial) as T;
if (entity?.Deleted == false)
{
return entity;
}
return entity?.Created <= reader.LastSerialized ? entity : null;
}
public static List<T> ReadEntityList<T>(this IGenericReader reader) where T : class, ISerializable