示例#1
0
 public OrderMessageInfo(int orderIndex, Order orderPrefab, string orderOption, int?orderOptionIndex, Character targetCharacter, Order.OrderTargetType targetType, Entity targetEntity, OrderTarget targetPosition, int?wallSectionIndex, int orderPriority)
 {
     OrderIndex       = orderIndex;
     OrderPrefab      = orderPrefab;
     OrderOption      = orderOption;
     OrderOptionIndex = orderOptionIndex;
     TargetCharacter  = targetCharacter;
     TargetType       = targetType;
     TargetEntity     = targetEntity;
     TargetPosition   = targetPosition;
     WallSectionIndex = wallSectionIndex;
     Priority         = orderPriority;
 }
        public static void ServerRead(IReadMessage msg, Client c)
        {
            c.KickAFKTimer = 0.0f;

            UInt16          ID   = msg.ReadUInt16();
            ChatMessageType type = (ChatMessageType)msg.ReadByte();
            string          txt;

            Character        orderTargetCharacter = null;
            Entity           orderTargetEntity    = null;
            OrderChatMessage orderMsg             = null;
            OrderTarget      orderTargetPosition  = null;

            Order.OrderTargetType orderTargetType = Order.OrderTargetType.Entity;
            int?wallSectionIndex = null;

            if (type == ChatMessageType.Order)
            {
                var orderMessageInfo = OrderChatMessage.ReadOrder(msg);
                if (orderMessageInfo.OrderIndex < 0 || orderMessageInfo.OrderIndex >= Order.PrefabList.Count)
                {
                    DebugConsole.ThrowError($"Invalid order message from client \"{c.Name}\" - order index out of bounds ({orderMessageInfo.OrderIndex}).");
                    if (NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID))
                    {
                        c.LastSentChatMsgID = ID;
                    }
                    return;
                }
                orderTargetCharacter = orderMessageInfo.TargetCharacter;
                orderTargetEntity    = orderMessageInfo.TargetEntity;
                orderTargetPosition  = orderMessageInfo.TargetPosition;
                orderTargetType      = orderMessageInfo.TargetType;
                wallSectionIndex     = orderMessageInfo.WallSectionIndex;
                var    orderPrefab = orderMessageInfo.OrderPrefab ?? Order.PrefabList[orderMessageInfo.OrderIndex];
                string orderOption = orderMessageInfo.OrderOption ??
                                     (orderMessageInfo.OrderOptionIndex == null || orderMessageInfo.OrderOptionIndex < 0 || orderMessageInfo.OrderOptionIndex >= orderPrefab.Options.Length ?
                                      "" : orderPrefab.Options[orderMessageInfo.OrderOptionIndex.Value]);
                orderMsg = new OrderChatMessage(orderPrefab, orderOption, orderMessageInfo.Priority, orderTargetPosition ?? orderTargetEntity as ISpatialEntity, orderTargetCharacter, c.Character)
                {
                    WallSectionIndex = wallSectionIndex
                };
                txt = orderMsg.Text;
            }
            else
            {
                txt = msg.ReadString() ?? "";
            }

            if (!NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID))
            {
                return;
            }

            c.LastSentChatMsgID = ID;

            if (txt.Length > MaxLength)
            {
                txt = txt.Substring(0, MaxLength);
            }

            c.LastSentChatMessages.Add(txt);
            if (c.LastSentChatMessages.Count > 10)
            {
                c.LastSentChatMessages.RemoveRange(0, c.LastSentChatMessages.Count - 10);
            }

            float similarity = 0.0f;

            for (int i = 0; i < c.LastSentChatMessages.Count; i++)
            {
                float closeFactor = 1.0f / (c.LastSentChatMessages.Count - i);

                if (string.IsNullOrEmpty(txt))
                {
                    similarity += closeFactor;
                }
                else
                {
                    int levenshteinDist = ToolBox.LevenshteinDistance(txt, c.LastSentChatMessages[i]);
                    similarity += Math.Max((txt.Length - levenshteinDist) / (float)txt.Length * closeFactor, 0.0f);
                }
            }
            //order/report messages can be sent a little faster than normal messages without triggering the spam filter
            if (orderMsg != null)
            {
                similarity *= 0.25f;
            }

            bool isOwner = GameMain.Server.OwnerConnection != null && c.Connection == GameMain.Server.OwnerConnection;

            if (similarity + c.ChatSpamSpeed > 5.0f && !isOwner)
            {
                GameMain.Server.KarmaManager.OnSpamFilterTriggered(c);

                c.ChatSpamCount++;
                if (c.ChatSpamCount > 3)
                {
                    //kick for spamming too much
                    GameMain.Server.KickClient(c, TextManager.Get("SpamFilterKicked"));
                }
                else
                {
                    ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null);
                    c.ChatSpamTimer = 10.0f;
                    GameMain.Server.SendDirectChatMessage(denyMsg, c);
                }
                return;
            }

            c.ChatSpamSpeed += similarity + 0.5f;

            if (c.ChatSpamTimer > 0.0f && !isOwner)
            {
                ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null);
                c.ChatSpamTimer = 10.0f;
                GameMain.Server.SendDirectChatMessage(denyMsg, c);
                return;
            }

            var should = GameMain.Lua.hook.Call("chatMessage", new DynValue[] { DynValue.NewString(txt), UserData.Create(c) });


            if (should != null)
            {
                if (should.CastToBool())
                {
                    return;
                }
                else
                {
                }
            }

            if (type == ChatMessageType.Order)
            {
                if (c.Character == null || c.Character.SpeechImpediment >= 100.0f || c.Character.IsDead)
                {
                    return;
                }
                if (orderMsg.Order.IsReport)
                {
                    HumanAIController.ReportProblem(orderMsg.Sender, orderMsg.Order);
                }
                Order order = orderTargetType switch
                {
                    Order.OrderTargetType.Entity =>
                    new Order(orderMsg.Order, orderTargetEntity, orderMsg.Order?.GetTargetItemComponent(orderTargetEntity as Item), orderGiver: orderMsg.Sender),
                    Order.OrderTargetType.Position =>
                    new Order(orderMsg.Order, orderTargetPosition, orderGiver: orderMsg.Sender),
                    Order.OrderTargetType.WallSection when orderTargetEntity is Structure s && wallSectionIndex.HasValue =>
                    new Order(orderMsg.Order, s, wallSectionIndex, orderGiver: orderMsg.Sender),
                    _ => throw new NotImplementedException()
                };
                if (order != null)
                {
                    if (order.TargetAllCharacters)
                    {
                        if (order.IsIgnoreOrder)
                        {
                            switch (orderTargetType)
                            {
                            case Order.OrderTargetType.Entity:
                                if (!(orderTargetEntity is IIgnorable ignorableEntity))
                                {
                                    break;
                                }
                                ignorableEntity.OrderedToBeIgnored = order.Identifier == "ignorethis";
                                break;

                            case Order.OrderTargetType.Position:
                                throw new NotImplementedException();

                            case Order.OrderTargetType.WallSection:
                                if (!wallSectionIndex.HasValue)
                                {
                                    break;
                                }
                                if (!(orderTargetEntity is Structure s))
                                {
                                    break;
                                }
                                if (!(s.GetSection(wallSectionIndex.Value) is IIgnorable ignorableWall))
                                {
                                    break;
                                }
                                ignorableWall.OrderedToBeIgnored = order.Identifier == "ignorethis";
                                break;
                            }
                        }
                        GameMain.GameSession?.CrewManager?.AddOrder(order, order.IsIgnoreOrder ? (float?)null : order.FadeOutTime);
                    }
                    else if (orderTargetCharacter != null)
                    {
                        orderTargetCharacter.SetOrder(order, orderMsg.OrderOption, orderMsg.OrderPriority, orderMsg.Sender);
                    }
                }
                GameMain.Server.SendOrderChatMessage(orderMsg);
            }
            else
            {
                GameMain.Server.SendChatMessage(txt, null, c);
            }
        }
示例#3
0
        public static void ClientRead(IReadMessage msg)
        {
            UInt16                     id           = msg.ReadUInt16();
            ChatMessageType            type         = (ChatMessageType)msg.ReadByte();
            PlayerConnectionChangeType changeType   = PlayerConnectionChangeType.None;
            string                     txt          = "";
            string                     styleSetting = string.Empty;

            if (type != ChatMessageType.Order)
            {
                changeType = (PlayerConnectionChangeType)msg.ReadByte();
                txt        = msg.ReadString();
            }

            string    senderName      = msg.ReadString();
            Character senderCharacter = null;
            Client    senderClient    = null;
            bool      hasSenderClient = msg.ReadBoolean();

            if (hasSenderClient)
            {
                UInt64 clientId = msg.ReadUInt64();
                senderClient = GameMain.Client.ConnectedClients.Find(c => c.SteamID == clientId || c.ID == clientId);
                if (senderClient != null)
                {
                    senderName = senderClient.Name;
                }
            }
            bool hasSenderCharacter = msg.ReadBoolean();

            if (hasSenderCharacter)
            {
                senderCharacter = Entity.FindEntityByID(msg.ReadUInt16()) as Character;
                if (senderCharacter != null)
                {
                    senderName = senderCharacter.Name;
                }
            }
            msg.ReadPadBits();

            switch (type)
            {
            case ChatMessageType.Default:
                break;

            case ChatMessageType.Order:
                int       orderIndex        = msg.ReadByte();
                UInt16    targetCharacterID = msg.ReadUInt16();
                Character targetCharacter   = Entity.FindEntityByID(targetCharacterID) as Character;
                Entity    targetEntity      = Entity.FindEntityByID(msg.ReadUInt16());

                Order  orderPrefab = null;
                int?   optionIndex = null;
                string orderOption = null;

                // The option of a Dismiss order is written differently so we know what order we target
                // now that the game supports multiple current orders simultaneously
                if (orderIndex >= 0 && orderIndex < Order.PrefabList.Count)
                {
                    orderPrefab = Order.PrefabList[orderIndex];
                    if (orderPrefab.Identifier != "dismissed")
                    {
                        optionIndex = msg.ReadByte();
                    }
                    // Does the dismiss order have a specified target?
                    else if (msg.ReadBoolean())
                    {
                        int identifierCount = msg.ReadByte();
                        if (identifierCount > 0)
                        {
                            int   dismissedOrderIndex  = msg.ReadByte();
                            Order dismissedOrderPrefab = null;
                            if (dismissedOrderIndex >= 0 && dismissedOrderIndex < Order.PrefabList.Count)
                            {
                                dismissedOrderPrefab = Order.PrefabList[dismissedOrderIndex];
                                orderOption          = dismissedOrderPrefab.Identifier;
                            }
                            if (identifierCount > 1)
                            {
                                int dismissedOrderOptionIndex = msg.ReadByte();
                                if (dismissedOrderPrefab != null)
                                {
                                    var options = dismissedOrderPrefab.Options;
                                    if (options != null && dismissedOrderOptionIndex >= 0 && dismissedOrderOptionIndex < options.Length)
                                    {
                                        orderOption += $".{options[dismissedOrderOptionIndex]}";
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    optionIndex = msg.ReadByte();
                }

                int                   orderPriority       = msg.ReadByte();
                OrderTarget           orderTargetPosition = null;
                Order.OrderTargetType orderTargetType     = (Order.OrderTargetType)msg.ReadByte();
                int                   wallSectionIndex    = 0;
                if (msg.ReadBoolean())
                {
                    var x    = msg.ReadSingle();
                    var y    = msg.ReadSingle();
                    var hull = Entity.FindEntityByID(msg.ReadUInt16()) as Hull;
                    orderTargetPosition = new OrderTarget(new Vector2(x, y), hull, creatingFromExistingData: true);
                }
                else if (orderTargetType == Order.OrderTargetType.WallSection)
                {
                    wallSectionIndex = msg.ReadByte();
                }

                if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
                {
                    DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
                    if (NetIdUtils.IdMoreRecent(id, LastID))
                    {
                        LastID = id;
                    }
                    return;
                }
                else
                {
                    orderPrefab ??= Order.PrefabList[orderIndex];
                }

                orderOption ??= optionIndex.HasValue && optionIndex >= 0 && optionIndex < orderPrefab.Options.Length ? orderPrefab.Options[optionIndex.Value] : "";
                txt = orderPrefab.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);

                if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
                {
                    Order order = null;
                    switch (orderTargetType)
                    {
                    case Order.OrderTargetType.Entity:
                        order = new Order(orderPrefab, targetEntity, orderPrefab.GetTargetItemComponent(targetEntity as Item), orderGiver: senderCharacter);
                        break;

                    case Order.OrderTargetType.Position:
                        order = new Order(orderPrefab, orderTargetPosition, orderGiver: senderCharacter);
                        break;

                    case Order.OrderTargetType.WallSection:
                        order = new Order(orderPrefab, targetEntity as Structure, wallSectionIndex, orderGiver: senderCharacter);
                        break;
                    }

                    if (order != null)
                    {
                        if (order.TargetAllCharacters)
                        {
                            var fadeOutTime = !orderPrefab.IsIgnoreOrder ? (float?)orderPrefab.FadeOutTime : null;
                            GameMain.GameSession?.CrewManager?.AddOrder(order, fadeOutTime);
                        }
                        else if (targetCharacter != null)
                        {
                            targetCharacter.SetOrder(order, orderOption, orderPriority, senderCharacter);
                        }
                    }
                }

                if (NetIdUtils.IdMoreRecent(id, LastID))
                {
                    GameMain.Client.AddChatMessage(
                        new OrderChatMessage(orderPrefab, orderOption, orderPriority, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
                    LastID = id;
                }
                return;

            case ChatMessageType.ServerMessageBox:
                txt = TextManager.GetServerMessage(txt);
                break;

            case ChatMessageType.ServerMessageBoxInGame:
                styleSetting = msg.ReadString();
                txt          = TextManager.GetServerMessage(txt);
                break;
            }

            if (NetIdUtils.IdMoreRecent(id, LastID))
            {
                switch (type)
                {
                case ChatMessageType.MessageBox:
                case ChatMessageType.ServerMessageBox:
                    //only show the message box if the text differs from the text in the currently visible box
                    if ((GUIMessageBox.VisibleBox as GUIMessageBox)?.Text?.Text != txt)
                    {
                        new GUIMessageBox("", txt);
                    }
                    break;

                case ChatMessageType.ServerMessageBoxInGame:
                    new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
                    break;

                case ChatMessageType.Console:
                    DebugConsole.NewMessage(txt, MessageColor[(int)ChatMessageType.Console]);
                    break;

                case ChatMessageType.ServerLog:
                    if (!Enum.TryParse(senderName, out ServerLog.MessageType messageType))
                    {
                        return;
                    }
                    GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
                    break;

                default:
                    GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType);
                    break;
                }
                LastID = id;
            }
        }
示例#4
0
        public static void ServerRead(IReadMessage msg, Client c)
        {
            c.KickAFKTimer = 0.0f;

            UInt16          ID   = msg.ReadUInt16();
            ChatMessageType type = (ChatMessageType)msg.ReadByte();
            string          txt;

            Character        orderTargetCharacter = null;
            Entity           orderTargetEntity    = null;
            OrderChatMessage orderMsg             = null;
            OrderTarget      orderTargetPosition  = null;

            Order.OrderTargetType orderTargetType = Order.OrderTargetType.Entity;
            int?wallSectionIndex = null;

            if (type == ChatMessageType.Order)
            {
                int orderIndex = msg.ReadByte();
                orderTargetCharacter = Entity.FindEntityByID(msg.ReadUInt16()) as Character;
                orderTargetEntity    = Entity.FindEntityByID(msg.ReadUInt16()) as Entity;

                Order  orderPrefab      = null;
                int?   orderOptionIndex = null;
                string orderOption      = null;

                // The option of a Dismiss order is written differently so we know what order we target
                // now that the game supports multiple current orders simultaneously
                if (orderIndex >= 0 && orderIndex < Order.PrefabList.Count)
                {
                    orderPrefab = Order.PrefabList[orderIndex];
                    if (orderPrefab.Identifier != "dismissed")
                    {
                        orderOptionIndex = msg.ReadByte();
                    }
                    // Does the dismiss order have a specified target?
                    else if (msg.ReadBoolean())
                    {
                        int identifierCount = msg.ReadByte();
                        if (identifierCount > 0)
                        {
                            int   dismissedOrderIndex  = msg.ReadByte();
                            Order dismissedOrderPrefab = null;
                            if (dismissedOrderIndex >= 0 && dismissedOrderIndex < Order.PrefabList.Count)
                            {
                                dismissedOrderPrefab = Order.PrefabList[dismissedOrderIndex];
                                orderOption          = dismissedOrderPrefab.Identifier;
                            }
                            if (identifierCount > 1)
                            {
                                int dismissedOrderOptionIndex = msg.ReadByte();
                                if (dismissedOrderPrefab != null)
                                {
                                    var options = dismissedOrderPrefab.Options;
                                    if (options != null && dismissedOrderOptionIndex >= 0 && dismissedOrderOptionIndex < options.Length)
                                    {
                                        orderOption += $".{options[dismissedOrderOptionIndex]}";
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    orderOptionIndex = msg.ReadByte();
                }

                int orderPriority = msg.ReadByte();
                orderTargetType = (Order.OrderTargetType)msg.ReadByte();
                if (msg.ReadBoolean())
                {
                    var x    = msg.ReadSingle();
                    var y    = msg.ReadSingle();
                    var hull = Entity.FindEntityByID(msg.ReadUInt16()) as Hull;
                    orderTargetPosition = new OrderTarget(new Vector2(x, y), hull, true);
                }
                else if (orderTargetType == Order.OrderTargetType.WallSection)
                {
                    wallSectionIndex = msg.ReadByte();
                }

                if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
                {
                    DebugConsole.ThrowError($"Invalid order message from client \"{c.Name}\" - order index out of bounds ({orderIndex}).");
                    if (NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID))
                    {
                        c.LastSentChatMsgID = ID;
                    }
                    return;
                }

                orderPrefab ??= Order.PrefabList[orderIndex];
                orderOption ??= orderOptionIndex == null || orderOptionIndex < 0 || orderOptionIndex >= orderPrefab.Options.Length ? "" : orderPrefab.Options[orderOptionIndex.Value];
                orderMsg = new OrderChatMessage(orderPrefab, orderOption, orderPriority, orderTargetPosition ?? orderTargetEntity as ISpatialEntity, orderTargetCharacter, c.Character)
                {
                    WallSectionIndex = wallSectionIndex
                };
                txt = orderMsg.Text;
            }
            else
            {
                txt = msg.ReadString() ?? "";
            }

            if (!NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID))
            {
                return;
            }

            c.LastSentChatMsgID = ID;

            if (txt.Length > MaxLength)
            {
                txt = txt.Substring(0, MaxLength);
            }

            c.LastSentChatMessages.Add(txt);
            if (c.LastSentChatMessages.Count > 10)
            {
                c.LastSentChatMessages.RemoveRange(0, c.LastSentChatMessages.Count - 10);
            }

            float similarity = 0.0f;

            for (int i = 0; i < c.LastSentChatMessages.Count; i++)
            {
                float closeFactor = 1.0f / (c.LastSentChatMessages.Count - i);

                if (string.IsNullOrEmpty(txt))
                {
                    similarity += closeFactor;
                }
                else
                {
                    int levenshteinDist = ToolBox.LevenshteinDistance(txt, c.LastSentChatMessages[i]);
                    similarity += Math.Max((txt.Length - levenshteinDist) / (float)txt.Length * closeFactor, 0.0f);
                }
            }
            //order/report messages can be sent a little faster than normal messages without triggering the spam filter
            if (orderMsg != null)
            {
                similarity *= 0.25f;
            }

            bool isOwner = GameMain.Server.OwnerConnection != null && c.Connection == GameMain.Server.OwnerConnection;

            if (similarity + c.ChatSpamSpeed > 5.0f && !isOwner)
            {
                GameMain.Server.KarmaManager.OnSpamFilterTriggered(c);

                c.ChatSpamCount++;
                if (c.ChatSpamCount > 3)
                {
                    //kick for spamming too much
                    GameMain.Server.KickClient(c, TextManager.Get("SpamFilterKicked"));
                }
                else
                {
                    ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null);
                    c.ChatSpamTimer = 10.0f;
                    GameMain.Server.SendDirectChatMessage(denyMsg, c);
                }
                return;
            }

            c.ChatSpamSpeed += similarity + 0.5f;

            if (c.ChatSpamTimer > 0.0f && !isOwner)
            {
                ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null);
                c.ChatSpamTimer = 10.0f;
                GameMain.Server.SendDirectChatMessage(denyMsg, c);
                return;
            }

            if (type == ChatMessageType.Order)
            {
                if (c.Character == null || c.Character.SpeechImpediment >= 100.0f || c.Character.IsDead)
                {
                    return;
                }
                Order order = null;
                if (orderMsg.Order.IsReport)
                {
                    HumanAIController.ReportProblem(orderMsg.Sender, orderMsg.Order);
                }
                else if (orderTargetCharacter != null && !orderMsg.Order.TargetAllCharacters)
                {
                    switch (orderTargetType)
                    {
                    case Order.OrderTargetType.Entity:
                        order = new Order(orderMsg.Order.Prefab, orderTargetEntity, orderMsg.Order.Prefab?.GetTargetItemComponent(orderTargetEntity as Item), orderGiver: orderMsg.Sender);
                        break;

                    case Order.OrderTargetType.Position:
                        order = new Order(orderMsg.Order.Prefab, orderTargetPosition, orderGiver: orderMsg.Sender);
                        break;
                    }
                    if (order != null)
                    {
                        orderTargetCharacter.SetOrder(order, orderMsg.OrderOption, orderMsg.OrderPriority, orderMsg.Sender);
                    }
                }
                else if (orderMsg.Order.IsIgnoreOrder)
                {
                    switch (orderTargetType)
                    {
                    case Order.OrderTargetType.Entity:
                        if (orderTargetEntity is IIgnorable ignorableEntity)
                        {
                            ignorableEntity.OrderedToBeIgnored = orderMsg.Order.Identifier == "ignorethis";
                        }
                        break;

                    case Order.OrderTargetType.WallSection:
                        if (!wallSectionIndex.HasValue)
                        {
                            break;
                        }
                        if (orderTargetEntity is Structure s && s.GetSection(wallSectionIndex.Value) is IIgnorable ignorableWall)
                        {
                            ignorableWall.OrderedToBeIgnored = orderMsg.Order.Identifier == "ignorethis";
                        }
                        break;
                    }
                }
                GameMain.Server.SendOrderChatMessage(orderMsg);
            }
            else
            {
                GameMain.Server.SendChatMessage(txt, null, c);
            }
        }
        public static void ClientRead(IReadMessage msg)
        {
            UInt16                     ID           = msg.ReadUInt16();
            ChatMessageType            type         = (ChatMessageType)msg.ReadByte();
            PlayerConnectionChangeType changeType   = PlayerConnectionChangeType.None;
            string                     txt          = "";
            string                     styleSetting = string.Empty;

            if (type != ChatMessageType.Order)
            {
                changeType = (PlayerConnectionChangeType)msg.ReadByte();
                txt        = msg.ReadString();
            }

            string    senderName         = msg.ReadString();
            Character senderCharacter    = null;
            bool      hasSenderCharacter = msg.ReadBoolean();

            if (hasSenderCharacter)
            {
                senderCharacter = Entity.FindEntityByID(msg.ReadUInt16()) as Character;
                if (senderCharacter != null)
                {
                    senderName = senderCharacter.Name;
                }
            }

            switch (type)
            {
            case ChatMessageType.Default:
                break;

            case ChatMessageType.Order:
                int                   orderIndex          = msg.ReadByte();
                UInt16                targetCharacterID   = msg.ReadUInt16();
                Character             targetCharacter     = Entity.FindEntityByID(targetCharacterID) as Character;
                Entity                targetEntity        = Entity.FindEntityByID(msg.ReadUInt16());
                int                   optionIndex         = msg.ReadByte();
                OrderTarget           orderTargetPosition = null;
                Order.OrderTargetType orderTargetType     = (Order.OrderTargetType)msg.ReadByte();
                int                   wallSectionIndex    = 0;
                if (msg.ReadBoolean())
                {
                    var x    = msg.ReadSingle();
                    var y    = msg.ReadSingle();
                    var hull = Entity.FindEntityByID(msg.ReadUInt16()) as Hull;
                    orderTargetPosition = new OrderTarget(new Vector2(x, y), hull, creatingFromExistingData: true);
                }
                else if (orderTargetType == Order.OrderTargetType.WallSection)
                {
                    wallSectionIndex = msg.ReadByte();
                }

                Order orderPrefab;
                if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
                {
                    DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
                    if (NetIdUtils.IdMoreRecent(ID, LastID))
                    {
                        LastID = ID;
                    }
                    return;
                }
                else
                {
                    orderPrefab = Order.PrefabList[orderIndex];
                }
                string orderOption = "";
                if (optionIndex >= 0 && optionIndex < orderPrefab.Options.Length)
                {
                    orderOption = orderPrefab.Options[optionIndex];
                }
                txt = orderPrefab.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);

                if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
                {
                    Order order = null;
                    switch (orderTargetType)
                    {
                    case Order.OrderTargetType.Entity:
                        order = new Order(orderPrefab, targetEntity, orderPrefab.GetTargetItemComponent(targetEntity as Item), orderGiver: senderCharacter);
                        break;

                    case Order.OrderTargetType.Position:
                        order = new Order(orderPrefab, orderTargetPosition, orderGiver: senderCharacter);
                        break;

                    case Order.OrderTargetType.WallSection:
                        order = new Order(orderPrefab, targetEntity as Structure, wallSectionIndex, orderGiver: senderCharacter);
                        break;
                    }

                    if (order != null)
                    {
                        if (order.TargetAllCharacters)
                        {
                            var fadeOutTime = !orderPrefab.IsIgnoreOrder ? (float?)orderPrefab.FadeOutTime : null;
                            GameMain.GameSession?.CrewManager?.AddOrder(order, fadeOutTime);
                        }
                        else if (targetCharacter != null)
                        {
                            targetCharacter.SetOrder(order, orderOption, senderCharacter);
                        }
                    }
                }

                if (NetIdUtils.IdMoreRecent(ID, LastID))
                {
                    GameMain.Client.AddChatMessage(
                        new OrderChatMessage(orderPrefab, orderOption, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
                    LastID = ID;
                }
                return;

            case ChatMessageType.ServerMessageBox:
                txt = TextManager.GetServerMessage(txt);
                break;

            case ChatMessageType.ServerMessageBoxInGame:
                styleSetting = msg.ReadString();
                txt          = TextManager.GetServerMessage(txt);
                break;
            }

            if (NetIdUtils.IdMoreRecent(ID, LastID))
            {
                switch (type)
                {
                case ChatMessageType.MessageBox:
                case ChatMessageType.ServerMessageBox:
                    //only show the message box if the text differs from the text in the currently visible box
                    if ((GUIMessageBox.VisibleBox as GUIMessageBox)?.Text?.Text != txt)
                    {
                        new GUIMessageBox("", txt);
                    }
                    break;

                case ChatMessageType.ServerMessageBoxInGame:
                    new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
                    break;

                case ChatMessageType.Console:
                    DebugConsole.NewMessage(txt, MessageColor[(int)ChatMessageType.Console]);
                    break;

                case ChatMessageType.ServerLog:
                    if (!Enum.TryParse(senderName, out ServerLog.MessageType messageType))
                    {
                        return;
                    }
                    GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
                    break;

                default:
                    GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter, changeType);
                    break;
                }
                LastID = ID;
            }
        }
示例#6
0
        public static OrderMessageInfo ReadOrder(IReadMessage msg)
        {
            int       orderIndex        = msg.ReadByte();
            ushort    targetCharacterId = msg.ReadUInt16();
            Character targetCharacter   = targetCharacterId != Entity.NullEntityID ? Entity.FindEntityByID(targetCharacterId) as Character : null;
            ushort    targetEntityId    = msg.ReadUInt16();
            Entity    targetEntity      = targetEntityId != Entity.NullEntityID ? Entity.FindEntityByID(targetEntityId) : null;

            Order  orderPrefab = null;
            int?   optionIndex = null;
            string orderOption = null;

            // The option of a Dismiss order is written differently so we know what order we target
            // now that the game supports multiple current orders simultaneously
            if (orderIndex >= 0 && orderIndex < Order.PrefabList.Count)
            {
                orderPrefab = Order.PrefabList[orderIndex];
                if (orderPrefab.Identifier != "dismissed")
                {
                    optionIndex = msg.ReadByte();
                }
                // Does the dismiss order have a specified target?
                else if (msg.ReadBoolean())
                {
                    int identifierCount = msg.ReadByte();
                    if (identifierCount > 0)
                    {
                        int   dismissedOrderIndex  = msg.ReadByte();
                        Order dismissedOrderPrefab = null;
                        if (dismissedOrderIndex >= 0 && dismissedOrderIndex < Order.PrefabList.Count)
                        {
                            dismissedOrderPrefab = Order.PrefabList[dismissedOrderIndex];
                            orderOption          = dismissedOrderPrefab.Identifier;
                        }
                        if (identifierCount > 1)
                        {
                            int dismissedOrderOptionIndex = msg.ReadByte();
                            if (dismissedOrderPrefab != null)
                            {
                                var options = dismissedOrderPrefab.Options;
                                if (options != null && dismissedOrderOptionIndex >= 0 && dismissedOrderOptionIndex < options.Length)
                                {
                                    orderOption += $".{options[dismissedOrderOptionIndex]}";
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                optionIndex = msg.ReadByte();
            }

            int         orderPriority       = msg.ReadByte();
            OrderTarget orderTargetPosition = null;

            Order.OrderTargetType orderTargetType = (Order.OrderTargetType)msg.ReadByte();
            int wallSectionIndex = 0;

            if (msg.ReadBoolean())
            {
                float  x      = msg.ReadSingle();
                float  y      = msg.ReadSingle();
                ushort hullId = msg.ReadUInt16();
                var    hull   = hullId != Entity.NullEntityID ? Entity.FindEntityByID(hullId) as Hull : null;
                orderTargetPosition = new OrderTarget(new Vector2(x, y), hull, creatingFromExistingData: true);
            }
            else if (orderTargetType == Order.OrderTargetType.WallSection)
            {
                wallSectionIndex = msg.ReadByte();
            }

            return(new OrderMessageInfo(orderIndex, orderPrefab, orderOption, optionIndex, targetCharacter, orderTargetType, targetEntity, orderTargetPosition, wallSectionIndex, orderPriority));
        }