Validate stored vehicle/object poses, show positions in 'vehicles', admin: Satsuma to me

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 23:25:26 +02:00
co-authored by Claude Opus 5.5
parent 741082f237
commit 1cfe139949
2 changed files with 24 additions and 6 deletions
+1 -1
View File
@@ -133,7 +133,7 @@ Fehlende Einstellungen ergänzt der Server beim Start automatisch. Umgebungsvari
| `stop` | speichern und beenden |
Im Spiel öffnen Admins mit `/admin` (Chat, Taste T) oder `admin` (F8-Konsole) das Admin-Menü: Kick/Ban,
GOTO/BRING (zu einem Spieler / Spieler zu sich teleportieren) und Cheats (Geld, Bedürfnisse auffüllen).
GOTO/BRING (zu einem Spieler / Spieler zu sich teleportieren) und Cheats (Geld, Bedürfnisse auffüllen, Satsuma zu sich holen).
Cheats werden allen im Chat angezeigt, Teleports stehen im Server-Log.
Der Chat landet auch im Server-Log.
+23 -5
View File
@@ -79,14 +79,32 @@ public sealed class WorldState
void ReadPose(BinaryReader r)
{
int id = r.ReadInt32();
var p = new float[3];
var q = new float[4];
for (int k = 0; k < 3; k++) p[k] = r.ReadSingle();
for (int k = 0; k < 4; k++) q[k] = r.ReadSingle();
r.ReadSingle(); r.ReadSingle(); r.ReadSingle(); // Geschwindigkeit wird nicht gespeichert
// Unsinnige Werte (Fehler, manipulierter Client) nicht speichern - sonst landet z.B. das Auto
// beim nächsten Beitreten im Boden oder außerhalb der Karte
if (!IsValidPose(p, q)) return;
if (!Objects.TryGetValue(id, out var pose))
{
pose = new ObjectPose(); // bei voller Liste nur mitlesen, nicht speichern
if (Objects.Count < MaxObjects) Objects[id] = pose;
if (Objects.Count >= MaxObjects) return;
Objects[id] = pose = new ObjectPose();
}
for (int k = 0; k < 3; k++) pose.P[k] = r.ReadSingle();
for (int k = 0; k < 4; k++) pose.R[k] = r.ReadSingle();
r.ReadSingle(); r.ReadSingle(); r.ReadSingle(); // Geschwindigkeit wird nicht gespeichert
pose.P = p;
pose.R = q;
}
/// <summary>Position innerhalb der Karte, Drehung ein gültiges Quaternion.</summary>
public static bool IsValidPose(float[] p, float[] q)
{
foreach (float f in p) if (!float.IsFinite(f)) return false;
foreach (float f in q) if (!float.IsFinite(f)) return false;
if (Math.Abs(p[0]) > 6000 || Math.Abs(p[2]) > 6000 || p[1] < -200 || p[1] > 3000) return false;
float len = MathF.Sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
return len > 0.9f && len < 1.1f;
}
public void ApplyMoney(byte[] payload)