public void Lock(MyEntityIdentifier entityId, bool enable) { if (IsHost) { // Host just sends lock to all bool success = TryLockEntity(entityId.NumericValue, MyEntityIdentifier.CurrentPlayerId, enable); if (success) { LogDevelop(MyEntities.GetEntityById(entityId).Name + " " + (enable ? "LOCKED" : "UNLOCKED")); } MyEntity entity; if (enable && MyEntities.TryGetEntityById(entityId, out entity)) { RaiseLockResponse(entity, success); } } else { // Send request to host MyEventLock msg = new MyEventLock(); msg.EntityId = entityId.NumericValue; msg.LockType = enable ? MyLockEnum.LOCK : MyLockEnum.UNLOCK; // Sometimes can be called after host already disconnected (closing screens etc) Peers.TrySendHost(ref msg); } }
private void OnLock(ref MyEventLock msg) { var player = (MyPlayerRemote)msg.SenderConnection.Tag; if (player != null) { if (IsHost) { // Someone wants to lock entity TryLockEntity(msg.EntityId, player.PlayerId, msg.LockType == MyLockEnum.LOCK); } else if (player.UserId == Peers.HostUserId) { using (m_lockedEntitiesLock.AcquireExclusiveUsing()) { if (msg.LockType == MyLockEnum.LOCK) { // Locked by host, just accept it m_lockedEntities[msg.EntityId] = 0; } else { // Unlocked by host m_lockedEntities.Remove(msg.EntityId); } } } else { Alert("Lock came from other player than host", msg.SenderEndpoint, msg.EventType); } } }
/// <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); }
public void ClearLocks(byte playerId) { foreach (var l in m_lockedEntities.ToArray()) { if (l.Value == playerId) { m_lockedEntities.Remove(l.Key); // Announce to all MyEventLock unlockMsg = new MyEventLock(); unlockMsg.EntityId = l.Key; unlockMsg.LockType = MyLockEnum.UNLOCK; Peers.SendToAll(ref unlockMsg); } } }