using System; using System.Collections.Generic; using Sandbox.ModAPI; using VRage; using VRage.Game.ModAPI; using VRage.Utils; using VRageMath; namespace SENetworkAPI { public class Server : NetworkAPI { /// /// Server class contains a few server only feature beond what is inharited from the NetworkAPI /// /// Identifies the channel to pass information to and from this mod /// identifies what chat entries should be captured and sent to the server public Server(ushort comId, string modName, string keyword = null) : base(comId, modName, keyword) { } /// /// Sends a command packet to the client(s) /// /// The command to be executed /// Text that will be displayed in client chat /// A serialized object to be sent across the network /// The date timestamp this command was sent /// The client reciving this packet (if 0 it sends to all clients) /// Enture delivery of the packet public override void SendCommand(string commandString, string message = null, byte[] data = null, DateTime? sent = null, ulong steamId = ulong.MinValue, bool isReliable = true) { SendCommand( new Command { SteamId = steamId, CommandString = commandString, Message = message, Data = data, Timestamp = sent == null ? DateTime.UtcNow.Ticks : sent.Value.Ticks }, steamId, isReliable); } /// /// /// Sends a command packet to the client(s) /// the center of the sync location /// the distance the message reaches (defaults to sync distance) /// Text that will be displayed in client chat /// A serialized object to be sent across the network /// The date timestamp this command was sent /// The client reciving this packet (if 0 it sends to all clients) /// Enture delivery of the packet public override void SendCommand(string commandString, Vector3D point, double radius = 0, string message = null, byte[] data = null, DateTime? sent = null, ulong steamId = ulong.MinValue, bool isReliable = true) { SendCommand( new Command { SteamId = steamId, CommandString = commandString, Message = message, Data = data, Timestamp = sent == null ? DateTime.UtcNow.Ticks : sent.Value.Ticks }, point, radius, steamId, isReliable); } /// /// Sends a command packet to a list of clients /// /// /// The command to be executed /// Text that will be displayed in client chat /// A serialized object to be sent across the network /// The date timestamp this command was sent /// Enture delivery of the packet public void SendCommandTo(ulong[] steamIds, string commandString, string message = null, byte[] data = null, DateTime? sent = null, bool isReliable = true) { foreach (var id in steamIds) SendCommand( new Command { SteamId = id, CommandString = commandString, Message = message, Data = data, Timestamp = sent == null ? DateTime.UtcNow.Ticks : sent.Value.Ticks }, id, isReliable); } /// /// Sends a command packet to the client(s) /// /// The object to be sent to the client /// The players steam id /// Make sure the data arrives internal override void SendCommand(Command cmd, ulong steamId = ulong.MinValue, bool isReliable = true) { if (cmd.Data != null && cmd.Data.Length > CompressionThreshold) { cmd.Data = MyCompression.Compress(cmd.Data); cmd.IsCompressed = true; } if (!string.IsNullOrWhiteSpace(cmd.Message) && MyAPIGateway.Multiplayer.IsServer && MyAPIGateway.Session != null) MyAPIGateway.Utilities.ShowMessage(ModName, cmd.Message); var packet = MyAPIGateway.Utilities.SerializeToBinary(cmd); if (LogNetworkTraffic) MyLog.Default.Info( $"[NetworkAPI] TRANSMITTING Bytes: {packet.Length} Command: {cmd.CommandString} User: {steamId}"); if (steamId == ulong.MinValue) MyAPIGateway.Multiplayer.SendMessageToOthers(ComId, packet, isReliable); else MyAPIGateway.Multiplayer.SendMessageTo(ComId, packet, steamId, isReliable); } /// /// Sends a command packet to the client(s) /// /// The object to be sent to the client /// the center of the sync location /// the distance the message reaches (defaults to sync distance) /// The players steam id /// Make sure the data arrives internal override void SendCommand(Command cmd, Vector3D point, double radius = 0, ulong steamId = ulong.MinValue, bool isReliable = true) { if (cmd.Data != null && cmd.Data.Length > CompressionThreshold) { cmd.Data = MyCompression.Compress(cmd.Data); cmd.IsCompressed = true; } if (radius == 0) radius = MyAPIGateway.Session.SessionSettings.SyncDistance; var players = new List(); if (steamId == ulong.MinValue) MyAPIGateway.Players.GetPlayers(players, p => (p.GetPosition() - point).LengthSquared() < radius * radius && p.SteamUserId != cmd.SteamId); else MyAPIGateway.Players.GetPlayers(players, p => p.SteamUserId == steamId); if (!string.IsNullOrWhiteSpace(cmd.Message) && MyAPIGateway.Multiplayer.IsServer && MyAPIGateway.Session != null) MyAPIGateway.Utilities.ShowMessage(ModName, cmd.Message); cmd.Timestamp = DateTime.UtcNow.Ticks; var packet = MyAPIGateway.Utilities.SerializeToBinary(cmd); if (LogNetworkTraffic) MyLog.Default.Info( $"[NetworkAPI] _TRANSMITTING_ Bytes: {packet.Length} Command: {cmd.CommandString} To: {players.Count} Users within {radius}m"); foreach (var player in players) MyAPIGateway.Multiplayer.SendMessageTo(ComId, packet, player.SteamUserId, isReliable); } public override void Say(string message) { SendCommand(null, message); } } }