diff --git a/SS14.Server/emotes.xml b/Resources/emotes.xml similarity index 100% rename from SS14.Server/emotes.xml rename to Resources/emotes.xml diff --git a/SS14.Client/BaseClient.cs b/SS14.Client/BaseClient.cs index be8cd85d1..74354bcaf 100644 --- a/SS14.Client/BaseClient.cs +++ b/SS14.Client/BaseClient.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using Lidgren.Network; +using SS14.Client.Console; using SS14.Client.Interfaces; using SS14.Client.Interfaces.Player; using SS14.Client.Interfaces.State; @@ -24,7 +25,7 @@ namespace SS14.Client [Dependency] private readonly IPlayerManager _playMan; - + /// public ushort DefaultPort { get; } = 1212; diff --git a/SS14.Client/Console/ClientChatConsole.cs b/SS14.Client/Console/ClientChatConsole.cs new file mode 100644 index 000000000..9f911dbe8 --- /dev/null +++ b/SS14.Client/Console/ClientChatConsole.cs @@ -0,0 +1,150 @@ +using System.Collections.Generic; +using OpenTK.Graphics; +using SS14.Client.Interfaces.GameObjects; +using SS14.Client.Interfaces.Player; +using SS14.Client.UserInterface.CustomControls; +using SS14.Shared.Console; +using SS14.Shared.GameObjects; +using SS14.Shared.IoC; +using SS14.Shared.Maths; +using SS14.Shared.Network.Messages; + +namespace SS14.Client.Console +{ + /// + /// Expands the console to support chat, channels, and emotes. + /// + public class ClientChatConsole : ClientConsole, IClientChatConsole + { + private const char ConCmdSlash = '/'; + private const char OocAlias = '['; + private const char MeAlias = '@'; + + private readonly Dictionary _chatColors; + + [Dependency] + private readonly IClientEntityManager _entityManager; + + [Dependency] + private readonly IPlayerManager _players; + + /// + /// Default Constructor. + /// + public ClientChatConsole() + { + _chatColors = new Dictionary + { + [ChatChannel.Default] = Color4.Gray, + [ChatChannel.Damage] = Color4.Red, + [ChatChannel.Radio] = new Color4(0, 100, 0, 255), + [ChatChannel.Server] = Color4.Blue, + [ChatChannel.Player] = new Color4(0, 128, 0, 255), + [ChatChannel.Local] = new Color4(0, 200, 0, 255), + [ChatChannel.OOC] = Color4.White, + [ChatChannel.Emote] = Color4.Cyan, + [ChatChannel.Visual] = Color4.Yellow, + }; + } + + /// + /// Initializes the console into a useable state. + /// + public override void Initialize() + { + base.Initialize(); + + _network.RegisterNetMessage(MsgChat.NAME, (int) MsgChat.ID, msg => HandleChatMsg((MsgChat) msg)); + } + + /// + public void ParseChatMessage(Chatbox chatBox, string text) + { + ParseChatMessage(text, chatBox.DefaultChatFormat); + } + + /// + public void ParseChatMessage(string text, string defaultFormat = null) + { + if (string.IsNullOrWhiteSpace(text)) + return; + + switch (text[0]) + { + case ConCmdSlash: + { + // run locally + var conInput = text.Substring(1); + ProcessCommand(conInput); + break; + } + case OocAlias: + { + var conInput = text.Substring(2); + ProcessCommand($"ooc \"{conInput}\""); + break; + } + case MeAlias: + { + var conInput = text.Substring(2); + ProcessCommand($"me \"{conInput}\""); + break; + } + default: + { + var conInput = defaultFormat != null ? string.Format(defaultFormat, text) : text; + ProcessCommand(conInput); + break; + } + } + } + + private void HandleChatMsg(MsgChat msg) + { + var channel = msg.Channel; + var text = msg.Text; + var index = msg.Index; + var entityId = msg.EntityId; + + switch (channel) + { + case ChatChannel.Local: + case ChatChannel.Server: + case ChatChannel.OOC: + case ChatChannel.Radio: + { + string name; + if (index.HasValue && _players.SessionsDict.TryGetValue(index.Value, out var session)) + { + name = session.Name; + } + else if (entityId.HasValue) + { + var ent = _entityManager.GetEntity(entityId.Value); + name = ent.Name ?? ent.ToString(); + } + else + { + name = ""; + } + + text = $"[{channel}] {name}: {text}"; + break; + } + } + + AddLine(text, channel, GetChannelColor(channel)); + + if (entityId.HasValue && _entityManager.TryGetEntity(entityId.Value, out var a)) + a.SendMessage(this, ComponentMessageType.EntitySaidSomething, channel, text); + } + + private Color GetChannelColor(ChatChannel channel) + { + if (_chatColors.TryGetValue(channel, out var color)) + return color; + + return Color.White; + } + } +} diff --git a/SS14.Client/Console/ClientConsole.cs b/SS14.Client/Console/ClientConsole.cs new file mode 100644 index 000000000..aee1a554a --- /dev/null +++ b/SS14.Client/Console/ClientConsole.cs @@ -0,0 +1,225 @@ +using System; +using System.Collections.Generic; +using Lidgren.Network; +using OpenTK.Graphics; +using SS14.Client.Interfaces.Console; +using SS14.Shared.Console; +using SS14.Shared.Interfaces.Network; +using SS14.Shared.Interfaces.Reflection; +using SS14.Shared.IoC; +using SS14.Shared.Log; +using SS14.Shared.Network; +using SS14.Shared.Network.Messages; +using SS14.Shared.Reflection; +using SS14.Shared.Utility; + +namespace SS14.Client.Console +{ + public class AddStringArgs : EventArgs + { + public string Text { get; } + public Color4 Color { get; } + public ChatChannel Channel { get; } + + public AddStringArgs(string text, Color4 color, ChatChannel channel) + { + Text = text; + Color = color; + Channel = channel; + } + } + + public class ClientConsole : IClientConsole, IDebugConsole + { + private static readonly Color4 MsgColor = new Color4(65, 105, 225, 255); + + [Dependency] + protected readonly IClientNetManager _network; + + private readonly Dictionary _commands = new Dictionary(); + private bool _requestedCommands; + + /// + public virtual void Initialize() + { + _network.RegisterNetMessage(MsgConCmdReg.NAME, (int)MsgConCmdReg.ID, HandleConCmdReg); + _network.RegisterNetMessage(MsgConCmdAck.NAME, (int)MsgConCmdAck.ID, HandleConCmdAck); + _network.RegisterNetMessage(MsgConCmd.NAME, (int)MsgConCmd.ID); + + Reset(); + } + + /// + public virtual void Reset() + { + _commands.Clear(); + _requestedCommands = false; + _network.Connected += OnNetworkConnected; + + InitializeCommands(); + SendServerCommandRequest(); + } + + private void OnNetworkConnected(object sender, NetChannelArgs netChannelArgs) + { + SendServerCommandRequest(); + } + + /// + public void Dispose() { } + + public IReadOnlyDictionary Commands => _commands; + + public void AddLine(string text, ChatChannel channel, Color4 color) + { + AddString?.Invoke(this, new AddStringArgs(text, color, channel)); + } + + public void Clear() + { + ClearText?.Invoke(this, EventArgs.Empty); + } + + public event EventHandler AddString; + public event EventHandler ClearText; + + private void HandleConCmdAck(NetMessage message) + { + var msg = (MsgConCmdAck) message; + + AddLine("< " + msg.Text, ChatChannel.Default, MsgColor); + } + + private void HandleConCmdReg(NetMessage message) + { + var msg = (MsgConCmdReg) message; + + foreach (var cmd in msg.Commands) + { + var commandName = cmd.Name; + + // Do not do duplicate commands. + if (_commands.ContainsKey(commandName)) + { + Logger.Warning($"Server sent console command {commandName}, but we already have one with the same name. Ignoring."); + continue; + } + + var command = new ServerDummyCommand(commandName, cmd.Help, cmd.Description); + _commands[commandName] = command; + } + } + + /// + /// Processes commands (chat messages starting with /) + /// + /// input text + public void ProcessCommand(string text) + { + if(string.IsNullOrWhiteSpace(text)) + return; + + // echo the command locally + AddLine("> " + text, ChatChannel.Default, new Color4(255, 250, 240, 255)); + + //Commands are processed locally and then sent to the server to be processed there again. + var args = new List(); + + CommandParsing.ParseArguments(text, args); + + var commandname = args[0]; + + var forward = true; + if (_commands.ContainsKey(commandname)) + { + var command = _commands[commandname]; + args.RemoveAt(0); + forward = command.Execute(this, args.ToArray()); + } + else if (!IoCManager.Resolve().IsConnected) + { + AddLine("Unknown command: " + commandname, ChatChannel.Default, Color4.Red); + return; + } + + if (forward) + SendServerConsoleCommand(text); + } + + /// + /// Locates and registeres all local commands. + /// + private void InitializeCommands() + { + var manager = IoCManager.Resolve(); + foreach (var t in manager.GetAllChildren()) + { + var instance = (IConsoleCommand) Activator.CreateInstance(t, null); + if (_commands.ContainsKey(instance.Command)) + throw new Exception($"Command already registered: {instance.Command}"); + + _commands[instance.Command] = instance; + } + } + + /// + /// Requests remote commands from server. + /// + public void SendServerCommandRequest() + { + if (_requestedCommands) + return; + + var netMgr = IoCManager.Resolve(); + if (!netMgr.IsConnected) + return; + + var msg = netMgr.CreateNetMessage(); + // empty message to request commands + netMgr.ClientSendMessage(msg, NetDeliveryMethod.ReliableUnordered); + + _requestedCommands = true; + } + + /// + /// Sends a command directly to the server. + /// + private void SendServerConsoleCommand(string text) + { + var netMgr = IoCManager.Resolve(); + + if (netMgr == null || !netMgr.IsConnected) + return; + + var msg = netMgr.CreateNetMessage(); + msg.Text = text; + netMgr.ClientSendMessage(msg, NetDeliveryMethod.ReliableUnordered); + } + } + + /// + /// These dummies are made purely so list and help can list server-side commands. + /// + [Reflect(false)] + internal class ServerDummyCommand : IConsoleCommand + { + internal ServerDummyCommand(string command, string help, string description) + { + Command = command; + Help = help; + Description = description; + } + + public string Command { get; } + + public string Help { get; } + + public string Description { get; } + + // Always forward to server. + public bool Execute(IDebugConsole console, params string[] args) + { + return true; + } + } +} diff --git a/SS14.Client/Console/ConsoleCommands.cs b/SS14.Client/Console/Commands/ConsoleCommands.cs similarity index 85% rename from SS14.Client/Console/ConsoleCommands.cs rename to SS14.Client/Console/Commands/ConsoleCommands.cs index bcb161663..f50464616 100644 --- a/SS14.Client/Console/ConsoleCommands.cs +++ b/SS14.Client/Console/Commands/ConsoleCommands.cs @@ -2,13 +2,13 @@ // Not some generic console command type. // Couldn't think of a better name sorry. +using System; using OpenTK.Graphics; using SS14.Client.Interfaces.Console; -using SS14.Client.Interfaces.UserInterface; -using SS14.Shared.IoC; -using System; +using SS14.Shared; +using SS14.Shared.Console; -namespace SS14.Client.Console +namespace SS14.Client.Console.Commands { class ClearCommand : IConsoleCommand { @@ -35,7 +35,7 @@ namespace SS14.Client.Console Random random = new Random(); for (int x = 0; x < 50; x++) { - console.AddLine("filling...", colors[random.Next(0, colors.Length)]); + console.AddLine("filling...", ChatChannel.Default, colors[random.Next(0, colors.Length)]); } return false; } diff --git a/SS14.Client/Console/Debug.cs b/SS14.Client/Console/Commands/Debug.cs similarity index 88% rename from SS14.Client/Console/Debug.cs rename to SS14.Client/Console/Commands/Debug.cs index f26b4a353..780ee3a16 100644 --- a/SS14.Client/Console/Debug.cs +++ b/SS14.Client/Console/Commands/Debug.cs @@ -1,22 +1,24 @@ -using OpenTK.Graphics; -using SS14.Client.GameObjects; -using SS14.Client.Graphics.Render; -using SS14.Client.Interfaces.Console; -using SS14.Client.Interfaces.GameObjects; -using SS14.Shared.Interfaces.GameObjects; -using SS14.Shared.IoC; -using SS14.Shared.GameObjects; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using OpenTK.Graphics; +using SS14.Client.GameObjects; using SS14.Client.Graphics; +using SS14.Client.Graphics.Render; +using SS14.Client.Interfaces.Console; +using SS14.Client.Interfaces.GameObjects; using SS14.Client.Interfaces.State; using SS14.Client.State.States; +using SS14.Shared; +using SS14.Shared.Console; using SS14.Shared.ContentPack; +using SS14.Shared.GameObjects; +using SS14.Shared.Interfaces.GameObjects; +using SS14.Shared.IoC; -namespace SS14.Client.Console +namespace SS14.Client.Console.Commands { class DumpEntitiesCommand : IConsoleCommand { @@ -30,7 +32,7 @@ namespace SS14.Client.Console foreach (IEntity e in entitymanager.GetEntities(new ComponentEntityQuery())) { - console.AddLine($"entity {e.Uid}, {e.Prototype.Name}.", Color4.White); + console.AddLine($"entity {e.Uid}, {e.Prototype.Name}.", ChatChannel.Default, Color4.White); } return false; @@ -53,7 +55,7 @@ namespace SS14.Client.Console foreach (var component in components) { - console.AddLine($"{component.Owner.Uid}: {component.GetType()}", Color4.White); + console.AddLine($"{component.Owner.Uid}: {component.GetType()}", ChatChannel.Default, Color4.White); } return false; } @@ -69,7 +71,7 @@ namespace SS14.Client.Console { if (args.Length < 1) { - console.AddLine($"Not enough arguments.", Color4.Red); + console.AddLine($"Not enough arguments.", ChatChannel.Default, Color4.Red); return false; } var componentFactory = IoCManager.Resolve(); @@ -89,16 +91,16 @@ namespace SS14.Client.Console } message.Append($", NSE: {registration.NetworkSynchronizeExistence}, references:"); - console.AddLine(message.ToString(), Color4.White); + console.AddLine(message.ToString(), ChatChannel.Default, Color4.White); foreach (Type type in registration.References) { - console.AddLine($" {type}", Color4.White); + console.AddLine($" {type}", ChatChannel.Default, Color4.White); } } catch (UnknownComponentException) { - console.AddLine($"No registration found for '{args[0]}'", Color4.Red); + console.AddLine($"No registration found for '{args[0]}'", ChatChannel.Default, Color4.Red); } return false; @@ -131,18 +133,18 @@ List of valid keys: playerocclusion, occluderdebug, light, lightintermediate, co { if (args.Length == 0) { - console.AddLine("No key specified.", Color4.Red); + console.AddLine("No key specified.", ChatChannel.Default, Color4.Red); return false; } if (args.Length > 1) { - console.AddLine("This command only takes one argument.", Color4.Red); + console.AddLine("This command only takes one argument.", ChatChannel.Default, Color4.Red); return false; } var statemgr = IoCManager.Resolve(); if (!(statemgr.CurrentState is GameScreen screen)) { - console.AddLine("Wrong game state active. Must be GameScreen", Color4.Red); + console.AddLine("Wrong game state active. Must be GameScreen", ChatChannel.Default, Color4.Red); return false; } RenderImage target; @@ -182,7 +184,7 @@ List of valid keys: playerocclusion, occluderdebug, light, lightintermediate, co target = screen.ShadowIntermediate; break; default: - console.AddLine("Unknown key", Color4.Red); + console.AddLine("Unknown key", ChatChannel.Default, Color4.Red); return false; } @@ -191,7 +193,7 @@ List of valid keys: playerocclusion, occluderdebug, light, lightintermediate, co var timestamp = DateTime.Now.ToString("yyyyMMddTHHmmsszzz"); var filename = Path.GetFullPath(PathHelpers.ExecutableRelativeFile($"dumprt-{key}-{timestamp}.png")); image.SaveToFile(filename); - console.AddLine($"Saved dump to {filename}!", Color4.Green); + console.AddLine($"Saved dump to {filename}!", ChatChannel.Default, Color4.Green); } return false; diff --git a/SS14.Client/Console/HelpCommands.cs b/SS14.Client/Console/Commands/HelpCommands.cs similarity index 83% rename from SS14.Client/Console/HelpCommands.cs rename to SS14.Client/Console/Commands/HelpCommands.cs index cc755675d..ae20a5e4f 100644 --- a/SS14.Client/Console/HelpCommands.cs +++ b/SS14.Client/Console/Commands/HelpCommands.cs @@ -1,16 +1,10 @@ using OpenTK.Graphics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using SS14.Client.Interfaces.Console; -using SS14.Shared.IoC; -using SS14.Client.Interfaces.UserInterface; -using SS14.Client.Interfaces.Network; +using SS14.Shared.Console; using SS14.Shared.Interfaces.Network; +using SS14.Shared.IoC; -namespace SS14.Client.Console +namespace SS14.Client.Console.Commands { class HelpCommand : IConsoleCommand { @@ -23,7 +17,7 @@ namespace SS14.Client.Console switch (args.Length) { case 0: - console.AddLine("To display help for a specific command, write 'help '. To list all available commands, write 'list'.", Color4.White); + console.AddLine("To display help for a specific command, write 'help '. To list all available commands, write 'list'.", ChatChannel.Default, Color4.White); break; case 1: @@ -33,19 +27,19 @@ namespace SS14.Client.Console if (!IoCManager.Resolve().IsConnected) { // No server so nothing to respond with unknown command. - console.AddLine("Unknown command: " + commandname, Color4.Red); + console.AddLine("Unknown command: " + commandname, ChatChannel.Default, Color4.Red); return false; } // TODO: Maybe have a server side help? return false; } IConsoleCommand command = console.Commands[commandname]; - console.AddLine(string.Format("{0} - {1}", command.Command, command.Description), Color4.White); - console.AddLine(command.Help, Color4.White); + console.AddLine(string.Format("{0} - {1}", command.Command, command.Description), ChatChannel.Default, Color4.White); + console.AddLine(command.Help, ChatChannel.Default, Color4.White); break; default: - console.AddLine("Invalid amount of arguments.", Color4.Red); + console.AddLine("Invalid amount of arguments.", ChatChannel.Default, Color4.Red); break; } return false; @@ -62,7 +56,7 @@ namespace SS14.Client.Console { foreach (IConsoleCommand command in console.Commands.Values) { - console.AddLine(command.Command + ": " + command.Description, Color4.White); + console.AddLine(command.Command + ": " + command.Description, ChatChannel.Default, Color4.White); } return false; diff --git a/SS14.Client/Console/QuitCommand.cs b/SS14.Client/Console/Commands/QuitCommand.cs similarity index 76% rename from SS14.Client/Console/QuitCommand.cs rename to SS14.Client/Console/Commands/QuitCommand.cs index 79acf39b2..822d42417 100644 --- a/SS14.Client/Console/QuitCommand.cs +++ b/SS14.Client/Console/Commands/QuitCommand.cs @@ -1,12 +1,7 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using SS14.Client.Interfaces.Console; -using SS14.Shared.IoC; -namespace SS14.Client.Console +namespace SS14.Client.Console.Commands { class QuitCommand : IConsoleCommand { diff --git a/SS14.Client/Console/IClientChatConsole.cs b/SS14.Client/Console/IClientChatConsole.cs new file mode 100644 index 000000000..e50f4452d --- /dev/null +++ b/SS14.Client/Console/IClientChatConsole.cs @@ -0,0 +1,23 @@ +using System; +using SS14.Client.UserInterface.CustomControls; + +namespace SS14.Client.Console +{ + /// + /// Interface for a chat compatible console. + /// + internal interface IClientChatConsole : IClientConsole + { + /// + /// Parses a raw chat message the player has submitted. + /// + /// Raw unsanitized string the player submitted. + /// + void ParseChatMessage(string text, string defaultFormat = null); + + /// + /// Parses a raw chat message the player has submitted. + /// + void ParseChatMessage(Chatbox chatBox, string text); + } +} diff --git a/SS14.Client/Console/IClientConsole.cs b/SS14.Client/Console/IClientConsole.cs new file mode 100644 index 000000000..0c8296855 --- /dev/null +++ b/SS14.Client/Console/IClientConsole.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using SS14.Client.Interfaces.Console; + +namespace SS14.Client.Console +{ + internal interface IClientConsole : IDisposable + { + /// + /// Initializes the console into a useable state. + /// + void Initialize(); + + /// + /// Resets the console to a post-initialized state. + /// + void Reset(); + + + event EventHandler AddString; + event EventHandler ClearText; + + IReadOnlyDictionary Commands { get; } + + /// + /// Parses console commands (verbs). + /// + /// + void ProcessCommand(string text); + + void SendServerCommandRequest(); + } +} diff --git a/SS14.Client/GameController.cs b/SS14.Client/GameController.cs index 8af75818b..b5c5f4f68 100644 --- a/SS14.Client/GameController.cs +++ b/SS14.Client/GameController.cs @@ -20,6 +20,7 @@ using SS14.Shared.Prototypes; using System; using System.Diagnostics; using System.IO; +using SS14.Client.Console; using SS14.Shared.ContentPack; using SS14.Shared.Interfaces; using SS14.Shared.Interfaces.Network; @@ -66,6 +67,8 @@ namespace SS14.Client private readonly IPlacementManager _placementManager; [Dependency] private readonly IBaseClient _client; + [Dependency] + private readonly IClientChatConsole _console; #endregion Fields @@ -109,6 +112,7 @@ namespace SS14.Client prototypeManager.LoadDirectory(@"Prototypes"); prototypeManager.Resync(); _networkManager.Initialize(false); + _console.Initialize(); _netGrapher.Initialize(); _userInterfaceManager.Initialize(); _mapManager.Initialize(); diff --git a/SS14.Client/GameObjects/Components/Renderable/AnimatedSpriteComponent.cs b/SS14.Client/GameObjects/Components/Renderable/AnimatedSpriteComponent.cs index 5848885c8..911000833 100644 --- a/SS14.Client/GameObjects/Components/Renderable/AnimatedSpriteComponent.cs +++ b/SS14.Client/GameObjects/Components/Renderable/AnimatedSpriteComponent.cs @@ -21,6 +21,7 @@ using Vector2i = SS14.Shared.Maths.Vector2i; using SS14.Shared.Map; using Vector2 = SS14.Shared.Maths.Vector2; using SS14.Client.Graphics.Utility; +using SS14.Shared.Console; namespace SS14.Client.GameObjects { @@ -136,7 +137,7 @@ namespace SS14.Client.GameObjects { string text = list[1].ToString(); - if (channel == ChatChannel.Ingame || channel == ChatChannel.Player || + if (channel == ChatChannel.Local || channel == ChatChannel.Player || channel == ChatChannel.Radio) { (_speechBubble ?? (_speechBubble = new SpeechBubble(Owner.Name + Owner.Uid))).SetText(text); diff --git a/SS14.Client/GameObjects/Components/Renderable/MobSpriteComponent.cs b/SS14.Client/GameObjects/Components/Renderable/MobSpriteComponent.cs index 82413c452..730a1fd4b 100644 --- a/SS14.Client/GameObjects/Components/Renderable/MobSpriteComponent.cs +++ b/SS14.Client/GameObjects/Components/Renderable/MobSpriteComponent.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using SS14.Shared.Maths; using YamlDotNet.RepresentationModel; using OpenTK.Graphics; +using SS14.Shared.Console; using Vector2 = SS14.Shared.Maths.Vector2; namespace SS14.Client.GameObjects @@ -84,7 +85,7 @@ namespace SS14.Client.GameObjects { string text = list[1].ToString(); - if (channel == ChatChannel.Ingame || channel == ChatChannel.Player || + if (channel == ChatChannel.Local || channel == ChatChannel.Player || channel == ChatChannel.Radio) { (_speechBubble ?? (_speechBubble = new SpeechBubble(Owner.Name + Owner.Uid))).SetText(text); diff --git a/SS14.Client/Interfaces/Console/IConsoleCommand.cs b/SS14.Client/Interfaces/Console/IConsoleCommand.cs index 2ec72b1a3..614a7ced7 100644 --- a/SS14.Client/Interfaces/Console/IConsoleCommand.cs +++ b/SS14.Client/Interfaces/Console/IConsoleCommand.cs @@ -1,5 +1,4 @@ -using SS14.Shared.Command; -using SS14.Shared.IoC; +using SS14.Shared.Console; namespace SS14.Client.Interfaces.Console { diff --git a/SS14.Client/Interfaces/Console/IDebugConsole.cs b/SS14.Client/Interfaces/Console/IDebugConsole.cs index c314221fe..4e8211d3c 100644 --- a/SS14.Client/Interfaces/Console/IDebugConsole.cs +++ b/SS14.Client/Interfaces/Console/IDebugConsole.cs @@ -1,5 +1,7 @@ using OpenTK.Graphics; using System.Collections.Generic; +using SS14.Shared; +using SS14.Shared.Console; namespace SS14.Client.Interfaces.Console { @@ -10,7 +12,7 @@ namespace SS14.Client.Interfaces.Console /// /// Write a line with a specific color to the console window. /// - void AddLine(string text, Color4 color); + void AddLine(string text, ChatChannel channel, Color4 color); void Clear(); } diff --git a/SS14.Client/Interfaces/Player/IPlayerManager.cs b/SS14.Client/Interfaces/Player/IPlayerManager.cs index 6d91b260a..4d4b6ab23 100644 --- a/SS14.Client/Interfaces/Player/IPlayerManager.cs +++ b/SS14.Client/Interfaces/Player/IPlayerManager.cs @@ -23,10 +23,7 @@ namespace SS14.Client.Interfaces.Player void Update(float frameTime); void Shutdown(); void Destroy(); - - //TODO: Move to console system - void SendVerb(string verb, int uid); - + void ApplyEffects(RenderImage image); void ApplyPlayerStates(List list); } diff --git a/SS14.Client/Interfaces/UserInterface/IUserInterfaceManager.cs b/SS14.Client/Interfaces/UserInterface/IUserInterfaceManager.cs index 2e7c09e6e..fa72c010e 100644 --- a/SS14.Client/Interfaces/UserInterface/IUserInterfaceManager.cs +++ b/SS14.Client/Interfaces/UserInterface/IUserInterfaceManager.cs @@ -1,7 +1,6 @@ using System; using SS14.Client.Graphics; using SS14.Client.Graphics.Input; -using SS14.Client.Interfaces.Console; using SS14.Client.UserInterface.Controls; using System.Collections.Generic; @@ -10,8 +9,7 @@ namespace SS14.Client.Interfaces.UserInterface public interface IUserInterfaceManager { IDragDropInfo DragInfo { get; } - - IDebugConsole Console { get; } + void Initialize(); void AddComponent(Control component); diff --git a/SS14.Client/Player/PlayerManager.cs b/SS14.Client/Player/PlayerManager.cs index c781ba944..8416edf44 100644 --- a/SS14.Client/Player/PlayerManager.cs +++ b/SS14.Client/Player/PlayerManager.cs @@ -124,24 +124,7 @@ namespace SS14.Client.Player UpdatePlayerList(list); } - - /// - /// Verb sender - /// If UID is 0, it means its a global verb. - /// - /// the verb - /// a target entity's Uid - public void SendVerb(string verb, int uid) - { - //TODO: Convert this to the ConCmd system. - - var message = _network.CreateNetMessage(); - message.MsgType = PlayerSessionMessage.Verb; - message.Uid = uid; - message.Verb = verb; - _network.ClientSendMessage(message, NetDeliveryMethod.ReliableOrdered); - } - + /// /// Handles an incoming session NetMsg from the server. /// diff --git a/SS14.Client/Program.cs b/SS14.Client/Program.cs index 678dcd4b6..f8480a4e8 100644 --- a/SS14.Client/Program.cs +++ b/SS14.Client/Program.cs @@ -1,4 +1,5 @@ -using SS14.Client.GameObjects; +using SS14.Client.Console; +using SS14.Client.GameObjects; using SS14.Client.Input; using SS14.Client.Interfaces; using SS14.Client.Interfaces.GameObjects; @@ -105,6 +106,8 @@ namespace SS14.Client IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); + IoCManager.Register(); + IoCManager.Register(); IoCManager.BuildGraph(); } diff --git a/SS14.Client/SS14.Client.csproj b/SS14.Client/SS14.Client.csproj index c036825cc..a57ee682c 100644 --- a/SS14.Client/SS14.Client.csproj +++ b/SS14.Client/SS14.Client.csproj @@ -152,6 +152,10 @@ + + + + @@ -230,10 +234,10 @@ - - - - + + + + @@ -346,4 +350,4 @@ - + \ No newline at end of file diff --git a/SS14.Client/State/States/GameScreen.cs b/SS14.Client/State/States/GameScreen.cs index 7786693a7..358784728 100644 --- a/SS14.Client/State/States/GameScreen.cs +++ b/SS14.Client/State/States/GameScreen.cs @@ -33,6 +33,7 @@ using SS14.Shared.Network; using System; using System.Collections.Generic; using System.Linq; +using SS14.Client.Console; using FrameEventArgs = SS14.Client.Graphics.FrameEventArgs; using Vector2 = SS14.Shared.Maths.Vector2; using Vector2i = SS14.Shared.Maths.Vector2i; @@ -147,6 +148,11 @@ namespace SS14.Client.State.States _cleanupList = new List(); _cleanupSpriteList = new List(); + //UI + var console = IoCManager.Resolve(); + _gameChat.TextSubmitted += console.ParseChatMessage; + console.AddString += _gameChat.AddLine; + UserInterfaceManager.AddComponent(_uiScreen); //Init serializer @@ -241,7 +247,7 @@ namespace SS14.Client.State.States blendingSettings.ColorDstFactor = BlendMode.Factor.OneMinusDstAlpha; blendingSettings.AlphaSrcFactor = BlendMode.Factor.SrcAlpha; blendingSettings.AlphaDstFactor = BlendMode.Factor.OneMinusSrcAlpha; - blendingSettings = blendingSettings; + _gasBatch.BlendingSettings = blendingSettings; _decalBatch = new SpriteBatch(); blendingSettings = _decalBatch.BlendingSettings; @@ -274,7 +280,7 @@ namespace SS14.Client.State.States _gameChat.Alignment = Align.Right; _gameChat.Size = new Vector2i(475, 175); _gameChat.Resize += (sender, args) => { _gameChat.LocalPosition = new Vector2i(-10 + -_gameChat.Size.X, 10); }; - _gameChat.TextSubmitted += ChatTextboxTextSubmitted; + _gameChat.DefaultChatFormat = "say \"{0}\""; _uiScreen.AddControl(_gameChat); } @@ -480,6 +486,11 @@ namespace SS14.Client.State.States /// public override void Shutdown() { + //UI + var console = IoCManager.Resolve(); + _gameChat.TextSubmitted -= console.ParseChatMessage; + console.AddString -= _gameChat.AddLine; + UserInterfaceManager.RemoveComponent(_uiScreen); IoCManager.Resolve().LocalPlayer.DetachEntity(); @@ -535,7 +546,7 @@ namespace SS14.Client.State.States } if (e.Key == Keyboard.Key.F5) { - PlayerManager.SendVerb("save", 0); + IoCManager.Resolve().ProcessCommand("save"); } if (e.Key == Keyboard.Key.F6) { @@ -547,9 +558,7 @@ namespace SS14.Client.State.States } if (e.Key == Keyboard.Key.F8) { - NetOutgoingMessage message = NetworkManager.CreateMessage(); - message.Write((byte)NetMessages.ForceRestart); - NetworkManager.ClientSendMessage(message, NetDeliveryMethod.ReliableUnordered); + IoCManager.Resolve().ProcessCommand("restart"); } if (e.Key == Keyboard.Key.Escape) { @@ -711,55 +720,13 @@ namespace SS14.Client.State.States UserInterfaceManager.MouseLeft(e); } #endregion Mouse + - #region Chat - private void HandleChatMessage(NetIncomingMessage msg) - { - var channel = (ChatChannel)msg.ReadByte(); - string text = msg.ReadString(); - int entityId = msg.ReadInt32(); - string message; - switch (channel) - { - case ChatChannel.Ingame: - case ChatChannel.Server: - case ChatChannel.OOC: - case ChatChannel.Radio: - message = "[" + channel + "] " + text; - break; - default: - message = text; - break; - } - _gameChat.AddLine(message, channel); - if (entityId > 0 && _entityManager.TryGetEntity(entityId, out IEntity a)) - { - a.SendMessage(this, ComponentMessageType.EntitySaidSomething, channel, text); - } - } +#endregion Input - private void ChatTextboxTextSubmitted(Chatbox chatbox, string text) - { - SendChatMessage(text); - } +#region Event Handlers - private void SendChatMessage(string text) - { - NetOutgoingMessage message = NetworkManager.CreateMessage(); - message.Write((byte)NetMessages.ChatMessage); - message.Write((byte)ChatChannel.Player); - message.Write(text); - message.Write(-1); - NetworkManager.ClientSendMessage(message, NetDeliveryMethod.ReliableUnordered); - } - - #endregion Chat - - #endregion Input - - #region Event Handlers - - #region Messages +#region Messages private void NetworkManagerMessageArrived(object sender, NetMessageArgs args) { @@ -788,15 +755,12 @@ namespace SS14.Client.State.States case NetMessages.PlacementManagerMessage: PlacementManager.HandleNetMessage(message); break; - case NetMessages.ChatMessage: - HandleChatMessage(message); - break; } break; } } - #endregion Messages +#endregion Messages private void OnPlayerMove(object sender, MoveEventArgs args) { @@ -811,9 +775,9 @@ namespace SS14.Client.State.States RecalculateScene(); } - #endregion Event Handlers +#endregion Event Handlers - #region Lighting in order of call +#region Lighting in order of call /** * Calculate lights In player view @@ -853,9 +817,9 @@ namespace SS14.Client.State.States //Step 2 - Set up the render targets for the composite lighting. RenderImage source = ScreenShadows; - #if !MACOS +#if !MACOS source.Clear(Color.Black); - #else +#else // For some insane reason, SFML does not clear the texture on MacOS. // unless you call CopyToImage() on it, which we can't due to performance. // This works though! @@ -866,7 +830,7 @@ namespace SS14.Client.State.States //͎̆̒̿ͤ̀͝͝H̙͇̽ͩ̓̚E̜̘̭̟͓͖̓̔̑̀͞͠ͅL̪̰̺̼̊̐̌P̸̴̴̙̻̻̗̯̤͎͓̿̊͌ͪ ̯̜͊̍̄M̩̻̺̬̗͕̬̈͗́ͯ̚̚͜Ȇ̟̜͙̙ ̅͐͐҉̱̫̼̱h̢̼͎͕̪͉͂̊ͤͣ͛͂̄ͯ͝͠t͎̺̼͙̰͓ͥ̏́ţ͕̼̱̲͈̹̾ͣͯͮ̄̅ͧͦ̚p̧̜̹͚̦ͧ̊̀̽ͫ̓̓ͣ̚͡ş̨̮̣̼̰̞̝̫͋̌ͬ͊͑ͣ:̷͇͚̲̻̩̞ͤ͐͞/̈́͋ͯ͂̀̅ͪ͑͞͏͖̮̯͍̟͚͓͎/̟̩̲͑̚ĩ̶̢̲̬̦͍͈̯͉̓̅͟.̦̭̲̭̂̓̿̈́̄͟ï͋͘҉̘̪̠̣̰m̖͎̮͆̀ͯ̑̃ͅg̢̝͉͔̽̃̀̂u̢̱̞̫̱̹̪̇͟r̸̯̞̹͓̥̮̮̝̹͌̀͌̈́͑.̪̦͕̞̥͕̩̎ͤ̇̉̒̓c̨̩̰̎̂ͬͤ̍̓̓ṍ̵͍͈̣̰m̛̱̥̘͙͈ͫͭ̒ͪͮ/̓͆̽̀͐̿͘҉̘̲͈̬̹̟M̡̺͍̜̺̘̰̼͂̎̃͞͝l̴̫̘̦̺̑ͪ̃͢ͅn̤̱̺̿͌ͨ͡U̧̢̜̞̝̒͒̐̄̊̽ͤͫͅL̡̺͉̠͖͚͉͚ͥͧ͋ͬ̀b̵̶̪̝̟̔ͪ̂̊A̧̧̝̭͖̭͍̬͑̀.̞̬͈́ͫ̍͘ͅp̶͎̠̱̍ͪ̆n̩͕̬̈ͪ̋ͅg̘̗̙̻͎̩̲͙͊ͨͭͣ͌̚̕ CluwneLib.drawRectangle(0, 0, source.Width, source.Height, Color.Black); source.EndDrawing(); - #endif +#endif RenderImage desto = ShadowIntermediate; RenderImage copy = null; @@ -1229,9 +1193,9 @@ namespace SS14.Client.State.States PlayerManager.ApplyEffects(ComposedSceneTarget); } - #endregion Lighting in order of call +#endregion Lighting in order of call - #region Helper methods +#region Helper methods private void RenderList(Vector2 topleft, Vector2 bottomright, IEnumerable renderables) { @@ -1325,9 +1289,9 @@ namespace SS14.Client.State.States debugWallOccluders = !debugWallOccluders; } - #endregion Helper methods +#endregion Helper methods - #region Nested type: ClickData +#region Nested type: ClickData private struct ClickData { @@ -1341,7 +1305,7 @@ namespace SS14.Client.State.States } } - #endregion Nested type: ClickData +#endregion Nested type: ClickData class GameScreenDebug { diff --git a/SS14.Client/State/States/LobbyMenu.cs b/SS14.Client/State/States/LobbyMenu.cs index 07e082059..180a041a6 100644 --- a/SS14.Client/State/States/LobbyMenu.cs +++ b/SS14.Client/State/States/LobbyMenu.cs @@ -10,6 +10,7 @@ using SS14.Shared.IoC; using SS14.Shared.Maths; using System; using System.Collections.Generic; +using SS14.Client.Console; namespace SS14.Client.State.States { @@ -124,6 +125,7 @@ namespace SS14.Client.State.States _lobbyChat = new Chatbox(new Vector2i(780, 225)); _lobbyChat.Alignment = Align.HCenter | Align.VCenter; + _lobbyChat.DefaultChatFormat = "ooc \"{0}\""; imgChatBg.AddControl(_lobbyChat); var btnReady = new ImageButton(); @@ -147,6 +149,10 @@ namespace SS14.Client.State.States _plyrMan = IoCManager.Resolve(); _plyrMan.PlayerListUpdated += HandlePlayerList; + var console = IoCManager.Resolve(); + _lobbyChat.TextSubmitted += console.ParseChatMessage; + console.AddString += _lobbyChat.AddLine; + UserInterfaceManager.AddComponent(_uiScreen); UpdateInfo(); @@ -158,6 +164,10 @@ namespace SS14.Client.State.States _plyrMan = IoCManager.Resolve(); _plyrMan.PlayerListUpdated -= HandlePlayerList; + var console = IoCManager.Resolve(); + _lobbyChat.TextSubmitted -= console.ParseChatMessage; + console.AddString -= _lobbyChat.AddLine; + UserInterfaceManager.RemoveComponent(_uiScreen); } @@ -271,7 +281,7 @@ namespace SS14.Client.State.States private void _btnReady_Clicked(ImageButton sender) { - IoCManager.Resolve().SendVerb("joingame", 0); + IoCManager.Resolve().ProcessCommand("joingame"); } private void _btnBack_Clicked(ImageButton sender) diff --git a/SS14.Client/UserInterface/CustomControls/Chatbox.cs b/SS14.Client/UserInterface/CustomControls/Chatbox.cs index 3bf62f45b..da5147c7b 100644 --- a/SS14.Client/UserInterface/CustomControls/Chatbox.cs +++ b/SS14.Client/UserInterface/CustomControls/Chatbox.cs @@ -2,9 +2,10 @@ using System.Linq; using System.Text.RegularExpressions; using OpenTK.Graphics; +using SS14.Client.Console; using SS14.Client.Graphics.Input; using SS14.Client.UserInterface.Controls; -using SS14.Shared; +using SS14.Shared.Console; using SS14.Shared.Maths; namespace SS14.Client.UserInterface.CustomControls @@ -15,10 +16,12 @@ namespace SS14.Client.UserInterface.CustomControls private const int MaxLinePixelLength = 500; - private readonly Dictionary _chatColors; - private readonly IList _inputHistory = new List(); + private readonly Textbox _input; + private readonly ScrollableContainer _historyBox; + private readonly ListPanel _chatHistoryList; + /// /// To prevent the TextEntered from the key toggling chat being registered. /// @@ -34,9 +37,15 @@ namespace SS14.Client.UserInterface.CustomControls /// private string _inputTemp; - private readonly Textbox _input; - private readonly ScrollableContainer _historyBox; - private readonly ListPanel _chatHistoryList; + /// + /// Default formatting string for the ClientChatConsole. + /// + public string DefaultChatFormat { get; set; } + + /// + /// Blacklists channels from being displayed. + /// + public List ChannelBlacklist { get; set; } public override bool Focus { @@ -66,18 +75,9 @@ namespace SS14.Client.UserInterface.CustomControls }; _input.OnSubmit += (sender, text) => input_OnSubmit(sender, text); - _chatColors = new Dictionary + ChannelBlacklist = new List() { - [ChatChannel.Default] = Color4.Gray, - [ChatChannel.Damage] = Color4.Red, - [ChatChannel.Radio] = new Color4(0, 100, 0, 255), - [ChatChannel.Server] = Color4.Blue, - [ChatChannel.Player] = new Color4(0, 128, 0, 255), - [ChatChannel.Lobby] = Color4.White, - [ChatChannel.Ingame] = new Color4(0, 200, 0, 255), - [ChatChannel.OOC] = Color4.White, - [ChatChannel.Emote] = Color4.Cyan, - [ChatChannel.Visual] = Color4.Yellow, + ChatChannel.Default, }; } @@ -164,7 +164,6 @@ namespace SS14.Client.UserInterface.CustomControls TextSubmitted = null; _input.Dispose(); - _chatColors.Clear(); } public override void DoLayout() @@ -257,10 +256,13 @@ namespace SS14.Client.UserInterface.CustomControls return lineList; } - public void AddLine(string message, ChatChannel channel) + public void AddLine(string message, ChatChannel channel, Color color) { if (Disposed) return; + if(ChannelBlacklist.Contains(channel)) + return; + //TODO: LineHeight should be from the Font, not hard coded. const int lineHeight = 12; @@ -272,7 +274,7 @@ namespace SS14.Client.UserInterface.CustomControls _chatHistoryList.AddControl(new Label(content, "CALIBRI") { Size = new Vector2i(ClientArea.Width - 10, lineHeight), - ForegroundColor = _chatColors[channel], + ForegroundColor = color, }); } @@ -312,5 +314,10 @@ namespace SS14.Client.UserInterface.CustomControls Focus = false; } + + public void AddLine(object sender, AddStringArgs e) + { + AddLine(e.Text, e.Channel, e.Color); + } } } diff --git a/SS14.Client/UserInterface/CustomControls/DebugConsole.cs b/SS14.Client/UserInterface/CustomControls/DebugConsole.cs index 10edd0920..1f8b1752b 100644 --- a/SS14.Client/UserInterface/CustomControls/DebugConsole.cs +++ b/SS14.Client/UserInterface/CustomControls/DebugConsole.cs @@ -1,59 +1,27 @@ -using System; -using System.Collections.Generic; -using Lidgren.Network; +using System.Collections.Generic; using OpenTK.Graphics; +using SS14.Client.Console; using SS14.Client.Graphics.Input; using SS14.Client.Interfaces.Console; using SS14.Client.UserInterface.Controls; -using SS14.Shared; -using SS14.Shared.Interfaces.Network; -using SS14.Shared.Interfaces.Reflection; +using SS14.Shared.Console; using SS14.Shared.IoC; -using SS14.Shared.Network; -using SS14.Shared.Network.Messages; -using SS14.Shared.Reflection; -using SS14.Shared.Utility; using Vector2i = SS14.Shared.Maths.Vector2i; namespace SS14.Client.UserInterface.CustomControls { public class DebugConsole : ScrollableContainer, IDebugConsole { + private readonly IClientConsole _console; private readonly Textbox _txtInput; private readonly ListPanel _historyList; - private readonly Dictionary _commands = new Dictionary(); - private int last_y; - private bool sentCommandRequestToServer; - - public override bool Visible - { - get => base.Visible; - set - { - base.Visible = value; - - var netMgr = IoCManager.Resolve(); - if (value) - { - // Focus doesn't matter because UserInterfaceManager is hardcoded to go to console when it's visible. - // Though TextBox does like focus for the caret and passing KeyDown. - _txtInput.Focus = true; - netMgr.MessageArrived += NetMgr_MessageArrived; - if (netMgr.IsConnected && !sentCommandRequestToServer) - SendServerCommandRequest(); - } - else - { - _txtInput.Focus = false; - netMgr.MessageArrived -= NetMgr_MessageArrived; - } - } - } - - public DebugConsole(string uniqueName, Vector2i size) + private int _lastY; + + public DebugConsole(Vector2i size) : base(size) { + _console = IoCManager.Resolve(); _txtInput = new Textbox(size.X) { ClearFocusOnSubmit = false, @@ -68,22 +36,23 @@ namespace SS14.Client.UserInterface.CustomControls BackgroundColor = new Color4(64, 64, 64, 200); DrawBackground = true; DrawBorder = true; - - InitializeCommands(); + + _console.AddString += (sender, args) => AddLine(args.Text, args.Channel, args.Color); + _console.ClearText += (sender, args) => Clear(); } - public IReadOnlyDictionary Commands => _commands; + public IReadOnlyDictionary Commands => _console.Commands; - public void AddLine(string text, Color4 color) + public void AddLine(string text, ChatChannel channel, Color4 color) { var atBottom = ScrollbarV.Value >= ScrollbarV.Max; var newLabel = new Label(text, "CALIBRI") { - Position = new Vector2i(5, last_y), + Position = new Vector2i(5, _lastY), ForegroundColor = color }; - last_y = newLabel.ClientArea.Bottom; + _lastY = newLabel.ClientArea.Bottom; _historyList.AddControl(newLabel); _historyList.DoLayout(); @@ -99,7 +68,7 @@ namespace SS14.Client.UserInterface.CustomControls { _historyList.DisposeAllChildren(); _historyList.DoLayout(); - last_y = 0; + _lastY = 0; ScrollbarV.Value = 0; } @@ -126,6 +95,7 @@ namespace SS14.Client.UserInterface.CustomControls public override void Dispose() { _txtInput.Dispose(); + _console.Dispose(); base.Dispose(); } @@ -166,145 +136,9 @@ namespace SS14.Client.UserInterface.CustomControls private void TxtInputOnSubmit(Textbox sender, string text) { - AddLine("> " + text, new Color4(255, 250, 240, 255)); - + // debugConsole input is not prefixed with slash if(!string.IsNullOrWhiteSpace(text)) - ProcessCommand(text); - } - - private void NetMgr_MessageArrived(object sender, NetMessageArgs e) - { - //Make sure we reset the position - we might receive this message after the gamestates. - if (e.RawMessage.Position > 0) - e.RawMessage.Position = 0; - - if (e.RawMessage.MessageType != NetIncomingMessageType.Data) - return; - - switch ((NetMessages) e.RawMessage.PeekByte()) - { - case NetMessages.ConsoleCommandReply: - e.RawMessage.ReadByte(); - AddLine("< " + e.RawMessage.ReadString(), new Color4(65, 105, 225, 255)); - break; - - case NetMessages.ConsoleCommandRegister: - e.RawMessage.ReadByte(); - for (var amount = e.RawMessage.ReadUInt16(); amount > 0; amount--) - { - var commandName = e.RawMessage.ReadString(); - // Do not do duplicate commands. - if (_commands.ContainsKey(commandName)) - { - AddLine("Server sent console command {0}, but we already have one with the same name. Ignoring." + commandName, Color4.White); - continue; - } - - var description = e.RawMessage.ReadString(); - var help = e.RawMessage.ReadString(); - - var command = new ServerDummyCommand(commandName, help, description); - _commands[commandName] = command; - } - break; - } - - //Again, make sure we reset the position - we might get it before the gamestate and then that would break. - e.RawMessage.Position = 0; - } - - /// - /// Processes commands (chat messages starting with /) - /// - /// input text - private void ProcessCommand(string text) - { - //Commands are processed locally and then sent to the server to be processed there again. - var args = new List(); - - CommandParsing.ParseArguments(text, args); - - var commandname = args[0]; - - var forward = true; - if (_commands.ContainsKey(commandname)) - { - var command = _commands[commandname]; - args.RemoveAt(0); - forward = command.Execute(this, args.ToArray()); - } - else if (!IoCManager.Resolve().IsConnected) - { - AddLine("Unknown command: " + commandname, Color4.Red); - return; - } - - if (forward) - SendServerConsoleCommand(text); - } - - private void InitializeCommands() - { - var manager = IoCManager.Resolve(); - foreach (var t in manager.GetAllChildren()) - { - var instance = Activator.CreateInstance(t, null) as IConsoleCommand; - if (_commands.ContainsKey(instance.Command)) - throw new Exception(string.Format("Command already registered: {0}", instance.Command)); - - _commands[instance.Command] = instance; - } - } - - private void SendServerConsoleCommand(string text) - { - var netMgr = IoCManager.Resolve(); - if (netMgr != null && netMgr.IsConnected) - { - var outMsg = netMgr.CreateMessage(); - outMsg.Write((byte) NetMessages.ConsoleCommand); - outMsg.Write(text); - netMgr.ClientSendMessage(outMsg, NetDeliveryMethod.ReliableUnordered); - } - } - - private void SendServerCommandRequest() - { - var netMgr = IoCManager.Resolve(); - if (!netMgr.IsConnected) - return; - - var msg = netMgr.CreateNetMessage(); - // empty message to request commands - netMgr.ClientSendMessage(msg, NetDeliveryMethod.ReliableUnordered); - - sentCommandRequestToServer = true; - } - } - - /// - /// These dummies are made purely so list and help can list server-side commands. - /// - [Reflect(false)] - internal class ServerDummyCommand : IConsoleCommand - { - internal ServerDummyCommand(string command, string help, string description) - { - Command = command; - Help = help; - Description = description; - } - - public string Command { get; } - - public string Help { get; } - - public string Description { get; } - - // Always forward to server. - public bool Execute(IDebugConsole console, params string[] args) - { - return true; + _console.ProcessCommand(text); } } } diff --git a/SS14.Client/UserInterface/UserInterfaceManager.cs b/SS14.Client/UserInterface/UserInterfaceManager.cs index 6f983eafe..29b80d737 100644 --- a/SS14.Client/UserInterface/UserInterfaceManager.cs +++ b/SS14.Client/UserInterface/UserInterfaceManager.cs @@ -52,7 +52,7 @@ namespace SS14.Client.UserInterface public void Initialize() { - _console = new DebugConsole("dbgConsole", new Vector2i((int) CluwneLib.Window.Viewport.Size.X, 400)); + _console = new DebugConsole(new Vector2i((int) CluwneLib.Window.Viewport.Size.X, 400)); _console.Visible = false; } diff --git a/SS14.Server/BaseServer.cs b/SS14.Server/BaseServer.cs index e8aa63556..5d24a854a 100644 --- a/SS14.Server/BaseServer.cs +++ b/SS14.Server/BaseServer.cs @@ -35,6 +35,7 @@ using SS14.Shared.Prototypes; using SS14.Shared.ServerEnums; using SS14.Shared.Map; using SS14.Server.Interfaces.Maps; +using SS14.Shared.Console; namespace SS14.Server { @@ -193,19 +194,12 @@ namespace SS14.Server netMan.RegisterNetMessage(MsgPlayerListReq.NAME, (int)MsgPlayerListReq.ID, HandlePlayerListReq); netMan.RegisterNetMessage(MsgPlayerList.NAME, (int)MsgPlayerList.ID, HandleErrorMessage); - // Unused: NetMessages.LobbyChat - netMan.RegisterNetMessage(MsgChat.NAME, (int)MsgChat.ID, message => IoCManager.Resolve().HandleNetMessage((MsgChat)message)); netMan.RegisterNetMessage(MsgSession.NAME, (int)MsgSession.ID, message => IoCManager.Resolve().HandleNetworkMessage((MsgSession)message)); - netMan.RegisterNetMessage(MsgConCmd.NAME, (int)MsgConCmd.ID, message => IoCManager.Resolve().ProcessCommand((MsgConCmd)message)); - netMan.RegisterNetMessage(MsgConCmdAck.NAME, (int)MsgConCmdAck.ID, HandleErrorMessage); - netMan.RegisterNetMessage(MsgConCmdReg.NAME, (int)MsgConCmdReg.ID, message => IoCManager.Resolve().HandleRegistrationRequest(message.MsgChannel)); netMan.RegisterNetMessage(MsgMapReq.NAME, (int)MsgMapReq.ID, message => SendMap(message.MsgChannel)); netMan.RegisterNetMessage(MsgPlacement.NAME, (int)MsgPlacement.ID, message => IoCManager.Resolve().HandleNetMessage((MsgPlacement)message)); netMan.RegisterNetMessage(MsgUi.NAME, (int)MsgUi.ID, HandleErrorMessage); - netMan.RegisterNetMessage(MsgJoinGame.NAME, (int)MsgJoinGame.ID, HandleErrorMessage); - netMan.RegisterNetMessage(MsgRestartReq.NAME, (int)MsgRestartReq.ID, message => Restart()); netMan.RegisterNetMessage(MsgEntity.NAME, (int)MsgEntity.ID, message => _entities.HandleEntityNetworkMessage((MsgEntity)message)); netMan.RegisterNetMessage(MsgAdmin.NAME, (int)MsgAdmin.ID, message => HandleAdminMessage((MsgAdmin)message)); @@ -213,10 +207,6 @@ namespace SS14.Server netMan.RegisterNetMessage(MsgStateAck.NAME, (int)MsgStateAck.ID, message => HandleStateAck((MsgStateAck)message)); netMan.RegisterNetMessage(MsgFullState.NAME, (int)MsgFullState.ID, message => HandleErrorMessage(message)); - IoCManager.Resolve().Initialize(); - IoCManager.Resolve().Initialize(this, MaxPlayers); - IoCManager.Resolve().Initialize(); - // Set up the VFS _resources.Initialize(); @@ -236,6 +226,11 @@ namespace SS14.Server // TODO: solve this properly. Serializer.Initialize(); + // Initialize Tier 2 services + IoCManager.Resolve().Initialize(); + IoCManager.Resolve().Initialize(this, MaxPlayers); + IoCManager.Resolve().Initialize(); + // Call Init in game assemblies. AssemblyLoader.BroadcastRunLevel(AssemblyLoader.RunLevel.Init); @@ -539,9 +534,8 @@ namespace SS14.Server if (_lastAnnounced != countdown.Seconds) { _lastAnnounced = countdown.Seconds; - IoCManager.Resolve().SendChatMessage(ChatChannel.Server, - "Starting in " + _lastAnnounced + " seconds...", - "", 0); + IoCManager.Resolve() + .DispatchMessage(ChatChannel.Server, $"Starting in {_lastAnnounced} seconds..."); } if (countdown.Seconds <= 0) StartGame(); diff --git a/SS14.Server/Chat/ChatManager.cs b/SS14.Server/Chat/ChatManager.cs index a74c5cf9c..1a018838d 100644 --- a/SS14.Server/Chat/ChatManager.cs +++ b/SS14.Server/Chat/ChatManager.cs @@ -1,278 +1,110 @@ -using OpenTK; -using SS14.Server.Interfaces; -using SS14.Server.Interfaces.Chat; -using SS14.Server.Interfaces.GameObjects; -using SS14.Server.Interfaces.Player; -using SS14.Shared; -using SS14.Shared.GameObjects; -using SS14.Shared.Interfaces.GameObjects.Components; -using SS14.Shared.Interfaces.Reflection; -using SS14.Shared.IoC; -using SS14.Shared.Log; -using SS14.Shared.Reflection; -using SS14.Shared.Utility; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; +using System.Collections.Generic; using System.Xml.Serialization; -using SS14.Shared.ContentPack; +using SS14.Server.Interfaces.Chat; +using SS14.Server.Interfaces.Player; +using SS14.Shared.Console; +using SS14.Shared.Interfaces; using SS14.Shared.Interfaces.Network; -using SS14.Shared.Network; +using SS14.Shared.IoC; using SS14.Shared.Network.Messages; +using SS14.Shared.Players; namespace SS14.Server.Chat { + /// + /// Dispatches chat messages to clients. + /// public class ChatManager : IChatManager { + private const string DefaultPronoun = "their"; + [Dependency] - private readonly IReflectionManager reflectionManager; + private readonly IServerNetManager _network; + [Dependency] - private readonly IServerEntityManager entityManager; + private readonly IResourceManager _resources; private readonly Dictionary _emotes = new Dictionary(); - private readonly Dictionary _commands = new Dictionary(); - private readonly string _emotePath = PathHelpers.ExecutableRelativeFile("emotes.xml"); - - public IDictionary Commands => _commands; - - #region IChatManager Members + /// public void Initialize() { + _network.RegisterNetMessage(MsgChat.NAME, (int) MsgChat.ID); LoadEmotes(); - LoadCommands(); } - public void HandleNetMessage(MsgChat message) + /// + public void DispatchMessage(INetChannel client, ChatChannel channel, string text, PlayerIndex? index = null, int? entityUid = null) { - var channel = message.Channel; - string text = message.Text; - - var client = message.MsgChannel; - - var session = IoCManager.Resolve().GetSessionByChannel(message.MsgChannel); - var playerName = session.Name; - - Logger.Debug("CHAT:: Channel: {0} :: Player: {1} :: Message: {2}", channel, playerName, text); - - var entityId = IoCManager.Resolve().GetSessionByChannel(message.MsgChannel).AttachedEntityUid; - - bool hasChannelIdentifier = false; - if (channel != ChatChannel.Lobby) - channel = DetectChannel(text, out hasChannelIdentifier); - if (hasChannelIdentifier) - text = text.Substring(1); - text = text.Trim(); // Remove whitespace - - if (text[0] == '/') - ProcessCommand(text, playerName, channel, entityId, client); - else if (text[0] == '*') - ProcessEmote(text, playerName, channel, entityId, message.MsgChannel); - else - SendChatMessage(channel, text, playerName, entityId); + var msg = BuildChatMessage(channel, text, index, entityUid); + _network.ServerSendMessage(msg, client); } - public void SendChatMessage(ChatChannel channel, string text, string name, int? entityId) + /// + public void DispatchMessage(List clients, ChatChannel channel, string text, PlayerIndex? index = null, int? entityUid = null) { - MsgChat message = MakeNetChatMessage(channel, text, name, entityId); + var msg = BuildChatMessage(channel, text, index, entityUid); + _network.ServerSendToMany(msg, clients); + } - switch (channel) + /// + public void DispatchMessage(ChatChannel channel, string text, PlayerIndex? index = null, int? entityUid = null) + { + var msg = BuildChatMessage(channel, text, index, entityUid); + _network.ServerSendToAll(msg); + } + + /// + public bool ExpandEmote(string input, IPlayerSession session, out string self, out string other) + { + if (_emotes.TryGetValue(input, out var emote)) { - case ChatChannel.Server: - case ChatChannel.OOC: - case ChatChannel.Radio: - case ChatChannel.Player: - case ChatChannel.Default: - IoCManager.Resolve().ServerSendToAll(message); - break; + //TODO: Notify content, allow it to override expansion + // args: session, Emote - case ChatChannel.Damage: - case ChatChannel.Ingame: - case ChatChannel.Visual: - case ChatChannel.Emote: - SendToPlayersInRange(message, entityId); - break; - - case ChatChannel.Lobby: - SendToLobby(message); - break; + self = string.Format(emote.SelfText); + other = string.Format(emote.OtherText, session.Name, DefaultPronoun); + return true; } + + self = string.Empty; + other = string.Empty; + return false; } - public void SendPrivateMessage(INetChannel client, ChatChannel channel, string text, string name, int? entityId) + private MsgChat BuildChatMessage(ChatChannel channel, string text, PlayerIndex? index, int? entityUid) { - MsgChat message = MakeNetChatMessage(channel, text, name, entityId); - IoCManager.Resolve().ServerSendMessage(message, client); - } - - private MsgChat MakeNetChatMessage(ChatChannel channel, string text, string name, int? entityId) - { - string fullmsg = text; - if (!string.IsNullOrEmpty(name) && channel == ChatChannel.Emote) - fullmsg = text; //Emote already has name in it probably... - else if (channel == ChatChannel.Ingame || channel == ChatChannel.OOC || channel == ChatChannel.Radio || - channel == ChatChannel.Lobby) - fullmsg = name + ": " + text; - - MsgChat message = IoCManager.Resolve().CreateNetMessage(); + var message = _network.CreateNetMessage(); message.Channel = channel; - message.Text = fullmsg; - message.EntityId = entityId; + message.Text = text; + message.Index = index; + message.EntityId = entityUid; return message; } - #endregion IChatManager Members - - private ChatChannel DetectChannel(string message, out bool hasChannelIdentifier) - { - hasChannelIdentifier = false; - var channel = ChatChannel.Ingame; - switch (message[0]) - { - case '[': - channel = ChatChannel.OOC; - hasChannelIdentifier = true; - break; - - case ':': - channel = ChatChannel.Radio; - hasChannelIdentifier = true; - break; - - case '@': - channel = ChatChannel.Emote; - hasChannelIdentifier = true; - break; - } - return channel; - } - private void LoadEmotes() { - if (File.Exists(_emotePath)) - { - using (var emoteFileStream = new FileStream(_emotePath, FileMode.Open, FileAccess.Read)) - { - XmlSerializer serializer = new XmlSerializer(typeof(List)); - - var emotes = (List)serializer.Deserialize(emoteFileStream); - emoteFileStream.Close(); - foreach (var emote in emotes) - { - _emotes.Add(emote.Command, emote); - } - } - } - else - { - using (var emoteFileStream = new FileStream(_emotePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) - { - var emote = new Emote() - { - Command = "default", - OtherText = "{0} does something!", - SelfText = "You do something!" - }; - _emotes.Add("default", emote); - XmlSerializer serializer = new XmlSerializer(typeof(List)); - serializer.Serialize(emoteFileStream, _emotes.Values.ToList()); - emoteFileStream.Close(); - } - } - } - - // Load all command types. - private void LoadCommands() - { - foreach (Type t in reflectionManager.GetAllChildren()) - { - IChatCommand instance = (IChatCommand)Activator.CreateInstance(t, null); - if (_commands.ContainsKey(instance.Command)) - { - Logger.Error("Command has duplicate name: {0}", instance.Command); - continue; - } - _commands[instance.Command] = instance; - } - } - - private void SendToPlayersInRange(NetMessage message, int? entityId) - { - //TODO: Move this to a real PVS system. - int withinRange = 512; - if (entityId == null) - return; - List recipients = IoCManager.Resolve() - .GetPlayersInRange(entityManager.GetEntity((int) entityId) - .GetComponent().LocalPosition, withinRange) - .Select(p => p.ConnectedClient).ToList(); - - IoCManager.Resolve().ServerSendToMany(message, recipients); - } - - private void SendToLobby(NetMessage message) - { - //TODO: Move this to the Content Assembly. - List recipients = IoCManager.Resolve().GetPlayersInLobby().Select(p => p.ConnectedClient).ToList(); - IoCManager.Resolve().ServerSendToMany(message, recipients); - } - - private void ProcessEmote(string text, string name, ChatChannel channel, int? entityId, INetChannel client) - { - if (entityId == null) - return; //No emotes from non-entities! - - var args = new List(); - - CommandParsing.ParseArguments(text, args); - if (_emotes.ContainsKey(args[0])) - { - // todo make a user-only channel that only the sender can see i.e. for emotes and game feedback ('you put the coins in the jar' or whatever) - var otherText = String.Format(_emotes[args[0]].OtherText, name, "his"); //todo pronouns, gender - SendChatMessage(ChatChannel.Emote, otherText, name, entityId); - } - else - { - //todo Bitch at the user - } - } - - /// - /// Processes commands (chat messages starting with /) - /// - /// Text content. - /// Player name that sent the chat text. - /// Channel message was received on. - /// Client that sent the command. - private void ProcessCommand(string text, string name, ChatChannel channel, int? entityId, INetChannel client) - { - List args = new List(); - - CommandParsing.ParseArguments(text.Substring(1), args); // Parse, but cut out the first character (/). - - if (args.Count <= 0) + if (!_resources.TryContentFileRead(@"emotes.xml", out var emoteFileStream)) return; - string command = args[0]; - if (!_commands.ContainsKey(command)) + var serializer = new XmlSerializer(typeof(List)); + var emotes = (List) serializer.Deserialize(emoteFileStream); + emoteFileStream.Close(); + + foreach (var emote in emotes) { - string message = string.Format("Command '{0}' not found.", command); - SendPrivateMessage(client, ChatChannel.Default, message, "Server", null); - return; + _emotes.Add(emote.Command, emote); } - - _commands[command].Execute(this, client, args.ToArray()); } - } - public struct Emote - { - public string Command { get; set; } - public string SelfText { get; set; } - public string OtherText { get; set; } + // xml serializer requires this to be public + public struct Emote + { + public string Command { get; set; } + public string SelfText { get; set; } + public string OtherText { get; set; } + } } } diff --git a/SS14.Server/Chat/Commands/ListCommands.cs b/SS14.Server/Chat/Commands/ListCommands.cs deleted file mode 100644 index 6f93a1fe6..000000000 --- a/SS14.Server/Chat/Commands/ListCommands.cs +++ /dev/null @@ -1,28 +0,0 @@ -using SS14.Server.Interfaces; -using SS14.Server.Interfaces.Chat; -using SS14.Shared.IoC; -using System; -using System.Text; -using SS14.Shared.Interfaces.Network; -using SS14.Shared.Network; - -namespace SS14.Server.Chat.Commands -{ - public class ListCommands : IChatCommand - { - public string Command => "list"; - public string Description => "Lists all available commands."; - public string Help => "Outputs a list of all commands which are currently available to you, and a total command number."; - - public void Execute(IChatManager manager, INetChannel client, params string[] args) - { - StringBuilder builder = new StringBuilder("Available commands:\n"); - foreach (IChatCommand command in manager.Commands.Values) - { - builder.AppendFormat("{0}: {1}\n", command.Command, command.Description); - } - string message = builder.ToString().Trim(' ', '\n'); - manager.SendPrivateMessage(client, Shared.ChatChannel.Default, message, "Server", null); - } - } -} diff --git a/SS14.Server/Chat/Commands/Test.cs b/SS14.Server/Chat/Commands/Test.cs deleted file mode 100644 index 09be56a16..000000000 --- a/SS14.Server/Chat/Commands/Test.cs +++ /dev/null @@ -1,21 +0,0 @@ -using SS14.Server.Interfaces; -using SS14.Server.Interfaces.Chat; -using SS14.Shared; -using SS14.Shared.Interfaces.Network; -using SS14.Shared.IoC; -using SS14.Shared.Network; - -namespace SS14.Server.Chat.Commands -{ - public class Test : IChatCommand - { - public string Command => "test"; - public string Description => "It's just a test bro."; - public string Help => "This thing tests stuff. If you got this message that means it worked. Hooray!"; - - public void Execute(IChatManager manager, INetChannel client, params string[] args) - { - IoCManager.Resolve().SendChatMessage(ChatChannel.Server, "Test worked!", "retarded shitcode", null); // That retarded shitcode is chat code fyi. - } - } -} diff --git a/SS14.Server/ClientConsoleHost/ClientConsoleHost.cs b/SS14.Server/ClientConsoleHost/ClientConsoleHost.cs index 200c93a54..e36ac8ab2 100644 --- a/SS14.Server/ClientConsoleHost/ClientConsoleHost.cs +++ b/SS14.Server/ClientConsoleHost/ClientConsoleHost.cs @@ -1,19 +1,14 @@ -using SS14.Server.Interfaces; +using System; +using System.Collections.Generic; using SS14.Server.Interfaces.ClientConsoleHost; -using SS14.Server.Interfaces.GameObjects; using SS14.Server.Interfaces.Player; -using SS14.Shared; -using SS14.Shared.GameObjects; +using SS14.Shared.Interfaces.Network; using SS14.Shared.Interfaces.Reflection; using SS14.Shared.IoC; using SS14.Shared.IoC.Exceptions; -using SS14.Shared.Utility; -using System.Collections.Generic; -using System.Reflection; -using System; -using SS14.Shared.Interfaces.Network; -using SS14.Shared.Network; +using SS14.Shared.Log; using SS14.Shared.Network.Messages; +using SS14.Shared.Utility; namespace SS14.Server.ClientConsoleHost { @@ -21,6 +16,12 @@ namespace SS14.Server.ClientConsoleHost { [Dependency] private readonly IReflectionManager reflectionManager; + [Dependency] + private readonly IPlayerManager _players; + [Dependency] + private readonly IServerNetManager _net; + + private readonly Dictionary availableCommands = new Dictionary(); public IDictionary AvailableCommands => availableCommands; @@ -33,7 +34,7 @@ namespace SS14.Server.ClientConsoleHost message.Commands = new MsgConCmdReg.Command[AvailableCommands.Count]; foreach (var command in AvailableCommands.Values) { - message.Commands[counter++] = new MsgConCmdReg.Command() + message.Commands[counter++] = new MsgConCmdReg.Command { Name = command.Command, Description = command.Description, @@ -46,49 +47,52 @@ namespace SS14.Server.ClientConsoleHost public void Initialize() { - foreach (Type type in reflectionManager.GetAllChildren()) + foreach (var type in reflectionManager.GetAllChildren()) { var instance = Activator.CreateInstance(type, null) as IClientCommand; - if (AvailableCommands.TryGetValue(instance.Command, out IClientCommand duplicate)) - { + if (AvailableCommands.TryGetValue(instance.Command, out var duplicate)) throw new InvalidImplementationException(instance.GetType(), typeof(IClientCommand), $"Command name already registered: {instance.Command}, previous: {duplicate.GetType()}"); - } AvailableCommands[instance.Command] = instance; } + + _net.RegisterNetMessage(MsgConCmd.NAME, (int)MsgConCmd.ID, message => ProcessCommand((MsgConCmd)message)); + _net.RegisterNetMessage(MsgConCmdAck.NAME, (int)MsgConCmdAck.ID); + _net.RegisterNetMessage(MsgConCmdReg.NAME, (int)MsgConCmdReg.ID, message => HandleRegistrationRequest(message.MsgChannel)); } public void ProcessCommand(MsgConCmd message) { - string text = message.Text; - INetChannel sender = message.MsgChannel; + var text = message.Text; + var sender = message.MsgChannel; + var session = _players.GetSessionByChannel(sender); var args = new List(); + Logger.Info($"[{(int)session.Index}]{session.Name}:{text}"); + CommandParsing.ParseArguments(text, args); if (args.Count == 0) - { return; - } - string cmd = args[0]; + var cmd = args[0]; try { - IClientCommand command = AvailableCommands[cmd]; - args.RemoveAt(0); - command.Execute(this, sender, args.ToArray()); - } - catch (KeyNotFoundException) - { - SendConsoleReply(string.Format("Unknown command: '{0}'", cmd), sender); + if (availableCommands.TryGetValue(cmd, out var command)) + { + args.RemoveAt(0); + command.Execute(this, session, args.ToArray()); + } + else + SendConsoleReply(sender, $"Unknown command: '{cmd}'"); } catch (Exception e) { - SendConsoleReply(string.Format("There was an error while executing the command: {0}", e.Message), sender); + SendConsoleReply(sender, $"There was an error while executing the command: {e.Message}"); } } - public void SendConsoleReply(string text, INetChannel target) + public void SendConsoleReply(INetChannel target, string text) { var netMgr = IoCManager.Resolve(); var replyMsg = netMgr.CreateNetMessage(); diff --git a/SS14.Server/ClientConsoleHost/Commands/ChatCommands.cs b/SS14.Server/ClientConsoleHost/Commands/ChatCommands.cs new file mode 100644 index 000000000..927151f0d --- /dev/null +++ b/SS14.Server/ClientConsoleHost/Commands/ChatCommands.cs @@ -0,0 +1,135 @@ +using System.Linq; +using SS14.Server.Interfaces.Chat; +using SS14.Server.Interfaces.ClientConsoleHost; +using SS14.Server.Interfaces.Player; +using SS14.Shared; +using SS14.Shared.Console; +using SS14.Shared.Interfaces.GameObjects; +using SS14.Shared.Interfaces.GameObjects.Components; +using SS14.Shared.IoC; + +namespace SS14.Server.ClientConsoleHost.Commands +{ + internal class SayCommand : IClientCommand + { + private const char RadioChar = ':'; // first char of first argument to designate radio messages + private const int VoiceRange = 7; // how far voice goes in world units + + public string Command => "say"; + public string Description => "Send chat messages to the local channel or a specified radio channel."; + public string Help => "say [<:channel>] "; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue) + return; + + if (args.Length < 1) + return; + + var sessions = IoCManager.Resolve(); + var ents = IoCManager.Resolve(); + var chat = IoCManager.Resolve(); + + var message = args[0]; + + string text; + if (message[0] == RadioChar) + { + // all they sent was the channel + if (args.Length < 2) + return; + + var channel = args[0]; + var listArgs = args.ToList(); + listArgs.RemoveAt(0); + text = string.Concat(listArgs); + + //TODO: Parse channel and broadcast over radio. + } + else + { + text = string.Concat(args); + } + + var pos = ents.GetEntity(player.AttachedEntityUid.Value).GetComponent().LocalPosition; + var clients = sessions.GetPlayersInRange(pos, VoiceRange).Select(p => p.ConnectedClient); + + chat.DispatchMessage(clients.ToList(), ChatChannel.Local, text, player.Index); + } + } + + internal class WhisperCommand : IClientCommand + { + private const int WhisperRange = 1; // how far voice goes in world units + + public string Command => "whisper"; + public string Description => "Send chat messages to the local channel in a 1 meter radius."; + public string Help => "whisper "; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue) + return; + + var sessions = IoCManager.Resolve(); + var ents = IoCManager.Resolve(); + var chat = IoCManager.Resolve(); + + var pos = ents.GetEntity(player.AttachedEntityUid.Value).GetComponent().LocalPosition; + var clients = sessions.GetPlayersInRange(pos, WhisperRange).Select(p => p.ConnectedClient); + + chat.DispatchMessage(clients.ToList(), ChatChannel.Local, args[0], player.Index); + } + } + + internal class MeCommand : IClientCommand + { + private const int VoiceRange = 7; + + public string Command => "me"; + public string Description => "Send third person chat messages to the local channel."; + public string Help => "me "; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue) + return; + + var sessions = IoCManager.Resolve(); + var ents = IoCManager.Resolve(); + var chat = IoCManager.Resolve(); + + if (chat.ExpandEmote(args[0], player, out var self, out var other)) + { + //TODO: Dispatch in PVS range instead + var pos = ents.GetEntity(player.AttachedEntityUid.Value).GetComponent().LocalPosition; + var clients = sessions.GetPlayersInRange(pos, VoiceRange).Where(p => p != player).Select(p => p.ConnectedClient); + + chat.DispatchMessage(player.ConnectedClient, ChatChannel.Emote, self, player.Index); + chat.DispatchMessage(clients.ToList(), ChatChannel.Emote, other, player.Index); + } + else + { + //TODO: Dispatch in PVS range instead + var pos = ents.GetEntity(player.AttachedEntityUid.Value).GetComponent().LocalPosition; + var clients = sessions.GetPlayersInRange(pos, VoiceRange).Select(p => p.ConnectedClient); + + chat.DispatchMessage(clients.ToList(), ChatChannel.Emote, $"{player.Name} {args[0]}", player.Index); + } + } + } + + internal class OocCommand : IClientCommand + { + public string Command => "ooc"; + public string Description => "Send Out of Character chat messages."; + public string Help => "ooc "; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + var chat = IoCManager.Resolve(); + chat.DispatchMessage(ChatChannel.OOC, args[0], player.Index); + } + } +} diff --git a/SS14.Server/ClientConsoleHost/Commands/DrugsCommand.cs b/SS14.Server/ClientConsoleHost/Commands/DrugsCommand.cs index ff5777bc1..ef9573aa0 100644 --- a/SS14.Server/ClientConsoleHost/Commands/DrugsCommand.cs +++ b/SS14.Server/ClientConsoleHost/Commands/DrugsCommand.cs @@ -1,15 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using SS14.Server.Interfaces; -using SS14.Server.Interfaces.ClientConsoleHost; +using SS14.Server.Interfaces.ClientConsoleHost; using SS14.Server.Interfaces.Player; -using SS14.Shared.IoC; using SS14.Shared; -using SS14.Shared.Interfaces.Network; -using SS14.Shared.Network; +using SS14.Shared.IoC; namespace SS14.Server.ClientConsoleHost.Commands { @@ -19,12 +11,12 @@ namespace SS14.Server.ClientConsoleHost.Commands public string Description => "Fuck no idea what this does honestly."; public string Help => "Nope! no clue!"; - public void Execute(IClientConsoleHost host, INetChannel client, params string[] args) + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) { - foreach (IPlayerSession playerfordrugs in IoCManager.Resolve().GetAllPlayers()) + foreach (var targetPlayer in IoCManager.Resolve().GetAllPlayers()) { - playerfordrugs.AddPostProcessingEffect(PostProcessingEffectType.Acid, 60); - host.SendConsoleReply("Okay then.", client); + targetPlayer.AddPostProcessingEffect(PostProcessingEffectType.Acid, 60); + host.SendConsoleReply(player.ConnectedClient, "Okay then."); } } } diff --git a/SS14.Server/ClientConsoleHost/Commands/JoinGameCommand.cs b/SS14.Server/ClientConsoleHost/Commands/JoinGameCommand.cs new file mode 100644 index 000000000..6092200d1 --- /dev/null +++ b/SS14.Server/ClientConsoleHost/Commands/JoinGameCommand.cs @@ -0,0 +1,20 @@ +using System; +using SS14.Server.Interfaces.ClientConsoleHost; +using SS14.Server.Interfaces.Player; +using SS14.Shared; + +namespace SS14.Server.ClientConsoleHost.Commands +{ + class JoinGameCommand : IClientCommand + { + public string Command => "joingame"; + public string Description => "Moves the player from the lobby to the game."; + public string Help => String.Empty; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + if (player.Status == SessionStatus.InLobby) + player.JoinGame(); + } + } +} diff --git a/SS14.Server/ClientConsoleHost/Commands/ListCommands.cs b/SS14.Server/ClientConsoleHost/Commands/ListCommands.cs new file mode 100644 index 000000000..4bd3a640d --- /dev/null +++ b/SS14.Server/ClientConsoleHost/Commands/ListCommands.cs @@ -0,0 +1,24 @@ +using System.Text; +using SS14.Server.Interfaces.ClientConsoleHost; +using SS14.Server.Interfaces.Player; + +namespace SS14.Server.ClientConsoleHost.Commands +{ + public class ListCommands : IClientCommand + { + public string Command => "sv_list"; + public string Description => "Lists all available commands."; + public string Help => "Outputs a list of all commands which are currently available to you, and a total command number."; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + var builder = new StringBuilder("Available commands:\n"); + foreach (var command in host.AvailableCommands.Values) + { + builder.AppendFormat("{0}: {1}\n", command.Command, command.Description); + } + var message = builder.ToString().Trim(' ', '\n'); + host.SendConsoleReply(player.ConnectedClient, message); + } + } +} diff --git a/SS14.Server/ClientConsoleHost/Commands/SysCommands.cs b/SS14.Server/ClientConsoleHost/Commands/SysCommands.cs new file mode 100644 index 000000000..c3ae194c7 --- /dev/null +++ b/SS14.Server/ClientConsoleHost/Commands/SysCommands.cs @@ -0,0 +1,32 @@ +using SS14.Server.Interfaces; +using SS14.Server.Interfaces.ClientConsoleHost; +using SS14.Server.Interfaces.Player; +using SS14.Shared.IoC; + +namespace SS14.Server.ClientConsoleHost.Commands +{ + class SaveCommand : IClientCommand + { + public string Command => "save"; + public string Description => "Saves the current map to disk."; + public string Help => "save"; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + //TODO: Check permissions here. + IoCManager.Resolve().SaveGame(); + } + } + + class RestartCommand : IClientCommand + { + public string Command => "restart"; + public string Description => "restarts the current round."; + public string Help => "restart"; + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + //TODO: Check permissions here. + IoCManager.Resolve().Restart(); + } + } +} diff --git a/SS14.Server/ClientConsoleHost/Commands/Test.cs b/SS14.Server/ClientConsoleHost/Commands/Test.cs new file mode 100644 index 000000000..108cd0f55 --- /dev/null +++ b/SS14.Server/ClientConsoleHost/Commands/Test.cs @@ -0,0 +1,21 @@ +using SS14.Server.Interfaces.Chat; +using SS14.Server.Interfaces.ClientConsoleHost; +using SS14.Server.Interfaces.Player; +using SS14.Shared.Console; +using SS14.Shared.Interfaces.Network; +using SS14.Shared.IoC; + +namespace SS14.Server.ClientConsoleHost.Commands +{ + public class Test : IClientCommand + { + public string Command => "test"; + public string Description => "It's just a test bro."; + public string Help => "This thing tests stuff. If you got this message that means it worked. Hooray!"; + + public void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args) + { + IoCManager.Resolve().DispatchMessage(player.ConnectedClient, ChatChannel.Server, "Test worked!"); + } + } +} diff --git a/SS14.Server/Interfaces/Chat/IChatCommand.cs b/SS14.Server/Interfaces/Chat/IChatCommand.cs index 164c8c2d8..232f32e91 100644 --- a/SS14.Server/Interfaces/Chat/IChatCommand.cs +++ b/SS14.Server/Interfaces/Chat/IChatCommand.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using SS14.Shared.Command; +using SS14.Shared.Console; using SS14.Shared.Interfaces.Network; using SS14.Shared.IoC; using SS14.Shared.Network; diff --git a/SS14.Server/Interfaces/Chat/IChatManager.cs b/SS14.Server/Interfaces/Chat/IChatManager.cs index 580272757..8d43fd9a1 100644 --- a/SS14.Server/Interfaces/Chat/IChatManager.cs +++ b/SS14.Server/Interfaces/Chat/IChatManager.cs @@ -1,19 +1,55 @@ -using SS14.Shared; -using System.Collections.Generic; +using System.Collections.Generic; +using SS14.Server.Interfaces.Player; +using SS14.Shared.Console; using SS14.Shared.Interfaces.Network; -using SS14.Shared.IoC; -using SS14.Shared.Network; -using SS14.Shared.Network.Messages; +using SS14.Shared.Players; namespace SS14.Server.Interfaces.Chat { public interface IChatManager { - void SendChatMessage(ChatChannel channel, string text, string name, int? entityID); - void SendPrivateMessage(INetChannel client, ChatChannel channel, string text, string name, int? entityId); + /// + /// Sets up the ChatManager into a usable state. + /// void Initialize(); - void HandleNetMessage(MsgChat message); - IDictionary Commands { get; } + /// + /// Sends a chat message to a single client. + /// + /// Clients to send the message to. + /// Channel that the chat is broadcast on. + /// Text to broadcast. + /// Optional PlayerIndex of the client that the message is bound to. + /// Optional entity Uid that the message is bound to. + void DispatchMessage(INetChannel client, ChatChannel channel, string text, PlayerIndex? index = null, int? entityUid = null); + + /// + /// Sends a chat message to multiple clients. + /// + /// + /// Channel that the chat is broadcast on. + /// Text to broadcast. + /// Optional PlayerIndex of the client that the message is bound to. + /// Optional entity Uid that the message is bound to. + void DispatchMessage(List clients, ChatChannel channel, string text, PlayerIndex? index = null, int? entityUid = null); + + /// + /// Sends a chat message to all connected clients. + /// + /// Channel that the chat is broadcast on. + /// Text to broadcast. + /// Optional PlayerIndex of the client that the message is bound to. + /// Optional entity Uid that the message is bound to. + void DispatchMessage(ChatChannel channel, string text, PlayerIndex? index = null, int? entityUid = null); + + /// + /// Checks a string to see if it is an emote, and expands it to self/other chat. + /// + /// String to check. + /// Player that the emote is acting on. + /// First person emote text. + /// Third person emote text. + /// If the string was a valid emote. + bool ExpandEmote(string input, IPlayerSession session, out string self, out string other); } } diff --git a/SS14.Server/Interfaces/ClientConsoleHost/IClientCommand.cs b/SS14.Server/Interfaces/ClientConsoleHost/IClientCommand.cs index a098b7bbc..713952bed 100644 --- a/SS14.Server/Interfaces/ClientConsoleHost/IClientCommand.cs +++ b/SS14.Server/Interfaces/ClientConsoleHost/IClientCommand.cs @@ -1,16 +1,13 @@ -using SS14.Shared.Command; -using SS14.Shared.IoC; -using System.Collections.Generic; -using SS14.Shared.Interfaces.Network; -using SS14.Shared.Network; +using SS14.Server.Interfaces.Player; +using SS14.Shared.Console; namespace SS14.Server.Interfaces.ClientConsoleHost { /// - /// A command, executed from the debug console of a client. + /// A command, executed from the debug console of a client. /// public interface IClientCommand : ICommand { - void Execute(IClientConsoleHost host, INetChannel client, params string[] args); + void Execute(IClientConsoleHost host, IPlayerSession player, params string[] args); } } diff --git a/SS14.Server/Interfaces/ClientConsoleHost/IClientConsoleHost.cs b/SS14.Server/Interfaces/ClientConsoleHost/IClientConsoleHost.cs index abbb17cd0..ba7469375 100644 --- a/SS14.Server/Interfaces/ClientConsoleHost/IClientConsoleHost.cs +++ b/SS14.Server/Interfaces/ClientConsoleHost/IClientConsoleHost.cs @@ -6,10 +6,11 @@ namespace SS14.Server.Interfaces.ClientConsoleHost { public interface IClientConsoleHost { - void Initialize(); IDictionary AvailableCommands { get; } + + void Initialize(); void ProcessCommand(MsgConCmd message); - void SendConsoleReply(string text, INetChannel target); + void SendConsoleReply(INetChannel target, string text); void HandleRegistrationRequest(INetChannel senderConnection); } } diff --git a/SS14.Server/Interfaces/Player/IPlayerSession.cs b/SS14.Server/Interfaces/Player/IPlayerSession.cs index 58868fc4f..9573e1f87 100644 --- a/SS14.Server/Interfaces/Player/IPlayerSession.cs +++ b/SS14.Server/Interfaces/Player/IPlayerSession.cs @@ -19,6 +19,7 @@ namespace SS14.Server.Interfaces.Player PlayerIndex Index { get; } void JoinLobby(); + void JoinGame(); void SetName(string name); diff --git a/SS14.Server/Interfaces/ServerConsole/IConsoleCommand.cs b/SS14.Server/Interfaces/ServerConsole/IConsoleCommand.cs index 51bcef44b..c5dac51ab 100644 --- a/SS14.Server/Interfaces/ServerConsole/IConsoleCommand.cs +++ b/SS14.Server/Interfaces/ServerConsole/IConsoleCommand.cs @@ -1,4 +1,4 @@ -using SS14.Shared.Command; +using SS14.Shared.Console; namespace SS14.Server.Interfaces.ServerConsole { diff --git a/SS14.Server/Player/PlayerSession.cs b/SS14.Server/Player/PlayerSession.cs index af69b2e1d..bd3cd9ae2 100644 --- a/SS14.Server/Player/PlayerSession.cs +++ b/SS14.Server/Player/PlayerSession.cs @@ -96,9 +96,6 @@ namespace SS14.Server.Player var messageType = message.MsgType; switch (messageType) { - case PlayerSessionMessage.Verb: - HandleVerb(message); - break; case PlayerSessionMessage.JoinLobby: JoinLobby(); break; @@ -153,33 +150,7 @@ namespace SS14.Server.Player net.ServerSendMessage(message, ConnectedClient); } - - private void HandleVerb(MsgSession message) - { - DispatchVerb(message.Verb, message.Uid); - } - - private void DispatchVerb(string verb, int uid) - { - //Handle global verbs - Logger.Log("Verb: " + verb + " from " + uid, LogLevel.Debug); - - if (uid == 0) - { - switch (verb) - { - case "joingame": - JoinGame(); - break; - case "toxins": - //Need debugging function to add more gas - case "save": - _playerManager.Server.SaveGame(); - break; - } - } - } - + private void SetAttachedEntityName() { if (Name != null && attachedEntity != null) @@ -208,11 +179,7 @@ namespace SS14.Server.Player { if (ConnectedClient == null || Status == SessionStatus.InGame || _playerManager.RunLevel != RunLevel.Game) return; - - var net = IoCManager.Resolve(); - var message = net.CreateNetMessage(); - net.ServerSendMessage(message, ConnectedClient); - + Status = SessionStatus.InGame; UpdatePlayerState(); } diff --git a/SS14.Server/Round/Gamemodes.cs b/SS14.Server/Round/Gamemodes.cs index 0e492e77a..59272aa56 100644 --- a/SS14.Server/Round/Gamemodes.cs +++ b/SS14.Server/Round/Gamemodes.cs @@ -1,8 +1,8 @@ -using SS14.Server.Interfaces; +using SS14.Server.Interfaces; using SS14.Server.Interfaces.Chat; using SS14.Server.Interfaces.GameMode; using SS14.Server.Interfaces.Player; -using SS14.Shared; +using SS14.Shared.Console; using SS14.Shared.IoC; namespace SS14.Server.Round @@ -55,14 +55,12 @@ namespace SS14.Server.Round public virtual void PlayerLeft(IPlayerSession player) { - IoCManager.Resolve().SendChatMessage(ChatChannel.Server, "Gamemode: Player left!", null, - player.AttachedEntityUid); + IoCManager.Resolve().DispatchMessage(ChatChannel.Server, "Gamemode: Player left!", player.Index); } public virtual void PlayerDied(IPlayerSession player) { - IoCManager.Resolve().SendChatMessage(ChatChannel.Server, "Gamemode: Player died!", null, - player.AttachedEntityUid); + IoCManager.Resolve().DispatchMessage(ChatChannel.Server, "Gamemode: Player died!", player.Index); } public virtual void Begin() @@ -82,4 +80,4 @@ namespace SS14.Server.Round #endregion } -} \ No newline at end of file +} diff --git a/SS14.Server/SS14.Server.csproj b/SS14.Server/SS14.Server.csproj index 3155a4e91..5cb016ba5 100644 --- a/SS14.Server/SS14.Server.csproj +++ b/SS14.Server/SS14.Server.csproj @@ -124,6 +124,9 @@ + + + @@ -143,10 +146,6 @@ PreserveNewest - - Code - PreserveNewest - PreserveNewest @@ -156,8 +155,8 @@ - - + + @@ -228,4 +227,4 @@ - + \ No newline at end of file diff --git a/SS14.Shared/ChatConfig.cs b/SS14.Shared/ChatConfig.cs deleted file mode 100644 index 278ccf114..000000000 --- a/SS14.Shared/ChatConfig.cs +++ /dev/null @@ -1,46 +0,0 @@ -namespace SS14.Shared -{ - public enum ChatChannel - { - /// - /// Default, unspecified - /// - Default, - /// - /// Players in the lobby chat - /// - Lobby, - /// - /// Chat heard by players within earshot - /// - Ingame, - /// - /// Messages from the server - /// - Server, - /// - /// Damage messages - /// - Damage, - /// - /// Messages that are sent by the player directly - /// - Player, - /// - /// Radio messages - /// - Radio, - /// - /// Emotes - /// - Emote, - /// - /// Out-of-character channel - /// - OOC, - /// - /// Things the character can see - /// - Visual, - } -} \ No newline at end of file diff --git a/SS14.Shared/Console/ChatChannel.cs b/SS14.Shared/Console/ChatChannel.cs new file mode 100644 index 000000000..7c824664f --- /dev/null +++ b/SS14.Shared/Console/ChatChannel.cs @@ -0,0 +1,50 @@ +namespace SS14.Shared.Console +{ + public enum ChatChannel + { + /// + /// Default, unspecified + /// + Default = 0, + + /// + /// Chat heard by players within earshot + /// + Local, + + /// + /// Messages from the server + /// + Server, + + /// + /// Damage messages + /// + Damage, + + /// + /// Messages that are sent by the player directly + /// + Player, + + /// + /// Radio messages + /// + Radio, + + /// + /// Emotes + /// + Emote, + + /// + /// Out-of-character channel + /// + OOC, + + /// + /// Things the character can see + /// + Visual + } +} diff --git a/SS14.Shared/Console/ICommand.cs b/SS14.Shared/Console/ICommand.cs new file mode 100644 index 000000000..d2b0f79da --- /dev/null +++ b/SS14.Shared/Console/ICommand.cs @@ -0,0 +1,34 @@ +namespace SS14.Shared.Console +{ + /// + /// Basic abstract to handle console commands. + /// Note that there is no Execute() function, this is due to chat & client commands needing a client, + /// While client-side and server console commands don't. + /// + public interface ICommand + { + /// + /// Name of the command. + /// + /// + /// A string as identifier for this command. + /// + string Command { get; } + + /// + /// Short description of the command. + /// + /// + /// String printed as short summary in the "help" command. + /// + string Description { get; } + + /// + /// Extended description for the command. + /// + /// + /// String printed as summary when "help Command" is used. + /// + string Help { get; } + } +} diff --git a/SS14.Shared/ConsoleCommand.cs b/SS14.Shared/ConsoleCommand.cs deleted file mode 100644 index d405daf15..000000000 --- a/SS14.Shared/ConsoleCommand.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Basic abstract to handle console commands. -// Note that there is no Execute() function, this is due to chat & client commands needing a client, -// While client-side and server console commands don't. -namespace SS14.Shared.Command -{ - public interface ICommand - { - /// - /// Name of the command. - /// - /// - /// A string as indentifier for this command. - /// - string Command { get; } - - /// - /// Short description of the command. - /// - /// - /// String printed as short summary in the "help" command. - /// - string Description { get; } - - /// - /// Extended description for the command. - /// - /// - /// String printed as summary when "help Command" is used. - /// - string Help { get; } - } -} \ No newline at end of file diff --git a/SS14.Shared/Log/LogManager.cs b/SS14.Shared/Log/LogManager.cs index eb77c46ef..18119df78 100644 --- a/SS14.Shared/Log/LogManager.cs +++ b/SS14.Shared/Log/LogManager.cs @@ -1,5 +1,4 @@ using SS14.Shared.Interfaces.Log; -using SS14.Shared.IoC; using System; namespace SS14.Shared.Log @@ -40,10 +39,10 @@ namespace SS14.Shared.Log string name = LogLevelToName(level); ConsoleColor color = LogLevelToConsoleColor(level); - Console.ForegroundColor = color; - Console.Write(name); - Console.ResetColor(); - Console.WriteLine(": {0}", message); + System.Console.ForegroundColor = color; + System.Console.Write(name); + System.Console.ResetColor(); + System.Console.WriteLine(": {0}", message); } // If you make either of these methods public. diff --git a/SS14.Shared/Maths/Angle.cs b/SS14.Shared/Maths/Angle.cs index 7fed4456f..c5078b07a 100644 --- a/SS14.Shared/Maths/Angle.cs +++ b/SS14.Shared/Maths/Angle.cs @@ -44,7 +44,7 @@ namespace SS14.Shared.Maths if (ang < 0.0f) // convert -PI > PI to 0 > 2PI ang += 2 * (float) Math.PI; - return (Direction) Math.Floor((ang + Offset) / Segment); + return (Direction) (Math.Floor((ang + Offset) / Segment) % 8); } /// diff --git a/SS14.Shared/Network/Messages/MsgChat.cs b/SS14.Shared/Network/Messages/MsgChat.cs index 81345fa23..cd31164d2 100644 --- a/SS14.Shared/Network/Messages/MsgChat.cs +++ b/SS14.Shared/Network/Messages/MsgChat.cs @@ -1,5 +1,7 @@ using Lidgren.Network; +using SS14.Shared.Console; using SS14.Shared.Interfaces.Network; +using SS14.Shared.Players; namespace SS14.Shared.Network.Messages { @@ -15,6 +17,7 @@ namespace SS14.Shared.Network.Messages public ChatChannel Channel { get; set; } public string Text { get; set; } + public PlayerIndex? Index { get; set; } public int? EntityId { get; set; } public override void ReadFromBuffer(NetIncomingMessage buffer) @@ -22,6 +25,12 @@ namespace SS14.Shared.Network.Messages Channel = (ChatChannel)buffer.ReadByte(); Text = buffer.ReadString(); + var index = buffer.ReadInt32(); + if (index == -1) + Index = null; + else + Index = new PlayerIndex(index); + var id = buffer.ReadInt32(); if (id == -1) EntityId = null; @@ -33,6 +42,12 @@ namespace SS14.Shared.Network.Messages { buffer.Write((byte)Channel); buffer.Write(Text); + + if (Index == null) + buffer.Write(-1); + else + buffer.Write(Index.Value); + if (EntityId == null) buffer.Write(-1); else diff --git a/SS14.Shared/Network/Messages/MsgJoinGame.cs b/SS14.Shared/Network/Messages/MsgJoinGame.cs deleted file mode 100644 index 0a1bc1aff..000000000 --- a/SS14.Shared/Network/Messages/MsgJoinGame.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Lidgren.Network; -using SS14.Shared.Interfaces.Network; - -namespace SS14.Shared.Network.Messages -{ - public class MsgJoinGame : NetMessage - { - #region REQUIRED - public static readonly NetMessages ID = NetMessages.JoinGame; - public static readonly MsgGroups GROUP = MsgGroups.Command; - - public static readonly string NAME = ID.ToString(); - public MsgJoinGame(INetChannel channel) : base(NAME, GROUP, ID) { } - #endregion - - - public override void ReadFromBuffer(NetIncomingMessage buffer) - { - } - - public override void WriteToBuffer(NetOutgoingMessage buffer) - { - } - } -} diff --git a/SS14.Shared/Network/Messages/MsgRestartReq.cs b/SS14.Shared/Network/Messages/MsgRestartReq.cs deleted file mode 100644 index ddc3d82cd..000000000 --- a/SS14.Shared/Network/Messages/MsgRestartReq.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Lidgren.Network; -using SS14.Shared.Interfaces.Network; - -namespace SS14.Shared.Network.Messages -{ - public class MsgRestartReq : NetMessage - { - #region REQUIRED - public static readonly NetMessages ID = NetMessages.ForceRestart; - public static readonly MsgGroups GROUP = MsgGroups.Command; - - public static readonly string NAME = ID.ToString(); - public MsgRestartReq(INetChannel channel) : base(NAME, GROUP, ID) { } - #endregion - - - public override void ReadFromBuffer(NetIncomingMessage buffer) - { - } - - public override void WriteToBuffer(NetOutgoingMessage buffer) - { - } - } -} diff --git a/SS14.Shared/Network/Messages/MsgSession.cs b/SS14.Shared/Network/Messages/MsgSession.cs index 9f53d79c5..a16728abb 100644 --- a/SS14.Shared/Network/Messages/MsgSession.cs +++ b/SS14.Shared/Network/Messages/MsgSession.cs @@ -16,7 +16,6 @@ namespace SS14.Shared.Network.Messages #endregion public PlayerSessionMessage MsgType { get; set; } - public string Verb { get; set; } public int Uid { get; set; } public PostProcessingEffectType PpType { get; set; } public float PpDuration { get; set; } @@ -27,10 +26,6 @@ namespace SS14.Shared.Network.Messages switch (MsgType) { - case PlayerSessionMessage.Verb: - Verb = buffer.ReadString(); - Uid = buffer.ReadInt32(); - break; case PlayerSessionMessage.AttachToEntity: Uid = buffer.ReadInt32(); break; @@ -46,10 +41,6 @@ namespace SS14.Shared.Network.Messages buffer.Write((byte)MsgType); switch (MsgType) { - case PlayerSessionMessage.Verb: - buffer.Write(Verb); - buffer.Write(Uid); - break; case PlayerSessionMessage.AttachToEntity: buffer.Write(Uid); break; diff --git a/SS14.Shared/NetworkEnums.cs b/SS14.Shared/NetworkEnums.cs index 4981073a7..c4716669e 100644 --- a/SS14.Shared/NetworkEnums.cs +++ b/SS14.Shared/NetworkEnums.cs @@ -16,7 +16,6 @@ StringTableEntry, // S>C An entry into the string table. // Console Commands - LobbyChat, // C>S Does nothing atm, Obsolete? ChatMessage, // C<>S Contains all of the chat messages. PlayerSessionMessage, // C>S Tells (lol.) the server about state changes. ConsoleCommand, // C>S Sends the server a console command. @@ -30,8 +29,6 @@ // misc stuff that will prob be removed PlacementManagerMessage,// S<>C Contains all placement messages. PlayerUiMessage, // S>C Sends a user interface message. - JoinGame, // S>C Tells the client to join the game. - ForceRestart, // C>S Tells (lol.) the server to restart. // entity stuff EntityMessage, // S<>C Contains all entity messages. @@ -120,7 +117,6 @@ public enum PlayerSessionMessage { AttachToEntity, - Verb, JoinLobby, AddPostProcessingEffect } diff --git a/SS14.Shared/SS14.Shared.csproj b/SS14.Shared/SS14.Shared.csproj index 4e01cd641..ff06b86c3 100644 --- a/SS14.Shared/SS14.Shared.csproj +++ b/SS14.Shared/SS14.Shared.csproj @@ -128,7 +128,7 @@ - + @@ -206,13 +206,11 @@ - - @@ -255,7 +253,7 @@ - + @@ -375,6 +373,10 @@ False + + + False + diff --git a/SS14.UnitTesting/Shared/Maths/Angle_Test.cs b/SS14.UnitTesting/Shared/Maths/Angle_Test.cs index df4a19c4a..5d7a073ef 100644 --- a/SS14.UnitTesting/Shared/Maths/Angle_Test.cs +++ b/SS14.UnitTesting/Shared/Maths/Angle_Test.cs @@ -20,7 +20,9 @@ namespace SS14.UnitTesting.Shared.Maths (-1, 0, Direction.West, System.Math.PI), (-1, -1, Direction.SouthWest, -3 * System.Math.PI / 4.0), (0, -1, Direction.South, -System.Math.PI / 2.0), - (1, -1, Direction.SouthEast, -System.Math.PI / 4.0) + (1, -1, Direction.SouthEast, -System.Math.PI / 4.0), + + (0.92387953251128674f, -0.38268343236508978f, Direction.East, -System.Math.PI / 8.0) }; [Test]