Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SharedObject" /> class.
 /// </summary>
 /// <param name="zOrderList">The z order list.</param>
 /// <param name="id">The identifier.</param>
 /// <param name="rectangle">The rectangle.</param>
 /// <param name="privateOwnerName">Name of the private owner.</param>
 /// <param name="gameElements">The game elements.</param>
 public SharedObject(List <SharedObject> zOrderList, int id, Rectangle rectangle, string privateOwnerName, List <GameElement> gameElements)
 {
     _zOrderList = zOrderList;
     Id          = id;
     // Apply magnetic grid at creation:
     rectangle.Location = ScgGameState.GetMagneticLocation(rectangle);
     Rectangle          = rectangle;
     GrabbedLocation    = new Point(Rectangle.Left, Rectangle.Top);
     PrivateOwnerName   = privateOwnerName;
     GameElements       = gameElements;
     GrabberName        = null;
 }
        /// <summary>
        /// Registers the new client.
        /// </summary>
        /// <param name="clientName">Name of the client.</param>
        /// <param name="clientProtocolVersion"></param>
        public void RegisterClient(string clientName, int clientProtocolVersion)
        {
            if (!string.IsNullOrEmpty(clientName))
            {
                try
                {
                    var callback = OperationContext.Current.GetCallbackChannel<IScgBroadcastorCallBack>();
                    if (clientProtocolVersion != Common.ClientServerProtocolVersion)
                    {
                        callback.BroadcastBadProtocolVersion(Common.ClientServerProtocolVersion);
                        return;
                    }
                    lock (ClientsLocker)
                    {
                        if (Clients.Count <= MaxClientCount)
                        {
                            lock (GameStateLocker)
                            {
                                LogInfo(string.Format("RegisterClient(clientName = '{0}')", clientName), 1);
                                var removedPrivateAreaId = -1;
                                //Remove the old client using the same name:
                                if (Clients.Keys.Contains(clientName))
                                {
                                    // The new client uses an already registerd name. Refuse it:
                                    return;
                                }
                                //{
                                //    Clients.Remove(clientName);
                                //    LogWarning(string.Format("_clients.Remove(clientName = '{0}')", clientName), 2);
                                //    // Remove the private area of the old client
                                //    removedPrivateAreaId = _gameState.RemovePrivateArea(clientName);
                                //    // Note: The removedSharedObjectId should be >= 0
                                //    if (removedPrivateAreaId >= 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 = removedPrivateAreaId;
                                //            // Send the StateChangeEventDataType to the client:
                                //            client.Value.ScgBroadcastorCallBack.BroadcastToClient(
                                //                stateChangeEventDataType);
                                //            LogInfo(
                                //                string.Format(
                                //                    "BroadcastToClient'{0}'(DisposeSharedObject, removedPrivateAreaId = '{1}')",
                                //                    client.Value.Name, removedPrivateAreaId), 3);
                                //        }
                                //    }
                                //}
                                Clients.Add(clientName, new Client(clientName, callback));
                                LogInfo(string.Format("_clients.Add(clientName = '{0}')", clientName), 4);

                                if (Clients.Count == 1)
                                {
                                    // Initialize a new game state
                                    _gameState = new ScgGameState(this);
                                }
                                bool newSharedObject;
                                var privateArea = _gameState.CreatePrivateArea(clientName, out newSharedObject);

                                // Search a possible client without private area (The registering client was previously already registered under another name we do not know)
                                // WARNING: This now shouldn't occur since the registered clients will now hide the registering pane:
                                foreach (var client in Clients)
                                {
                                    if (_gameState.FindPrivateArea(client.Value.Name) == null)
                                    {
                                        var oldClientName = client.Value.Name;
                                        // Remove this orphan client corresponding to the old name of the registering client:
                                        Clients.Remove(oldClientName);
                                        LogWarning(
                                            string.Format("_clients.Remove(oldClientName = '{0}')", oldClientName), 5);

                                        // Inform other existing clients of the disposed PrivateArea id:
                                        foreach (var cli in Clients)
                                        {
                                            if (cli.Value.Name != clientName)
                                            {
                                                // Prepare StateChangeEventDataType:
                                                var stateChangeEventDataType =
                                                    new StateChangeEventDataType();
                                                stateChangeEventDataType.StateChangeEventType =
                                                    StateChangeEventType.DisposeSharedObject;
                                                stateChangeEventDataType.PrivateOwnerClientName = oldClientName;
                                                stateChangeEventDataType.SharedObjectId = removedPrivateAreaId;
                                                // Send the StateChangeEventDataType to the client:
                                                cli.Value.ScgBroadcastorCallBack.BroadcastToClient(
                                                    stateChangeEventDataType);
                                                LogInfo(
                                                    string.Format(
                                                        "BroadcastToClient'{0}'(DisposeSharedObject, removedPrivateAreaId = '{1}')",
                                                        cli.Value.Name, removedPrivateAreaId), 6);
                                            }
                                        }
                                        break;
                                    }
                                }

                                // Inform other existing clients of new PrivateArea:
                                foreach (var client in Clients)
                                {
                                    if (client.Value.Name != clientName)
                                    {
                                        // Prepare StateChangeEventDataType:
                                        var stateChangeEventDataType =
                                            new StateChangeEventDataType();
                                        stateChangeEventDataType.StateChangeEventType =
                                            StateChangeEventType.NewSharedObject;
                                        stateChangeEventDataType.SharedObjectId = privateArea.Id;
                                        stateChangeEventDataType.PrivateOwnerClientName = privateArea.PrivateOwnerName;
                                        stateChangeEventDataType.NewSharedObjectLocation =
                                            new Point(privateArea.Rectangle.Left, privateArea.Rectangle.Top);
                                        stateChangeEventDataType.SharedObjectSize =
                                            new Size(privateArea.Rectangle.Size.Width, privateArea.Rectangle.Size.Height);
                                        stateChangeEventDataType.NewSharedObjectPicture = privateArea.Picture;
                                        // Send the StateChangeEventDataType to the client:
                                        client.Value.ScgBroadcastorCallBack.BroadcastToClient(stateChangeEventDataType);
                                        LogInfo(
                                            string.Format(
                                                "BroadcastToClient'{0}'(NewSharedObject, privateArea.Id = '{1}')",
                                                client.Value.Name, privateArea.Id), 7);
                                    }
                                }

                                // Inform the new client (and only him) of the current state of the game:
                                Client newClient;
                                var foundNewClient = Clients.TryGetValue(clientName, out newClient);
                                if (foundNewClient && newClient != null)
                                {
                                    // Parse all shared objects in reversed order (from the back to the topmost one shared object):
                                    for (var i = _gameState.ZOrderListOfSharedObjects.Count - 1; i >= 0; i--)
                                    {
                                        var sharedObject = _gameState.ZOrderListOfSharedObjects[i];

                                        // Prepare StateChangeEventDataType:
                                        var stateChangeEventDataType = new StateChangeEventDataType();
                                        stateChangeEventDataType.StateChangeEventType =
                                            StateChangeEventType.NewSharedObject;
                                        stateChangeEventDataType.SharedObjectId = sharedObject.Id;
                                        stateChangeEventDataType.PrivateOwnerClientName = sharedObject.PrivateOwnerName;
                                        stateChangeEventDataType.NewSharedObjectLocation =
                                            new Point(sharedObject.Rectangle.Left, sharedObject.Rectangle.Top);
                                        stateChangeEventDataType.SharedObjectSize =
                                            new Size(sharedObject.Rectangle.Size.Width,
                                                sharedObject.Rectangle.Size.Height);
                                        stateChangeEventDataType.NewSharedObjectPicture = sharedObject.Picture;
                                        // Send the StateChangeEventDataType to the new (and only) client:
                                        newClient.ScgBroadcastorCallBack.BroadcastToClient(stateChangeEventDataType);
                                        LogInfo(
                                            string.Format(
                                                "BroadcastToClient'{0}'(NewSharedObject, sharedObject.Id = '{1}')",
                                                newClient, sharedObject.Id), 8);
                                    }
                                }
                            }
                        }
                        else
                        {
                            LogWarning(
                                string.Format(
                                    "Refused to RegisterClient(clientName = '{0}') because the _clients list is full. ({1} clients)",
                                    clientName, Clients.Count), 1);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Unexpected exception:
                    LogWarning(string.Format("Unexpected exception ex.Message = '{0}' in RegisterClient)", ex.Message), 9);
                    // Throw it to restart the service (in case of service channel canceled)
                    throw;
                }
            }
        }