/// <summary> /// Handles the <see cref = "SetPropertiesRequest" /> and sends event <see cref = "PropertiesChangedEvent" /> to all <see cref = "Actor" />s in the room. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "setPropertiesRequest"> /// The <see cref = "SetPropertiesRequest" /> operation to handle. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleSetPropertiesOperation(LitePeer peer, SetPropertiesRequest setPropertiesRequest, SendParameters sendParameters) { // check if peer has joined this room instance var sender = this.GetActorByPeer(peer); if (sender == null) { var response = new OperationResponse { OperationCode = setPropertiesRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Room not joined" }; peer.SendOperationResponse(response, sendParameters); return; } if (setPropertiesRequest.ActorNumber > 0) { Actor actor = this.Actors.GetActorByNumber(setPropertiesRequest.ActorNumber); if (actor == null) { peer.SendOperationResponse( new OperationResponse { OperationCode = setPropertiesRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = string.Format("Actor with number {0} not found.", setPropertiesRequest.ActorNumber) }, sendParameters); return; } actor.Properties.SetProperties(setPropertiesRequest.Properties); } else { this.Properties.SetProperties(setPropertiesRequest.Properties); } peer.SendOperationResponse(new OperationResponse { OperationCode = setPropertiesRequest.OperationRequest.OperationCode }, sendParameters); // if the optional paramter Broadcast is set a EvPropertiesChanged // event will be send to room actors if (setPropertiesRequest.Broadcast) { Actor actor = this.Actors.GetActorByPeer(peer); IEnumerable <Actor> recipients = this.Actors.GetExcludedList(actor); var propertiesChangedEvent = new PropertiesChangedEvent(actor.ActorNr) { TargetActorNumber = setPropertiesRequest.ActorNumber, Properties = setPropertiesRequest.Properties }; this.PublishEvent(propertiesChangedEvent, recipients, 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); }
private void HandleMyGameOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters) { var requestContract = new MyGameRequest(peer.Protocol, operationRequest); requestContract.OnStart(); var responseContract = new MyGameResponse(); responseContract.Response = "You are in game " + this.Name; var operationResponse = new OperationResponse(operationRequest.OperationCode, responseContract); peer.SendOperationResponse(operationResponse, sendParameters); requestContract.OnComplete(); }
/// <summary> /// Handles the <see cref = "GetPropertiesRequest" /> operation: Sends the properties with the <see cref = "OperationResponse" />. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "getPropertiesRequest"> /// The operation to handle. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleGetPropertiesOperation(LitePeer peer, GetPropertiesRequest getPropertiesRequest, SendParameters sendParameters) { var response = new GetPropertiesResponse(); // check if game properties should be returned if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Game) == (byte)PropertyType.Game) { response.GameProperties = this.Properties.GetProperties(getPropertiesRequest.GamePropertyKeys); } // check if actor properties should be returned if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Actor) == (byte)PropertyType.Actor) { response.ActorProperties = new Hashtable(); if (getPropertiesRequest.ActorNumbers == null) { foreach (Actor actor in this.Actors) { Hashtable actorProperties = actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys); response.ActorProperties.Add(actor.ActorNr, actorProperties); } } else { foreach (int actorNumber in getPropertiesRequest.ActorNumbers) { Actor actor = this.Actors.GetActorByNumber(actorNumber); if (actor != null) { Hashtable actorProperties = actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys); response.ActorProperties.Add(actorNumber, actorProperties); } } } } peer.SendOperationResponse( new OperationResponse(getPropertiesRequest.OperationRequest.OperationCode, response), 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> /// Handles the <see cref = "GetPropertiesRequest" /> operation: Sends the properties with the <see cref = "OperationResponse" />. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "getPropertiesRequest"> /// The operation to handle. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleGetPropertiesOperation(LitePeer peer, GetPropertiesRequest getPropertiesRequest, SendParameters sendParameters) { var response = new GetPropertiesResponse(); // check if game properties should be returned if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Game) == (byte)PropertyType.Game) { response.GameProperties = this.Properties.GetProperties(getPropertiesRequest.GamePropertyKeys); } // check if actor properties should be returned if ((getPropertiesRequest.PropertyType & (byte)PropertyType.Actor) == (byte)PropertyType.Actor) { response.ActorProperties = new Hashtable(); if (getPropertiesRequest.ActorNumbers == null) { foreach (Actor actor in this.Actors) { Hashtable actorProperties = actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys); response.ActorProperties.Add(actor.ActorNr, actorProperties); } } else { foreach (int actorNumber in getPropertiesRequest.ActorNumbers) { Actor actor = this.Actors.GetActorByNumber(actorNumber); if (actor != null) { Hashtable actorProperties = actor.Properties.GetProperties(getPropertiesRequest.ActorPropertyKeys); response.ActorProperties.Add(actorNumber, actorProperties); } } } } peer.SendOperationResponse(new OperationResponse(getPropertiesRequest.OperationRequest.OperationCode, response), sendParameters); }
/// <summary> /// Handles the <see cref = "RaiseEventRequest" />: Sends a <see cref = "CustomEvent" /> to actors in the room. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "raiseEventRequest"> /// The operation /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleRaiseEventOperation(LitePeer peer, RaiseEventRequest raiseEventRequest, SendParameters sendParameters) { // get the actor who send the operation request Actor actor = this.GetActorByPeer(peer); if (actor == null) { return; } sendParameters.Flush = raiseEventRequest.Flush; if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromRoomCache) { this.eventCache.RemoveEvents(raiseEventRequest); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) { ReturnCode = 0 }; peer.SendOperationResponse(response, sendParameters); return; } if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromCacheForActorsLeft) { var currentActorNumbers = this.Actors.GetActorNumbers(); this.eventCache.RemoveEventsForActorsNotInList(currentActorNumbers); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) { ReturnCode = 0 }; peer.SendOperationResponse(response, sendParameters); return; } // publish the custom event var customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data); bool updateEventCache = false; IEnumerable <Actor> recipients; if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0) { recipients = this.Actors.GetActorsByNumbers(raiseEventRequest.Actors); } else if (raiseEventRequest.Group != 0) { ActorGroup group; if (this.actorGroups.TryGetValue(raiseEventRequest.Group, out group)) { recipients = group.GetExcludedList(actor); } else { return; } } else { switch ((ReceiverGroup)raiseEventRequest.ReceiverGroup) { case ReceiverGroup.All: recipients = this.Actors; updateEventCache = true; break; case ReceiverGroup.Others: recipients = this.Actors.GetExcludedList(actor); updateEventCache = true; break; case ReceiverGroup.MasterClient: recipients = new[] { this.Actors[0] }; break; default: peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid ReceiverGroup " + raiseEventRequest.ReceiverGroup }, sendParameters); return; } } if (updateEventCache && raiseEventRequest.Cache != (byte)CacheOperation.DoNotCache) { string msg; if (!this.UpdateEventCache(actor, raiseEventRequest, out msg)) { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = msg }, sendParameters); return; } } this.PublishEvent(customEvent, recipients, sendParameters); }
protected override void ExecuteOperation(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters) { try { if (Log.IsDebugEnabled) { Log.DebugFormat("Executing operation {0}", operationRequest.OperationCode); } switch (operationRequest.OperationCode) { case (byte)OperationCode.CreateGame: var createGameRequest = new JoinGameRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(createGameRequest, sendParameters) == false) { return; } if (this.LogQueue.Log.IsDebugEnabled) { this.LogQueue.Add( new LogEntry( "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode, "Peer=" + peer.ConnectionId)); } this.HandleCreateGameOperation(peer, createGameRequest, sendParameters); break; case (byte)OperationCode.JoinGame: var joinGameRequest = new JoinRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(joinGameRequest, sendParameters) == false) { return; } if (this.LogQueue.Log.IsDebugEnabled) { this.LogQueue.Add( new LogEntry( "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode, "Peer=" + peer.ConnectionId)); } this.HandleJoinGameOperation(peer, joinGameRequest, sendParameters); break; // Lite operation code for join is not allowed in load balanced games. case (byte)Lite.Operations.OperationCode.Join: var response = new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (short)ErrorCode.OperationDenied, DebugMessage = "Invalid operation code" }; peer.SendOperationResponse(response, sendParameters); break; case (byte)OperationCode.DebugGame: var debugGameRequest = new DebugGameRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(debugGameRequest, sendParameters) == false) { return; } if (this.LogQueue.Log.IsDebugEnabled) { this.LogQueue.Add( new LogEntry( "ExecuteOperation: " + (OperationCode)operationRequest.OperationCode, "Peer=" + peer.ConnectionId)); } this.HandleDebugGameOperation(peer, debugGameRequest, sendParameters); break; // all other operation codes will be handled by the Lite game implementation default: base.ExecuteOperation(peer, operationRequest, sendParameters); break; } } catch (Exception ex) { Log.Error(ex); } }
/// <summary> /// Handles the <see cref = "JoinRequest" />: Joins a peer to a room and calls <see cref = "PublishJoinEvent" />. /// Before a JoinOperation reaches this point (inside a room), the <see cref = "LitePeer" /> made /// sure that it is removed from the previous Room (if there was any). /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "joinRequest"> /// The join operation. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> /// <returns> /// The newly created (joined) actor or null if the peer already joined. /// </returns> protected virtual Actor HandleJoinOperation(LitePeer peer, JoinRequest joinRequest, SendParameters sendParameters) { if (this.IsDisposed) { // join arrived after being disposed - repeat join operation if (Log.IsWarnEnabled) { Log.WarnFormat("Join operation on disposed game. GameName={0}", this.Name); } return(null); } if (Log.IsDebugEnabled) { Log.DebugFormat("Join operation from IP: {0} to port: {1}", peer.RemoteIP, peer.LocalPort); } // create an new actor Actor actor; if (this.TryAddPeerToGame(peer, joinRequest.ActorNr, out actor) == false) { peer.SendOperationResponse( new OperationResponse { OperationCode = joinRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Peer already joined the specified game." }, sendParameters); return(null); } // check if a room removal is in progress and cancel it if so if (this.RemoveTimer != null) { this.RemoveTimer.Dispose(); this.RemoveTimer = null; } // set game properties for join from the first actor (game creator) if (this.Actors.Count == 1) { this.DeleteCacheOnLeave = joinRequest.DeleteCacheOnLeave; this.SuppressRoomEvents = joinRequest.SuppressRoomEvents; if (joinRequest.GameProperties != null) { this.Properties.SetProperties(joinRequest.GameProperties); } } // set custom actor properties if defined if (joinRequest.ActorProperties != null) { actor.Properties.SetProperties(joinRequest.ActorProperties); } // set operation return values and publish the response var joinResponse = new JoinResponse { ActorNr = actor.ActorNr }; if (this.Properties.Count > 0) { joinResponse.CurrentGameProperties = this.Properties.GetProperties(); } foreach (Actor t in this.Actors) { if (t.ActorNr != actor.ActorNr && t.Properties.Count > 0) { if (joinResponse.CurrentActorProperties == null) { joinResponse.CurrentActorProperties = new Hashtable(); } Hashtable actorProperties = t.Properties.GetProperties(); joinResponse.CurrentActorProperties.Add(t.ActorNr, actorProperties); } } peer.SendOperationResponse(new OperationResponse(joinRequest.OperationRequest.OperationCode, joinResponse), sendParameters); // publish join event this.PublishJoinEvent(peer, joinRequest); this.PublishEventCache(peer); return(actor); }
private static bool TryParseDefaultProperties( LitePeer peer, Operation operation, Hashtable propertyTable, SendParameters sendParameters, out byte? maxPlayer, out bool? isOpen, out bool? isVisible, out object[] properties) { string debugMessage; if (!GameParameterReader.TryReadDefaultParameter(propertyTable, out maxPlayer, out isOpen, out isVisible, out properties, out debugMessage)) { var response = new OperationResponse { OperationCode = operation.OperationRequest.OperationCode, ReturnCode = (short)ErrorCode.OperationInvalid, DebugMessage = debugMessage }; peer.SendOperationResponse(response, sendParameters); return false; } return true; }
/// <summary> /// Handles the <see cref = "RaiseEventRequest" />: Sends a <see cref = "CustomEvent" /> to actors in the room. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "raiseEventRequest"> /// The operation /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleRaiseEventOperation(LitePeer peer, RaiseEventRequest raiseEventRequest, SendParameters sendParameters) { // get the actor who send the operation request Actor actor = this.GetActorByPeer(peer); if (actor == null) { return; } sendParameters.Flush = raiseEventRequest.Flush; if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromRoomCache) { this.eventCache.RemoveEvents(raiseEventRequest); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) { ReturnCode = 0 }; peer.SendOperationResponse(response, sendParameters); return; } if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromCacheForActorsLeft) { var currentActorNumbers = this.Actors.GetActorNumbers(); this.eventCache.RemoveEventsForActorsNotInList(currentActorNumbers); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) { ReturnCode = 0 }; peer.SendOperationResponse(response, sendParameters); return; } // publish the custom event var customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data) { Cache = raiseEventRequest.Cache }; bool updateEventCache = false; IEnumerable<Actor> recipients; if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0) { recipients = this.Actors.GetActorsByNumbers(raiseEventRequest.Actors); } else { switch ((ReceiverGroup)raiseEventRequest.ReceiverGroup) { case ReceiverGroup.All: recipients = this.Actors; updateEventCache = true; break; case ReceiverGroup.Others: recipients = this.Actors.GetExcludedList(actor); updateEventCache = true; break; case ReceiverGroup.MasterClient: recipients = new[] { this.Actors[0] }; break; default: peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid ReceiverGroup " + raiseEventRequest.ReceiverGroup }, sendParameters); return; } } if (updateEventCache && raiseEventRequest.Cache != (byte)CacheOperation.DoNotCache) { if (!this.UpdateEventCache(actor, raiseEventRequest)) { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache }, sendParameters); return; } } this.PublishEvent(customEvent, recipients, sendParameters); }
protected virtual void HandleDebugGameOperation(LitePeer peer, DebugGameRequest request, SendParameters sendParameters) { // Room: Properties; # of cached events // Actors: Count, Last Activity, Actor #, Peer State, Connection ID // Room Reference // get info from request (was gathered in Peer class before operation was forwarded to the game): var peerInfo = request.Info; var debugInfo = peerInfo + this; if (Log.IsInfoEnabled) { Log.Info("DebugGame: " + debugInfo); } this.LogQueue.WriteLog(); var debugGameResponse = new DebugGameResponse { Info = debugInfo }; peer.SendOperationResponse(new OperationResponse(request.OperationRequest.OperationCode, debugGameResponse), sendParameters); }
/// <summary> /// Handles the <see cref = "JoinRequest" />: Joins a peer to a room and calls <see cref = "PublishJoinEvent" />. /// Before a JoinOperation reaches this point (inside a room), the <see cref = "LitePeer" /> made /// sure that it is removed from the previous Room (if there was any). /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "joinRequest"> /// The join operation. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> /// <returns> /// The newly created (joined) actor or null if the peer already joined. /// </returns> protected virtual Actor HandleJoinOperation(LitePeer peer, JoinRequest joinRequest, SendParameters sendParameters) { if (this.IsDisposed) { // join arrived after being disposed - repeat join operation if (Log.IsWarnEnabled) { Log.WarnFormat("Join operation on disposed game. GameName={0}", this.Name); } return null; } if (Log.IsDebugEnabled) { Log.DebugFormat("Join operation from IP: {0} to port: {1}", peer.RemoteIP, peer.LocalPort); } // create an new actor Actor actor; if (this.TryAddPeerToGame(peer, out actor) == false) { peer.SendOperationResponse( new OperationResponse { OperationCode = joinRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Peer already joined the specified game." }, sendParameters); return null; } // set game properties for join from the first actor if (this.Actors.Count == 1) { this.DeleteCacheOnLeave = joinRequest.DeleteCacheOnLeave; if (joinRequest.GameProperties != null) { this.Properties.SetProperties(joinRequest.GameProperties); } } // set custom actor properties if defined if (joinRequest.ActorProperties != null) { actor.Properties.SetProperties(joinRequest.ActorProperties); } // set operation return values and publish the response var joinResponse = new JoinResponse { ActorNr = actor.ActorNr }; if (this.Properties.Count > 0) { joinResponse.CurrentGameProperties = this.Properties.GetProperties(); } foreach (Actor t in this.Actors) { if (t.ActorNr != actor.ActorNr && t.Properties.Count > 0) { if (joinResponse.CurrentActorProperties == null) { joinResponse.CurrentActorProperties = new Hashtable(); } Hashtable actorProperties = t.Properties.GetProperties(); joinResponse.CurrentActorProperties.Add(t.ActorNr, actorProperties); } } peer.SendOperationResponse(new OperationResponse(joinRequest.OperationRequest.OperationCode, joinResponse), sendParameters); // publish join event this.PublishJoinEvent(peer, joinRequest); this.PublishEventCache(peer); return actor; }
private void HandleLiteOperations(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters) { string message = string.Format("Unknown operation code {0}", (Lite.Operations.OperationCode)operationRequest.OperationCode); peer.SendOperationResponse( new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = -1, DebugMessage = message }, sendParameters); if (Log.IsWarnEnabled) { Log.Warn(message); } }
private void HandleUpdateFlightControls(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters) { var op = new UpdateControlsRequest(peer.Protocol, operationRequest); if (peer.ValidateOperation(op, sendParameters) == false) { return; } DebugLog(peer, operationRequest); op.OnStart(); peer.SendOperationResponse(new OperationResponse { OperationCode = op.OperationRequest.OperationCode }, sendParameters); op.OnComplete(); }
/// <summary> /// Handles the <see cref = "RaiseEventRequest" />: Sends a <see cref = "CustomEvent" /> to actors in the room. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "raiseEventRequest"> /// The operation /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleRaiseEventOperation(LitePeer peer, RaiseEventRequest raiseEventRequest, SendParameters sendParameters) { // get the actor who send the operation request Actor actor = this.GetActorByPeer(peer); if (actor == null) { return; } var customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data); if (raiseEventRequest.Cache == (byte) CacheOperation.RemoveFromRoomCache) { this.roomEventCache.RemoveEvents(raiseEventRequest); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) {ReturnCode = 0}; peer.SendOperationResponse(response, sendParameters); return; } // publish the custom event IEnumerable<Actor> recipients; if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0) { recipients = this.Actors.GetActorsByNumbers(raiseEventRequest.Actors); sendParameters.Flush = raiseEventRequest.Flush; this.PublishEvent(customEvent, recipients, sendParameters); return; } switch (raiseEventRequest.ReceiverGroup) { case (byte) ReceiverGroup.All: { recipients = this.Actors; if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCache) { customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCacheGlobal) { customEvent.ActorNr = 0; customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache != (byte) CacheOperation.DoNotCache) { if (!this.UpdateEventCache(actor, raiseEventRequest, raiseEventRequest.EvCode)) { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache }, sendParameters); return; } customEvent.Cache = raiseEventRequest.Cache; } break; } case (byte) ReceiverGroup.Others: { recipients = this.Actors.GetExcludedList(actor); if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCache) { customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache == (byte) CacheOperation.AddToRoomCacheGlobal) { customEvent.ActorNr = 0; customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache != (byte) CacheOperation.DoNotCache) { if (!this.UpdateEventCache(actor, raiseEventRequest, raiseEventRequest.EvCode)) { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache }, sendParameters); return; } customEvent.Cache = raiseEventRequest.Cache; } break; } case (byte) ReceiverGroup.MasterClient: { recipients = new[] {this.Actors[0]}; break; } default: { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid ReceiverGroup " + raiseEventRequest.ReceiverGroup }, sendParameters); return; } } this.PublishEvent(customEvent, recipients, sendParameters); }
protected bool ValidateGame(LitePeer peer, OperationRequest operationRequest, SendParameters sendParameters) { var gamePeer = (GameClientPeer)peer; // check if the game is open if (this.isOpen == false) { var errorResponse = new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameClosed, DebugMessage = "Game closed" }; peer.SendOperationResponse(errorResponse, sendParameters); gamePeer.OnJoinFailed(ErrorCode.GameClosed); return false; } // check if the maximum number of players has already been reached if (this.maxPlayers > 0 && this.Actors.Count >= this.maxPlayers) { var errorResponse = new OperationResponse { OperationCode = operationRequest.OperationCode, ReturnCode = (int)ErrorCode.GameFull, DebugMessage = "Game full" }; peer.SendOperationResponse(errorResponse, sendParameters); gamePeer.OnJoinFailed(ErrorCode.GameFull); return false; } return true; }
/// <summary> /// Handles the <see cref = "RaiseEventRequest" />: Sends a <see cref = "CustomEvent" /> to actors in the room. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "raiseEventRequest"> /// The operation /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleRaiseEventOperation(LitePeer peer, RaiseEventRequest raiseEventRequest, SendParameters sendParameters) { // get the actor who send the operation request Actor actor = this.GetActorByPeer(peer); if (actor == null) { return; } var customEvent = new CustomEvent(actor.ActorNr, raiseEventRequest.EvCode, raiseEventRequest.Data); if (raiseEventRequest.Cache == (byte)CacheOperation.RemoveFromRoomCache) { this.roomEventCache.RemoveEvents(raiseEventRequest); var response = new OperationResponse(raiseEventRequest.OperationRequest.OperationCode) { ReturnCode = 0 }; peer.SendOperationResponse(response, sendParameters); return; } // publish the custom event IEnumerable <Actor> recipients; if (raiseEventRequest.Actors != null && raiseEventRequest.Actors.Length > 0) { recipients = this.Actors.GetActorsByNumbers(raiseEventRequest.Actors); sendParameters.Flush = raiseEventRequest.Flush; this.PublishEvent(customEvent, recipients, sendParameters); return; } switch (raiseEventRequest.ReceiverGroup) { case (byte)ReceiverGroup.All: { recipients = this.Actors; if (raiseEventRequest.Cache == (byte)CacheOperation.AddToRoomCache) { customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache == (byte)CacheOperation.AddToRoomCacheGlobal) { customEvent.ActorNr = 0; customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache != (byte)CacheOperation.DoNotCache) { if (!this.UpdateEventCache(actor, raiseEventRequest, raiseEventRequest.EvCode)) { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache }, sendParameters); return; } customEvent.Cache = raiseEventRequest.Cache; } break; } case (byte)ReceiverGroup.Others: { recipients = this.Actors.GetExcludedList(actor); if (raiseEventRequest.Cache == (byte)CacheOperation.AddToRoomCache) { customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache == (byte)CacheOperation.AddToRoomCacheGlobal) { customEvent.ActorNr = 0; customEvent.Cache = raiseEventRequest.Cache; this.roomEventCache.AddEvent(customEvent); } else if (raiseEventRequest.Cache != (byte)CacheOperation.DoNotCache) { if (!this.UpdateEventCache(actor, raiseEventRequest, raiseEventRequest.EvCode)) { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid cache operation " + raiseEventRequest.Cache }, sendParameters); return; } customEvent.Cache = raiseEventRequest.Cache; } break; } case (byte)ReceiverGroup.MasterClient: { recipients = new[] { this.Actors[0] }; break; } default: { peer.SendOperationResponse( new OperationResponse { OperationCode = raiseEventRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = "Invalid ReceiverGroup " + raiseEventRequest.ReceiverGroup }, sendParameters); return; } } this.PublishEvent(customEvent, recipients, sendParameters); }
/// <summary> /// Handles the <see cref = "SetPropertiesRequest" /> and sends event <see cref = "PropertiesChangedEvent" /> to all <see cref = "Actor" />s in the room. /// </summary> /// <param name = "peer"> /// The peer. /// </param> /// <param name = "setPropertiesRequest"> /// The <see cref = "SetPropertiesRequest" /> operation to handle. /// </param> /// <param name = "sendParameters"> /// The send Parameters. /// </param> protected virtual void HandleSetPropertiesOperation(LitePeer peer, SetPropertiesRequest setPropertiesRequest, SendParameters sendParameters) { if (setPropertiesRequest.ActorNumber > 0) { Actor actor = this.Actors.GetActorByNumber(setPropertiesRequest.ActorNumber); if (actor == null) { peer.SendOperationResponse( new OperationResponse { OperationCode = setPropertiesRequest.OperationRequest.OperationCode, ReturnCode = -1, DebugMessage = string.Format("Actor with number {0} not found.", setPropertiesRequest.ActorNumber) }, sendParameters); return; } actor.Properties.SetProperties(setPropertiesRequest.Properties); } else { this.Properties.SetProperties(setPropertiesRequest.Properties); } peer.SendOperationResponse(new OperationResponse { OperationCode = setPropertiesRequest.OperationRequest.OperationCode }, sendParameters); // if the optional paramter Broadcast is set a EvPropertiesChanged // event will be send to room actors if (setPropertiesRequest.Broadcast) { Actor actor = this.Actors.GetActorByPeer(peer); IEnumerable<Actor> recipients = this.Actors.GetExcludedList(actor); var propertiesChangedEvent = new PropertiesChangedEvent(actor.ActorNr) { TargetActorNumber = setPropertiesRequest.ActorNumber, Properties = setPropertiesRequest.Properties }; this.PublishEvent(propertiesChangedEvent, recipients, 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; } if (this.LogQueue.Log.IsDebugEnabled) { 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; } if (this.LogQueue.Log.IsDebugEnabled) { 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; } case OperationCode.ChangeGroups: { var changeGroupsOperation = new ChangeGroups(peer.Protocol, operationRequest); if (peer.ValidateOperation(changeGroupsOperation, sendParameters) == false) { return; } changeGroupsOperation.OnStart(); this.HandleChangeGroupsOperation(peer, changeGroupsOperation, sendParameters); changeGroupsOperation.OnComplete(); 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); } }