예제 #1
0
        /// <summary>
        /// Try lock entity and announce to other players (runs only on host)
        /// </summary>
        bool TryLockEntity(uint entityId, byte playerId, bool enable)
        {
            bool success = true;

            if (enable)
            {
                using (m_lockedEntitiesLock.AcquireExclusiveUsing())
                {
                    success = !m_lockedEntities.ContainsKey(entityId);

                    if (success)
                    {
                        m_lockedEntities[entityId] = playerId;
                        MyEntities.GetEntityById(entityId.ToEntityId()).OnClosing += m_unlockOnClosing;
                    }
                }
            }
            else
            {
                using (m_lockedEntitiesLock.AcquireExclusiveUsing())
                {
                    success = m_lockedEntities.Remove(entityId);
                    MyEntity entity;
                    if (MyEntities.TryGetEntityById(entityId.ToEntityId(), out entity))
                    {
                        entity.OnClosing -= m_unlockOnClosing;
                    }
                }
            }

            if (success)
            {
                // Send lock to all
                MyEventLock response = new MyEventLock();
                response.EntityId = entityId;
                response.LockType = enable ? MyLockEnum.LOCK : MyLockEnum.UNLOCK;
                Peers.SendToAll(ref response, NetDeliveryMethod.ReliableOrdered, 0);
            }

            if (enable)
            {
                // Send response to player
                MyPlayerRemote player;
                if (Peers.TryGetPlayer(playerId, out player))
                {
                    MyEventLockResult response = new MyEventLockResult();
                    response.EntityId  = entityId;
                    response.IsSuccess = success;
                    Peers.NetworkClient.Send(ref response, player.Connection, NetDeliveryMethod.ReliableOrdered, 0);
                }
            }

            return(success);
        }
예제 #2
0
        bool CheckSenderId <T>(T msg, uint id)
            where T : struct, IMyEvent
        {
            if (msg.SenderConnection == null)
            {
                return(false);
            }

            var senderPlayer = (MyPlayerRemote)msg.SenderConnection.Tag;
            var entityId     = new MyEntityIdentifier(id);

            if (senderPlayer.UserId == Peers.HostUserId && entityId.PlayerId == 0)
            {
                return(true);
            }

            if (m_lockedEntities.ContainsKey(id))
            {
                return(true);
            }

            MyPlayerRemote ownerPlayer;
            bool           playerExists = Peers.TryGetPlayer(entityId.PlayerId, out ownerPlayer);

            if (!playerExists)
            {
                Alert("Owner of this entity does not exist!", msg.SenderEndpoint, msg.EventType);
                return(false);
            }

            if (entityId.PlayerId == 0 && Peers.HostUserId != ownerPlayer.UserId)
            {
                Alert("Only host can update neutral entities!", msg.SenderEndpoint, msg.EventType);
                return(false);
            }

            if (senderPlayer.PlayerId != entityId.PlayerId)
            {
                Alert("Entity Id send by sender is not his!", msg.SenderEndpoint, msg.EventType);
                return(false);
            }

            return(true);
        }
예제 #3
0
        public void UpdateCoopTarget()
        {
            if (IsHost)
            {
                return;
            }

            MyPlayerRemote host;

            if (Peers.TryGetPlayer(Peers.HostUserId, out host))
            {
                var ship = host.Ship;
                if (IsStory() && ship != null && m_followMission != null)
                {
                    m_followMission.MainObjective.Location = new MyMissionBase.MyMissionLocation(MyGuiScreenGamePlay.Static.GetSectorIdentifier().Position, ship.EntityId.Value.NumericValue);
                    m_followMission.MainObjective.SetLocationVisibility(true);
                }
            }
        }
예제 #4
0
        public void Resume()
        {
            if (MyFakes.MULTIPLAYER_DISABLED)
            {
                return;
            }

            IsWaiting = false;

            if (!IsHost)
            {
                // When host is disconnected in resume, he disconnected in load, so shutdown MP
                MyPlayerRemote host;
                if (!Peers.TryGetPlayer(Peers.HostUserId, out host))
                {
                    var handler = OnShutdown;
                    if (handler != null)
                    {
                        handler();
                    }
                    return;
                }
            }

            if (!IsHost)
            {
                MyGlobalEvents.DisableAllGlobalEvents();
            }

            if (!IsHost || OtherPlayersConnected) //TODO: remove
            {
                RemoveUnsupportedEntities();
            }

            if (!IsHost)
            {
                MakeAllEntitiesDummy();
            }

            if (IsSandBox())
            {
                LoadRespawnPoints();
            }

            RegisterCallbacks();

            if (!IsHost)
            {
                foreach (var p in Peers.Players)
                {
                    if (p.Ship == null) // Ship can be already assigned (player has respawned before we finished loading)
                    {
                        var newShip = FindPlayerShip(p.PlayerId);
                        if (newShip != null)
                        {
                            p.Ship    = newShip;
                            p.Faction = newShip.Faction;
                            OnNewPlayerShip(p.Ship);
                        }
                    }
                }
            }

            if (!IsHost)
            {
                if (IsStory())
                {
                    MyMissions.Unload();
                    m_followMission = MyMissions.GetMissionByID(MyMissionID.COOP_FOLLOW_HOST) as MyFollowHostMission;
                    if (m_followMission == null)
                    {
                        m_followMission          = new MyFollowHostMission();
                        m_followMission.Location = new MyMissionBase.MyMissionLocation(MyGuiScreenGamePlay.Static.GetSectorIdentifier().Position, 0);
                        MyMissions.AddMission(m_followMission);
                    }
                    m_followMission.SetHudName(Peers[Peers.HostUserId].GetDisplayName());
                    UpdateCoopTarget();
                    m_followMission.Accept();
                }
            }

            m_processingBuffer = true;
            Peers.NetworkClient.ProcessBuffered();
            m_processingBuffer = false;

            if (IsSandBox())
            {
                if (IsHost)
                {
                    MySession.Static.Player.Faction = ChooseFaction();
                }
            }

            //DisableCheats();

            if (!IsHost)
            {
                if (IsSandBox())
                {
                    // No faction, prevents respawn until server assigns faction
                    MySession.Static.Player.Faction = MyMwcObjectBuilder_FactionEnum.None;
                }
                RequestFaction(MyMwcObjectBuilder_FactionEnum.None);
            }

            if (!IsStory() || !IsHost)
            {
                // Player's ship is dummy
                MySession.PlayerShip.IsDummy = true;
                m_respawnTime = MyMinerGame.TotalGamePlayTimeInMilliseconds;
            }
            else
            {
                m_respawnTime = Int32.MaxValue;
            }

            if (IsHost)
            {
                // Why is this set only for host?
                MySession.PlayerShip.ConfigChanged    += m_onConfigChanged;
                MySession.PlayerShip.OnDie            += m_onEntityDie;
                MySession.PlayerShip.InventoryChanged += m_onInventoryChanged;
            }

            // Hook entities (hook required events)
            foreach (var entity in MyEntities.GetEntities().OfType <MyCargoBox>())
            {
                HookEntity(entity);
            }
            foreach (var entity in MyEntities.GetEntities().OfType <MyPrefabContainer>())
            {
                HookEntity(entity);
            }

            SendGlobalFlag(MyGlobalFlagsEnum.REQUEST_INFO);
        }