fix(core): Updates to serialization (#590)
- [X] Adds `AdhocPersistence` which replaces RunUO `Persistence` - [X] Fixes a few minor bugs with EntityPersistence deserialization - [X] Reverts/updates some serialization changes
This commit is contained in:
parent
f0969223f7
commit
6e9477ea13
18 changed files with 370 additions and 248 deletions
|
|
@ -126,14 +126,12 @@ namespace Server
|
|||
continue;
|
||||
}
|
||||
|
||||
T t;
|
||||
ConstructorInfo ctor = objs.Item1;
|
||||
I indexer = indexInfo.CreateIndex(number);
|
||||
|
||||
ctorArgs[0] = indexer;
|
||||
t = ctor.Invoke(ctorArgs) as T;
|
||||
|
||||
if (t != null)
|
||||
if (ctor.Invoke(ctorArgs) is T t)
|
||||
{
|
||||
entities.Add(new EntityIndex<T>(t, typeID, pos, length));
|
||||
map[indexer] = t;
|
||||
|
|
@ -162,19 +160,18 @@ namespace Server
|
|||
}
|
||||
|
||||
using FileStream bin = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
BufferReader br = null;
|
||||
|
||||
foreach (var entry in entities)
|
||||
{
|
||||
T t = entry.Entity;
|
||||
|
||||
var position = bin.Position;
|
||||
var position = entry.Position;
|
||||
bin.Seek(position, SeekOrigin.Begin);
|
||||
|
||||
// Skip this entry
|
||||
if (t == null)
|
||||
{
|
||||
bin.Seek(entry.Length, SeekOrigin.Current);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +182,7 @@ namespace Server
|
|||
}
|
||||
else
|
||||
{
|
||||
br.SwapBuffers(buffer, out _);
|
||||
br.Reset(buffer, out _);
|
||||
}
|
||||
|
||||
bin.Read(buffer.AsSpan());
|
||||
|
|
@ -221,8 +218,6 @@ namespace Server
|
|||
}
|
||||
|
||||
t.Delete();
|
||||
// Skip this entry
|
||||
bin.Seek(position + entry.Length, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ namespace Server
|
|||
m_DiskWriteHandle.WaitOne();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void EnqueueForDecay(Item item)
|
||||
{
|
||||
if (WorldState != WorldState.Saving)
|
||||
|
|
@ -468,8 +469,6 @@ namespace Server
|
|||
|
||||
Broadcast(0x35, true, "The world is saving, please wait.");
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
logger.Information("Saving world");
|
||||
|
||||
var watch = Stopwatch.StartNew();
|
||||
|
|
@ -645,5 +644,85 @@ namespace Server
|
|||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void RemoveGuild(BaseGuild guild) => Guilds.Remove(guild.Serial);
|
||||
|
||||
private struct TypeOf<T> { }
|
||||
public static T ReadEntity<T>(this IGenericReader reader) where T : class, ISerializable
|
||||
{
|
||||
Serial serial = reader.ReadUInt();
|
||||
|
||||
return default(TypeOf<T>) switch
|
||||
{
|
||||
TypeOf<BaseGuild> => FindGuild(serial) as T,
|
||||
TypeOf<IEntity> => FindEntity<IEntity>(serial) as T,
|
||||
_ => default
|
||||
};
|
||||
}
|
||||
|
||||
public static List<T> ReadEntityList<T>(this IGenericReader reader) where T : class, ISerializable
|
||||
{
|
||||
var count = reader.ReadInt();
|
||||
|
||||
var list = new List<T>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var entity = reader.ReadEntity<T>();
|
||||
if (entity != null)
|
||||
{
|
||||
list.Add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static HashSet<T> ReadEntitySet<T>(this IGenericReader reader) where T : class, ISerializable
|
||||
{
|
||||
var count = reader.ReadInt();
|
||||
|
||||
var set = new HashSet<T>(count);
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
var entity = reader.ReadEntity<T>();
|
||||
if (entity != null)
|
||||
{
|
||||
set.Add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
public static void Write(this IGenericWriter writer, ISerializable value)
|
||||
{
|
||||
writer.Write(value?.Deleted != false ? Serial.MinusOne : value.Serial);
|
||||
}
|
||||
|
||||
public static void Write<T>(this IGenericWriter writer, ICollection<T> coll) where T : class, ISerializable
|
||||
{
|
||||
writer.Write(coll.Count);
|
||||
foreach (var entry in coll)
|
||||
{
|
||||
writer.Write(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write<T>(
|
||||
this IGenericWriter writer, ICollection<T> coll, Action<IGenericWriter, T> action
|
||||
) where T : class, ISerializable
|
||||
{
|
||||
if (coll == null)
|
||||
{
|
||||
writer.Write(0);
|
||||
return;
|
||||
}
|
||||
|
||||
writer.Write(coll.Count);
|
||||
foreach (var entry in coll)
|
||||
{
|
||||
action(writer, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue