fix: Fixes infinite loop in BinaryFileWriter (#1792)
### Summary - Fixes infinite loop with binary file writer - Removes extra buffer copying with binary file writer - Removes storing type counts during world save file writing - Fixes display cache self-deletion warning during world load
This commit is contained in:
parent
0011db7f47
commit
9f1f314077
6 changed files with 50 additions and 25 deletions
|
|
@ -47,6 +47,32 @@ public class BinaryFileWriter : BufferWriter, IDisposable
|
|||
_file.Write(Buffer, 0, (int)Index);
|
||||
Index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Flush(); // Increase buffer size
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(byte[] bytes) => Write(bytes, 0, bytes.Length);
|
||||
|
||||
public override void Write(byte[] bytes, int offset, int count)
|
||||
{
|
||||
if (Index > 0)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
_file.Write(bytes, offset, count);
|
||||
}
|
||||
|
||||
public override void Write(ReadOnlySpan<byte> bytes)
|
||||
{
|
||||
if (Index > 0)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
_file.Write(bytes);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
|
|
@ -61,7 +87,10 @@ public class BinaryFileWriter : BufferWriter, IDisposable
|
|||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
Flush();
|
||||
if (Index > 0)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
return _position = _file.Seek(offset, origin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,11 @@ public class BufferWriter : IGenericWriter
|
|||
}
|
||||
}
|
||||
|
||||
public void Write(ReadOnlySpan<byte> bytes)
|
||||
public virtual void Write(byte[] bytes) => Write(bytes.AsSpan());
|
||||
|
||||
public virtual void Write(byte[] bytes, int offset, int count) => Write(bytes.AsSpan(offset, count));
|
||||
|
||||
public virtual void Write(ReadOnlySpan<byte> bytes)
|
||||
{
|
||||
var length = bytes.Length;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public class GenericEntityPersistence<T> : Persistence, IGenericEntityPersistenc
|
|||
public override void WriteSnapshot(string basePath)
|
||||
{
|
||||
IIndexInfo<Serial> indexInfo = new EntityTypeIndex(_name);
|
||||
EntityPersistence.WriteEntities(indexInfo, EntitiesBySerial, basePath,World.SerializedTypes, out _);
|
||||
EntityPersistence.WriteEntities(indexInfo, EntitiesBySerial, basePath,World.SerializedTypes);
|
||||
}
|
||||
|
||||
public virtual void DeserializeIndexes(string savePath, Dictionary<ulong, string> typesDb)
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ public interface IGenericWriter
|
|||
}
|
||||
void Write(Map value) => Write((byte)(value?.MapIndex ?? 0xFF));
|
||||
void Write(Race value) => Write((byte)(value?.RaceIndex ?? 0xFF));
|
||||
void Write(byte[] bytes);
|
||||
void Write(byte[] bytes, int offset, int count);
|
||||
void Write(ReadOnlySpan<byte> bytes);
|
||||
unsafe void WriteEnum<T>(T value) where T : unmanaged, Enum
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,12 +28,9 @@ public static class EntityPersistence
|
|||
IIndexInfo<I> indexInfo,
|
||||
Dictionary<I, T> entities,
|
||||
string savePath,
|
||||
ConcurrentQueue<Type> types,
|
||||
out Dictionary<string, int> counts
|
||||
ConcurrentQueue<Type> types
|
||||
) where T : class, ISerializable
|
||||
{
|
||||
counts = new Dictionary<string, int>();
|
||||
|
||||
var typeName = indexInfo.TypeName;
|
||||
|
||||
var path = Path.Combine(savePath, typeName);
|
||||
|
|
@ -61,12 +58,6 @@ public static class EntityPersistence
|
|||
e.SerializeTo(bin);
|
||||
|
||||
idx.Write((int)(bin.Position - start));
|
||||
|
||||
var type = e.GetType().FullName;
|
||||
if (type != null)
|
||||
{
|
||||
counts[type] = (counts.TryGetValue(type, out var count) ? count : 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -257,10 +257,11 @@ namespace Server.Mobiles
|
|||
|
||||
var version = reader.ReadInt();
|
||||
|
||||
List<IEntity> entities = new (Items);
|
||||
List<IEntity> entities = [..Items];
|
||||
entities.AddRange(reader.ReadEntityList<Mobile>());
|
||||
|
||||
m_Mobiles = new List<Mobile>(); // This cannot be null in case it is referenced before disposing
|
||||
m_Table = new Dictionary<Type, IEntity>();
|
||||
|
||||
Timer.StartTimer(() =>
|
||||
{
|
||||
|
|
@ -268,19 +269,17 @@ namespace Server.Mobiles
|
|||
{
|
||||
entity.Delete();
|
||||
}
|
||||
|
||||
if (m_Cache == null)
|
||||
{
|
||||
m_Cache = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
m_Table = new Dictionary<Type, IEntity>();
|
||||
|
||||
if (m_Cache == null)
|
||||
{
|
||||
m_Cache = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue