Exemplo n.º 1
0
 protected override bool ProcessBeforeJoinGame(JoinGameRequest joinRequest, SendParameters sendParameters, HivePeer peer)
 {
     if (joinRequest.ActorProperties != null && joinRequest.ActorProperties.ContainsKey("ProcessBeforeJoinException"))
     {
         peer = null;
         joinRequest.CacheSlice = 123;
     }
     return base.ProcessBeforeJoinGame(joinRequest, sendParameters, peer);
 }
Exemplo n.º 2
0
 protected override Caching.RoomReference GetRoomReference(JoinGameRequest joinRequest, params object[] args)
 {
     return TestGameCache.Instance.GetRoomReference(joinRequest.GameId, this, args);
 }
Exemplo n.º 3
0
        protected bool Join(HivePeer peer, JoinGameRequest joinRequest, SendParameters sendParameters)
        {
            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("Processing Join from IP: {0} to port: {1}", peer.RemoteIP, peer.LocalPort);
            }

            Actor a;
            if (this.JoinApplyGameStateChanges(peer, joinRequest, sendParameters, out a))
            {
                return this.JoinSendResponseAndEvents(peer, joinRequest, sendParameters, a.ActorNr, new ProcessJoinParams());
            }

            this.JoinFailureHandler(LeaveReason.ServerDisconnect, peer, joinRequest);

            return false;
        }
Exemplo n.º 4
0
        protected virtual OperationResponse GetUserJoinResponse(JoinGameRequest joinRequest, int actorNr, ProcessJoinParams prms)
        {
            var actor = this.ActorsManager.ActorsGetActorByNumber(actorNr);

            var joinResponse = new JoinResponse {ActorNr = actor.ActorNr};

            if (this.Properties.Count > 0)
            {
                joinResponse.CurrentGameProperties = this.Properties.GetProperties();
            }

            foreach (var t in this.ActorsManager)
            {
                // if actor is joining normaly we skip its own properties
                // if actor is rejoining we send its own properties
                if ((t.ActorNr != actor.ActorNr
                    || (!t.IsInactive && joinRequest.IsRejoining))
                    && (t.Properties.Count > 0 || this.PublishUserId))
                {
                    if (joinResponse.CurrentActorProperties == null)
                    {
                        joinResponse.CurrentActorProperties = new Hashtable();
                    }

                    var actorProperties = t.Properties.GetProperties();
                    if (t.IsInactive)
                    {
                        actorProperties.Add((byte) ActorParameter.IsInactive, true);
                    }

                    if (this.PublishUserId)
                    {
                        actorProperties.Add((byte)ActorParameter.UserId, t.UserId);
                    }
                    joinResponse.CurrentActorProperties.Add(t.ActorNr, actorProperties);
                }
            }

            var actorList = new List<int>();
            actorList.AddRange(this.ActorsManager.ActorsGetActorNumbers().ToArray());
            actorList.AddRange(this.ActorsManager.InactiveActorsGetActorNumbers().ToArray());

            if (!this.SuppressRoomEvents)
            {
                joinResponse.Actors = actorList.ToArray();
            }

            var oresponse = new OperationResponse(joinRequest.OperationRequest.OperationCode, joinResponse);
            if (prms.ResponseExtraParameters != null)
            {
                foreach (var extraParameter in prms.ResponseExtraParameters)
                {
                    oresponse.Parameters.Add(extraParameter.Key, extraParameter.Value);
                }
            }
            return oresponse;
        }
Exemplo n.º 5
0
        protected bool CreateGame(HivePeer peer, JoinGameRequest request, SendParameters sendParameters)
        {
            peer.JoinStage = HivePeer.JoinStages.CreatingOrLoadingGame;

            return this.Join(peer, request, sendParameters);
        }
Exemplo n.º 6
0
        public bool CheckBeforeJoinThisIsNewCreatedRoom(JoinGameRequest request)
        {
            if (this.ActorsManager.ActorNumberCounter == 0)
            {
                return true;
            }

            return false;
        }
Exemplo n.º 7
0
        private bool ConvertParamsAndValidateGame(HivePeer peer, JoinGameRequest joinRequest, SendParameters sendParameters)
        {
            // ValidateGame checks isOpen and maxplayers
            // and does not apply to rejoins
            if (this.CheckBeforeJoinThisIsNewCreatedRoom(joinRequest))
            {
                return true;
            }

            if (joinRequest.IsRejoining)
            {
                string errorMsg;
                ErrorCode errorcode;

                if (this.CheckUserOnJoin)
                {
                    if (this.ActorsManager.GetActorByUserId(peer.UserId) != null)
                    {
                        return true;
                    }

                    errorcode = ErrorCode.JoinFailedWithRejoinerNotFound;
                    errorMsg = HiveErrorMessages.UserNotFound;
                }
                else
                {
                    if (this.ActorsManager.GetActorByNumber(joinRequest.ActorNr) != null)
                    {
                        return true;
                    }

                    errorcode = ErrorCode.JoinFailedWithRejoinerNotFound;
                    errorMsg = string.Format(HiveErrorMessages.ActorNotFound, joinRequest.ActorNr);
                }

                if (joinRequest.JoinMode == JoinModes.RejoinOnly)
                {
                    this.SendErrorResponse(peer, joinRequest.OperationCode, errorcode, errorMsg, sendParameters);

                    joinRequest.OnJoinFailed(errorcode, errorMsg);

                    if (Log.IsWarnEnabled)
                    {
                        Log.WarnFormat("ConvertParamsAndValidateGame: Game '{0}' userId '{1}' failed to join. msg:'{2}' (JoinMode={3}) -- peer:{4}",
                            this.Name, peer.UserId, errorMsg, joinRequest.JoinMode, peer);
                    }

                    return false;
                }

                //TBD - I suggest beeing even stricter if the room is configured with expected users - we don't support JoinMode2!
                if (joinRequest.JoinMode == JoinModes.RejoinOrJoin && this.ActorsManager.IsExpectedUser(peer.UserId))
                {
                    errorMsg = HiveErrorMessages.CanNotUseRejoinOrJoinIfPlayerExpected;
                    this.SendErrorResponse(peer, joinRequest.OperationCode, ErrorCode.OperationDenied, errorMsg, sendParameters);

                    joinRequest.OnJoinFailed(ErrorCode.OperationDenied, errorMsg);

                    if (Log.IsWarnEnabled)
                    {
                        Log.WarnFormat("Game '{0}' userId '{1}' failed to join. msg:{2} (JoinMode={3}) -- peer:{4}",
                            this.Name, peer.UserId, errorMsg, joinRequest.JoinMode, peer);
                    }

                    return false;
                }
            }

            return this.ValidateGame(peer, joinRequest, sendParameters);
        }
Exemplo n.º 8
0
        protected bool ValidateGame(HivePeer peer, JoinGameRequest joinGameRequest, SendParameters sendParameters)
        {
            // check if the game is open
            if (this.IsOpen == false)
            {
                this.SendErrorResponse(peer, joinGameRequest.OperationCode, ErrorCode.GameClosed,
                    HiveErrorMessages.GameClosed, sendParameters);

                joinGameRequest.OnJoinFailed(ErrorCode.GameClosed, HiveErrorMessages.GameClosed);

                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("ValidateGame: Game '{0}' userId '{1}' failed to join. msg:{2} -- peer: {3}",
                        this.Name, peer.UserId, HiveErrorMessages.GameClosed, peer);
                }
                return false;
            }

            var am = this.ActorsManager;
            var isGameFull = am.ActorsCount + am.InactiveActorsCount + am.YetExpectedUsersCount >= this.MaxPlayers;

            // check if the maximum number of players has already been reached
            if (this.MaxPlayers > 0 && isGameFull && !this.ActorsManager.IsExpectedUser(peer.UserId))
            {
                this.SendErrorResponse(peer, joinGameRequest.OperationCode, ErrorCode.GameFull,
                    HiveErrorMessages.GameFull, sendParameters);

                joinGameRequest.OnJoinFailed(ErrorCode.GameFull, HiveErrorMessages.GameFull);

                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("ValidateGame: Game '{0}' userId '{1}' failed to join. msg:{2} -- peer:{3}",
                        this.Name, peer.UserId, HiveErrorMessages.GameFull, peer);
                }

                return false;
            }

            return true;
        }
Exemplo n.º 9
0
        private void HandleCreateGameOperationInt(HivePeer peer, SendParameters sendParameters,
            JoinGameRequest createGameRequest, bool fromJoin = false)
        {
            var createOptions = createGameRequest.GetCreateGameSettings(this);

            peer.SetPrivateCustomTypeCache(this.customTypeCache);

            RequestHandler handler = () =>
            {
                var oldValue = this.allowSetGameState;

                try
                {
                    this.allowSetGameState = false;

                    // since we allow to make changes to the original request sent by the client in a plugin
                    // we should check op.IsValid() - if not report error
                    createGameRequest.SetupRequest();

                    return this.ProcessCreateGame(peer, createGameRequest, sendParameters);
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Exception: {0}", e);
                    this.allowSetGameState = oldValue;
                    throw;
                }
            };

            var info = new CreateGameCallInfo(this.PendingPluginContinue, this.callEnv)
            {
                Request = createGameRequest,
                UserId = peer.UserId,
                Nickname = createGameRequest.GetNickname(),
                CreateOptions = createOptions,
                IsJoin = fromJoin,
                Handler = handler,
                Peer = peer,
                SendParams = sendParameters,
                OnFail = (onFailMsg, errorData) =>
                {
                    this.allowSetGameState = false;
                    this.failureOnCreate = true;

                    this.SendErrorResponse(peer, createGameRequest.OperationCode,
                        ErrorCode.PluginReportedError, onFailMsg, sendParameters, errorData);

                    peer.ReleaseRoomReference();
                    peer.ScheduleDisconnect(); // this gives the client a chance to get the reason
                }
            };

            try
            {
                this.Plugin.OnCreateGame(info);
            }
            catch (Exception e)
            {
                this.Plugin.ReportError(Photon.Hive.Plugin.ErrorCodes.UnhandledException, e);
            }
        }
Exemplo n.º 10
0
        private bool CheckGameCanBeCreated(HivePeer peer, JoinGameRequest joinGameRequest)
        {
            if (joinGameRequest.OperationCode == (byte)OperationCode.Join
                || joinGameRequest.JoinMode == JoinModes.CreateIfNotExists
                || joinGameRequest.JoinMode == JoinModes.RejoinOrJoin // for backwards compatibility - it seams some games expect this behavior - ISSUE: Codemasters uses RejoinOrJoin and now expects this to return false!
                || this.Plugin.IsPersistent)
            {
                return true;
            }

            this.SendErrorResponse(peer, joinGameRequest.OperationCode,
                ErrorCode.GameIdNotExists, HiveErrorMessages.GameIdDoesNotExist, new SendParameters());

            if (Log.IsWarnEnabled)
            {
                Log.WarnFormat(
                    "CheckGameCanBeCreated: Game '{0}' userId '{1}' failed to join game. msg:'{2}' (JoinMode={3}) -- peer:{4}",
                    this.Name,
                    peer.UserId,
                    HiveErrorMessages.GameIdDoesNotExist,
                    joinGameRequest.JoinMode,
                    peer);
            }

            joinGameRequest.OnJoinFailed(ErrorCode.GameIdNotExists, HiveErrorMessages.GameIdDoesNotExist);

            this.JoinFailureHandler(LeaveReason.ServerDisconnect, peer, joinGameRequest);
            return false;
        }
Exemplo n.º 11
0
        private void CallPluginOnLeaveIfJoinFailed(byte reason, HivePeer peer, JoinGameRequest request)
        {
            if (peer.JoinStage == HivePeer.JoinStages.Connected || peer.JoinStage == Hive.HivePeer.JoinStages.CreatingOrLoadingGame)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.DebugFormat("Peer join stage is {0}. CallPluginOnLeaveIfJoinFailed will be skiped. p:{1}", peer.JoinStage, peer);
                }
                return;
            }

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("Peer join stage is {0}. reason:{1}. CallPluginOnLeaveIfJoinFailed is called. p:{2}", peer.JoinStage, reason, peer);
            }

            var actor = this.GetActorByPeer(peer);

            RequestHandler handler = () =>
            {
                try
                {
                    this.RemovePeerFromGame(peer, false);
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Exception: {0}", e);
                    throw;
                }
                return true;
            };

            var info = new LeaveGameCallInfo(this.PendingPluginContinue, this.callEnv)
            {
                ActorNr = actor != null ? actor.ActorNr : -1,
                UserId = actor != null ? actor.UserId : peer.UserId,
                Nickname = actor != null ? actor.Nickname : request.GetNickname(),
                IsInactive = false,
                Reason = reason,
                Request = null,
                Handler = handler,
                Peer = null,
                SendParams = new SendParameters(),
            };
            try
            {
                this.Plugin.OnLeave(info);
            }
            catch (Exception e)
            {
                this.Plugin.ReportError(Photon.Hive.Plugin.ErrorCodes.UnhandledException, e);
            }
        }
Exemplo n.º 12
0
 protected virtual bool ProcessJoin(int actorNr, JoinGameRequest joinRequest, SendParameters sendParameters, ProcessJoinParams prms, HivePeer peer)
 {
     return this.JoinSendResponseAndEvents(peer, joinRequest, sendParameters, actorNr, prms);
 }
Exemplo n.º 13
0
        protected virtual bool ProcessCreateGame(HivePeer peer, JoinGameRequest joinRequest, SendParameters sendParameters)
        {
            var result = this.CreateGame(peer, joinRequest, sendParameters);

            this.ActorsManager.DeactivateActors(this);

            return result;
        }
Exemplo n.º 14
0
        protected virtual bool ProcessBeforeJoinGame(JoinGameRequest joinRequest, SendParameters sendParameters, HivePeer peer)
        {
            Actor actor;
            if (!this.JoinApplyGameStateChanges(peer, joinRequest, sendParameters, out actor))
            {
                this.JoinFailureHandler(LeaveReason.ServerDisconnect, peer, joinRequest);
                return false;
            }

            peer.JoinStage = HivePeer.JoinStages.BeforeJoinComplete;

            var info = new JoinGameCallInfo(this.PendingPluginContinue, this.callEnv)
            {
                UserId = peer.UserId,
                Peer = peer,
                Nickname = actor.Nickname,
                ActorNr = actor.ActorNr,
                Request = joinRequest,
                JoinParams = new ProcessJoinParams(),
                OnFail = (reason, parameters) => this.OnJoinFailHandler(LeaveReason.PluginFailedJoin, reason, parameters, peer, sendParameters, joinRequest),
            };

            RequestHandler handler = () =>
            {
                try
                {
                    if (!this.ProcessJoin(actor.ActorNr, joinRequest, sendParameters, info.JoinParams, peer))
                    {
                        // here we suppose that error response is already sent
                        this.JoinFailureHandler(LeaveReason.ServerDisconnect, peer, joinRequest);
                        return false;
                    }
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Exception:{0}", e);
                    throw;
                }
                return true;
            };

            info.Handler = handler;

            try
            {
                this.Plugin.OnJoin(info);
            }
            catch (Exception e)
            {
                this.Plugin.ReportError(ErrorCodes.UnhandledException, e);
            }
            return true;
        }
Exemplo n.º 15
0
        protected override void JoinFailureHandler(byte leaveReason, HivePeer peer, JoinGameRequest request)
        {
            base.JoinFailureHandler(leaveReason, peer, request);

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("JoinFailureHandler is called for peer with reason:{0}.room:{1},p:{2}", request.FailureReason, this.Name, peer);
            }
            this.CallPluginOnLeaveIfJoinFailed(leaveReason, peer, request);
            peer.ScheduleDisconnect();
        }
Exemplo n.º 16
0
        /// <summary>
        ///   Sends a <see cref = "JoinEvent" /> to all <see cref = "Actor" />s.
        /// </summary>
        /// <param name = "peer">
        ///   The peer.
        /// </param>
        /// <param name = "joinRequest">
        ///   The join request.
        /// </param>
        protected virtual void PublishJoinEvent(HivePeer peer, JoinGameRequest joinRequest)
        {
            if (this.SuppressRoomEvents)
            {
                return;
            }

            var actor = this.GetActorByPeer(peer);
            if (actor == null)
            {
                Log.ErrorFormat("There is no Actor for peer {0}", peer.ConnectionId);
                return;
            }

            // generate a join event and publish to all actors in the room
            var joinEvent = new JoinEvent(actor.ActorNr, this.ActorsManager.ActorsGetActorNumbers().ToArray());

            if (joinRequest.BroadcastActorProperties)
            {
                joinEvent.ActorProperties = joinRequest.ActorProperties;
                if (this.PublishUserId)
                {
                    if (joinEvent.ActorProperties == null)
                    {
                        joinEvent.ActorProperties = new Hashtable();
                    }
                    joinEvent.ActorProperties.Add((byte)ActorParameter.UserId, peer.UserId);
                }
            }

            this.PublishEvent(joinEvent, this.Actors, new SendParameters());
        }
Exemplo n.º 17
0
 /// <summary>
 /// Tries to add a <see cref="HivePeer"/> to this game instance.
 /// </summary>
 /// <param name="peer">
 /// The peer to add.
 /// </param>
 /// <param name="actorNr">
 /// The actor Nr.
 /// </param>
 /// <param name="actor">
 /// When this method returns this out param contains the <see cref="Actor"/> associated with the <paramref name="peer"/>.
 /// </param>
 /// <param name="errorcode">returns error code if we fail to add actor</param>
 /// <param name="reason">
 /// reason why player can not be added
 /// </param>
 /// <param name="isNewActor">returns true if actor is new</param>
 /// <param name="joinRequest">join request which was sent by client</param>
 /// <returns>
 /// Returns true if no actor exists for the specified peer and a new actor for the peer has been successfully added. 
 ///   The actor parameter is set to the newly created <see cref="Actor"/> instance.
 ///   Returns false if an actor for the specified peer already exists. 
 ///   The actor parameter is set to the existing <see cref="Actor"/> for the specified peer.
 /// </returns>
 protected virtual bool TryAddPeerToGame(HivePeer peer, int actorNr, out Actor actor, 
     out bool isNewActor, out ErrorCode errorcode, out string reason, JoinGameRequest joinRequest)
 {
     return this.ActorsManager.TryAddPeerToGame(this, peer, actorNr, out actor, out isNewActor, out errorcode, out reason, joinRequest);
 }
Exemplo n.º 18
0
        private void OnJoinFailHandler(byte leaveReason, string reasonDetails, Dictionary<byte, object> parameters,
            HivePeer peer, SendParameters sendParameters, JoinGameRequest request)
        {
            this.SendErrorResponse(peer, request.OperationCode,
                ErrorCode.PluginReportedError, reasonDetails, sendParameters, parameters);

            if (Log.IsWarnEnabled)
            {
                Log.WarnFormat("OnJoinFailHandler: Game '{0}' userId '{1}' failed to join. msg:{2} -- peer:{3}", this.Name, peer.UserId, reasonDetails, peer);
            }

            this.JoinFailureHandler(leaveReason, peer, request);
        }
Exemplo n.º 19
0
        private void ApplyGameProperties(JoinGameRequest createRequest)
        {
            // set default properties
            if (createRequest.newMaxPlayer.HasValue && createRequest.newMaxPlayer.Value != this.MaxPlayers)
            {
                this.MaxPlayers = createRequest.newMaxPlayer.Value;
            }

            if (createRequest.newIsOpen.HasValue && createRequest.newIsOpen.Value != this.IsOpen)
            {
                this.IsOpen = createRequest.newIsOpen.Value;
            }

            if (createRequest.newIsVisible.HasValue && createRequest.newIsVisible.Value != this.IsVisible)
            {
                this.IsVisible = createRequest.newIsVisible.Value;
            }

            if (createRequest.newLobbyProperties != null)
            {
                this.LobbyProperties = new HashSet<object>(createRequest.newLobbyProperties);
            }

            this.LobbyId = createRequest.LobbyName;
            this.LobbyType = (AppLobbyType)createRequest.LobbyType;
        }
Exemplo n.º 20
0
        private bool ValidatePlugin(JoinGameRequest operation, out string msg)
        {
            if (operation.Plugins != null)
            {
                if (operation.Plugins.Length > 0)
                {
                    if (operation.Plugins.Length > 1)
                    {
                        msg = "Currently only one plugin per game supported.";
                        return false;
                    }

                    if (this.Plugin.Name != operation.Plugins[0])
                    {
                        var errorPlugin = this.Plugin as ErrorPlugin;
                        if (errorPlugin != null)
                        {
                            msg = string.Format("Plugin Mismatch requested='{0}' got ErrorPlugin with message:'{1}'",
                                operation.Plugins[0], errorPlugin.Message);
                        }
                        else
                        {
                            msg = string.Format("Plugin Mismatch requested='{0}' got='{1}'", operation.Plugins[0], this.Plugin.Name);
                        }
                        return false;
                    }
                }
                else
                {
                    if (this.Plugin.Name != "Default")
                    {
                        msg = string.Format("Room is setup with unexpected plugin '{0}' - instead of default (none).", this.Plugin.Name);
                        return false;
                    }
                }
            }
            msg = string.Empty;
            return true;
        }
Exemplo n.º 21
0
        private void CopyGamePropertiesForMasterUpdate(JoinGameRequest request)
        {
            request.properties = this.Properties.GetProperties();

            if (this.MaxPlayers != 0)
            {
                request.newMaxPlayer = this.MaxPlayers;
            }

            request.newIsOpen = this.IsOpen;
            request.newIsVisible = this.IsVisible;

            if (this.LobbyProperties != null)
            {
                request.newLobbyProperties = new object[this.LobbyProperties.Count];
                this.LobbyProperties.CopyTo(request.newLobbyProperties);
            }
        }
Exemplo n.º 22
0
 protected override OperationResponse GetUserJoinResponse(JoinGameRequest joinRequest, int actorNr, ProcessJoinParams prms)
 {
     var res = base.GetUserJoinResponse(joinRequest, actorNr, prms);
     if (this.Plugin.Name != "Default")
     {
         res.Parameters.Add((byte)ParameterKey.PluginName, this.Plugin.Name);
         res.Parameters.Add((byte)ParameterKey.PluginVersion, this.Plugin.Version);
     }
     return res;
 }
Exemplo n.º 23
0
 protected virtual bool AddExpectedUsers(JoinGameRequest joinRequest)
 {
     return this.ActorsManager.TryAddExpectedUsers(this, joinRequest);
 }
Exemplo n.º 24
0
        protected override void HandleJoinGameOperation(HivePeer peer, SendParameters sendParameters, JoinGameRequest joinGameRequest)
        {
            if (this.isClosed)
            {
                if (!this.CheckGameCanBeCreated(peer, joinGameRequest))
                {
                    return;
                }

                if (!this.ReinitGame())
                {
                    this.SendErrorResponse(peer, joinGameRequest.OperationCode,
                        ErrorCode.InternalServerError, HiveErrorMessages.ReinitGameFailed, sendParameters);

                    joinGameRequest.OnJoinFailed(ErrorCode.InternalServerError, HiveErrorMessages.ReinitGameFailed);

                    this.JoinFailureHandler(LeaveReason.ServerDisconnect, peer, joinGameRequest);
                    if (Log.IsWarnEnabled)
                    {
                        Log.WarnFormat("Game '{0}' userId '{1}' failed to join. msg:{2}", this.Name, peer.UserId,
                            HiveErrorMessages.ReinitGameFailed);
                    }
                    return;
                }
            }

            //TBD do we still need this?
            string msg;
            if (!this.ValidatePlugin(joinGameRequest, out msg))
            {
                this.SendErrorResponse(peer, joinGameRequest.OperationCode, ErrorCode.PluginMismatch, msg, sendParameters);

                joinGameRequest.OnJoinFailed(ErrorCode.InternalServerError, HiveErrorMessages.ReinitGameFailed);
                this.JoinFailureHandler(LeaveReason.ServerDisconnect, peer, joinGameRequest);

                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("HandleJoinGameOperation: Game '{0}' userId '{1}' failed to join. msg:{2} -- peer:{3}", this.Name, peer.UserId, msg, peer);
                }
                return;
            }

            if (this.ActorsManager.ActorNumberCounter == 0) // we were just beeing created
            {
                if (!this.CheckGameCanBeCreated(peer, joinGameRequest))
                {
                    return;
                }

                this.HandleCreateGameOperationInt(peer, sendParameters, joinGameRequest, true);
            }
            else
            {
                peer.SetPrivateCustomTypeCache(this.customTypeCache);

                RequestHandler handler = () =>
                {
                    try
                    {
                        return this.ProcessBeforeJoinGame(joinGameRequest, sendParameters, peer);
                    }
                    catch (Exception e)
                    {
                        Log.ErrorFormat("Exception: {0}", e);
                        throw;
                    }
                };
                var info = new BeforeJoinGameCallInfo(this.PendingPluginContinue, this.callEnv)
                {
                    Request = joinGameRequest,
                    UserId = peer.UserId,
                    Nickname = joinGameRequest.GetNickname(),
                    Handler = handler,
                    Peer = peer,
                    SendParams = sendParameters,
                    OnFail = (onFailMsg, errorData) =>
                    {
                        this.allowSetGameState = false;
                        joinGameRequest.OnJoinFailed(ErrorCode.PluginReportedError, onFailMsg);
                        this.OnJoinFailHandler(LeaveReason.ServerDisconnect, onFailMsg, errorData, peer, sendParameters, joinGameRequest);
                    }
                };

                try
                {

                    this.Plugin.BeforeJoin(info);
                }
                catch (Exception e)
                {
                    this.Plugin.ReportError(Photon.Hive.Plugin.ErrorCodes.UnhandledException, e);
                }
            }
        }
Exemplo n.º 25
0
        /// <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(HivePeer 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.CreateGame2:
                        {
                            var createGameRequest = new CreateGameRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(createGameRequest, sendParameters) == false)
                            {
                                return;
                            }

                            this.LogOperation(peer, operationRequest);

                            createGameRequest.OnStart();
                            this.HandleCreateGameOperation(peer, sendParameters, createGameRequest);
                            createGameRequest.OnComplete();
                        }

                        break;

                    case OperationCode.Join:
                    case OperationCode.JoinGame2:
                        {
                            var joinGameRequest = new JoinGameRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(joinGameRequest, sendParameters) == false)
                            {
                                return;
                            }

                            // Join should be default CreateIfNotexists=true
                            //if (!joinGameRequest.CreateIfNotExists && operationRequest.OperationCode == (byte)OperationCode.Join)
                            //{
                            //    joinGameRequest.CreateIfNotExists = true;
                            //}

                            this.LogOperation(peer, operationRequest);

                            joinGameRequest.OnStart();
                            this.HandleJoinGameOperation(peer, sendParameters, joinGameRequest);
                            joinGameRequest.OnComplete();
                        }

                        break;

                    case OperationCode.DebugGame:
                        var debugGameRequest = new DebugGameRequest(peer.Protocol, operationRequest);
                        if (peer.ValidateOperation(debugGameRequest, sendParameters) == false)
                        {
                            return;
                        }

                        this.LogOperation(peer, operationRequest);

                        debugGameRequest.OnStart();
                        this.HandleDebugGameOperation(peer, debugGameRequest, sendParameters);
                        debugGameRequest.OnComplete();
                        break;

                    case OperationCode.Leave:
                        {
                            var leaveOperation = new LeaveRequest(peer.Protocol, operationRequest);
                            if (peer.ValidateOperation(leaveOperation, sendParameters) == false)
                            {
                                return;
                            }

                            this.LogOperation(peer, operationRequest);

                            leaveOperation.OnStart();
                            this.HandleLeaveOperation(peer, sendParameters, leaveOperation);
                            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 (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:
                        {
                            var message = string.Format("Unknown operation code {0}", (OperationCode)operationRequest.OperationCode);
                            this.SendErrorResponse(peer, operationRequest.OperationCode,
                                ErrorCode.OperationInvalid, message, sendParameters);

                            if (Log.IsWarnEnabled)
                            {
                                Log.Warn(message);
                            }
                        }

                        break;
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
Exemplo n.º 26
0
 protected virtual void JoinFailureHandler(byte leaveReason, HivePeer peer, JoinGameRequest request)
 {
     if (Log.IsDebugEnabled)
     {
         Log.DebugFormat("JoinFailureHandler is called for peer with reason:{0}.room:{1},p:{2}", request.FailureReason, this.Name, peer);
     }
     peer.OnJoinFailed(request.FailureReason, request.FailureMessage);
 }
Exemplo n.º 27
0
 /// <summary>
 /// Handles the <see cref="JoinGameRequest"/>: Joins a peer to a room and calls <see cref="PublishJoinEvent"/>.
 ///   Before a JoinOperation reaches this point (inside a room), the <see cref="HivePeer"/> made 
 ///   sure that it is removed from the previous Room (if there was any).
 /// </summary>
 /// <param name="peer">
 /// The peer.
 /// </param>
 /// <param name="sendParameters">
 /// The send Parameters.
 /// </param>
 /// <param name="joinGameRequest">
 /// The join Game Request.
 /// </param>
 protected virtual void HandleJoinGameOperation(HivePeer peer, SendParameters sendParameters, JoinGameRequest joinGameRequest)
 {
     this.Join(peer, joinGameRequest, sendParameters);
 }
Exemplo n.º 28
0
        protected bool JoinSendResponseAndEvents(HivePeer peer, JoinGameRequest joinRequest, SendParameters sendParameters, int actorNr, ProcessJoinParams prms)
        {
            peer.JoinStage = HivePeer.JoinStages.GettingUserResponse;
            var oresponse = this.GetUserJoinResponse(joinRequest, actorNr, prms);
            peer.SendOperationResponse(oresponse, sendParameters);

            peer.JoinStage = HivePeer.JoinStages.PublishingEvents;
            this.PublishJoinEvent(peer, joinRequest);
            peer.JoinStage = HivePeer.JoinStages.EventsPublished;
            this.PublishEventCache(peer, joinRequest);

            peer.JoinStage = HivePeer.JoinStages.Complete;
            return true;
        }
Exemplo n.º 29
0
        protected bool JoinApplyGameStateChanges(HivePeer peer, JoinGameRequest joinRequest, SendParameters sendParameters, out Actor actor)
        {
            var isCreatingGame = false;
            var isNewGame = false;
            if (peer.JoinStage == HivePeer.JoinStages.CreatingOrLoadingGame)
            {
                isCreatingGame = true;
                if (this.CheckBeforeJoinThisIsNewCreatedRoom(joinRequest))
                {
                    isNewGame = true;
                    this.ApplyGameProperties(joinRequest);
                }
                else
                {
                    this.CopyGamePropertiesForMasterUpdate(joinRequest);
                }
            }

            actor = null;
            peer.JoinStage = HivePeer.JoinStages.ConvertingParams;
            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 false;
            }

            if (!this.ConvertParamsAndValidateGame(peer, joinRequest, sendParameters))
            {
                return false;
            }

            peer.JoinStage = HivePeer.JoinStages.CheckingCacheSlice;
            if (joinRequest.CacheSlice.HasValue && !this.EventCache.HasSlice(joinRequest.CacheSlice.Value))
            {
                var msg = string.Format(HiveErrorMessages.CacheSliceNoAviable, joinRequest.CacheSlice);
                this.SendErrorResponse(peer, joinRequest.OperationCode, ErrorCode.OperationInvalid, msg, sendParameters);
                joinRequest.OnJoinFailed(ErrorCode.OperationInvalid, msg);

                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("JoinApplyGameStateChanges: Game '{0}' userId '{1}' failed to join. msg:{2} -- peer:{3}",
                        this.Name, peer.UserId, msg, peer);
                }
                return false;
            }

            peer.JoinStage = HivePeer.JoinStages.AddingActor;
            ErrorCode errorcode;
            string reason;
            // create an new actor
            bool isNewActor;
            if (this.TryAddPeerToGame(peer, joinRequest.ActorNr, out actor, out isNewActor, out errorcode, out reason, joinRequest) == false)
            {
                this.SendErrorResponse(peer, joinRequest.OperationCode, errorcode, reason, sendParameters);
                joinRequest.OnJoinFailed(errorcode, reason);

                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("JoinApplyGameStateChanges: Game '{0}' userId '{1}' failed to join. msg:{2} -- peer:{3}",
                        this.Name, peer.UserId, reason, peer);
                }
                return false;
            }

            // check if a room removal is in progress and cancel it if so
            if (this.RemoveTimer != null)
            {
                this.RemoveTimer.Dispose();
                this.RemoveTimer = null;
            }

            if (this.MasterClientId == 0)
            {
                this.UpdateMasterClientId();
            }

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("JoinApplyGameStateChanges: Actor {0} is added. MasterClientId is {1}", actor.ActorNr, this.MasterClientId);
            }

            peer.JoinStage = HivePeer.JoinStages.CheckAfterJoinParams;

            // set game properties for join from the first actor (game creator)
            if (isNewGame)
            {
                this.DeleteCacheOnLeave = joinRequest.DeleteCacheOnLeave;
                this.SuppressRoomEvents = joinRequest.SuppressRoomEvents;
                if (this.MaxEmptyRoomTTL < joinRequest.EmptyRoomLiveTime)
                {
                    var msg = string.Format(HiveErrorMessages.MaxTTLExceeded, joinRequest.EmptyRoomLiveTime, MaxEmptyRoomTTL);
                    this.SendErrorResponse(peer, joinRequest.OperationCode, ErrorCode.OperationInvalid, msg, sendParameters);
                    joinRequest.OnJoinFailed(ErrorCode.OperationInvalid, msg);

                    if (Log.IsWarnEnabled)
                    {
                        Log.WarnFormat("Game '{0}' userId '{1}' failed to create. msg:{2} -- peer:{3}", this.Name, peer.UserId, msg, peer);
                    }
                    return false;
                }
                this.EmptyRoomLiveTime = joinRequest.EmptyRoomLiveTime;
                this.PlayerTTL = joinRequest.PlayerTTL;
                this.CheckUserOnJoin = joinRequest.CheckUserOnJoin;
                this.PublishUserId = joinRequest.PublishUserId;

                if (joinRequest.GameProperties != null)
                {
                    this.Properties.SetProperties(joinRequest.GameProperties);
                }

                if (joinRequest.AddUsers != null)
                {
                    this.Properties.Set((byte)GameParameter.ExpectedUsers, joinRequest.AddUsers);
                }
            }

            if (Log.IsDebugEnabled)
            {
                if (isCreatingGame)
                {
                    Log.DebugFormat(
                        "{0} Game - name={2}, lobyName={3}, lobbyType={4}, maxPlayers={5}, IsOpen={6}, IsVisible={7}, EmptyRoomLiveTime={8}, PlayerTTL={9}, CheckUserOnJoin={10}, PublishUserId={11}, ExpectedUsers={12}",
                        isNewGame ? "Created" : "Loaded", // 0
                        "", // 1
                        this.Name, // 2
                        this.LobbyId,
                        this.LobbyType,
                        this.MaxPlayers,
                        this.IsOpen,
                        this.IsVisible,
                        this.EmptyRoomLiveTime,
                        this.PlayerTTL,
                        this.CheckUserOnJoin,
                        this.PublishUserId,
                        joinRequest.AddUsers != null ? joinRequest.AddUsers.Aggregate((current, next) => current + ", " + next) : ""
                        );
                }
            }

            if (!this.AddExpectedUsers(joinRequest))
            {
                this.SendErrorResponse(peer, joinRequest.OperationRequest.OperationCode, ErrorCode.InternalServerError,
                        HiveErrorMessages.CantAddSlots, sendParameters);
                joinRequest.OnJoinFailed(ErrorCode.InternalServerError, HiveErrorMessages.CantAddSlots);
                if (Log.IsWarnEnabled)
                {
                    Log.WarnFormat("Game '{0}' userId '{1}' failed to join. msg:{2}", this.Name, peer.UserId, HiveErrorMessages.CantAddSlots);
                }
                return false;
            }

            peer.JoinStage = HivePeer.JoinStages.ApplyActorProperties;
            // set custom actor properties if defined
            if (joinRequest.ActorProperties != null)
            {
                // this is set by the server only
                joinRequest.ActorProperties.Remove((byte)ActorParameter.IsInactive);
                joinRequest.ActorProperties.Remove((byte)ActorParameter.UserId);

                actor.Properties.SetProperties(joinRequest.ActorProperties);
            }

            if (!isNewGame && this.ModifyExpectedUsersProperty(joinRequest.AddUsers))
            {
                const byte propertyId = (byte)GameParameter.ExpectedUsers;
                var propertiesChangedEvent = new PropertiesChangedEvent(0)
                {
                    Properties = new Hashtable
                    {
                        {propertyId, this.Properties.GetProperty(propertyId).Value}
                    }
                };
                this.PublishEvent(propertiesChangedEvent, this.Actors, sendParameters); // shouldn't we publish this in the next JoinStage2?
            }
            return true;
        }
Exemplo n.º 30
0
        /// <summary>
        ///   Sends all cached events to a peer.
        /// </summary>
        /// <param name = "litePeer">
        ///   The lite peer that receives the events.
        /// </param>
        /// <param name="joinRequest"></param>
        protected void PublishEventCache(HivePeer litePeer, JoinGameRequest joinRequest)
        {
            var @event = new CustomEvent(0, 0, null);
            foreach (KeyValuePair<int, EventCache> entry in this.ActorEventCache)
            {
                var actor = entry.Key;
                var cache = entry.Value;
                @event.ActorNr = actor;
                foreach (KeyValuePair<byte, Hashtable> eventEntry in cache)
                {
                    @event.Code = @eventEntry.Key;
                    @event.Data = @eventEntry.Value;

                    var eventData = new EventData(@event.Code, @event);
                    litePeer.SendEvent(eventData, new SendParameters());
                }
            }

            int cacheSliceRequested = 0;
            if (joinRequest.CacheSlice.HasValue)
            {
                cacheSliceRequested = joinRequest.CacheSlice.Value;
            }
            foreach (var slice in this.EventCache.Slices)
            {
                if (slice >= cacheSliceRequested)
                {
                    if (slice != 0)
                    {
                        var sliceChangedEvent = new CacheSliceChanged(0) { Slice = slice };
                        this.PublishEvent(sliceChangedEvent, this.GetActorByPeer(litePeer), new SendParameters());
                    }

                    foreach (var customEvent in this.EventCache[slice])
                    {
                        var eventData = new EventData(customEvent.Code, customEvent);
                        litePeer.SendEvent(eventData, new SendParameters());
                    }
                }
            }
        }