Ejemplo n.º 1
0
        public virtual void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            if (extraData != null)
            {
                const int min = 0, max = 13;
                switch ((NetEntityEvent.Type)extraData[0])
                {
                case NetEntityEvent.Type.InventoryState:
                    msg.WriteRangedInteger(0, min, max);
                    msg.Write(GameMain.Server.EntityEventManager.Events.Last()?.ID ?? (ushort)0);
                    Inventory.ServerWrite(msg, c);
                    break;

                case NetEntityEvent.Type.Control:
                    msg.WriteRangedInteger(1, min, max);
                    Client owner = (Client)extraData[1];
                    msg.Write(owner != null && owner.Character == this && GameMain.Server.ConnectedClients.Contains(owner) ? owner.ID : (byte)0);
                    break;

                case NetEntityEvent.Type.Status:
                    msg.WriteRangedInteger(2, min, max);
                    WriteStatus(msg);
                    break;

                case NetEntityEvent.Type.UpdateSkills:
                    msg.WriteRangedInteger(3, min, max);
                    if (Info?.Job == null)
                    {
                        msg.Write((byte)0);
                    }
                    else
                    {
                        msg.Write((byte)Info.Job.Skills.Count);
                        foreach (Skill skill in Info.Job.Skills)
                        {
                            msg.Write(skill.Identifier);
                            msg.Write(skill.Level);
                        }
                    }
                    break;

                case NetEntityEvent.Type.SetAttackTarget:
                case NetEntityEvent.Type.ExecuteAttack:
                    Limb   attackLimb      = extraData[1] as Limb;
                    UInt16 targetEntityID  = (UInt16)extraData[2];
                    int    targetLimbIndex = extraData.Length > 3 ? (int)extraData[3] : 0;
                    msg.WriteRangedInteger(extraData[0] is NetEntityEvent.Type.SetAttackTarget ? 4 : 5, min, max);
                    msg.Write((byte)(Removed ? 255 : Array.IndexOf(AnimController.Limbs, attackLimb)));
                    msg.Write(targetEntityID);
                    msg.Write((byte)targetLimbIndex);
                    msg.Write(extraData.Length > 4 ? (float)extraData[4] : 0);
                    msg.Write(extraData.Length > 5 ? (float)extraData[5] : 0);
                    break;

                case NetEntityEvent.Type.AssignCampaignInteraction:
                    msg.WriteRangedInteger(6, min, max);
                    msg.Write((byte)CampaignInteractionType);
                    msg.Write(RequireConsciousnessForCustomInteract);
                    break;

                case NetEntityEvent.Type.ObjectiveManagerState:
                    msg.WriteRangedInteger(7, min, max);
                    int type = (extraData[1] as string) switch
                    {
                        "order" => 1,
                        "objective" => 2,
                        _ => 0
                    };
                    msg.WriteRangedInteger(type, 0, 2);
                    if (!(AIController is HumanAIController controller))
                    {
                        msg.Write(false);
                        break;
                    }
                    if (type == 1)
                    {
                        var  currentOrderInfo = controller.ObjectiveManager.GetCurrentOrderInfo();
                        bool validOrder       = currentOrderInfo.HasValue;
                        msg.Write(validOrder);
                        if (!validOrder)
                        {
                            break;
                        }
                        var orderPrefab = currentOrderInfo.Value.Order.Prefab;
                        int orderIndex  = Order.PrefabList.IndexOf(orderPrefab);
                        msg.WriteRangedInteger(orderIndex, 0, Order.PrefabList.Count);
                        if (!orderPrefab.HasOptions)
                        {
                            break;
                        }
                        int optionIndex = orderPrefab.AllOptions.IndexOf(currentOrderInfo.Value.OrderOption);
                        if (optionIndex == -1)
                        {
                            DebugConsole.AddWarning($"Error while writing order data. Order option \"{(currentOrderInfo.Value.OrderOption ?? null)}\" not found in the order prefab \"{orderPrefab.Name}\".");
                        }
                        msg.WriteRangedInteger(optionIndex, -1, orderPrefab.AllOptions.Length);
                    }
                    else if (type == 2)
                    {
                        var  objective      = controller.ObjectiveManager.CurrentObjective;
                        bool validObjective = !string.IsNullOrEmpty(objective?.Identifier);
                        msg.Write(validObjective);
                        if (!validObjective)
                        {
                            break;
                        }
                        msg.Write(objective.Identifier);
                        msg.Write(objective.Option ?? "");
                        UInt16 targetEntityId = 0;
                        if (objective is AIObjectiveOperateItem operateObjective && operateObjective.OperateTarget != null)
                        {
                            targetEntityId = operateObjective.OperateTarget.ID;
                        }
                        msg.Write(targetEntityId);
                    }
                    break;

                case NetEntityEvent.Type.TeamChange:
                    msg.WriteRangedInteger(8, min, max);
                    msg.Write((byte)TeamID);
                    break;

                case NetEntityEvent.Type.AddToCrew:
                    msg.WriteRangedInteger(9, min, max);
                    msg.Write((byte)(CharacterTeamType)extraData[1]);     // team id
                    ushort[] inventoryItemIDs = (ushort[])extraData[2];
                    msg.Write((ushort)inventoryItemIDs.Length);
                    for (int i = 0; i < inventoryItemIDs.Length; i++)
                    {
                        msg.Write(inventoryItemIDs[i]);
                    }
                    break;

                case NetEntityEvent.Type.UpdateExperience:
                    msg.WriteRangedInteger(10, min, max);
                    msg.Write(Info.ExperiencePoints);
                    break;

                case NetEntityEvent.Type.UpdateTalents:
                    msg.WriteRangedInteger(11, min, max);
                    msg.Write((ushort)characterTalents.Count);
                    foreach (var unlockedTalent in characterTalents)
                    {
                        msg.Write(unlockedTalent.AddedThisRound);
                        msg.Write(unlockedTalent.Prefab.UIntIdentifier);
                    }
                    break;

                case NetEntityEvent.Type.UpdateMoney:
                    msg.WriteRangedInteger(12, min, max);
                    msg.Write(GameMain.GameSession.Campaign.Money);
                    break;

                case NetEntityEvent.Type.UpdatePermanentStats:
                    msg.WriteRangedInteger(13, min, max);
                    if (Info == null || extraData.Length < 2 || !(extraData[1] is StatTypes statType))
                    {
                        msg.Write((byte)0);
                        msg.Write((byte)0);
                    }
                    else if (!Info.SavedStatValues.ContainsKey(statType))
                    {
                        msg.Write((byte)0);
                        msg.Write((byte)statType);
                    }
                    else
                    {
                        msg.Write((byte)Info.SavedStatValues[statType].Count);
                        msg.Write((byte)statType);
                        foreach (var savedStatValue in Info.SavedStatValues[statType])
                        {
                            msg.Write(savedStatValue.StatIdentifier);
                            msg.Write(savedStatValue.StatValue);
                            msg.Write(savedStatValue.RemoveOnDeath);
                        }
                    }
                    break;

                default:
                    DebugConsole.ThrowError("Invalid NetworkEvent type for entity " + ToString() + " (" + (NetEntityEvent.Type)extraData[0] + ")");
                    break;
                }
                msg.WritePadBits();
            }
            else
            {
                msg.Write(ID);

                IWriteMessage tempBuffer = new WriteOnlyMessage();

                if (this == c.Character)
                {
                    tempBuffer.Write(true);
                    if (LastNetworkUpdateID < memInput.Count + 1)
                    {
                        tempBuffer.Write((UInt16)0);
                    }
                    else
                    {
                        tempBuffer.Write((UInt16)(LastNetworkUpdateID - memInput.Count - 1));
                    }
                }
                else
                {
                    tempBuffer.Write(false);

                    bool aiming = false;
                    bool use    = false;
                    bool attack = false;
                    bool shoot  = false;

                    if (IsRemotePlayer)
                    {
                        aiming = dequeuedInput.HasFlag(InputNetFlags.Aim);
                        use    = dequeuedInput.HasFlag(InputNetFlags.Use);
                        attack = dequeuedInput.HasFlag(InputNetFlags.Attack);
                        shoot  = dequeuedInput.HasFlag(InputNetFlags.Shoot);
                    }
                    else if (keys != null)
                    {
                        aiming            = keys[(int)InputType.Aim].GetHeldQueue;
                        use               = keys[(int)InputType.Use].GetHeldQueue;
                        attack            = keys[(int)InputType.Attack].GetHeldQueue;
                        shoot             = keys[(int)InputType.Shoot].GetHeldQueue;
                        networkUpdateSent = true;
                    }

                    tempBuffer.Write(aiming);
                    tempBuffer.Write(shoot);
                    tempBuffer.Write(use);
                    if (AnimController is HumanoidAnimController)
                    {
                        tempBuffer.Write(((HumanoidAnimController)AnimController).Crouching);
                    }
                    tempBuffer.Write(attack);

                    Vector2 relativeCursorPos = cursorPosition - AimRefPosition;
                    tempBuffer.Write((UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI)));

                    tempBuffer.Write(IsRagdolled || Stun > 0.0f || IsDead || IsIncapacitated);

                    tempBuffer.Write(AnimController.Dir > 0.0f);
                }

                if (SelectedCharacter != null || SelectedConstruction != null)
                {
                    tempBuffer.Write(true);
                    tempBuffer.Write(SelectedCharacter != null ? SelectedCharacter.ID : NullEntityID);
                    tempBuffer.Write(SelectedConstruction != null ? SelectedConstruction.ID : NullEntityID);
                    if (SelectedCharacter != null)
                    {
                        tempBuffer.Write(AnimController.Anim == AnimController.Animation.CPR);
                    }
                }
                else
                {
                    tempBuffer.Write(false);
                }

                tempBuffer.Write(SimPosition.X);
                tempBuffer.Write(SimPosition.Y);
                float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
                AnimController.Collider.LinearVelocity = new Vector2(
                    MathHelper.Clamp(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel),
                    MathHelper.Clamp(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel));
                tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12);
                tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12);

                bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation || !AnimController.Collider.PhysEnabled;
                tempBuffer.Write(fixedRotation);
                if (!fixedRotation)
                {
                    tempBuffer.Write(AnimController.Collider.Rotation);
                    float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
                    AnimController.Collider.AngularVelocity = NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
                    tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8);
                }

                bool writeStatus = healthUpdateTimer <= 0.0f;
                tempBuffer.Write(writeStatus);
                if (writeStatus)
                {
                    WriteStatus(tempBuffer);
                    AIController?.ServerWrite(tempBuffer);
                    HealthUpdatePending = false;
                }

                tempBuffer.WritePadBits();

                msg.WriteVariableUInt32((uint)tempBuffer.LengthBytes);
                msg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
            }
        }
Ejemplo n.º 2
0
            public void Write(IWriteMessage msg, object overrideValue = null)
            {
                if (overrideValue == null)
                {
                    overrideValue = property.GetValue(parentObject);
                }
                switch (typeString)
                {
                case "float":
                    msg.WriteVariableUInt32(4);
                    msg.Write((float)overrideValue);
                    break;

                case "int":
                    msg.WriteVariableUInt32(4);
                    msg.Write((int)overrideValue);
                    break;

                case "vector2":
                    msg.WriteVariableUInt32(8);
                    msg.Write(((Vector2)overrideValue).X);
                    msg.Write(((Vector2)overrideValue).Y);
                    break;

                case "vector3":
                    msg.WriteVariableUInt32(12);
                    msg.Write(((Vector3)overrideValue).X);
                    msg.Write(((Vector3)overrideValue).Y);
                    msg.Write(((Vector3)overrideValue).Z);
                    break;

                case "vector4":
                    msg.WriteVariableUInt32(16);
                    msg.Write(((Vector4)overrideValue).X);
                    msg.Write(((Vector4)overrideValue).Y);
                    msg.Write(((Vector4)overrideValue).Z);
                    msg.Write(((Vector4)overrideValue).W);
                    break;

                case "color":
                    msg.WriteVariableUInt32(4);
                    msg.Write(((Color)overrideValue).R);
                    msg.Write(((Color)overrideValue).G);
                    msg.Write(((Color)overrideValue).B);
                    msg.Write(((Color)overrideValue).A);
                    break;

                case "rectangle":
                    msg.WriteVariableUInt32(16);
                    msg.Write(((Rectangle)overrideValue).X);
                    msg.Write(((Rectangle)overrideValue).Y);
                    msg.Write(((Rectangle)overrideValue).Width);
                    msg.Write(((Rectangle)overrideValue).Height);
                    break;

                default:
                    string strVal = overrideValue.ToString();

                    msg.Write(strVal);
                    break;
                }
            }
Ejemplo n.º 3
0
 public void Write(IWriteMessage msg)
 {
     msg.Write(CharacterStateID);
     serializable.ClientWrite(msg, Data);
 }
Ejemplo n.º 4
0
 public void ClientWrite(IWriteMessage msg, object[] extraData = null)
 {
     //flowpercentage can only be adjusted at 10% intervals -> no need for more accuracy than this
     msg.WriteRangedInteger((int)(flowPercentage / 10.0f), -10, 10);
     msg.Write(IsActive);
 }
Ejemplo n.º 5
0
        public void WriteSpawnData(IWriteMessage msg, UInt16 entityID, UInt16 originalInventoryID, byte originalItemContainerIndex)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            msg.Write(Prefab.OriginalName);
            msg.Write(Prefab.Identifier);
            msg.Write(Description != prefab.Description);
            if (Description != prefab.Description)
            {
                msg.Write(Description);
            }

            msg.Write(entityID);

            if (ParentInventory == null || ParentInventory.Owner == null || originalInventoryID == 0)
            {
                msg.Write((ushort)0);

                msg.Write(Position.X);
                msg.Write(Position.Y);
                msg.Write(Submarine != null ? Submarine.ID : (ushort)0);
            }
            else
            {
                msg.Write(originalInventoryID);
                msg.Write(originalItemContainerIndex);

                int slotIndex = ParentInventory.FindIndex(this);
                msg.Write(slotIndex < 0 ? (byte)255 : (byte)slotIndex);
            }

            msg.Write(body == null ? (byte)0 : (byte)body.BodyType);
            msg.Write(SpawnedInOutpost);

            byte teamID = 0;

            foreach (WifiComponent wifiComponent in GetComponents <WifiComponent>())
            {
                teamID = (byte)wifiComponent.TeamID;
                break;
            }

            msg.Write(teamID);
            bool tagsChanged = tags.Count != prefab.Tags.Count || !tags.All(t => prefab.Tags.Contains(t));

            msg.Write(tagsChanged);
            if (tagsChanged)
            {
                msg.Write(Tags);
            }
        }
Ejemplo n.º 6
0
 public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write(deattachTimer);
 }
Ejemplo n.º 7
0
 public virtual void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write(activePicker == null ? (ushort)0 : activePicker.ID);
 }
Ejemplo n.º 8
0
 public void ClientWrite(IWriteMessage msg, object[] extraData = null)
 {
     msg.Write((string)extraData[2]);
 }
Ejemplo n.º 9
0
        public void ServerWrite(IWriteMessage msg)
        {
            msg.Write(ID);
            msg.Write(Name);
            msg.Write((byte)Gender);
            msg.Write((byte)Race);
            msg.Write((byte)HeadSpriteId);
            msg.Write((byte)Head.HairIndex);
            msg.Write((byte)Head.BeardIndex);
            msg.Write((byte)Head.MoustacheIndex);
            msg.Write((byte)Head.FaceAttachmentIndex);
            msg.Write(ragdollFileName);

            if (Job != null)
            {
                msg.Write(Job.Prefab.Identifier);
                msg.Write((byte)Job.Variant);
                msg.Write((byte)Job.Skills.Count);
                foreach (Skill skill in Job.Skills)
                {
                    msg.Write(skill.Identifier);
                    msg.Write(skill.Level);
                }
            }
            else
            {
                msg.Write("");
                msg.Write((byte)0);
            }
            // TODO: animations
        }
Ejemplo n.º 10
0
        public void WriteSpawnData(IWriteMessage msg, UInt16 entityId, bool restrictMessageSize)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            int msgLength = msg.LengthBytes;

            msg.Write(Info == null);
            msg.Write(entityId);
            msg.Write(SpeciesName);
            msg.Write(Seed);

            if (Removed)
            {
                msg.Write(0.0f);
                msg.Write(0.0f);
            }
            else
            {
                msg.Write(WorldPosition.X);
                msg.Write(WorldPosition.Y);
            }

            msg.Write(Enabled);

            //character with no characterinfo (e.g. some monster)
            if (Info == null)
            {
                TryWriteStatus(msg);
                return;
            }

            Client ownerClient = GameMain.Server.ConnectedClients.Find(c => c.Character == this);

            if (ownerClient != null)
            {
                msg.Write(true);
                msg.Write(ownerClient.ID);
            }
            else if (GameMain.Server.Character == this)
            {
                msg.Write(true);
                msg.Write((byte)0);
            }
            else
            {
                msg.Write(false);
            }

            msg.Write((byte)TeamID);
            msg.Write(this is AICharacter);
            msg.Write(info.SpeciesName);
            info.ServerWrite(msg);

            msg.Write((byte)CampaignInteractionType);


            // Current orders
            msg.Write((byte)info.CurrentOrders.Count(o => o.Order != null));
            foreach (var orderInfo in info.CurrentOrders)
            {
                if (orderInfo.Order == null)
                {
                    continue;
                }
                msg.Write((byte)Order.PrefabList.IndexOf(orderInfo.Order.Prefab));
                msg.Write(orderInfo.Order.TargetEntity == null ? (UInt16)0 : orderInfo.Order.TargetEntity.ID);
                var hasOrderGiver = orderInfo.Order.OrderGiver != null;
                msg.Write(hasOrderGiver);
                if (hasOrderGiver)
                {
                    msg.Write(orderInfo.Order.OrderGiver.ID);
                }
                msg.Write((byte)(string.IsNullOrWhiteSpace(orderInfo.OrderOption) ? 0 : Array.IndexOf(orderInfo.Order.Prefab.Options, orderInfo.OrderOption)));
                msg.Write((byte)orderInfo.ManualPriority);
                var hasTargetPosition = orderInfo.Order.TargetPosition != null;
                msg.Write(hasTargetPosition);
                if (hasTargetPosition)
                {
                    msg.Write(orderInfo.Order.TargetPosition.Position.X);
                    msg.Write(orderInfo.Order.TargetPosition.Position.Y);
                    msg.Write(orderInfo.Order.TargetPosition.Hull == null ? (UInt16)0 : orderInfo.Order.TargetPosition.Hull.ID);
                }
            }

            TryWriteStatus(msg);

            void TryWriteStatus(IWriteMessage msg)
            {
                var tempBuffer = new ReadWriteMessage();

                WriteStatus(tempBuffer);
                if (msg.LengthBytes + tempBuffer.LengthBytes >= 255 && restrictMessageSize)
                {
                    msg.Write(false);
                    DebugConsole.ThrowError($"Error when writing character spawn data: status data caused the length of the message to exceed 255 bytes ({msg.LengthBytes} + {tempBuffer.LengthBytes})");
                }
                else
                {
                    msg.Write(true);
                    WriteStatus(msg);
                }
            }

            DebugConsole.Log("Character spawn message length: " + (msg.LengthBytes - msgLength));
        }
Ejemplo n.º 11
0
 public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write(IsActive);
     lastSentState = IsActive;
 }
Ejemplo n.º 12
0
        public virtual void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            if (extraData != null)
            {
                switch ((NetEntityEvent.Type)extraData[0])
                {
                case NetEntityEvent.Type.InventoryState:
                    msg.WriteRangedInteger(0, 0, 6);
                    msg.Write(GameMain.Server.EntityEventManager.Events.Last()?.ID ?? (ushort)0);
                    Inventory.ServerWrite(msg, c);
                    break;

                case NetEntityEvent.Type.Control:
                    msg.WriteRangedInteger(1, 0, 6);
                    Client owner = (Client)extraData[1];
                    msg.Write(owner != null && owner.Character == this && GameMain.Server.ConnectedClients.Contains(owner) ? owner.ID : (byte)0);
                    break;

                case NetEntityEvent.Type.Status:
                    msg.WriteRangedInteger(2, 0, 6);
                    WriteStatus(msg);
                    break;

                case NetEntityEvent.Type.UpdateSkills:
                    msg.WriteRangedInteger(3, 0, 6);
                    if (Info?.Job == null)
                    {
                        msg.Write((byte)0);
                    }
                    else
                    {
                        msg.Write((byte)Info.Job.Skills.Count);
                        foreach (Skill skill in Info.Job.Skills)
                        {
                            msg.Write(skill.Identifier);
                            msg.Write(skill.Level);
                        }
                    }
                    break;

                case NetEntityEvent.Type.ExecuteAttack:
                    Limb   attackLimb      = extraData[1] as Limb;
                    UInt16 targetEntityID  = (UInt16)extraData[2];
                    int    targetLimbIndex = extraData.Length > 3 ? (int)extraData[3] : 0;
                    msg.WriteRangedInteger(4, 0, 6);
                    msg.Write((byte)(Removed ? 255 : Array.IndexOf(AnimController.Limbs, attackLimb)));
                    msg.Write(targetEntityID);
                    msg.Write((byte)targetLimbIndex);
                    break;

                case NetEntityEvent.Type.AssignCampaignInteraction:
                    msg.WriteRangedInteger(5, 0, 6);
                    msg.Write((byte)CampaignInteractionType);
                    break;

                case NetEntityEvent.Type.ObjectiveManagerOrderState:
                    msg.WriteRangedInteger(6, 0, 6);
                    if (!(AIController is HumanAIController controller))
                    {
                        msg.Write(false);
                        break;
                    }
                    var currentOrderInfo = controller.ObjectiveManager.GetCurrentOrderInfo();
                    if (!currentOrderInfo.HasValue)
                    {
                        msg.Write(false);
                        break;
                    }
                    msg.Write(true);
                    var orderPrefab = currentOrderInfo.Value.Order.Prefab;
                    int orderIndex  = Order.PrefabList.IndexOf(orderPrefab);
                    msg.WriteRangedInteger(orderIndex, 0, Order.PrefabList.Count);
                    if (!orderPrefab.HasOptions)
                    {
                        break;
                    }
                    int optionIndex = orderPrefab.Options.IndexOf(currentOrderInfo.Value.OrderOption);
                    msg.WriteRangedInteger(optionIndex, 0, orderPrefab.Options.Length);
                    break;

                default:
                    DebugConsole.ThrowError("Invalid NetworkEvent type for entity " + ToString() + " (" + (NetEntityEvent.Type)extraData[0] + ")");
                    break;
                }
                msg.WritePadBits();
            }
            else
            {
                msg.Write(ID);

                IWriteMessage tempBuffer = new WriteOnlyMessage();

                if (this == c.Character)
                {
                    tempBuffer.Write(true);
                    if (LastNetworkUpdateID < memInput.Count + 1)
                    {
                        tempBuffer.Write((UInt16)0);
                    }
                    else
                    {
                        tempBuffer.Write((UInt16)(LastNetworkUpdateID - memInput.Count - 1));
                    }
                }
                else
                {
                    tempBuffer.Write(false);

                    bool aiming = false;
                    bool use    = false;
                    bool attack = false;
                    bool shoot  = false;

                    if (IsRemotePlayer)
                    {
                        aiming = dequeuedInput.HasFlag(InputNetFlags.Aim);
                        use    = dequeuedInput.HasFlag(InputNetFlags.Use);
                        attack = dequeuedInput.HasFlag(InputNetFlags.Attack);
                        shoot  = dequeuedInput.HasFlag(InputNetFlags.Shoot);
                    }
                    else if (keys != null)
                    {
                        aiming            = keys[(int)InputType.Aim].GetHeldQueue;
                        use               = keys[(int)InputType.Use].GetHeldQueue;
                        attack            = keys[(int)InputType.Attack].GetHeldQueue;
                        shoot             = keys[(int)InputType.Shoot].GetHeldQueue;
                        networkUpdateSent = true;
                    }

                    tempBuffer.Write(aiming);
                    tempBuffer.Write(shoot);
                    tempBuffer.Write(use);
                    if (AnimController is HumanoidAnimController)
                    {
                        tempBuffer.Write(((HumanoidAnimController)AnimController).Crouching);
                    }
                    tempBuffer.Write(attack);

                    Vector2 relativeCursorPos = cursorPosition - AimRefPosition;
                    tempBuffer.Write((UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI)));

                    tempBuffer.Write(IsRagdolled || Stun > 0.0f || IsDead || IsIncapacitated);

                    tempBuffer.Write(AnimController.Dir > 0.0f);
                }

                if (SelectedCharacter != null || SelectedConstruction != null)
                {
                    tempBuffer.Write(true);
                    tempBuffer.Write(SelectedCharacter != null ? SelectedCharacter.ID : NullEntityID);
                    tempBuffer.Write(SelectedConstruction != null ? SelectedConstruction.ID : NullEntityID);
                    if (SelectedCharacter != null)
                    {
                        tempBuffer.Write(AnimController.Anim == AnimController.Animation.CPR);
                    }
                }
                else
                {
                    tempBuffer.Write(false);
                }

                tempBuffer.Write(SimPosition.X);
                tempBuffer.Write(SimPosition.Y);
                float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
                AnimController.Collider.LinearVelocity = new Vector2(
                    MathHelper.Clamp(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel),
                    MathHelper.Clamp(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel));
                tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12);
                tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12);

                bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation || !AnimController.Collider.PhysEnabled;
                tempBuffer.Write(fixedRotation);
                if (!fixedRotation)
                {
                    tempBuffer.Write(AnimController.Collider.Rotation);
                    float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
                    AnimController.Collider.AngularVelocity = NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
                    tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8);
                }

                bool writeStatus = healthUpdateTimer <= 0.0f;
                tempBuffer.Write(writeStatus);
                if (writeStatus)
                {
                    WriteStatus(tempBuffer);
                    (AIController as EnemyAIController)?.PetBehavior?.ServerWrite(tempBuffer);
                    HealthUpdatePending = false;
                }

                tempBuffer.WritePadBits();

                msg.WriteVariableUInt32((uint)tempBuffer.LengthBytes);
                msg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Writes all the events that the client hasn't received yet into the outgoing message
        /// </summary>
        public void Write(Client client, IWriteMessage msg, out List <NetEntityEvent> sentEvents)
        {
            List <NetEntityEvent> eventsToSync = null;

            if (client.NeedsMidRoundSync)
            {
                eventsToSync = GetEventsToSync(client);
            }
            else
            {
                eventsToSync = GetEventsToSync(client);
            }

            if (eventsToSync.Count == 0)
            {
                sentEvents = eventsToSync;
                return;
            }

            //too many events for one packet
            //(normal right after a round has just started, don't show a warning if it's been less than 10 seconds)
            if (eventsToSync.Count > 200 && GameMain.GameSession != null && Timing.TotalTime > GameMain.GameSession.RoundStartTime + 10.0)
            {
                if (eventsToSync.Count > 200 && !client.NeedsMidRoundSync && Timing.TotalTime > lastEventCountHighWarning + 2.0)
                {
                    Color color = eventsToSync.Count > 500 ? Color.Red : Color.Orange;
                    if (eventsToSync.Count < 300)
                    {
                        color = Color.Yellow;
                    }
                    string warningMsg = "WARNING: event count very high: " + eventsToSync.Count;

                    var sortedEvents = eventsToSync.GroupBy(e => e.Entity.ToString())
                                       .Select(e => new { Value = e.Key, Count = e.Count() })
                                       .OrderByDescending(e => e.Count);

                    int count = 1;
                    foreach (var sortedEvent in sortedEvents)
                    {
                        warningMsg += "\n" + count + ". " + (sortedEvent.Value?.ToString() ?? "null") + " x" + sortedEvent.Count;
                        count++;
                        if (count > 3)
                        {
                            break;
                        }
                    }
                    if (GameSettings.VerboseLogging)
                    {
                        GameServer.Log(warningMsg, ServerLog.MessageType.Error);
                    }
                    DebugConsole.NewMessage(warningMsg, color);
                    lastEventCountHighWarning = Timing.TotalTime;
                }
            }

            if (client.NeedsMidRoundSync)
            {
                msg.Write((byte)ServerNetObject.ENTITY_EVENT_INITIAL);
                msg.Write(client.UnreceivedEntityEventCount);
                msg.Write(client.FirstNewEventID);

                Write(msg, eventsToSync, out sentEvents, client);
            }
            else
            {
                msg.Write((byte)ServerNetObject.ENTITY_EVENT);
                Write(msg, eventsToSync, out sentEvents, client);
            }

            foreach (NetEntityEvent entityEvent in sentEvents)
            {
                (entityEvent as ServerEntityEvent).Sent    = true;
                client.EntityEventLastSent[entityEvent.ID] = Lidgren.Network.NetTime.Now;
            }
        }
Ejemplo n.º 14
0
 public void Serialize(IWriteMessage msg)
 {
     msg.Write(RadiationEnabled);
     msg.Write(MaxMissionCount);
 }
Ejemplo n.º 15
0
 public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write(user == null ? (ushort)0 : user.ID);
     ClientWrite(msg, extraData);
 }
Ejemplo n.º 16
0
        public void ServerWrite(IWriteMessage msg)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            msg.Write(allowSubVoting);
            if (allowSubVoting)
            {
                List <Pair <object, int> > voteList = GetVoteList(VoteType.Sub, GameMain.Server.ConnectedClients);
                msg.Write((byte)voteList.Count);
                foreach (Pair <object, int> vote in voteList)
                {
                    msg.Write((byte)vote.Second);
                    msg.Write(((SubmarineInfo)vote.First).Name);
                }
            }
            msg.Write(AllowModeVoting);
            if (allowModeVoting)
            {
                List <Pair <object, int> > voteList = GetVoteList(VoteType.Mode, GameMain.Server.ConnectedClients);
                msg.Write((byte)voteList.Count);
                foreach (Pair <object, int> vote in voteList)
                {
                    msg.Write((byte)vote.Second);
                    msg.Write(((GameModePreset)vote.First).Identifier);
                }
            }
            msg.Write(AllowEndVoting);
            if (AllowEndVoting)
            {
                msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned && c.GetVote <bool>(VoteType.EndRound)));
                msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned));
            }

            msg.Write(AllowVoteKick);

            msg.Write((byte)SubVote.State);
            if (SubVote.State != VoteState.None)
            {
                msg.Write((byte)SubVote.VoteType);

                if (SubVote.VoteType != VoteType.Unknown)
                {
                    var yesClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <int>(SubVote.VoteType) == 2);
                    msg.Write((byte)yesClients.Count);
                    foreach (Client c in yesClients)
                    {
                        msg.Write(c.ID);
                    }

                    var noClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <int>(SubVote.VoteType) == 1);
                    msg.Write((byte)noClients.Count);
                    foreach (Client c in noClients)
                    {
                        msg.Write(c.ID);
                    }

                    msg.Write((byte)GameMain.Server.SubmarineVoteMax);

                    switch (SubVote.State)
                    {
                    case VoteState.Started:
                        msg.Write(SubVote.Sub.Name);
                        msg.Write(SubVote.VoteStarter.ID);
                        msg.Write((byte)GameMain.Server.ServerSettings.SubmarineVoteTimeout);
                        break;

                    case VoteState.Running:
                        // Nothing specific
                        break;

                    case VoteState.Passed:
                    case VoteState.Failed:
                        msg.Write(SubVote.State == VoteState.Passed);
                        msg.Write(SubVote.Sub.Name);
                        if (SubVote.State == VoteState.Passed)
                        {
                            msg.Write((short)SubVote.DeliveryFee);
                        }
                        break;
                    }
                }
            }

            var readyClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <bool>(VoteType.StartRound));

            msg.Write((byte)readyClients.Count);
            foreach (Client c in readyClients)
            {
                msg.Write(c.ID);
            }

            msg.WritePadBits();
        }
 public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write(Value);
     lastSentValue = Value;
 }
Ejemplo n.º 18
0
        public void ClientWrite(IWriteMessage msg)
        {
            System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue);

            msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex);
            msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex);
            msg.Write(map.SelectedMissionIndex == -1 ? byte.MaxValue : (byte)map.SelectedMissionIndex);
            msg.Write(PurchasedHullRepairs);
            msg.Write(PurchasedItemRepairs);
            msg.Write(PurchasedLostShuttles);

            msg.Write((UInt16)CargoManager.ItemsInBuyCrate.Count);
            foreach (PurchasedItem pi in CargoManager.ItemsInBuyCrate)
            {
                msg.Write(pi.ItemPrefab.Identifier);
                msg.WriteRangedInteger(pi.Quantity, 0, 100);
            }

            msg.Write((UInt16)CargoManager.PurchasedItems.Count);
            foreach (PurchasedItem pi in CargoManager.PurchasedItems)
            {
                msg.Write(pi.ItemPrefab.Identifier);
                msg.WriteRangedInteger(pi.Quantity, 0, 100);
            }

            msg.Write((UInt16)CargoManager.SoldItems.Count);
            foreach (SoldItem si in CargoManager.SoldItems)
            {
                msg.Write(si.ItemPrefab.Identifier);
                msg.Write((UInt16)si.ID);
                msg.Write(si.Removed);
                msg.Write(si.SellerID);
            }

            msg.Write((ushort)UpgradeManager.PurchasedUpgrades.Count);
            foreach (var(prefab, category, level) in UpgradeManager.PurchasedUpgrades)
            {
                msg.Write(prefab.Identifier);
                msg.Write(category.Identifier);
                msg.Write((byte)level);
            }
        }
Ejemplo n.º 19
0
        public void ServerWrite(IWriteMessage msg, Client c)
        {
            System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue);

            Reputation reputation = Map?.CurrentLocation?.Reputation;

            msg.Write(IsFirstRound);
            msg.Write(CampaignID);
            msg.Write(lastUpdateID);
            msg.Write(lastSaveID);
            msg.Write(map.Seed);
            msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex);
            msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex);

            var selectedMissionIndices = map.GetSelectedMissionIndices();

            msg.Write((byte)selectedMissionIndices.Count());
            foreach (int selectedMissionIndex in selectedMissionIndices)
            {
                msg.Write((byte)selectedMissionIndex);
            }

            msg.Write(map.AllowDebugTeleport);
            msg.Write(reputation != null);
            if (reputation != null)
            {
                msg.Write(reputation.Value);
            }

            // hopefully we'll never have more than 128 factions
            msg.Write((byte)Factions.Count);
            foreach (Faction faction in Factions)
            {
                msg.Write(faction.Prefab.Identifier);
                msg.Write(faction.Reputation.Value);
            }

            msg.Write(ForceMapUI);

            msg.Write(Money);
            msg.Write(PurchasedHullRepairs);
            msg.Write(PurchasedItemRepairs);
            msg.Write(PurchasedLostShuttles);

            if (map.CurrentLocation != null)
            {
                msg.Write((byte)map.CurrentLocation?.AvailableMissions.Count());
                foreach (Mission mission in map.CurrentLocation.AvailableMissions)
                {
                    msg.Write(mission.Prefab.Identifier);
                    if (mission.Locations[0] == mission.Locations[1])
                    {
                        msg.Write((byte)255);
                    }
                    else
                    {
                        Location           missionDestination = mission.Locations[0] == map.CurrentLocation ? mission.Locations[1] : mission.Locations[0];
                        LocationConnection connection         = map.CurrentLocation.Connections.Find(c => c.OtherLocation(map.CurrentLocation) == missionDestination);
                        msg.Write((byte)map.CurrentLocation.Connections.IndexOf(connection));
                    }
                }

                // Store balance
                msg.Write(true);
                msg.Write((UInt16)map.CurrentLocation.StoreCurrentBalance);
            }
            else
            {
                msg.Write((byte)0);
                // Store balance
                msg.Write(false);
            }

            msg.Write((UInt16)CargoManager.ItemsInBuyCrate.Count);
            foreach (PurchasedItem pi in CargoManager.ItemsInBuyCrate)
            {
                msg.Write(pi.ItemPrefab.Identifier);
                msg.WriteRangedInteger(pi.Quantity, 0, 100);
            }

            msg.Write((UInt16)CargoManager.PurchasedItems.Count);
            foreach (PurchasedItem pi in CargoManager.PurchasedItems)
            {
                msg.Write(pi.ItemPrefab.Identifier);
                msg.WriteRangedInteger(pi.Quantity, 0, 100);
            }

            msg.Write((UInt16)CargoManager.SoldItems.Count);
            foreach (SoldItem si in CargoManager.SoldItems)
            {
                msg.Write(si.ItemPrefab.Identifier);
                msg.Write((UInt16)si.ID);
                msg.Write(si.Removed);
                msg.Write(si.SellerID);
            }

            msg.Write((ushort)UpgradeManager.PendingUpgrades.Count);
            foreach (var(prefab, category, level) in UpgradeManager.PendingUpgrades)
            {
                msg.Write(prefab.Identifier);
                msg.Write(category.Identifier);
                msg.Write((byte)level);
            }

            msg.Write((ushort)UpgradeManager.PurchasedItemSwaps.Count);
            foreach (var itemSwap in UpgradeManager.PurchasedItemSwaps)
            {
                msg.Write(itemSwap.ItemToRemove.ID);
                msg.Write(itemSwap.ItemToInstall?.Identifier ?? string.Empty);
            }

            var characterData = GetClientCharacterData(c);

            if (characterData?.CharacterInfo == null)
            {
                msg.Write(false);
            }
            else
            {
                msg.Write(true);
                characterData.CharacterInfo.ServerWrite(msg);
            }
        }
Ejemplo n.º 20
0
 public void ServerWrite(IWriteMessage msg, Client client, object[] extraData = null)
 {
     msg.Write(IsAlive);
 }
Ejemplo n.º 21
0
 public override void ClientWrite(IWriteMessage msg)
 {
     msg.Write((byte)ClientNetObject.CHAT_MESSAGE);
     msg.Write(NetStateID);
     msg.Write((byte)ChatMessageType.Order);
     msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab));
     msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID);
     msg.Write(TargetEntity is Entity ? (TargetEntity as Entity).ID : (UInt16)0);
     msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption));
     msg.Write((byte)Order.TargetType);
     if (Order.TargetType == Order.OrderTargetType.Position && TargetEntity is OrderTarget orderTarget)
     {
         msg.Write(true);
         msg.Write(orderTarget.Position.X);
         msg.Write(orderTarget.Position.Y);
         msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID);
     }
     else
     {
         msg.Write(false);
         if (Order.TargetType == Order.OrderTargetType.WallSection)
         {
             msg.Write((byte)(WallSectionIndex ?? Order.WallSectionIndex ?? 0));
         }
     }
 }
Ejemplo n.º 22
0
        public void ServerWrite(IWriteMessage msg, Barotrauma.Networking.Client c, object[] extraData = null)
        {
            msg.Write(autoPilot);
            msg.Write(extraData.Length > 2 && extraData[2] is bool && (bool)extraData[2]);

            if (!autoPilot)
            {
                //no need to write steering info if autopilot is controlling
                msg.Write(steeringInput.X);
                msg.Write(steeringInput.Y);
                msg.Write(targetVelocity.X);
                msg.Write(targetVelocity.Y);
                msg.Write(steeringAdjustSpeed);
            }
            else
            {
                msg.Write(posToMaintain != null);
                if (posToMaintain != null)
                {
                    msg.Write(((Vector2)posToMaintain).X);
                    msg.Write(((Vector2)posToMaintain).Y);
                }
                else
                {
                    msg.Write(LevelStartSelected);
                }
            }
        }
Ejemplo n.º 23
0
        public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
        {
            string errorMsg = "";

            if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type))
            {
                if (extraData == null)
                {
                    errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was null.";
                }
                else if (extraData.Length == 0)
                {
                    errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was empty.";
                }
                else
                {
                    errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event type not set.";
                }
                msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1);
                DebugConsole.Log(errorMsg);
                GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:InvalidData" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
                return;
            }

            int initialWritePos = msg.LengthBits;

            NetEntityEvent.Type eventType = (NetEntityEvent.Type)extraData[0];
            msg.WriteRangedInteger((int)eventType, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1);
            switch (eventType)
            {
            case NetEntityEvent.Type.ComponentState:
                if (extraData.Length < 2 || !(extraData[1] is int))
                {
                    errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index not given.";
                    break;
                }
                int componentIndex = (int)extraData[1];
                if (componentIndex < 0 || componentIndex >= components.Count)
                {
                    errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index out of range (" + componentIndex + ").";
                    break;
                }
                else if (!(components[componentIndex] is IServerSerializable))
                {
                    errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component \"" + components[componentIndex] + "\" is not server serializable.";
                    break;
                }
                msg.WriteRangedInteger(componentIndex, 0, components.Count - 1);
                (components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData);
                break;

            case NetEntityEvent.Type.InventoryState:
                if (extraData.Length < 2 || !(extraData[1] is int))
                {
                    errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component index not given.";
                    break;
                }
                int containerIndex = (int)extraData[1];
                if (containerIndex < 0 || containerIndex >= components.Count)
                {
                    errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - container index out of range (" + containerIndex + ").";
                    break;
                }
                else if (!(components[containerIndex] is ItemContainer))
                {
                    errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component \"" + components[containerIndex] + "\" is not server serializable.";
                    break;
                }
                msg.WriteRangedInteger(containerIndex, 0, components.Count - 1);
                msg.Write(GameMain.Server.EntityEventManager.Events.Last()?.ID ?? (ushort)0);
                (components[containerIndex] as ItemContainer).Inventory.ServerWrite(msg, c);
                break;

            case NetEntityEvent.Type.Status:
                msg.Write(condition);
                break;

            case NetEntityEvent.Type.Treatment:
            {
                ItemComponent targetComponent = (ItemComponent)extraData[1];
                ActionType    actionType      = (ActionType)extraData[2];
                ushort        targetID        = (ushort)extraData[3];
                Limb          targetLimb      = (Limb)extraData[4];

                Character targetCharacter = FindEntityByID(targetID) as Character;
                byte      targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255;

                msg.Write((byte)components.IndexOf(targetComponent));
                msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1);
                msg.Write(targetID);
                msg.Write(targetLimbIndex);
            }
            break;

            case NetEntityEvent.Type.ApplyStatusEffect:
            {
                ActionType    actionType      = (ActionType)extraData[1];
                ItemComponent targetComponent = extraData.Length > 2 ? (ItemComponent)extraData[2] : null;
                ushort        characterID     = extraData.Length > 3 ? (ushort)extraData[3] : (ushort)0;
                Limb          targetLimb      = extraData.Length > 4 ? (Limb)extraData[4] : null;
                ushort        useTargetID     = extraData.Length > 5 ? (ushort)extraData[5] : (ushort)0;
                Vector2?      worldPosition   = null;
                if (extraData.Length > 6)
                {
                    worldPosition = (Vector2)extraData[6];
                }

                Character targetCharacter = FindEntityByID(characterID) as Character;
                byte      targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255;

                msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1);
                msg.Write((byte)(targetComponent == null ? 255 : components.IndexOf(targetComponent)));
                msg.Write(characterID);
                msg.Write(targetLimbIndex);
                msg.Write(useTargetID);
                msg.Write(worldPosition.HasValue);
                if (worldPosition.HasValue)
                {
                    msg.Write(worldPosition.Value.X);
                    msg.Write(worldPosition.Value.Y);
                }
            }
            break;

            case NetEntityEvent.Type.ChangeProperty:
                try
                {
                    WritePropertyChange(msg, extraData, inGameEditableOnly: !GameMain.NetworkMember.IsServer);
                }
                catch (Exception e)
                {
                    errorMsg = "Failed to write a ChangeProperty network event for the item \"" + Name + "\" (" + e.Message + ")";
                }
                break;

            case NetEntityEvent.Type.Upgrade:
                if (extraData.Length > 0 && extraData[1] is Upgrade upgrade)
                {
                    var upgradeTargets = upgrade.TargetComponents;
                    msg.Write(upgrade.Identifier);
                    msg.Write((byte)upgrade.Level);
                    msg.Write((byte)upgradeTargets.Count);
                    foreach (var(_, value) in upgrade.TargetComponents)
                    {
                        msg.Write((byte)value.Length);
                        foreach (var propertyReference in value)
                        {
                            object originalValue = propertyReference.OriginalValue;
                            msg.Write((float)(originalValue ?? -1));
                        }
                    }
                }
                else
                {
                    errorMsg = extraData.Length > 0
                            ? $"Failed to write a network event for the item \"{Name}\" - \"{extraData[1].GetType()}\" is not a valid upgrade."
                            : $"Failed to write a network event for the item \"{Name}\". No upgrade specified.";
                }
                break;

            default:
                errorMsg = "Failed to write a network event for the item \"" + Name + "\" - \"" + eventType + "\" is not a valid entity event type for items.";
                break;
            }

            if (!string.IsNullOrEmpty(errorMsg))
            {
                //something went wrong - rewind the write position and write invalid event type to prevent creating an unreadable event
                msg.BitPosition = initialWritePos;
                msg.LengthBits  = initialWritePos;
                msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1);
                DebugConsole.Log(errorMsg);
                GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:" + errorMsg, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
            }
        }
Ejemplo n.º 24
0
        public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
        {
            string errorMsg = "";

            if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type))
            {
                if (extraData == null)
                {
                    errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was null.";
                }
                else if (extraData.Length == 0)
                {
                    errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was empty.";
                }
                else
                {
                    errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event type not set.";
                }
                msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1);
                DebugConsole.Log(errorMsg);
                GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:InvalidData" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
                return;
            }

            int initialWritePos = msg.LengthBits;

            NetEntityEvent.Type eventType = (NetEntityEvent.Type)extraData[0];
            msg.WriteRangedInteger((int)eventType, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1);
            switch (eventType)
            {
            case NetEntityEvent.Type.ComponentState:
                if (extraData.Length < 2 || !(extraData[1] is int))
                {
                    errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index not given.";
                    break;
                }
                int componentIndex = (int)extraData[1];
                if (componentIndex < 0 || componentIndex >= components.Count)
                {
                    errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index out of range (" + componentIndex + ").";
                    break;
                }
                else if (!(components[componentIndex] is IServerSerializable))
                {
                    errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component \"" + components[componentIndex] + "\" is not server serializable.";
                    break;
                }
                msg.WriteRangedInteger(componentIndex, 0, components.Count - 1);
                (components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData);
                break;

            case NetEntityEvent.Type.InventoryState:
                if (extraData.Length < 2 || !(extraData[1] is int))
                {
                    errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component index not given.";
                    break;
                }
                int containerIndex = (int)extraData[1];
                if (containerIndex < 0 || containerIndex >= components.Count)
                {
                    errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - container index out of range (" + containerIndex + ").";
                    break;
                }
                else if (!(components[containerIndex] is ItemContainer))
                {
                    errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component \"" + components[containerIndex] + "\" is not server serializable.";
                    break;
                }
                msg.WriteRangedInteger(containerIndex, 0, components.Count - 1);
                (components[containerIndex] as ItemContainer).Inventory.ServerWrite(msg, c);
                break;

            case NetEntityEvent.Type.Status:
                msg.Write(condition);
                break;

            case NetEntityEvent.Type.Treatment:
            {
                ItemComponent targetComponent = (ItemComponent)extraData[1];
                ActionType    actionType      = (ActionType)extraData[2];
                ushort        targetID        = (ushort)extraData[3];
                Limb          targetLimb      = (Limb)extraData[4];

                Character targetCharacter = FindEntityByID(targetID) as Character;
                byte      targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255;

                msg.Write((byte)components.IndexOf(targetComponent));
                msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1);
                msg.Write(targetID);
                msg.Write(targetLimbIndex);
            }
            break;

            case NetEntityEvent.Type.ApplyStatusEffect:
            {
                ActionType    actionType      = (ActionType)extraData[1];
                ItemComponent targetComponent = extraData.Length > 2 ? (ItemComponent)extraData[2] : null;
                ushort        targetID        = extraData.Length > 3 ? (ushort)extraData[3] : (ushort)0;
                Limb          targetLimb      = extraData.Length > 4 ? (Limb)extraData[4] : null;

                Character targetCharacter = FindEntityByID(targetID) as Character;
                byte      targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255;

                msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1);
                msg.Write((byte)(targetComponent == null ? 255 : components.IndexOf(targetComponent)));
                msg.Write(targetID);
                msg.Write(targetLimbIndex);
            }
            break;

            case NetEntityEvent.Type.ChangeProperty:
                try
                {
                    WritePropertyChange(msg, extraData, false);
                }
                catch (Exception e)
                {
                    errorMsg = "Failed to write a ChangeProperty network event for the item \"" + Name + "\" (" + e.Message + ")";
                }
                break;

            default:
                errorMsg = "Failed to write a network event for the item \"" + Name + "\" - \"" + eventType + "\" is not a valid entity event type for items.";
                break;
            }

            if (!string.IsNullOrEmpty(errorMsg))
            {
                //something went wrong - rewind the write position and write invalid event type to prevent creating an unreadable event
                msg.BitPosition = initialWritePos;
                msg.LengthBits  = initialWritePos;
                msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1);
                DebugConsole.Log(errorMsg);
                GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:" + errorMsg, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
            }
        }
Ejemplo n.º 25
0
        public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
        {
            Item item = (Item)extraData[2];

            msg.Write(item.Removed ? (ushort)0 : item.ID);
        }
Ejemplo n.º 26
0
        public void WriteSpawnData(IWriteMessage msg)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            msg.Write(Prefab.OriginalName);
            msg.Write(Prefab.Identifier);
            msg.Write(Description != prefab.Description);
            if (Description != prefab.Description)
            {
                msg.Write(Description);
            }

            msg.Write(ID);

            if (ParentInventory == null || ParentInventory.Owner == null)
            {
                msg.Write((ushort)0);

                msg.Write(Position.X);
                msg.Write(Position.Y);
                msg.Write(Submarine != null ? Submarine.ID : (ushort)0);
            }
            else
            {
                msg.Write(ParentInventory.Owner.ID);

                //find the index of the ItemContainer this item is inside to get the item to
                //spawn in the correct inventory in multi-inventory items like fabricators
                byte containerIndex = 0;
                if (Container != null)
                {
                    for (int i = 0; i < Container.components.Count; i++)
                    {
                        if (Container.components[i] is ItemContainer container &&
                            container.Inventory == ParentInventory)
                        {
                            containerIndex = (byte)i;
                            break;
                        }
                    }
                }
                msg.Write(containerIndex);

                int slotIndex = ParentInventory.FindIndex(this);
                msg.Write(slotIndex < 0 ? (byte)255 : (byte)slotIndex);
            }

            byte teamID = 0;

            foreach (WifiComponent wifiComponent in GetComponents <WifiComponent>())
            {
                teamID = (byte)wifiComponent.TeamID;
                break;
            }

            msg.Write(teamID);
            bool tagsChanged = tags.Count != prefab.Tags.Count || !tags.All(t => prefab.Tags.Contains(t));

            msg.Write(tagsChanged);
            if (tagsChanged)
            {
                msg.Write(Tags);
            }
        }
Ejemplo n.º 27
0
        public virtual void ServerWrite(IWriteMessage msg, Client c)
        {
            msg.Write((byte)ServerNetObject.CHAT_MESSAGE);
            msg.Write(NetStateID);
            msg.Write((byte)Type);
            msg.Write((byte)ChangeType);
            msg.Write(Text);

            msg.Write(SenderName);
            msg.Write(SenderClient != null);
            if (SenderClient != null)
            {
                msg.Write((SenderClient.SteamID != 0) ? SenderClient.SteamID : SenderClient.ID);
            }
            msg.Write(Sender != null && c.InGame);
            if (Sender != null && c.InGame)
            {
                msg.Write(Sender.ID);
            }
            msg.WritePadBits();
            if (Type == ChatMessageType.ServerMessageBoxInGame)
            {
                msg.Write(IconStyle);
            }
        }
Ejemplo n.º 28
0
 public override void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write((byte)Variant);
     base.ServerWrite(msg, c, extraData);
 }
Ejemplo n.º 29
0
 public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write(state);
 }
Ejemplo n.º 30
0
        private void WriteOrder(IWriteMessage msg)
        {
            msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab));
            msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID);
            msg.Write(TargetEntity is Entity ? (TargetEntity as Entity).ID : (UInt16)0);

            // 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 (Order.Prefab.Identifier != "dismissed")
            {
                msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption));
            }
            else
            {
                if (!string.IsNullOrEmpty(OrderOption))
                {
                    msg.Write(true);
                    string[] dismissedOrder = OrderOption.Split('.');
                    msg.Write((byte)dismissedOrder.Length);
                    if (dismissedOrder.Length > 0)
                    {
                        string dismissedOrderIdentifier = dismissedOrder[0];
                        var    orderPrefab = Order.GetPrefab(dismissedOrderIdentifier);
                        msg.Write((byte)Order.PrefabList.IndexOf(orderPrefab));
                        if (dismissedOrder.Length > 1)
                        {
                            string dismissedOrderOption = dismissedOrder[1];
                            msg.Write((byte)Array.IndexOf(orderPrefab.Options, dismissedOrderOption));
                        }
                    }
                }
                else
                {
                    // If the order option is not specified for a Dismiss order,
                    // we dismiss all current orders for the character
                    msg.Write(false);
                }
            }

            msg.Write((byte)OrderPriority);
            msg.Write((byte)Order.TargetType);
            if (Order.TargetType == Order.OrderTargetType.Position && TargetEntity is OrderTarget orderTarget)
            {
                msg.Write(true);
                msg.Write(orderTarget.Position.X);
                msg.Write(orderTarget.Position.Y);
                msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID);
            }
            else
            {
                msg.Write(false);
                if (Order.TargetType == Order.OrderTargetType.WallSection)
                {
                    msg.Write((byte)(WallSectionIndex ?? Order.WallSectionIndex ?? 0));
                }
            }
        }