Enhance school management and protocol handling by introducing a new worker failure mechanism, ensuring proper cleanup of schools when a worker thread encounters an error. Update the map snapshot protocol to allow larger school data sizes, improving the handling of extensive map layouts. Revise documentation to reflect changes in save intervals and introduce a minimum save interval for better performance. Update tests to validate the new functionalities and ensure robustness in handling large data scenarios.
ci / server (push) Failing after 3m29s
ci / client (push) Successful in 16s

This commit is contained in:
Leonid Pershin
2026-08-18 17:02:28 +03:00
parent 6ca9ff9d03
commit f000b128f6
14 changed files with 325 additions and 74 deletions
+37
View File
@@ -1,3 +1,5 @@
using System.Text;
namespace HSchool.Protocol;
/// <summary>
@@ -99,6 +101,38 @@ public static class ProtocolCodec
return writer.Position;
}
/// <summary>
/// Bytes <see cref="WriteMapSnapshot"/> needs for this message.
///
/// A school's map has no fixed size — the create editor lets a player add rooms — so a
/// snapshot can outgrow <see cref="ProtocolConstants.MaxMessageSize"/>. That limit guards
/// what the server *reads*; callers size an outbound snapshot from the message itself.
/// </summary>
public static int MapSnapshotSize(ServerMapSnapshotMessage message)
{
var size = sizeof(byte) + sizeof(int) + sizeof(ushort);
foreach (var node in message.Nodes)
{
size += sizeof(byte);
size += StringSize(node.Id) + StringSize(node.ParentId) + StringSize(node.Name);
size += sizeof(byte);
foreach (var item in node.Items)
{
size += StringSize(item);
}
size += sizeof(byte);
foreach (var position in node.Positions)
{
size += StringSize(position);
}
}
return size;
}
public static int WriteMapSnapshot(Span<byte> destination, ServerMapSnapshotMessage message)
{
if (message.Nodes.Count > ushort.MaxValue)
@@ -249,6 +283,9 @@ public static class ProtocolCodec
return new ServerMapSnapshotMessage(schoolId, nodes);
}
/// <summary>Matches <see cref="PacketWriter.WriteString"/>: a <c>u16</c> length plus UTF-8.</summary>
private static int StringSize(string value) => sizeof(ushort) + Encoding.UTF8.GetByteCount(value);
private static void Expect(ref PacketReader reader, MessageType expected)
{
var actual = reader.ReadMessageType();