public static void AddMessageToCache(ChatMessage message, bool lastEntry)
        {
            MessageCache.Add(message);

            if (lastEntry)
            {
                StringBuilder content = new StringBuilder();
                foreach (ChatMessage chatMessage in MessageCache.OrderByDescending(m => m.Date))
                    content.AppendLine(string.Format("[{0:yyyy-MM-dd HH:mm:ss}] {1}: {2}", chatMessage.Date, chatMessage.Sender.PlayerName, chatMessage.Message));

                MyAPIGateway.Utilities.ShowMissionScreen("Chat History", "Displayed messages: ", MessageCache.Count.ToString(), content.ToString());

                MessageCache.Clear();
            }
        }
        public void LogPrivateMessage(ChatMessage chatMessage, ulong receiver)
        {
            if (!Config.LogPrivateMessages)
                return;

            List<PrivateConversation> senderConversations = PrivateConversations.FindAll(c => c.Participants.Exists(p => p.SteamId == chatMessage.Sender.SteamId));

            var pm = new PrivateMessage()
            {
                Sender = chatMessage.Sender.SteamId,
                Receiver = receiver,
                Date = chatMessage.Date,
                Text = chatMessage.Text
            };

            if (senderConversations.Exists(c => c.Participants.Exists(p => p.SteamId == receiver)))
            {
                PrivateConversation conversation = senderConversations.Find(c => c.Participants.Exists(p => p.SteamId == receiver));
                conversation.Messages.Add(pm);
            }
            else
            {
                List<IMyPlayer> players = new List<IMyPlayer>();
                MyAPIGateway.Players.GetPlayers(players, p => p != null);
                var senderPlayer = players.FirstOrDefault(p => p.SteamUserId == chatMessage.Sender.SteamId);
                var receiverPlayer = players.FirstOrDefault(p => p.SteamUserId == receiver);

                PrivateConversations.Add(new PrivateConversation()
                {
                    Participants = new List<Player>(new Player[] {
                            new Player() {
                                SteamId = senderPlayer.SteamUserId,
                                PlayerName = senderPlayer.DisplayName
                            },
                            new Player(){
                                SteamId = receiverPlayer.SteamUserId,
                                PlayerName = receiverPlayer.DisplayName
                            }}),
                    Messages = new List<PrivateMessage>(new PrivateMessage[] { pm })
                });
            }
        }
 public void LogGlobalMessage(ChatMessage chatMessage)
 {
     ChatMessages.Add(chatMessage);
 }
        /// <summary>
        /// Client side execution of the actions defined in the data
        /// </summary>
        /// <param name="dataString"></param>
        public static void ProcessClientData(string dataString)
        {
            var parsedData = Parse(dataString);
            foreach (KeyValuePair<string, string> entry in parsedData)
            {
                Logger.Debug(string.Format("[Client]Processing KeyValuePair - Key: {0}, Value: {1}", entry.Key, entry.Value));
                switch (entry.Key)
                {
                    #region motd
                    case ConnectionKeys.MotdHeadLine:
                        CommandMessageOfTheDay.HeadLine = entry.Value;
                        break;
                    case ConnectionKeys.MotdShowInChat:
                        bool showInChat = CommandMessageOfTheDay.ShowInChat;
                        if (bool.TryParse(entry.Value, out showInChat))
                        {
                            CommandMessageOfTheDay.ShowInChat = showInChat;
                        }
                        break;
                    case ConnectionKeys.MessageOfTheDay: //motd
                        CommandMessageOfTheDay.Content = entry.Value;
                        if (!CommandMessageOfTheDay.Received)
                        {
                            CommandMessageOfTheDay.Received = true;
                            if (CommandMessageOfTheDay.ShowOnReceive && !String.IsNullOrEmpty(CommandMessageOfTheDay.Content))
                                CommandMessageOfTheDay.ShowMotd();
                            break;
                        }
                        MyAPIGateway.Utilities.ShowMessage("Motd", "The message of the day was updated just now. To see what is new use '/motd'.");
                        break;
                    #endregion

                    #region misc
                    case ConnectionKeys.AdminNotification:
                        ChatCommandLogic.Instance.AdminNotification = entry.Value;
                        if (CommandMessageOfTheDay.ShowOnReceive)
                            MyAPIGateway.Utilities.ShowMissionScreen("Admin Message System", "Error", null, ChatCommandLogic.Instance.AdminNotification, null, null);
                        break;
                    case ConnectionKeys.PrivateMessage: //pm
                        IMyPlayer sender = null;
                        string senderName = null;
                        string message = null;
                        foreach (KeyValuePair<string, string> pmEntry in Parse(entry.Value))
                        {
                            Logger.Debug(string.Format("[Client]Processing PM KeyValuePair - Key: {0}, Value: {1}", pmEntry.Key, pmEntry.Value));
                            switch (pmEntry.Key)
                            {
                                case ConnectionKeys.ChatSender:
                                    ulong senderSteamId;
                                    if (ulong.TryParse(pmEntry.Value, out senderSteamId) && senderSteamId != 0)
                                    {
                                        MyAPIGateway.Players.TryGetPlayer(senderSteamId, out sender);
                                    }
                                    break;
                                case ConnectionKeys.ChatSenderName:
                                    senderName = pmEntry.Value;
                                    break;
                                case ConnectionKeys.ChatMessage:
                                    message = pmEntry.Value;
                                    break;
                            }
                        }

                        if (sender != null)
                        {
                            senderName = sender.DisplayName;
                            CommandPrivateMessage.LastWhisperId = sender.SteamUserId;
                        }

                        MyAPIGateway.Utilities.ShowMessage(string.Format("{0}{1}", senderName, senderName.Equals("Server") ? "" : " whispers"), message);
                        break;
                    case ConnectionKeys.ForceKick:
                        ulong steamId;
                        if (ulong.TryParse(entry.Value, out steamId) && steamId == MyAPIGateway.Session.Player.SteamUserId)
                            CommandForceKick.DropPlayer = true;
                        break;
                    case ConnectionKeys.LogPrivateMessages:
                        bool logPms;
                        if (bool.TryParse(entry.Value, out logPms))
                            CommandPrivateMessage.LogPrivateMessages = logPms;
                        break;
                    case ConnectionKeys.IncomingMessageParts:
                        int parts;
                        if (int.TryParse(entry.Value, out parts))
                        {
                            if (parts < 0)
                                break;
                            client_IncomingMessages = parts;
                            client_MessageCache.Clear();
                        }
                        break;
                    case ConnectionKeys.Chat:
                        bool lastEntry = false;
                        ChatMessage chatMessage = new ChatMessage();
                        foreach (KeyValuePair<string, string> pair in Parse(entry.Value))
                        {
                            switch (pair.Key)
                            {
                                case ConnectionKeys.ListEntry:
                                    foreach (KeyValuePair<string, string> chatMsgPair in Parse(pair.Value))
                                    {
                                        ulong msgSenderSteamId;
                                        switch (chatMsgPair.Key)
                                        {
                                            case ConnectionKeys.ChatMessage:
                                                chatMessage.Message = chatMsgPair.Value;
                                                break;
                                            case ConnectionKeys.ChatSender:
                                                if (ulong.TryParse(chatMsgPair.Value, out msgSenderSteamId))
                                                    chatMessage.Sender.SteamId = msgSenderSteamId;
                                                break;
                                            case ConnectionKeys.ChatSenderName:
                                                chatMessage.Sender.PlayerName = chatMsgPair.Value;
                                                break;
                                            case ConnectionKeys.ChatDate:
                                                chatMessage.Date = DateTime.Parse(chatMsgPair.Value);
                                                break;
                                        }
                                    }
                                    break;
                                case ConnectionKeys.ListLastEntry:
                                    lastEntry = true;
                                    break;
                            }
                        }

                        CommandChatHistory.AddMessageToCache(chatMessage, lastEntry);
                        break;
                    #endregion

                    #region session settings
                    case ConnectionKeys.CargoShips:
                        bool enableCargoShips;
                        if (bool.TryParse(entry.Value, out enableCargoShips))
                        {
                            //already set by server
                            if (!MyAPIGateway.Session.Player.IsHost())
                                MyAPIGateway.Session.GetCheckpoint("null").CargoShipsEnabled = enableCargoShips;
                            if (MyAPIGateway.Session.Player.IsAdmin())
                                MyAPIGateway.Utilities.ShowMessage("Server CargoShips", enableCargoShips ? "On" : "Off");
                        }
                        break;
                    case ConnectionKeys.CopyPaste:
                        bool enableCopyPaste;
                        if (bool.TryParse(entry.Value, out enableCopyPaste))
                        {
                            if (!MyAPIGateway.Session.Player.IsHost())
                                MyAPIGateway.Session.GetCheckpoint("null").EnableCopyPaste = enableCopyPaste;
                            if (MyAPIGateway.Session.Player.IsAdmin())
                                MyAPIGateway.Utilities.ShowMessage("Server CopyPaste", enableCopyPaste ? "On" : "Off");
                        }
                        break;
                    case ConnectionKeys.Creative:
                        bool enableCreative;
                        if (bool.TryParse(entry.Value, out enableCreative))
                        {
                            if (!MyAPIGateway.Session.Player.IsHost())
                            {
                                MyGameModeEnum gameMode = enableCreative ? MyGameModeEnum.Creative : MyGameModeEnum.Survival;
                                MyAPIGateway.Session.GetCheckpoint("null").GameMode = gameMode;
                            }
                            if (MyAPIGateway.Session.Player.IsAdmin())
                                MyAPIGateway.Utilities.ShowMessage("Server Creative", enableCreative ? "On" : "Off");
                        }
                        break;
                    case ConnectionKeys.Spectator:
                        bool enableSpectator;
                        if (bool.TryParse(entry.Value, out enableSpectator))
                        {
                            if (!MyAPIGateway.Session.Player.IsHost())
                            {
                                MyAPIGateway.Session.GetCheckpoint("null").Settings.EnableSpectator = enableSpectator;
                            }
                            if (MyAPIGateway.Session.Player.IsAdmin())
                                MyAPIGateway.Utilities.ShowMessage("Server Spectator", enableSpectator ? "On" : "Off");
                        }
                        break;
                    case ConnectionKeys.Weapons:
                        bool enableWeapons;
                        if (bool.TryParse(entry.Value, out enableWeapons))
                        {
                            if (!MyAPIGateway.Session.Player.IsHost())
                            {
                                MyAPIGateway.Session.GetCheckpoint("null").WeaponsEnabled = enableWeapons;
                            }
                            if (MyAPIGateway.Session.Player.IsAdmin())
                                MyAPIGateway.Utilities.ShowMessage("Server Weapons", enableWeapons ? "On" : "Off");
                        }
                        break;
                    #endregion

                    #region permissions
                    case ConnectionKeys.CommandLevel:
                        uint level;
                        string[] values = entry.Value.Split(':');

                        if (values.Length < 2)
                            break;

                        if (uint.TryParse(values[1], out level))
                        {
                            ChatCommandService.UpdateCommandSecurity(values[0], level);
                        }
                        break;
                    case ConnectionKeys.CommandList:
                        string commandName = "";
                        string commandLevel = "";
                        bool newCommandList = false;
                        bool showCommandList = false;

                        foreach (KeyValuePair<string, string> pair in Parse(entry.Value))
                        {
                            switch (pair.Key)
                            {
                                case ConnectionKeys.ListEntry:
                                    commandName = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryLevel:
                                    commandLevel = pair.Value;
                                    break;
                                case ConnectionKeys.NewList:
                                    newCommandList = true;
                                    break;
                                case ConnectionKeys.ListLastEntry:
                                    showCommandList = true;
                                    break;
                            }
                        }

                        CommandPermission.AddToCommandCache(commandName, commandLevel, showCommandList, newCommandList);
                        break;
                    case ConnectionKeys.PlayerLevel:
                        uint newUserSecurity;
                        if (uint.TryParse(entry.Value, out newUserSecurity))
                            ChatCommandService.UserSecurity = newUserSecurity;
                        ChatCommandLogic.Instance.BlockCommandExecution = false;
                        break;
                    case ConnectionKeys.PlayerList:
                        string playerName = "";
                        string playerLevel = "";
                        string playerListEntrySteamId = "";
                        string extensions = "";
                        string restrictions = "";
                        bool usePlayerLevel = false;
                        bool newPlayerList = false;
                        bool showPlayerList = false;

                        foreach (KeyValuePair<string, string> pair in Parse(entry.Value))
                        {
                            switch (pair.Key)
                            {
                                case ConnectionKeys.ListEntry:
                                    playerName = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryLevel:
                                    playerLevel = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryId:
                                    playerListEntrySteamId = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryExtensions:
                                    extensions = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryRestrictions:
                                    restrictions = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryUsePlayerLevel:
                                    usePlayerLevel = true;
                                    break;
                                case ConnectionKeys.NewList:
                                    newPlayerList = true;
                                    break;
                                case ConnectionKeys.ListLastEntry:
                                    showPlayerList = true;
                                    break;
                            }
                        }

                        CommandPermission.AddToPlayerCache(playerName, playerLevel, playerListEntrySteamId, extensions, restrictions, usePlayerLevel, showPlayerList, newPlayerList);
                        break;
                    case ConnectionKeys.GroupList:
                        string groupName = "";
                        string groupLevel = "";
                        string members = "";
                        bool newGroupList = false;
                        bool showGroupList = false;

                        foreach (KeyValuePair<string, string> pair in Parse(entry.Value))
                        {
                            switch (pair.Key)
                            {
                                case ConnectionKeys.ListEntry:
                                    groupName = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryLevel:
                                    groupLevel = pair.Value;
                                    break;
                                case ConnectionKeys.PermEntryMembers:
                                    members = pair.Value;
                                    break;
                                case ConnectionKeys.NewList:
                                    newGroupList = true;
                                    break;
                                case ConnectionKeys.ListLastEntry:
                                    showGroupList = true;
                                    break;
                            }
                        }

                        CommandPermission.AddToGroupCache(groupName, groupLevel, members, showGroupList, newGroupList);
                        break;
                    #endregion

                    #region sync
                    case ConnectionKeys.Smite:
                        CommandPlayerSmite.Smite(MyAPIGateway.Session.Player);
                        break;
                    case ConnectionKeys.StopAndMove:
                        {
                            string[] properties = entry.Value.Split(':');
                            long entityId;
                            double posX;
                            double posY;
                            double posZ;

                            if (properties.Length > 3 && long.TryParse(properties[0], out entityId) && MyAPIGateway.Entities.EntityExists(entityId)
                                && double.TryParse(properties[1], out posX) && double.TryParse(properties[2], out posY) && double.TryParse(properties[3], out posZ))
                            {
                                var entity = MyAPIGateway.Entities.GetEntityById(entityId);
                                if (entity != null)
                                {
                                    entity.Stop();
                                    var destination = new Vector3D(posX, posY, posZ);

                                    // This still is not syncing properly. Called on the server, it does not show correctly on the client.
                                    entity.SetPosition(destination);
                                }
                            }
                        }
                        break;
                    case ConnectionKeys.Delete:
                        {
                            long entityId;
                            if (long.TryParse(entry.Value, out entityId) && MyAPIGateway.Entities.EntityExists(entityId))
                            {
                                var entity = MyAPIGateway.Entities.GetEntityById(entityId);
                                if (entity != null)
                                    entity.Delete();  // Doesn't sync from server to clients, or client to server.
                            }
                        }
                        break;

                    #endregion
                }
                Logger.Debug(string.Format("[Client]Finished processing KeyValuePair for Key: {0}", entry.Key));
            }
        }
 public void LogGlobalMessage(ChatMessage chatMessage)
 {
     chatMessage.Date = DateTime.Now;
     ChatMessages.Add(chatMessage);
 }