Example #1
0
        public void ServerRead(ClientNetObject type, IReadMessage msg, Client c)
        {
            int     nodeCount   = msg.ReadByte();
            Vector2 lastNodePos = Vector2.Zero;

            if (nodeCount > 0)
            {
                lastNodePos = new Vector2(msg.ReadSingle(), msg.ReadSingle());
            }

            if (!item.CanClientAccess(c))
            {
                return;
            }

            if (nodes.Count > nodeCount)
            {
                nodes.RemoveRange(nodeCount, nodes.Count - nodeCount);
            }
            if (nodeCount > 0)
            {
                if (nodeCount > nodes.Count)
                {
                    nodes.Add(lastNodePos);
                }
                else
                {
                    nodes[nodes.Count - 1] = lastNodePos;
                }
            }
            CreateNetworkEvent();
        }
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            var newState = (State)msg.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length);

            switch (newState)
            {
            case State.Transporting:
                ReturnCountdownStarted = msg.ReadBoolean();
                maxTransportTime       = msg.ReadSingle();
                float transportTimeLeft = msg.ReadSingle();

                ReturnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(transportTimeLeft * 1000.0f));
                RespawnCountdownStarted = false;
                if (CurrentState != newState)
                {
                    CoroutineManager.StopCoroutines("forcepos");
                    //CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition - Vector2.UnitY * Level.ShaftHeight, 100.0f), "forcepos");
                }
                break;

            case State.Waiting:
                RespawnCountdownStarted = msg.ReadBoolean();
                ResetShuttle();
                float newRespawnTime = msg.ReadSingle();
                RespawnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(newRespawnTime * 1000.0f));
                break;

            case State.Returning:
                RespawnCountdownStarted = false;
                break;
            }
            CurrentState = newState;

            msg.ReadPadBits();
        }
Example #3
0
        public override void ClientReadInitial(IReadMessage msg)
        {
            byte selectedCaveIndex = msg.ReadByte();

            nestPosition = new Vector2(
                msg.ReadSingle(),
                msg.ReadSingle());
            if (selectedCaveIndex < 255 && Level.Loaded != null)
            {
                if (selectedCaveIndex < Level.Loaded.Caves.Count)
                {
                    Level.Loaded.Caves[selectedCaveIndex].DisplayOnSonar = true;
                    SpawnNestObjects(Level.Loaded, Level.Loaded.Caves[selectedCaveIndex]);
                }
                else
                {
                    DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCaveIndex}, number of caves: {Level.Loaded.Caves.Count}");
                }
            }

            ushort itemCount = msg.ReadUInt16();

            for (int i = 0; i < itemCount; i++)
            {
                var item = Item.ReadSpawnData(msg);
                items.Add(item);
                if (item.body != null)
                {
                    item.body.FarseerBody.BodyType = BodyType.Kinematic;
                }
            }
        }
Example #4
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            int eventIndex     = msg.ReadRangedInteger(0, (int)Math.Ceiling(MaxNodeCount / (float)MaxNodesPerNetworkEvent));
            int nodeCount      = msg.ReadRangedInteger(0, MaxNodesPerNetworkEvent);
            int nodeStartIndex = eventIndex * MaxNodesPerNetworkEvent;

            Vector2[] nodePositions = new Vector2[nodeStartIndex + nodeCount];
            for (int i = 0; i < nodes.Count && i < nodePositions.Length; i++)
            {
                nodePositions[i] = nodes[i];
            }

            for (int i = 0; i < nodeCount; i++)
            {
                nodePositions[nodeStartIndex + i] = new Vector2(msg.ReadSingle(), msg.ReadSingle());
            }

            if (nodePositions.Any(n => !MathUtils.IsValid(n)))
            {
                nodes.Clear();
                return;
            }

            nodes = nodePositions.ToList();
            UpdateSections();
            Drawable = nodes.Any();
        }
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            bool isGlobalUpdate = msg.ReadBoolean();

            if (isGlobalUpdate)
            {
                foreach (LevelWall levelWall in ExtraWalls)
                {
                    if (levelWall.Body.BodyType == BodyType.Static)
                    {
                        continue;
                    }

                    Vector2 bodyPos = new Vector2(
                        msg.ReadSingle(),
                        msg.ReadSingle());
                    levelWall.MoveState = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 16);
                    DestructibleLevelWall destructibleWall = levelWall as DestructibleLevelWall;
                    if (Vector2.DistanceSquared(bodyPos, levelWall.Body.Position) > 0.5f && (destructibleWall == null || !destructibleWall.Destroyed))
                    {
                        levelWall.Body.SetTransformIgnoreContacts(ref bodyPos, levelWall.Body.Rotation);
                    }
                }
            }
            else
            {
                int  index      = msg.ReadUInt16();
                byte damageByte = msg.ReadByte();
                if (index < ExtraWalls.Count && ExtraWalls[index] is DestructibleLevelWall destructibleWall)
                {
                    destructibleWall.SetDamage(destructibleWall.MaxHealth * damageByte / 255.0f);
                }
            }
        }
Example #6
0
 public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
 {
     deteriorationTimer          = msg.ReadSingle();
     deteriorateAlwaysResetTimer = msg.ReadSingle();
     DeteriorateAlways           = msg.ReadBoolean();
     CurrentFixer       = msg.ReadBoolean() ? Character.Controlled : null;
     currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2);
 }
Example #7
0
        public PosInfo ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime, string parentDebugName)
        {
            float MaxVel        = NetConfig.MaxPhysicsBodyVelocity;
            float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;

            Vector2 newPosition        = SimPosition;
            float?  newRotation        = null;
            bool    awake              = FarseerBody.Awake;
            Vector2 newVelocity        = LinearVelocity;
            float?  newAngularVelocity = null;

            newPosition = new Vector2(
                msg.ReadSingle(),
                msg.ReadSingle());

            awake = msg.ReadBoolean();
            bool fixedRotation = msg.ReadBoolean();

            if (!fixedRotation)
            {
                newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 8);
            }
            if (awake)
            {
                newVelocity = new Vector2(
                    msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
                    msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
                newVelocity = NetConfig.Quantize(newVelocity, -MaxVel, MaxVel, 12);

                if (!fixedRotation)
                {
                    newAngularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8);
                    newAngularVelocity = NetConfig.Quantize(newAngularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8);
                }
            }
            msg.ReadPadBits();

            if (!MathUtils.IsValid(newPosition) ||
                !MathUtils.IsValid(newVelocity) ||
                (newRotation.HasValue && !MathUtils.IsValid(newRotation.Value)) ||
                (newAngularVelocity.HasValue && !MathUtils.IsValid(newAngularVelocity.Value)))
            {
                string errorMsg = "Received invalid position data for \"" + parentDebugName
                                  + "\" (position: " + newPosition + ", rotation: " + (newRotation ?? 0) + ", velocity: " + newVelocity + ", angular velocity: " + (newAngularVelocity ?? 0) + ")";
#if DEBUG
                DebugConsole.ThrowError(errorMsg);
#endif
                GameAnalyticsManager.AddErrorEventOnce("PhysicsBody.ClientRead:InvalidData" + parentDebugName,
                                                       GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
                                                       errorMsg);
                return(null);
            }

            return(lastProcessedNetworkState > sendingTime ?
                   null :
                   new PosInfo(newPosition, newRotation, newVelocity, newAngularVelocity, sendingTime));
        }
Example #8
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            deteriorationTimer          = msg.ReadSingle();
            deteriorateAlwaysResetTimer = msg.ReadSingle();
            DeteriorateAlways           = msg.ReadBoolean();
            ushort currentFixerID = msg.ReadUInt16();

            currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2);
            CurrentFixer       = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null;
        }
Example #9
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            deteriorationTimer          = msg.ReadSingle();
            deteriorateAlwaysResetTimer = msg.ReadSingle();
            DeteriorateAlways           = msg.ReadBoolean();
            tinkeringDuration           = msg.ReadSingle();
            tinkeringStrength           = msg.ReadSingle();
            ushort currentFixerID = msg.ReadUInt16();

            currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2);
            CurrentFixer       = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null;
            item.MaxRepairConditionMultiplier = GetMaxRepairConditionMultiplier(CurrentFixer);
        }
Example #10
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            int msgStartPos = msg.BitPosition;

            float flowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
            bool  isActive       = msg.ReadBoolean();
            bool  hijacked       = msg.ReadBoolean();
            float?targetLevel;

            if (msg.ReadBoolean())
            {
                targetLevel = msg.ReadSingle();
            }
            else
            {
                targetLevel = null;
            }

            if (correctionTimer > 0.0f)
            {
                int msgLength = msg.BitPosition - msgStartPos;
                msg.BitPosition = msgStartPos;
                StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime);
                return;
            }

            FlowPercentage = flowPercentage;
            IsActive       = isActive;
            Hijacked       = hijacked;
            TargetLevel    = targetLevel;
        }
Example #11
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            FabricatorState newState          = (FabricatorState)msg.ReadByte();
            float           newTimeUntilReady = msg.ReadSingle();
            int             itemIndex         = msg.ReadRangedInteger(-1, fabricationRecipes.Count - 1);
            UInt16          userID            = msg.ReadUInt16();
            Character       user = Entity.FindEntityByID(userID) as Character;

            State          = newState;
            timeUntilReady = newTimeUntilReady;

            if (newState == FabricatorState.Stopped || itemIndex == -1 || user == null)
            {
                CancelFabricating();
            }
            else if (newState == FabricatorState.Active || newState == FabricatorState.Paused)
            {
                //if already fabricating the selected item, return
                if (fabricatedItem != null && fabricationRecipes.IndexOf(fabricatedItem) == itemIndex)
                {
                    return;
                }
                if (itemIndex < 0 || itemIndex >= fabricationRecipes.Count)
                {
                    return;
                }

                SelectItem(user, fabricationRecipes[itemIndex]);
                StartFabricating(fabricationRecipes[itemIndex], user);
            }
        }
Example #12
0
        public override void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            base.ClientRead(type, msg, sendingTime);

            bool readAttachData = msg.ReadBoolean();

            if (!readAttachData)
            {
                return;
            }

            bool      shouldBeAttached = msg.ReadBoolean();
            Vector2   simPosition      = new Vector2(msg.ReadSingle(), msg.ReadSingle());
            UInt16    submarineID      = msg.ReadUInt16();
            Submarine sub = Entity.FindEntityByID(submarineID) as Submarine;

            if (shouldBeAttached)
            {
                if (!attached)
                {
                    Drop(false, null);
                    item.SetTransform(simPosition, 0.0f);
                    item.Submarine = sub;
                    AttachToWall();
                }
            }
            else
            {
                if (attached)
                {
                    DropConnectedWires(null);
                    if (body != null)
                    {
                        item.body         = body;
                        item.body.Enabled = true;
                    }
                    IsActive = false;

                    DeattachFromWall();
                }
                else
                {
                    item.SetTransform(simPosition, 0.0f);
                    item.Submarine = sub;
                }
            }
        }
Example #13
0
        public override void ClientReadInitial(IReadMessage msg)
        {
            nestPosition = new Vector2(
                msg.ReadSingle(),
                msg.ReadSingle());
            ushort itemCount = msg.ReadUInt16();

            for (int i = 0; i < itemCount; i++)
            {
                var item = Item.ReadSpawnData(msg);
                items.Add(item);
                if (item.body != null)
                {
                    item.body.FarseerBody.BodyType = BodyType.Kinematic;
                }
            }
        }
Example #14
0
 public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
 {
     deattachTimer = msg.ReadSingle();
     if (deattachTimer >= DeattachDuration)
     {
         holdable.DeattachFromWall();
     }
 }
Example #15
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            bool wasScanCompletedPreviously = IsScanCompleted;

            scanTimer = msg.ReadSingle();
            if (!wasScanCompletedPreviously && IsScanCompleted)
            {
                OnScanCompleted?.Invoke(this);
            }
        }
Example #16
0
        public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
        {
            ushort infoID              = inc.ReadUInt16();
            string newName             = inc.ReadString();
            string originalName        = inc.ReadString();
            int    gender              = inc.ReadByte();
            int    race                = inc.ReadByte();
            int    headSpriteID        = inc.ReadByte();
            int    hairIndex           = inc.ReadByte();
            int    beardIndex          = inc.ReadByte();
            int    moustacheIndex      = inc.ReadByte();
            int    faceAttachmentIndex = inc.ReadByte();
            string ragdollFile         = inc.ReadString();

            string jobIdentifier = inc.ReadString();
            int    variant       = inc.ReadByte();

            JobPrefab jobPrefab = null;
            Dictionary <string, float> skillLevels = new Dictionary <string, float>();

            if (!string.IsNullOrEmpty(jobIdentifier))
            {
                jobPrefab = JobPrefab.Get(jobIdentifier);
                byte skillCount = inc.ReadByte();
                for (int i = 0; i < skillCount; i++)
                {
                    string skillIdentifier = inc.ReadString();
                    float  skillLevel      = inc.ReadSingle();
                    skillLevels.Add(skillIdentifier, skillLevel);
                }
            }

            // TODO: animations
            CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant)
            {
                ID = infoID,
            };

            ch.RecreateHead(headSpriteID, (Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
            if (ch.Job != null)
            {
                foreach (KeyValuePair <string, float> skill in skillLevels)
                {
                    Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
                    if (matchingSkill == null)
                    {
                        ch.Job.Skills.Add(new Skill(skill.Key, skill.Value));
                        continue;
                    }
                    matchingSkill.Level = skill.Value;
                }
                ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
            }
            return(ch);
        }
Example #17
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            foreach (LevelWall levelWall in ExtraWalls)
            {
                if (levelWall.Body.BodyType == BodyType.Static)
                {
                    continue;
                }

                Vector2 bodyPos = new Vector2(
                    msg.ReadSingle(),
                    msg.ReadSingle());

                levelWall.MoveState = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 16);

                if (Vector2.DistanceSquared(bodyPos, levelWall.Body.Position) > 0.5f)
                {
                    levelWall.Body.SetTransformIgnoreContacts(ref bodyPos, levelWall.Body.Rotation);
                }
            }
        }
Example #18
0
        public void ServerRead(ClientNetObject type, IReadMessage msg, Client c)
        {
            Vector2 simPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle());

            if (!item.CanClientAccess(c) || !Attachable || attached || !MathUtils.IsValid(simPosition))
            {
                return;
            }

            Vector2 offset = simPosition - c.Character.SimPosition;

            offset      = offset.ClampLength(MaxAttachDistance * 1.5f);
            simPosition = c.Character.SimPosition + offset;

            Drop(false, null);
            item.SetTransform(simPosition, 0.0f);
            AttachToWall();

            item.CreateServerEvent(this);
            GameServer.Log(GameServer.CharacterLogName(c.Character) + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction);
        }
Example #19
0
        public override void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            base.ClientRead(type, msg, sendingTime);
            bool    shouldBeAttached = msg.ReadBoolean();
            Vector2 simPosition      = new Vector2(msg.ReadSingle(), msg.ReadSingle());

            if (!attachable)
            {
                DebugConsole.ThrowError("Received an attachment event for an item that's not attachable.");
                return;
            }

            if (shouldBeAttached)
            {
                if (!attached)
                {
                    Drop(false, null);
                    item.SetTransform(simPosition, 0.0f);
                    AttachToWall();
                }
            }
            else
            {
                if (attached)
                {
                    DropConnectedWires(null);

                    if (body != null)
                    {
                        item.body         = body;
                        item.body.Enabled = true;
                    }
                    IsActive = false;

                    DeattachFromWall();
                }
            }
        }
Example #20
0
        public static CharacterInfo ClientRead(string speciesName, IReadMessage inc)
        {
            ushort infoID              = inc.ReadUInt16();
            string newName             = inc.ReadString();
            string originalName        = inc.ReadString();
            int    gender              = inc.ReadByte();
            int    race                = inc.ReadByte();
            int    headSpriteID        = inc.ReadByte();
            int    hairIndex           = inc.ReadByte();
            int    beardIndex          = inc.ReadByte();
            int    moustacheIndex      = inc.ReadByte();
            int    faceAttachmentIndex = inc.ReadByte();
            Color  skinColor           = inc.ReadColorR8G8B8();
            Color  hairColor           = inc.ReadColorR8G8B8();
            Color  facialHairColor     = inc.ReadColorR8G8B8();
            string ragdollFile         = inc.ReadString();

            string jobIdentifier = inc.ReadString();
            int    variant       = inc.ReadByte();

            JobPrefab jobPrefab = null;
            Dictionary <string, float> skillLevels = new Dictionary <string, float>();

            if (!string.IsNullOrEmpty(jobIdentifier))
            {
                jobPrefab = JobPrefab.Get(jobIdentifier);
                byte skillCount = inc.ReadByte();
                for (int i = 0; i < skillCount; i++)
                {
                    string skillIdentifier = inc.ReadString();
                    float  skillLevel      = inc.ReadSingle();
                    skillLevels.Add(skillIdentifier, skillLevel);
                }
            }

            // TODO: animations
            CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant)
            {
                ID = infoID,
            };

            ch.RecreateHead(headSpriteID, (Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
            ch.SkinColor       = skinColor;
            ch.HairColor       = hairColor;
            ch.FacialHairColor = facialHairColor;
            if (ch.Job != null)
            {
                foreach (KeyValuePair <string, float> skill in skillLevels)
                {
                    Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
                    if (matchingSkill == null)
                    {
                        ch.Job.Skills.Add(new Skill(skill.Key, skill.Value));
                        continue;
                    }
                    matchingSkill.Level = skill.Value;
                }
                ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier));
            }

            byte savedStatValueCount = inc.ReadByte();

            for (int i = 0; i < savedStatValueCount; i++)
            {
                int    statType       = inc.ReadByte();
                string statIdentifier = inc.ReadString();
                float  statValue      = inc.ReadSingle();
                bool   removeOnDeath  = inc.ReadBoolean();
                ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath);
            }
            ch.ExperiencePoints       = inc.ReadUInt16();
            ch.AdditionalTalentPoints = inc.ReadUInt16();
            return(ch);
        }
Example #21
0
        public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            int msgStartPos = msg.BitPosition;

            bool    autoPilot              = msg.ReadBoolean();
            bool    dockingButtonClicked   = msg.ReadBoolean();
            Vector2 newSteeringInput       = steeringInput;
            Vector2 newTargetVelocity      = targetVelocity;
            float   newSteeringAdjustSpeed = steeringAdjustSpeed;
            Vector2?newPosToMaintain       = null;
            bool    headingToStart         = false;

            if (dockingButtonClicked)
            {
                item.SendSignal(0, "1", "toggle_docking", sender: null);
            }

            if (autoPilot)
            {
                if (msg.ReadBoolean())
                {
                    newPosToMaintain = new Vector2(
                        msg.ReadSingle(),
                        msg.ReadSingle());
                }
                else
                {
                    headingToStart = msg.ReadBoolean();
                }
            }
            else
            {
                newSteeringInput       = new Vector2(msg.ReadSingle(), msg.ReadSingle());
                newTargetVelocity      = new Vector2(msg.ReadSingle(), msg.ReadSingle());
                newSteeringAdjustSpeed = msg.ReadSingle();
            }

            if (correctionTimer > 0.0f)
            {
                int msgLength = (int)(msg.BitPosition - msgStartPos);
                msg.BitPosition = msgStartPos;
                StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime);
                return;
            }

            AutoPilot = autoPilot;

            if (!AutoPilot)
            {
                SteeringInput       = newSteeringInput;
                TargetVelocity      = newTargetVelocity;
                steeringAdjustSpeed = newSteeringAdjustSpeed;
            }
            else
            {
                MaintainPos   = newPosToMaintain != null;
                posToMaintain = newPosToMaintain;

                if (posToMaintain == null)
                {
                    LevelStartSelected = headingToStart;
                    LevelEndSelected   = !headingToStart;
                    UpdatePath();
                }
                else
                {
                    LevelStartSelected = false;
                    LevelEndSelected   = false;
                }
            }
        }
Example #22
0
        public static void ClientRead(IReadMessage inc)
        {
            ReadyCheckState state        = (ReadyCheckState)inc.ReadByte();
            CrewManager?    crewManager  = GameMain.GameSession?.CrewManager;
            List <Client>   otherClients = GameMain.Client.ConnectedClients;

            if (crewManager == null || otherClients == null)
            {
                if (state == ReadyCheckState.Start)
                {
                    SendState(ReadyStatus.No);
                }
                return;
            }

            switch (state)
            {
            case ReadyCheckState.Start:
                bool isOwn    = false;
                byte authorId = 0;

                float  duration  = inc.ReadSingle();
                string author    = inc.ReadString();
                bool   hasAuthor = inc.ReadBoolean();

                if (hasAuthor)
                {
                    authorId = inc.ReadByte();
                    isOwn    = authorId == GameMain.Client.ID;
                }

                ushort      clientCount = inc.ReadUInt16();
                List <byte> clients     = new List <byte>();
                for (int i = 0; i < clientCount; i++)
                {
                    clients.Add(inc.ReadByte());
                }

                ReadyCheck rCheck = new ReadyCheck(clients, duration);
                crewManager.ActiveReadyCheck = rCheck;

                if (isOwn)
                {
                    SendState(ReadyStatus.Yes);
                    rCheck.CreateResultsMessage();
                }
                else
                {
                    rCheck.CreateMessageBox(author);
                }

                if (hasAuthor && rCheck.Clients.ContainsKey(authorId))
                {
                    rCheck.Clients[authorId] = ReadyStatus.Yes;
                }
                break;

            case ReadyCheckState.Update:
                float       time     = inc.ReadSingle();
                ReadyStatus newState = (ReadyStatus)inc.ReadByte();
                byte        targetId = inc.ReadByte();
                if (crewManager.ActiveReadyCheck != null)
                {
                    crewManager.ActiveReadyCheck.time = time;
                    crewManager.ActiveReadyCheck?.UpdateState(targetId, newState);
                }
                break;

            case ReadyCheckState.End:
                ushort count = inc.ReadUInt16();
                for (int i = 0; i < count; i++)
                {
                    byte        id     = inc.ReadByte();
                    ReadyStatus status = (ReadyStatus)inc.ReadByte();
                    crewManager.ActiveReadyCheck?.UpdateState(id, status);
                }

                crewManager.ActiveReadyCheck?.EndReadyCheck();
                crewManager.ActiveReadyCheck?.msgBox?.Close();
                crewManager.ActiveReadyCheck = null;
                break;
            }
        }
Example #23
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;
            }
        }
Example #24
0
            public void Read(IReadMessage msg)
            {
                int    oldPos = msg.BitPosition;
                UInt32 size   = msg.ReadVariableUInt32();

                float x; float y; float z; float w;
                byte  r; byte g; byte b; byte a;
                int   ix; int iy; int width; int height;

                switch (typeString)
                {
                case "float":
                    if (size != 4)
                    {
                        break;
                    }
                    property.SetValue(parentObject, msg.ReadSingle());
                    return;

                case "int":
                    if (size != 4)
                    {
                        break;
                    }
                    property.SetValue(parentObject, msg.ReadInt32());
                    return;

                case "vector2":
                    if (size != 8)
                    {
                        break;
                    }
                    x = msg.ReadSingle();
                    y = msg.ReadSingle();
                    property.SetValue(parentObject, new Vector2(x, y));
                    return;

                case "vector3":
                    if (size != 12)
                    {
                        break;
                    }
                    x = msg.ReadSingle();
                    y = msg.ReadSingle();
                    z = msg.ReadSingle();
                    property.SetValue(parentObject, new Vector3(x, y, z));
                    return;

                case "vector4":
                    if (size != 16)
                    {
                        break;
                    }
                    x = msg.ReadSingle();
                    y = msg.ReadSingle();
                    z = msg.ReadSingle();
                    w = msg.ReadSingle();
                    property.SetValue(parentObject, new Vector4(x, y, z, w));
                    return;

                case "color":
                    if (size != 4)
                    {
                        break;
                    }
                    r = msg.ReadByte();
                    g = msg.ReadByte();
                    b = msg.ReadByte();
                    a = msg.ReadByte();
                    property.SetValue(parentObject, new Color(r, g, b, a));
                    return;

                case "rectangle":
                    if (size != 16)
                    {
                        break;
                    }
                    ix     = msg.ReadInt32();
                    iy     = msg.ReadInt32();
                    width  = msg.ReadInt32();
                    height = msg.ReadInt32();
                    property.SetValue(parentObject, new Rectangle(ix, iy, width, height));
                    return;

                default:
                    msg.BitPosition = oldPos;     //reset position to properly read the string
                    string incVal = msg.ReadString();
                    property.TrySetValue(parentObject, incVal);
                    return;
                }

                //size didn't match: skip this
                msg.BitPosition += (int)(8 * size);
            }
        public void ServerRead(IReadMessage incMsg, Client c)
        {
            if (!c.HasPermission(Networking.ClientPermissions.ManageSettings))
            {
                return;
            }

            NetFlags flags = (NetFlags)incMsg.ReadByte();

            bool changed = false;

            if (flags.HasFlag(NetFlags.Name))
            {
                string serverName = incMsg.ReadString();
                if (ServerName != serverName)
                {
                    changed = true;
                }
                ServerName = serverName;
            }

            if (flags.HasFlag(NetFlags.Message))
            {
                string serverMessageText = incMsg.ReadString();
                if (ServerMessageText != serverMessageText)
                {
                    changed = true;
                }
                ServerMessageText = serverMessageText;
            }

            if (flags.HasFlag(NetFlags.Properties))
            {
                changed |= ReadExtraCargo(incMsg);

                UInt32 count = incMsg.ReadUInt32();

                for (int i = 0; i < count; i++)
                {
                    UInt32 key = incMsg.ReadUInt32();

                    if (netProperties.ContainsKey(key))
                    {
                        object prevValue = netProperties[key].Value;
                        netProperties[key].Read(incMsg);
                        if (!netProperties[key].PropEquals(prevValue, netProperties[key]))
                        {
                            GameServer.Log(GameServer.ClientLogName(c) + " changed " + netProperties[key].Name + " to " + netProperties[key].Value.ToString(), ServerLog.MessageType.ServerMessage);
                        }
                        changed = true;
                    }
                    else
                    {
                        UInt32 size = incMsg.ReadVariableUInt32();
                        incMsg.BitPosition += (int)(8 * size);
                    }
                }

                bool changedMonsterSettings = incMsg.ReadBoolean(); incMsg.ReadPadBits();
                changed |= changedMonsterSettings;
                if (changedMonsterSettings)
                {
                    ReadMonsterEnabled(incMsg);
                }
                changed |= BanList.ServerAdminRead(incMsg, c);
                changed |= Whitelist.ServerAdminRead(incMsg, c);
            }

            if (flags.HasFlag(NetFlags.Misc))
            {
                int orBits  = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
                int andBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
                GameMain.NetLobbyScreen.MissionType = (Barotrauma.MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits);

                int traitorSetting = (int)TraitorsEnabled + incMsg.ReadByte() - 1;
                if (traitorSetting < 0)
                {
                    traitorSetting = 2;
                }
                if (traitorSetting > 2)
                {
                    traitorSetting = 0;
                }
                TraitorsEnabled = (YesNoMaybe)traitorSetting;

                int botCount = BotCount + incMsg.ReadByte() - 1;
                if (botCount < 0)
                {
                    botCount = MaxBotCount;
                }
                if (botCount > MaxBotCount)
                {
                    botCount = 0;
                }
                BotCount = botCount;

                int botSpawnMode = (int)BotSpawnMode + incMsg.ReadByte() - 1;
                if (botSpawnMode < 0)
                {
                    botSpawnMode = 1;
                }
                if (botSpawnMode > 1)
                {
                    botSpawnMode = 0;
                }
                BotSpawnMode = (BotSpawnMode)botSpawnMode;

                float levelDifficulty = incMsg.ReadSingle();
                if (levelDifficulty >= 0.0f)
                {
                    SelectedLevelDifficulty = levelDifficulty;
                }

                UseRespawnShuttle = incMsg.ReadBoolean();

                bool changedAutoRestart = incMsg.ReadBoolean();
                bool autoRestart        = incMsg.ReadBoolean();
                if (changedAutoRestart)
                {
                    AutoRestart = autoRestart;
                }

                changed |= true;
            }

            if (flags.HasFlag(NetFlags.LevelSeed))
            {
                GameMain.NetLobbyScreen.LevelSeed = incMsg.ReadString();
                changed |= true;
            }

            if (changed)
            {
                if (KarmaPreset == "custom")
                {
                    GameMain.NetworkMember?.KarmaManager?.SaveCustomPreset();
                    GameMain.NetworkMember?.KarmaManager?.Save();
                }
                SaveSettings();
                GameMain.NetLobbyScreen.LastUpdateID++;
            }
        }
Example #26
0
        public override void ClientReadInitial(IReadMessage msg)
        {
            base.ClientReadInitial(msg);
            byte caveCount = msg.ReadByte();

            for (int i = 0; i < caveCount; i++)
            {
                byte selectedCave = msg.ReadByte();
                if (selectedCave < 255 && Level.Loaded != null)
                {
                    if (selectedCave < Level.Loaded.Caves.Count)
                    {
                        Level.Loaded.Caves[selectedCave].DisplayOnSonar = true;
                    }
                    else
                    {
                        DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCave}, number of caves: {Level.Loaded.Caves.Count}");
                    }
                }
            }

            for (int i = 0; i < resourceClusters.Count; i++)
            {
                var amount   = msg.ReadByte();
                var rotation = msg.ReadSingle();
                for (int j = 0; j < amount; j++)
                {
                    var item = Item.ReadSpawnData(msg);
                    if (item.GetComponent <Holdable>() is Holdable h)
                    {
                        h.AttachToWall();
                        item.Rotation = rotation;
                    }
                    if (spawnedResources.TryGetValue(item.Prefab.Identifier, out var resources))
                    {
                        resources.Add(item);
                    }
                    else
                    {
                        spawnedResources.Add(item.Prefab.Identifier, new List <Item>()
                        {
                            item
                        });
                    }
                }
            }

            CalculateMissionClusterPositions();

            for (int i = 0; i < resourceClusters.Count; i++)
            {
                var identifier = msg.ReadString();
                var count      = msg.ReadByte();
                var resources  = new Item[count];
                for (int j = 0; j < count; j++)
                {
                    var id     = msg.ReadUInt16();
                    var entity = Entity.FindEntityByID(id);
                    if (!(entity is Item item))
                    {
                        continue;
                    }
                    resources[j] = item;
                }
                relevantLevelResources.Add(identifier, resources);
            }
        }
        //static because we may need to instantiate the campaign if it hasn't been done yet
        public static void ClientRead(IReadMessage msg)
        {
            bool   isFirstRound         = msg.ReadBoolean();
            byte   campaignID           = msg.ReadByte();
            UInt16 updateID             = msg.ReadUInt16();
            UInt16 saveID               = msg.ReadUInt16();
            string mapSeed              = msg.ReadString();
            UInt16 currentLocIndex      = msg.ReadUInt16();
            UInt16 selectedLocIndex     = msg.ReadUInt16();
            byte   selectedMissionIndex = msg.ReadByte();
            bool   allowDebugTeleport   = msg.ReadBoolean();
            float? reputation           = null;

            if (msg.ReadBoolean())
            {
                reputation = msg.ReadSingle();
            }

            Dictionary <string, float> factionReps = new Dictionary <string, float>();
            byte factionsCount = msg.ReadByte();

            for (int i = 0; i < factionsCount; i++)
            {
                factionReps.Add(msg.ReadString(), msg.ReadSingle());
            }

            bool forceMapUI = msg.ReadBoolean();

            int  money = msg.ReadInt32();
            bool purchasedHullRepairs  = msg.ReadBoolean();
            bool purchasedItemRepairs  = msg.ReadBoolean();
            bool purchasedLostShuttles = msg.ReadBoolean();

            byte missionCount = msg.ReadByte();
            List <Pair <string, byte> > availableMissions = new List <Pair <string, byte> >();

            for (int i = 0; i < missionCount; i++)
            {
                string missionIdentifier = msg.ReadString();
                byte   connectionIndex   = msg.ReadByte();
                availableMissions.Add(new Pair <string, byte>(missionIdentifier, connectionIndex));
            }

            UInt16?storeBalance = null;

            if (msg.ReadBoolean())
            {
                storeBalance = msg.ReadUInt16();
            }

            UInt16 buyCrateItemCount           = msg.ReadUInt16();
            List <PurchasedItem> buyCrateItems = new List <PurchasedItem>();

            for (int i = 0; i < buyCrateItemCount; i++)
            {
                string itemPrefabIdentifier = msg.ReadString();
                int    itemQuantity         = msg.ReadRangedInteger(0, CargoManager.MaxQuantity);
                buyCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity));
            }

            UInt16 purchasedItemCount           = msg.ReadUInt16();
            List <PurchasedItem> purchasedItems = new List <PurchasedItem>();

            for (int i = 0; i < purchasedItemCount; i++)
            {
                string itemPrefabIdentifier = msg.ReadString();
                int    itemQuantity         = msg.ReadRangedInteger(0, CargoManager.MaxQuantity);
                purchasedItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity));
            }

            UInt16          soldItemCount = msg.ReadUInt16();
            List <SoldItem> soldItems     = new List <SoldItem>();

            for (int i = 0; i < soldItemCount; i++)
            {
                string itemPrefabIdentifier = msg.ReadString();
                UInt16 id       = msg.ReadUInt16();
                bool   removed  = msg.ReadBoolean();
                byte   sellerId = msg.ReadByte();
                soldItems.Add(new SoldItem(ItemPrefab.Prefabs[itemPrefabIdentifier], id, removed, sellerId));
            }

            ushort pendingUpgradeCount = msg.ReadUInt16();
            List <PurchasedUpgrade> pendingUpgrades = new List <PurchasedUpgrade>();

            for (int i = 0; i < pendingUpgradeCount; i++)
            {
                string          upgradeIdentifier  = msg.ReadString();
                UpgradePrefab   prefab             = UpgradePrefab.Find(upgradeIdentifier);
                string          categoryIdentifier = msg.ReadString();
                UpgradeCategory category           = UpgradeCategory.Find(categoryIdentifier);
                int             upgradeLevel       = msg.ReadByte();
                if (prefab == null || category == null)
                {
                    continue;
                }
                pendingUpgrades.Add(new PurchasedUpgrade(prefab, category, upgradeLevel));
            }

            bool          hasCharacterData = msg.ReadBoolean();
            CharacterInfo myCharacterInfo  = null;

            if (hasCharacterData)
            {
                myCharacterInfo = CharacterInfo.ClientRead(CharacterPrefab.HumanSpeciesName, msg);
            }

            if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaignID != campaign.CampaignID)
            {
                string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer);

                GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, mapSeed);
                campaign             = (MultiPlayerCampaign)GameMain.GameSession.GameMode;
                campaign.CampaignID  = campaignID;
                GameMain.NetLobbyScreen.ToggleCampaignMode(true);
            }

            //server has a newer save file
            if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID))
            {
                campaign.PendingSaveID = saveID;
            }

            if (NetIdUtils.IdMoreRecent(updateID, campaign.lastUpdateID))
            {
                campaign.SuppressStateSending = true;
                campaign.IsFirstRound         = isFirstRound;

                //we need to have the latest save file to display location/mission/store
                if (campaign.LastSaveID == saveID)
                {
                    campaign.ForceMapUI = forceMapUI;

                    UpgradeStore.WaitForServerUpdate = false;

                    campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex);
                    campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
                    campaign.Map.SelectMission(selectedMissionIndex);
                    campaign.Map.AllowDebugTeleport = allowDebugTeleport;
                    campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems);
                    campaign.CargoManager.SetPurchasedItems(purchasedItems);
                    campaign.CargoManager.SetSoldItems(soldItems);
                    if (storeBalance.HasValue)
                    {
                        campaign.Map.CurrentLocation.StoreCurrentBalance = storeBalance.Value;
                    }
                    campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades);
                    campaign.UpgradeManager.PurchasedUpgrades.Clear();

                    foreach (var(identifier, rep) in factionReps)
                    {
                        Faction faction = campaign.Factions.FirstOrDefault(f => f.Prefab.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase));
                        if (faction?.Reputation != null)
                        {
                            faction.Reputation.Value = rep;
                        }
                        else
                        {
                            DebugConsole.ThrowError($"Received an update for a faction that doesn't exist \"{identifier}\".");
                        }
                    }

                    if (reputation.HasValue)
                    {
                        campaign.Map.CurrentLocation.Reputation.Value = reputation.Value;
                        campaign?.CampaignUI?.UpgradeStore?.RefreshAll();
                    }

                    foreach (var availableMission in availableMissions)
                    {
                        MissionPrefab missionPrefab = MissionPrefab.List.Find(mp => mp.Identifier == availableMission.First);
                        if (missionPrefab == null)
                        {
                            DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.First}\" not found.");
                            continue;
                        }
                        if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count)
                        {
                            DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count}).");
                            continue;
                        }
                        LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second];
                        campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection);
                    }

                    GameMain.NetLobbyScreen.ToggleCampaignMode(true);
                }

                bool shouldRefresh = campaign.Money != money ||
                                     campaign.PurchasedHullRepairs != purchasedHullRepairs ||
                                     campaign.PurchasedItemRepairs != purchasedItemRepairs ||
                                     campaign.PurchasedLostShuttles != purchasedLostShuttles;

                campaign.Money = money;
                campaign.PurchasedHullRepairs  = purchasedHullRepairs;
                campaign.PurchasedItemRepairs  = purchasedItemRepairs;
                campaign.PurchasedLostShuttles = purchasedLostShuttles;

                if (shouldRefresh)
                {
                    campaign?.CampaignUI?.UpgradeStore?.RefreshAll();
                }

                if (myCharacterInfo != null)
                {
                    GameMain.Client.CharacterInfo = myCharacterInfo;
                    GameMain.NetLobbyScreen.SetCampaignCharacterInfo(myCharacterInfo);
                }
                else
                {
                    GameMain.NetLobbyScreen.SetCampaignCharacterInfo(null);
                }

                campaign.lastUpdateID         = updateID;
                campaign.SuppressStateSending = false;
            }
        }
Example #28
0
        public void ClientRead(ServerNetObject type, IReadMessage message, float sendingTime)
        {
            bool isBallastFloraUpdate = message.ReadBoolean();

            if (isBallastFloraUpdate)
            {
                BallastFloraBehavior.NetworkHeader header = (BallastFloraBehavior.NetworkHeader)message.ReadByte();
                if (header == BallastFloraBehavior.NetworkHeader.Spawn)
                {
                    string identifier = message.ReadString();
                    float  x          = message.ReadSingle();
                    float  y          = message.ReadSingle();
                    BallastFlora = new BallastFloraBehavior(this, BallastFloraPrefab.Find(identifier), new Vector2(x, y), firstGrowth: true)
                    {
                        PowerConsumptionTimer = message.ReadSingle()
                    };
                }
                else
                {
                    BallastFlora?.ClientRead(message, header);
                }
                return;
            }
            remoteWaterVolume      = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
            remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);

            bool hasFireSources = message.ReadBoolean();

            remoteFireSources = new List <Vector3>();
            if (hasFireSources)
            {
                int fireSourceCount = message.ReadRangedInteger(0, 16);
                for (int i = 0; i < fireSourceCount; i++)
                {
                    remoteFireSources.Add(new Vector3(
                                              MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
                                              MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
                                              message.ReadRangedSingle(0.0f, 1.0f, 8)));
                }
            }

            bool hasExtraData = message.ReadBoolean();

            if (hasExtraData)
            {
                bool hasSectionUpdate = message.ReadBoolean();
                if (hasSectionUpdate)
                {
                    int sectorToUpdate = message.ReadRangedInteger(0, BackgroundSections.Count - 1);
                    int start          = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
                    int end            = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
                    for (int i = start; i < end; i++)
                    {
                        float colorStrength           = message.ReadRangedSingle(0.0f, 1.0f, 8);
                        Color color                   = new Color(message.ReadUInt32());
                        var   remoteBackgroundSection = remoteBackgroundSections.Find(s => s.Index == i);
                        if (remoteBackgroundSection != null)
                        {
                            remoteBackgroundSection.SetColorStrength(colorStrength);
                            remoteBackgroundSection.SetColor(color);
                        }
                        else
                        {
                            remoteBackgroundSections.Add(new BackgroundSection(new Rectangle(0, 0, 1, 1), i, colorStrength, color, 0));
                        }
                    }
                    paintAmount = BackgroundSections.Sum(s => s.ColorStrength);
                }
                else
                {
                    int decalCount = message.ReadRangedInteger(0, MaxDecalsPerHull);
                    if (decalCount == 0)
                    {
                        decals.Clear();
                    }
                    remoteDecals.Clear();
                    for (int i = 0; i < decalCount; i++)
                    {
                        UInt32 decalId        = message.ReadUInt32();
                        int    spriteIndex    = message.ReadByte();
                        float  normalizedXPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
                        float  normalizedYPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
                        float  decalScale     = message.ReadRangedSingle(0.0f, 2.0f, 12);
                        remoteDecals.Add(new RemoteDecal(decalId, spriteIndex, new Vector2(normalizedXPos, normalizedYPos), decalScale));
                    }
                }
            }

            if (serverUpdateDelay > 0.0f)
            {
                return;
            }

            ApplyRemoteState();
        }
        public virtual void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
        {
            switch (type)
            {
            case ServerNetObject.ENTITY_POSITION:
                bool facingRight = AnimController.Dir > 0.0f;

                lastRecvPositionUpdateTime = (float)Lidgren.Network.NetTime.Now;

                AnimController.Frozen = false;
                Enabled = true;

                UInt16 networkUpdateID = 0;
                if (msg.ReadBoolean())
                {
                    networkUpdateID = msg.ReadUInt16();
                }
                else
                {
                    bool aimInput = msg.ReadBoolean();
                    keys[(int)InputType.Aim].Held = aimInput;
                    keys[(int)InputType.Aim].SetState(false, aimInput);

                    bool shootInput = msg.ReadBoolean();
                    keys[(int)InputType.Shoot].Held = shootInput;
                    keys[(int)InputType.Shoot].SetState(false, shootInput);

                    bool useInput = msg.ReadBoolean();
                    keys[(int)InputType.Use].Held = useInput;
                    keys[(int)InputType.Use].SetState(false, useInput);

                    if (AnimController is HumanoidAnimController)
                    {
                        bool crouching = msg.ReadBoolean();
                        keys[(int)InputType.Crouch].Held = crouching;
                        keys[(int)InputType.Crouch].SetState(false, crouching);
                    }

                    bool attackInput = msg.ReadBoolean();
                    keys[(int)InputType.Attack].Held = attackInput;
                    keys[(int)InputType.Attack].SetState(false, attackInput);

                    double aimAngle = msg.ReadUInt16() / 65535.0 * 2.0 * Math.PI;
                    cursorPosition = AimRefPosition + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 500.0f;
                    TransformCursorPos();

                    bool ragdollInput = msg.ReadBoolean();
                    keys[(int)InputType.Ragdoll].Held = ragdollInput;
                    keys[(int)InputType.Ragdoll].SetState(false, ragdollInput);

                    facingRight = msg.ReadBoolean();
                }

                bool      entitySelected    = msg.ReadBoolean();
                Character selectedCharacter = null;
                Item      selectedItem      = null;

                AnimController.Animation animation = AnimController.Animation.None;
                if (entitySelected)
                {
                    ushort characterID = msg.ReadUInt16();
                    ushort itemID      = msg.ReadUInt16();
                    selectedCharacter = FindEntityByID(characterID) as Character;
                    selectedItem      = FindEntityByID(itemID) as Item;
                    if (characterID != NullEntityID)
                    {
                        bool doingCpr = msg.ReadBoolean();
                        if (doingCpr && SelectedCharacter != null)
                        {
                            animation = AnimController.Animation.CPR;
                        }
                    }
                }

                Vector2 pos = new Vector2(
                    msg.ReadSingle(),
                    msg.ReadSingle());
                float   MaxVel         = NetConfig.MaxPhysicsBodyVelocity;
                Vector2 linearVelocity = new Vector2(
                    msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
                    msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
                linearVelocity = NetConfig.Quantize(linearVelocity, -MaxVel, MaxVel, 12);

                bool  fixedRotation   = msg.ReadBoolean();
                float?rotation        = null;
                float?angularVelocity = null;
                if (!fixedRotation)
                {
                    rotation = msg.ReadSingle();
                    float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
                    angularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8);
                    angularVelocity = NetConfig.Quantize(angularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8);
                }

                bool readStatus = msg.ReadBoolean();
                if (readStatus)
                {
                    ReadStatus(msg);
                    (AIController as EnemyAIController)?.PetBehavior?.ClientRead(msg);
                }

                msg.ReadPadBits();

                int index = 0;
                if (GameMain.Client.Character == this && CanMove)
                {
                    var posInfo = new CharacterStateInfo(
                        pos, rotation,
                        networkUpdateID,
                        facingRight ? Direction.Right : Direction.Left,
                        selectedCharacter, selectedItem, animation);

                    while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID))
                    {
                        index++;
                    }
                    memState.Insert(index, posInfo);
                }
                else
                {
                    var posInfo = new CharacterStateInfo(
                        pos, rotation,
                        linearVelocity, angularVelocity,
                        sendingTime, facingRight ? Direction.Right : Direction.Left,
                        selectedCharacter, selectedItem, animation);

                    while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp)
                    {
                        index++;
                    }
                    memState.Insert(index, posInfo);
                }

                break;

            case ServerNetObject.ENTITY_EVENT:

                int eventType = msg.ReadRangedInteger(0, 5);
                switch (eventType)
                {
                case 0:         //NetEntityEvent.Type.InventoryState
                    if (Inventory == null)
                    {
                        string errorMsg = "Received an inventory update message for an entity with no inventory (" + Name + ", removed: " + Removed + ")";
                        DebugConsole.ThrowError(errorMsg);
                        GameAnalyticsManager.AddErrorEventOnce("CharacterNetworking.ClientRead:NoInventory" + ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);

                        //read anyway to prevent messing up reading the rest of the message
                        UInt16 lastEventID = msg.ReadUInt16();
                        byte   itemCount   = msg.ReadByte();
                        for (int i = 0; i < itemCount; i++)
                        {
                            msg.ReadUInt16();
                        }
                    }
                    else
                    {
                        Inventory.ClientRead(type, msg, sendingTime);
                    }
                    break;

                case 1:         //NetEntityEvent.Type.Control
                    byte ownerID = msg.ReadByte();
                    ResetNetState();
                    if (ownerID == GameMain.Client.ID)
                    {
                        if (controlled != null)
                        {
                            LastNetworkUpdateID = controlled.LastNetworkUpdateID;
                        }

                        if (!IsDead)
                        {
                            Controlled = this;
                        }
                        IsRemotePlayer                   = false;
                        GameMain.Client.HasSpawned       = true;
                        GameMain.Client.Character        = this;
                        GameMain.LightManager.LosEnabled = true;
                    }
                    else
                    {
                        if (controlled == this)
                        {
                            Controlled     = null;
                            IsRemotePlayer = ownerID > 0;
                        }
                    }
                    break;

                case 2:         //NetEntityEvent.Type.Status
                    ReadStatus(msg);
                    break;

                case 3:         //NetEntityEvent.Type.UpdateSkills
                    int skillCount = msg.ReadByte();
                    for (int i = 0; i < skillCount; i++)
                    {
                        string skillIdentifier = msg.ReadString();
                        float  skillLevel      = msg.ReadSingle();
                        info?.SetSkillLevel(skillIdentifier, skillLevel, WorldPosition + Vector2.UnitY * 150.0f);
                    }
                    break;

                case 4:         //NetEntityEvent.Type.ExecuteAttack
                    int    attackLimbIndex = msg.ReadByte();
                    UInt16 targetEntityID  = msg.ReadUInt16();
                    int    targetLimbIndex = msg.ReadByte();

                    //255 = entity already removed, no need to do anything
                    if (attackLimbIndex == 255 || Removed)
                    {
                        break;
                    }

                    if (attackLimbIndex >= AnimController.Limbs.Length)
                    {
                        DebugConsole.ThrowError($"Received invalid ExecuteAttack message. Limb index out of bounds (character: {Name}, limb index: {attackLimbIndex}, limb count: {AnimController.Limbs.Length})");
                        break;
                    }
                    Limb attackLimb = AnimController.Limbs[attackLimbIndex];
                    Limb targetLimb = null;
                    if (!(FindEntityByID(targetEntityID) is IDamageable targetEntity))
                    {
                        DebugConsole.ThrowError($"Received invalid ExecuteAttack message. Target entity not found (ID {targetEntityID})");
                        break;
                    }
                    if (targetEntity is Character targetCharacter)
                    {
                        if (targetLimbIndex >= targetCharacter.AnimController.Limbs.Length)
                        {
                            DebugConsole.ThrowError($"Received invalid ExecuteAttack message. Target limb index out of bounds (target character: {targetCharacter.Name}, limb index: {targetLimbIndex}, limb count: {targetCharacter.AnimController.Limbs.Length})");
                            break;
                        }
                        targetLimb = targetCharacter.AnimController.Limbs[targetLimbIndex];
                    }
                    if (attackLimb?.attack != null)
                    {
                        attackLimb.ExecuteAttack(targetEntity, targetLimb, out _);
                    }
                    break;

                case 5:         //NetEntityEvent.Type.AssignCampaignInteraction
                    byte campaignInteractionType = msg.ReadByte();
                    (GameMain.GameSession?.GameMode as CampaignMode)?.AssignNPCMenuInteraction(this, (CampaignMode.InteractionType)campaignInteractionType);
                    break;
                }
                msg.ReadPadBits();
                break;
            }
        }
        public static Character ReadSpawnData(IReadMessage inc)
        {
            DebugConsole.Log("Reading character spawn data");

            if (GameMain.Client == null)
            {
                return(null);
            }

            bool   noInfo      = inc.ReadBoolean();
            ushort id          = inc.ReadUInt16();
            string speciesName = inc.ReadString();
            string seed        = inc.ReadString();

            Vector2 position = new Vector2(inc.ReadSingle(), inc.ReadSingle());

            bool enabled = inc.ReadBoolean();

            DebugConsole.Log("Received spawn data for " + speciesName);

            Character character = null;

            if (noInfo)
            {
                character    = Create(speciesName, position, seed, null, false);
                character.ID = id;
                bool containsStatusData = inc.ReadBoolean();
                if (containsStatusData)
                {
                    character.ReadStatus(inc);
                }
            }
            else
            {
                bool   hasOwner        = inc.ReadBoolean();
                int    ownerId         = hasOwner ? inc.ReadByte() : -1;
                byte   teamID          = inc.ReadByte();
                bool   hasAi           = inc.ReadBoolean();
                string infoSpeciesName = inc.ReadString();

                CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc);

                character        = Create(speciesName, position, seed, info, ownerId > 0 && GameMain.Client.ID != ownerId, hasAi);
                character.ID     = id;
                character.TeamID = (TeamType)teamID;
                character.CampaignInteractionType = (CampaignMode.InteractionType)inc.ReadByte();
                if (character.CampaignInteractionType != CampaignMode.InteractionType.None)
                {
                    (GameMain.GameSession.GameMode as CampaignMode)?.AssignNPCMenuInteraction(character, character.CampaignInteractionType);
                }

                // Check if the character has a current order
                if (inc.ReadBoolean())
                {
                    int         orderPrefabIndex = inc.ReadByte();
                    Entity      targetEntity     = FindEntityByID(inc.ReadUInt16());
                    Character   orderGiver       = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null;
                    int         orderOptionIndex = inc.ReadByte();
                    OrderTarget targetPosition   = null;
                    if (inc.ReadBoolean())
                    {
                        var x    = inc.ReadSingle();
                        var y    = inc.ReadSingle();
                        var hull = FindEntityByID(inc.ReadUInt16()) as Hull;
                        targetPosition = new OrderTarget(new Vector2(x, y), hull, true);
                    }

                    if (orderPrefabIndex >= 0 && orderPrefabIndex < Order.PrefabList.Count)
                    {
                        var orderPrefab = Order.PrefabList[orderPrefabIndex];
                        var component   = orderPrefab.GetTargetItemComponent(targetEntity as Item);
                        if (!orderPrefab.MustSetTarget || (targetEntity != null && component != null) || targetPosition != null)
                        {
                            var order = targetPosition == null ?
                                        new Order(orderPrefab, targetEntity, component, orderGiver: orderGiver) :
                                        new Order(orderPrefab, targetPosition, orderGiver: orderGiver);
                            character.SetOrder(order,
                                               orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length ? orderPrefab.Options[orderOptionIndex] : null,
                                               orderGiver, speak: false);
                        }
                        else
                        {
                            DebugConsole.ThrowError("Could not set order \"" + orderPrefab.Identifier + "\" for character \"" + character.Name + "\" because required target entity was not found.");
                        }
                    }
                    else
                    {
                        DebugConsole.ThrowError("Invalid order prefab index - index (" + orderPrefabIndex + ") out of bounds.");
                    }
                }

                bool containsStatusData = inc.ReadBoolean();
                if (containsStatusData)
                {
                    character.ReadStatus(inc);
                }

                if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC && !character.IsDead)
                {
                    CharacterInfo duplicateCharacterInfo = GameMain.GameSession.CrewManager.GetCharacterInfos().FirstOrDefault(c => c.ID == info.ID);
                    GameMain.GameSession.CrewManager.RemoveCharacterInfo(duplicateCharacterInfo);
                    GameMain.GameSession.CrewManager.AddCharacter(character);
                }

                if (GameMain.Client.ID == ownerId)
                {
                    GameMain.Client.HasSpawned = true;
                    GameMain.Client.Character  = character;
                    if (!character.IsDead)
                    {
                        Controlled = character;
                    }

                    GameMain.LightManager.LosEnabled = true;

                    character.memInput.Clear();
                    character.memState.Clear();
                    character.memLocalState.Clear();
                }
            }

            character.Enabled = Controlled == character || enabled;

            return(character);
        }