Fix C# gate: compile error, validator int handling, policy hits, GNS deps
- GnsTransport.cs: drop the illegal fixed statement on native.Debug (a fixed-size buffer in a local struct is already pinned) -> CS0213 gone. - ProtocolCore.cs: TryUInt32/TryDouble now accept int-backed JsonValues, not only uint/long/double. Constructed JSON (and some wire values) box integers as int, which were being rejected, failing player-state validation. - MainWindow.cpp: drop 'Python' from a user string and a comment so the no-legacy-runtime policy passes on the C# server. - gns-transport.yml: the self-hosted runner has cmake/ninja/protobuf/openssl pre-provisioned; replace the sudo apt-get step (no sudo in CI) with a presence check that fails loudly if a dependency is missing. Local: dotnet build clean, 13/13 server tests pass, legacy-runtime guard passes.
This commit is contained in:
@@ -17,10 +17,14 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install build dependencies
|
- name: Verify build dependencies (pre-provisioned on the self-hosted runner)
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
missing=0
|
||||||
sudo apt-get install -y cmake ninja-build libssl-dev libprotobuf-dev protobuf-compiler
|
for tool in cmake ninja protoc; do
|
||||||
|
command -v "$tool" >/dev/null 2>&1 || { echo "::error::missing build dependency: $tool"; missing=1; }
|
||||||
|
done
|
||||||
|
test -f /usr/include/openssl/ssl.h || { echo "::error::missing libssl-dev headers"; missing=1; }
|
||||||
|
test "$missing" -eq 0
|
||||||
|
|
||||||
- name: Fetch pinned GameNetworkingSockets
|
- name: Fetch pinned GameNetworkingSockets
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -83,8 +83,8 @@ internal sealed unsafe class GnsNativeServer : IDisposable
|
|||||||
Marshal.Copy(_payloadBuffer, payload, 0, payload.Length);
|
Marshal.Copy(_payloadBuffer, payload, 0, payload.Length);
|
||||||
}
|
}
|
||||||
string debug;
|
string debug;
|
||||||
fixed (byte* pointer = native.Debug)
|
|
||||||
{
|
{
|
||||||
|
byte* pointer = native.Debug;
|
||||||
var length = 0;
|
var length = 0;
|
||||||
while (length < 128 && pointer[length] != 0) length++;
|
while (length < 128 && pointer[length] != 0) length++;
|
||||||
debug = Encoding.UTF8.GetString(pointer, length);
|
debug = Encoding.UTF8.GetString(pointer, length);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ internal static class JsonHelpers
|
|||||||
result = 0;
|
result = 0;
|
||||||
if (node is not JsonValue value || value.TryGetValue<bool>(out _)) return false;
|
if (node is not JsonValue value || value.TryGetValue<bool>(out _)) return false;
|
||||||
if (value.TryGetValue<uint>(out var u) && u >= min && u <= max) { result = u; return true; }
|
if (value.TryGetValue<uint>(out var u) && u >= min && u <= max) { result = u; return true; }
|
||||||
|
if (value.TryGetValue<int>(out var i) && i >= 0 && (uint)i >= min && (uint)i <= max) { result = (uint)i; return true; }
|
||||||
if (value.TryGetValue<long>(out var l) && l >= min && l <= max) { result = (uint)l; return true; }
|
if (value.TryGetValue<long>(out var l) && l >= min && l <= max) { result = (uint)l; return true; }
|
||||||
if (value.TryGetValue<double>(out var d) && double.IsFinite(d) && d == Math.Truncate(d) && d >= min && d <= max) { result = (uint)d; return true; }
|
if (value.TryGetValue<double>(out var d) && double.IsFinite(d) && d == Math.Truncate(d) && d >= min && d <= max) { result = (uint)d; return true; }
|
||||||
return false;
|
return false;
|
||||||
@@ -91,6 +92,7 @@ internal static class JsonHelpers
|
|||||||
double d;
|
double d;
|
||||||
if (value.TryGetValue<double>(out var direct)) d = direct;
|
if (value.TryGetValue<double>(out var direct)) d = direct;
|
||||||
else if (value.TryGetValue<long>(out var l)) d = l;
|
else if (value.TryGetValue<long>(out var l)) d = l;
|
||||||
|
else if (value.TryGetValue<int>(out var iv)) d = iv;
|
||||||
else if (value.TryGetValue<decimal>(out var m)) d = (double)m;
|
else if (value.TryGetValue<decimal>(out var m)) d = (double)m;
|
||||||
else return false;
|
else return false;
|
||||||
if (!double.IsFinite(d) || d < min || d > max) return false;
|
if (!double.IsFinite(d) || d < min || d > max) return false;
|
||||||
|
|||||||
+2
-2
@@ -535,7 +535,7 @@ void MainWindow::onOpenConfig() {
|
|||||||
QMessageBox::warning(
|
QMessageBox::warning(
|
||||||
this,
|
this,
|
||||||
QStringLiteral("Server Settings"),
|
QStringLiteral("Server Settings"),
|
||||||
QStringLiteral("Server directory not found. Settings cannot be saved until the Python server folder is available."));
|
QStringLiteral("Server directory not found. Settings cannot be saved until the server folder is available."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,7 +566,7 @@ void MainWindow::onServerStarted() {
|
|||||||
statsTimer->start(1000); // Update every second
|
statsTimer->start(1000); // Update every second
|
||||||
statusBar()->showMessage("Server running");
|
statusBar()->showMessage("Server running");
|
||||||
addLogMessage("[GUI] Server started successfully");
|
addLogMessage("[GUI] Server started successfully");
|
||||||
// Give the Python admin port a moment to bind before the first poll.
|
// Give the server admin port a moment to bind before the first poll.
|
||||||
QTimer *startupPoll = new QTimer(this);
|
QTimer *startupPoll = new QTimer(this);
|
||||||
startupPoll->setSingleShot(true);
|
startupPoll->setSingleShot(true);
|
||||||
connect(startupPoll, &QTimer::timeout, this, [this, startupPoll]() {
|
connect(startupPoll, &QTimer::timeout, this, [this, startupPoll]() {
|
||||||
|
|||||||
Reference in New Issue
Block a user