feat(runtime): share chat commands and run login sequence

This commit is contained in:
Erik 2026-08-14 20:27:45 +02:00
parent 5535d0adac
commit 41b15efd4d
57 changed files with 1739 additions and 345 deletions

View file

@ -32,11 +32,12 @@ public sealed class SessionStatusWriterTests
writer.EnteredWorld("s1", 0x50000001u, "Ready");
writer.PluginLoaded("s1", "acdream.good");
writer.PluginFailed("s1", "acdream.bad", "enable failed");
writer.LoginCommandFailed("s1", 2, "/version", "unsupported headless command");
writer.Disconnected("s1", "stopped");
writer.Exited("s1", 0, "disposed");
string[] lines = File.ReadAllLines(file.Path);
Assert.Equal(8, lines.Length);
Assert.Equal(9, lines.Length);
JsonElement started = Parse(lines[0]);
Assert.Equal(1, started.GetProperty("v").GetInt32());
@ -73,11 +74,25 @@ public sealed class SessionStatusWriterTests
Assert.Equal("acdream.bad", pluginFailed.GetProperty("plugin").GetString());
Assert.Equal("enable failed", pluginFailed.GetProperty("error").GetString());
JsonElement disconnected = Parse(lines[6]);
JsonElement loginCommandFailed = Parse(lines[6]);
Assert.Equal(1, loginCommandFailed.GetProperty("v").GetInt32());
Assert.Equal("loginCommandFailed", loginCommandFailed.GetProperty("e").GetString());
Assert.Equal("s1", loginCommandFailed.GetProperty("sessionId").GetString());
Assert.Equal(2, loginCommandFailed.GetProperty("commandIndex").GetInt32());
Assert.Equal("/version", loginCommandFailed.GetProperty("command").GetString());
Assert.Equal(
"unsupported headless command",
loginCommandFailed.GetProperty("error").GetString());
Assert.Equal(
["v", "e", "t", "sessionId", "commandIndex", "command", "error"],
loginCommandFailed.EnumerateObject()
.Select(static property => property.Name));
JsonElement disconnected = Parse(lines[7]);
Assert.Equal("disconnected", disconnected.GetProperty("e").GetString());
Assert.Equal("stopped", disconnected.GetProperty("reason").GetString());
JsonElement exited = Parse(lines[7]);
JsonElement exited = Parse(lines[8]);
Assert.Equal("exited", exited.GetProperty("e").GetString());
Assert.Equal(0, exited.GetProperty("code").GetInt32());
Assert.Equal("disposed", exited.GetProperty("reason").GetString());
@ -93,6 +108,7 @@ public sealed class SessionStatusWriterTests
writer.Connected("s1");
writer.PluginLoaded("s1", "acdream.good");
writer.PluginFailed("s1", "acdream.bad", "failed");
writer.LoginCommandFailed("s1", 0, "", "unknown command");
writer.Disconnected("s1", "stopped");
writer.Exited("s1", 0, "disposed");
@ -199,11 +215,12 @@ public sealed class SessionStatusWriterTests
writer.EnteredWorld("bot", 0x50000001u, "Ready");
writer.PluginLoaded("bot", "acdream.good");
writer.PluginFailed("bot", "acdream.bad", "enable failed");
writer.LoginCommandFailed("bot", 1, "/version", "unsupported");
writer.Disconnected("bot", "stopped");
writer.Exited("bot", 0, "disposed");
string[] lines = File.ReadAllLines(file.Path);
Assert.Equal(8, lines.Length);
Assert.Equal(9, lines.Length);
AssertExactProperties(lines[0], "v", "e", "t", "sessionId");
AssertExactProperties(lines[1], "v", "e", "t", "sessionId");
@ -215,8 +232,11 @@ public sealed class SessionStatusWriterTests
AssertExactProperties(lines[4], "v", "e", "t", "sessionId", "plugin");
AssertExactProperties(
lines[5], "v", "e", "t", "sessionId", "plugin", "error");
AssertExactProperties(lines[6], "v", "e", "t", "sessionId", "reason");
AssertExactProperties(lines[7], "v", "e", "t", "sessionId", "code", "reason");
AssertExactProperties(
lines[6],
"v", "e", "t", "sessionId", "commandIndex", "command", "error");
AssertExactProperties(lines[7], "v", "e", "t", "sessionId", "reason");
AssertExactProperties(lines[8], "v", "e", "t", "sessionId", "code", "reason");
// The nested characters[] entries are exact too — the exact shape a
// password could otherwise be smuggled through.