private void HandleLeaveOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters) { var leaveOperation = new LeaveRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(leaveOperation, sendParameters) == false) { return; } DebugLog(peer, operationRequest); leaveOperation.OnStart(); this.HandleLeaveOperation(peer, leaveOperation, sendParameters); leaveOperation.OnComplete(); }
/// <summary> /// Removes a peer from the game. /// This method is called if a client sends a <see cref = "LeaveRequest" /> or disconnects. /// </summary> /// <param name = "peer"> /// The <see cref = "LitePeer" /> to remove. /// </param> /// <param name="leaveRequest"> /// The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request. /// </param> /// <returns> /// The actor number of the removed actor. /// If the specified peer does not exists -1 will be returned. /// </returns> protected virtual int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest) { Actor actor = this.Actors.RemoveActorByPeer(peer); if (actor == null) { if (Log.IsWarnEnabled) { Log.WarnFormat("RemovePeerFromGame - Actor to remove not found for peer: {0}", peer.ConnectionId); } return -1; } this.eventCacheOld.Remove(actor.ActorNr); if (this.DeleteCacheOnLeave) { this.eventCache.RemoveEventsByActor(actor.ActorNr); } // raise leave event this.PublishLeaveEvent(actor, leaveRequest); return actor.ActorNr; }
/// <summary> /// Sends a <see cref = "LeaveEvent" /> to all <see cref = "Actor" />s. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "leaveRequest"> /// The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request. /// </param> protected virtual void PublishLeaveEvent(Actor actor, LeaveRequest leaveRequest) { if (this.Actors.Count > 0 && actor != null) { IEnumerable<int> actorNumbers = this.Actors.GetActorNumbers(); var leaveEvent = new LeaveEvent(actor.ActorNr, actorNumbers.ToArray()); this.PublishEvent(leaveEvent, this.Actors, new SendParameters()); } }
/// <summary> /// Handles the <see cref = "LeaveRequest" /> and calls <see cref = "RemovePeerFromGame" />. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "leaveRequest"> /// The operation. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleLeaveOperation(LitePeer peer, LeaveRequest leaveRequest, SendParameters sendParameters) { this.RemovePeerFromGame(peer, leaveRequest); // is always reliable, so it gets a response peer.SendOperationResponse(new OperationResponse { OperationCode = leaveRequest.OperationRequest.OperationCode }, sendParameters); }
/// <summary> /// Called for each operation in the execution queue. /// Every <see cref = "Room" /> has a queue of incoming operations to execute. /// Per game <see cref = "ExecuteOperation" /> is never executed multi-threaded, thus all code executed here has thread safe access to all instance members. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "operationRequest"> /// The operation request to execute. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected override void ExecuteOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters) { try { base.ExecuteOperation(peer, operationRequest, sendParameters); if (Log.IsDebugEnabled) { Log.DebugFormat("Executing operation {0}", (OperationCode)operationRequest.OperationCode); } switch ((OperationCode)operationRequest.OperationCode) { case OperationCode.Join: { var joinRequest = new JoinRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(joinRequest, sendParameters) == false) { return; } this.logQueue.Add(new LogEntry("ExecuteOperation: " + (OperationCode)operationRequest.OperationCode, "Peer=" + peer.ConnectionId)); joinRequest.OnStart(); this.HandleJoinOperation(peer, joinRequest, sendParameters); joinRequest.OnComplete(); break; } case OperationCode.Leave: { var leaveOperation = new LeaveRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(leaveOperation, sendParameters) == false) { return; } this.logQueue.Add(new LogEntry("ExecuteOperation: " + (OperationCode)operationRequest.OperationCode, "Peer=" + peer.ConnectionId)); leaveOperation.OnStart(); this.HandleLeaveOperation(peer, leaveOperation, sendParameters); leaveOperation.OnComplete(); break; } case OperationCode.RaiseEvent: { var raiseEventOperation = new RaiseEventRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(raiseEventOperation, sendParameters) == false) { return; } raiseEventOperation.OnStart(); this.HandleRaiseEventOperation(peer, raiseEventOperation, sendParameters); raiseEventOperation.OnComplete(); break; } case OperationCode.GetProperties: { var getPropertiesOperation = new GetPropertiesRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(getPropertiesOperation, sendParameters) == false) { return; } getPropertiesOperation.OnStart(); this.HandleGetPropertiesOperation(peer, getPropertiesOperation, sendParameters); getPropertiesOperation.OnComplete(); break; } case OperationCode.SetProperties: { var setPropertiesOperation = new SetPropertiesRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(setPropertiesOperation, sendParameters) == false) { return; } setPropertiesOperation.OnStart(); this.HandleSetPropertiesOperation(peer, setPropertiesOperation, sendParameters); setPropertiesOperation.OnComplete(); break; } case OperationCode.Ping: { peer.SendOperationResponse(new OperationResponse { OperationCode = operationRequest.OperationCode }, sendParameters); break; } default: { string message = string.Format("Unknown operation code {0}", (OperationCode)operationRequest.OperationCode); peer.SendOperationResponse( new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = -1, DebugMessage = message }, sendParameters); if (Log.IsWarnEnabled) { Log.Warn(message); } } break; } } catch (Exception ex) { Log.Error(ex); } }
/// <summary> /// Updates the lobby when an <see cref = "Actor" /> leaves (disconnect, <see cref = "LeaveRequest" />, <see cref = "JoinRequest" /> for another game). /// </summary> /// <param name = "peer"> /// The <see cref = "LitePeer" /> to remove. /// </param> /// <param name="leaveRequest"> /// The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request. /// </param> /// <returns> /// The actore number of the removed actor. /// If the specified peer does not exists -1 will be returned. /// </returns> protected override int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest) { int actorNr = base.RemovePeerFromGame(peer, leaveRequest); this.UpdateLobby(); return actorNr; }
/// <summary> /// This override disables the event publishing. /// </summary> /// <param name="peer"> /// The peer. /// </param> /// <param name="leaveRequest"> /// The <see cref="LeaveRequest"/> sent by the peer or null if the peer have been disconnected without sending a leave request. /// </param> /// <returns> /// the actor number. /// </returns> protected override int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest) { Actor actor = this.Actors.GetActorByPeer(peer); if (this.Actors.Remove(actor) == false) { if (Log.IsWarnEnabled) { Log.WarnFormat("RemovePeerFromGame - Actor to remove not found for peer: {0}", peer.ConnectionId); } return 0; } return actor.ActorNr; }
/// <summary> /// This override disables the event publishing. /// </summary> /// <param name="peer"> /// The peer. /// </param> /// <param name="leaveOperation"> /// The leave operation. /// </param> protected override void PublishLeaveEvent(Actor actor, LeaveRequest leaveOperation) { // lobbies don't publish a leave event to the clients }
protected override int RemovePeerFromGame(LitePeer peer, LeaveRequest leaveRequest) { int result = base.RemovePeerFromGame(peer, leaveRequest); if (this.IsDisposed) { return result; } // If there are still peers left an UpdateGameStateOperation with the new // actor count will be send to the master server. // If there are no actors left the RoomCache will dispose this instance and a // RemoveGameStateOperation will be sent to the master. if (this.Actors.Count > 0) { var gamePeer = (GameClientPeer)peer; var peerId = gamePeer.PeerId ?? string.Empty; this.UpdateGameStateOnMaster(null, null, null, null, null, null, peerId); } return result; }