Skip to content

Commit

Permalink
fix: Fixes infinite loop in BinaryFileWriter (#1792)
Browse files Browse the repository at this point in the history
### 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
  • Loading branch information
kamronbatman authored May 24, 2024
1 parent 0011db7 commit 9f1f314
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 25 deletions.
31 changes: 30 additions & 1 deletion Projects/Server/Serialization/BinaryFileWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,32 @@ public override void Flush()
_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()
Expand All @@ -61,7 +87,10 @@ public override void Close()

public override long Seek(long offset, SeekOrigin origin)
{
Flush();
if (Index > 0)
{
Flush();
}

return _position = _file.Seek(offset, origin);
}
Expand Down
6 changes: 5 additions & 1 deletion Projects/Server/Serialization/BufferWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ private void FlushIfNeeded(int amount)
}
}

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;

Expand Down
2 changes: 1 addition & 1 deletion Projects/Server/Serialization/GenericEntityPersistence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public override void Serialize()
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)
Expand Down
2 changes: 2 additions & 0 deletions Projects/Server/Serialization/IGenericWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ void Write(Rectangle3D value)
}
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
{
Expand Down
11 changes: 1 addition & 10 deletions Projects/Server/World/EntityPersistence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ public static void WriteEntities<I, T>(
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);
Expand Down Expand Up @@ -61,12 +58,6 @@ out Dictionary<string, int> counts
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;
}
}
}

Expand Down
23 changes: 11 additions & 12 deletions Projects/UOContent/Mobiles/Vendors/GenericBuy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,30 +257,29 @@ public override void Deserialize(IGenericReader reader)

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(() =>
{
foreach (var entity in entities)
{
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();
}
}
}
}
Expand Down

0 comments on commit 9f1f314

Please sign in to comment.