using System; using System.IO; namespace BSO.Net { /// /// Netzwerkprotokoll von Mod und Server - beide binden diese Dateien ein (Shared\*.cs), es gibt also nur eine /// Fassung. Aufbau wie bei MSCO: [int Laenge][byte Typ][Daten], Daten mit BinaryWriter, Positionen in cm (Engine). /// public static class Protocol { /// Bei jeder inkompatiblen Aenderung erhoehen - der Server lehnt andere Versionen ab. public const int Version = 1; public const int DefaultPort = 7777; } public enum MsgType : byte { Hello = 1, // Client -> Server: int Protokoll, string Mod-Version, string Name Welcome = 2, // Server -> Client: int eigene ID, string Servername, int n, je [int ID, string Name] Reject = 3, // Server -> Client: string Grund PlayerState = 4, // Client -> Server: PlayerState; Server -> Client: int ID + PlayerState PlayerJoined = 5, // Server -> Client: int ID, string Name PlayerLeft = 6, // Server -> Client: int ID Ping = 7, // long Zeitstempel (Stopwatch-Ticks des Senders) Pong = 8, // Antwort auf Ping mit demselben Zeitstempel (Laufzeit messen) Info = 9, // Abfrage ohne Hello (spaeter Server-Browser, jetzt --probe) InfoReply = 10 // string Servername, string Version, int Spieler, int max. Spieler } public enum PlayerMode : byte { Menu = 0, // noch keine Szene / Ladebildschirm OnFoot = 1, // Spielfigur (KeyControlledCharacter) InBus = 2 // sitzt im eigenen Bus (CarVehicle) } public struct Message { public MsgType Type; public byte[] Payload; public BinaryReader Reader() => new PacketReader(Payload); } /// Was jeder Spieler ~10x pro Sekunde von sich schickt. Drehung wie die Engine: Grad (Gier, Nick, Roll). public struct PlayerState { public PlayerMode Mode; public float X, Y, Z; public float Yaw, Pitch, Roll; public float Speed; // cm/s public void Write(BinaryWriter w) { w.Write((byte)Mode); w.Write(X); w.Write(Y); w.Write(Z); w.Write(Yaw); w.Write(Pitch); w.Write(Roll); w.Write(Speed); } public static PlayerState Read(BinaryReader r) => new PlayerState { Mode = (PlayerMode)r.ReadByte(), X = r.ReadSingle(), Y = r.ReadSingle(), Z = r.ReadSingle(), Yaw = r.ReadSingle(), Pitch = r.ReadSingle(), Roll = r.ReadSingle(), Speed = r.ReadSingle() }; public float DistanceTo(PlayerState o) { float dx = X - o.X, dy = Y - o.Y, dz = Z - o.Z; return MathF.Sqrt(dx * dx + dy * dy + dz * dz); } } public static class Wire { public static byte[] Build(Action write) { using var ms = new MemoryStream(); using var w = new BinaryWriter(ms); write(w); w.Flush(); return ms.ToArray(); } } }