/// <summary> /// Finds the enclosing private area. /// </summary> /// <param name="enclosedSharedObject">The enclosed shared object.</param> /// <returns>null or the enclosing shared object if found.</returns> public SharedObject FindEnclosingPrivateArea(SharedObject enclosedSharedObject) { foreach (var sharedObject in ZOrderListOfSharedObjects) { if (sharedObject.PrivateOwnerName != null && sharedObject.Rectangle.Contains(enclosedSharedObject.Rectangle)) { return(sharedObject); } } return(null); }
/// <summary> /// Tries to stack the grabbedSharedObject on another shared object. /// The grabbedShared object has to be composed of stackable elements and to be brought to front. /// The first shared object found under the grabbed shared object has also to be composed of stackable /// elements of the same kind and must be placed at the same location. /// </summary> /// <param name="grabbedSharedObject">The grabbed shared object.</param> /// <param name="stackObject">The stack object.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public bool TryToStackOnAnotherSharedObject(SharedObject grabbedSharedObject, out SharedObject stackObject) { stackObject = null; if (!(grabbedSharedObject.GameElements.First() is IStackable)) { return(false); } if (ZOrderListOfSharedObjects.First() != grabbedSharedObject) { return(false); } foreach (SharedObject sharedObject in ZOrderListOfSharedObjects) { if (sharedObject.Rectangle.IntersectsWith(grabbedSharedObject.Rectangle) && sharedObject != grabbedSharedObject) { // sharedObject is the first shared object found under the grabbed one. Point centerSharedObject = new Point(sharedObject.Location.X + sharedObject.Rectangle.Width / 2, sharedObject.Location.Y + sharedObject.Rectangle.Height / 2); Point centerGrabbedObject = new Point(grabbedSharedObject.Location.X + grabbedSharedObject.Rectangle.Width / 2, grabbedSharedObject.Location.Y + grabbedSharedObject.Rectangle.Height / 2); if (centerSharedObject.Equals(centerGrabbedObject) && sharedObject.GameElements.First() is IStackable && sharedObject.GameElements.First().GetType() == grabbedSharedObject.GameElements.First().GetType()) { // stacking is possible: stackObject = sharedObject; } break; } } if (stackObject != null) { if (stackObject.GameElements.Count < 2 && stackObject.GameElements.First() is Card) { // The stack object was a single card. Change its size for a stack of cards: stackObject.Rectangle = new Rectangle(stackObject.Rectangle.X, stackObject.Rectangle.Y, DimXStackOfCards, DimYStackOfCards); // and apply again magnetic grid: stackObject.Rectangle = new Rectangle(GetMagneticLocation(stackObject.Rectangle), stackObject.Rectangle.Size); } // Stack the elements for (int i = grabbedSharedObject.GameElements.Count - 1; i >= 0; i--) { GameElement gameElement = grabbedSharedObject.GameElements[i]; stackObject.GameElements.Insert(0, gameElement); } // Remove the grabbed shared object from the ZList: ZOrderListOfSharedObjects.RemoveAt(0); return(true); } return(false); }
/// <summary> /// Creates a private area for the given client. /// </summary> /// <param name="clientName">Name of the client.</param> /// <param name="newSharedObject">if set to <c>true</c> the private area was created; otherwise it was already existing.</param> /// <returns>SharedObject.</returns> public SharedObject CreatePrivateArea(string clientName, out bool newSharedObject) { newSharedObject = false; var foundSharedObject = FindPrivateArea(clientName); if (foundSharedObject == null) { newSharedObject = true; var id = GetFreeId(); var theNewSharedObject = new SharedObject(ZOrderListOfSharedObjects, id, new Rectangle(3, 3, 180, 100), clientName, new List <GameElement>(new[] { new GameElement("wood") })); ZOrderListOfSharedObjects.Insert(id, theNewSharedObject); theNewSharedObject.BringToFront(); return(theNewSharedObject); } return(foundSharedObject); }
/// <summary> /// Gathers the cards in the specified rectangle. /// </summary> /// <param name="gatheringRectangle">The gathering rectangle.</param> public void GatherCards(Rectangle gatheringRectangle) { SharedObject gatheringStackSharedObject = null; for (int i = ZOrderListOfSharedObjects.Count - 1; i >= 0; i--) { SharedObject sharedObject = ZOrderListOfSharedObjects[i]; if (gatheringRectangle.Contains(sharedObject.Rectangle) && sharedObject.GrabberName == null && sharedObject.GameElements.First() is Card) { gatheringStackSharedObject = sharedObject; break; } } if (gatheringStackSharedObject != null) { gatheringStackSharedObject.SetAllCardsSameFace(false); List <SharedObject> listSharedObjectsToGather = new List <SharedObject>(); for (int i = ZOrderListOfSharedObjects.Count - 1; i >= 0; i--) { SharedObject sharedObject = ZOrderListOfSharedObjects[i]; if (gatheringRectangle.Contains(sharedObject.Rectangle) && sharedObject.GrabberName == null && sharedObject.GameElements.First() is Card && sharedObject != gatheringStackSharedObject) { sharedObject.SetAllCardsSameFace(false); listSharedObjectsToGather.Add(sharedObject); } } foreach (SharedObject sharedObject in listSharedObjectsToGather) { GatherCards(sharedObject, gatheringStackSharedObject); } // gatheringStackSharedObject.Shuffle(); // Broadcast the gathering shared object move event: StateChangeEventDataType stateChangeEventDataType = new StateChangeEventDataType(); stateChangeEventDataType.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChangeEventDataType.SharedObjectId = gatheringStackSharedObject.Id; stateChangeEventDataType.NewSharedObjectLocation = gatheringStackSharedObject.Location; stateChangeEventDataType.SharedObjectSize = gatheringStackSharedObject.Rectangle.Size; stateChangeEventDataType.NewSharedObjectPicture = gatheringStackSharedObject.Picture; ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null); } }
/// <summary> /// Removes one client's private area of the ZOrderList of shared objects. /// </summary> /// <param name="clientName">Name of the client.</param> /// <returns>System.Int32.</returns> public int RemovePrivateArea(string clientName) { SharedObject foundSharedObject = null; foreach (var sharedObject in ZOrderListOfSharedObjects) { if (sharedObject.PrivateOwnerName == clientName) { foundSharedObject = sharedObject; break; } } if (foundSharedObject != null) { ZOrderListOfSharedObjects.RemoveAt(ZOrderListOfSharedObjects.IndexOf(foundSharedObject)); return(foundSharedObject.Id); } return(-1); }
/// <summary> /// Checks if the given private area contains other shared objects. /// </summary> /// <param name="privateArea">The private area.</param> /// <returns>true if the given private area contains other shared objects</returns> public bool PrivateAreaIsNotEmpty(SharedObject privateArea) { if (privateArea.PrivateOwnerName == null) { return(true); // Not a private area } foreach (var sharedObject in ZOrderListOfSharedObjects) { if (sharedObject == privateArea) { return(false); } if (sharedObject != privateArea && privateArea.Rectangle.Contains(sharedObject.Rectangle)) { return(true); } } return(false); }
/// <summary> /// Gathers the cards of sharedObject in the GameElments of gatheringObject. /// </summary> /// <param name="sharedObject">The shared object.</param> /// <param name="gatheringObject">The gathering object.</param> public void GatherCards(SharedObject sharedObject, SharedObject gatheringObject) { if (sharedObject.GameElements.First() is Card && gatheringObject.GameElements.First() is Card) { if (gatheringObject.GameElements.Count == 1) { // The gathering object was a single card. Change its size for a stack of cards: gatheringObject.Rectangle = new Rectangle(gatheringObject.Rectangle.X, gatheringObject.Rectangle.Y, DimXStackOfCards, DimYStackOfCards); // and apply again magnetic grid: gatheringObject.Rectangle = new Rectangle(GetMagneticLocation(gatheringObject.Rectangle), gatheringObject.Rectangle.Size); } // Transfer the cards: try { foreach (Card card in sharedObject.GameElements) { gatheringObject.GameElements.Insert(0, card); } } catch (Exception ex) { ScgBroadcastorService.LogError(string.Format("Unexpected exception '{0}' in GameState.GatherCards in foreach loop doing gatheringObject.GameElements.Add(card);", ex.Message), 97); throw; } // Broadcast the gathering shared object move event: StateChangeEventDataType stateChangeEventDataType = new StateChangeEventDataType(); stateChangeEventDataType.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChangeEventDataType.SharedObjectId = gatheringObject.Id; stateChangeEventDataType.NewSharedObjectLocation = gatheringObject.Location; stateChangeEventDataType.SharedObjectSize = gatheringObject.Rectangle.Size; stateChangeEventDataType.NewSharedObjectPicture = gatheringObject.Picture; ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null); // Remove the source shared object and broadcast the dispose event: ZOrderListOfSharedObjects.Remove(sharedObject); stateChangeEventDataType.StateChangeEventType = StateChangeEventType.DisposeSharedObject; stateChangeEventDataType.SharedObjectId = sharedObject.Id; ScgBroadcastorService.BroadcastStateChange(stateChangeEventDataType, null, null); } }
/// <summary> /// Checks if the given private area contains other shared objects. /// </summary> /// <param name="privateArea">The private area.</param> /// <returns>true if the given private area contains other shared objects</returns> public bool PrivateAreaIsNotEmpty(SharedObject privateArea) { if (privateArea.PrivateOwnerName == null) { return true; // Not a private area } foreach (var sharedObject in ZOrderListOfSharedObjects) { if (sharedObject == privateArea) { return false; } if (sharedObject != privateArea && privateArea.Rectangle.Contains(sharedObject.Rectangle)) { return true; } } return false; }
/// <summary> /// Tries to stack the grabbedSharedObject on another shared object. /// The grabbedShared object has to be composed of stackable elements and to be brought to front. /// The first shared object found under the grabbed shared object has also to be composed of stackable /// elements of the same kind and must be placed at the same location. /// </summary> /// <param name="grabbedSharedObject">The grabbed shared object.</param> /// <param name="stackObject">The stack object.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> public bool TryToStackOnAnotherSharedObject(SharedObject grabbedSharedObject, out SharedObject stackObject) { stackObject = null; if (!(grabbedSharedObject.GameElements.First() is IStackable)) { return false; } if (ZOrderListOfSharedObjects.First() != grabbedSharedObject) { return false; } foreach (SharedObject sharedObject in ZOrderListOfSharedObjects) { if (sharedObject.Rectangle.IntersectsWith(grabbedSharedObject.Rectangle) && sharedObject != grabbedSharedObject) { // sharedObject is the first shared object found under the grabbed one. Point centerSharedObject = new Point(sharedObject.Location.X + sharedObject.Rectangle.Width / 2, sharedObject.Location.Y + sharedObject.Rectangle.Height / 2); Point centerGrabbedObject = new Point(grabbedSharedObject.Location.X + grabbedSharedObject.Rectangle.Width / 2, grabbedSharedObject.Location.Y + grabbedSharedObject.Rectangle.Height / 2); if (centerSharedObject.Equals(centerGrabbedObject) && sharedObject.GameElements.First() is IStackable && sharedObject.GameElements.First().GetType() == grabbedSharedObject.GameElements.First().GetType()) { // stacking is possible: stackObject = sharedObject; } break; } } if (stackObject != null) { if (stackObject.GameElements.Count < 2 && stackObject.GameElements.First() is Card) { // The stack object was a single card. Change its size for a stack of cards: stackObject.Rectangle = new Rectangle(stackObject.Rectangle.X, stackObject.Rectangle.Y, DimXStackOfCards, DimYStackOfCards); // and apply again magnetic grid: stackObject.Rectangle = new Rectangle(GetMagneticLocation(stackObject.Rectangle),stackObject.Rectangle.Size); } // Stack the elements for (int i = grabbedSharedObject.GameElements.Count - 1; i >= 0; i--) { GameElement gameElement = grabbedSharedObject.GameElements[i]; stackObject.GameElements.Insert(0, gameElement); } // Remove the grabbed shared object from the ZList: ZOrderListOfSharedObjects.RemoveAt(0); return true; } return false; }
/// <summary> /// Finds the enclosing private area. /// </summary> /// <param name="enclosedSharedObject">The enclosed shared object.</param> /// <returns>null or the enclosing shared object if found.</returns> public SharedObject FindEnclosingPrivateArea(SharedObject enclosedSharedObject) { foreach (var sharedObject in ZOrderListOfSharedObjects) { if (sharedObject.PrivateOwnerName != null && sharedObject.Rectangle.Contains(enclosedSharedObject.Rectangle)) { return sharedObject; } } return null; }
/// <summary> /// Creates a private area for the given client. /// </summary> /// <param name="clientName">Name of the client.</param> /// <param name="newSharedObject">if set to <c>true</c> the private area was created; otherwise it was already existing.</param> /// <returns>SharedObject.</returns> public SharedObject CreatePrivateArea(string clientName, out bool newSharedObject) { newSharedObject = false; var foundSharedObject = FindPrivateArea(clientName); if (foundSharedObject == null) { newSharedObject = true; var id = GetFreeId(); var theNewSharedObject = new SharedObject(ZOrderListOfSharedObjects, id, new Rectangle(3, 3, 180, 100), clientName, new List<GameElement>(new[] {new GameElement("wood")})); ZOrderListOfSharedObjects.Insert(id, theNewSharedObject); theNewSharedObject.BringToFront(); return theNewSharedObject; } return foundSharedObject; }
/// <summary> /// Notifies the server command. /// (Will be remotely called by the clients) /// </summary> /// <param name="clientCommandData">The client command data.</param> public void NotifyServerCmd(ClientCommandDataType clientCommandData) { // Handle the received mouseEventData and update the State of the Shared Card Game: switch (clientCommandData.ClientCommandType) { case ClientCommandType.LeavingCmd: lock (ClientsLocker) { LogInfo( string.Format("NotifyServerCmd (LeavingCmd, clientCommandData.ClientName = '{0}')", clientCommandData.ClientName), 10); Client leavingClient; var foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out leavingClient); if (foundTheClient) { // Free a possible grabbed object by the leaving client: if (leavingClient.GrabbedSharedObject != null) { leavingClient.GrabbedSharedObject.GrabberName = null; leavingClient.GrabbedSharedObject. ContextualMenuOpened = false; } Clients.Remove(leavingClient.Name); LogInfo(string.Format("_clients.Remove(leavingClient.Name = '{0}')", leavingClient.Name), 11); // Remove the private area of the inactive client var removedSharedObjectId = _gameState.RemovePrivateArea(leavingClient.Name); // Note: The removedSharedObjectId should be >= 0 if (removedSharedObjectId >= 0) { // Inform other existing clients of the disposed PrivateArea id: foreach (var client in Clients) { // Prepare StateChangeEventDataType: var stateChangeEventDataType = new StateChangeEventDataType(); stateChangeEventDataType.StateChangeEventType = StateChangeEventType.DisposeSharedObject; stateChangeEventDataType.SharedObjectId = removedSharedObjectId; stateChangeEventDataType.PrivateOwnerClientName = leavingClient.Name; // Send the StateChangeEventDataType to the client: client.Value.ScgBroadcastorCallBack.BroadcastToClient( stateChangeEventDataType); LogInfo( string.Format( "BroadcastToClient'{0}'(DisposeSharedObject, removedSharedObjectId = '{1}')", client.Value.Name, removedSharedObjectId), 12); } } } } break; case ClientCommandType.GatheringCmd: lock (GameStateLocker) { Rectangle gatheringRectangle = clientCommandData.TargetRectangle; LogInfo(string.Format("NotifyServerCmd (GatheringCmd, clientCommandData.ClientName = '{0} gatheringRectangle = [Location={1},Size={2}]')", clientCommandData.ClientName, gatheringRectangle.Location, gatheringRectangle.Size), 20); try { _gameState.GatherCards(gatheringRectangle); } catch (Exception ex) { LogError(string.Format("Unexpected exception '{0}' raised in NotifyServerCmd(GatheringCmd) handling when calling _gameState.GatherCards(gatheringRectangle)", ex.Message), 98); throw; } } break; case ClientCommandType.RequestDealingParametersCmd: lock (GameStateLocker) { SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId); LogInfo( string.Format( "NotifyServerCmd (RequestDealingParametersCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')", clientCommandData.ClientName, clientCommandData.SharedObjectId), 31); if (stackOfCards != null && stackOfCards.GameElements.First() is Card && stackOfCards.GrabberName == null) { Client theClient; bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out theClient); if (foundTheClient && theClient != null) { // Do the specific stuff here: // Prepare and send state change for the clicked stack of cards shared object: StateChangeEventDataType stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.OpenDealingParametersDialog; stateChange.SharedObjectId = stackOfCards.Id; stateChange.GrabbingClientName = clientCommandData.ClientName; stateChange.ReleasingClientName = null; stateChange.PrivateOwnerClientName = null; stateChange.DealingClockwise = DealingClockwise; stateChange.NumberOfCardsToDeal = NumberOfCardsToDeal; LogInfo( "Broadcasting state change (OpenDealingParametersDialog) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // Prepare and send state change for the clicked stack of cards shared object: stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = clientCommandData.ClientName; stateChange.ReleasingClientName = null; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // The stackOfCards is again grabbed: stackOfCards.GrabberName = clientCommandData.ClientName; stackOfCards.ContextualMenuOpened = false; theClient.GrabbedSharedObject = stackOfCards; } } } break; case ClientCommandType.CancelDealingParametersDialogCmd: lock (GameStateLocker) { SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId); LogInfo( string.Format( "NotifyServerCmd (CancelDealingParametersDialogCmdl, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')", clientCommandData.ClientName, clientCommandData.SharedObjectId), 31); if (stackOfCards != null && stackOfCards.GameElements.First() is Card) { Client theClient; bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out theClient); if (foundTheClient && theClient != null) { // Do the specific stuff here: // Prepare and send state change for the clicked stack of cards shared object: StateChangeEventDataType stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.ReleasingClientName = clientCommandData.ClientName; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // The stackOfCards is no more grabbed: stackOfCards.GrabberName = null; stackOfCards.ContextualMenuOpened = false; theClient.GrabbedSharedObject = null; } } } break; case ClientCommandType.ExtractFirstCardCmd: lock (GameStateLocker) { SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId); LogInfo( string.Format("NotifyServerCmd (ExtractFirstCardCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')", clientCommandData.ClientName, clientCommandData.SharedObjectId), 31); if (stackOfCards != null && stackOfCards.GameElements.First() is Card) { // Check that no card is already present at the extraction location; Point extractLocation = new Point(stackOfCards.Location.X + stackOfCards.Rectangle.Width / 2 - ScgGameState.MagneticGridStep - ScgGameState.DimXCard, stackOfCards.Location.Y + stackOfCards.Rectangle.Height / 2 - ScgGameState.MagneticGridStep - ScgGameState.DimYCard); // Vérifier l'extract location !!! SharedObject otherObject = _gameState.GetSharedObjectAt(extractLocation); if (!(otherObject != null && otherObject.GameElements.First() is Card && otherObject.Location.Equals(extractLocation))) { LogInfo(string.Format("OK, the extraction Location is free ! clientCommandData.ClientName='{0}'", clientCommandData.ClientName), 97); Client theClient; bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out theClient); if (foundTheClient && theClient != null) { // Extract the top most card and create a new shared object: Card extractedCard = (Card) stackOfCards.GameElements.First(); stackOfCards.GameElements.RemoveAt(0); // Create a new shared object for the extracted card: SharedObject newSharedObject = new SharedObject(_gameState.ZOrderListOfSharedObjects, _gameState.GetFreeId(), new Rectangle( new Point( stackOfCards.Location.X - ScgGameState.MagneticGridStep, stackOfCards.Location.Y - ScgGameState.MagneticGridStep), new Size(ScgGameState.DimXCard, ScgGameState.DimYCard)), null, new List<GameElement>()); newSharedObject.GameElements.Add(extractedCard); if (stackOfCards.GameElements.Count == 1) { // Resize the clickedSharedObject which owns now a single card: stackOfCards.Rectangle = new Rectangle(stackOfCards.Location, new Size(ScgGameState.DimXCard, ScgGameState.DimYCard)); // Apply magnetic grid: stackOfCards.Rectangle = new Rectangle( ScgGameState.GetMagneticLocation( stackOfCards.Rectangle), stackOfCards.Rectangle.Size); } // The stackOfCards is no more grabbed: stackOfCards.GrabberName = null; stackOfCards.ContextualMenuOpened = false; // Prepare and send state change for the clicked shared object: StateChangeEventDataType stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.ReleasingClientName = clientCommandData.ClientName; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // Add the new Shared object to the ZOrderList: _gameState.ZOrderListOfSharedObjects.Insert(0, newSharedObject); // Prepare sending the state change for the new Shared object: stateChange.StateChangeEventType = StateChangeEventType.NewSharedObject; stateChange.SharedObjectId = newSharedObject.Id; stateChange.NewSharedObjectPicture = newSharedObject.Picture; stateChange.NewSharedObjectLocation = newSharedObject.Location; stateChange.SharedObjectSize = newSharedObject.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.PrivateOwnerClientName = null; LogInfo( string.Format("Broadcasting state change (NewSharedObject) for the extracted card shared object (newSharedObject.Id ={0})",newSharedObject.Id),95); BroadcastStateChange(stateChange, null, null); // Mark the new object as not grabbed: newSharedObject.GrabberName = null; theClient.GrabbedSharedObject = null; newSharedObject.BringToFront(); } } else { LogWarning(string.Format("NOT OK, the extraction Location is not free ! clientCommandData.ClientName='{0}'", clientCommandData.ClientName), 97); } } } break; case ClientCommandType.CountCardsCmd: lock (GameStateLocker) { SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId); LogInfo( string.Format( "NotifyServerCmd (CountCardsCmd clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')", clientCommandData.ClientName, clientCommandData.SharedObjectId), 31); if (stackOfCards != null && stackOfCards.GameElements.First() is Card) { Client theClient; bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out theClient); if (foundTheClient && theClient != null) { // Do the specific stuff here: StateChangeEventDataType stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.ShowMessage; stateChange.SharedObjectId = stackOfCards.Id; stateChange.RecipientClientName = clientCommandData.ClientName; stateChange.ToEveryone = false; stateChange.MessageToDisplay = string.Format("This deck includes {0} cards.", stackOfCards.GameElements.Count); stateChange.MessageBoxTitle = "Deck Card Count"; LogInfo( "Broadcasting state change (ShowMessage) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // Prepare and send state change for the clicked stack of cards shared object: stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.ReleasingClientName = clientCommandData.ClientName; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // The stackOfCards is no more grabbed: stackOfCards.GrabberName = null; stackOfCards.ContextualMenuOpened = false; theClient.GrabbedSharedObject = null; } } } break; case ClientCommandType.DealCmd: lock (GameStateLocker) { SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId); LogInfo( string.Format( "NotifyServerCmd (DealCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')", clientCommandData.ClientName, clientCommandData.SharedObjectId), 31); if (stackOfCards != null && stackOfCards.GameElements.First() is Card) { Client theDealerClient; bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out theDealerClient); if (foundTheClient && theDealerClient != null) { // Do the specific stuff here: DealingClockwise = clientCommandData.DealingClockwise; NumberOfCardsToDeal = clientCommandData.NumberOfCardsToDeal; //DO THE DEALING: TO BE COMPLETED // Code issued from ExtractFirstCard as reference // Extract the top most card and create a new shared object: Card extractedCard = (Card)stackOfCards.GameElements.First(); stackOfCards.GameElements.RemoveAt(0); // Create a new shared object for the extracted card: SharedObject newSharedObject = new SharedObject(_gameState.ZOrderListOfSharedObjects, _gameState.GetFreeId(), new Rectangle( new Point( stackOfCards.Location.X - ScgGameState.MagneticGridStep, stackOfCards.Location.Y - ScgGameState.MagneticGridStep), new Size(ScgGameState.DimXCard, ScgGameState.DimYCard)), null, new List<GameElement>()); newSharedObject.GameElements.Add(extractedCard); if (stackOfCards.GameElements.Count == 1) { // Resize the clickedSharedObject which owns now a single card: stackOfCards.Rectangle = new Rectangle(stackOfCards.Location, new Size(ScgGameState.DimXCard, ScgGameState.DimYCard)); // Apply magnetic grid: stackOfCards.Rectangle = new Rectangle( ScgGameState.GetMagneticLocation( stackOfCards.Rectangle), stackOfCards.Rectangle.Size); } // The stackOfCards is no more grabbed: stackOfCards.GrabberName = null; stackOfCards.ContextualMenuOpened = false; // Prepare and send state change for the clicked shared object: StateChangeEventDataType stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.ReleasingClientName = clientCommandData.ClientName; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // Add the new Shared object to the ZOrderList: _gameState.ZOrderListOfSharedObjects.Insert(0, newSharedObject); // Prepare sending the state change for the new Shared object: stateChange.StateChangeEventType = StateChangeEventType.NewSharedObject; stateChange.SharedObjectId = newSharedObject.Id; stateChange.NewSharedObjectPicture = newSharedObject.Picture; stateChange.NewSharedObjectLocation = newSharedObject.Location; stateChange.SharedObjectSize = newSharedObject.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.PrivateOwnerClientName = null; LogInfo( string.Format("Broadcasting state change (NewSharedObject) for the extracted card shared object (newSharedObject.Id ={0})", newSharedObject.Id), 95); BroadcastStateChange(stateChange, null, null); // Prepare and send state change for the clicked stack of cards shared object: stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.ReleasingClientName = clientCommandData.ClientName; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // The stackOfCards is no more grabbed: stackOfCards.GrabberName = null; stackOfCards.ContextualMenuOpened = false; theDealerClient.GrabbedSharedObject = null; } } } break; case ClientCommandType.ShuffleUpCmd: lock (GameStateLocker) { SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId); LogInfo( string.Format( "NotifyServerCmd (ShuffleUpCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')", clientCommandData.ClientName, clientCommandData.SharedObjectId), 31); if (stackOfCards != null && stackOfCards.GameElements.First() is Card) { Client theClient; bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out theClient); if (foundTheClient && theClient != null) { // Do the specific stuff here: stackOfCards.Shuffle(); // Prepare and send state change for the clicked stack of cards shared object: StateChangeEventDataType stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.ReleasingClientName = clientCommandData.ClientName; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // The stackOfCards is no more grabbed: stackOfCards.GrabberName = null; stackOfCards.ContextualMenuOpened = false; theClient.GrabbedSharedObject = null; } } } break; case ClientCommandType.ContextualMenuClosedCmd: lock (GameStateLocker) { SharedObject stackOfCards = _gameState.GetSharedObjectFromId(clientCommandData.SharedObjectId); LogInfo( string.Format( "NotifyServerCmd (ContextualMenuClosedCmd, clientCommandData.ClientName = '{0}', clientCommandData.SharedObjectId = '{1}')", clientCommandData.ClientName, clientCommandData.SharedObjectId), 31); if (stackOfCards != null && stackOfCards.GameElements.First() is Card) { Client theClient; bool foundTheClient = Clients.TryGetValue(clientCommandData.ClientName, out theClient); if (foundTheClient && theClient != null && theClient.GrabbedSharedObject != null && theClient.GrabbedSharedObject.Id == stackOfCards.Id) { // Do the specific stuff here: // Nothing to do. // Prepare and send state change for the clicked stack of cards shared object: StateChangeEventDataType stateChange = new StateChangeEventDataType(); stateChange.StateChangeEventType = StateChangeEventType.SharedObjectMove; stateChange.SharedObjectId = stackOfCards.Id; stateChange.NewSharedObjectPicture = stackOfCards.Picture; stateChange.NewSharedObjectLocation = stackOfCards.Location; stateChange.SharedObjectSize = stackOfCards.Rectangle.Size; stateChange.GrabbingClientName = null; stateChange.ReleasingClientName = clientCommandData.ClientName; stateChange.PrivateOwnerClientName = null; LogInfo( "Broadcasting state change (SharedObjectMove) for the clicked shared object (stackOfCard)", 95); BroadcastStateChange(stateChange, null, null); // The stackOfCards is no more grabbed: stackOfCards.GrabberName = null; stackOfCards.ContextualMenuOpened = false; theClient.GrabbedSharedObject = null; } } } break; } }
/// <summary> /// Broadcasts the state change to all clients. /// </summary> /// <param name="stateChangeEventDataType">Type of the state change event data.</param> /// <param name="enclosingPrivateArea">The enclosing private area.</param> /// <param name="otherFaceCardPicture">The other face card picture.</param> public void BroadcastStateChange(StateChangeEventDataType stateChangeEventDataType, SharedObject enclosingPrivateArea, string otherFaceCardPicture) { // if required, Broadcast The state change to each client: if (stateChangeEventDataType.StateChangeEventType != StateChangeEventType.NoStateChange) { lock (ClientsLocker) { var inactiveClients = new List<string>(); foreach (var client in Clients) { try { // Change the NewSharedObjectPicture information for card on private area for the PrivateAreaOwner client only: if (stateChangeEventDataType.StateChangeEventType == StateChangeEventType.SharedObjectMove && enclosingPrivateArea != null && otherFaceCardPicture != null && client.Value.Name == enclosingPrivateArea.PrivateOwnerName) { var savedPicture = stateChangeEventDataType.NewSharedObjectPicture; stateChangeEventDataType.NewSharedObjectPicture = otherFaceCardPicture; (client.Value).ScgBroadcastorCallBack.BroadcastToClient(stateChangeEventDataType); stateChangeEventDataType.NewSharedObjectPicture = savedPicture; } else { (client.Value).ScgBroadcastorCallBack.BroadcastToClient(stateChangeEventDataType); } } catch (Exception ex) { LogError(string.Format("Exception '{0}' raised in ScgBroadcastorService.BroadcastStateChange when calling (client.Value).ScgBroadcastorCallBack.BroadcastToClient(). client.Value.Name = '{1}')", ex.Message , client.Value.Name), 99); inactiveClients.Add(client.Key); } } if (inactiveClients.Count > 0) { foreach (var inactiveClient in inactiveClients) { // Search the leavingClient (Client) corresponding to the inactiveClient (name): Client leavingClient; var foundTheClient = Clients.TryGetValue(inactiveClient, out leavingClient); if (foundTheClient) { // Free a possible grabbed object by the leaving client: if (leavingClient.GrabbedSharedObject != null) { leavingClient.GrabbedSharedObject.GrabberName = null; leavingClient.GrabbedSharedObject.ContextualMenuOpened = false; } } // Remove the inactive client from the clients list: Clients.Remove(inactiveClient); LogInfo(string.Format("_clients.Remove(inactiveClient = '{0}')", inactiveClient), 13); // Remove the private area of the inactive client var removedSharedObjectId = _gameState.RemovePrivateArea(inactiveClient); // Note: The removedSharedObjectId should be >= 0 if (removedSharedObjectId >= 0) { // Inform other existing clients of the disposed PrivateArea id: foreach (var client in Clients) { // Prepare StateChangeEventDataType: var aStateChangeEventDataType = new StateChangeEventDataType(); aStateChangeEventDataType.StateChangeEventType = StateChangeEventType.DisposeSharedObject; aStateChangeEventDataType.SharedObjectId = removedSharedObjectId; stateChangeEventDataType.PrivateOwnerClientName = inactiveClient; // Send the StateChangeEventDataType to the client: client.Value.ScgBroadcastorCallBack.BroadcastToClient( aStateChangeEventDataType); LogInfo( string.Format( "BroadcastToClient'{0}'(DisposeSharedObject, removedSharedObjectId = '{1}')", client.Value.Name, removedSharedObjectId), 14); } } } } } } }